Skip to content

Commit 4dd7b01

Browse files
committed
šŸŒ #376 Fix conversion exception when a generator error couldn't be resolved
1 parent 44f7033 commit 4dd7b01

File tree

17 files changed

+237
-80
lines changed

17 files changed

+237
-80
lines changed

ā€Žsrc/GalaxyCheck.Tests.V3/DomainGen.csā€Ž

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,17 @@ from testFunction in TestFunctions.Nullary()
3535
public static Stable.IGen<int> Size() =>
3636
Stable.Gen.Int32().Between(GalaxyCheck.Gens.Parameters.Size.Zero.Value, GalaxyCheck.Gens.Parameters.Size.Max.Value);
3737

38-
public static Stable.IGen<int> Seed() => Stable.Gen.Int32();
38+
public static Stable.IGen<int> Seed() => Stable.Gen.Int32().NoShrink();
3939

4040
public static Stable.IGen<int?> SeedWaypoint() => Seed().OrNullStruct();
4141

4242
public static Stable.IGen<Property> ToProperty(this Stable.IGen<IGen<object>> metaGen) =>
4343
from gen in metaGen
4444
from testFunction in TestFunctions.Unary<object>()
4545
select new Property((IGen<Property.Test<object>>)Property.ForAll<object>(gen, testFunction));
46+
47+
public class SeedAttribute : Stable.GenAttribute
48+
{
49+
public override Stable.IGen Value => Seed();
50+
}
4651
}

ā€Žsrc/GalaxyCheck.Tests.V3/Features/Generators/Operators/AboutWhereOperator.csā€Ž

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ static void Test(int seed, int size)
1515
var filteredGen = baseGen.Where(testFunction);
1616

1717
// Act
18-
var sample = filteredGen.Sample(args => args with { Seed = seed, Size = size });
18+
var sample = filteredGen.SampleTraversal(args => args with { Seed = seed, Size = size });
1919

2020
// Assert
2121
sample.Should().OnlyContain(x => testFunction(x));
@@ -35,7 +35,7 @@ static void Test(int seed, int size)
3535
var filteredGen = baseGen.Where(testFunction);
3636

3737
// Act
38-
var act = () => filteredGen.Sample(args => args with { Seed = seed, Size = size });
38+
var act = () => filteredGen.SampleTraversal(args => args with { Seed = seed, Size = size });
3939

4040
// Assert
4141
act.Should().NotThrow<Exceptions.GenExhaustionException>();

ā€Žsrc/GalaxyCheck.Tests.V3/Features/Generators/Reflection/AboutDynamicGeneration.csā€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void ItCanGenerateTheType(Type type)
1616
var gen = Gen.Create(type);
1717

1818
// Act
19-
var sample = gen.Sample();
19+
var sample = gen.SampleTraversal();
2020

