diff --git a/lib/parse-test-args.js b/lib/parse-test-args.js index 8a0cda0c7..cb19954b5 100644 --- a/lib/parse-test-args.js +++ b/lib/parse-test-args.js @@ -1,10 +1,12 @@ +const normalize = title => typeof title === 'string' ? title.trim().replace(/\s+/g, ' ') : title; + export default function parseTestArgs(args) { const rawTitle = typeof args[0] === 'string' ? args.shift() : undefined; const receivedImplementationArray = Array.isArray(args[0]); const implementations = receivedImplementationArray ? args.shift() : args.splice(0, 1); const buildTitle = implementation => { - const title = implementation.title ? implementation.title(rawTitle, ...args) : rawTitle; + const title = normalize(implementation.title ? implementation.title(rawTitle, ...args) : rawTitle); return {title, isSet: typeof title !== 'undefined', isValid: typeof title === 'string', isEmpty: !title}; }; diff --git a/test/snapshot-tests/fixtures/normalized-title-in-snapshots/package.json b/test/snapshot-tests/fixtures/normalized-title-in-snapshots/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/snapshot-tests/fixtures/normalized-title-in-snapshots/package.json @@ -0,0 +1 @@ +{} diff --git a/test/snapshot-tests/fixtures/normalized-title-in-snapshots/test.js b/test/snapshot-tests/fixtures/normalized-title-in-snapshots/test.js new file mode 100644 index 000000000..f9059ef13 --- /dev/null +++ b/test/snapshot-tests/fixtures/normalized-title-in-snapshots/test.js @@ -0,0 +1,12 @@ +const test = require(process.env.TEST_AVA_IMPORT_FROM); + +test('test\r\n\ttitle', t => { + t.snapshot('Hello, World!'); +}); + +test('test\r\n\ttitle', Object.assign(t => { + t.snapshot('Hello, World!'); +}, { + title: title => `macro\n${title}` +})); + diff --git a/test/snapshot-tests/fixtures/normalized-title-in-stdout/package.json b/test/snapshot-tests/fixtures/normalized-title-in-stdout/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/snapshot-tests/fixtures/normalized-title-in-stdout/package.json @@ -0,0 +1 @@ +{} diff --git a/test/snapshot-tests/fixtures/normalized-title-in-stdout/test.js b/test/snapshot-tests/fixtures/normalized-title-in-stdout/test.js new file mode 100644 index 000000000..447356d2a --- /dev/null +++ b/test/snapshot-tests/fixtures/normalized-title-in-stdout/test.js @@ -0,0 +1,21 @@ +const test = require(process.env.TEST_AVA_IMPORT_FROM); + +test(`a rather wordy test title that is wrapped + to meet line length requirements in + an unconventional way that may interfere + with report formatting `, t => { + t.pass(); +}); + +test('test\r\n\ttitle', Object.assign(t => { + t.pass(); +}, { + title: title => title +})); + +test('multiline try assertion title', async t => { + const firstTry = await t.try(`try assertions + can have titles too`, tt => tt.pass()); + firstTry.commit(); + t.log(firstTry.title); +}); diff --git a/test/snapshot-tests/formatting.js b/test/snapshot-tests/formatting.js index 3585f4900..f51c0ffef 100644 --- a/test/snapshot-tests/formatting.js +++ b/test/snapshot-tests/formatting.js @@ -1,7 +1,10 @@ import fs from 'fs'; +import os from 'os'; import path from 'path'; import test from '@ava/test'; +import figures from 'figures'; +import replaceString from 'replace-string'; import {cwd, fixture} from '../helpers/exec.js'; import {withTemporaryFixture} from '../helpers/with-temporary-fixture.js'; @@ -22,3 +25,43 @@ test('multiline snapshot label should be formatted correctly in the report', asy t.snapshot(report, 'resulting snapshot report'); }); }); + +test('test title should be normalized in stdout', async t => { + await withTemporaryFixture(cwd('normalized-title-in-stdout'), async cwd => { + // Run test fixture + const result = await fixture(['--update-snapshots'], { + cwd, + env: { + AVA_FORCE_CI: 'not-ci' + } + }); + + // Assert stdout is unchanged + t.snapshot( + replaceString( + replaceString( + replaceString(result.stdout, os.EOL, '\n'), + figures.main.info, figures.windows.info + ), + figures.main.tick, figures.windows.tick + ), + 'stdout'); + }); +}); + +test('test title should be normalized in snapshot', async t => { + await withTemporaryFixture(cwd('normalized-title-in-snapshots'), async cwd => { + // Run test fixture + await fixture(['--update-snapshots'], { + cwd, + env: { + AVA_FORCE_CI: 'not-ci' + } + }); + + // Assert report is unchanged + const reportPath = path.join(cwd, 'test.js.md'); + const report = fs.readFileSync(reportPath, {encoding: 'utf8'}); + t.snapshot(report, 'resulting snapshot report'); + }); +}); diff --git a/test/snapshot-tests/snapshots/formatting.js.md b/test/snapshot-tests/snapshots/formatting.js.md index aa2d483b0..57fb91b64 100644 --- a/test/snapshot-tests/snapshots/formatting.js.md +++ b/test/snapshot-tests/snapshots/formatting.js.md @@ -27,3 +27,39 @@ Generated by [AVA](https://avajs.dev). ␊ 'Hello, World!'␊ ` + +## test title should be normalized in stdout + +> stdout + + `␊ + √ a rather wordy test title that is wrapped to meet line length requirements in an unconventional way that may interfere with report formatting␊ + √ test title␊ + √ multiline try assertion title␊ + i multiline try assertion title ─ try assertions can have titles too␊ + ─␊ + ␊ + 3 tests passed` + +## test title should be normalized in snapshot + +> resulting snapshot report + + `# Snapshot report for \`test.js\`␊ + ␊ + The actual snapshot is saved in \`test.js.snap\`.␊ + ␊ + Generated by [AVA](https://avajs.dev).␊ + ␊ + ## test title␊ + ␊ + > Snapshot 1␊ + ␊ + 'Hello, World!'␊ + ␊ + ## macro test title␊ + ␊ + > Snapshot 1␊ + ␊ + 'Hello, World!'␊ + ` diff --git a/test/snapshot-tests/snapshots/formatting.js.snap b/test/snapshot-tests/snapshots/formatting.js.snap index 8382a9887..4306a462f 100644 Binary files a/test/snapshot-tests/snapshots/formatting.js.snap and b/test/snapshot-tests/snapshots/formatting.js.snap differ