@@ -4,9 +4,8 @@ import React from "react";
44import { PromptInput , type PromptSubmission } from "../ui/views/PromptInput" ;
55import { terminal } from "./terminal-helper" ;
66
7- test ( "PromptInput wraps words, switches cursor modes and submits the original buffer" , async ( t ) => {
8- const submissions : PromptSubmission [ ] = [ ] ;
9- const props = {
7+ function inputProps ( submissions : PromptSubmission [ ] ) {
8+ return {
109 projectRoot : process . cwd ( ) ,
1110 screenWidth : 12 ,
1211 skills : [ ] ,
@@ -23,6 +22,11 @@ test("PromptInput wraps words, switches cursor modes and submits the original bu
2322 onPlanModeChange ( ) { } ,
2423 onInterrupt ( ) { } ,
2524 } ;
25+ }
26+
27+ test ( "PromptInput wraps words, switches cursor modes and submits the original buffer" , async ( t ) => {
28+ const submissions : PromptSubmission [ ] = [ ] ;
29+ const props = inputProps ( submissions ) ;
2630 const h = await terminal ( t , React . createElement ( PromptInput , props ) , 24 ) ;
2731 await h . send ( "hello" ) ;
2832 assert . match ( h . frame ( ) , / > h e l l o / ) ;
@@ -50,3 +54,54 @@ test("PromptInput wraps words, switches cursor modes and submits the original bu
5054 await h . send ( "\r" ) ;
5155 assert . equal ( submissions [ 0 ] ?. text , "hello world" ) ;
5256} ) ;
57+
58+ test ( "PromptInput wraps Chinese by character and edits across the wrap without changing submitted whitespace" , async ( t ) => {
59+ const submissions : PromptSubmission [ ] = [ ] ;
60+ const h = await terminal ( t , React . createElement ( PromptInput , inputProps ( submissions ) ) , 12 ) ;
61+ const text = "aaaaaa 君不见高堂明镜悲白发\nhello world" ;
62+ await h . send ( `\x1b[200~${ text } \x1b[201~` ) ;
63+ assert . match ( h . frame ( ) , / > a a a a a a 君 \s * \n { 2 } 不 见 高 堂 明 \s * \n { 2 } 镜 悲 白 发 / ) ;
64+
65+ await h . send ( "\x1b[A" ) ;
66+ await h . send ( "\x01" ) ;
67+ for ( let i = 0 ; i < 8 ; i ++ ) await h . send ( "\x1b[C" ) ;
68+ assert . ok ( h . rawFrame ( ) . includes ( "\x1b[7m不\x1b[27m" ) ) ;
69+ await h . send ( "天" ) ;
70+ assert . match ( h . frame ( ) , / > a a a a a a 君 \s * \n { 2 } 天 不 见 高 堂 / ) ;
71+ await h . send ( "\x7f" ) ;
72+ await h . send ( "\x1b[3~" ) ;
73+ await h . send ( "不" ) ;
74+ await h . send ( "\r" ) ;
75+ assert . equal ( submissions [ 0 ] ?. text , text ) ;
76+ } ) ;
77+
78+ test ( "PromptInput reflows mixed Chinese and English when resized and preserves the cursor" , async ( t ) => {
79+ const submissions : PromptSubmission [ ] = [ ] ;
80+ const props = inputProps ( submissions ) ;
81+ const h = await terminal ( t , React . createElement ( PromptInput , props ) , 24 ) ;
82+ await h . send ( "aaaaaa 君不见" ) ;
83+ await h . send ( "\x1b[D" ) ;
84+ assert . ok ( h . rawFrame ( ) . includes ( "\x1b[7m见\x1b[27m" ) ) ;
85+
86+ h . rerender ( React . createElement ( PromptInput , { ...props , screenWidth : 24 } ) ) ;
87+ await h . send ( "天" ) ;
88+ assert . match ( h . frame ( ) , / > a a a a a a 君 不 天 见 / ) ;
89+ h . rerender ( React . createElement ( PromptInput , props ) ) ;
90+ await h . send ( "\x7f" ) ;
91+ assert . match ( h . frame ( ) , / > a a a a a a 君 \s * \n { 2 } 不 见 / ) ;
92+ await h . send ( "\r" ) ;
93+ assert . equal ( submissions [ 0 ] ?. text , "aaaaaa 君不见" ) ;
94+ } ) ;
95+
96+ test ( "PromptInput uses the same Chinese wrapping in highlighted history previews" , async ( t ) => {
97+ const submissions : PromptSubmission [ ] = [ ] ;
98+ const text = "aaaaaa 君不见高堂明镜悲白发" ;
99+ const props = { ...inputProps ( submissions ) , promptHistory : [ text ] } ;
100+ const h = await terminal ( t , React . createElement ( PromptInput , props ) , 12 ) ;
101+ await h . send ( "\x12君不见" ) ;
102+ assert . match ( h . frame ( ) , / > a a a a a a 君 \s * \n { 2 } 不 见 高 堂 明 / ) ;
103+ await h . send ( "\r" ) ;
104+ assert . equal ( submissions . length , 0 ) ;
105+ await h . send ( "\r" ) ;
106+ assert . equal ( submissions [ 0 ] ?. text , text ) ;
107+ } ) ;
0 commit comments