using System.Collections.Generic;
using NUnit.Framework;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.Markdown.Sequence;
namespace Robust.UnitTesting.Shared.Serialization;
///
/// Tests that arrays and lists of virtual/abstract objects can be properly serialized and deserialized.
///
public sealed partial class VirtualObjectArrayTest : SerializationTest
{
[ImplicitDataDefinitionForInheritors]
private abstract partial class BaseTestDataDef { }
private sealed partial class SealedTestDataDef : BaseTestDataDef { }
[Virtual]
private partial class VirtualTestDataDef : BaseTestDataDef { }
private sealed partial class ChildTestDef : VirtualTestDataDef { }
[Test]
public void SerializeVirtualObjectArrayTest()
{
var sequence = new SequenceDataNode
{
new MappingDataNode {Tag = $"!type:SealedTestDataDef"},
new MappingDataNode {Tag = $"!type:VirtualTestDataDef"},
new MappingDataNode {Tag = $"!type:ChildTestDef"}
};
{
// Deserialize the above yaml
var arr = Serialization.Read(sequence, notNullableOverride: true);
// Ensure that the !type: tags were properly parsed
Assert.That(arr[0], Is.TypeOf(typeof(SealedTestDataDef)));
Assert.That(arr[1], Is.TypeOf(typeof(VirtualTestDataDef)));
Assert.That(arr[2], Is.TypeOf(typeof(ChildTestDef)));
// Write the parsed object back to yaml
var newSquence = Serialization.WriteValue(arr, notNullableOverride: true);
// Check that the yaml doesn't differ in any way.
var diff = newSquence.Except(sequence);
Assert.That(diff, Is.Null);
// And finally, double check that the serialized data can be re-deserialized (dataNode.Except isn't perfect).
arr = Serialization.Read(newSquence, notNullableOverride: true);
Assert.That(arr[0], Is.TypeOf(typeof(SealedTestDataDef)));
Assert.That(arr[1], Is.TypeOf(typeof(VirtualTestDataDef)));
Assert.That(arr[2], Is.TypeOf(typeof(ChildTestDef)));
}
// Repeat the above, but using lists instead of arrays
{
var list = Serialization.Read>(sequence, notNullableOverride: true);
Assert.That(list[0], Is.TypeOf(typeof(SealedTestDataDef)));
Assert.That(list[1], Is.TypeOf(typeof(VirtualTestDataDef)));
Assert.That(list[2], Is.TypeOf(typeof(ChildTestDef)));
var newSquence = Serialization.WriteValue(list, notNullableOverride: true);
var diff = newSquence.Except(sequence);
Assert.That(diff, Is.Null);
list = Serialization.Read>(sequence, notNullableOverride: true);
Assert.That(list[0], Is.TypeOf(typeof(SealedTestDataDef)));
Assert.That(list[1], Is.TypeOf(typeof(VirtualTestDataDef)));
Assert.That(list[2], Is.TypeOf(typeof(ChildTestDef)));
}
// remove the first entry -- leave only entries that inherit from VirtualTestDataDef
sequence.RemoveAt(0);
// When writing, this will skip the !type tag for the first entry
var expectedSequence = new SequenceDataNode
{
new MappingDataNode(),
new MappingDataNode {Tag = $"!type:ChildTestDef"}
};
{
var virtArr = Serialization.Read(sequence, notNullableOverride: true);
Assert.That(virtArr[0], Is.TypeOf(typeof(VirtualTestDataDef)));
Assert.That(virtArr[1], Is.TypeOf(typeof(ChildTestDef)));
// The old sequence will now differ as it should not write the redundant !type tag
var newSquence = Serialization.WriteValue(virtArr, notNullableOverride: true);
var diff = newSquence.Except(sequence);
Assert.That(diff, Is.Not.Null);
diff = newSquence.Except(expectedSequence);
Assert.That(diff, Is.Null);
virtArr = Serialization.Read(newSquence, notNullableOverride: true);
Assert.That(virtArr[0], Is.TypeOf(typeof(VirtualTestDataDef)));
Assert.That(virtArr[1], Is.TypeOf(typeof(ChildTestDef)));
}
// And again, repeat for lists instead of arrays
{
var virtList = Serialization.Read>(sequence, notNullableOverride: true);
Assert.That(virtList[0], Is.TypeOf(typeof(VirtualTestDataDef)));
Assert.That(virtList[1], Is.TypeOf(typeof(ChildTestDef)));
var newSquence = Serialization.WriteValue(virtList, notNullableOverride: true);
var diff = newSquence.Except(sequence);
Assert.That(diff, Is.Not.Null);
diff = newSquence.Except(expectedSequence);
Assert.That(diff, Is.Null);
virtList = Serialization.Read>(newSquence, notNullableOverride: true);
Assert.That(virtList[0], Is.TypeOf(typeof(VirtualTestDataDef)));
Assert.That(virtList[1], Is.TypeOf(typeof(ChildTestDef)));
}
}
}