mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Add tests for GameVersionConverter and fix edge case (#1726)
- Adds tests for GameVersionConverter - Refactors GameVersionConverter to reduce nesting - Fixes an edge case in GameVersion deserialization in which the JsonConstructor will be invoked even if no properties match - Adds a test for the GameVersion deserialization edge case
This commit is contained in:
parent
7fcd10ecd8
commit
d393fa64b6
4 changed files with 171 additions and 22 deletions
|
|
@ -109,26 +109,31 @@ public sealed class GameVersion : ICloneable, IComparable, IComparable<GameVersi
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the year component.
|
/// Gets the year component.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonRequired]
|
||||||
public int Year { get; } = -1;
|
public int Year { get; } = -1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the month component.
|
/// Gets the month component.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonRequired]
|
||||||
public int Month { get; } = -1;
|
public int Month { get; } = -1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the day component.
|
/// Gets the day component.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonRequired]
|
||||||
public int Day { get; } = -1;
|
public int Day { get; } = -1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the major version component.
|
/// Gets the major version component.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonRequired]
|
||||||
public int Major { get; } = -1;
|
public int Major { get; } = -1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the minor version component.
|
/// Gets the minor version component.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonRequired]
|
||||||
public int Minor { get; } = -1;
|
public int Minor { get; } = -1;
|
||||||
|
|
||||||
public static implicit operator GameVersion(string ver)
|
public static implicit operator GameVersion(string ver)
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,16 @@ public sealed class GameVersionConverter : JsonConverter
|
||||||
/// <param name="serializer">The calling serializer.</param>
|
/// <param name="serializer">The calling serializer.</param>
|
||||||
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||||
{
|
{
|
||||||
if (value == null)
|
switch (value)
|
||||||
{
|
{
|
||||||
writer.WriteNull();
|
case null:
|
||||||
}
|
writer.WriteNull();
|
||||||
else if (value is GameVersion)
|
break;
|
||||||
{
|
case GameVersion:
|
||||||
writer.WriteValue(value.ToString());
|
writer.WriteValue(value.ToString());
|
||||||
}
|
break;
|
||||||
else
|
default:
|
||||||
{
|
throw new JsonSerializationException("Expected GameVersion object value");
|
||||||
throw new JsonSerializationException("Expected GameVersion object value");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,24 +42,20 @@ public sealed class GameVersionConverter : JsonConverter
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (reader.TokenType == JsonToken.String)
|
||||||
{
|
{
|
||||||
if (reader.TokenType == JsonToken.String)
|
try
|
||||||
{
|
{
|
||||||
try
|
return new GameVersion((string)reader.Value!);
|
||||||
{
|
|
||||||
return new GameVersion((string)reader.Value!);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new JsonSerializationException($"Error parsing GameVersion string: {reader.Value}", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new JsonSerializationException($"Unexpected token or value when parsing GameVersion. Token: {reader.TokenType}, Value: {reader.Value}");
|
throw new JsonSerializationException($"Error parsing GameVersion string: {reader.Value}", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new JsonSerializationException($"Unexpected token or value when parsing GameVersion. Token: {reader.TokenType}, Value: {reader.Value}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
138
Dalamud.Test/Game/GameVersionConverterTests.cs
Normal file
138
Dalamud.Test/Game/GameVersionConverterTests.cs
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
using Dalamud.Common.Game;
|
||||||
|
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Dalamud.Test.Game;
|
||||||
|
|
||||||
|
public class GameVersionConverterTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void ReadJson_ConvertsFromString()
|
||||||
|
{
|
||||||
|
var serialized = """
|
||||||
|
{
|
||||||
|
"Version": "2020.06.15.0000.0000"
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
var deserialized = JsonConvert.DeserializeObject<TestSerializationClass>(serialized);
|
||||||
|
|
||||||
|
Assert.NotNull(deserialized);
|
||||||
|
Assert.Equal(GameVersion.Parse("2020.06.15.0000.0000"), deserialized.Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ReadJson_ConvertsFromNull()
|
||||||
|
{
|
||||||
|
var serialized = """
|
||||||
|
{
|
||||||
|
"Version": null
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
var deserialized = JsonConvert.DeserializeObject<TestSerializationClass>(serialized);
|
||||||
|
|
||||||
|
Assert.NotNull(deserialized);
|
||||||
|
Assert.Null(deserialized.Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ReadJson_WhenInvalidType_Throws()
|
||||||
|
{
|
||||||
|
var serialized = """
|
||||||
|
{
|
||||||
|
"Version": 2
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
Assert.Throws<JsonSerializationException>(
|
||||||
|
() => JsonConvert.DeserializeObject<TestSerializationClass>(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ReadJson_WhenInvalidVersion_Throws()
|
||||||
|
{
|
||||||
|
var serialized = """
|
||||||
|
{
|
||||||
|
"Version": "junk"
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
Assert.Throws<JsonSerializationException>(
|
||||||
|
() => JsonConvert.DeserializeObject<TestSerializationClass>(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WriteJson_ConvertsToString()
|
||||||
|
{
|
||||||
|
var deserialized = new TestSerializationClass
|
||||||
|
{
|
||||||
|
Version = GameVersion.Parse("2020.06.15.0000.0000"),
|
||||||
|
};
|
||||||
|
var serialized = JsonConvert.SerializeObject(deserialized);
|
||||||
|
|
||||||
|
Assert.Equal("""{"Version":"2020.06.15.0000.0000"}""", RemoveWhitespace(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WriteJson_ConvertsToNull()
|
||||||
|
{
|
||||||
|
var deserialized = new TestSerializationClass
|
||||||
|
{
|
||||||
|
Version = null,
|
||||||
|
};
|
||||||
|
var serialized = JsonConvert.SerializeObject(deserialized);
|
||||||
|
|
||||||
|
Assert.Equal("""{"Version":null}""", RemoveWhitespace(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WriteJson_WhenInvalidVersion_Throws()
|
||||||
|
{
|
||||||
|
var deserialized = new TestWrongTypeSerializationClass
|
||||||
|
{
|
||||||
|
Version = 42,
|
||||||
|
};
|
||||||
|
Assert.Throws<JsonSerializationException>(() => JsonConvert.SerializeObject(deserialized));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanConvert_WhenGameVersion_ReturnsTrue()
|
||||||
|
{
|
||||||
|
var converter = new GameVersionConverter();
|
||||||
|
Assert.True(converter.CanConvert(typeof(GameVersion)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanConvert_WhenNotGameVersion_ReturnsFalse()
|
||||||
|
{
|
||||||
|
var converter = new GameVersionConverter();
|
||||||
|
Assert.False(converter.CanConvert(typeof(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanConvert_WhenNull_ReturnsFalse()
|
||||||
|
{
|
||||||
|
var converter = new GameVersionConverter();
|
||||||
|
Assert.False(converter.CanConvert(null!));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string RemoveWhitespace(string input)
|
||||||
|
{
|
||||||
|
return input.Replace(" ", "").Replace("\r", "").Replace("\n", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestSerializationClass
|
||||||
|
{
|
||||||
|
[JsonConverter(typeof(GameVersionConverter))]
|
||||||
|
[CanBeNull]
|
||||||
|
public GameVersion Version { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestWrongTypeSerializationClass
|
||||||
|
{
|
||||||
|
[JsonConverter(typeof(GameVersionConverter))]
|
||||||
|
public int Version { get; init; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -225,6 +225,17 @@ namespace Dalamud.Test.Game
|
||||||
Assert.Throws<ArgumentOutOfRangeException>(() => JsonConvert.DeserializeObject<GameVersion>(serialized));
|
Assert.Throws<ArgumentOutOfRangeException>(() => JsonConvert.DeserializeObject<GameVersion>(serialized));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void VersionInvalidTypeDeserialization()
|
||||||
|
{
|
||||||
|
var serialized = """
|
||||||
|
{
|
||||||
|
"Value": "Hello"
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
Assert.Throws<JsonSerializationException>(() => JsonConvert.DeserializeObject<GameVersion>(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void VersionConstructorNegativeYear()
|
public void VersionConstructorNegativeYear()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue