Skip to content

Releases: nth-commit/GalaxyCheck

0.8.0-preview.16

01 Jun 08:57
Compare
Choose a tag to compare
0.8.0-preview.16 Pre-release
Pre-release

What's Changed

Full Changelog: 0.7.0...0.8.0-preview.16

0.8.0-preview.15

01 Jun 05:10
Compare
Choose a tag to compare
0.8.0-preview.15 Pre-release
Pre-release

What's Changed

Full Changelog: 0.7.0...0.8.0-preview.15

0.8.0-preview.14

03 Apr 01:42
Compare
Choose a tag to compare
0.8.0-preview.14 Pre-release
Pre-release

What's Changed

Full Changelog: 0.7.0...0.8.0-preview.14

0.8.0-preview.13

29 Nov 07:10
Compare
Choose a tag to compare
0.8.0-preview.13 Pre-release
Pre-release

What's Changed

Full Changelog: 0.7.0...0.8.0-preview.13

0.8.0-preview.12

15 Aug 06:55
Compare
Choose a tag to compare
0.8.0-preview.12 Pre-release
Pre-release

What's Changed

Full Changelog: 0.7.0...0.8.0-preview.12

0.7.0

11 Jul 20:38
Compare
Choose a tag to compare

.NET 6.0 Support

GalaxyCheck was initially built when netstandard was a thing. It's not anymore.

Only support .NET 6.0 for now. .NET 5.0 support may be retroactively added if required. .NET 7.0 support coming soon.

Full Changelog: 0.6.1...0.7.0

0.6.1

10 Jul 00:10
Compare
Choose a tag to compare

After a hiatus from .NET development I'm back and ready to chip away at the final features/bugs required to get GalaxyCheck stable.

What's Changed

  • 🌍 Add GalaxyCheck.Xunit.CodeAnalysis to publishable packages by @nth-commit in #313
  • 🌍 #314 Code refactoring suggestions now also apply to SampleAttribute by @nth-commit in #315
  • 🌍 #316 Shrink string/char gens to 'a' instead of whitespace by @nth-commit in #317
  • 🌍 #318 Optimize shrinking for "any list over count" counterexample by @nth-commit in #319
  • 🌍 #318 Count all iterations after the initial counterexample as shrinks by @nth-commit in #321

Full Changelog: 0.6.0...0.6.1

0.6.1-alpha.1

11 Dec 04:12
Compare
Choose a tag to compare
0.6.1-alpha.1 Pre-release
Pre-release

What's Changed

  • 🌍 Add GalaxyCheck.Xunit.CodeAnalysis to publishable packages by @nth-commit in #313
  • 🌍 #314 Code refactoring suggestions now also apply to SampleAttribute by @nth-commit in #315
  • 🌍 #316 Shrink string/char gens to 'a' instead of whitespace by @nth-commit in #317
  • 🌍 #318 Optimize shrinking for "any list over count" counterexample by @nth-commit in #319
  • 🌍 #318 Count all iterations after the initial counterexample as shrinks by @nth-commit in #321

Full Changelog: 0.6.0...0.6.1-alpha.1

0.6.0

08 Dec 01:58
Compare
Choose a tag to compare

New package: GalaxyCheck.Xunit.CodeAnalysis

It's installed automatically when you install GalaxyCheck.Xunit, and will be the home of Roslyn analyzers and code refactoring providers.

Add MemberGenAttribute

This new attribute mirrors MemberData in xunit, but allows parameter-level configuration of data generation. It allows you to quickly configure generators without using a custom GenFactory, or switching to LINQ-properties.

using GalaxyCheck;
using Xunit;

public class FizzBuzzTests
{
    private static IGen<int> MultipleOfThree => Gen.Int32().Select(x => x * 3);

    [Property]
    public void ItFizzes([MemberGen(nameof(MultipleOfThree))] int n)
    {
        Assert.Contains("Fizz", FizzBuzz(n));
    }
}

MemberGenAttribute is optional on parameters. If omitted, it will fall back to the default generation strategy.

Add Roslyn analyzers for statically checking the validity of a MemberGenAttribute

  • GalaxyCheckXunit1000: MemberGen must reference an existing member - (the member must exist in the test class)
  • GalaxyCheckXunit1001: MemberGen must reference a valid member type - (the member must be a field or a property)
  • GalaxyCheckXunit1002: MemberGen must reference a member providing a suitable data type - (the member must be of type IGen<T>, where T is the parameter type the attribute is decorating)

Add Roslyn code-refactoring provider for generating MemberGenAttributes

The code refactor will interpret the type of parameter that the cursor is over, and produce a generator inside the class that'll provide a good starting point for further configuration.

membergen

Improves Property.Precondition

