Skip to content

Commit

Permalink
Fix snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
SteveDunn committed Sep 9, 2024
1 parent 3087943 commit ded2dba
Show file tree
Hide file tree
Showing 12 changed files with 4,607 additions and 273 deletions.
91 changes: 37 additions & 54 deletions samples/Vogen.Examples/TypicalScenarios/NullableExamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// ReSharper disable ClassNeverInstantiated.Global



// ReSharper disable RedundantNullableDirective

using System;
Expand All @@ -32,11 +31,6 @@ public Task Run()

void NullableDisabledClassValueObjectWrappingAnInt()
{
// Error CS1503 : Argument 1: cannot convert from '<null>' to 'int'
// Even though nullability was disabled, because it wraps an int, we can pass null.
// _ = NullableDisabledClassWrappingInt.From(null);
_ = NullableDisabledClassWrappingInt.TryFrom(null);

var nd1 = NullableDisabledClassWrappingInt.From(1);
var nd2 = NullableDisabledClassWrappingInt.From(2);

Expand All @@ -47,7 +41,7 @@ void NullableDisabledClassValueObjectWrappingAnInt()
// Even though we turned off nullability for this value object, the signatures for some methods
// are 'hoisted' from the primitive.
// _ = NullableDisabledClassWrappingInt.TryParse((string)null, out _);

_ = nd1.CompareTo(null);

_ = nd1.Equals(null as object);
Expand All @@ -60,11 +54,6 @@ void NullableDisabledClassValueObjectWrappingAnInt()

void NullableEnabledClassValueObjectWrappingAnInt()
{
// Error CS1503 : Argument 1: cannot convert from '<null>' to 'int'
// Even though nullability was disabled, because it wraps an int, we can pass null.
// NullableEnabledClassWrappingInt.From(null);
// NullableEnabledClassWrappingInt.TryFrom(null);

var nd1 = NullableEnabledClassWrappingInt.From(1);
var nd2 = NullableEnabledClassWrappingInt.From(2);

Expand All @@ -76,7 +65,7 @@ void NullableEnabledClassValueObjectWrappingAnInt()
// Even though we turned off nullability for this value object, the signatures for some methods
// are 'hoisted' from the primitive.
// _ = NullableEnabledClassWrappingInt.TryParse((string)null, out _);

_ = nd1.CompareTo(null);

_ = nd1.Equals(null);
Expand All @@ -88,11 +77,6 @@ void NullableEnabledClassValueObjectWrappingAnInt()

void NullableDisabledStructValueObjectWrappingAnInt()
{
// Error CS1503 : Argument 1: cannot convert from '<null>' to 'int'
// Even though nullability was disabled, because it wraps an int, we can pass null.
// _ = NullableDisabledStructWrappingInt.From(null);
// NullableDisabledStructWrappingInt.TryFrom(null);

var nd1 = NullableDisabledStructWrappingInt.From(1);
var nd2 = NullableDisabledStructWrappingInt.From(2);

Expand All @@ -103,26 +87,20 @@ void NullableDisabledStructValueObjectWrappingAnInt()
// Even though we turned off nullability for this value object, the signatures for some methods
// are 'hoisted' from the primitive.
// _ = NullableDisabledStructWrappingInt.TryParse((string)null, out _);

_ = nd1.CompareTo(null);

_ = nd1.Equals(null);

_ = nd1 == nd2;
_ = nd1 == 1;

// makes no sense to compare to null as it's a struct, resulting in Error CS8073 : The result of the expression is always 'false'
// _ = nd1 == null;
}

void NullableEnabledStructValueObjectWrappingAnInt()
{
// Error CS1503 : Argument 1: cannot convert from '<null>' to 'int'
// Even though nullability was enabled, because the value object itself
// is a class, we still get CS1503
// NullableEnabledStructWrappingInt.From(null);
// NullableEnabledStructWrappingInt.TryFrom(null);

var nd1 = NullableEnabledStructWrappingInt.From(1);
var nd2 = NullableEnabledStructWrappingInt.From(2);

Expand All @@ -134,7 +112,7 @@ void NullableEnabledStructValueObjectWrappingAnInt()
// Even though we turned off nullability for this value object, the signatures for some methods
// are 'hoisted' from the primitive.
// _ = NullableEnabledStructWrappingInt.TryParse((string)null, out _);

_ = nd1.CompareTo(null);

_ = nd1.Equals(null);
Expand All @@ -149,12 +127,12 @@ void NullableDisabledClassValueObjectWrappingAString()
{
// No issues - we've disabled null when creating this value object, so no warnings
NullableDisabledClassWrappingString c1 = NullableDisabledClassWrappingString.From(null);

// CS8600 - even though nullability is disabled, the `MaybeNullWhen` creates the error.
// _ = NullableDisabledClassWrappingString.TryFrom(null, out NullableDisabledClassWrappingString c2);

Console.WriteLine(c1.Value); // NullReferenceException

var nd1 = NullableDisabledClassWrappingString.From("1");
var nd2 = NullableDisabledClassWrappingString.From("2");

Expand All @@ -167,7 +145,7 @@ void NullableDisabledClassValueObjectWrappingAString()
// Even though we turned off nullability for this value object, the signatures for some methods
// are 'hoisted' from the primitive.
// _ = NullableDisabledClassWrappingString.TryParse((string)null, out _);

_ = nd1.CompareTo(null);

// not marked as nullable
Expand All @@ -187,13 +165,13 @@ void NullableEnabledClassValueObjectWrappingAString()
{
// CS8625 - cannot provide null as nullability is enabled in the generated value object
// NullableEnabledClassWrappingString c1 = NullableEnabledClassWrappingString.From(null);

// CS8600 - needs nullable
// _ = NullableEnabledClassWrappingString.TryFrom(null, out NullableEnabledClassWrappingString c2);

// OK
_ = NullableEnabledClassWrappingString.TryFrom(null, out NullableEnabledClassWrappingString? _);

var vo1 = NullableEnabledClassWrappingString.From("1");
var vo2 = NullableEnabledClassWrappingString.From("2");

Expand All @@ -202,17 +180,17 @@ void NullableEnabledClassValueObjectWrappingAString()

// OK
_ = NullableEnabledClassWrappingString.TryParse(null, CultureInfo.InvariantCulture, out _);

// CS8602 dereference of possibly null reference
// Console.WriteLine(r.Value);

_ = vo1.CompareTo(null);

// not marked as nullable
_ = vo1.Equals(null as string);

// CS8600 - as not marked as nullable

//OK
_ = vo1.Equals(null as string);
_ = vo1.Equals(null as NullableEnabledClassWrappingString);
Expand All @@ -229,13 +207,13 @@ void NullableEnabledStructValueObjectWrappingString()
{
// CS8625 - cannot provide null as nullability is enabled in the generated value object
// NullableEnabledStructWrappingString c1 = NullableEnabledStructWrappingString.From(null);

// CS8600 - needs nullable
// _ = NullableEnabledStructWrappingString.TryFrom(null, out NullableEnabledStructWrappingString c2);

// OK - nullable not needed because the value object is a value type
_ = NullableEnabledStructWrappingString.TryFrom(null, out NullableEnabledStructWrappingString _);

var vo1 = NullableEnabledStructWrappingString.From("1");
var vo2 = NullableEnabledStructWrappingString.From("2");

Expand All @@ -244,7 +222,7 @@ void NullableEnabledStructValueObjectWrappingString()

// OK
_ = NullableEnabledStructWrappingString.TryParse(null, CultureInfo.InvariantCulture, out _);

_ = vo1.CompareTo(null);

// marked as nullable
Expand All @@ -264,10 +242,10 @@ void NullableDisabledStructValueObjectWrappingString()
{
// OK - even though nullability is disabled, the
_ = NullableDisabledStructWrappingString.From(null);

// OK
_ = NullableDisabledStructWrappingString.TryFrom(null, out NullableDisabledStructWrappingString _);

var vo1 = NullableDisabledStructWrappingString.From("1");
var vo2 = NullableDisabledStructWrappingString.From("2");

Expand All @@ -276,17 +254,17 @@ void NullableDisabledStructValueObjectWrappingString()

// OK
_ = NullableDisabledStructWrappingString.TryParse(null, CultureInfo.InvariantCulture, out _);

// CS8602 dereference of possibly null reference
// Console.WriteLine(r.Value);

_ = vo1.CompareTo(null);

// not marked as nullable
_ = vo1.Equals(null);

// CS8600 - as not marked as nullable

//OK
_ = vo1.Equals(null);
_ = vo1.Equals(null as object);
Expand All @@ -301,32 +279,37 @@ void NullableDisabledStructValueObjectWrappingString()
}

#nullable disable
[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)]
[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)]
public partial class NullableDisabledClassWrappingInt;

[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)]
[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)]
public partial struct NullableDisabledStructWrappingInt;

[ValueObject<string>(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, parsableForStrings: GenerateMethodsAndInterface)]
[ValueObject<string>(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces,
parsableForStrings: GenerateMethodsAndInterface)]
public partial class NullableDisabledClassWrappingString;

[ValueObject<string>(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, parsableForStrings: GenerateMethodsAndInterface)]
[ValueObject<string>(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces,
parsableForStrings: GenerateMethodsAndInterface)]
public partial struct NullableDisabledStructWrappingString;

#nullable restore


#nullable enable

[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)]
[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)]
public partial class NullableEnabledClassWrappingInt;

