champions-of-luneraria/Assets/Luneraria/Tests/Core/SuiteReport.cs
Martin Stickelbroeck 44d3bcdee9 U1.5 Unity Core Integration (1/2): Unity-Projekt, Test Runner, Diagnose
- Projekt mit Unity 6.3 LTS (6000.3.20f1, Personal) geöffnet: ProjectSettings,
  .meta-Dateien, URP-Global-Settings, packages-lock.json.
- Manifest auf die benötigten Pakete zurückgeführt; Unity hatte beim ersten
  Öffnen Vorlagenpakete ergänzt (Purchasing, Analytics, Collab, XR, 2D, Navigation).
- Test Runner: Die U1-Suiten laufen unverändert als EditMode-Tests; mit
  LUNE_TEST_REPORT schreiben .NET und Unity dasselbe JSON-Protokoll (SuiteReport).
- Golden-Vergleich zusätzlich je Fachbereich (Gold, HP, Positionen, Türme,
  Ancients, Wellen, Helden, Boss, Gewinner, ...). Nur Bericht; Testwerte und
  Prüfungsanzahl unverändert.
- Diagnose: FloatProbe (Kern-Arithmetik gegen Godot-Bits und Auswertungsart der
  Laufzeit), DivergenceTrace und tools/port/trace_diff.py (erster abweichender
  Schritt), CoreBenchmark für .NET und Editor, CoreBatch als -executeMethod-Einstieg.
- .NET-Harness baut nach tools/out/, weil Unity Temp/ beim Beenden löscht.
- .gitignore ignoriert nur noch die csproj/sln im Projektwurzelverzeichnis;
  die Projektdateien des .NET-Harness fehlten deshalb in U1 und kommen jetzt dazu.

Stand dieses Commits im Unity-Editor (Mono): 4 von 5 Suiten grün; golden
152/157, weil Mono float32-Zwischenwerte doppelt genau rechnet (Teil 2/2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:19:08 +02:00

64 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
namespace Luneraria.Core.Tests
{
/// <summary>
/// JSON protocol of a suite run, identical for the .NET harness and the Unity Test Runner
/// (docs/port/logs/u1/core-tests.json, docs/port/logs/u1_5/*.json). The target file comes from
/// the environment variable LUNE_TEST_REPORT; without it nothing is written.
/// </summary>
public sealed class SuiteReport
{
readonly StringBuilder _suites = new StringBuilder();
int _count;
public int Failures { get; private set; }
public static string TargetPath { get { return Environment.GetEnvironmentVariable("LUNE_TEST_REPORT"); } }
public void Add(CheckSuite suite, double seconds)
{
Failures += suite.Failures.Count;
_suites.Append(_count == 0 ? "" : ",\n");
_count++;
_suites.AppendFormat(CultureInfo.InvariantCulture, " {{\"suite\": \"{0}\", \"checks\": {1}, \"failures\": {2}, \"seconds\": {3:0.00}, \"failed\": [{4}], \"notes\": [{5}]}}",
suite.Name, suite.Checks, suite.Failures.Count, seconds, Join(suite.Failures), Join(suite.Notes));
}
public string ToJson(string runtime, string label)
{
var text = new StringBuilder("{\n \"suites\": [\n");
text.Append(_suites);
text.Append("\n ],\n");
text.Append(" \"runtime\": \"" + Escape(runtime) + "\",\n");
text.Append(" \"label\": \"" + Escape(label) + "\",\n");
text.Append(" \"os\": \"" + Escape(System.Runtime.InteropServices.RuntimeInformation.OSDescription + " " + System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture) + "\"\n}\n");
return text.ToString();
}
public void WriteTo(string path, string runtime, string label)
{
string directory = Path.GetDirectoryName(Path.GetFullPath(path));
if (!string.IsNullOrEmpty(directory))
Directory.CreateDirectory(directory);
File.WriteAllText(path, ToJson(runtime, label));
}
static string Join(List<string> values)
{
var parts = new List<string>();
foreach (string value in values)
parts.Add("\"" + Escape(value) + "\"");
return string.Join(", ", parts);
}
static string Escape(string value)
{
return value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n");
}
}
}