mirror of
https://github.com/dcronqvist/DotTiled.git
synced 2025-05-09 13:56:03 +03:00
Move test data and current tests into UnitTests
This commit is contained in:
parent
0a77a9fec7
commit
d23eec4433
67 changed files with 55 additions and 65 deletions
317
src/DotTiled.Tests/UnitTests/OptionalTests.cs
Normal file
317
src/DotTiled.Tests/UnitTests/OptionalTests.cs
Normal file
|
@ -0,0 +1,317 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public class OptionalTests
|
||||
{
|
||||
// Constructor Tests
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithNonNullValue_ShouldSetHasValueToTrue()
|
||||
{
|
||||
// Arrange
|
||||
string expectedValue = "test";
|
||||
|
||||
// Act
|
||||
var optional = new Optional<string>(expectedValue);
|
||||
|
||||
// Assert
|
||||
Assert.True(optional.HasValue);
|
||||
Assert.Equal(expectedValue, optional.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_WithNullValue_ShouldSetHasValueToTrue()
|
||||
{
|
||||
// Arrange
|
||||
string expectedValue = null;
|
||||
|
||||
// Act
|
||||
var optional = new Optional<string>(expectedValue);
|
||||
|
||||
// Assert
|
||||
Assert.True(optional.HasValue);
|
||||
Assert.Null(optional.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DefaultConstructor_ShouldSetHasValueToFalse()
|
||||
{
|
||||
// Arrange & Act
|
||||
var optional = new Optional<string>();
|
||||
|
||||
// Assert
|
||||
Assert.False(optional.HasValue);
|
||||
_ = Assert.Throws<InvalidOperationException>(() => optional.Value);
|
||||
}
|
||||
|
||||
// Implicit Conversion Tests
|
||||
|
||||
[Fact]
|
||||
public void ImplicitConversion_FromValueToOptional_ShouldSetHasValueToTrue()
|
||||
{
|
||||
// Arrange
|
||||
int expectedValue = 5;
|
||||
|
||||
// Act
|
||||
Optional<int> optional = expectedValue;
|
||||
|
||||
// Assert
|
||||
Assert.True(optional.HasValue);
|
||||
Assert.Equal(expectedValue, optional.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImplicitConversion_FromOptionalToValue_ShouldReturnValue_WhenHasValueIsTrue()
|
||||
{
|
||||
// Arrange
|
||||
int expectedValue = 10;
|
||||
var optional = new Optional<int>(expectedValue);
|
||||
|
||||
// Act
|
||||
int value = optional;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedValue, value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImplicitConversion_FromOptionalToValue_ShouldThrowException_WhenHasValueIsFalse()
|
||||
{
|
||||
// Arrange
|
||||
var optional = new Optional<int>();
|
||||
|
||||
// Act & Assert
|
||||
_ = Assert.Throws<InvalidOperationException>(() => { int value = optional; });
|
||||
}
|
||||
|
||||
// ToString Method Tests
|
||||
|
||||
[Fact]
|
||||
public void ToString_WithValue_ShouldReturnValueToString()
|
||||
{
|
||||
// Arrange
|
||||
int expectedValue = 42;
|
||||
var optional = new Optional<int>(expectedValue);
|
||||
|
||||
// Act
|
||||
string result = optional.ToString();
|
||||
|
||||
// Assert
|
||||
#pragma warning disable CA1305 // Specify IFormatProvider
|
||||
Assert.Equal(expectedValue.ToString(), result);
|
||||
#pragma warning restore CA1305 // Specify IFormatProvider
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToString_WithoutValue_ShouldReturnEmpty()
|
||||
{
|
||||
// Arrange & Act
|
||||
var optional = new Optional<int>();
|
||||
string result = optional.ToString();
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Empty", result);
|
||||
}
|
||||
|
||||
// Equality Tests
|
||||
|
||||
[Fact]
|
||||
public void Equals_WithSameValue_ShouldReturnTrue()
|
||||
{
|
||||
// Arrange
|
||||
var optional1 = new Optional<int>(10);
|
||||
var optional2 = new Optional<int>(10);
|
||||
|
||||
// Act
|
||||
bool areEqual = optional1.Equals(optional2);
|
||||
|
||||
// Assert
|
||||
Assert.True(areEqual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equals_WithDifferentValues_ShouldReturnFalse()
|
||||
{
|
||||
// Arrange
|
||||
var optional1 = new Optional<int>(10);
|
||||
var optional2 = new Optional<int>(20);
|
||||
|
||||
// Act
|
||||
bool areEqual = optional1.Equals(optional2);
|
||||
|
||||
// Assert
|
||||
Assert.False(areEqual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equals_WithNull_ShouldReturnFalse()
|
||||
{
|
||||
// Arrange
|
||||
var optional = new Optional<string>("test");
|
||||
|
||||
// Act
|
||||
bool areEqual = optional.Equals(null);
|
||||
|
||||
// Assert
|
||||
Assert.False(areEqual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equals_WithEmptyOptional_ShouldReturnTrue()
|
||||
{
|
||||
// Arrange
|
||||
var optional1 = new Optional<string>();
|
||||
var optional2 = new Optional<string>();
|
||||
|
||||
// Act
|
||||
bool areEqual = optional1.Equals(optional2);
|
||||
|
||||
// Assert
|
||||
Assert.True(areEqual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equals_WithSameReferenceTypeValue_ShouldReturnTrue()
|
||||
{
|
||||
// Arrange
|
||||
var value = new object();
|
||||
var optional1 = new Optional<object>(value);
|
||||
var optional2 = new Optional<object>(value);
|
||||
|
||||
// Act
|
||||
bool areEqual = optional1.Equals(optional2);
|
||||
|
||||
// Assert
|
||||
Assert.True(areEqual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Equals_WithDifferentReferenceTypeValues_ShouldReturnFalse()
|
||||
{
|
||||
// Arrange
|
||||
var optional1 = new Optional<object>(new object());
|
||||
var optional2 = new Optional<object>(new object());
|
||||
|
||||
// Act
|
||||
bool areEqual = optional1.Equals(optional2);
|
||||
|
||||
// Assert
|
||||
Assert.False(areEqual);
|
||||
}
|
||||
|
||||
// GetHashCode Method Tests
|
||||
|
||||
[Fact]
|
||||
public void GetHashCode_WithValue_ShouldReturnValueHashCode()
|
||||
{
|
||||
// Arrange
|
||||
int value = 42;
|
||||
var optional = new Optional<int>(value);
|
||||
|
||||
// Act
|
||||
int hashCode = optional.GetHashCode();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(value.GetHashCode(), hashCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetHashCode_WithoutValue_ShouldReturnZero()
|
||||
{
|
||||
// Arrange & Act
|
||||
var optional = new Optional<int>();
|
||||
int hashCode = optional.GetHashCode();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, hashCode);
|
||||
}
|
||||
|
||||
// Exception Tests
|
||||
|
||||
[Fact]
|
||||
public void Value_WhenHasValueIsFalse_ShouldThrowInvalidOperationException()
|
||||
{
|
||||
// Arrange
|
||||
var optional = new Optional<string>();
|
||||
|
||||
// Act & Assert
|
||||
_ = Assert.Throws<InvalidOperationException>(() => optional.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ImplicitConversion_WhenHasValueIsFalse_ShouldThrowInvalidOperationException()
|
||||
{
|
||||
// Arrange
|
||||
var optional = new Optional<int>();
|
||||
|
||||
// Act & Assert
|
||||
_ = Assert.Throws<InvalidOperationException>(() => { int value = optional; });
|
||||
}
|
||||
|
||||
// Edge Cases
|
||||
|
||||
[Fact]
|
||||
public void EmptyOptionalEquality_ShouldReturnTrue()
|
||||
{
|
||||
// Arrange
|
||||
var optional1 = new Optional<int>();
|
||||
var optional2 = new Optional<int>();
|
||||
|
||||
// Act
|
||||
bool areEqual = optional1.Equals(optional2);
|
||||
|
||||
// Assert
|
||||
Assert.True(areEqual);
|
||||
}
|
||||
|
||||
// Special Scenarios
|
||||
|
||||
public struct CustomStruct
|
||||
{
|
||||
public int X { get; set; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OptionalWithCustomStruct_ShouldBehaveCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var structValue = new CustomStruct { X = 10 };
|
||||
var optional = new Optional<CustomStruct>(structValue);
|
||||
|
||||
// Act
|
||||
CustomStruct value = optional.Value;
|
||||
|
||||
// Assert
|
||||
Assert.True(optional.HasValue);
|
||||
Assert.Equal(structValue, value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OptionalWithNullableInt_ShouldBehaveCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
int? nullableValue = 5;
|
||||
var optional = new Optional<int?>(nullableValue);
|
||||
|
||||
// Act
|
||||
int? value = optional.Value;
|
||||
|
||||
// Assert
|
||||
Assert.True(optional.HasValue);
|
||||
Assert.Equal(nullableValue, value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OptionalWithNullNullableInt_ShouldBehaveCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
int? nullableValue = null;
|
||||
var optional = new Optional<int?>(nullableValue);
|
||||
|
||||
// Act
|
||||
int? value = optional.Value;
|
||||
|
||||
// Assert
|
||||
Assert.True(optional.HasValue);
|
||||
Assert.Null(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public class CustomClassDefinitionTests
|
||||
{
|
||||
private sealed class TestClass1
|
||||
{
|
||||
public string Name { get; set; } = "John Doe";
|
||||
public int Age { get; set; } = 42;
|
||||
}
|
||||
|
||||
private static CustomClassDefinition ExpectedTestClass1Definition => new CustomClassDefinition
|
||||
{
|
||||
Name = "TestClass1",
|
||||
UseAs = CustomClassUseAs.All,
|
||||
Members = new List<IProperty>
|
||||
{
|
||||
new StringProperty { Name = "Name", Value = "John Doe" },
|
||||
new IntProperty { Name = "Age", Value = 42 }
|
||||
}
|
||||
};
|
||||
|
||||
private sealed class TestClass2WithNestedClass
|
||||
{
|
||||
public string Name { get; set; } = "John Doe";
|
||||
public int Age { get; set; } = 42;
|
||||
public TestClass1 Nested { get; set; } = new TestClass1();
|
||||
}
|
||||
|
||||
private static CustomClassDefinition ExpectedTestClass2WithNestedClassDefinition => new CustomClassDefinition
|
||||
{
|
||||
Name = "TestClass2WithNestedClass",
|
||||
UseAs = CustomClassUseAs.All,
|
||||
Members = [
|
||||
new StringProperty { Name = "Name", Value = "John Doe" },
|
||||
new IntProperty { Name = "Age", Value = 42 },
|
||||
new ClassProperty
|
||||
{
|
||||
Name = "Nested",
|
||||
PropertyType = "TestClass1",
|
||||
Value = []
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
private sealed class TestClass3WithOverridenNestedClass
|
||||
{
|
||||
public string Name { get; set; } = "John Doe";
|
||||
public int Age { get; set; } = 42;
|
||||
public TestClass1 Nested { get; set; } = new TestClass1
|
||||
{
|
||||
Name = "Jane Doe"
|
||||
};
|
||||
}
|
||||
|
||||
private static CustomClassDefinition ExpectedTestClass3WithOverridenNestedClassDefinition => new CustomClassDefinition
|
||||
{
|
||||
Name = "TestClass3WithOverridenNestedClass",
|
||||
UseAs = CustomClassUseAs.All,
|
||||
Members = [
|
||||
new StringProperty { Name = "Name", Value = "John Doe" },
|
||||
new IntProperty { Name = "Age", Value = 42 },
|
||||
new ClassProperty
|
||||
{
|
||||
Name = "Nested",
|
||||
PropertyType = "TestClass1",
|
||||
Value = [
|
||||
new StringProperty { Name = "Name", Value = "Jane Doe" },
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
private static IEnumerable<(Type, CustomClassDefinition)> GetCustomClassDefinitionTestData()
|
||||
{
|
||||
yield return (typeof(TestClass1), ExpectedTestClass1Definition);
|
||||
yield return (typeof(TestClass2WithNestedClass), ExpectedTestClass2WithNestedClassDefinition);
|
||||
yield return (typeof(TestClass3WithOverridenNestedClass), ExpectedTestClass3WithOverridenNestedClassDefinition);
|
||||
}
|
||||
|
||||
private static void AssertCustomClassDefinitionEqual(CustomClassDefinition expected, CustomClassDefinition actual)
|
||||
{
|
||||
DotTiledAssert.AssertEqual(expected.ID, actual.ID, nameof(CustomClassDefinition.ID));
|
||||
DotTiledAssert.AssertEqual(expected.Name, actual.Name, nameof(CustomClassDefinition.Name));
|
||||
DotTiledAssert.AssertEqual(expected.Color, actual.Color, nameof(CustomClassDefinition.Color));
|
||||
DotTiledAssert.AssertEqual(expected.DrawFill, actual.DrawFill, nameof(CustomClassDefinition.DrawFill));
|
||||
DotTiledAssert.AssertEqual(expected.UseAs, actual.UseAs, nameof(CustomClassDefinition.UseAs));
|
||||
DotTiledAssert.AssertProperties(expected.Members, actual.Members);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> CustomClassDefinitionTestData =>
|
||||
GetCustomClassDefinitionTestData().Select(data => new object[] { data.Item1, data.Item2 });
|
||||
[Theory]
|
||||
[MemberData(nameof(CustomClassDefinitionTestData))]
|
||||
public void FromClass_Type_WhenTypeIsCustomClass_ReturnsCustomClassDefinition(Type type, CustomClassDefinition expected)
|
||||
{
|
||||
// Arrange & Act
|
||||
var result = CustomClassDefinition.FromClass(type);
|
||||
|
||||
// Assert
|
||||
AssertCustomClassDefinitionEqual(expected, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromClass_Type_WhenTypeIsNull_ThrowsArgumentNullException()
|
||||
{
|
||||
// Arrange
|
||||
Type type = null;
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentNullException>(() => CustomClassDefinition.FromClass(type));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromClass_Type_WhenTypeIsString_ThrowsArgumentException()
|
||||
{
|
||||
// Arrange
|
||||
Type type = typeof(string);
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentException>(() => CustomClassDefinition.FromClass(type));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromClass_Type_WhenTypeIsNotClass_ThrowsArgumentException()
|
||||
{
|
||||
// Arrange
|
||||
Type type = typeof(int);
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentException>(() => CustomClassDefinition.FromClass(type));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
namespace DotTiled.Tests;
|
||||
|
||||
public class CustomEnumDefinitionTests
|
||||
{
|
||||
private static void AssertCustomEnumDefinitionEqual(CustomEnumDefinition expected, CustomEnumDefinition actual)
|
||||
{
|
||||
DotTiledAssert.AssertEqual(expected.ID, actual.ID, nameof(CustomEnumDefinition.ID));
|
||||
DotTiledAssert.AssertEqual(expected.Name, actual.Name, nameof(CustomEnumDefinition.Name));
|
||||
DotTiledAssert.AssertEqual(expected.StorageType, actual.StorageType, nameof(CustomEnumDefinition.StorageType));
|
||||
DotTiledAssert.AssertEqual(expected.ValueAsFlags, actual.ValueAsFlags, nameof(CustomEnumDefinition.ValueAsFlags));
|
||||
DotTiledAssert.AssertListOrdered(expected.Values, actual.Values, nameof(CustomEnumDefinition.Values));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromEnum_Type_WhenTypeIsNotEnum_ThrowsArgumentException()
|
||||
{
|
||||
// Arrange
|
||||
var type = typeof(string);
|
||||
|
||||
// Act & Assert
|
||||
Assert.Throws<ArgumentException>(() => CustomEnumDefinition.FromEnum(type));
|
||||
}
|
||||
|
||||
private enum TestEnum1 { Value1, Value2, Value3 }
|
||||
|
||||
[Fact]
|
||||
public void FromEnum_Type_WhenTypeIsEnum_ReturnsCustomEnumDefinition()
|
||||
{
|
||||
// Arrange
|
||||
var type = typeof(TestEnum1);
|
||||
var expected = new CustomEnumDefinition
|
||||
{
|
||||
ID = 0,
|
||||
Name = "TestEnum1",
|
||||
StorageType = CustomEnumStorageType.Int,
|
||||
Values = ["Value1", "Value2", "Value3"],
|
||||
ValueAsFlags = false
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = CustomEnumDefinition.FromEnum(type);
|
||||
|
||||
// Assert
|
||||
AssertCustomEnumDefinitionEqual(expected, result);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum TestEnum2 { Value1, Value2, Value3 }
|
||||
|
||||
[Fact]
|
||||
public void FromEnum_Type_WhenEnumIsFlags_ReturnsCustomEnumDefinition()
|
||||
{
|
||||
// Arrange
|
||||
var type = typeof(TestEnum2);
|
||||
var expected = new CustomEnumDefinition
|
||||
{
|
||||
ID = 0,
|
||||
Name = "TestEnum2",
|
||||
StorageType = CustomEnumStorageType.Int,
|
||||
Values = ["Value1", "Value2", "Value3"],
|
||||
ValueAsFlags = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = CustomEnumDefinition.FromEnum(type);
|
||||
|
||||
// Assert
|
||||
AssertCustomEnumDefinitionEqual(expected, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromEnum_T_WhenTypeIsEnum_ReturnsCustomEnumDefinition()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new CustomEnumDefinition
|
||||
{
|
||||
ID = 0,
|
||||
Name = "TestEnum1",
|
||||
StorageType = CustomEnumStorageType.Int,
|
||||
Values = ["Value1", "Value2", "Value3"],
|
||||
ValueAsFlags = false
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = CustomEnumDefinition.FromEnum<TestEnum1>();
|
||||
|
||||
// Assert
|
||||
AssertCustomEnumDefinitionEqual(expected, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromEnum_T_WhenEnumIsFlags_ReturnsCustomEnumDefinition()
|
||||
{
|
||||
// Arrange
|
||||
var expected = new CustomEnumDefinition
|
||||
{
|
||||
ID = 0,
|
||||
Name = "TestEnum2",
|
||||
StorageType = CustomEnumStorageType.Int,
|
||||
Values = ["Value1", "Value2", "Value3"],
|
||||
ValueAsFlags = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = CustomEnumDefinition.FromEnum<TestEnum2>();
|
||||
|
||||
// Assert
|
||||
AssertCustomEnumDefinitionEqual(expected, result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,300 @@
|
|||
using System.Globalization;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public class HasPropertiesBaseTests
|
||||
{
|
||||
private sealed class TestHasProperties(IList<IProperty> props) : HasPropertiesBase
|
||||
{
|
||||
public override IList<IProperty> GetProperties() => props;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetProperty_PropertyNotFound_ReturnsFalseAndOutIsNull()
|
||||
{
|
||||
// Arrange
|
||||
var hasProperties = new TestHasProperties([]);
|
||||
|
||||
// Act
|
||||
var result = hasProperties.TryGetProperty<BoolProperty>("Test", out var property);
|
||||
|
||||
// Assert
|
||||
Assert.False(result);
|
||||
Assert.Null(property);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetProperty_PropertyFound_ReturnsTrueAndOutIsProperty()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [new BoolProperty { Name = "Test", Value = true }];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act
|
||||
var result = hasProperties.TryGetProperty<BoolProperty>("Test", out var property);
|
||||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.NotNull(property);
|
||||
Assert.Equal("Test", property.Name);
|
||||
Assert.True(property.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetProperty_PropertyNotFound_ThrowsKeyNotFoundException()
|
||||
{
|
||||
// Arrange
|
||||
var hasProperties = new TestHasProperties([]);
|
||||
|
||||
// Act & Assert
|
||||
_ = Assert.Throws<KeyNotFoundException>(() => hasProperties.GetProperty<BoolProperty>("Test"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetProperty_PropertyFound_ReturnsProperty()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [new BoolProperty { Name = "Test", Value = true }];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act
|
||||
var property = hasProperties.GetProperty<BoolProperty>("Test");
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(property);
|
||||
Assert.Equal("Test", property.Name);
|
||||
Assert.True(property.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetProperty_PropertyIsWrongType_ThrowsInvalidCastException()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [new BoolProperty { Name = "Test", Value = true }];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act & Assert
|
||||
_ = Assert.Throws<InvalidCastException>(() => hasProperties.GetProperty<IntProperty>("Test"));
|
||||
}
|
||||
|
||||
private sealed class MapTo
|
||||
{
|
||||
public bool MapToBool { get; set; } = false;
|
||||
public Color MapToColor { get; set; } = Color.Parse("#00000000", CultureInfo.InvariantCulture);
|
||||
public float MapToFloat { get; set; } = 0.0f;
|
||||
public string MapToFile { get; set; } = "";
|
||||
public int MapToInt { get; set; } = 0;
|
||||
public int MapToObject { get; set; } = 0;
|
||||
public string MapToString { get; set; } = "";
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapPropertiesTo_NestedPropertyNotFound_ThrowsKeyNotFoundException()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [
|
||||
new ClassProperty {
|
||||
Name = "ClassInObject",
|
||||
PropertyType = "MapTo",
|
||||
Value = [
|
||||
new StringProperty { Name = "PropertyThatDoesNotExistInMapTo", Value = "Test" }
|
||||
],
|
||||
}
|
||||
];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act & Assert
|
||||
_ = Assert.Throws<KeyNotFoundException>(() => hasProperties.GetProperty<ClassProperty>("ClassInObject").MapPropertiesTo<MapTo>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapPropertiesTo_NestedPropertyIsNotClassProperty_ThrowsInvalidCastException()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [
|
||||
new StringProperty { Name = "ClassInObject", Value = "Test" }
|
||||
];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act & Assert
|
||||
_ = Assert.Throws<InvalidCastException>(() => hasProperties.GetProperty<ClassProperty>("ClassInObject").MapPropertiesTo<MapTo>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapPropertiesTo_NestedAllBasicValidProperties_ReturnsMappedProperty()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [
|
||||
new ClassProperty {
|
||||
Name = "ClassInObject",
|
||||
PropertyType = "MapTo",
|
||||
Value = [
|
||||
new BoolProperty { Name = "MapToBool", Value = true },
|
||||
new ColorProperty { Name = "MapToColor", Value = Color.Parse("#FF0000FF", CultureInfo.InvariantCulture) },
|
||||
new FloatProperty { Name = "MapToFloat", Value = 1.0f },
|
||||
new StringProperty { Name = "MapToFile", Value = "Test" },
|
||||
new IntProperty { Name = "MapToInt", Value = 1 },
|
||||
new IntProperty { Name = "MapToObject", Value = 1 },
|
||||
new StringProperty { Name = "MapToString", Value = "Test" },
|
||||
],
|
||||
}
|
||||
];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act
|
||||
var mappedProperty = hasProperties.GetProperty<ClassProperty>("ClassInObject").MapPropertiesTo<MapTo>();
|
||||
|
||||
// Assert
|
||||
Assert.True(mappedProperty.MapToBool);
|
||||
Assert.Equal(Color.Parse("#FF0000FF", CultureInfo.InvariantCulture), mappedProperty.MapToColor);
|
||||
Assert.Equal(1.0f, mappedProperty.MapToFloat);
|
||||
Assert.Equal("Test", mappedProperty.MapToFile);
|
||||
Assert.Equal(1, mappedProperty.MapToInt);
|
||||
Assert.Equal(1, mappedProperty.MapToObject);
|
||||
Assert.Equal("Test", mappedProperty.MapToString);
|
||||
}
|
||||
|
||||
private sealed class NestedMapTo
|
||||
{
|
||||
public string NestedMapToString { get; set; } = "";
|
||||
public MapTo MapToInNested { get; set; } = new MapTo();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapPropertiesTo_NestedNestedMapTo_ReturnsMappedProperty()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [
|
||||
new ClassProperty {
|
||||
Name = "ClassInObject",
|
||||
PropertyType = "NestedMapTo",
|
||||
Value = [
|
||||
new StringProperty { Name = "NestedMapToString", Value = "Test" },
|
||||
new ClassProperty {
|
||||
Name = "MapToInNested",
|
||||
PropertyType = "MapTo",
|
||||
Value = [
|
||||
new BoolProperty { Name = "MapToBool", Value = true },
|
||||
new ColorProperty { Name = "MapToColor", Value = Color.Parse("#FF0000FF", CultureInfo.InvariantCulture) },
|
||||
new FloatProperty { Name = "MapToFloat", Value = 1.0f },
|
||||
new StringProperty { Name = "MapToFile", Value = "Test" },
|
||||
new IntProperty { Name = "MapToInt", Value = 1 },
|
||||
new IntProperty { Name = "MapToObject", Value = 1 },
|
||||
new StringProperty { Name = "MapToString", Value = "Test" },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act
|
||||
var mappedProperty = hasProperties.GetProperty<ClassProperty>("ClassInObject").MapPropertiesTo<NestedMapTo>();
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Test", mappedProperty.NestedMapToString);
|
||||
Assert.True(mappedProperty.MapToInNested.MapToBool);
|
||||
Assert.Equal(Color.Parse("#FF0000FF", CultureInfo.InvariantCulture), mappedProperty.MapToInNested.MapToColor);
|
||||
Assert.Equal(1.0f, mappedProperty.MapToInNested.MapToFloat);
|
||||
Assert.Equal("Test", mappedProperty.MapToInNested.MapToFile);
|
||||
Assert.Equal(1, mappedProperty.MapToInNested.MapToInt);
|
||||
Assert.Equal(1, mappedProperty.MapToInNested.MapToObject);
|
||||
Assert.Equal("Test", mappedProperty.MapToInNested.MapToString);
|
||||
}
|
||||
|
||||
private enum TestEnum
|
||||
{
|
||||
TestValue1,
|
||||
TestValue2,
|
||||
TestValue3
|
||||
}
|
||||
|
||||
private sealed class EnumMapTo
|
||||
{
|
||||
public TestEnum EnumMapToEnum { get; set; } = TestEnum.TestValue1;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapPropertiesTo_NestedEnumProperty_ReturnsMappedProperty()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [
|
||||
new ClassProperty {
|
||||
Name = "ClassInObject",
|
||||
PropertyType = "EnumMapTo",
|
||||
Value = [
|
||||
new EnumProperty { Name = "EnumMapToEnum", PropertyType = "TestEnum", Value = new HashSet<string> { "TestValue1" } },
|
||||
],
|
||||
}
|
||||
];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act
|
||||
var mappedProperty = hasProperties.GetProperty<ClassProperty>("ClassInObject").MapPropertiesTo<EnumMapTo>();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(TestEnum.TestValue1, mappedProperty.EnumMapToEnum);
|
||||
}
|
||||
|
||||
private enum TestEnumWithFlags
|
||||
{
|
||||
TestValue1 = 1,
|
||||
TestValue2 = 2,
|
||||
TestValue3 = 4
|
||||
}
|
||||
|
||||
private sealed class EnumWithFlagsMapTo
|
||||
{
|
||||
public TestEnumWithFlags EnumWithFlagsMapToEnum { get; set; } = TestEnumWithFlags.TestValue1;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapPropertiesTo_NestedEnumWithFlagsProperty_ReturnsMappedProperty()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [
|
||||
new ClassProperty {
|
||||
Name = "ClassInObject",
|
||||
PropertyType = "EnumWithFlagsMapTo",
|
||||
Value = [
|
||||
new EnumProperty { Name = "EnumWithFlagsMapToEnum", PropertyType = "TestEnumWithFlags", Value = new HashSet<string> { "TestValue1", "TestValue2" } },
|
||||
],
|
||||
}
|
||||
];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act
|
||||
var mappedProperty = hasProperties.GetProperty<ClassProperty>("ClassInObject").MapPropertiesTo<EnumWithFlagsMapTo>();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(TestEnumWithFlags.TestValue1 | TestEnumWithFlags.TestValue2, mappedProperty.EnumWithFlagsMapToEnum);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MapPropertiesTo_WithProperties_ReturnsMappedProperty()
|
||||
{
|
||||
// Arrange
|
||||
List<IProperty> props = [
|
||||
new BoolProperty { Name = "MapToBool", Value = true },
|
||||
new ColorProperty { Name = "MapToColor", Value = Color.Parse("#FF0000FF", CultureInfo.InvariantCulture) },
|
||||
new FloatProperty { Name = "MapToFloat", Value = 1.0f },
|
||||
new StringProperty { Name = "MapToFile", Value = "Test" },
|
||||
new IntProperty { Name = "MapToInt", Value = 1 },
|
||||
new IntProperty { Name = "MapToObject", Value = 1 },
|
||||
new StringProperty { Name = "MapToString", Value = "Test" },
|
||||
];
|
||||
var hasProperties = new TestHasProperties(props);
|
||||
|
||||
// Act
|
||||
var mappedProperty = hasProperties.MapPropertiesTo<MapTo>();
|
||||
|
||||
// Assert
|
||||
Assert.True(mappedProperty.MapToBool);
|
||||
Assert.Equal(Color.Parse("#FF0000FF", CultureInfo.InvariantCulture), mappedProperty.MapToColor);
|
||||
Assert.Equal(1.0f, mappedProperty.MapToFloat);
|
||||
Assert.Equal("Test", mappedProperty.MapToFile);
|
||||
Assert.Equal(1, mappedProperty.MapToInt);
|
||||
Assert.Equal(1, mappedProperty.MapToObject);
|
||||
Assert.Equal("Test", mappedProperty.MapToString);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
using DotTiled.Serialization;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public class DefaultResourceCacheTests
|
||||
{
|
||||
[Fact]
|
||||
public void GetTemplate_TemplateDoesNotExist_ReturnsEmptyOptional()
|
||||
{
|
||||
// Arrange
|
||||
var cache = new DefaultResourceCache();
|
||||
var path = "template.tsx";
|
||||
|
||||
// Act
|
||||
var result = cache.GetTemplate(path);
|
||||
|
||||
// Assert
|
||||
Assert.False(result.HasValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTemplate_TemplateHasBeenInserted_ReturnsTemplate()
|
||||
{
|
||||
// Arrange
|
||||
var cache = new DefaultResourceCache();
|
||||
var path = "template.tsx";
|
||||
var template = new Template
|
||||
{
|
||||
Object = new EllipseObject { }
|
||||
};
|
||||
|
||||
// Act
|
||||
cache.InsertTemplate(path, template);
|
||||
var result = cache.GetTemplate(path);
|
||||
|
||||
// Assert
|
||||
Assert.True(result.HasValue);
|
||||
Assert.Same(template, result.Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTileset_TilesetDoesNotExist_ReturnsEmptyOptional()
|
||||
{
|
||||
// Arrange
|
||||
var cache = new DefaultResourceCache();
|
||||
var path = "tileset.tsx";
|
||||
|
||||
// Act
|
||||
var result = cache.GetTileset(path);
|
||||
|
||||
// Assert
|
||||
Assert.False(result.HasValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTileset_TilesetHasBeenInserted_ReturnsTileset()
|
||||
{
|
||||
// Arrange
|
||||
var cache = new DefaultResourceCache();
|
||||
var path = "tileset.tsx";
|
||||
var tileset = new Tileset
|
||||
{
|
||||
Name = "Tileset",
|
||||
TileWidth = 32,
|
||||
TileHeight = 32,
|
||||
TileCount = 1,
|
||||
Columns = 1
|
||||
};
|
||||
|
||||
// Act
|
||||
cache.InsertTileset(path, tileset);
|
||||
var result = cache.GetTileset(path);
|
||||
|
||||
// Assert
|
||||
Assert.True(result.HasValue);
|
||||
Assert.Same(tileset, result.Value);
|
||||
}
|
||||
}
|
247
src/DotTiled.Tests/UnitTests/Serialization/LoaderTests.cs
Normal file
247
src/DotTiled.Tests/UnitTests/Serialization/LoaderTests.cs
Normal file
|
@ -0,0 +1,247 @@
|
|||
using System.Numerics;
|
||||
using DotTiled.Serialization;
|
||||
using NSubstitute;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public class LoaderTests
|
||||
{
|
||||
[Fact]
|
||||
public void LoadMap_Always_ReadsFromResourceReader()
|
||||
{
|
||||
// Arrange
|
||||
var resourceReader = Substitute.For<IResourceReader>();
|
||||
resourceReader.Read("map.tmx").Returns(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
||||
""");
|
||||
|
||||
var resourceCache = Substitute.For<IResourceCache>();
|
||||
var customTypeDefinitions = Enumerable.Empty<ICustomTypeDefinition>();
|
||||
var loader = new Loader(resourceReader, resourceCache, customTypeDefinitions);
|
||||
|
||||
// Act
|
||||
loader.LoadMap("map.tmx");
|
||||
|
||||
// Assert
|
||||
resourceReader.Received(1).Read("map.tmx");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadMap_MapReferencesExternalTileset_ReadsTilesetFromResourceReaderAndAttemptsToRetrieveFromCache()
|
||||
{
|
||||
// Arrange
|
||||
var resourceReader = Substitute.For<IResourceReader>();
|
||||
resourceReader.Read("map.tmx").Returns(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<tileset firstgid="1" source="tileset.tsx"/>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
||||
""");
|
||||
|
||||
resourceReader.Read("tileset.tsx").Returns(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.2" tiledversion="1.11.0" name="Tileset" tilewidth="32" tileheight="32" tilecount="1" columns="1">
|
||||
<tile id="1">
|
||||
<image width="32" height="32" source="tile.png"/>
|
||||
</tile>
|
||||
</tileset>
|
||||
""");
|
||||
|
||||
var resourceCache = Substitute.For<IResourceCache>();
|
||||
resourceCache.GetTileset(Arg.Any<string>()).Returns(Optional<Tileset>.Empty);
|
||||
resourceCache.GetTemplate(Arg.Any<string>()).Returns(Optional<Template>.Empty);
|
||||
|
||||
var customTypeDefinitions = Enumerable.Empty<ICustomTypeDefinition>();
|
||||
var loader = new Loader(resourceReader, resourceCache, customTypeDefinitions);
|
||||
|
||||
// Act
|
||||
loader.LoadMap("map.tmx");
|
||||
|
||||
// Assert
|
||||
resourceReader.Received(1).Read("tileset.tsx");
|
||||
resourceCache.Received(1).GetTileset("tileset.tsx");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadMap_MapReferencesExternalTemplate_ReadsTemplateFromResourceReaderAndAttemptsToRetrieveFromCache()
|
||||
{
|
||||
// Arrange
|
||||
var resourceReader = Substitute.For<IResourceReader>();
|
||||
resourceReader.Read("map.tmx").Returns(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<tileset firstgid="1" source="tileset.tsx"/>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup id="2" name="Object Layer 1" width="5" height="5">
|
||||
<object id="1" name="Template" template="template.tx" x="0" y="0" width="32" height="32" gid="1"/>
|
||||
</objectgroup>
|
||||
</map>
|
||||
""");
|
||||
|
||||
resourceReader.Read("tileset.tsx").Returns(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.2" tiledversion="1.11.0" name="Tileset" tilewidth="32" tileheight="32" tilecount="1" columns="1">
|
||||
<tile id="1">
|
||||
<image width="32" height="32" source="tile.png"/>
|
||||
</tile>
|
||||
</tileset>
|
||||
""");
|
||||
|
||||
resourceReader.Read("template.tx").Returns(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<template>
|
||||
<object name="Poly">
|
||||
<properties>
|
||||
<property name="templateprop" value="helo there"/>
|
||||
</properties>
|
||||
<polygon points="0,0 104,20 35.6667,32.3333"/>
|
||||
</object>
|
||||
</template>
|
||||
""");
|
||||
|
||||
var resourceCache = Substitute.For<IResourceCache>();
|
||||
resourceCache.GetTileset(Arg.Any<string>()).Returns(Optional<Tileset>.Empty);
|
||||
resourceCache.GetTemplate(Arg.Any<string>()).Returns(Optional<Template>.Empty);
|
||||
|
||||
var customTypeDefinitions = Enumerable.Empty<ICustomTypeDefinition>();
|
||||
var loader = new Loader(resourceReader, resourceCache, customTypeDefinitions);
|
||||
|
||||
// Act
|
||||
loader.LoadMap("map.tmx");
|
||||
|
||||
// Assert
|
||||
resourceReader.Received(1).Read("template.tx");
|
||||
resourceCache.Received(1).GetTemplate("template.tx");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadMap_CacheReturnsTileset_ReturnsTilesetFromCache()
|
||||
{
|
||||
// Arrange
|
||||
var resourceReader = Substitute.For<IResourceReader>();
|
||||
resourceReader.Read("map.tmx").Returns(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<tileset firstgid="1" source="tileset.tsx"/>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
||||
""");
|
||||
|
||||
var resourceCache = Substitute.For<IResourceCache>();
|
||||
resourceCache.GetTileset("tileset.tsx").Returns(new Optional<Tileset>(new Tileset { Name = "Tileset", TileWidth = 32, TileHeight = 32, TileCount = 1, Columns = 1 }));
|
||||
|
||||
var customTypeDefinitions = Enumerable.Empty<ICustomTypeDefinition>();
|
||||
var loader = new Loader(resourceReader, resourceCache, customTypeDefinitions);
|
||||
|
||||
// Act
|
||||
loader.LoadMap("map.tmx");
|
||||
|
||||
// Assert
|
||||
resourceReader.DidNotReceive().Read("tileset.tsx");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LoadMap_CacheReturnsTemplate_ReturnsTemplateFromCache()
|
||||
{
|
||||
// Arrange
|
||||
var resourceReader = Substitute.For<IResourceReader>();
|
||||
resourceReader.Read("map.tmx").Returns(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="5" height="5" tilewidth="32" tileheight="32" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<tileset firstgid="1" source="tileset.tsx"/>
|
||||
<layer id="1" name="Tile Layer 1" width="5" height="5">
|
||||
<data encoding="csv">
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0,
|
||||
0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup id="2" name="Object Layer 1" width="5" height="5">
|
||||
<object id="1" name="Template" template="template.tx" x="0" y="0" width="32" height="32" gid="1"/>
|
||||
</objectgroup>
|
||||
</map>
|
||||
""");
|
||||
|
||||
resourceReader.Read("tileset.tsx").Returns(
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.2" tiledversion="1.11.0" name="Tileset" tilewidth="32" tileheight="32" tilecount="1" columns="1">
|
||||
<tile id="1">
|
||||
<image width="32" height="32" source="tile.png"/>
|
||||
</tile>
|
||||
</tileset>
|
||||
""");
|
||||
|
||||
var resourceCache = Substitute.For<IResourceCache>();
|
||||
resourceCache.GetTileset(Arg.Any<string>()).Returns(Optional<Tileset>.Empty);
|
||||
resourceCache.GetTemplate("template.tx").Returns(new Optional<Template>(new Template
|
||||
{
|
||||
Object = new PolygonObject
|
||||
{
|
||||
Points = [
|
||||
new Vector2(0,0),
|
||||
new Vector2(104,20),
|
||||
new Vector2(35.6667f,32.3333f)
|
||||
],
|
||||
Properties = [
|
||||
new StringProperty { Name = "templateprop", Value = "helo there" }
|
||||
]
|
||||
}
|
||||
}));
|
||||
|
||||
var customTypeDefinitions = Enumerable.Empty<ICustomTypeDefinition>();
|
||||
var loader = new Loader(resourceReader, resourceCache, customTypeDefinitions);
|
||||
|
||||
// Act
|
||||
loader.LoadMap("map.tmx");
|
||||
|
||||
// Assert
|
||||
resourceReader.DidNotReceive().Read("template.tx");
|
||||
}
|
||||
}
|
49
src/DotTiled.Tests/UnitTests/Serialization/MapReaderTests.cs
Normal file
49
src/DotTiled.Tests/UnitTests/Serialization/MapReaderTests.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using DotTiled.Serialization;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class MapReaderTests
|
||||
{
|
||||
public static IEnumerable<object[]> Maps => TestData.MapTests;
|
||||
[Theory]
|
||||
[MemberData(nameof(Maps))]
|
||||
public void MapReaderReadMap_ValidFilesExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(
|
||||
string testDataFile,
|
||||
Func<string, Map> expectedMap,
|
||||
IReadOnlyCollection<ICustomTypeDefinition> customTypeDefinitions)
|
||||
{
|
||||
// Arrange
|
||||
string[] fileFormats = [".tmx", ".tmj"];
|
||||
|
||||
foreach (var fileFormat in fileFormats)
|
||||
{
|
||||
var testDataFileWithFormat = testDataFile + fileFormat;
|
||||
var fileDir = Path.GetDirectoryName(testDataFileWithFormat);
|
||||
var mapString = TestData.GetRawStringFor(testDataFileWithFormat);
|
||||
Template ResolveTemplate(string source)
|
||||
{
|
||||
var templateString = TestData.GetRawStringFor($"{fileDir}/{source}");
|
||||
using var templateReader = new TemplateReader(templateString, ResolveTileset, ResolveTemplate, ResolveCustomType);
|
||||
return templateReader.ReadTemplate();
|
||||
}
|
||||
Tileset ResolveTileset(string source)
|
||||
{
|
||||
var tilesetString = TestData.GetRawStringFor($"{fileDir}/{source}");
|
||||
using var tilesetReader = new TilesetReader(tilesetString, ResolveTileset, ResolveTemplate, ResolveCustomType);
|
||||
return tilesetReader.ReadTileset();
|
||||
}
|
||||
ICustomTypeDefinition ResolveCustomType(string name)
|
||||
{
|
||||
return customTypeDefinitions.FirstOrDefault(ctd => ctd.Name == name)!;
|
||||
}
|
||||
using var mapReader = new MapReader(mapString, ResolveTileset, ResolveTemplate, ResolveCustomType);
|
||||
|
||||
// Act
|
||||
var map = mapReader.ReadMap();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(map);
|
||||
DotTiledAssert.AssertMap(expectedMap(fileFormat[1..]), map);
|
||||
}
|
||||
}
|
||||
}
|
49
src/DotTiled.Tests/UnitTests/Serialization/TestData.cs
Normal file
49
src/DotTiled.Tests/UnitTests/Serialization/TestData.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System.Xml;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public static partial class TestData
|
||||
{
|
||||
public static XmlReader GetXmlReaderFor(string testDataFile)
|
||||
{
|
||||
var fullyQualifiedTestDataFile = $"DotTiled.Tests.{ConvertPathToAssemblyResourcePath(testDataFile)}";
|
||||
using var stream = typeof(TestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile)
|
||||
?? throw new ArgumentException($"Test data file '{fullyQualifiedTestDataFile}' not found");
|
||||
|
||||
using var stringReader = new StreamReader(stream);
|
||||
var xml = stringReader.ReadToEnd();
|
||||
var xmlStringReader = new StringReader(xml);
|
||||
return XmlReader.Create(xmlStringReader);
|
||||
}
|
||||
|
||||
public static string GetRawStringFor(string testDataFile)
|
||||
{
|
||||
var fullyQualifiedTestDataFile = $"DotTiled.Tests.{ConvertPathToAssemblyResourcePath(testDataFile)}";
|
||||
using var stream = typeof(TestData).Assembly.GetManifestResourceStream(fullyQualifiedTestDataFile)
|
||||
?? throw new ArgumentException($"Test data file '{fullyQualifiedTestDataFile}' not found");
|
||||
|
||||
using var stringReader = new StreamReader(stream);
|
||||
return stringReader.ReadToEnd();
|
||||
}
|
||||
|
||||
private static string ConvertPathToAssemblyResourcePath(string path) =>
|
||||
path.Replace("/", ".").Replace("\\", ".").Replace(" ", "_");
|
||||
|
||||
private static string GetMapPath(string mapName) => $"TestData/Maps/{mapName.Replace('-', '_')}/{mapName}";
|
||||
|
||||
public static IEnumerable<object[]> MapTests =>
|
||||
[
|
||||
[GetMapPath("default-map"), (string f) => DefaultMap(), Array.Empty<ICustomTypeDefinition>()],
|
||||
[GetMapPath("map-with-common-props"), (string f) => MapWithCommonProps(), Array.Empty<ICustomTypeDefinition>()],
|
||||
[GetMapPath("map-with-custom-type-props"), (string f) => MapWithCustomTypeProps(), MapWithCustomTypePropsCustomTypeDefinitions()],
|
||||
[GetMapPath("map-with-embedded-tileset"), (string f) => MapWithEmbeddedTileset(), Array.Empty<ICustomTypeDefinition>()],
|
||||
[GetMapPath("map-with-external-tileset"), (string f) => MapWithExternalTileset(f), Array.Empty<ICustomTypeDefinition>()],
|
||||
[GetMapPath("map-with-flippingflags"), (string f) => MapWithFlippingFlags(f), Array.Empty<ICustomTypeDefinition>()],
|
||||
[GetMapPath("map-external-tileset-multi"), (string f) => MapExternalTilesetMulti(f), Array.Empty<ICustomTypeDefinition>()],
|
||||
[GetMapPath("map-external-tileset-wangset"), (string f) => MapExternalTilesetWangset(f), Array.Empty<ICustomTypeDefinition>()],
|
||||
[GetMapPath("map-with-many-layers"), (string f) => MapWithManyLayers(f), Array.Empty<ICustomTypeDefinition>()],
|
||||
[GetMapPath("map-with-deep-props"), (string f) => MapWithDeepProps(), MapWithDeepPropsCustomTypeDefinitions()],
|
||||
[GetMapPath("map-with-class"), (string f) => MapWithClass(), MapWithClassCustomTypeDefinitions()],
|
||||
[GetMapPath("map-with-class-and-props"), (string f) => MapWithClassAndProps(), MapWithClassAndPropsCustomTypeDefinitions()],
|
||||
];
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
using DotTiled.Serialization.Tmj;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmjMapReaderTests
|
||||
{
|
||||
public static IEnumerable<object[]> Maps => TestData.MapTests;
|
||||
[Theory]
|
||||
[MemberData(nameof(Maps))]
|
||||
public void TmxMapReaderReadMap_ValidTmjExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(
|
||||
string testDataFile,
|
||||
Func<string, Map> expectedMap,
|
||||
IReadOnlyCollection<ICustomTypeDefinition> customTypeDefinitions)
|
||||
{
|
||||
// Arrange
|
||||
testDataFile += ".tmj";
|
||||
var fileDir = Path.GetDirectoryName(testDataFile);
|
||||
var json = TestData.GetRawStringFor(testDataFile);
|
||||
Template ResolveTemplate(string source)
|
||||
{
|
||||
var templateJson = TestData.GetRawStringFor($"{fileDir}/{source}");
|
||||
using var templateReader = new TjTemplateReader(templateJson, ResolveTileset, ResolveTemplate, ResolveCustomType);
|
||||
return templateReader.ReadTemplate();
|
||||
}
|
||||
Tileset ResolveTileset(string source)
|
||||
{
|
||||
var tilesetJson = TestData.GetRawStringFor($"{fileDir}/{source}");
|
||||
using var tilesetReader = new TsjTilesetReader(tilesetJson, ResolveTileset, ResolveTemplate, ResolveCustomType);
|
||||
return tilesetReader.ReadTileset();
|
||||
}
|
||||
ICustomTypeDefinition ResolveCustomType(string name)
|
||||
{
|
||||
return customTypeDefinitions.FirstOrDefault(ctd => ctd.Name == name)!;
|
||||
}
|
||||
using var mapReader = new TmjMapReader(json, ResolveTileset, ResolveTemplate, ResolveCustomType);
|
||||
|
||||
// Act
|
||||
var map = mapReader.ReadMap();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(map);
|
||||
DotTiledAssert.AssertMap(expectedMap("tmj"), map);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
using DotTiled.Serialization.Tmx;
|
||||
|
||||
namespace DotTiled.Tests;
|
||||
|
||||
public partial class TmxMapReaderTests
|
||||
{
|
||||
public static IEnumerable<object[]> Maps => TestData.MapTests;
|
||||
[Theory]
|
||||
[MemberData(nameof(Maps))]
|
||||
public void TmxMapReaderReadMap_ValidXmlExternalTilesetsAndTemplates_ReturnsMapThatEqualsExpected(
|
||||
string testDataFile,
|
||||
Func<string, Map> expectedMap,
|
||||
IReadOnlyCollection<ICustomTypeDefinition> customTypeDefinitions)
|
||||
{
|
||||
// Arrange
|
||||
testDataFile += ".tmx";
|
||||
var fileDir = Path.GetDirectoryName(testDataFile);
|
||||
using var reader = TestData.GetXmlReaderFor(testDataFile);
|
||||
Template ResolveTemplate(string source)
|
||||
{
|
||||
using var xmlTemplateReader = TestData.GetXmlReaderFor($"{fileDir}/{source}");
|
||||
using var templateReader = new TxTemplateReader(xmlTemplateReader, ResolveTileset, ResolveTemplate, ResolveCustomType);
|
||||
return templateReader.ReadTemplate();
|
||||
}
|
||||
Tileset ResolveTileset(string source)
|
||||
{
|
||||
using var xmlTilesetReader = TestData.GetXmlReaderFor($"{fileDir}/{source}");
|
||||
using var tilesetReader = new TsxTilesetReader(xmlTilesetReader, ResolveTileset, ResolveTemplate, ResolveCustomType);
|
||||
return tilesetReader.ReadTileset();
|
||||
}
|
||||
ICustomTypeDefinition ResolveCustomType(string name)
|
||||
{
|
||||
return customTypeDefinitions.FirstOrDefault(ctd => ctd.Name == name)!;
|
||||
}
|
||||
using var mapReader = new TmxMapReader(reader, ResolveTileset, ResolveTemplate, ResolveCustomType);
|
||||
|
||||
// Act
|
||||
var map = mapReader.ReadMap();
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(map);
|
||||
DotTiledAssert.AssertMap(expectedMap("tmx"), map);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue