From f99b5e4c63939a3bbefffe2a4b5335f40f199307 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Mon, 4 May 2026 21:28:56 -0600 Subject: [PATCH 1/2] fix: fix cli not reading stdin --- bin/main.js | 14 +++++++------- test/unit/bin.test.js | 6 ++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/bin/main.js b/bin/main.js index e0c5357f81..3c6585776f 100644 --- a/bin/main.js +++ b/bin/main.js @@ -156,13 +156,13 @@ export async function main(nodeProcess) { if (string) { return string; } - if (!input) { - if (files.length === 0) { - return await getStdin(); - } - input = files.pop(); + if (input) { + return await readFile(input, 'utf8'); + } + if (files.length > 0) { + return await readFile(files.pop(), 'utf8'); } - return await readFile(input, 'utf8'); + return await getStdin(); } function resolveFile(file) { @@ -271,7 +271,7 @@ export async function main(nodeProcess) { } try { - await start(nodeProcess.argv.slice()); + await start(nodeProcess.argv.slice(2)); nodeProcess.exit(0); } catch(err) { if (err.code === 'ENOENT') { diff --git a/test/unit/bin.test.js b/test/unit/bin.test.js index 7db58ec774..06ab9bf595 100644 --- a/test/unit/bin.test.js +++ b/test/unit/bin.test.js @@ -120,5 +120,11 @@ describe('bin/marked', () => { stderr: `marked: ${fixturePath('does-not-exist.md')}: No such file or directory`, code: 1, })); + + it('reads from stdin when no files are provided', testInput({ + args: [], + stdin: '# test\n', + stdout: '

test

', + })); }); }); From 74e3bea1f280529c80f7a7bf783fc73703160e43 Mon Sep 17 00:00:00 2001 From: Tony Brix Date: Mon, 4 May 2026 22:42:33 -0600 Subject: [PATCH 2/2] test exec marked --- test/unit/bin.test.js | 56 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/test/unit/bin.test.js b/test/unit/bin.test.js index 06ab9bf595..30fa726674 100644 --- a/test/unit/bin.test.js +++ b/test/unit/bin.test.js @@ -1,11 +1,12 @@ import { main } from '../../bin/main.js'; import { htmlIsEqual } from '@markedjs/testutils'; -import { dirname, resolve } from 'node:path'; -import { fileURLToPath } from 'node:url'; +import { resolve } from 'node:path'; import { describe, it, mock } from 'node:test'; import assert from 'node:assert'; +import { exec } from 'node:child_process'; +import { promisify } from 'node:util'; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const execAsync = promisify(exec); function createMocks() { const mocks = { @@ -64,7 +65,26 @@ function testInput({ args = [], stdin = '', stdinError = '', stdout = '', stderr } function fixturePath(filePath) { - return resolve(__dirname, './fixtures', filePath); + return resolve(import.meta.dirname, './fixtures', filePath); +} + +function execMarked({ args = '', stdin = '', stdout = '', stderr = '' }) { + const execPath = resolve(import.meta.dirname, '../../bin/marked'); + return async() => { + let command = ''; + + if (stdin) { + command += `node -e "process.stdout.write('${stdin}')" | `; + } + command += `node ${execPath}`; + if (args) { + command += ` ${args}`; + } + const res = await execAsync(command); + + assert.ok(await htmlIsEqual(res.stdout, stdout)); + assert.strictEqual(res.stderr, stderr); + }; } describe('bin/marked', () => { @@ -122,9 +142,35 @@ describe('bin/marked', () => { })); it('reads from stdin when no files are provided', testInput({ - args: [], stdin: '# test\n', stdout: '

test

', })); }); }); + +describe('exec', () => { + it('stdin', execMarked({ + stdin: '# test', + stdout: '

test

', + })); + + it('string', execMarked({ + args: '-s "# test"', + stdout: '

test

', + })); + + it('input', execMarked({ + args: `-i ${fixturePath('bin-input.md')}`, + stdout: '

file

', + })); + + it('input file positional', execMarked({ + args: fixturePath('bin-input.md'), + stdout: '

file

', + })); + + it('input last file positional', execMarked({ + args: `${fixturePath('does-not-exist.md')} ${fixturePath('bin-input.md')}`, + stdout: '

file

', + })); +});