Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 2 additions & 2 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<PackageVersion Include="MinVer" Version="6.0.0" />

<!-- Generator dependencies -->
<PackageVersion Include="XmlSchemaClassGenerator-beta" Version="99.0.8-local" />
<PackageVersion Include="XmlSchemaClassGenerator.Analyzer" Version="99.0.8-local" />
<PackageVersion Include="XmlSchemaClassGenerator-beta" Version="99.0.9-local" />
<PackageVersion Include="XmlSchemaClassGenerator.Analyzer" Version="99.0.9-local" />
<PackageVersion Include="System.CommandLine" Version="2.0.2" />

<!-- Test dependencies -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,6 @@ public void Should_serialize_and_deserialize_parking_with_typed_enum_list()
deserialized.ParkingPaymentProcess[1].Should().Be(ParkingPaymentProcessEnumeration.PayByMobileDevice);
}



[Test]
public void Should_serialize_and_deserialize_optional_element_with_default_value_to_nullable_property_with_fallback_default()
{
Expand Down Expand Up @@ -267,4 +265,65 @@ public void Should_have_xml_root_attribute_on_publication_delivery_structure()
xmlRootAttr.ElementName.Should().Be("PublicationDelivery");
xmlRootAttr.Namespace.Should().Be("http://www.netex.org.uk/netex");
}

/// <summary>
/// PublicationDeliveryStructure.Version defaults to "1.0" via backing field initialization.
/// With <c>[DefaultValueAttribute]</c> suppressed on <c>string?</c> properties,
/// <c>XmlSerializer</c> must include the default value in the serialized XML.
/// </summary>
[Test]
public void Should_serialize_default_string_value_when_property_is_left_as_default()
{
// arrange
var serializer = new XmlSerializer(typeof(PublicationDeliveryStructure));
var original = new PublicationDeliveryStructure
{
PublicationTimestamp = DateTimeOffset.UtcNow,
ParticipantRef = "test",
};

// act
using var writer = new StringWriter();
serializer.Serialize(writer, original);
var xml = writer.ToString();

using var reader = new StringReader(xml);
var deserialized = serializer.Deserialize(reader) as PublicationDeliveryStructure;

// assert
xml.Should().Contain("version=\"1.0\"");
deserialized.Should().NotBeNull();
deserialized.Version.Should().Be("1.0");
}

/// <summary>
/// Even when PublicationDeliveryStructure.Version is explicitly set to the default value of "1.0",
/// it should still be serialized in the XML since the [DefaultValue] attribute is suppressed on nullable string
/// properties to avoid unintended consequences of the serializer omitting elements with default values.
/// </summary>
[Test]
public void Should_serialize_default_string_value_when_property_is_explicitly_set_to_default()
{
// arrange
var serializer = new XmlSerializer(typeof(PublicationDeliveryStructure));
var original = new PublicationDeliveryStructure
{
PublicationTimestamp = DateTimeOffset.UtcNow,
ParticipantRef = "test",
Version = "1.0",
};

// act
using var writer = new StringWriter();
serializer.Serialize(writer, original);
var xml = writer.ToString();

using var reader = new StringReader(xml);
var deserialized = serializer.Deserialize(reader) as PublicationDeliveryStructure;

// assert
xml.Should().Contain("version=\"1.0\"");
deserialized.Should().NotBeNull();
deserialized.Version.Should().Be("1.0");
}
}
18 changes: 16 additions & 2 deletions src/netex/Spillgebees.NeTEx.Models.Tests/XsdTypeMappingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public void Should_generate_default_value_for_xsd_default_version_attribute()
}

[Test]
public void Should_have_default_value_attribute_on_version_property()
public void Should_not_have_default_value_attribute_on_nullable_string_property_with_xsd_default()
{
// arrange
var property = typeof(PublicationDeliveryStructure)
Expand All @@ -113,9 +113,23 @@ public void Should_have_default_value_attribute_on_version_property()
// act
var attr = property.GetCustomAttribute<DefaultValueAttribute>();

// assert
attr.Should().BeNull();
}