[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)]
[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)]
public partial struct NullableEnabledStructWrappingInt;

[ValueObject<string>(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, parsableForStrings: GenerateMethodsAndInterface)]
[ValueObject<string>(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces,
parsableForStrings: GenerateMethodsAndInterface)]
public partial class NullableEnabledClassWrappingString;

[ValueObject<string>(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, parsableForStrings: GenerateMethodsAndInterface)]
[ValueObject<string>(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces,
parsableForStrings: GenerateMethodsAndInterface)]
public partial struct NullableEnabledStructWrappingString;

#nullable restore
1 change: 0 additions & 1 deletion samples/Vogen.Examples/Vogen.Examples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>NULLABLE_ENABLED_BUILD</DefineConstants>
<Nullable>enable</Nullable>
</PropertyGroup>

Expand Down
3 changes: 2 additions & 1 deletion src/Vogen/GenerateCodeForTryParse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,14 @@ private static void BuildHoistedTryParseMethod(IMethodSymbol methodSymbol, Strin

private static string GenerateCallToValidationIfNeeded(VoWorkItem workItem, string parameterName)
{
string bangForWrapper = workItem.Nullable.BangForWrapper;
if (workItem.ValidateMethod is not null)
{
return $$"""
var validation = {{workItem.TypeToAugment.Identifier}}.{{workItem.ValidateMethod.Identifier.Value}}({{parameterName}});
if (validation != Vogen.Validation.Ok)
{
result = default;
result = default{{bangForWrapper}};
return false;
}

Expand Down
38 changes: 30 additions & 8 deletions tests/SnapshotTests/GeneralStuff/GeneralTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,13 @@ public async Task Nullable_enabled_if_set_in_scope(string type)
{
var source =
$$"""
#nullable enable

using System;
using Vogen;

public class C<T>
{
}

#nullable enable
[ValueObject<C<int>>]
[ValueObject]
public partial {{type}} MyVo;

#nullable restore
""";

await new SnapshotRunner<ValueObjectGenerator>()
Expand All @@ -64,6 +59,33 @@ public class C<T>
.RunOn(TargetFramework.Net8_0);
}

[Theory]
[InlineData("struct")]
[InlineData("class")]
[InlineData("record struct")]
[InlineData("record class")]
public async Task Nullable_try_parse_if_validation_supplied(string type)
{
var source =
$$"""
#nullable enable

using System;
using Vogen;

[ValueObject]
public partial {{type}} MyVo
{
private static Validation Validate(int value) => value > 0 ? Validation.Ok : Validation.Invalid("Must be > 0");
}
""";

await new SnapshotRunner<ValueObjectGenerator>()
.WithSource(source)
.CustomizeSettings(s => s.UseFileName(TestHelper.ShortenForFilename($"{nameof(Nullable_try_parse_if_validation_supplied)}{type}")))
.RunOn(TargetFramework.Net8_0);
}

[Fact]
public async Task Can_specify_a_generic_underlying()
{
Expand Down
Loading

0 comments on commit ded2dba

Please sign in to comment.