-
Notifications
You must be signed in to change notification settings - Fork 86
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
Add test for validateFlatTerm and round trip test for FlatTerm conversions #196
base: master
Are you sure you want to change the base?
Conversation
DeepakKapiswe
commented
Mar 22, 2019
•
edited
Loading
edited
- Tests for validateFlatTerm function
- Travis: GHC versions update
- Add round trip property tests for FlatTerm to / from conversion
780d172
to
6dab918
Compare
4464bf9
to
30eff8a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good. The first main patch (ignoring the CI one) is good and just needs a few adjustments. The second patch will need re-thinking, at least the property for invalid flat terms. It'd be ok to split this into two if you like so we can commit the first patch sooner.
cborg/tests/Tests/Properties.hs
Outdated
imp = fromRef . canonicaliseRef $ x | ||
eq = eqImp t | ||
enc = encodeImp t imp | ||
fn e = fromFlatTerm (decodeImp (Proxy :: Proxy t)) $ toFlatTerm e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be decodeImp t
rather than decodeImp (Proxy :: Proxy t)
, since we already defined the value t
as Proxy :: Proxy t
(where the latter t
is the type).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed
cborg/tests/Tests/Properties.hs
Outdated
prop_toFromFlatTerm :: forall t. Token t => Proxy t -> t -> Bool | ||
prop_toFromFlatTerm _ x = | ||
|
||
liftA2 eq (fn enc) (Right imp) == Right True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be expressed a bit more elegantly if you followed the same trick as deserialiseImp
which is basically a wrapper that throws an exception of the result is a decode failure.
Here, you'd make a local wrapper around fromFlatTerm
that just throws an exception in the Left
case. Something like
where
deserialiseFromFlatTerm dec =
case fromFlatTerm dec flatterm of
Left _ -> error "fromFlatTerm: decode failure"
Right x -> x
Then your overall property can match the diagram directly (and like in your comment).
(deserialiseFromFlatTerm (decodeImp t) . toFlatTerm . encodeImp t) imp `eq` imp
The idea with these commuting diagrams is that the property can be read off directly by composing all the arrows. So this reads most nicely when the property is exactly that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, correct Implemented accordingly.
cborg/tests/Tests/FlatTerm.hs
Outdated
|
||
|
||
-- Convert Term to List of Valid TermTokens | ||
termToValidTermTokens :: Term -> [TermToken] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be replaced by toFlatTerm . encodeTerm
couldn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
cborg/tests/Tests/FlatTerm.hs
Outdated
prop_validateValidFlat (ValidFlat ts) = property $ validFlatTerm ts | ||
|
||
prop_validateInValidFlat :: InValidFlat -> Property | ||
prop_validateInValidFlat (InValidFlat ts) = property $ validFlatTerm ts == False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very add-hoc property. The generator for InValidFlat
is just using various but fixed ways of making an invalid flat term.
I'm not happy with adding this property. It looks like it's testing something that it's really not testing well.
An alternative approach would be to naively generate arbitrary flat terms and then check that the reference decoder (ie from Tests.Reference.Implementation
) agrees with validFlatTerm
. By agree, I mean they both agree it's valid, or both agree it's invalid. Of course most arbitrarily generated flat terms will be invalid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dcoutts Yes I agree you are right, the generation of InvalidFlat
is ad hoc in the sense that it is not covering all possible ways of invalidity but a few fixed ones.
Alternative approach looks fine to me btw do you think that testing arbitrarily generated FlatTerms along with the current setup will be better or its of no use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the currently proposed change here is misleading, and not of a lot of use. I'd accept the PR without the second patch. Or I'd accept the second patch without the bogus property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the property as per your suggestions!
e67919c
to
7c3e62c
Compare
cborg/tests/Tests/FlatTerm.hs
Outdated
prop_validFlatTerm :: [TermToken] -> Property | ||
prop_validFlatTerm ts = property $ case refImpDecode ts of | ||
(Just x, Just y) -> x == y && validFlatTerm ts | ||
(Nothing, Nothing) -> True && (not $ validFlatTerm ts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that position True
does absolutely nothing. You should drop it an just leave the not (validFlatTerm ts)
.
Basically for all values of x
, True && x == x
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have the logic right here (ie prop_validFlatTerm
and refImpDecode
) but the structure is a bit weird. Specifically, you have an function that encodes a pair two different ways and returns them as a tuple, when a large chunk of that could just be inlined in the property. Once you inline like that, you probably don't need maybeRdecoded
you can just pattern match on an (Maybe a, Either e a)
pair.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While i think the above is logically correct, I think that the QC generated [TermToken]
data will be invalid for all but the most trivial cases. It would be much nicer if we could manipulate this so that it generated terms that were valid say 80% of the time and invalid 20% of the time. This would give us much better assurance that this property is getting thoroughly tested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented the requested changes!
-- | ||
prop_toFromFlatTerm :: forall t. Token t => Proxy t -> t -> Bool | ||
prop_toFromFlatTerm _ x = | ||
|
||
liftA2 eq (fn enc) (Right imp) == Right True | ||
(deserialiseFromFlatTerm (decodeImp t) . toFlatTerm . encodeImp t) imp `eq` imp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should probably use QuickCheck's ===
operator there because if the property fails ===
gives a much better error message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, eq
is not directly equivalent to QC's ===
as eq
is defined as eq = eqImp t
and eqImp
is a method of TypeClass Token
for which the test property is written.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok. Disregard that comment then.
5f1fa38
to
761ef0c
Compare