You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
2.0 KiB
JavaScript

"use strict";
const fs = require("fs");
const path = require("path");
const cbor = require("cbor");
function sanitizeTestName(name) {
return name.replace(/[\/\\\s]+/g, "-");
}
function serializeValue(value) {
return cbor.encodeOne(value, { highWaterMark: 1e8 });
}
function deserializeValue(value) {
return cbor.decodeFirstSync(value);
}
module.exports = {
setup: function (tape, snapshotsRoot) {
Object.assign(tape.Test.prototype, {
equalsSnapshot: function (value, id) {
let testName = sanitizeTestName(this.name);
let snapshotNumber = (this.__lastSnapshot ?? 0) + 1;
this.__lastSnapshot = snapshotNumber;
let fullTestName = (id != null)
? `${testName}-${id}`
: `${testName}-snapshot-${snapshotNumber}`
let snapshotPath = path.resolve(snapshotsRoot, `${fullTestName}.cbor`);
let serializedValue = serializeValue(value);
if (process.env.UPDATE_SNAPSHOT === "ALL" || process.env.UPDATE_SNAPSHOT === fullTestName) {
fs.mkdirSync(snapshotsRoot, { recursive: true });
fs.writeFileSync(snapshotPath, serializedValue);
console.warn(`[!] Snapshot for '${fullTestName}' was updated`);
} else if (fs.existsSync(snapshotPath)) {
// NOTE: To ensure that the replacer transforms are applied to *both* values, we *always* serialize the current value even when we're just comparing it against a known one; we then just deserialize it again below.
// TODO: Investigate whether this can be optimized with a recursive object transform instead
let knownValue = deserializeValue(fs.readFileSync(snapshotPath));
let deserializedValue = deserializeValue(serializedValue);
this.deepEquals(deserializedValue, knownValue, `Snapshot for '${fullTestName}' does not match; re-run with UPDATE_SNAPSHOT=${fullTestName} to update the snapshot and mark the current result as valid`);
} else {
throw new Error(`No known snapshot for '${fullTestName}'; re-run with UPDATE_SNAPSHOT=${fullTestName} to create it automatically`);
}
}
});
}
};