Can't use beAnInstanceOf to match Expectations
SunDog opened this issue · comments
When comparing instances or classes the methods beAnInstanceOf
and beAKindOf
returns a Predicate<Any>
but RxNimble expectation ask's for Predicate<T>
instead.
Code:
let driverObject = Driver.just(Int())
// doesn't compile
expect(driverObject.asObservable()).first.to(beAnInstanceOf(Int.self))
// compile
let result = try! driverObject.asObservable().toBlocking().first()
expect(result).to(beAnInstanceOf(Int.self))
I don't know if it is as expected or if we can improve this.
Therefore I'm at your disposal to make a PR for this, but I would need some direction since I think this is not as easy as just changing the type of var first
Hmm! Sounds like you may have found a bug. We recently refactored the internals to support RxTest in #35, maybe this is a limitation we've hit? I'm not sure. The docs for Nimble's custom matchers are here: https://github.com/Quick/Nimble#writing-your-own-matchers Not sure about RxTest but I'd start in our Nimble implementation: https://github.com/RxSwiftCommunity/RxNimble/blob/master/Source/RxTest/Expectation%2BRxTest.swift A PR would be very welcome, thanks 🙇
Hey @SunDog thank you for reporting this.
I don't think, it's an issue with RxNimble. It's just the way it was implemented
expect(subject).first
resolves as Expectation<Int>
, so we can't check its type. Because we know it for sure.
RxTest has another API, which extends ObservableConvertibleType
type. So it doesn't change behaviour of expect
method.
if you want to get such behaviour, you can use:
let driverObject: Driver<Any> = Driver.just(Int())
// will compile
expect(driverObject.asObservable()).first.to(beAnInstanceOf(Int.self))
The only way to resolve this issue - fully rethink API of RxNimble. first
shouldn't be in extension of Expectation
, but in ObservableConvertibleType
. Like this:
public extension ObservableConvertibleType {
var first: Element {
return try! self.toBlocking().first()! // dirty version with force unwrap
}
}
...
expect(o.first).to(beAnInstanceOf(Int.self)) // compiles
If maintainers are ok with that, i will create PR @gobetti
Hi @ashfurrow @MortyMerr !
You guys mentioned RxTest, so just making sure we're on the same page: I think grabbing the first
only makes sense when using RxBlocking
, because the idea with RxTest
is to test a sequence instead of specific events (we would need to block it until the first one is received if we want one event, right?). So @MortyMerr your proposed solution makes sense to me, as long as it's part of the RxBlocking subspec only.
Please feel free to correct me if I'm wrong! 🙏
@gobetti these declarations will conflict with first()
from Observable
I think it's better to just ignore beAnInstanceOf
or use the approach with explicit type