From 88ceee46e5849d68f8295176bc6e59d6edea4555 Mon Sep 17 00:00:00 2001 From: Daniel Cronqvist Date: Wed, 27 Nov 2024 22:53:28 +0100 Subject: [PATCH] Add some test cases for the enum parsing bug and fix issue with .tmj format --- ...map-with-custom-type-props-without-defs.cs | 85 +++++++++++++++++++ ...ap-with-custom-type-props-without-defs.tmj | 68 +++++++++++++++ ...ap-with-custom-type-props-without-defs.tmx | 25 ++++++ .../UnitTests/Serialization/TestData.cs | 1 + .../Tmj/TmjReaderBase.Properties.cs | 31 +++++-- 5 files changed, 205 insertions(+), 5 deletions(-) create mode 100644 src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.cs create mode 100644 src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.tmj create mode 100644 src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.tmx diff --git a/src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.cs b/src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.cs new file mode 100644 index 0000000..4134dac --- /dev/null +++ b/src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.cs @@ -0,0 +1,85 @@ +using System.Globalization; + +namespace DotTiled.Tests; + +public partial class TestData +{ + public static Map MapWithCustomTypePropsWithoutDefs() => new Map + { + Class = "", + Orientation = MapOrientation.Orthogonal, + Width = 5, + Height = 5, + TileWidth = 32, + TileHeight = 32, + Infinite = false, + ParallaxOriginX = 0, + ParallaxOriginY = 0, + RenderOrder = RenderOrder.RightDown, + CompressionLevel = -1, + BackgroundColor = Color.Parse("#00000000", CultureInfo.InvariantCulture), + 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([ + 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.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 ClassProperty + { + Name = "customclassprop", + PropertyType = "CustomClass", + Value = [ + new BoolProperty { Name = "boolinclass", Value = true }, + new FloatProperty { Name = "floatinclass", Value = 13.37f }, + new StringProperty { Name = "stringinclass", Value = "This is a set string" } + ] + }, + new IntProperty + { + Name = "customenumintflagsprop", + Value = 6 + }, + new IntProperty + { + Name = "customenumintprop", + Value = 3 + }, + new StringProperty + { + Name = "customenumstringprop", + Value = "CustomEnumString_2" + }, + new StringProperty + { + Name = "customenumstringflagsprop", + Value = "CustomEnumStringFlags_1,CustomEnumStringFlags_2" + } + ] + }; +} diff --git a/src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.tmj b/src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.tmj new file mode 100644 index 0000000..74f892b --- /dev/null +++ b/src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.tmj @@ -0,0 +1,68 @@ +{ "compressionlevel":-1, + "height":5, + "infinite":false, + "layers":[ + { + "data":[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], + "height":5, + "id":1, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":5, + "x":0, + "y":0 + }], + "nextlayerid":2, + "nextobjectid":1, + "orientation":"orthogonal", + "properties":[ + { + "name":"customclassprop", + "propertytype":"CustomClass", + "type":"class", + "value": + { + "boolinclass":true, + "floatinclass":13.37, + "stringinclass":"This is a set string" + } + }, + { + "name":"customenumintflagsprop", + "propertytype":"CustomEnumIntFlags", + "type":"int", + "value":6 + }, + { + "name":"customenumintprop", + "propertytype":"CustomEnumInt", + "type":"int", + "value":3 + }, + { + "name":"customenumstringflagsprop", + "propertytype":"CustomEnumStringFlags", + "type":"string", + "value":"CustomEnumStringFlags_1,CustomEnumStringFlags_2" + }, + { + "name":"customenumstringprop", + "propertytype":"CustomEnumString", + "type":"string", + "value":"CustomEnumString_2" + }], + "renderorder":"right-down", + "tiledversion":"1.11.0", + "tileheight":32, + "tilesets":[], + "tilewidth":32, + "type":"map", + "version":"1.10", + "width":5 +} \ No newline at end of file diff --git a/src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.tmx b/src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.tmx new file mode 100644 index 0000000..cadc2fa --- /dev/null +++ b/src/DotTiled.Tests/TestData/Maps/map-with-custom-type-props-without-defs/map-with-custom-type-props-without-defs.tmx @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + +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 + + + diff --git a/src/DotTiled.Tests/UnitTests/Serialization/TestData.cs b/src/DotTiled.Tests/UnitTests/Serialization/TestData.cs index 28358b3..677dfb0 100644 --- a/src/DotTiled.Tests/UnitTests/Serialization/TestData.cs +++ b/src/DotTiled.Tests/UnitTests/Serialization/TestData.cs @@ -36,6 +36,7 @@ public static partial class TestData [GetMapPath("default-map"), (string f) => DefaultMap(), Array.Empty()], [GetMapPath("map-with-common-props"), (string f) => MapWithCommonProps(), Array.Empty()], [GetMapPath("map-with-custom-type-props"), (string f) => MapWithCustomTypeProps(), MapWithCustomTypePropsCustomTypeDefinitions()], + [GetMapPath("map-with-custom-type-props-without-defs"), (string f) => MapWithCustomTypePropsWithoutDefs(), Array.Empty()], [GetMapPath("map-with-embedded-tileset"), (string f) => MapWithEmbeddedTileset(), Array.Empty()], [GetMapPath("map-with-external-tileset"), (string f) => MapWithExternalTileset(f), Array.Empty()], [GetMapPath("map-with-flippingflags"), (string f) => MapWithFlippingFlags(f), Array.Empty()], diff --git a/src/DotTiled/Serialization/Tmj/TmjReaderBase.Properties.cs b/src/DotTiled/Serialization/Tmj/TmjReaderBase.Properties.cs index 6ea39e4..ae7ea1c 100644 --- a/src/DotTiled/Serialization/Tmj/TmjReaderBase.Properties.cs +++ b/src/DotTiled/Serialization/Tmj/TmjReaderBase.Properties.cs @@ -75,11 +75,7 @@ public abstract partial class TmjReaderBase { Name = name, PropertyType = propertyType, - Value = ReadPropertiesInsideClass(valueElement, new CustomClassDefinition - { - Name = propertyType, - Members = [] - }) + Value = ReadPropertiesInsideClass(valueElement, null) }; } @@ -104,6 +100,31 @@ public abstract partial class TmjReaderBase { List resultingProps = []; + if (customClassDefinition is null) + { + foreach (var prop in element.EnumerateObject()) + { + var name = prop.Name; + var value = prop.Value; + +#pragma warning disable IDE0072 // Add missing cases + IProperty property = value.ValueKind switch + { + JsonValueKind.String => new StringProperty { Name = name, Value = value.GetString() }, + JsonValueKind.Number => value.TryGetInt32(out var intValue) ? new IntProperty { Name = name, Value = intValue } : new FloatProperty { Name = name, Value = value.GetSingle() }, + JsonValueKind.True => new BoolProperty { Name = name, Value = true }, + JsonValueKind.False => new BoolProperty { Name = name, Value = false }, + JsonValueKind.Object => new ClassProperty { Name = name, PropertyType = "", Value = ReadPropertiesInsideClass(value, null) }, + _ => throw new JsonException("Invalid property type") + }; +#pragma warning restore IDE0072 // Add missing cases + + resultingProps.Add(property); + } + + return resultingProps; + } + foreach (var prop in customClassDefinition.Members) { if (!element.TryGetProperty(prop.Name, out var propElement))