2121
// Assert
2222
sample.Should().AllBeAssignableTo(type);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
namespace GalaxyCheck.Tests.Features.Generators.Reflection.ObjectGraph;
2+
3+
public class AboutErrorReproduction
4+
{
5+
[Stable.Property]
6+
[InlineData(typeof(ExampleObjects.UnconstructableClass), "")]
7+
[InlineData(typeof(ClassWithNestedUnconstructableClass), " at path '$.Property'")]
8+
[InlineData(typeof(ClassWithNestedNullableUnconstructableClass), " at path '$.Property'")]
9+
[InlineData(typeof(List<ExampleObjects.UnconstructableClass>), " at path '$.[*]'")]
10+
public Stable.Property WhenTypeIsUnresolvable(Type type, string expectedPathDescription)
11+
{
12+
return Stable.Property.ForAll(DomainGen.Seed(), seed =>
13+
{
14+
// Arrange
15+
var gen = Gen.Create(type);
16+
17+
// Act
18+
var action = () => gen.Sample(args => args with { Seed = seed });
19+
20+
// Assert
21+
action
22+
.Should()
23+
.Throw<Exceptions.GenErrorException>()
24+
.WithGenErrorMessage($"could not resolve type '*'{expectedPathDescription}");
25+
});
26+
}
27+
28+
private class ClassWithNestedUnconstructableClass
29+
{
30+
public ExampleObjects.UnconstructableClass Property { get; set; } = null!;
31+
}
32+
33+
private class ClassWithNestedNullableUnconstructableClass
34+
{
35+
public ExampleObjects.UnconstructableClass? Property { get; set; } = null!;
36+
}
37+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
namespace GalaxyCheck.Tests.Features.Generators.Reflection.ObjectGraph;
2+
3+
public static class ExampleObjects
4+
{
5+
public class ClassWithFailingConstructor
6+
{
7+
private static readonly Exception _exception = new("Constructor failed");
8+
9+
public ClassWithFailingConstructor()
10+
{
11+
throw _exception;
12+
}
13+
}
14+
15+
public class ClassWithNestedFailingConstructor
16+
{
17+
public ClassWithFailingConstructor Property { get; set; } = null!;
18+
}
19+
20+
public class ClassWithArrayOfFailingConstructors
21+
{
22+
public ClassWithFailingConstructor[] Property { get; set; } = null!;
23+
}
24+
25+
public class ClassWithArrayOfNestedFailingConstructors
26+
{
27+
public ClassWithNestedFailingConstructor[] Property { get; set; } = null!;
28+
}
29+
30+
public class ClassWithFailingConstructorAsConstructorParameter
31+
{
32+
public ClassWithFailingConstructor Property { get; set; }
33+
34+
public ClassWithFailingConstructorAsConstructorParameter(ClassWithFailingConstructor property)
35+
{
36+
Property = property;
37+
}
38+
}
39+
40+
public class ClassWithNestedFailingConstructorAsConstructorParameter
41+
{
42+
public ClassWithNestedFailingConstructor Property { get; set; }
43+
44+
public ClassWithNestedFailingConstructorAsConstructorParameter(ClassWithNestedFailingConstructor property)
45+
{
46+
Property = property;
47+
}
48+
}
49+
50+
public class ClassWithOneProperty
51+
{
52+
public int Property { get; set; }
53+
}
54+
55+
public class ClassWithTwoProperties
56+
{
57+
public int Property1 { get; set; }
58+
public int Property2 { get; set; }
59+
}
60+
61+
public class ClassWithOneNestedProperty
62+
{
63+
public ClassWithOneProperty Property { get; set; } = null!;
64+
}
65+
66+
public abstract class UnconstructableClass
67+
{
68+
}
69+
}

ā€Žsrc/GalaxyCheck.Tests.V3/GalaxyCheck.Tests.V3.csprojā€Ž

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<ItemGroup>
1414
<PackageReference Include="FluentAssertions" Version="6.11.0" />
15-
<PackageReference Include="GalaxyCheck.Stable.Xunit" Version="0.0.0-5085494672" />
15+
<PackageReference Include="GalaxyCheck.Stable.Xunit" Version="0.0.0-5131115847" />
1616
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
1717
<PackageReference Include="Snapshooter.Xunit" Version="0.5.8" />
1818
<PackageReference Include="xunit" Version="2.4.2" />
@@ -31,8 +31,4 @@
3131
<ProjectReference Include="..\GalaxyCheck\GalaxyCheck.csproj" />
3232
</ItemGroup>
3333

34-
<ItemGroup>
35-
<Folder Include="IntegrationTests" />
36-
</ItemGroup>
37-
3834
</Project>

ā€Žsrc/GalaxyCheck.Tests.V3/TestProxy.csā€Ž

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public static CheckResult<object> Check(this PropertyProxy propertyProxy, Func<C
7575
/// Samples a generator by traversing the example space. This is useful to ensure that not only the produced value satisfies some invariant, but
7676
/// also all shrunk values.
7777
/// </summary>
78-
public static IReadOnlyCollection<T> Sample<T>(this IGen<T> gen, Func<SampleGenArgs, SampleGenArgs>? configure = null)
78+
public static IReadOnlyCollection<T> SampleTraversal<T>(this IGen<T> gen, Func<SampleGenArgs, SampleGenArgs>? configure = null)
7979
{
8080
var args = SampleGenArgs.Default;
8181
if (configure != null)
@@ -84,12 +84,26 @@ public static IReadOnlyCollection<T> Sample<T>(this IGen<T> gen, Func<SampleGenA
8484
}
8585

8686
return gen.Advanced
87-
.SampleOneExampleSpace(seed: args.Seed, size: args.Size)
87+
.SampleOneExampleSpace(seed: args.Seed, size: args.Size ?? 100)
8888
.Traverse()
8989
.Take(args.MaxSampleSize)
9090
.ToList();
9191
}
9292

93+
public static IReadOnlyCollection<T> Sample<T>(this IGen<T> gen, Func<SampleGenArgs, SampleGenArgs>? configure = null)
94+
{
95+
var args = SampleGenArgs.Default;
96+
if (configure != null)
97+
{
98+
args = configure(args);
99+
}
100+
101+
return gen
102+
.Sample(seed: args.Seed, size: args.Size ?? 100)
103+
.Take(args.MaxSampleSize)
104+
.ToList();
105+
}
106+
93107
public record CheckPropertyArgs(int Seed, int? Size, string? Replay)
94108
{
95109
public static CheckPropertyArgs Default { get; } = new(0, null, null);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using FluentAssertions.Specialized;
2+
3+
namespace GalaxyCheck.Tests.TestUtility;
4+
5+
public static class AssertionExtensions
6+
{
7+
public static ExceptionAssertions<Exceptions.GenErrorException> WithGenErrorMessage(
8+
this ExceptionAssertions<Exceptions.GenErrorException> assertions,
9+
string messageBody)
10+
{
11+
return assertions.WithMessage("Error during generation: " + messageBody);
12+
}
13+
}

ā€Žsrc/GalaxyCheck/Gens/FactoryGen.csā€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ protected override IGen<T> Get
229229
var context = ReflectedGenHandlerContext.Create(typeof(T), NullabilityInfo);
230230

231231
return ReflectedGenBuilder
232-
.Build(typeof(T), RegisteredGensByType, MemberOverrides, Error, context)
232+
.Build(typeof(T), RegisteredGensByType, MemberOverrides, context)
233233
.Cast<T>();
234234
}
235235
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
namespace GalaxyCheck.Gens.ReflectedGenHelpers
1+
using System;
2+
3+
namespace GalaxyCheck.Gens.ReflectedGenHelpers
24
{
35
internal delegate IGen ErrorFactory(string message);
4-
5-
internal delegate IGen ContextualErrorFactory(string message, ReflectedGenHandlerContext context);
66
}

0 commit comments

Comments
Ā (0)