Skip to content

Instantly share code, notes, and snippets.

@bajtos
Created September 17, 2019 08:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bajtos/ee9a0006edcf036620168873827d23d1 to your computer and use it in GitHub Desktop.
Save bajtos/ee9a0006edcf036620168873827d23d1 to your computer and use it in GitHub Desktop.
Proof of concept helper for snapshot testing in Mocha
exports['mocha snapshot checker always works for strings'] = `
foo
hello
world
`.slice(1, -1); // remove leading & trailing newlines
exports['mocha snapshot checker always works for objects'] = {
key: 'valuex',
number: 1,
};
const createSnapshotChecker = require('../../snapshot');
const path = require('path');
describe('mocha snapshot checker', () => {
let expectSnapshot;
beforeEach(function setupSnapshots() {
expectSnapshot = createSnapshotChecker(
path.resolve(__dirname, '../../__snapshots__'),
this,
);
});
context('always', () => {
it('works for strings', function() {
expectSnapshot('foo\nbar\nbaz');
});
it('works for objects', function() {
expectSnapshot({key: 'value', number: 1});
});
});
});
const assert = require('assert');
const path = require('path');
module.exports = function createSnapshotChecker(snapshotDir, beforeEachCtx) {
const currentTest = beforeEachCtx.currentTest;
const title = buildTitle(currentTest);
const snapshotFile = buildSnapshotFile(snapshotDir, currentTest);
const data = loadSnapshots(snapshotFile);
let counter = 0;
return function expectSnapshot(actual) {
const key = counter ? `${title}-${counter}` : title;
counter++;
if (!(key in data)) {
throw new Error(`No snapshot found for ${JSON.stringify(key)}.`);
}
assert.deepStrictEqual(actual, data[key]);
};
}
function buildTitle(ctx) {
let result = ctx.title;
for (;;) {
if (!ctx.parent) break;
ctx = ctx.parent;
if (ctx.title) {
result = ctx.title + ' ' + result;
}
}
return result;
}
function buildSnapshotFile(snapshotDir, currentTest) {
const parsed = path.parse(currentTest.file);
const parts = path.normalize(parsed.dir).split(path.sep);
const ix = parts.findIndex(p => p === 'test' || p === '__tests__');
if (ix < 0) {
throw new Error(
'Snapshot checker requires test files in `test` or `__tests__`'
);
}
// Remove everything from start up to (including) `test` or `__tests__`
parts.splice(0, ix+1);
return path.join(snapshotDir, ...parts, parsed.name + '.snapshot.js');
}
function loadSnapshots(snapshotFile) {
try {
return require(snapshotFile);
} catch (err) {
console.log(err.code);
if (err.code === 'MODULE_NOT_FOUND') {
console.warn(
'Warning: snapshot file %j was not found.',
path.relative(process.cwd(), snapshotFile),
);
return {};
}
throw err;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment