Skip to content

Commit 6725bca

Browse files
committed
Fix #536 caused due to a failing test being "fixed"
Added additional unit test to prevent regression from occuring in the future
1 parent 55de78a commit 6725bca

File tree

2 files changed

+130
-31
lines changed

2 files changed

+130
-31
lines changed

src/IronyModManager.Parser.Tests/ModParserTests.cs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
// Created : 02-22-2020
55
//
66
// Last Modified By : Nick Butcher
7-
// Last Modified On : 12-12-2021
7+
// Last Modified On : 02-19-2025
88
// ***********************************************************************
99
// <copyright file="ModParserTests.cs" company="Mario">
1010
// Mario
1111
// </copyright>
1212
// <summary></summary>
1313
// ***********************************************************************
14+
1415
using System;
1516
using System.Collections.Generic;
1617
using System.Linq;
@@ -196,7 +197,7 @@ public void Should_parse_json_metadata_mod_file()
196197
{
197198
DISetup.SetupContainer();
198199

199-
var sb = new System.Text.StringBuilder();
200+
var sb = new StringBuilder();
200201
sb.AppendLine(@"{");
201202
sb.AppendLine(@" ""name"" : ""Test"",");
202203
sb.AppendLine(@" ""id"" : ""test"",");
@@ -233,5 +234,59 @@ public void Should_parse_json_metadata_mod_file()
233234
result.ReplacePath.Count().Should().Be(1);
234235
result.ReplacePath.FirstOrDefault().Should().Be("gfx/FX");
235236
}
237+
238+
/// <summary>
239+
/// Defines the test method Should_parse_json_metadata_mod_file_v2.
240+
/// </summary>
241+
[Fact]
242+
public void Should_parse_json_metadata_mod_file_v2()
243+
{
244+
DISetup.SetupContainer();
245+
246+
var sb = new StringBuilder();
247+
sb.AppendLine(@"{");
248+
sb.AppendLine(@" ""name"" : ""Test"",");
249+
sb.AppendLine(@" ""id"" : ""test"",");
250+
sb.AppendLine(@" ""version"" : """",");
251+
sb.AppendLine(@" ""supported_game_version"" : ""1.0.3"",");
252+
sb.AppendLine(@" ""short_description"" : """",");
253+
sb.AppendLine(@" ""tags"" : [""test"", ""test2"",],");
254+
sb.AppendLine(@" ""relationships"": [{");
255+
sb.AppendLine(@" ""rel_type"": ""dependency"",");
256+
sb.AppendLine(@" ""id"": ""com.github.Victoria-3-Modding-Co-op.Community-Mod-Framework"",");
257+
sb.AppendLine(@" ""display_name"": ""Community Mod Framework"",");
258+
sb.AppendLine(@" ""resource_type"": ""mod"",");
259+
sb.AppendLine(@" ""version"": ""1.*""");
260+
sb.AppendLine(@" }");
261+
sb.AppendLine(@" ],");
262+
sb.AppendLine(@" ""game_custom_data"" : { ");
263+
sb.AppendLine(@" ""user_dir"": [");
264+
sb.AppendLine(@" 1");
265+
sb.AppendLine(@" ], ");
266+
sb.AppendLine(@" ""replace_paths"" : [");
267+
sb.AppendLine(@" ""gfx/FX""");
268+
sb.AppendLine(@" ]");
269+
sb.AppendLine(@" }");
270+
sb.AppendLine(@"}");
271+
272+
273+
var parser = new ModParser(new Logger(), new CodeParser(new Logger()));
274+
var result = parser.Parse(sb.ToString().Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries), Common.DescriptorModType.JsonMetadata);
275+
result.Dependencies.Count().Should().Be(1);
276+
result.Dependencies.First().Should().Be("Community Mod Framework");
277+
result.FileName.Should().BeNullOrEmpty();
278+
result.Name.Should().Be("Test");
279+
result.Picture.Should().BeNullOrEmpty();
280+
result.RemoteId.Should().BeNull();
281+
result.Tags.Count().Should().Be(2);
282+
result.Tags.First().Should().Be("test");
283+
result.Tags.Last().Should().Be("test2");
284+
result.Version.Should().Be("1.0.3");
285+
result.UserDir.Count().Should().Be(1);
286+
result.UserDir.FirstOrDefault().Should().Be("1");
287+
result.ReplacePath.Count().Should().Be(1);
288+
result.ReplacePath.FirstOrDefault().Should().Be("gfx/FX");
289+
}
236290
}
237291
}
292+

src/IronyModManager.Parser/Mod/ModParser.cs

