Skip to content

Commit f8aa171

Browse files
committed
feat(snapshot): support snapshotResolver and snapshotSerializers written in ESM
1 parent 27b89ec commit f8aa171

File tree

16 files changed

+327
-29
lines changed

16 files changed

+327
-29
lines changed

e2e/__tests__/transform.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,4 +347,40 @@ onNodeVersions('>=12.17.0', () => {
347347
expect(json.numPassedTests).toBe(1);
348348
});
349349
});
350+
351+
describe('transform-esm-snapshotResolver', () => {
352+
const dir = path.resolve(
353+
__dirname,
354+
'..',
355+
'transform/transform-esm-snapshotResolver',
356+
);
357+
const snapshotDir = path.resolve(dir, '__snapshots__');
358+
const snapshotFile = path.resolve(snapshotDir, 'snapshot.test.js.snap');
359+
360+
const cleanupTest = () => {
361+
if (fs.existsSync(snapshotFile)) {
362+
fs.unlinkSync(snapshotFile);
363+
}
364+
if (fs.existsSync(snapshotDir)) {
365+
fs.rmdirSync(snapshotDir);
366+
}
367+
};
368+
369+
beforeAll(() => {
370+
runYarnInstall(dir);
371+
});
372+
beforeEach(cleanupTest);
373+
afterAll(cleanupTest);
374+
375+
it('should transform the snapshotResolver', () => {
376+
const result = runJest(dir, ['-w=1', '--no-cache', '--ci=false']);
377+
378+
expect(result.stderr).toMatch('1 snapshot written from 1 test suite');
379+
380+
const contents = require(snapshotFile);
381+
expect(contents).toHaveProperty(
382+
'snapshots are written to custom location 1',
383+
);
384+
});
385+
});
350386
});
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
'use strict';
9+
10+
describe('snapshot serializers', () => {
11+
it('works with first plugin', () => {
12+
const test = {
13+
foo: 1,
14+
};
15+
expect(test).toMatchSnapshot();
16+
});
17+
18+
it('works with second plugin', () => {
19+
const test = {
20+
bar: 2,
21+
};
22+
expect(test).toMatchSnapshot();
23+
});
24+
25+
it('works with nested serializable objects', () => {
26+
const test = {
27+
foo: {
28+
bar: 2,
29+
},
30+
};
31+
expect(test).toMatchSnapshot();
32+
});
33+
34+
it('works with default serializers', () => {
35+
const test = {
36+
$$typeof: Symbol.for('react.test.json'),
37+
children: null,
38+
props: {
39+
id: 'foo',
40+
},
41+
type: 'div',
42+
};
43+
expect(test).toMatchSnapshot();
44+
});
45+
46+
it('works with prepended plugins and default serializers', () => {
47+
const test = {
48+
$$typeof: Symbol.for('react.test.json'),
49+
children: null,
50+
props: {
51+
aProp: {a: 6},
52+
bProp: {foo: 8},
53+
},
54+
type: 'div',
55+
};
56+
expect(test).toMatchSnapshot();
57+
});
58+
59+
it('works with prepended plugins from expect method called once', () => {
60+
const test = {
61+
$$typeof: Symbol.for('react.test.json'),
62+
children: null,
63+
props: {
64+
aProp: {a: 6},
65+
bProp: {foo: 8},
66+
},
67+
type: 'div',
68+
};
69+
// Add plugin that overrides foo specified by Jest config in package.json
70+
expect.addSnapshotSerializer({
71+
print: (val, serialize) => `Foo: ${serialize(val.foo)}`,
72+
test: val => val && val.hasOwnProperty('foo'),
73+
});
74+
expect(test).toMatchSnapshot();
75+
});
76+
77+
it('works with prepended plugins from expect method called twice', () => {
78+
const test = {
79+
$$typeof: Symbol.for('react.test.json'),
80+
children: null,
81+
props: {
82+
aProp: {a: 6},
83+
bProp: {foo: 8},
84+
},
85+
type: 'div',
86+
};
87+
// Add plugin that overrides preceding added plugin
88+
expect.addSnapshotSerializer({
89+
print: (val, serialize) => `FOO: ${serialize(val.foo)}`,
90+
test: val => val && val.hasOwnProperty('foo'),
91+
});
92+
expect(test).toMatchSnapshot();
93+
});
94+
95+
it('works with array of strings in property matcher', () => {
96+
expect({
97+
arrayOfStrings: ['stream'],
98+
}).toMatchSnapshot({
99+
arrayOfStrings: ['stream'],
100+
});
101+
});
102+
103+
it('works with expect.XXX within array in property matcher', () => {
104+
expect({
105+
arrayOfStrings: ['stream'],
106+
}).toMatchSnapshot({
107+
arrayOfStrings: [expect.any(String)],
108+
});
109+
});
110+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"jest": {
3+
"testEnvironment": "node",
4+
"transform": {
5+
"\\.js$": "<rootDir>/transformer.js"
6+
},
7+
"snapshotSerializers": [
8+
"./plugins/foo",
9+
"<rootDir>/plugins/bar"
10+
]
11+
}
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
9+
import {createPlugin} from '../utils';
10+
11+
// We inject the call to "createPlugin('bar') through the transformer"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
9+
import {createPlugin} from '../../utils';
10+
export default createPlugin('foo');
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
'use strict';
9+
10+
module.exports = {
11+
process(src, filename) {
12+
if (/bar.js$/.test(filename)) {
13+
return `${src};\nmodule.exports = createPlugin('bar');`;
14+
}
15+
return src;
16+
},
17+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*/
8+
9+
export const createPlugin = prop => ({
10+
print: (val, serialize) => `${prop} - ${serialize(val[prop])}`,
11+
test: val => val && val.hasOwnProperty(prop),
12+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
test('snapshots are written to custom location', () => {
9+
expect('foobar').toMatchSnapshot();
10+
});
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import {SnapshotResolver} from 'jest-snapshot';
9+
10+
const snapshotResolver = {
11+
resolveSnapshotPath: (testPath, snapshotExtension) =>
12+
testPath.replace('__tests__', '__snapshots__') + snapshotExtension,
13+
14+
resolveTestPath: (snapshotFilePath, snapshotExtension) =>
15+
snapshotFilePath
16+
.replace('__snapshots__', '__tests__')
17+
.slice(0, -(snapshotExtension || '').length),
18+
19+
testPathForConsistencyCheck: 'foo/__tests__/bar.test.js',
20+
};
21+
22+
export default snapshotResolver;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"jest": {
3+
"testEnvironment": "node",
4+
"snapshotResolver": "<rootDir>/customSnapshotResolver.mjs"
5+
}
6+
}

0 commit comments

Comments
 (0)