Skip to content

Commit 9e20ca6

Browse files
committed
[T] 增补一个中二官谱
1 parent fa5e32f commit 9e20ca6

5 files changed

Lines changed: 4892 additions & 7 deletions

File tree

tests/chu/ChuTests.cs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void C2sRoundTrip(string c2sPath)
3737
AssertNotesEqual(chart.Notes, reparsed.Notes);
3838
}
3939

40-
private static void AssertNotesEqual(IReadOnlyList<ChuNote> expected_, IReadOnlyList<ChuNote> actual_)
40+
private static void AssertNotesEqual(IReadOnlyList<ChuNote> expected_, IReadOnlyList<ChuNote> actual_, bool allowExDiff = false)
4141
{
4242
const string EOF = "<EOF>";
4343
List<ChuNote> expected = expected_.ToList();
@@ -49,14 +49,14 @@ private static void AssertNotesEqual(IReadOnlyList<ChuNote> expected_, IReadOnly
4949
if (i >= expected.Count || i >= actual.Count) result = false;
5050
else
5151
{
52-
result = CompareNote(expected[i], actual[i]);
52+
result = CompareNote(expected[i], actual[i], allowExDiff);
5353
if (!result)
5454
{
5555
// 尝试同一时刻的其他行有无相同的,如果有,交换之
5656
var j = i + 1;
5757
while (j < expected.Count && expected[j].Time == actual[i].Time)
5858
{
59-
if (CompareNote(expected[j], actual[i]))
59+
if (CompareNote(expected[j], actual[i], allowExDiff))
6060
{
6161
(expected[j], expected[i]) = (expected[i], expected[j]);
6262
result = true;
@@ -79,23 +79,43 @@ private static void AssertNotesEqual(IReadOnlyList<ChuNote> expected_, IReadOnly
7979
/// <summary>
8080
/// 比较两个音符是否实质等同;时间与时长等字段可命中宽容规则(见测试类内常量与分支注释)。
8181
/// </summary>
82-
public static bool CompareNote(ChuNote expected, ChuNote actual)
82+
public static bool CompareNote(ChuNote expected, ChuNote actual, bool allowExDiff = false)
8383
{
84-
if (expected.Type != actual.Type) return false;
84+
if (!TypesEquivalent(expected.Type, actual.Type, allowExDiff)) return false;
8585
if (!TimesEquivalent(expected.Time, actual.Time)) return false;
8686
if (!DurationsEquivalent(expected, actual)) return false;
8787
if (expected.Cell != actual.Cell || expected.Width != actual.Width) return false;
8888
if (expected.EndCell != actual.EndCell || expected.EndWidth != actual.EndWidth) return false;
8989
if (Math.Abs(expected.Height - actual.Height) > 0.05m || Math.Abs(expected.EndHeight - actual.EndHeight) > 0.05m) return false;
9090
if (expected.CrushInterval != actual.CrushInterval) return false;
9191
if (!TagsEquivalent(expected, actual)) return false;
92-
if (expected.TargetNote != actual.TargetNote) return false;
92+
if (!TypesEquivalent(expected.TargetNote, actual.TargetNote, allowExDiff)) return false;
9393
return true;
9494
}
9595

9696
/// <summary>规则 (a):time 相差 ≤ 1/768 视为相等。</summary>
9797
private static bool TimesEquivalent(Rational a, Rational b) => (a - b).Abs() <= Tol768;
9898

99+
/// <summary>
100+
/// 类型比较。<paramref name="allowExDiff"/> 为 true 时,HLD/HXD、SLD/SXD、SLC/SXC 之间允许互相匹配
101+
/// (即忽略 Ex 标志位差异);否则要求严格相等。
102+
/// </summary>
103+
private static bool TypesEquivalent(string e, string a, bool allowExDiff)
104+
{
105+
if (e == a) return true;
106+
if (!allowExDiff) return false;
107+
return StripExFlag(e) == StripExFlag(a);
108+
109+
static string StripExFlag(string t) => t switch
110+
{
111+
"HXD" => "HLD",
112+
"SXD" => "SLD",
113+
"SXC" => "SLC",
114+
"AHX" => "AHD",
115+
_ => t,
116+
};
117+
}
118+
99119
/// <summary>
100120
/// 规则 (b):|Δduration| ≤ 1/768,或(|Δduration| ≤ 1/384 且 |ΔendTime| ≤ 1/768)时视为 duration 语义相等。
101121
/// </summary>
@@ -158,6 +178,6 @@ public void C2sToUgcViaGenerator(string c2sPath)
158178
// 再把转出来的ugc,parse回去,比较是否和一开始的c2s等价
159179
var (ugcReparsed, _) = new UgcParser().Parse(ugcText);
160180
Assert.NotEmpty(ugcReparsed.Notes);
161-
AssertNotesEqual(c2s.Notes, ugcReparsed.Notes.Where(n => n.Type != "CLICK").ToList());
181+
AssertNotesEqual(c2s.Notes, ugcReparsed.Notes.Where(n => n.Type != "CLICK").ToList(), allowExDiff: true);
162182
}
163183
}

0 commit comments

Comments
 (0)