Property.Precondition is a quick and dirty way to filter input to a property that you can add inside it's body. It's similar to Gen.Where, but it has a few limitations. However, a lot of the time, it's just what you need.

For example, consider the property:

[Property]
public void DifferentIntegersHashDifferently(int x, int y)
{
    Assert.NotEqual(Hash(x), Hash(y));
}

This property will almost certainly fail, as early on in testing a property, GalaxyCheck has a high chance of generating the minimum value (e.g. 0), and later on, it has a reasonably chance of generating the maximum value (e.g. int.MaxValue). The chance of collision over a 100 iterations of a test becomes extremely high. One way to fix that is to couple the generation of the integers together, like so:

private static IGen<(int x, int y)> TwoDistinctIntegers =>
    from x in Gen.Int32()
    from y in Gen.Int32()
    where x != y
    select (x, y);

[Property]
public void DifferentIntegersHashDifferently([MemberGen(nameof(TwoDistinctIntegers))] (int x, int y) tupleOfInts)
{
    Assert.NotEqual(Hash(tupleOfInts.x), Hash(tupleOfInts.y));
}

This is reasonably verbose - and quite a disruptive iteration on the test.

Property.Precondition allows you augment the existing test slightly to provide that filter, rather than modifying the whole generation:

[Property]
public void DifferentIntegersHashDifferently(int x, int y)
{
    Property.Precondition(x != y);

    Assert.NotEqual(Hash(x), Hash(y));
}

This release improves Property.Precondition so it behaves slightly more like Gen.Where. Whilst some of the limitations between it and Gen.Where are impossible to resolve (mostly, because GalaxyCheck has no insight into what and why the values are filtered), it improves the usability a fair bit, such that:

  • GalaxyCheck will give up after a certain amount of effort trying to generate parameters that don't seem to ever fulfil the precondition.
  • GalaxyCheck will try and generate "bigger" data, if smaller data is not fulfilling the precondition. That means it can retry its way out of preconditions like x > 100.

BREAKING: Simplified some of the information returned by Property.Check

This change has a very low-chance of being breaking in reality, but some of the properties on the CheckResult were trimmed down, somewhat.

0.5.0

18 Nov 19:15
Compare
Choose a tag to compare

BREAKING: Fix Gen.Byte().GreaterThan() types

This method was erroneously accepting an int, rather than a byte. Fixed now.

Add Gen.Nullable<T>()

Added a higher-order generator which takes a generator of any reference type, and returns a generator that produces values from the source generator, or produces nulls.

Gen.Nullable(Gen.String()); // "a", "aa", "a ", null, "ab" ...
Gen.String().OrNull(); // alternative syntax 

Gen.Create() now handles IEnumerables

IEnumerable<T> is now wired up to the reflection-based generator, Gen.Create<T>(). At the moment, it produces values that are lists of a limited size, but in the future, we may decide to leverage Gen.Infinite<T> - the generator which produces IEnumerable<T>s of infinite size.

That means that we can generate structures like this:

public class House
{
    public Address Address { get; set; }

    public IEnumerable<Room> Rooms { get; set; } // Previously this property was unsupported
}

Gen.Create<House>();

It also means IEnumerables are now supported in injected properties:

[Property]
public void SortIdempotency(IEnumerable<int> xs)
{
    Assert.Equal(xs.Sort(), xs.Sort().Sort());
}

GreaterThan()/LessThan() integer-generating builder methods now error on numeric overflow

Previously, a generator defined as Gen.Int32().GreaterThan(int.MaxValue) would silently cause a numeric overflow, and create a generator equivalent to Gen.Int32().GreaterThanEqual(int.MinValue).

Now, GalaxyCheck detects overflow in these methods, and will produce an error instead.

This is currently supported for the generators Gen.Byte(), Gen.Int16(), Gen.Int32(), Gen.Int64(). In the future, other (less likely to overflow) methods will have similar checks, such as Gen.String().WithCountGreaterThan().

Protect the inferred maximum count of the List<T> generator from overflowing

When you provide the list generator a really big minimum, and an unconstrained maximum e.g. Gen.List().WithCountGreaterThanEqual(int.MaxValue), it would previously return the error Error while running generator ListGen: 'maxCount' cannot be negative. This is because, if unspecified, internally in the generator, we infer the maxCount to be minCount + 20, and we weren't checking for integer overflow.

Now, we clamp the maxCount to int.MaxValue to prevent overflow. Out-of-the-box, this will result in a much clearer error message:

GalaxyCheck.Exceptions+GenErrorException : Error while running generator ListGen: Count limit exceeded. This is a built-in safety mechanism to prevent hanging tests. If generating a list with over 1000 elements was intended, relax this constraint by calling IListGen.DisableCountLimitUnsafe().

Generating a list with int.MaxValue items is probably not intended, so the error now gives a better hint towards what has gone wrong.