• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MeltyPlayer / MeltyTool / 22551907903

01 Mar 2026 08:26PM UTC coverage: 41.595% (+0.06%) from 41.54%
22551907903

push

github

MeltyPlayer
Set up a little project for loading Mario Kart 3d tracks.

6988 of 18904 branches covered (36.97%)

Branch coverage included in aggregate %.

0 of 52 new or added lines in 4 files covered. (0.0%)

726 existing lines in 36 files now uncovered.

29926 of 69843 relevant lines covered (42.85%)

62490.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.93
/FinModelUtility/Fin/Fin.Testing/src/GoldenAssert.cs
1
using System.Reflection;
2
using System.Text;
3

4
using fin.image;
5
using fin.io;
6
using fin.util.asserts;
7
using fin.util.exceptions;
8
using fin.util.strings;
9

10
using Microsoft.VisualStudio.TestTools.UnitTesting;
11

12
using SixLabors.ImageSharp.PixelFormats;
13

14

15
namespace fin.testing;
16

17
public static partial class GoldenAssert {
18
  private const string TMP_NAME = "tmp";
19

20
  public static ISystemDirectory GetRootGoldensDirectory(
21
      Assembly executingAssembly) {
28✔
22
    var assemblyName =
28✔
23
        executingAssembly.ManifestModule.Name.SubstringUpTo(".dll");
28✔
24

25
    var executingAssemblyDll = new FinFile(executingAssembly.Location);
28✔
26
    var executingAssemblyDir = executingAssemblyDll.AssertGetParent();
28✔
27

28
    var currentDir = executingAssemblyDir;
28✔
29
    while (!currentDir.Name.Equals(assemblyName,
140✔
30
                                   StringComparison.OrdinalIgnoreCase)) {
252✔
31
      currentDir = currentDir.AssertGetParent();
112✔
32
    }
112✔
33

34
    Assert.IsNotNull(currentDir);
28✔
35

36
    var gloTestsDir = currentDir;
28✔
37
    var goldensDirectory = gloTestsDir.AssertGetExistingSubdir("goldens");
28✔
38

39
    return goldensDirectory;
28✔
40
  }
28✔
41

42
  public static IEnumerable<IFileHierarchyDirectory> GetGoldenDirectories(
43
      ISystemDirectory rootGoldenDirectory) {
25✔
44
    var hierarchy = FileHierarchy.From(rootGoldenDirectory);
25✔
45
    return hierarchy.Root.GetExistingSubdirs()
25✔
46
                    .Where(subdir => !subdir.Name.SequenceEqual(TMP_NAME));
101✔
47
  }
25✔
48

49
  public static async Task AssertGoldenFiles(
50
      IFileHierarchyDirectory goldenSubdir,
51
      Action<IFileHierarchyDirectory, ISystemDirectory> handler) {
88✔
52
    var inputDirectory = goldenSubdir.AssertGetExistingSubdir("input");
88✔
53
    var outputDirectory = goldenSubdir.AssertGetExistingSubdir("output");
88✔
54

55
    if (outputDirectory.IsEmpty) {
88!
56
      handler(inputDirectory, outputDirectory.Impl);
×
57
      return;
×
58
    }
59

60
    var tmpDirectory = FinFileSystem.CreateVirtualTempDirectory();
88✔
61
    handler(inputDirectory, tmpDirectory);
88✔
62

63
    await GoldenAssert.AssertFilesInDirectoriesAreIdentical_(
88✔
64
        tmpDirectory,
88✔
65
        outputDirectory.Impl);
88✔
66

67
    tmpDirectory.Delete(true);
88✔
68
  }
88✔
69

70
  private static async Task AssertFilesInDirectoriesAreIdentical_(
71
      IReadOnlyTreeDirectory lhs,
72
      IReadOnlyTreeDirectory rhs) {
88✔
73
    var lhsFiles = lhs.GetExistingFiles()
88✔
74
                      .ToDictionary(file => file.Name.ToString());
5,851✔
75
    var rhsFiles = rhs.GetExistingFiles()
88✔
76
                      .ToDictionary(file => file.Name.ToString());
5,851✔
77

78
    var lhsFullPaths = lhsFiles.Keys.ToHashSet();
88✔
79
    var rhsFullPaths = rhsFiles.Keys.ToHashSet();
88✔
80

81
    if (!lhsFullPaths.SetEquals(rhsFullPaths)) {
88!
82
      var lhsOnly = lhsFullPaths.Where(v => !rhsFullPaths.Contains(v))
×
83
                                .Order()
×
84
                                .ToArray();
×
85
      var rhsOnly = rhsFullPaths.Where(v => !lhsFullPaths.Contains(v))
×
86
                                .Order()
×
87
                                .ToArray();
×
88

89
      var sb = new StringBuilder();
×
90
      sb.AppendLine(
×
91
          "Expected fileset to be identical to golden's, but there were the following differences:");
×
92

93
      if (lhsOnly.Length > 0) {
×
94
        sb.AppendLine("Lhs only:");
×
95
        foreach (var lhsPath in lhsOnly) {
×
96
          sb.AppendLine($" - {lhsPath}");
×
97
        }
×
98
      }
×
99

100
      if (rhsOnly.Length > 0) {
×
101
        sb.AppendLine("Rhs only:");
×
102
        foreach (var rhsPath in rhsOnly) {
×
103
          sb.AppendLine($" - {rhsPath}");
×
104
        }
×
105
      }
×
106

107
      Assert.Fail(sb.ToString());
×
108
    }
×
109

110
    foreach (var (name, lhsFile) in lhsFiles) {
17,553✔
111
      var rhsFile = rhsFiles[name];
5,763✔
112

113
      await AnnotatedException.SpaceAsync(
5,763✔
114
          $"Found a change in file {name}:\n",
5,763✔
115
          async () => {
5,763✔
116
            await AssertFilesAreIdentical_(lhsFile, rhsFile);
5,763✔
117
          });
11,526✔
118
    }
5,763✔
119
  }
88✔
120

121
  private static async Task AssertFilesAreIdentical_(
122
      IReadOnlyTreeFile lhs,
123
      IReadOnlyTreeFile rhs) {
5,763✔
124
    var lhsAndRhsBytes
5,763✔
125
        = await Task.WhenAll(lhs.ReadAllBytesAsync(),
5,763✔
126
                             rhs.ReadAllBytesAsync());
5,763✔
127

128
    var lhsBytes = lhsAndRhsBytes[0];
5,763✔
129
    var rhsBytes = lhsAndRhsBytes[1];
5,763✔
130

131
    try {
5,763✔
132
      Assert.IsTrue(lhsBytes.SequenceEqual(rhsBytes));
5,763✔
133
    } catch (Exception e) {
5,821✔
134
      if (lhs.FileType.ToLower() is ".bmp"
58!
135
                                    or ".jpg"
58✔
136
                                    or ".jpeg"
58✔
137
                                    or ".gif"
58✔
138
                                    or ".png") {
116✔
139
        AssertImageFilesAreIdentical_(lhs, rhs);
58✔
140
      } else if (lhs.FileType.ToLower() is ".glb" or ".gltf") {
58!
141
        AssertModelFilesAreIdentical_(lhs, rhs);
×
142
        Asserts.SpansEqual(lhsBytes, rhsBytes);
×
UNCOV
143
      } else if (lhs.FileType.ToLower() is ".glsl") {
×
144
        Assert.AreEqual(lhs.ReadAllText(), rhs.ReadAllText());
×
UNCOV
145
      } else {
×
UNCOV
146
        Asserts.SpansEqual(lhsBytes, rhsBytes);
×
147
      }
×
148
    }
58✔
149
  }
5,763✔
150

151
  private static void AssertImageFilesAreIdentical_(
152
      IReadOnlyTreeFile lhs,
153
      IReadOnlyTreeFile rhs,
154
      float allowableError = 2) {
58✔
155
    using var lhsImage = FinImage.FromFile(lhs);
58✔
156
    using var rhsImage = FinImage.FromFile(rhs);
58✔
157

158
    Assert.AreEqual(lhsImage.Width, rhsImage.Width);
58✔
159
    Assert.AreEqual(lhsImage.Height, rhsImage.Height);
58✔
160

161
    lhsImage.Access(lhsGet => {
116✔
162
      rhsImage.Access(rhsGet => {
116✔
163
        for (var y = 0; y < lhsImage.Height; ++y) {
26,108✔
164
          for (var x = 0; x < lhsImage.Width; ++x) {
15,710,160✔
165
            lhsGet(x,
5,230,944✔
166
                   y,
5,230,944✔
167
                   out var lhsR,
5,230,944✔
168
                   out var lhsG,
5,230,944✔
169
                   out var lhsB,
5,230,944✔
170
                   out var lhsA);
5,230,944✔
171

58✔
172
            rhsGet(x,
5,230,944✔
173
                   y,
5,230,944✔
174
                   out var rhsR,
5,230,944✔
175
                   out var rhsG,
5,230,944✔
176
                   out var rhsB,
5,230,944✔
177
                   out var rhsA);
5,230,944✔
178

58✔
179
            var lPixel = new Rgba32(lhsR, lhsG, lhsB, lhsA);
5,230,944✔
180
            var rPixel = new Rgba32(rhsR, rhsG, rhsB, rhsA);
5,230,944✔
181

58✔
182
            if (Math.Abs(lhsR - rhsR) > allowableError ||
5,230,944!
183
                Math.Abs(lhsG - rhsG) > allowableError ||
5,230,944✔
184
                Math.Abs(lhsB - rhsB) > allowableError ||
5,230,944✔
185
                Math.Abs(lhsA - rhsA) > allowableError) {
5,230,944✔
186
              Asserts.Fail(
×
187
                  $"Files with name \"{lhs.Name}\" are different at pixel ({x},{y}): {lPixel} / {rPixel}");
×
188
            }
×
189
          }
5,230,944✔
190
        }
8,664✔
191
      });
116✔
192
    });
116✔
193
  }
116✔
194
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc