Files
RobustToolbox/Robust.Shared.IntegrationTests/Serialization/PropertyAndFieldDefinitionTest.cs
T
PJB3005 788e9386fd Split up test project
Robust.UnitTesting was both ALL tests for RT, and also API surface for content tests.

Tests are now split into separate projects as appropriate, and the API side has also been split off.
2025-12-16 01:36:53 +01:00

138 lines
7.0 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 alwaysPushDataField = propertyInfo.GetAttribute<DataFieldAttribute>();
var propertyDefinition =
dataDefinition!.BaseFieldDefinitions.Single(e => e.Attribute.Equals(alwaysPushDataField));
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);
var neverPushDataField = propertyInfo.GetAttribute<DataFieldAttribute>();
propertyDefinition =
dataDefinition!.BaseFieldDefinitions.Single(e => e.Attribute.Equals(neverPushDataField));
inheritanceBehaviour = propertyDefinition.InheritanceBehavior;
dataDefinition = ((SerializationManager) Serialization).GetDefinition(property!.DeclaringType!);
Assert.That(dataDefinition, Is.Not.Null);
Assert.That(inheritanceBehaviour, Is.EqualTo(InheritanceBehavior.Never));
}
[Robust.Shared.Serialization.Manager.Attributes.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; }
}
}
}