diff --git a/src/lib/doctor.ts b/src/lib/doctor.ts index a72da4e3..dba0d502 100644 --- a/src/lib/doctor.ts +++ b/src/lib/doctor.ts @@ -114,7 +114,14 @@ const doctor = async (run: Run, options: Options): Promise => { } if (options.doctorTest) { - const [testCommand, ...testArgs] = options.doctorTest.split(' ') + const regexp = /"(.+?)"|'(.+?)'|[^ ]+/g + const matches = options.doctorTest.matchAll(regexp) + let groups: string[] = [] + // eslint-disable-next-line fp/no-loops + for (const match of matches) { + groups = [...groups, match[2] || match[1] || match[0]] + } + const [testCommand, ...testArgs] = groups await spawn(testCommand, testArgs, spawnOptions) } else { await npm( diff --git a/test/doctor.test.ts b/test/doctor.test.ts index b2049052..10af9c57 100644 --- a/test/doctor.test.ts +++ b/test/doctor.test.ts @@ -304,13 +304,54 @@ describe('doctor', function () { pkgUpgraded.should.containIgnoreCase('"ncu-test-v2": "~2.0.0"') }) + it('custom test script with --doctorTest command that includes spaced words wrapped in quotes', async function () { + // use dynamic import for ESM module + const { default: stripAnsi } = await import('strip-ansi') + const cwd = path.join(doctorTests, 'customtest2') + const pkgPath = path.join(cwd, 'package.json') + const lockfilePath = path.join(cwd, 'package-lock.json') + const nodeModulesPath = path.join(cwd, 'node_modules') + const echoPath = path.join(cwd, 'echo.js') + const pkgOriginal = await fs.readFile(path.join(cwd, 'package.json'), 'utf-8') + let stdout = '' + let stderr = '' + + try { + await ncu(['--doctor', '-u', '--doctorTest', `node ${echoPath} '123 456'`], { + cwd, + stdout: function (data: string) { + stdout += data + }, + stderr: function (data: string) { + stderr += data + }, + }) + } catch (e) {} + + const pkgUpgraded = await fs.readFile(pkgPath, 'utf-8') + + // cleanup before assertions in case they fail + await fs.writeFile(pkgPath, pkgOriginal) + rimraf.sync(lockfilePath) + rimraf.sync(nodeModulesPath) + + // stderr should be empty + stderr.should.equal('') + + // stdout should include expected output + stripAnsi(stdout).should.contain("'123 456'") + + // package file should include upgrades + pkgUpgraded.should.containIgnoreCase('"ncu-test-v2": "~2.0.0"') + }) + it('handle failed prepare script', async () => { const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'npm-check-updates-')) const pkgPath = path.join(tempDir, 'package.json') await fs.mkdtemp(path.join(os.tmpdir(), 'npm-check-updates-')) /* - - packagu.json + - package.json - tsconfig.json - src/ - index.ts diff --git a/test/test-data/doctor/customtest2/echo.js b/test/test-data/doctor/customtest2/echo.js new file mode 100644 index 00000000..3e91ea78 --- /dev/null +++ b/test/test-data/doctor/customtest2/echo.js @@ -0,0 +1 @@ +console.log(process.argv) diff --git a/test/test-data/doctor/customtest2/package.json b/test/test-data/doctor/customtest2/package.json new file mode 100644 index 00000000..b1bb8f21 --- /dev/null +++ b/test/test-data/doctor/customtest2/package.json @@ -0,0 +1,9 @@ +{ + "license": "MIT", + "dependencies": { + "ncu-test-v2": "~1.0.0" + }, + "scripts": { + "mytest": "echo Success" + } +}