11"use strict" ;
22
33const path = require ( "node:path" ) ;
4- const { stripVTControlCharacters } = require ( "node:util" ) ;
5- const concat = require ( "concat-stream" ) ;
6- const { Writable } = require ( "readable-stream" ) ;
74const testUtilsPkg = require ( "../utils/test-utils" ) ;
85
9- const { processKill } = testUtilsPkg ;
10-
11- const ENABLE_LOG_COMPILATION = process . env . ENABLE_PIPE || false ;
126const nodeVersion = Number . parseInt ( process . versions . node . split ( "." ) [ 0 ] , 10 ) ;
137
148// eslint-disable-next-line jsdoc/reject-any-type
@@ -17,206 +11,47 @@ const nodeVersion = Number.parseInt(process.versions.node.split(".")[0], 10);
1711function createPathDependentUtils ( cli ) {
1812 const CLI_PATH = path . resolve ( __dirname , `../../packages/${ cli } /bin/cli.js` ) ;
1913
20- /**
21- * Webpack CLI test runner.
22- * @param {string } cwd The path to folder that contains test
23- * @param {Array<string> } args Array of arguments
24- * @param {TestOptions } options Options for tests
25- * @returns {Promise<import("execa").ExecaChildProcess> } child process
26- */
27- const createProcess = ( cwd , args , options ) => {
28- const { nodeOptions = [ ] } = options ;
29-
30- return Promise . resolve ( )
31- . then ( ( ) => import ( "execa" ) )
32- . then ( ( execa ) => {
33- const processExecutor = nodeOptions . length ? execa . execaNode : execa . execa ;
34-
35- return processExecutor ( CLI_PATH , args , {
36- cwd : path . resolve ( cwd ) ,
37- reject : false ,
38- stdio : ENABLE_LOG_COMPILATION ? "inherit" : "pipe" ,
39- maxBuffer : Infinity ,
40- env : { WEBPACK_CLI_HELP_WIDTH : 1024 } ,
41- ...options ,
42- } ) ;
43- } ) ;
44- } ;
45-
4614 /**
4715 * Run the webpack CLI for a test case.
4816 * @param {string } cwd The path to folder that contains test
4917 * @param {Array<string> } args Array of arguments
5018 * @param {TestOptions } options Options for tests
51- * @returns {Promise<import("execa").ExecaChildProcess > } child process
19+ * @returns {Promise<import("execa").Result > } child process
5220 */
53- const run = async ( cwd , args = [ ] , options = { } ) => createProcess ( cwd , args , options ) ;
54-
55- /**
56- * Run the webpack CLI for a test case and get process.
57- * @param {string } cwd The path to folder that contains test
58- * @param {Array<string> } args Array of arguments
59- * @param {TestOptions } options Options for tests
60- * @returns {Promise<import("execa").ExecaChildProcess> } child process
61- */
62- const runAndGetProcess = ( cwd , args = [ ] , options = { } ) => createProcess ( cwd , args , options ) ;
21+ const run = async ( cwd , args = [ ] , options = { } ) =>
22+ testUtilsPkg . run ( cwd , args , {
23+ ...options ,
24+ executorPath : CLI_PATH ,
25+ } ) ;
6326
6427 /**
6528 * Run the webpack CLI in watch mode for a test case.
6629 * @param {string } cwd The path to folder that contains test
6730 * @param {Array<string> } args Array of arguments
6831 * @param {TestOptions } options Options for tests
69- * @returns {Promise<TestOptions > } The webpack output or Promise when nodeOptions are present
32+ * @returns {Promise<import("execa").Result > } The webpack output or Promise when nodeOptions are present
7033 */
71- const runWatch = ( cwd , args = [ ] , options = { } ) =>
72- new Promise ( ( resolve , reject ) => {
73- const process = createProcess ( cwd , args , options ) ;
74- const outputKillStr = options . killString || / w e b p a c k \d + \. \d + \. \d / ;
75- const { stdoutKillStr } = options ;
76- const { stderrKillStr } = options ;
77-
78- let isStdoutDone = false ;
79- let isStderrDone = false ;
80-
81- process . stdout . pipe (
82- new Writable ( {
83- write ( chunk , encoding , callback ) {
84- const output = stripVTControlCharacters ( chunk . toString ( "utf8" ) ) ;
85-
86- if ( stdoutKillStr && stdoutKillStr . test ( output ) ) {
87- isStdoutDone = true ;
88- } else if ( ! stdoutKillStr && outputKillStr . test ( output ) ) {
89- processKill ( process ) ;
90- }
91-
92- if ( isStdoutDone && isStderrDone ) {
93- processKill ( process ) ;
94- }
95-
96- callback ( ) ;
97- } ,
98- } ) ,
99- ) ;
100-
101- process . stderr . pipe (
102- new Writable ( {
103- write ( chunk , encoding , callback ) {
104- const output = stripVTControlCharacters ( chunk . toString ( "utf8" ) ) ;
105-
106- if ( stderrKillStr && stderrKillStr . test ( output ) ) {
107- isStderrDone = true ;
108- } else if ( ! stderrKillStr && outputKillStr . test ( output ) ) {
109- processKill ( process ) ;
110- }
111-
112- if ( isStdoutDone && isStderrDone ) {
113- processKill ( process ) ;
114- }
115-
116- callback ( ) ;
117- } ,
118- } ) ,
119- ) ;
120-
121- process
122- . then ( ( result ) => {
123- resolve ( result ) ;
124- } )
125- . catch ( ( error ) => {
126- reject ( error ) ;
127- } ) ;
34+ const runWatch = async ( cwd , args = [ ] , options = { } ) =>
35+ testUtilsPkg . runWatch ( cwd , args , {
36+ ...options ,
37+ executorPath : CLI_PATH ,
12838 } ) ;
12939
13040 /**
13141 * runPromptWithAnswers
132- * @param {string } location of current working directory
42+ * @param {string } cwd The path to folder that contains test
13343 * @param {string[] } args CLI args to pass in
134- * @param {string[] } answers to be passed to stdout for inquirer question
44+ * @param {string[] } answers answers to be passed to stdout for inquirer question
45+ * @param {TestOptions } options Options for tests
13546 * @returns {Promise<{ stdout: string, stderr: string }> } result
13647 */
137- const runPromptWithAnswers = ( location , args , answers ) => {
138- const process = runAndGetProcess ( location , args ) ;
139-
140- process . stdin . setDefaultEncoding ( "utf8" ) ;
141-
142- const delay = 1000 ;
143- let outputTimeout ;
144- let currentAnswer = 0 ;
145-
146- const writeAnswer = ( output ) => {
147- if ( ! answers ) {
148- process . stdin . write ( output ) ;
149- processKill ( process ) ;
150-
151- return ;
152- }
153-
154- if ( currentAnswer < answers . length ) {
155- process . stdin . write ( answers [ currentAnswer ] ) ;
156- currentAnswer ++ ;
157- }
158- } ;
159-
160- process . stdout . pipe (
161- new Writable ( {
162- write ( chunk , encoding , callback ) {
163- const output = chunk . toString ( "utf8" ) ;
164-
165- if ( output . length > 0 ) {
166- if ( outputTimeout ) {
167- clearTimeout ( outputTimeout ) ;
168- }
169-
170- // we must receive new stdout, then have 1 second
171- // without any stdout before writing the next answer
172- outputTimeout = setTimeout ( ( ) => {
173- writeAnswer ( output ) ;
174- } , delay ) ;
175- }
176-
177- callback ( ) ;
178- } ,
179- } ) ,
180- ) ;
181-
182- return new Promise ( ( resolve ) => {
183- const obj = { } ;
184-
185- let stdoutDone = false ;
186- let stderrDone = false ;
187-
188- const complete = ( ) => {
189- if ( outputTimeout ) {
190- clearTimeout ( outputTimeout ) ;
191- }
192-
193- if ( stdoutDone && stderrDone ) {
194- processKill ( process ) ;
195- resolve ( obj ) ;
196- }
197- } ;
198-
199- process . stdout . pipe (
200- concat ( ( result ) => {
201- stdoutDone = true ;
202- obj . stdout = result . toString ( ) ;
203-
204- complete ( ) ;
205- } ) ,
206- ) ;
207-
208- process . stderr . pipe (
209- concat ( ( result ) => {
210- stderrDone = true ;
211- obj . stderr = result . toString ( ) ;
212-
213- complete ( ) ;
214- } ) ,
215- ) ;
48+ const runPromptWithAnswers = async ( cwd , args , answers = [ ] , options = { } ) =>
49+ testUtilsPkg . runPromptWithAnswers ( cwd , args , answers , {
50+ ...options ,
51+ executorPath : CLI_PATH ,
21652 } ) ;
217- } ;
21853
219- return { runAndGetProcess , run, runWatch, runPromptWithAnswers } ;
54+ return { run, runWatch, runPromptWithAnswers } ;
22055}
22156
22257module . exports = {
0 commit comments