Skip to content

Commit

Permalink
Fix to make required and nullable properties nullable in schema (#2879)
Browse files Browse the repository at this point in the history
Fix to make required and nullable properties nullable in schema.
- Added test for type with required nullable properties.
  • Loading branch information
keahpeters committed May 14, 2024
1 parent 8908e1e commit a29ba36
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,24 +68,13 @@ public SchemaGenerator(SchemaGeneratorOptions generatorOptions, ISerializerDataC
{
var requiredAttribute = customAttributes.OfType<RequiredAttribute>().FirstOrDefault();

schema.ReadOnly = dataProperty.IsReadOnly;
schema.WriteOnly = dataProperty.IsWriteOnly;

#if NET7_0_OR_GREATER
var hasRequiredMemberAttribute = customAttributes.OfType<System.Runtime.CompilerServices.RequiredMemberAttribute>().Any();

schema.Nullable = _generatorOptions.SupportNonNullableReferenceTypes
? dataProperty.IsNullable && requiredAttribute == null && !hasRequiredMemberAttribute && !memberInfo.IsNonNullableReferenceType()
: dataProperty.IsNullable && requiredAttribute == null && !hasRequiredMemberAttribute;

schema.MinLength = modelType == typeof(string) && (hasRequiredMemberAttribute || requiredAttribute is { AllowEmptyStrings: false }) ? 1 : null;
#else
schema.Nullable = _generatorOptions.SupportNonNullableReferenceTypes
? dataProperty.IsNullable && requiredAttribute==null && !memberInfo.IsNonNullableReferenceType()
: dataProperty.IsNullable && requiredAttribute==null;
? dataProperty.IsNullable && requiredAttribute == null && !memberInfo.IsNonNullableReferenceType()
: dataProperty.IsNullable && requiredAttribute == null;

schema.ReadOnly = dataProperty.IsReadOnly;
schema.WriteOnly = dataProperty.IsWriteOnly;
schema.MinLength = modelType == typeof(string) && requiredAttribute is { AllowEmptyStrings: false } ? 1 : null;
#endif
}

var defaultValueAttribute = customAttributes.OfType<DefaultValueAttribute>().FirstOrDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,10 @@ public void GenerateSchema_SetsReadOnlyAndWriteOnlyFlags_IfPropertyIsRestricted(
}

#if NET7_0_OR_GREATER
public class TypeWithRequiredProperty
public class TypeWithRequiredProperties
{
public required string RequiredProperty { get; set; }
public required string RequiredString { get; set; }
public required int RequiredInt { get; set; }
}

public class TypeWithRequiredPropertyAndValidationAttribute
Expand All @@ -383,10 +384,13 @@ public void GenerateSchema_SetsRequired_IfPropertyHasRequiredKeyword()
{
var schemaRepository = new SchemaRepository();

var referenceSchema = Subject().GenerateSchema(typeof(TypeWithRequiredProperty), schemaRepository);
var referenceSchema = Subject().GenerateSchema(typeof(TypeWithRequiredProperties), schemaRepository);

var schema = schemaRepository.Schemas[referenceSchema.Reference.Id];
Assert.Equal(new[] { "RequiredProperty" }, schema.Required.ToArray());
Assert.True(schema.Properties["RequiredString"].Nullable);
Assert.Contains("RequiredString", schema.Required.ToArray());
Assert.False(schema.Properties["RequiredInt"].Nullable);
Assert.Contains("RequiredInt", schema.Required.ToArray());
}

[Fact]
Expand All @@ -398,9 +402,31 @@ public void GenerateSchema_SetsRequired_IfPropertyHasRequiredKeywordAndValidatio

var schema = schemaRepository.Schemas[referenceSchema.Reference.Id];
Assert.Equal(1, schema.Properties["RequiredProperty"].MinLength);
Assert.False(schema.Properties["RequiredProperty"].Nullable);
Assert.True(schema.Properties["RequiredProperty"].Nullable);
Assert.Equal(new[] { "RequiredProperty" }, schema.Required.ToArray());
}

#nullable enable
public class TypeWithNullableReferenceTypes
{
public required string? RequiredNullableString { get; set; }
public required string RequiredNonNullableString { get; set; }
}

[Fact]
public void GenerateSchema_SetsRequiredAndNullable_IfPropertyHasRequiredKeywordAndIsNullable()
{
var schemaRepository = new SchemaRepository();

var referenceSchema = Subject(configureGenerator: (c) => c.SupportNonNullableReferenceTypes = true).GenerateSchema(typeof(TypeWithNullableReferenceTypes), schemaRepository);

var schema = schemaRepository.Schemas[referenceSchema.Reference.Id];
Assert.True(schema.Properties["RequiredNullableString"].Nullable);
Assert.Contains("RequiredNullableString", schema.Required.ToArray());
Assert.False(schema.Properties["RequiredNonNullableString"].Nullable);
Assert.Contains("RequiredNonNullableString", schema.Required.ToArray());
}
#nullable disable
#endif

[Theory]
Expand Down

0 comments on commit a29ba36

Please sign in to comment.