Fix normalizer sidecar log and coverage test (#4)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-07 14:17:22 +09:00
parent 7920de15b3
commit 05c7a3f388
6 changed files with 251 additions and 31 deletions

View File

@@ -6,6 +6,9 @@ namespace Recordingtest.Normalizer;
public static class Normalizer
{
public static NormalizeResult Normalize(string input, string profileName)
=> Normalize(input, profileName, null);
public static NormalizeResult Normalize(string input, string profileName, string? sidecarPath)
{
var profile = Profile.Load(profileName);
var log = new List<RuleApplication>();
@@ -99,6 +102,20 @@ public static class Normalizer
}
break;
}
case "mask_volatile_settings":
{
if (isJson && jsonNode is not null)
{
var (n, c) = Rules.MaskVolatileSettings(jsonNode);
jsonNode = n;
log.Add(new RuleApplication(rule, c));
}
else
{
log.Add(new RuleApplication(rule, 0));
}
break;
}
case "sort_json_keys":
{
if (isJson && jsonNode is not null)
@@ -128,6 +145,36 @@ public static class Normalizer
output = current;
}
return new NormalizeResult(output, log);
var result = new NormalizeResult(output, log);
if (sidecarPath is not null)
{
string filePath;
if (Directory.Exists(sidecarPath))
{
filePath = Path.Combine(sidecarPath, "normalization.log");
}
else
{
var parent = Path.GetDirectoryName(sidecarPath);
if (!string.IsNullOrEmpty(parent) && !Directory.Exists(parent))
{
Directory.CreateDirectory(parent);
}
filePath = sidecarPath;
}
var sb = new System.Text.StringBuilder();
int total = 0;
foreach (var entry in log.OrderBy(l => l.RuleId, StringComparer.Ordinal))
{
sb.Append(entry.RuleId).Append("\tcount=").Append(entry.Count).Append('\n');
total += entry.Count;
}
sb.Append("total=").Append(total).Append('\n');
File.WriteAllText(filePath, sb.ToString());
}
return result;
}
}

View File

@@ -163,6 +163,66 @@ public static class Rules
return false;
}
/// <summary>
/// Allowlist of field names whose values are known to be volatile boolean/scalar
/// settings (per docs/sut-catalog/json-configs.json). The values are replaced with
/// a deterministic placeholder so golden-file comparisons stay stable while still
/// preserving the field's presence and key order.
/// </summary>
public static readonly HashSet<string> VolatileSettingFieldNames = new(StringComparer.Ordinal)
{
"CanOverrideWireColorWithFace",
"IsSidePanelVisible",
"OverrideFaceColor",
"Solar_IsLocalTime",
"VisibleGrid",
"GridSnap",
"MidpointOsnap",
"GridSpacing",
"GridColor.ALPHA",
"GridColor.BLUE",
"GridColor.GREEN",
"GridColor.RED",
"MajorGridColor.ALPHA",
"MajorGridColor.BLUE",
"MajorGridColor.GREEN",
"MajorGridColor.RED",
};
public static (JsonNode? node, int count) MaskVolatileSettings(JsonNode? node)
{
int count = 0;
if (node is null) return (null, 0);
Walk(node);
return (node, count);
void Walk(JsonNode n)
{
if (n is JsonObject obj)
{
foreach (var kv in obj.ToList())
{
if (VolatileSettingFieldNames.Contains(kv.Key))
{
obj[kv.Key] = JsonValue.Create("<VOLATILE>");
count++;
}
else if (kv.Value is JsonObject || kv.Value is JsonArray)
{
Walk(kv.Value);
}
}
}
else if (n is JsonArray arr)
{
foreach (var item in arr)
{
if (item is JsonObject || item is JsonArray) Walk(item);
}
}
}
}
/// <summary>
/// Returns a new JsonNode with object keys sorted recursively. Counts the number of objects sorted.
/// </summary>

View File

@@ -4,4 +4,5 @@ rules:
- mask_guids
- normalize_paths
- round_floats
- mask_volatile_settings
- sort_json_keys