Files
RobustToolbox/Robust.Shared.IntegrationTests/Serialization/PropertyAndFieldDefinitionTest.cs
34ce2ba534 serv5 (#6496)
* Add source generator for DataDefinition validation

* Add source generator for reading

* Add source generator for writing

* Include prototypes and other meansdatadefinition types

* Target ISerializationGenerated in data definitions

* Murder

* Use array, struct, enum methods

* Source generate get field definitions

* serv5

* Fix and pray

* Fix release compile

* Tayrtahn review

* a

* Generator bugfix

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
2026-07-08 22:18:35 +10:00

136 lines
6.9 KiB
C#

using System.Linq;
using NUnit.Framework;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.Manager.Definition;
using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.Markdown.Value;
using Robust.Shared.Utility;
// ReSharper disable UnassignedGetOnlyAutoProperty
// ReSharper disable UnusedAutoPropertyAccessor.Global
namespace Robust.UnitTesting.Shared.Serialization
{
internal sealed partial class PropertyAndFieldDefinitionTest : OurSerializationTest
{
private const string GetOnlyPropertyName = "GetOnlyProperty";
private const string GetOnlyPropertyFieldTargetedName = "GetOnlyPropertyFieldTargeted";
private const string GetAndSetPropertyName = "GetAndSetProperty";
private const string FieldName = "Field";
private const string GetOnlyPropertyWithOtherAttributeFieldTargetedName =
"GetOnlyPropertyWithOtherAttributeFieldTargeted";
private const string GetOnlyPropertyFieldTargetedAndOtherAttributeName =
"GetOnlyPropertyFieldTargetedAndOtherAttribute";
[Test]
public void ParityTest()
{
var mapping = new MappingDataNode();
mapping.Add(GetOnlyPropertyName, new ValueDataNode("5"));
mapping.Add(GetOnlyPropertyFieldTargetedName, new ValueDataNode("10"));
mapping.Add(GetAndSetPropertyName, new ValueDataNode("15"));
mapping.Add(FieldName, new ValueDataNode("20"));
mapping.Add(GetOnlyPropertyWithOtherAttributeFieldTargetedName, new ValueDataNode("25"));
mapping.Add(GetOnlyPropertyFieldTargetedAndOtherAttributeName, new ValueDataNode("30"));
var definition = Serialization.Read<PropertyAndFieldDefinitionTestDefinition>(mapping, notNullableOverride: true);
Assert.That(definition, Is.Not.Null);
// Get only property with backing field, property targeted
Assert.That(definition!.GetOnlyProperty, Is.EqualTo(5));
var backingField = definition.GetType().GetBackingField(GetOnlyPropertyName);
Assert.That(backingField, Is.Not.Null);
var backingFieldValue = backingField!.GetValue(definition);
Assert.That(backingFieldValue, Is.EqualTo(5));
// Get only property with backing field, field targeted
Assert.That(definition.GetOnlyPropertyFieldTargeted, Is.EqualTo(10));
// Get and set property with backing field, property targeted
Assert.That(definition.GetAndSetProperty, Is.EqualTo(15));
// Field
Assert.That(definition.Field, Is.EqualTo(20));
// Get only property with backing field, property targeted with another attribute field targeted
Assert.That(definition.GetOnlyPropertyWithOtherAttributeFieldTargeted, Is.EqualTo(25));
var property = definition.GetType().GetProperty(GetOnlyPropertyWithOtherAttributeFieldTargetedName);
Assert.That(property, Is.Not.Null);
var propertyInfo = new SpecificPropertyInfo(property!);
Assert.That(propertyInfo.GetAttribute<DataFieldAttribute>(), Is.Not.Null);
Assert.That(propertyInfo.GetAttribute<AlwaysPushInheritanceAttribute>(), Is.Not.Null);
// We check for the property info properly finding field targeted attributes as
// well, otherwise we run the risk of the data field being targeted to the
// property but an additional attribute like AlwaysPushInheritance being targeted
// to the field, as was the case in EntityPrototype.
// And I don't want to debug that ever again.
Assert.That(propertyInfo.DeclaringType, Is.Not.Null);
var dataDefinition = ((SerializationManager) Serialization).GetDefinition(propertyInfo.DeclaringType!);
Assert.That(dataDefinition, Is.Not.Null);
var propertyDefinition =
dataDefinition!.BaseFieldDefinitions.Single(e => (e.Tag ?? e.CamelCasedName).Equals(GetOnlyPropertyWithOtherAttributeFieldTargetedName));
var inheritanceBehaviour = propertyDefinition.InheritanceBehavior;
Assert.That(inheritanceBehaviour, Is.EqualTo(InheritanceBehavior.Always));
// Get only property with backing field, field targeted with another attribute property targeted
Assert.That(definition.GetOnlyPropertyFieldTargetedAndOtherAttribute, Is.EqualTo(30));
property = definition.GetType().GetProperty(GetOnlyPropertyFieldTargetedAndOtherAttributeName);
Assert.That(property, Is.Not.Null);
propertyInfo = new SpecificPropertyInfo(property!);
// Data field is targeted to the backing field
Assert.That(propertyInfo.GetAttribute<DataFieldAttribute>(), Is.Not.Null);
Assert.That(propertyInfo.GetBackingField()!.GetAttribute<DataFieldAttribute>(), Is.Null);
Assert.That(propertyInfo.GetAttribute<DataFieldAttribute>(true), Is.Not.Null);
// NeverPushInheritanceAttribute is targeted to the property
Assert.That(propertyInfo.GetAttribute<NeverPushInheritanceAttribute>(), Is.Not.Null);
Assert.That(propertyInfo.GetBackingField()!.GetAttribute<NeverPushInheritanceAttribute>(), Is.Null);
Assert.That(propertyInfo.GetAttribute<NeverPushInheritanceAttribute>(true), Is.Not.Null);
propertyDefinition =
dataDefinition!.BaseFieldDefinitions.Single(e => (e.Tag ?? e.CamelCasedName).Equals(GetOnlyPropertyFieldTargetedAndOtherAttributeName));
inheritanceBehaviour = propertyDefinition.InheritanceBehavior;
dataDefinition = ((SerializationManager) Serialization).GetDefinition(property!.DeclaringType!);
Assert.That(dataDefinition, Is.Not.Null);
Assert.That(inheritanceBehaviour, Is.EqualTo(InheritanceBehavior.Never));
}
[DataDefinition]
internal sealed partial class PropertyAndFieldDefinitionTestDefinition
{
[DataField(GetOnlyPropertyName)]
public int GetOnlyProperty { get; private set; }
[DataField(GetOnlyPropertyFieldTargetedName)]
public int GetOnlyPropertyFieldTargeted { get; private set; }
[DataField(GetAndSetPropertyName)]
public int GetAndSetProperty { get; set; }
[DataField(FieldName)]
// ReSharper disable once UnassignedField.Global
public int Field;
[DataField(GetOnlyPropertyWithOtherAttributeFieldTargetedName)]
[AlwaysPushInheritance]
public int GetOnlyPropertyWithOtherAttributeFieldTargeted { get; private set; }
[DataField(GetOnlyPropertyFieldTargetedAndOtherAttributeName)]
[NeverPushInheritance]
public int GetOnlyPropertyFieldTargetedAndOtherAttribute { get; private set; }
}
}
}