Implement requested changes

This commit is contained in:
Kat 2024-11-20 05:11:45 -08:00
parent 1027b922fe
commit 7a7f360e22
No known key found for this signature in database
GPG key ID: 11C549BC42DB9B8A
3 changed files with 133 additions and 32 deletions

View file

@ -5,25 +5,10 @@ namespace DotTiled.Tests;
public class FromTypeUsedInLoaderTests
{
private enum TestEnum
{
A,
B,
C
}
[Flags]
private enum TestFlags
{
A = 0b001,
B = 0b010,
C = 0b100
}
private sealed class TestClass
{
public string Name { get; set; } = "John Doe";
public int Age { get; set; } = 42;
public TestEnum Enum { get; set; } = TestEnum.A;
public TestFlags Flags { get; set; } = TestFlags.B | TestFlags.C;
}
[Fact]
@ -97,9 +82,7 @@ public class FromTypeUsedInLoaderTests
],
Properties = [
new StringProperty { Name = "Name", Value = "John Doe" },
new IntProperty { Name = "Age", Value = 42 },
new EnumProperty { Name = "Enum", PropertyType = "TestEnum", Value = new HashSet<string> { "A" } },
new EnumProperty { Name = "Flags", PropertyType = "TestFlags", Value = new HashSet<string> { "B", "C" } }
new IntProperty { Name = "Age", Value = 42 }
]
};
@ -184,9 +167,99 @@ public class FromTypeUsedInLoaderTests
],
Properties = [
new StringProperty { Name = "Name", Value = "John Doe" },
new IntProperty { Name = "Age", Value = 42 },
new EnumProperty { Name = "Enum", PropertyType = "TestEnum", Value = new HashSet<string> { "A" } },
new EnumProperty { Name = "Flags", PropertyType = "TestFlags", Value = new HashSet<string> { "B", "C" } }
new IntProperty { Name = "Age", Value = 42 }
]
};
// Act
var result = loader.LoadMap("map.tmx");
// Assert
DotTiledAssert.AssertMap(expectedMap, result);
}
private enum TestEnum
{
Value1,
Value2
}
private sealed class TestClassWithEnum
{
public TestEnum Enum { get; set; } = TestEnum.Value1;
}
[Fact]
public void LoadMap_MapHasClassWithEnumAndClassIsDefined_ReturnsCorrectMap()
{
// 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" class="TestClassWithEnum" 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 classDefinition = CustomClassDefinition.FromClass<TestClassWithEnum>();
var loader = Loader.DefaultWith(
resourceReader: resourceReader,
customTypeDefinitions: [classDefinition]);
var expectedMap = new Map
{
Class = "TestClassWithEnum",
Orientation = MapOrientation.Orthogonal,
Width = 5,
Height = 5,
TileWidth = 32,
TileHeight = 32,
Infinite = false,
ParallaxOriginX = 0,
ParallaxOriginY = 0,
RenderOrder = RenderOrder.RightDown,
CompressionLevel = -1,
BackgroundColor = new Color { R = 0, G = 0, B = 0, A = 0 },
Version = "1.10",
TiledVersion = "1.11.0",
NextLayerID = 2,
NextObjectID = 1,
Layers = [
new TileLayer
{
ID = 1,
Name = "Tile Layer 1",
Width = 5,
Height = 5,
Data = new Data
{
Encoding = DataEncoding.Csv,
GlobalTileIDs = new Optional<uint[]>([
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
]),
FlippingFlags = new Optional<FlippingFlags[]>([
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None,
FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None, FlippingFlags.None
])
}
}
],
Properties = [
new EnumProperty { Name = "Enum", PropertyType = "TestEnum", Value = new HashSet<string> { "Value1" } }
]
};

View file

@ -70,11 +70,42 @@ public class CustomClassDefinitionTests
]
};
private enum TestEnum1
{
Value1,
Value2
}
[Flags]
private enum TestFlags1
{
Value1 = 0b001,
Value2 = 0b010,
Value3 = 0b100
}
private sealed class TestClass4WithEnums
{
public TestEnum1 Enum { get; set; } = TestEnum1.Value2;
public TestFlags1 Flags { get; set; } = TestFlags1.Value1 | TestFlags1.Value2;
}
private static CustomClassDefinition ExpectedTestClass4WithEnumsDefinition => new CustomClassDefinition
{
Name = "TestClass4WithEnums",
UseAs = CustomClassUseAs.All,
Members = [
new EnumProperty { Name = "Enum", PropertyType = "TestEnum1", Value = new HashSet<string> { "Value2" } },
new EnumProperty { Name = "Flags", PropertyType = "TestFlags1", Value = new HashSet<string> { "Value1", "Value2" } }
]
};
private static IEnumerable<(Type, CustomClassDefinition)> GetCustomClassDefinitionTestData()
{
yield return (typeof(TestClass1), ExpectedTestClass1Definition);
yield return (typeof(TestClass2WithNestedClass), ExpectedTestClass2WithNestedClassDefinition);
yield return (typeof(TestClass3WithOverridenNestedClass), ExpectedTestClass3WithOverridenNestedClassDefinition);
yield return (typeof(TestClass4WithEnums), ExpectedTestClass4WithEnumsDefinition);
}
public static IEnumerable<object[]> CustomClassDefinitionTestData =>

View file

@ -166,19 +166,16 @@ public class CustomClassDefinition : HasPropertiesBase, ICustomTypeDefinition
case Type t when t.IsClass:
return new ClassProperty { Name = propertyInfo.Name, PropertyType = t.Name, Value = GetNestedProperties(propertyInfo.PropertyType, propertyInfo.GetValue(instance)) };
case Type t when t.IsEnum:
var isFlags = t.GetCustomAttributes(typeof(FlagsAttribute), false).Length != 0;
var enumDefinition = CustomEnumDefinition.FromEnum(t);
if (isFlags)
{
ISet<string> values = new HashSet<string>();
foreach (var value in t.GetEnumValues())
{
if (((int)value & (int)propertyInfo.GetValue(instance)) != 0) values.Add(t.GetEnumName(value));
}
return new EnumProperty { Name = propertyInfo.Name, PropertyType = t.Name, Value = values };
}
if (!enumDefinition.ValueAsFlags)
return new EnumProperty { Name = propertyInfo.Name, PropertyType = t.Name, Value = new HashSet<string> { propertyInfo.GetValue(instance).ToString() } };
return new EnumProperty { Name = propertyInfo.Name, PropertyType = t.Name, Value = new HashSet<string> { t.GetEnumName(propertyInfo.GetValue(instance)) } };
var flags = (Enum)propertyInfo.GetValue(instance);
var enumValues = Enum.GetValues(t).Cast<Enum>();
var enumNames = enumValues.Where(flags.HasFlag).Select(e => e.ToString());
return new EnumProperty { Name = propertyInfo.Name, PropertyType = t.Name, Value = enumNames.ToHashSet() };
default:
break;
}