Lines changed: 73 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// Created : 02-22-2020
55
//
66
// Last Modified By : Mario
7-
// Last Modified On : 02-06-2025
7+
// Last Modified On : 02-19-2025
88
// ***********************************************************************
99
// <copyright file="ModParser.cs" company="Mario">
1010
// Mario
@@ -88,7 +88,10 @@ public IModObject Parse(IEnumerable<string> lines, DescriptorModType descriptorM
8888
/// <returns>JsonSerializerSettings.</returns>
8989
private JsonSerializerSettings GetJsonSerializerSettings()
9090
{
91-
jsonSerializerSettings ??= new JsonSerializerSettings { Error = (_, error) => error.ErrorContext.Handled = true, NullValueHandling = NullValueHandling.Ignore };
91+
jsonSerializerSettings ??= new JsonSerializerSettings
92+
{
93+
Error = (_, error) => error.ErrorContext.Handled = true, NullValueHandling = NullValueHandling.Ignore, Converters = new List<JsonConverter> { new JsonMetaDataConverter() }
94+
};
9295
return jsonSerializerSettings;
9396
}
9497

@@ -129,33 +132,7 @@ private IModObject ParseJsonMetadata(IEnumerable<string> lines)
129132
try
130133
{
131134
var json = string.Join(Environment.NewLine, lines);
132-
JsonMetadataBase result = null;
133-
var ex = new List<Exception>();
134-
try
135-
{
136-
result = JsonConvert.DeserializeObject<JsonMetadata>(json, GetJsonSerializerSettings());
137-
}
138-
catch (Exception e)
139-
{
140-
ex.Add(e);
141-
}
142-
143-
if (ex.Count > 0)
144-
{
145-
try
146-
{
147-
result = JsonConvert.DeserializeObject<JsonMetadataV2>(json, GetJsonSerializerSettings());
148-
}
149-
catch (Exception e)
150-
{
151-
ex.Add(e);
152-
}
153-
}
154-
155-
if (ex.Count >= 2)
156-
{
157-
throw new AggregateException(ex);
158-
}
135+
var result = JsonConvert.DeserializeObject<JsonMetadataBase>(json, GetJsonSerializerSettings());
159136

160137
if (result!.GameCustomData != null)
161138
{
@@ -327,6 +304,73 @@ private abstract class JsonMetadataBase
327304
#endregion Properties
328305
}
329306

307+
/// <summary>
308+
/// Class JsonMetaDataConverter.
309+
/// Implements the <see cref="Newtonsoft.Json.JsonConverter{IronyModManager.Parser.Mod.ModParser.JsonMetadataBase}" />
310+
/// </summary>
311+
/// <seealso cref="Newtonsoft.Json.JsonConverter{IronyModManager.Parser.Mod.ModParser.JsonMetadataBase}" />
312+
private class JsonMetaDataConverter : JsonConverter<JsonMetadataBase>
313+
{
314+
#region Methods
315+
316+
/// <summary>
317+
/// Reads the JSON representation of the object.
318+
/// </summary>
319+
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param>
320+
/// <param name="objectType">Type of the object.</param>
321+
/// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param>
322+
/// <param name="hasExistingValue">The existing value has a value.</param>
323+
/// <param name="serializer">The calling serializer.</param>
324+
/// <returns>The object value.</returns>
325+
public override JsonMetadataBase ReadJson(JsonReader reader, Type objectType, JsonMetadataBase existingValue, bool hasExistingValue, JsonSerializer serializer)
326+
{
327+
var obj = JObject.Load(reader);
328+
var relationshipToken = obj["relationships"];
329+
JsonMetadataBase result = null;
330+
if (relationshipToken != null)
331+
{
332+
result = relationshipToken.Type switch
333+
{
334+
JTokenType.Array => CheckArrayType(relationshipToken as JArray),
335+
_ => new JsonMetadataV2()
336+
};
337+
}
338+
339+
result ??= new JsonMetadataV2();
340+
serializer.Populate(obj.CreateReader(), result);
341+
return result;
342+
}
343+
344+
/// <summary>
345+
/// Writes the JSON representation of the object.
346+
/// </summary>
347+
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
348+
/// <param name="value">The value.</param>
349+
/// <param name="serializer">The calling serializer.</param>
350+
/// <exception cref="System.NotSupportedException"></exception>
351+
public override void WriteJson(JsonWriter writer, JsonMetadataBase value, JsonSerializer serializer)
352+
{
353+
throw new NotSupportedException();
354+
}
355+
356+
/// <summary>
357+
/// Checks the type of the array.
358+
/// </summary>
359+
/// <param name="token">The token.</param>
360+
/// <returns>JsonMetadataBase.</returns>
361+
private JsonMetadataBase CheckArrayType(JToken token)
362+
{
363+
if (token.All(p => p.Type == JTokenType.String))
364+
{
365+
return new JsonMetadata();
366+
}
367+
368+
return new JsonMetadataV2();
369+
}
370+
371+
#endregion Methods
372+
}
373+
330374
/// <summary>
331375
/// Class JsonMetadataV2.
332376
/// </summary>

0 commit comments

Comments
 (0)