Setting the file. One moment.
TTS Spawn Test · Media Use · heygen-com/hyperframes · Skills Docs
ContentsBack to the top of the page ⋯
scripts/11 files
audio/scripts/lib/tts.spawn.test.mjs
audio/scripts/lib/ tts.spawn.test.mjs
JavaScript · 158 lines · 5 KB
11
12 // Regression: on Windows, npx resolves to npx.cmd, which spawn() cannot exec
13 // without shell:true — it fails ENOENT, silently swallowed as ok:false by the
14 // caller. spawnP takes injectable platform/spawnFn params so this doesn't
15 // need to touch the real process.platform or mock node:child_process (whose
16 // ESM exports are non-configurable).
17 function fakeSpawn ( captured ) {
18 return ( cmd , args , opts ) => {
19 captured. push ({ cmd, args, opts });
20 const p = new EventEmitter ();
21 setImmediate (() => p. emit ( "exit" , 0 ));
22 return p;
23 };
24 }
25
26 const envWithNpxCli = {
27 npm_execpath: "/opt/node/lib/node_modules/npm/bin/npm-cli.js" ,
28 npm_node_execpath: "/opt/node/bin/node" ,
29 };
30 const npxCliPath = "/opt/node/lib/node_modules/npm/bin/npx-cli.js" ;
31 const pathExists = ( path ) => path === npxCliPath;
32
33 test ( "resolveNpxCliFromNpmExecPath finds npx-cli next to npm-cli" , () => {
34 assert. equal ( resolveNpxCliFromNpmExecPath (envWithNpxCli.npm_execpath, pathExists), npxCliPath);
35 });
36
37 test ( "resolveNpxCliPath finds npx-cli beside node when npm_execpath is unset" , () => {
38 const node = "C:/Program Files/nodejs/node.exe" ;
39 const expected = "C:/Program Files/nodejs/node_modules/npm/bin/npx-cli.js" ;
40 assert. equal (
41 resolveNpxCliPath ( undefined , node, ( path ) => path === expected),
42 expected,
43 );
44 });
45
46 test ( "resolveSpawnCommand routes npx through node+npx-cli on win32 without shell:true" , () => {
47 const resolved = resolveSpawnCommand (
48 "npx" ,
49 [ "hyperframes" , "tts" , "C: \\ Users \\ Test User \\ line.txt" , "--voice" , "am_michael" ],
50 {},
51 "win32" ,
52 envWithNpxCli,
53 pathExists,
54 );
55 assert. ok (resolved);
56 assert. equal (resolved.cmd, envWithNpxCli.npm_node_execpath);
57 assert. deepEqual (resolved.args, [
58 npxCliPath,
59 "hyperframes" ,
60 "tts" ,
61 "C: \\ Users \\ Test User \\ line.txt" ,
62 "--voice" ,
63 "am_michael" ,
64 ]);
65 assert. equal (resolved.opts.shell, undefined );
66 });
67
68 test ( "resolveSpawnCommand preserves Windows npx shell metacharacters as argv data" , () => {
69 const resolved = resolveSpawnCommand (
70 "npx" ,
71 [ "hyperframes" , "tts" , "hello & calc" ],
72 {},
73 "win32" ,
74 envWithNpxCli,
75 pathExists,
76 );
77 assert. ok (resolved);
78 assert. deepEqual (resolved.args, [npxCliPath, "hyperframes" , "tts" , "hello & calc" ]);
79 });
80
81 test ( "spawnP uses the resolved node+npx-cli command for npx on win32" , async () => {
82 const captured = [];
83 await spawnP (
84 "npx" ,
85 [ "hyperframes" , "tts" ],
86 {},
87 "win32" ,
88 fakeSpawn (captured),
89 envWithNpxCli,
90 pathExists,
91 );
92 assert. equal (captured. length , 1 );
93 assert. equal (captured[ 0 ].cmd, envWithNpxCli.npm_node_execpath);
94 assert. deepEqual (captured[ 0 ].args, [npxCliPath, "hyperframes" , "tts" ]);
95 assert. equal (captured[ 0 ].opts.shell, undefined );
96 });
97
98 test ( "spawnP does not enable shell for npx on darwin/linux" , async () => {
99 const captured = [];
100 await spawnP ( "npx" , [ "hyperframes" , "tts" ], {}, "darwin" , fakeSpawn (captured));
101 assert. equal (captured[ 0 ].cmd, "npx" );
102 assert. deepEqual (captured[ 0 ].args, [ "hyperframes" , "tts" ]);
103 assert. equal (captured[ 0 ].opts.shell, undefined );
104 });
105
106 test ( "spawnP does not enable shell for non-npx commands even on win32" , async () => {
107 const captured = [];
108 await spawnP ( "python3" , [ "-c" , "pass" ], {}, "win32" , fakeSpawn (captured));
109 assert. equal (captured[ 0 ].cmd, "python3" );
110 assert. deepEqual (captured[ 0 ].args, [ "-c" , "pass" ]);
111 assert. equal (captured[ 0 ].opts.shell, undefined );
112 });
113
114 test ( "spawnP resolves npx beside node when npm_execpath is unset on win32" , async () => {
115 _resetNpxResolutionWarnForTests ();
116 const captured = [];
117 const node = "C:/Program Files/nodejs/node.exe" ;
118 const npxCli = "C:/Program Files/nodejs/node_modules/npm/bin/npx-cli.js" ;
119 const result = await spawnP (
120 "npx" ,
121 [ "hyperframes" , "tts" ],
122 {},
123 "win32" ,
124 fakeSpawn (captured),
125 { npm_node_execpath: node },
126 ( path ) => path === npxCli,
127 );
128 assert. equal (result.status, 0 );
129 assert. equal (captured. length , 1 );
130 assert. equal (captured[ 0 ].cmd, node);
131 assert. deepEqual (captured[ 0 ].args, [npxCli, "hyperframes" , "tts" ]);
132 });
133
134 test ( "spawnP warns once with an accurate diagnostic when neither npx path exists" , async () => {
135 _resetNpxResolutionWarnForTests ();
136 const errors = [];
137 const originalError = console.error;
138 console. error = ( message ) => errors. push ( String (message));
139 try {
140 const env = { npm_execpath: "C:/missing/npm-cli.js" , npm_node_execpath: "C:/node/node.exe" };
141 const missing = () => false ;
142 assert. equal (
143 ( await spawnP ( "npx" , [ "hyperframes" , "tts" ], {}, "win32" , fakeSpawn ([]), env, missing))
144 .status,
145 - 1 ,
146 );
147 assert. equal (
148 ( await spawnP ( "npx" , [ "hyperframes" , "tts" ], {}, "win32" , fakeSpawn ([]), env, missing))
149 .status,
150 - 1 ,
151 );
152 } finally {
153 console.error = originalError;
154 }
155 assert. equal (errors. length , 1 );
156 assert. match (errors[ 0 ], /npm_execpath \( C: \/ missing \/ npm-cli \. js \) / );
157 assert. doesNotMatch (errors[ 0 ], /npm_execpath is not set/ );
158 });