DotTiled/src/DotTiled.Tests/UnitTests/Serialization/LoaderTests.cs

354 lines
12 KiB
C#
Raw Normal View History

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.Empty);
resourceCache.GetTemplate(Arg.Any<string>()).Returns(Optional.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.Empty);
resourceCache.GetTemplate(Arg.Any<string>()).Returns(Optional.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.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");
}
[Fact]
2024-11-16 21:14:23 +01:00
public void LoadMap_MapHasClassAndLoaderHasNoCustomTypes_ReturnsMapWithEmptyProperties()
{
// 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="TestClass" 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);
2024-11-16 21:14:23 +01:00
// Act
var result = loader.LoadMap("map.tmx");
// Assert
DotTiledAssert.AssertProperties([], result.Properties);
}
[Fact]
public void LoadMap_MapHasClassAndLoaderHasCustomTypeWithSameName_ReturnsMapWithPropertiesFromCustomClass()
{
// 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="TestClass" 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 customClassDefinition = new CustomClassDefinition
{
Name = "TestClass",
UseAs = CustomClassUseAs.All,
Members = [
new StringProperty { Name = "Test1", Value = "Hello" },
new IntProperty { Name = "Test2", Value = 42 }
]
};
var loader = new Loader(resourceReader, resourceCache, [customClassDefinition]);
// Act
var result = loader.LoadMap("map.tmx");
// Assert
DotTiledAssert.AssertProperties(customClassDefinition.Members, result.Properties);
}
public static IEnumerable<object[]> Maps => TestData.MapTests;
[Theory]
[MemberData(nameof(Maps))]
public void LoadMap_ValidFilesExternalTilesetsAndTemplatesWithCache_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 resourceReader = Substitute.For<IResourceReader>();
resourceReader.Read(Arg.Any<string>()).Returns(callInfo =>
{
var filePath = callInfo.Arg<string>();
return TestData.GetRawStringFor(filePath);
});
var loader = Loader.DefaultWith(
resourceReader: resourceReader,
customTypeDefinitions: customTypeDefinitions);
// Act
var map = loader.LoadMap(testDataFileWithFormat);
// Assert
Assert.NotNull(map);
DotTiledAssert.AssertMap(expectedMap(fileFormat[1..]), map);
}
}
}