[Test]
public void Should_still_have_default_value_attribute_on_value_type_property_with_xsd_default()
{
// arrange
var property = typeof(DayTypeAssignmentVersionStructure)
.GetProperty(nameof(DayTypeAssignmentVersionStructure.IsAvailable))!;

// act
var attr = property.GetCustomAttribute<DefaultValueAttribute>();

// assert
attr.Should().NotBeNull();
attr!.Value.Should().Be("1.0");
attr!.Value.Should().Be(true);
}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,54 @@ public void Should_have_correct_xml_type_namespace_on_siri_types()
xmlTypeAttr.Should().NotBeNull();
xmlTypeAttr.Namespace.Should().Be("http://www.siri.org.uk/siri");
}

/// <summary>
/// Siri.Version defaults to "2.1" via backing field initialization.
/// With <c>[DefaultValueAttribute]</c> suppressed on <c>string?</c> properties,
/// <c>XmlSerializer</c> must include the default value in the serialized XML.
/// </summary>
[Test]
public void Should_serialize_default_string_value_when_property_is_left_as_default()
{
// arrange
var serializer = new XmlSerializer(typeof(Siri));
var original = new Siri();

// act
using var writer = new StringWriter();
serializer.Serialize(writer, original);
var xml = writer.ToString();

using var reader = new StringReader(xml);
var deserialized = serializer.Deserialize(reader) as Siri;

// assert
xml.Should().Contain("version=\"2.1\"");
deserialized.Should().NotBeNull();
deserialized.Version.Should().Be("2.1");
}

/// <summary>
/// Even when Siri.Version is explicitly set to the default value of "2.1", it should still be serialized in the XML since the [DefaultValue] attribute is suppressed on nullable string properties to avoid unintended consequences of the serializer omitting elements with default values.
/// </summary>
[Test]
public void Should_serialize_default_string_value_when_property_is_explicitly_set_to_default()
{
// arrange — explicitly setting Version to the same value as the XSD default
var serializer = new XmlSerializer(typeof(Siri));
var original = new Siri { Version = "2.1" };

// act
using var writer = new StringWriter();
serializer.Serialize(writer, original);
var xml = writer.ToString();

using var reader = new StringReader(xml);
var deserialized = serializer.Deserialize(reader) as Siri;

// assert
xml.Should().Contain("version=\"2.1\"");
deserialized.Should().NotBeNull();
deserialized.Version.Should().Be("2.1");
}
}
33 changes: 16 additions & 17 deletions src/siri/Spillgebees.SIRI.Models.Tests/XsdTypeMappingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void Should_generate_default_value_for_xsd_default_version_attribute()
}

[Test]
public void Should_have_default_value_attribute_on_siri_version_property()
public void Should_not_have_default_value_attribute_on_nullable_string_property_with_xsd_default()
{
// arrange
var property = typeof(Siri)
Expand All @@ -105,9 +105,23 @@ public void Should_have_default_value_attribute_on_siri_version_property()
// act
var attr = property.GetCustomAttribute<DefaultValueAttribute>();

// assert
attr.Should().BeNull();
}

[Test]
public void Should_still_have_default_value_attribute_on_value_type_property_with_xsd_default()
{
// arrange
var property = typeof(HalfOpenTimestampOutputRangeStructure)
.GetProperty(nameof(HalfOpenTimestampOutputRangeStructure.EndTimeStatus))!;

// act
var attr = property.GetCustomAttribute<DefaultValueAttribute>();

// assert
attr.Should().NotBeNull();
attr!.Value.Should().Be("2.1");
attr!.Value.Should().Be(EndTimeStatusEnumeration.Undefined);
}

[Test]
Expand All @@ -124,21 +138,6 @@ public void Should_generate_default_value_for_xsd_default_enum_property()
range.EndTimeStatus.Should().Be(EndTimeStatusEnumeration.Undefined);
}

[Test]
public void Should_have_default_value_attribute_on_enum_property()
{
// arrange
var property = typeof(HalfOpenTimestampOutputRangeStructure)
.GetProperty(nameof(HalfOpenTimestampOutputRangeStructure.EndTimeStatus))!;

// act
var attr = property.GetCustomAttribute<DefaultValueAttribute>();

// assert
attr.Should().NotBeNull();
attr!.Value.Should().Be(EndTimeStatusEnumeration.Undefined);
}

[Test]
public void Should_use_init_setter_on_collection_properties()
{
Expand Down