Skip to content

Commit 4f458d3

Browse files
author
SqlRush
committed
Accept wrapped expectation bool fields
1 parent ecf55a3 commit 4f458d3

5 files changed

Lines changed: 96 additions & 25 deletions

File tree

docs/cc-100-roadmap.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,8 @@ M7 补充:prompt history `LogEntry` 读取现在接受 `sessionID`/`session`/`
602602

603603
本轮补充:interaction script 的 direct focus bool alias 字段现在也递归解包 wrapper;`focus``focused``focusIn``focusOut``blur`/`blurred` 可从 wrapped `enabled``value``selected` 等字段恢复焦点事件控制,避免 direct field fixture 在 bool decode 阶段失败。
604604

605+
本轮补充:interaction script 的 direct expectation bool alias 字段现在也递归解包 wrapper;`expectNoEvent``expectNoDialogResult(s)``expectFocused` 可从 wrapped `value`/`enabled`/`selected` 恢复断言控制,避免 direct expectation fixture 在 bool decode 阶段失败。
606+
605607
本轮补充:interaction script action/type/kind/name/operation 动作判别字段现在也接受 compact/camel event/media aliases,包括 `focusIn``focusOut``mouseEvent``pasteImage``imagePaste`
606608

607609
本轮补充:interaction script 的 mouseEvent/pasteImage action payload 现在递归解包 JSON:API/GraphQL-style `resource`/`attributes`/`properties`/`attrs`/`edge.node` wrapper,wrapped mouse 坐标/按钮和 image filename/media/content 可直接驱动 dialog click 与 image paste。

docs/claude-code-go-rewrite-plan.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ test/parity/ # golden tests against TS/official behavior
312312
- 本轮补充:interaction script resize/terminalSize/screenSize action payload 现在递归解包 `value`/`payload`/`data`/`resource`/`attributes`/`properties`/`attrs`/`edge.node` 等 wrapper,官方/API fixture 可把 columns/rows 放在 JSON:API 或 GraphQL envelope 内。
313313
- 本轮补充:interaction script 的 direct resize 数字 alias 字段现在也递归解包 wrapper;`resizeWidth`/`resizeHeight``screenWidth`/`screenHeight` 和 terminal width/height 相邻别名可从 wrapped `value``columns``rows` 中恢复尺寸。
314314
- 本轮补充:interaction script 的 direct focus bool alias 字段现在也递归解包 wrapper;`focus``focused``focusIn``focusOut``blur`/`blurred` 可从 wrapped `enabled``value``selected` 等字段恢复焦点事件控制。
315+
- 本轮补充:interaction script 的 direct expectation bool alias 字段现在也递归解包 wrapper;`expectNoEvent``expectNoDialogResult(s)``expectFocused` 可从 wrapped `value`/`enabled`/`selected` 恢复断言控制。
315316
- 本轮补充:interaction script action/type/kind/name/operation 动作判别字段继续接受 compact/camel event/media aliases,包括 `focusIn``focusOut``mouseEvent``pasteImage``imagePaste`
316317
- 本轮补充:interaction script mouseEvent/pasteImage action payload 现在递归解包 JSON:API/GraphQL-style `resource`/`attributes`/`properties`/`attrs`/`edge.node` wrapper,wrapped mouse 坐标/按钮和 image filename/media/content 可直接驱动 dialog click 与 image paste。
317318
- 本轮补充:interaction script action/type/kind/name/operation 动作判别字段也可驱动 runtime/dialog mutation,支持 `requestPermission``taskStatus``showTasks``cancelTasks``removeTask``showDialog` 等动作,并从 `value`/`payload`/`data`/`body` 载荷解析对象、ID 或取消原因。

docs/first-second-parity-audit.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ M7 progress now includes:
292292
- `internal/tui`: direct scripted string alias fields such as `text`, `pasteText`, `setStatus`, and `snapshotName` now accept JSON:API/GraphQL-style wrapper objects without failing strong scalar decoding.
293293
- `internal/tui`: direct scripted resize aliases such as `resizeWidth`/`resizeHeight` and `screenWidth`/`screenHeight` now recursively unwrap numeric JSON:API/GraphQL-style wrapper objects.
294294
- `internal/tui`: direct scripted focus aliases such as `focus`, `focused`, `focusIn`, `focusOut`, and `blurred` now recursively unwrap boolean JSON:API/GraphQL-style wrapper objects.
295+
- `internal/tui`: direct scripted expectation bool aliases such as `expectNoEvent`, `expectNoDialogResult(s)`, and `expectFocused` now recursively unwrap JSON:API/GraphQL-style wrapper objects.
295296
- `internal/tui`: terminal key parsing now accepts CSI-u/kitty keyboard protocol sequences for existing ctrl/alt editing keys, shift-enter, shift-tab, and printable shift-only runes.
296297
- `internal/tui`: terminal CSI-u/kitty keyboard parsing now also accepts colon-suffixed alternate codepoint and modifier event-type fields such as `CSI 97:65;5:1u`.
297298
- `internal/tui`: terminal CSI-u/kitty keyboard parsing now also accepts base/unmodified sequences such as `CSI 97u` and `CSI 13;1u`, mapping printable runes plus Enter, Tab, Esc, and Backspace instead of treating ordinary extended-key reports as unknown.

internal/tui/script_aliases.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,8 @@ func (step *ScriptStep) UnmarshalJSON(data []byte) error {
457457
ExpectEventCamel *ScreenEvent `json:"expectEvent"`
458458
ExpectEvents []ScreenEvent `json:"expect_events"`
459459
ExpectEventsCamel []ScreenEvent `json:"expectEvents"`
460-
ExpectNoEvent *bool `json:"expect_no_event"`
461-
ExpectNoEventCamel *bool `json:"expectNoEvent"`
460+
ExpectNoEvent *json.RawMessage `json:"expect_no_event"`
461+
ExpectNoEventCamel *json.RawMessage `json:"expectNoEvent"`
462462
ExpectEventCount *int `json:"expect_event_count"`
463463
ExpectEventCountCamel *int `json:"expectEventCount"`
464464
ExpectTotalEventCount *int `json:"expect_total_event_count"`
@@ -467,9 +467,9 @@ func (step *ScriptStep) UnmarshalJSON(data []byte) error {
467467
ExpectDialogResultCamel *DialogResultExpectation `json:"expectDialogResult"`
468468
ExpectDialogResults []DialogResultExpectation `json:"expect_dialog_results"`
469469
ExpectDialogResultsCamel []DialogResultExpectation `json:"expectDialogResults"`
470-
ExpectNoDialogResult *bool `json:"expect_no_dialog_result"`
471-
ExpectNoDialogResultCamel *bool `json:"expectNoDialogResult"`
472-
ExpectNoDialogResults *bool `json:"expect_no_dialog_results"`
470+
ExpectNoDialogResult *json.RawMessage `json:"expect_no_dialog_result"`
471+
ExpectNoDialogResultCamel *json.RawMessage `json:"expectNoDialogResult"`
472+
ExpectNoDialogResults *json.RawMessage `json:"expect_no_dialog_results"`
473473
ExpectDialogResultCount *int `json:"expect_dialog_result_count"`
474474
ExpectDialogCountCamel *int `json:"expectDialogResultCount"`
475475
ExpectTotalDialogCount *int `json:"expect_total_dialog_result_count"`
@@ -488,8 +488,8 @@ func (step *ScriptStep) UnmarshalJSON(data []byte) error {
488488
ExpectViewportCamel *ViewportExpectation `json:"expectViewport"`
489489
ExpectScreen *ScreenExpectation `json:"expect_screen"`
490490
ExpectScreenCamel *ScreenExpectation `json:"expectScreen"`
491-
ExpectFocused *bool `json:"expect_focused"`
492-
ExpectFocusedCamel *bool `json:"expectFocused"`
491+
ExpectFocused *json.RawMessage `json:"expect_focused"`
492+
ExpectFocusedCamel *json.RawMessage `json:"expectFocused"`
493493
ExpectStatusContains *stringList `json:"expect_status_contains"`
494494
ExpectStatusContainsCamel *stringList `json:"expectStatusContains"`
495495
ExpectStatusNotContains *stringList `json:"expect_status_not_contains"`
@@ -841,11 +841,8 @@ func (step *ScriptStep) UnmarshalJSON(data []byte) error {
841841
if fields.ExpectEventsCamel != nil {
842842
step.ExpectEvents = fields.ExpectEventsCamel
843843
}
844-
if fields.ExpectNoEvent != nil {
845-
step.ExpectNoEvent = *fields.ExpectNoEvent
846-
}
847-
if fields.ExpectNoEventCamel != nil {
848-
step.ExpectNoEvent = *fields.ExpectNoEventCamel
844+
if value, ok := scriptRuntimeMutationBoolField(fieldMap, "expect_no_event", "expectNoEvent"); ok {
845+
step.ExpectNoEvent = value
849846
}
850847
if fields.ExpectEventCount != nil {
851848
step.ExpectEventCount = fields.ExpectEventCount
@@ -871,14 +868,8 @@ func (step *ScriptStep) UnmarshalJSON(data []byte) error {
871868
if fields.ExpectDialogResultsCamel != nil {
872869
step.ExpectDialogResults = fields.ExpectDialogResultsCamel
873870
}
874-
if fields.ExpectNoDialogResult != nil {
875-
step.ExpectNoDialogResult = *fields.ExpectNoDialogResult
876-
}
877-
if fields.ExpectNoDialogResultCamel != nil {
878-
step.ExpectNoDialogResult = *fields.ExpectNoDialogResultCamel
879-
}
880-
if fields.ExpectNoDialogResults != nil {
881-
step.ExpectNoDialogResult = *fields.ExpectNoDialogResults
871+
if value, ok := scriptRuntimeMutationBoolField(fieldMap, "expect_no_dialog_result", "expectNoDialogResult", "expect_no_dialog_results"); ok {
872+
step.ExpectNoDialogResult = value
882873
}
883874
if fields.ExpectDialogResultCount != nil {
884875
step.ExpectDialogResultCount = fields.ExpectDialogResultCount
@@ -934,11 +925,9 @@ func (step *ScriptStep) UnmarshalJSON(data []byte) error {
934925
if fields.ExpectScreenCamel != nil {
935926
step.ExpectScreen = fields.ExpectScreenCamel
936927
}
937-
if fields.ExpectFocused != nil {
938-
step.ExpectFocused = fields.ExpectFocused
939-
}
940-
if fields.ExpectFocusedCamel != nil {
941-
step.ExpectFocused = fields.ExpectFocusedCamel
928+
if value, ok := scriptRuntimeMutationBoolField(fieldMap, "expect_focused", "expectFocused"); ok {
929+
focused := value
930+
step.ExpectFocused = &focused
942931
}
943932
if fields.ExpectStatusContains != nil {
944933
step.ExpectStatusContains = stringListValue(fields.ExpectStatusContains)
@@ -2329,6 +2318,17 @@ func stripScriptStepRawScalarAliasFields(data []byte) []byte {
23292318
"ResizeHeight",
23302319
"resizeHeight",
23312320
"resize_height",
2321+
"ExpectNoEvent",
2322+
"expectNoEvent",
2323+
"expect_no_event",
2324+
"ExpectNoDialogResult",
2325+
"expectNoDialogResult",
2326+
"expect_no_dialog_result",
2327+
"ExpectNoDialogResults",
2328+
"expect_no_dialog_results",
2329+
"ExpectFocused",
2330+
"expectFocused",
2331+
"expect_focused",
23322332
} {
23332333
raw, ok := fields[name]
23342334
if !ok {

internal/tui/tui_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5921,6 +5921,73 @@ func TestRunInteractionScriptAcceptsWrappedFocusAliasFields(t *testing.T) {
59215921
}
59225922
}
59235923

5924+
func TestRunInteractionScriptAcceptsWrappedExpectationBoolAliasFields(t *testing.T) {
5925+
steps, err := ParseInteractionScript([]byte(`[
5926+
{
5927+
"expectNoEvent": {
5928+
"resource": {
5929+
"attributes": {
5930+
"value": true
5931+
}
5932+
}
5933+
},
5934+
"expectNoDialogResult": {
5935+
"edge": {
5936+
"node": {
5937+
"attrs": {
5938+
"enabled": true
5939+
}
5940+
}
5941+
}
5942+
}
5943+
},
5944+
{
5945+
"focus": false,
5946+
"expectEvent": {"type": "focus_out"},
5947+
"expectFocused": {
5948+
"resource": {
5949+
"attributes": {
5950+
"value": false
5951+
}
5952+
}
5953+
}
5954+
},
5955+
{
5956+
"focus": true,
5957+
"expectEvent": {"type": "focus_in"},
5958+
"expectNoDialogResults": {
5959+
"resource": {
5960+
"attributes": {
5961+
"selected": true
5962+
}
5963+
}
5964+
},
5965+
"expectFocused": {
5966+
"edge": {
5967+
"node": {
5968+
"attrs": {
5969+
"selected": true
5970+
}
5971+
}
5972+
}
5973+
}
5974+
}
5975+
]`))
5976+
if err != nil {
5977+
t.Fatal(err)
5978+
}
5979+
screen := NewREPLScreen(40, 8, nil)
5980+
result, err := RunInteractionScriptChecked(&screen, steps)
5981+
if err != nil {
5982+
t.Fatal(err)
5983+
}
5984+
if len(result.Events) != 2 ||
5985+
result.Events[0].Type != ScreenEventFocusOut ||
5986+
result.Events[1].Type != ScreenEventFocusIn {
5987+
t.Fatalf("events = %#v", result.Events)
5988+
}
5989+
}
5990+
59245991
func TestRunInteractionScriptAcceptsWrappedMouseAndImageActionPayloads(t *testing.T) {
59255992
steps, err := ParseInteractionScript([]byte(`[
59265993
{

0 commit comments

Comments
 (0)