PKHeX/Tests/PKHeX.Core.Tests/Util/StringQualityTests.cs
Kurt 47071b41f3
Refactoring: Span-based value writes and method signatures (#3361)
Existing `get`/`set` logic is flawed in that it doesn't work on Big Endian operating systems, and it allocates heap objects when it doesn't need to.

`System.Buffers.Binary.BinaryPrimitives` in the `System.Memory` NuGet package provides both Little Endian and Big Endian methods to read and write data; all the `get`/`set` operations have been reworked to use this new API. This removes the need for PKHeX's manual `BigEndian` class, as all functions are already covered by the BinaryPrimitives API.

The `StringConverter` has now been rewritten to accept a Span to read from & write to, no longer requiring a temporary StringBuilder.

Other Fixes included:
- The Super Training UI for Gen6 has been reworked according to the latest block structure additions.
- Cloning a Stadium2 Save File now works correctly (opening from the Folder browser list).
- Checksum & Sanity properties removed from parent PKM class, and is now implemented via interface.
2022-01-02 21:35:59 -08:00

99 lines
No EOL
3.2 KiB
C#

using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using PKHeX.Core;
using Xunit;
namespace PKHeX.Tests.Util
{
public class StringQualityTests
{
[Theory]
[InlineData("ja")]
[InlineData("en")]
[InlineData("it")]
[InlineData("de")]
[InlineData("fr")]
[InlineData("es")]
[InlineData("ko")]
[InlineData("zh")]
public void HasNoDuplicates(string language)
{
CheckMetLocations(language);
CheckItemNames(language);
CheckMoveNames(language);
}
private static void CheckMoveNames(string language)
{
var strings = GameInfo.GetStrings(language);
var arr = strings.movelist;
var duplicates = GetDuplicates(arr);
duplicates.Count.Should().Be(0, "expected no duplicate strings.");
}
private static void CheckItemNames(string language)
{
var strings = GameInfo.GetStrings(language);
var arr = strings.itemlist;
var duplicates = GetDuplicates(arr);
var questionmarks = arr[129];
duplicates.RemoveAll(z => z == questionmarks);
duplicates.Count.Should().Be(0, "expected no duplicate strings.");
}
private static List<string> GetDuplicates(string[] arr)
{
var hs = new HashSet<string>();
var duplicates = new List<string>();
foreach (var line in arr)
{
if (line.Length == 0)
continue;
if (hs.Contains(line))
duplicates.Add(line);
hs.Add(line);
}
return duplicates;
}
private static void CheckMetLocations(string language)
{
var strings = GameInfo.GetStrings(language);
const string prefix = "met";
nameof(strings.metBW2_00000).StartsWith(prefix).Should()
.BeTrue("expected field name to exist prior to using reflection to fetch all");
var metstrings = typeof(GameStrings).GetFields().Where(z => z.Name.StartsWith(prefix));
bool iterated = false;
var duplicates = new List<string>();
foreach (var p in metstrings)
{
iterated = true;
var name = p.Name;
var value = p.GetValue(strings);
Assert.NotNull(value);
var arr = (string[])value!;
var hs = new HashSet<string>();
bool sm0 = name == nameof(GameStrings.metSM_00000);
for (int i = 0; i < arr.Length; i++)
{
var line = arr[i];
if (line.Length == 0)
continue;
if (sm0 && i % 2 != 0)
continue;
if (hs.Contains(line))
duplicates.Add($"{name}\t{line}");
hs.Add(line);
}
}
duplicates.Count.Should().Be(0, "expected no duplicate strings.");
iterated.Should().BeTrue();
}
}
}