diff --git a/lib/runner.js b/lib/runner.js index e2773b2e1..11539446e 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -224,8 +224,8 @@ export default class Runner extends Emittery { return this.snapshots.skipSnapshot(options); } - saveSnapshotState() { - return {touchedFiles: this.snapshots.save()}; + async saveSnapshotState() { + return {touchedFiles: await this.snapshots.save()}; } onRun(runnable) { diff --git a/lib/snapshot-manager.js b/lib/snapshot-manager.js index c7a907810..3e3b4b89d 100644 --- a/lib/snapshot-manager.js +++ b/lib/snapshot-manager.js @@ -182,8 +182,8 @@ function sortBlocks(blocksByTitle, blockIndices) { ); } -function encodeSnapshots(snapshotData) { - const encoded = cbor.encodeOne(snapshotData, { +async function encodeSnapshots(snapshotData) { + const encoded = await cbor.encodeAsync(snapshotData, { omitUndefinedProperties: true, canonical: true, }); @@ -351,7 +351,7 @@ class Manager { this.recordSerialized({belongsTo, index, ...snapshot}); } - save() { + async save() { const {dir, relFile, snapFile, snapPath, reportPath} = this; if (this.updating && this.newBlocksByTitle.size === 0) { @@ -371,15 +371,17 @@ class Manager { ), }; - const buffer = encodeSnapshots(snapshots); + const buffer = await encodeSnapshots(snapshots); const reportBuffer = generateReport(relFile, snapFile, snapshots); - fs.mkdirSync(dir, {recursive: true}); + await fs.promises.mkdir(dir, {recursive: true}); const temporaryFiles = []; const tmpfileCreated = file => temporaryFiles.push(file); - writeFileAtomic.sync(snapPath, buffer, {tmpfileCreated}); - writeFileAtomic.sync(reportPath, reportBuffer, {tmpfileCreated}); + await Promise.all([ + writeFileAtomic(snapPath, buffer, {tmpfileCreated}), + writeFileAtomic(reportPath, reportBuffer, {tmpfileCreated}), + ]); return { changedFiles: [snapPath, reportPath], temporaryFiles, diff --git a/lib/worker/base.js b/lib/worker/base.js index 20e36e33d..e62e30eb4 100644 --- a/lib/worker/base.js +++ b/lib/worker/base.js @@ -81,7 +81,7 @@ const run = async options => { runner.on('finish', async () => { try { - const {touchedFiles} = runner.saveSnapshotState(); + const {touchedFiles} = await runner.saveSnapshotState(); if (touchedFiles) { channel.send({type: 'touched-files', files: touchedFiles}); } diff --git a/test-tap/assert.js b/test-tap/assert.js index edd817c01..fe86cb279 100644 --- a/test-tap/assert.js +++ b/test-tap/assert.js @@ -1303,7 +1303,7 @@ test('.notThrowsAsync() fails if passed a bad value', t => { t.end(); }); -test('.snapshot()', t => { +test('.snapshot()', async t => { // Set to `true` to update the snapshot, then run: // npx tap test-tap/assert.js // @@ -1411,7 +1411,7 @@ test('.snapshot()', t => { }); } - manager.save(); + await manager.save(); t.end(); }); diff --git a/test-tap/try-snapshot.js b/test-tap/try-snapshot.js index 2bd1097ba..ff8830d22 100644 --- a/test-tap/try-snapshot.js +++ b/test-tap/try-snapshot.js @@ -84,5 +84,5 @@ test(async t => { t.equal(result.error.name, 'Error'); }); - manager.save(); + await manager.save(); }); diff --git a/test/snapshot-regenerate-report/test.js b/test/snapshot-regenerate-report/test.js index e2704984a..2d0a4ca39 100644 --- a/test/snapshot-regenerate-report/test.js +++ b/test/snapshot-regenerate-report/test.js @@ -38,7 +38,7 @@ test('snapshot report can be regenerated from .snap file', async t => { // Regenerate report snapshots.hasChanges = true; // Force. - snapshots.save(); + await snapshots.save(); // Assert that reports match t.is(await fs.readFile(reportPath, 'utf8'), report); diff --git a/test/snapshot-tests/fixtures/large/package.json b/test/snapshot-tests/fixtures/large/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/snapshot-tests/fixtures/large/package.json @@ -0,0 +1 @@ +{} diff --git a/test/snapshot-tests/fixtures/large/test.js b/test/snapshot-tests/fixtures/large/test.js new file mode 100644 index 000000000..cc86fec06 --- /dev/null +++ b/test/snapshot-tests/fixtures/large/test.js @@ -0,0 +1,9 @@ +const {Buffer} = require('buffer'); + +const test = require(process.env.TEST_AVA_IMPORT_FROM); + +for (let i = 0; i < 2; i++) { + test(`large snapshot ${i}`, t => { + t.snapshot(Buffer.alloc(1024 * 16)); + }); +} diff --git a/test/snapshot-tests/large.js b/test/snapshot-tests/large.js new file mode 100644 index 000000000..ccdc5dbbb --- /dev/null +++ b/test/snapshot-tests/large.js @@ -0,0 +1,15 @@ +import test from '@ava/test'; + +import {cwd, fixture} from '../helpers/exec.js'; +import {withTemporaryFixture} from '../helpers/with-temporary-fixture.js'; + +// Reproduction for https://github.com/avajs/ava/issues/2932. +test('can encode and decode large snapshots', async t => { + await withTemporaryFixture(cwd('large'), async cwd => { + const env = { + AVA_FORCE_CI: 'not-ci', + }; + await fixture(['--update-snapshots'], {cwd, env}); + await t.notThrowsAsync(fixture([], {cwd, env})); + }); +});