Skip to content

Commit

Permalink
test: Integrate Jest snapshot with fixtures (#2294)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmdartus authored Apr 20, 2021
1 parent 3bf63d0 commit 73e98fa
Show file tree
Hide file tree
Showing 55 changed files with 460 additions and 349 deletions.
4 changes: 1 addition & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,9 @@ yarn test <path_to_test>
If you change the way the compiler outputs code, then you may see failed tests due to these changes. In those cases, you can regenerate the test snapshots like so:

```bash
find . -type f | grep __tests__ | grep expected | xargs rm -f
yarn test -u
```

Then run `yarn test` to regenerate the snapshots.

If you want to debug these tests, you can do as follow:

1. First, insert a new line in your test where you think it might be failing and type `debugger`. This will serve as a break point for the debugger to stop at.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"is-ci": "^3.0.0",
"isbinaryfile": "^4.0.6",
"jest": "^26.6.3",
"jest-utils-lwc-internals": "link:./scripts/jest/utils",
"lerna": "^4.0.0",
"lint-staged": "^10.5.4",
"prettier": "^2.2.1",
Expand Down
3 changes: 3 additions & 0 deletions packages/@lwc/engine-server/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ module.exports = {
displayName: 'lwc-engine-server',
roots: ['<rootDir>/src'],
testEnvironment: 'node',
moduleNameMapper: {
'^lwc$': '<rootDir>/src/index.ts',
},
};
156 changes: 47 additions & 109 deletions packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,38 @@

import fs from 'fs';
import path from 'path';

import { rollup } from 'rollup';
import prettier from 'prettier';
import lwcRollupPlugin from '@lwc/rollup-plugin';
import { testFixtureDir } from 'jest-utils-lwc-internals';

const FIXTURE_DIR = path.join(__dirname, 'fixtures');
jest.setTimeout(10_000 /* 10 seconds */);

const DIST_DIRNAME = 'dist';
const MODULE_DIRNAME = 'modules';
const FIXTURE_NAMESPACE = 'x';
async function compileFixture({ input, dirname }) {
const modulesDir = path.resolve(dirname, './modules');
const outputFile = path.resolve(dirname, './dist/compiled.js');

const CONFIG_FILENAME = 'config.json';
const COMPILER_ENTRY_FILENAME = 'fixture.js';
const EXPECTED_HTML_FILENAME = 'expected.html';
const bundle = await rollup({
input,
external: ['lwc'],
plugins: [
lwcRollupPlugin({
modules: [
{
dir: modulesDir,
},
],
}),
],
});

const ONLY_FILENAME = '.only';
const SKIP_FILENAME = '.skip';
await bundle.write({
file: outputFile,
});

jest.setTimeout(10_000 /* 10 seconds */);
return outputFile;
}

function formatHTML(code: string): string {
return prettier.format(code, {
Expand All @@ -34,95 +48,24 @@ function formatHTML(code: string): string {
}

describe('fixtures', () => {
const fixtures = fs.readdirSync(FIXTURE_DIR);

for (const caseName of fixtures) {
const caseTagName = `${FIXTURE_NAMESPACE}-${caseName}`;
const caseModuleName = `${FIXTURE_NAMESPACE}/${caseName}`;
const caseFolder = path.join(FIXTURE_DIR, caseName);

const fixtureFilePath = (fileName): string => {
return path.join(caseFolder, fileName);
};

const fixtureFileExists = (fileName): boolean => {
const filePath = fixtureFilePath(fileName);
return fs.existsSync(filePath);
};

const readFixtureFile = (fileName): string => {
const filePath = fixtureFilePath(fileName);
return fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : null;
};

const writeFixtureFile = (fileName, content): void => {
const filePath = fixtureFilePath(fileName);
fs.writeFileSync(filePath, content, { encoding: 'utf-8' });
};

const compileFixture = async () => {
const bundle = await rollup({
input: COMPILER_ENTRY_FILENAME,
plugins: [
{
name: 'fixture-resolver',
resolveId(specifier) {
if (specifier === COMPILER_ENTRY_FILENAME) {
return COMPILER_ENTRY_FILENAME;
}
},
load(specifier) {
if (specifier === COMPILER_ENTRY_FILENAME) {
return `export { default as ctor } from '${caseModuleName}';`;
}
},
},
{
name: 'lwc-server-resolver',
resolveId(specifier) {
if (specifier === 'lwc') {
const lwcServerRelativePath = path.relative(
fixtureFilePath(MODULE_DIRNAME),
path.resolve(__dirname, '../index')
);

return {
id: lwcServerRelativePath,
external: true,
};
}
},
},
lwcRollupPlugin({
modules: [
{
dir: fixtureFilePath(MODULE_DIRNAME),
},
],
}) as any,
],
});
testFixtureDir(
{
root: path.resolve(__dirname, 'fixtures'),
pattern: '**/index.js',
},
async ({ filename, dirname }) => {
const configPath = path.resolve(dirname, 'config.json');

let config: any = {};
if (fs.existsSync(configPath)) {
config = require(configPath);
}

await bundle.write({
dir: fixtureFilePath(DIST_DIRNAME),
const compiledFixturePath = await compileFixture({
input: filename,
dirname,
});

return fixtureFilePath(`${DIST_DIRNAME}/${COMPILER_ENTRY_FILENAME}`);
};

let testFn = it;
if (fixtureFileExists(ONLY_FILENAME)) {
testFn = (it as any).only;
} else if (fixtureFileExists(SKIP_FILENAME)) {
testFn = (it as any).skip;
}

testFn(`${caseName}`, async () => {
const compiledFixturePath = await compileFixture();

let expected = readFixtureFile(EXPECTED_HTML_FILENAME);
const config = JSON.parse(readFixtureFile(CONFIG_FILENAME) || '{}');

// The LWC engine holds global state like the current VM index, which has an impact on
// the generated HTML IDs. So the engine has to be re-evaluated between tests.
// On top of this, the engine also checks if the component constructor is an instance of
Expand All @@ -135,20 +78,15 @@ describe('fixtures', () => {
module = require(compiledFixturePath);
});

const actual = lwcEngineServer.renderComponent(
caseTagName,
module.ctor,
const result = lwcEngineServer.renderComponent(
module.tagName,
module.default,
config.props || {}
);

if (!expected) {
// Write rendered HTML file if doesn't exist (ie new fixture).
expected = actual;
writeFixtureFile(EXPECTED_HTML_FILENAME, formatHTML(expected));
}

// Check rendered HTML.
expect(formatHTML(actual)).toEqual(formatHTML(expected));
});
}
return {
'expected.html': formatHTML(result),
};
}
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attribute-boolean';
export { default } from 'x/attribute-boolean';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attribute-component-aria';
export { default } from 'x/attribute-component-aria';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attribute-component-global-html';
export { default } from 'x/attribute-component-global-html';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attribute-dynamic-escape';
export { default } from 'x/attribute-dynamic-escape';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attribute-dynamic';
export { default } from 'x/attribute-dynamic';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attribute-global-html';
export { default } from 'x/attribute-global-html';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attribute-live-bindings';
export { default } from 'x/attribute-live-bindings';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attribute-static';
export { default } from 'x/attribute-static';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attribute-style';
export { default } from 'x/attribute-style';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-attributes-aria';
export { default } from 'x/attributes-aria';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-component';
export { default } from 'x/component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-computed';
export { default } from 'x/computed';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-delegates-focus';
export { default } from 'x/delegates-focus';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-for-each-block';
export { default } from 'x/for-each-block';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-for-each-child-nested';
export { default } from 'x/for-each-child-nested';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-for-each-nested';
export { default } from 'x/for-each-nested';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-getter-class-list';
export { default } from 'x/getter-class-list';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-getter-is-connected';
export { default } from 'x/getter-is-connected';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-if-block';
export { default } from 'x/if-block';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-if-conditional-slot-content';
export { default } from 'x/if-conditional-slot-content';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-if-conditional-slot';
export { default } from 'x/if-conditional-slot';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-if-custom-element-child';
export { default } from 'x/if-custom-element-child';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-if-element-child';
export { default } from 'x/if-element-child';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-iterator-block';
export { default } from 'x/iterator-block';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-lifecycle-hooks';
export { default } from 'x/lifecycle-hooks';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-lwc-dom-manual';
export { default } from 'x/lwc-dom-manual';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-lwc-dynamic';
export { default } from 'x/lwc-dynamic';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-method-get-attribute';
export { default } from 'x/method-get-attribute';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-method-remove-attribute';
export { default } from 'x/method-remove-attribute';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-method-set-attribute';
export { default } from 'x/method-set-attribute';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-methods-noop';
export { default } from 'x/methods-noop';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-methods-unsupported';
export { default } from 'x/methods-unsupported';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-rehydration';
export { default } from 'x/rehydration';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-slotchange';
export { default } from 'x/slotchange';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-slots-fallback';
export { default } from 'x/slots-fallback';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-slots-nested';
export { default } from 'x/slots-nested';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-slots-unknown';
export { default } from 'x/slots-unknown';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-slots';
export { default } from 'x/slots';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-styles';
export { default } from 'x/styles';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-text-interpolation-escape';
export { default } from 'x/text-interpolation-escape';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-text-interpolation';
export { default } from 'x/text-interpolation';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-text-static';
export { default } from 'x/text-static';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagName = 'x-wire';
export { default } from 'x/wire';
Loading

0 comments on commit 73e98fa

Please sign in to comment.