Make another pass through moves file
All checks were successful
Build / Build (push) Successful in 47s

This commit is contained in:
2025-05-18 14:15:37 +02:00
parent 9ff4745c0a
commit cbd4340b13
11 changed files with 322 additions and 17 deletions

View File

@@ -1,6 +1,11 @@
using System.Buffers;
using System.Text.Json;
using PkmnLib.Dynamic.Libraries;
using PkmnLib.Dynamic.Libraries.DataLoaders.Models;
using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Dynamic.ScriptHandling.Registry;
using PkmnLib.Static.Moves;
using TUnit.Core.Logging;
namespace PkmnLib.Plugin.Gen7.Tests.DataTests;
@@ -84,4 +89,106 @@ public class MoveDataTests
await Assert.That(test.Library.ScriptResolver.TryResolve(ScriptCategory.Status, status, null, out _)).IsTrue();
}
public record HasEitherEffectOrComment(string MoveName, bool HasEffect, bool HasComment)
{
/// <inheritdoc />
public override string ToString() => MoveName + " has effect: " + HasEffect + ", comment: " + HasComment;
}
public static IEnumerable<Func<HasEitherEffectOrComment>> EveryMoveHasEitherEffectOrCommentData()
{
IResourceProvider plugin = new Gen7Plugin();
using var movesJson = plugin.GetResource(ResourceFileType.Moves)!.Open();
var json = new BinaryReader(movesJson);
var moves = json.ReadBytes((int)movesJson.Length);
var reader = new Utf8JsonReader(new ReadOnlySequence<byte>(moves), new JsonReaderOptions
{
CommentHandling = JsonCommentHandling.Allow,
AllowTrailingCommas = true,
});
Console.WriteLine("Reading moves.json");
// The JSON is an object { "data": [] }.
// Each move is an object in the "data" array.
// Each object needs to have either an "effect" or a "comment" property.
// Read the first object
reader.Read();
// Read the properties, until we find the "data" property
while (reader.TokenType != JsonTokenType.PropertyName || reader.GetString() != "data")
{
reader.Read();
}
// Read the "data" property
reader.Read();
// Read the start of the array
reader.Read();
var results = new List<HasEitherEffectOrComment>();
// Read each move object
while (reader.TokenType != JsonTokenType.EndArray)
{
// Read the start of the object
if (!reader.Read())
break;
// Read each property
var name = "";
var hasEffect = false;
var hasComment = false;
while (reader.TokenType != JsonTokenType.EndObject)
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
if (propertyName == "name")
{
reader.Read();
name = reader.GetString()!;
}
else if (propertyName == "effect")
{
hasEffect = true;
reader.Read();
// Read the effect object
while (reader.TokenType != JsonTokenType.EndObject)
{
reader.Read();
if (reader.TokenType != JsonTokenType.StartObject)
continue;
while (reader.TokenType != JsonTokenType.EndObject)
{
reader.Read();
}
reader.Read();
}
}
}
else if (reader.TokenType == JsonTokenType.Comment)
{
// Read the comment
var comment = reader.GetComment();
hasComment = comment.Trim() == "No secondary effect";
}
reader.Read();
}
results.Add(new HasEitherEffectOrComment(name, hasEffect, hasComment));
}
return results.Where(x => !string.IsNullOrWhiteSpace(x.MoveName))
.Select<HasEitherEffectOrComment, Func<HasEitherEffectOrComment>>(x => () => x).ToList();
}
/// <summary>
/// To ensure that all moves have been properly implemented, we require that each move has either an "effect" property,
/// or a comment with the exact text "No secondary effect". This ensures that we have not missed any moves.
///
/// The implementation of this test is a bit tricky, as we need to read the JSON file and parse it ourselves,
/// as System.Text.Json does not support reading comments in JSON files beyond the low-level API.
/// </summary>
/// <param name="test"></param>
[Test, MethodDataSource(nameof(EveryMoveHasEitherEffectOrCommentData))]
public async Task AllMovesHaveEitherEffectOrComment(HasEitherEffectOrComment test) =>
// Check that each move has either an "effect" or a "comment" property
await Assert.That(test.HasEffect || test.HasComment).IsTrue();
}