Forge
csharpdeeb25a2
1using Xunit;
2
3namespace CascadeIDE.Tests;
4
5public sealed class IntentMelodyCatalogWireTests
6{
7 [Fact]
8 public void ParseBundle_unknown_wire_class_throws()
9 {
10 const string toml =
11 """
12 intent_catalog_schema_version = 2
13 melody_catalog_schema_version = 1
14 [[tail_wire_class]]
15 id = "ok"
16 kind = "delimited_slots"
17 between_slots_any_of = [":"]
18 [[command]]
19 command_id = "select"
20 melody_slug = "x"
21 melody_shape = "parametric"
22 melody_tail_signature = "<start:int>:<end:int>"
23 melody_wire_class = "missing"
24 melody_chord_commit = "enter"
25 """;
26
27 var ex = Assert.Throws<InvalidOperationException>(() =>
28 IntentMelodyAliases.ParseBundleForTests(toml.Trim()));
29
30 Assert.Contains("missing", ex.Message, StringComparison.OrdinalIgnoreCase);
31 }
32
33 [Fact]
34 public void ParseBundle_wire_kind_mismatch_delimited_requires_two_int_slots()
35 {
36 const string toml =
37 """
38 intent_catalog_schema_version = 2
39 melody_catalog_schema_version = 1
40 [[tail_wire_class]]
41 id = "del"
42 kind = "delimited_slots"
43 between_slots_any_of = [":"]
44 [[command]]
45 command_id = "cmd"
46 melody_slug = "x"
47 melody_shape = "parametric"
48 melody_tail_signature = "<url:url>"
49 melody_wire_class = "del"
50 melody_chord_commit = "enter"
51 """;
52
53 var ex = Assert.Throws<InvalidOperationException>(() =>
54 IntentMelodyAliases.ParseBundleForTests(toml.Trim()));
55
56 Assert.Contains("DelimitedSlots", ex.Message, StringComparison.Ordinal);
57 }
58
59 [Fact]
60 public void ParseBundle_wire_kind_mismatch_single_remainder_requires_url_slot()
61 {
62 const string toml =
63 """
64 intent_catalog_schema_version = 2
65 melody_catalog_schema_version = 1
66 [[tail_wire_class]]
67 id = "sr"
68 kind = "single_remainder"
69 [[command]]
70 command_id = "cmd"
71 melody_slug = "x"
72 melody_shape = "parametric"
73 melody_tail_signature = "<a:int>:<b:int>"
74 melody_wire_class = "sr"
75 melody_chord_commit = "enter"
76 """;
77
78 var ex = Assert.Throws<InvalidOperationException>(() =>
79 IntentMelodyAliases.ParseBundleForTests(toml.Trim()));
80
81 Assert.Contains("SingleRemainder", ex.Message, StringComparison.Ordinal);
82 }
83
84 [Fact]
85 public void ChordDefersInstantExecute_respects_enter_vs_instant_commit()
86 {
87 var enterCommit = new MelodyRootEntry(
88 "p",
89 "cmd",
90 IntentMelodyShape.Parametric,
91 ShowUsageHintIfBareSlug: false,
92 TailSignature: "<start:ln>:<end:ln>",
93 WireClass: "int_chain_colon_space",
94 ChordCommit: "enter",
95 PaletteHintSlug: null);
96
97 var instantCommit = enterCommit with { ChordCommit = "instant" };
98
99 Assert.True(ParametricIntentMelody.ChordDefersInstantExecuteForMelodyRoot(enterCommit));
100 Assert.False(ParametricIntentMelody.ChordDefersInstantExecuteForMelodyRoot(instantCommit));
101 }
102
103 [Fact]
104 public void ResolvePaletteHintKey_falls_back_to_slug_when_field_absent()
105 {
106 Assert.Equal("gs", ParametricIntentMelody.ResolvePaletteHintKey("gs"));
107 }
108
109 [Fact]
110 public void ResolvePaletteHintKey_uses_bundled_palette_hint_slug_for_wai()
111 {
112 Assert.Equal("wai-url", ParametricIntentMelody.ResolvePaletteHintKey("wai"));
113 }
114
115 [Fact]
116 public void Bundled_int_chain_colon_space_supports_space_after_slug()
117 {
118 Assert.True(IntentMelodyCatalog.TryGetTailWireClass("int_chain_colon_space", out var wire));
119 Assert.Contains(wire.BetweenSlotsSeparators, s => s.Length == 1 && s[0] == ' ');
120 Assert.True(ParametricIntentMelody.TryParseLineRangeTail("els 7", out _));
121 }
122}
123
View only · write via MCP/CIDE