0.4.1 #255
nth-commit
announced in
Announcements
0.4.1
#255
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Enhancements for generators
Gen.Two, Gen.Three, Gen.Four
Added a family of higher-order generators, which take a generator and return a new generator of a tuple, whose values are sourced from the original generator.
Gen.Set
Added another higher-order generator, that takes a generator and returns a new generator for sets, whose elements are sourced from the original generator. The values it returns are of type
IReadOnlyCollection<T>
, as that is the most fundamental immutable "set"-like interface in the core framework.ISet<T>
was considered, but it's methods hint towards mutability, which breaks shrinking.The API has familiar configuration methods to
Gen.List
,Gen.String
for specifying the range of counts that are acceptable for generated sets.Sometimes you need to stop trying
Unlike other property-based testing frameworks, GalaxyCheck has exhaustion protection built-in as a fundamental property of generators. Other frameworks have similar protections, but only at the property level. This means you can discard/filter values inside the test method, and excessive filtering will cause the property to fail.
However, discards inside the generators passed to your property will not be tracked. It's easy to mistakenly construct a generator that never complete, which cause tests to hang, mysteriously. Sometimes the preconditions that caused the generator to struggle are disconnected (like in different functions, for example).
GalaxyCheck detects excessive discards everywhere and will bail out of such generation attempts, for example:
The newly-introduced set generator leverages the same behaviour. This means that GalaxyCheck won't hang when trying to generate impossible sets (or sets that are really hard to fill). Instead, the following code will crash:
The set generator will also do just fine when you don't explicitly tell it what count you want, either. For example:
Gen.Create now knows about sets
This release also wires up a few of the .NET set types to the set generator, meaning reflection-based properties that have sets as parameters will now work out-of-the-box.
Note,
IReadOnlyCollection<T>
is still handled by the list generator, by default.FlagsAttribute variant of Gen.Enum now uses Gen.Set under-the-hood
Previously, it used Gen.List, which means the shrinks inherited the structure of that generator. Now, it uses Gen.Set, which greatly decreases the number of shrinks - as only distinct values will be bitwise-OR'd together, and there will be no shrinks dedicated to modifying the order of the bitwise-OR - removing ineffective shrinks.
This diff demonstrates what that means in practice.
Gen.Cast is more flexible
Previously, the following code would throw:
This is weird, as there is a defined cast between those two types.
I'm pretty sure it's a limitation of boxing...
Anyway, in the latest version, if casting fails, the generator will try and do a
Convert.ChangeType
instead - which might work! (it does in this case). That's the best I can do right now.BUGFIX: Gen.Create with could cause a list to only contain a single repeating value
A certain code-path through the reflection-based generator (specifically, an object inside a list) meant that the list might only contain a single-repeated value. This was because the reflection generator for types with a default constructor, would only ever create one instance. Then, inside the generator body, it would call
PropertyInfo.SetValue
/FieldInfo.SetValue
.This was fixed in this version, by moving the object creation inside the generator body.
This discussion was created from the release 0.4.1.
Beta Was this translation helpful? Give feedback.
All reactions