11import assert from "node:assert/strict" ;
2+ import { spawn } from "node:child_process" ;
23import test from "node:test" ;
4+ import { fileURLToPath } from "node:url" ;
35
46import { splitCommandLine } from "../src/tui.mjs" ;
57
8+ const BIN = fileURLToPath ( new URL ( "../bin/moshcode.mjs" , import . meta. url ) ) ;
9+
10+ function runTui ( input ) {
11+ return new Promise ( ( resolve , reject ) => {
12+ const child = spawn ( process . execPath , [ BIN ] , { stdio : [ "pipe" , "pipe" , "pipe" ] } ) ;
13+ let stdout = "" ;
14+ let stderr = "" ;
15+ child . stdout . on ( "data" , ( chunk ) => { stdout += chunk ; } ) ;
16+ child . stderr . on ( "data" , ( chunk ) => { stderr += chunk ; } ) ;
17+ child . on ( "error" , reject ) ;
18+ child . on ( "close" , ( status , signal ) => resolve ( { status, signal, stdout, stderr } ) ) ;
19+ child . stdin . end ( input ) ;
20+ } ) ;
21+ }
22+
623test ( "TUI command parsing preserves quoted native CLI arguments" , ( ) => {
724 assert . deepEqual (
825 splitCommandLine ( '/coinpay card pay --description "Fix the build" --note \'ship it\'' ) ,
@@ -23,3 +40,11 @@ test("TUI command parsing rejects incomplete quoting", () => {
2340 assert . throws ( ( ) => splitCommandLine ( '/coinpay --description "unfinished' ) , / u n t e r m i n a t e d / ) ;
2441 assert . throws ( ( ) => splitCommandLine ( "/ugig trailing\\" ) , / t r a i l i n g e s c a p e / ) ;
2542} ) ;
43+
44+ test ( "TUI /run rejects unknown options before reading a script file" , async ( ) => {
45+ const result = await runTui ( "/run --dryrun\n/quit\n" ) ;
46+
47+ assert . equal ( result . status , 0 ) ;
48+ assert . match ( result . stdout , / u n k n o w n o p t i o n - - d r y r u n / ) ;
49+ assert . doesNotMatch ( result . stdout , / c a n ' t r e a d - - d r y r u n / ) ;
50+ } ) ;
0 commit comments