| import { spawnPromisified } from '../common/index.mjs'; |
| import * as fixtures from '../common/fixtures.mjs'; |
| import tmpdir from '../common/tmpdir.js'; |
| import assert from 'node:assert'; |
| import path from 'node:path'; |
| import { execPath } from 'node:process'; |
| import { writeFile, readFile, unlink } from 'node:fs/promises'; |
| import { describe, it } from 'node:test'; |
| |
| tmpdir.refresh(); |
| |
| function getSnapshotPath(filename) { |
| const { name, dir } = path.parse(filename); |
| return path.join(tmpdir.path, dir, `${name}.snapshot`); |
| } |
| |
| async function spawnTmpfile(content = '', filename, extraFlags = []) { |
| const header = filename.endsWith('.mjs') ? |
| 'import assert from \'node:assert\';' : |
| 'const assert = require(\'node:assert\');'; |
| await writeFile(path.join(tmpdir.path, filename), `${header}\n${content}`); |
| const { stdout, stderr, code } = await spawnPromisified( |
| execPath, |
| ['--no-warnings', ...extraFlags, filename], |
| { cwd: tmpdir.path }); |
| |
| const snapshotPath = getSnapshotPath(filename); |
| const snapshot = await readFile(snapshotPath, 'utf8').catch((err) => err); |
| return { stdout, stderr, code, snapshot, snapshotPath, filename }; |
| } |
| |
| async function spawnFixture(filename) { |
| const { dir, base, name } = path.parse(filename); |
| const { stdout, stderr, code } = await spawnPromisified(execPath, ['--no-warnings', base], { cwd: dir }); |
| |
| const snapshotPath = path.join(dir, `${name}.snapshot`); |
| const snapshot = await readFile(snapshotPath, 'utf8').catch((err) => err); |
| return { stdout, stderr, code, snapshot, snapshotPath }; |
| } |
| |
| describe('assert.snapshot', { concurrency: true }, () => { |
| it('should write snapshot', async () => { |
| const { stderr, code, snapshot, snapshotPath } = await spawnFixture(fixtures.path('assert-snapshot/basic.mjs')); |
| await unlink(snapshotPath); |
| assert.strictEqual(stderr, ''); |
| assert.strictEqual(code, 0); |
| assert.match(snapshot, /^name:\r?\n'test'$/); |
| }); |
| |
| it('should write multiple snapshots', async () => { |
| const { stderr, code, snapshot, snapshotPath } = await spawnFixture(fixtures.path('assert-snapshot/multiple.mjs')); |
| await unlink(snapshotPath); |
| assert.strictEqual(stderr, ''); |
| assert.strictEqual(code, 0); |
| assert.match(snapshot, /^name:\n'test'\r?\n#\*#\*#\*#\*#\*#\*#\*#\*#\*#\*#\*#\r?\nanother name:\r?\n'test'$/); |
| }); |
| |
| it('should succeed running multiple times', async () => { |
| let result = await spawnFixture(fixtures.path('assert-snapshot/single.mjs'), false); |
| assert.strictEqual(result.stderr, ''); |
| assert.strictEqual(result.code, 0); |
| assert.match(result.snapshot, /^snapshot:\r?\n'test'$/); |
| |
| result = await spawnFixture(fixtures.path('assert-snapshot/single.mjs')); |
| await unlink(result.snapshotPath); |
| assert.strictEqual(result.stderr, ''); |
| assert.strictEqual(result.code, 0); |
| assert.match(result.snapshot, /^snapshot:\r?\n'test'$/); |
| }); |
| |
| it('should fail when name is not provided', async () => { |
| for (const name of [1, undefined, null, {}, function() {}]) { |
| await assert.rejects(() => assert.snapshot('', name), { |
| code: 'ERR_INVALID_ARG_TYPE', |
| name: 'TypeError', |
| message: /^The "name" argument must be of type string/ |
| }); |
| } |
| }); |
| |
| it('should fail when value does not match snapshot', async () => { |
| const { code, stderr, snapshot } = await spawnFixture(fixtures.path('assert-snapshot/value-changed.mjs')); |
| assert.match(stderr, /AssertionError \[ERR_ASSERTION\]/); |
| assert.strictEqual(code, 1); |
| assert.match(snapshot, /^snapshot:\r?\n'original'$/); |
| }); |
| |
| it('should fail when snapshot does not contain a named snapshot', async () => { |
| const { code, stderr, snapshot } = await spawnFixture(fixtures.path('assert-snapshot/non-existing-name.mjs')); |
| assert.match(stderr, /AssertionError \[ERR_ASSERTION\]/); |
| assert.match(stderr, /Snapshot "non existing" does not exist/); |
| assert.strictEqual(code, 1); |
| assert.match(snapshot, /^another name:\r?\n'test'\r?\n#\*#\*#\*#\*#\*#\*#\*#\*#\*#\*#\*#\r?\nname:\r?\n'test'$/); |
| }); |
| |
| it('should snapshot a random replaced value', async () => { |
| const originalSnapshot = await readFile(fixtures.path('assert-snapshot/random.snapshot'), 'utf8'); |
| const { stderr, code, snapshot } = await spawnFixture(fixtures.path('assert-snapshot/random.mjs')); |
| assert.strictEqual(stderr, ''); |
| assert.strictEqual(code, 0); |
| assert.strictEqual(snapshot, originalSnapshot); |
| }); |
| |
| it('should serialize values', async () => { |
| const originalSnapshot = await readFile(fixtures.path('assert-snapshot/serialize.snapshot'), 'utf8'); |
| const { stderr, code, snapshot } = await spawnFixture(fixtures.path('assert-snapshot/serialize.mjs')); |
| assert.strictEqual(stderr, ''); |
| assert.strictEqual(code, 0); |
| assert.strictEqual(snapshot, originalSnapshot); |
| }); |
| |
| it('should override snapshot when passing --update-assert-snapshot', async () => { |
| const filename = 'updated.mjs'; |
| await writeFile(getSnapshotPath(filename), 'snapshot:\n\'test\''); |
| const { stderr, code, snapshot } = await spawnTmpfile('await assert.snapshot(\'changed\', \'snapshot\');', |
| filename, ['--update-assert-snapshot']); |
| assert.strictEqual(stderr, ''); |
| assert.strictEqual(code, 0); |
| assert.match(snapshot, /^snapshot:\r?\n'changed'$/); |
| }); |
| |
| it('snapshot file should have the name of the module - esm', async () => { |
| const filename = 'name.mjs'; |
| const { snapshotPath } = await spawnTmpfile('await assert.snapshot("test");', filename); |
| assert.match(snapshotPath, /name\.snapshot$/); |
| }); |
| |
| it('snapshot file should have the name of the module - common js', async () => { |
| const filename = 'name.js'; |
| const { snapshotPath } = await spawnTmpfile('assert.snapshot("test").then(() => process.exit());', filename); |
| assert.match(snapshotPath, /name\.snapshot$/); |
| }); |
| }); |