-
Notifications
You must be signed in to change notification settings - Fork 157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bool
≈ Task<bool>
, Property
≉ Task<Property>
#684
Comments
Sounds very reasonable to me. I think that would amount to not upcasting to Task in testable, and writing a Prop.ofTaskT which also looks at the result of the Task<T> to determine test outcome.
|
I agree that the behaviour reported here looks undesirable. |
Hmm. Given the current design (originally added in 3e90689), it seems obvious that it is impossible to create a Something like this, while it works for the trivial examples I have tried, is surely wrong because of the call to static member TaskGeneric() =
{ new ITestable<Task<'T>> with
member __.Property t =
Property (fun arbMap ->
Gen.promote (fun runner ->
Shrink.ofValue (Future (
t.ContinueWith (fun (t : Task<'T>) ->
match t.IsCanceled, t.IsFaulted with
| _, true -> Task.FromResult (Res.failedException t.Exception)
| true, _ -> Task.FromResult Res.failedCancelled
| false, false ->
let prop = property t.Result
let gen = Property.GetGen arbMap prop
let shrink = runner gen
match Shrink.getValue shrink with
| Value result, _ -> Task.FromResult result
| Future resultTask, _ -> resultTask)
|> _.Unwrap())))) } Or am I missing something or failing to do the proper type Tetris? |
Yes, I think your analysis is essentially correct. I remember something about struggling with this issue - ResultContainer was probably part of trying to break the recursive relationship, before F# properly supported recursive modules. My memory is very hazy on the whole thing though...if you see a reasonable way through I am happy to defer to your judgement. |
The behavior added in #634 to address #633 feels confusing to me when contrasted with the behavior of tests that return
Task<bool>
, especially for xUnit/NUnit tests annotated withPropertyAttribute
.That is:
PropertyAttribute
that returnbool
fail when thebool
isfalse
.PropertyAttribute
that returnTask<bool>
fail when thebool
isfalse
.PropertyAttribute
that returnProperty
fail when theProperty
is falsy.PropertyAttribute
that returnTask<Property>
pass when theProperty
is falsy.I would expect 4 to fail just as 1–3 do.
I understand the original desire not to need to explicitly upcast
Task<unit>
toTask
, but the difference in treatment betweenTask<bool>
andTask<Property>
is dangerous, because it is far too easy to write a test that returnsTask<Property>
and have it pass for the wrong reason.That is, a developer might expect the test to fail if the
Property
inside the returnedTask<Property>
was falsy, just as such a test would fail for afalse
or falsybool
,Task<bool>
, orProperty
— but the test returningTask<Property>
would actually always pass as long as no exceptions were thrown.Is there is any chance we could make
Task<Property>
behave likeTask<bool>
andProperty
here? Or, ideally,Task<'T>
when'T
is testable behave like'T
?I'd be willing to open a PR.
CC @ploeh, @kurtschelfthout.
The text was updated successfully, but these errors were encountered: