Skip to content

Commit

Permalink
Merge pull request #18 from luboshl/fix/nullable-propert-without-setter
Browse files Browse the repository at this point in the history
Fix getting nullability info for property with getter only
  • Loading branch information
luboshl authored Jul 26, 2024
2 parents a8a79c3 + 72908ad commit f877fe7
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>

<PropertyGroup>
<VersionPrefix>1.2.0</VersionPrefix>
<VersionPrefix>1.2.1</VersionPrefix>
<!-- VersionSuffix used for local builds -->
<VersionSuffix>dev</VersionSuffix>
<!-- VersionSuffix to be used for CI builds -->
Expand Down
2 changes: 1 addition & 1 deletion src/MiniValidationPlus/NonNullablePropertyHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public bool IsNonNullableReferenceType(PropertyInfo propertyInfo)
}

var nullabilityInfo = nullabilityContext.Create(propertyInfo);
return nullabilityInfo.WriteState is not NullabilityState.Nullable;
return nullabilityInfo.ReadState is not NullabilityState.Nullable;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void IsNonNullableReferenceType_Identifies_Correct_Properties_Of_Class()
Assert.Contains(nameof(ClassModel.IntNullable), other);
Assert.Contains(nameof(ClassModel.StringNullable), other);
Assert.Contains(nameof(ClassModel.AnotherNullable), other);
Assert.Contains(nameof(ClassModel.StringNullableWithoutSetter), other);
}

[Fact]
Expand Down Expand Up @@ -70,12 +71,14 @@ public void IsNonNullableReferenceType_Identifies_Correct_Properties_Of_Record()
Assert.Contains(nameof(RecordModel.AnotherNullable), other);
}

[SuppressMessage("ReSharper", "UnassignedGetOnlyAutoProperty")]
private class ClassModel
{
public int IntNonNullable { get; set; }
public int? IntNullable { get; set; }
public string StringNonNullable { get; set; } = null!;
public string? StringNullable { get; set; }
public string? StringNullableWithoutSetter { get; }
public AnotherModel AnotherNonNullable { get; set; } = new();
public AnotherModel? AnotherNullable { get; set; }
}
Expand Down
27 changes: 26 additions & 1 deletion tests/MiniValidationPlus.UnitTests/TestTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -284,4 +284,29 @@ class TestTypeForTypeDescriptor

[MaxLength(1)]
public string? AnotherProperty { get; set; } = "Test";
}
}

class TestTypeWithPropertiesWithoutSetter
{
public string NonNullableString { get; }

public string? NullableString { get; }

[Required(AllowEmptyStrings = false)]
public string RequiredNonNullableString { get; }

[Required(AllowEmptyStrings = false)]
public string? RequiredNullableString { get; }

public TestTypeWithPropertiesWithoutSetter(
string nonNullableString = "Default",
string? nullableString = "Default",
string requiredNonNullableString = "Default",
string? requiredNullableString = "Default")
{
NonNullableString = nonNullableString;
NullableString = nullableString;
RequiredNonNullableString = requiredNonNullableString;
RequiredNullableString = requiredNullableString;
}
}
132 changes: 132 additions & 0 deletions tests/MiniValidationPlus.UnitTests/TryValidate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,138 @@ public void NonNullable_Invalid_When_Null_On_Record()
Assert.False(result);
Assert.Single(errors);
}

[Fact]
public void PropertyWithoutSetter_NonNullable_Valid_When_NonEmpty()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(nonNullableString: "test");

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.True(result);
Assert.Empty(errors);
}

[Fact]
public void PropertyWithoutSetter_NonNullable_Valid_When_Empty()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(nonNullableString: string.Empty);

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.True(result);
Assert.Empty(errors);
}

[Fact]
public void PropertyWithoutSetter_NonNullable_Invalid_When_Null()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(nonNullableString: null!);

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.False(result);
Assert.Single(errors);
}

[Fact]
public void PropertyWithoutSetter_Nullable_Valid_When_NonEmpty()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(nullableString: "test");

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.True(result);
Assert.Empty(errors);
}

[Fact]
public void PropertyWithoutSetter_Nullable_Valid_When_Empty()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(nullableString: string.Empty);

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.True(result);
Assert.Empty(errors);
}

[Fact]
public void PropertyWithoutSetter_Nullable_Valid_When_Null()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(nullableString: null!);

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.True(result);
Assert.Empty(errors);
}

[Fact]
public void PropertyWithoutSetter_RequiredNonNullable_Valid_When_NonEmpty()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(requiredNonNullableString: "test");

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.True(result);
Assert.Empty(errors);
}

[Fact]
public void PropertyWithoutSetter_RequiredNonNullable_Invalid_When_Empty()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(requiredNonNullableString: string.Empty);

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.False(result);
Assert.Single(errors);
}

[Fact]
public void PropertyWithoutSetter_RequiredNonNullable_Invalid_When_Null()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(requiredNonNullableString: null!);

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.False(result);
Assert.Single(errors);
}

[Fact]
public void PropertyWithoutSetter_RequiredNullable_Valid_When_NonEmpty()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(requiredNullableString: "test");

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.True(result);
Assert.Empty(errors);
}

[Fact]
public void PropertyWithoutSetter_RequiredNullable_Invalid_When_Empty()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(requiredNullableString: string.Empty);

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.False(result);
Assert.Single(errors);
}

[Fact]
public void PropertyWithoutSetter_RequiredNullable_Invalid_When_Null()
{
var thingToValidate = new TestTypeWithPropertiesWithoutSetter(requiredNullableString: null!);

var result = MiniValidatorPlus.TryValidate(thingToValidate, out var errors);

Assert.False(result);
Assert.Single(errors);
}
#endif

[Fact]
Expand Down

0 comments on commit f877fe7

Please sign in to comment.