Replies: 2 comments
-
instance StateModel Model where
-- here we don't specify what errors might the actions throw
-- as the return of `perform` will be the one declaring those errors Yes, the data Action Model a where
....
type Error Model = Either FooError BarError Minor comment but I think an actual sum type would be more suited here arbitraryAction = ...
nextState state (Foo args) _res = -- here we should assume that Foo succeeded?
nextState state (Bar args) _res = -- same Yes, this expresses the "natural" state transition in the model when the action succeed -- as Baz cannot fail, with Baz we will only arrive here,
-- not to `failureNextState`? But _we_ know that, there is nothing in the test that prevents this...
nextState state (Baz args) _res =
failureNextState state _ = state -- we don't change the model on failures (this could be defaulted I think?) Indeed. The logic is that precondition state (Foo args) = -- here we should *ONLY* accept Foo iff it will succeed?
precondition state (Bar args) = -- same Yes precondition state (Baz args) = -- this will always be the case when we run `Baz`?
-- but as said above, _we_ know that, but the test doesn't.
validFailingAction state (Foo args) = -- here we should *ONLY* accept Foo iff it will fail? or is it fine
-- to accept it regardless of whether it will fail or not?
validFailingAction state (Bar args) = -- same
validFailingAction state (Baz args) = -- we know this will never be executed, right?
Perhaps things are clearer in the code? instance RunModel State m where
perform = ...
postcondition (a, b) (Foo args) lookup realized = -- here we should check the postcondition considering that Foo succeeded?
-- same with Bar, understandable for Baz Same logic than before: postconditionOnFailure states act lookup (Right v) = postcondition states act lookup v -- is this reasonable? It might be in your particular case but that seems indicative of a hole in the model. postconditionOnFailure (a, b) (Foo args) lookup (Left (Left FooError)) = -- ok I know what to do here, but what about
postconditionOnFailure (a, b) (Foo args) lookup (Left (Left BarError)) == -- here I should just throw an `error "impossible combination of action+result"`?
... -- same for Bar Yes, there's no direct link between the postconditionOnFailure (a, b) (Baz args) lookup (Left _) = -- _we_ know baz cannot fail, so what should this do? throw an error? Yes, there's no provision to prevent this match as the types are not linked. If your |
Beta Was this translation helpful? Give feedback.
-
I think your question highlights the fact we did not do a good job at explaining how this "negative testing" works, I will write some documentation and hopefully examples to better illustrate the ideas behind it. |
Beta Was this translation helpful? Give feedback.
-
Say I have some actions which might throw some different errors, or none.
From what I can see in the documentation of q-d, if some actions might return errors, we should define a different
type Error
instance. I imagine that error should be a combination of all the errors possible in all the commands?I want to see if my current understanding of how this would be implemented seems correct. Most of the functions here carry a question on how to implement them. It would be nice if the intended usage could be clarified:
Disclaimer: I have not tried what is after this line, it might not even be doable.
I wonder if
Error
could insted be determined by the action that is run, such as:This way, we could define:
and in the case of Baz, this could not be defined as there exists no
BazError :: Error Model (Action Model BazResult)
. And also forFoo
andBar
we know precisely which is the error that could be thrown on each case.Beta Was this translation helpful? Give feedback.
All reactions