From 79acc55326648e8126a5b277af97a3c2765b1cce Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 16:06:31 -0700
Subject: [PATCH 01/24] test: move to proper jest project structure
---
jest.config.js | 19 +++++++++----------
.../jest.config.js | 5 +++++
packages/lwc-compiler/jest.config.js | 10 ++++++++++
packages/lwc-engine/jest.config.js | 9 +++++++++
.../src/framework/__tests__/api.spec.ts | 4 ++--
packages/lwc-module-resolver/jest.config.js | 5 +++++
packages/lwc-template-compiler/jest.config.js | 9 +++++++++
packages/lwc-wire-service/jest.config.js | 9 +++++++++
packages/observable-membrane/jest.config.js | 9 +++++++++
packages/postcss-plugin-lwc/jest.config.js | 9 +++++++++
.../rollup-plugin-lwc-compiler/jest.config.js | 5 +++++
11 files changed, 81 insertions(+), 12 deletions(-)
create mode 100644 packages/babel-plugin-transform-lwc-class/jest.config.js
create mode 100644 packages/lwc-compiler/jest.config.js
create mode 100644 packages/lwc-engine/jest.config.js
create mode 100644 packages/lwc-module-resolver/jest.config.js
create mode 100644 packages/lwc-template-compiler/jest.config.js
create mode 100644 packages/lwc-wire-service/jest.config.js
create mode 100644 packages/observable-membrane/jest.config.js
create mode 100644 packages/postcss-plugin-lwc/jest.config.js
create mode 100644 packages/rollup-plugin-lwc-compiler/jest.config.js
diff --git a/jest.config.js b/jest.config.js
index f7ae879312..e03078ad06 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,13 +1,12 @@
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- '.js': require.resolve('ts-jest/preprocessor.js')
- },
- testMatch: [
- '/packages/*/**/__tests__/*.spec.(js|ts)'
- ],
projects: [
- ''
- ]
+ '/packages/babel-plugin-transform-lwc-class',
+ '/packages/lwc-compiler',
+ '/packages/lwc-engine',
+ '/packages/lwc-module-resolver',
+ '/packages/lwc-template-compiler',
+ '/packages/lwc-wire-service',
+ '/packages/observable-membrane',
+ '/packages/postcss-plugin-lwc',
+ ],
};
diff --git a/packages/babel-plugin-transform-lwc-class/jest.config.js b/packages/babel-plugin-transform-lwc-class/jest.config.js
new file mode 100644
index 0000000000..ef2879887a
--- /dev/null
+++ b/packages/babel-plugin-transform-lwc-class/jest.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ testMatch: [
+ '/**/__tests__/**/*.spec.js'
+ ],
+};
diff --git a/packages/lwc-compiler/jest.config.js b/packages/lwc-compiler/jest.config.js
new file mode 100644
index 0000000000..0f694e417f
--- /dev/null
+++ b/packages/lwc-compiler/jest.config.js
@@ -0,0 +1,10 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.js': require.resolve('ts-jest/preprocessor.js'),
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.js'
+ ],
+};
diff --git a/packages/lwc-engine/jest.config.js b/packages/lwc-engine/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/lwc-engine/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/lwc-engine/src/framework/__tests__/api.spec.ts b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
index de588f65bb..f187c27623 100644
--- a/packages/lwc-engine/src/framework/__tests__/api.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
@@ -190,8 +190,8 @@ describe('api', () => {
});
});
- describe('#i()', () => {
- it('should support various types', () => {
+ describe.only('#i()', () => {
+ it.only('should support various types', () => {
expect(api.i([], () => null)).toEqual([]);
expect(api.i(undefined as any, () => null)).toEqual([]);
expect(api.i(null as any, () => null)).toEqual([]);
diff --git a/packages/lwc-module-resolver/jest.config.js b/packages/lwc-module-resolver/jest.config.js
new file mode 100644
index 0000000000..ef2879887a
--- /dev/null
+++ b/packages/lwc-module-resolver/jest.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ testMatch: [
+ '/**/__tests__/**/*.spec.js'
+ ],
+};
diff --git a/packages/lwc-template-compiler/jest.config.js b/packages/lwc-template-compiler/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/lwc-template-compiler/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/lwc-wire-service/jest.config.js b/packages/lwc-wire-service/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/lwc-wire-service/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/observable-membrane/jest.config.js b/packages/observable-membrane/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/observable-membrane/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/postcss-plugin-lwc/jest.config.js b/packages/postcss-plugin-lwc/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/postcss-plugin-lwc/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/rollup-plugin-lwc-compiler/jest.config.js b/packages/rollup-plugin-lwc-compiler/jest.config.js
new file mode 100644
index 0000000000..ef2879887a
--- /dev/null
+++ b/packages/rollup-plugin-lwc-compiler/jest.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ testMatch: [
+ '/**/__tests__/**/*.spec.js'
+ ],
+};
From e71b82a5e1c67a26efcf007f513844e0112075da Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 16:07:59 -0700
Subject: [PATCH 02/24] test: remove only
---
packages/lwc-engine/src/framework/__tests__/api.spec.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/lwc-engine/src/framework/__tests__/api.spec.ts b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
index f187c27623..de588f65bb 100644
--- a/packages/lwc-engine/src/framework/__tests__/api.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
@@ -190,8 +190,8 @@ describe('api', () => {
});
});
- describe.only('#i()', () => {
- it.only('should support various types', () => {
+ describe('#i()', () => {
+ it('should support various types', () => {
expect(api.i([], () => null)).toEqual([]);
expect(api.i(undefined as any, () => null)).toEqual([]);
expect(api.i(null as any, () => null)).toEqual([]);
From b2cf0d9173b6b01049acab684cceeb89f7476ed8 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 16:45:02 -0700
Subject: [PATCH 03/24] test: add setup script to clean up the registry after
each test
---
packages/lwc-engine/jest.config.js | 1 +
packages/lwc-engine/package.json | 6 +++---
packages/lwc-engine/scripts/jest/setup.ts | 7 +++++++
.../scripts/{ => rollup}/engine.rollup.config.util.js | 0
.../scripts/{ => rollup}/rollup.config.es-and-cjs.js | 8 ++++----
.../scripts/{ => rollup}/rollup.config.umd.dev.js | 6 +++---
.../scripts/{ => rollup}/rollup.config.umd.prod.js | 6 +++---
packages/lwc-engine/src/framework/def.ts | 9 ++++++++-
8 files changed, 29 insertions(+), 14 deletions(-)
create mode 100644 packages/lwc-engine/scripts/jest/setup.ts
rename packages/lwc-engine/scripts/{ => rollup}/engine.rollup.config.util.js (100%)
rename packages/lwc-engine/scripts/{ => rollup}/rollup.config.es-and-cjs.js (80%)
rename packages/lwc-engine/scripts/{ => rollup}/rollup.config.umd.dev.js (86%)
rename packages/lwc-engine/scripts/{ => rollup}/rollup.config.umd.prod.js (90%)
diff --git a/packages/lwc-engine/jest.config.js b/packages/lwc-engine/jest.config.js
index f6a181e3c2..c2e16e9c0b 100644
--- a/packages/lwc-engine/jest.config.js
+++ b/packages/lwc-engine/jest.config.js
@@ -6,4 +6,5 @@ module.exports = {
testMatch: [
'/**/__tests__/**/*.spec.ts'
],
+ setupTestFrameworkScriptFile: '/scripts/jest/setup.ts',
};
diff --git a/packages/lwc-engine/package.json b/packages/lwc-engine/package.json
index 1098513c06..893f56d57f 100644
--- a/packages/lwc-engine/package.json
+++ b/packages/lwc-engine/package.json
@@ -9,9 +9,9 @@
"clean": "rm -rf dist",
"build": "concurrently \"yarn build:es-and-cjs\" \"yarn build:umd:prod\" \"yarn build:umd:dev\"",
"test": "DIR=`pwd` && cd ../../ && yarn test $DIR",
- "build:umd:dev": "rollup -c scripts/rollup.config.umd.dev.js",
- "build:umd:prod": "rollup -c scripts/rollup.config.umd.prod.js",
- "build:es-and-cjs": "rollup -c scripts/rollup.config.es-and-cjs.js"
+ "build:umd:dev": "rollup -c scripts/rollup/rollup.config.umd.dev.js",
+ "build:umd:prod": "rollup -c scripts/rollup/rollup.config.umd.prod.js",
+ "build:es-and-cjs": "rollup -c scripts/rollup/rollup.config.es-and-cjs.js"
},
"devDependencies": {
"concurrently": "^3.5.1",
diff --git a/packages/lwc-engine/scripts/jest/setup.ts b/packages/lwc-engine/scripts/jest/setup.ts
new file mode 100644
index 0000000000..d30838ebe7
--- /dev/null
+++ b/packages/lwc-engine/scripts/jest/setup.ts
@@ -0,0 +1,7 @@
+import { flushComponentRegistry } from '../../src/framework/def';
+
+// Clean-up after each test the engine component registry. This avoid having the
+// engine warning that multiple component class are registered with the same name.
+afterEach(() => {
+ flushComponentRegistry();
+});
diff --git a/packages/lwc-engine/scripts/engine.rollup.config.util.js b/packages/lwc-engine/scripts/rollup/engine.rollup.config.util.js
similarity index 100%
rename from packages/lwc-engine/scripts/engine.rollup.config.util.js
rename to packages/lwc-engine/scripts/rollup/engine.rollup.config.util.js
diff --git a/packages/lwc-engine/scripts/rollup.config.es-and-cjs.js b/packages/lwc-engine/scripts/rollup/rollup.config.es-and-cjs.js
similarity index 80%
rename from packages/lwc-engine/scripts/rollup.config.es-and-cjs.js
rename to packages/lwc-engine/scripts/rollup/rollup.config.es-and-cjs.js
index 8e07fec4af..1a43c815ec 100644
--- a/packages/lwc-engine/scripts/rollup.config.es-and-cjs.js
+++ b/packages/lwc-engine/scripts/rollup/rollup.config.es-and-cjs.js
@@ -3,11 +3,11 @@ const typescript = require('rollup-plugin-typescript');
const nodeResolve = require('rollup-plugin-node-resolve');
const { generateTargetName, ignoreCircularDependencies } = require('./engine.rollup.config.util');
-const { version } = require('../package.json');
+const { version } = require('../../package.json');
-const entry = path.resolve(__dirname, '../src/framework/main.ts');
-const commonJSDirectory = path.resolve(__dirname, '../dist/commonjs');
-const modulesDirectory = path.resolve(__dirname, '../dist/modules');
+const entry = path.resolve(__dirname, '../../src/framework/main.ts');
+const commonJSDirectory = path.resolve(__dirname, '../../dist/commonjs');
+const modulesDirectory = path.resolve(__dirname, '../../dist/modules');
const banner = (`/* proxy-compat-disable */`);
const footer = `/** version: ${version} */`;
diff --git a/packages/lwc-engine/scripts/rollup.config.umd.dev.js b/packages/lwc-engine/scripts/rollup/rollup.config.umd.dev.js
similarity index 86%
rename from packages/lwc-engine/scripts/rollup.config.umd.dev.js
rename to packages/lwc-engine/scripts/rollup/rollup.config.umd.dev.js
index 25ecc78aa5..9aafc2afa2 100644
--- a/packages/lwc-engine/scripts/rollup.config.umd.dev.js
+++ b/packages/lwc-engine/scripts/rollup/rollup.config.umd.dev.js
@@ -3,11 +3,11 @@ const replace = require('rollup-plugin-replace');
const typescript = require('rollup-plugin-typescript');
const nodeResolve = require('rollup-plugin-node-resolve');
-const { version } = require('../package.json');
+const { version } = require('../../package.json');
const { generateTargetName, ignoreCircularDependencies } = require('./engine.rollup.config.util');
-const input = path.resolve(__dirname, '../src/framework/main.ts');
-const outputDir = path.resolve(__dirname, '../dist/umd');
+const input = path.resolve(__dirname, '../../src/framework/main.ts');
+const outputDir = path.resolve(__dirname, '../../dist/umd');
const banner = (`/* proxy-compat-disable */`);
const footer = `/** version: ${version} */`;
diff --git a/packages/lwc-engine/scripts/rollup.config.umd.prod.js b/packages/lwc-engine/scripts/rollup/rollup.config.umd.prod.js
similarity index 90%
rename from packages/lwc-engine/scripts/rollup.config.umd.prod.js
rename to packages/lwc-engine/scripts/rollup/rollup.config.umd.prod.js
index 0d8c61f967..4aad8e6786 100644
--- a/packages/lwc-engine/scripts/rollup.config.umd.prod.js
+++ b/packages/lwc-engine/scripts/rollup/rollup.config.umd.prod.js
@@ -5,11 +5,11 @@ const typescript = require('typescript');
const rollupTypescriptPlugin = require('rollup-plugin-typescript');
const nodeResolve = require('rollup-plugin-node-resolve');
const babelMinify = require('babel-minify');
-const { version } = require('../package.json');
+const { version } = require('../../package.json');
const { generateTargetName, ignoreCircularDependencies } = require('./engine.rollup.config.util');
-const entry = path.resolve(__dirname, '../src/framework/main.ts');
-const outputDir = path.resolve(__dirname, '../dist/umd');
+const entry = path.resolve(__dirname, '../../src/framework/main.ts');
+const outputDir = path.resolve(__dirname, '../../dist/umd');
const banner = (`/* proxy-compat-disable */`);
const footer = `/** version: ${version} */`;
diff --git a/packages/lwc-engine/src/framework/def.ts b/packages/lwc-engine/src/framework/def.ts
index bfc7339cd4..6e7145435c 100644
--- a/packages/lwc-engine/src/framework/def.ts
+++ b/packages/lwc-engine/src/framework/def.ts
@@ -504,7 +504,7 @@ export function getComponentDef(Ctor: ComponentConstructor): ComponentDef {
return def;
}
-const TagNameToCtor: HashTable = create(null);
+let TagNameToCtor: HashTable = create(null);
export function getCtorByTagName(tagName: string): ComponentConstructor | undefined {
return TagNameToCtor[tagName];
@@ -525,3 +525,10 @@ export function registerComponent(tagName: string, Ctor: ComponentConstructor) {
}
TagNameToCtor[tagName] = Ctor;
}
+
+// This method is internal to the engine and should only be used for testing purposes!
+// The component registry need to get flushed between each test to avoid having the
+// engine warning about multiple class registration with the same tag name.
+export function flushComponentRegistry() {
+ TagNameToCtor = create(null);
+}
From 704ee1da19d28ea741ad2345112d6b5d6b67cd8a Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 17:03:11 -0700
Subject: [PATCH 04/24] wip: fix more tests
---
jest.config.js | 1 +
packages/lwc-engine/src/framework/__tests__/invoker.spec.ts | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/jest.config.js b/jest.config.js
index e03078ad06..e7ab5b7976 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -8,5 +8,6 @@ module.exports = {
'/packages/lwc-wire-service',
'/packages/observable-membrane',
'/packages/postcss-plugin-lwc',
+ '/packages/rollup-plugin-lwc-compiler',
],
};
diff --git a/packages/lwc-engine/src/framework/__tests__/invoker.spec.ts b/packages/lwc-engine/src/framework/__tests__/invoker.spec.ts
index a7a2b1b2ee..6ed1337dcc 100644
--- a/packages/lwc-engine/src/framework/__tests__/invoker.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/invoker.spec.ts
@@ -155,7 +155,7 @@ describe('invoker', () => {
}
}
function html($api) {
- return [$api.c('x-foo', Child, {})];
+ return [$api.c('x-child', Child, {})];
}
class MyComponent3 extends Element {
renderedCallback() {
From bd1ec47835f9806efda5549b534bdb166b77ebe9 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 17:36:50 -0700
Subject: [PATCH 05/24] wip: fix more warnings
---
.../framework/__tests__/class-list.spec.ts | 12 +-
.../src/framework/__tests__/events.spec.ts | 10 +-
.../framework/__tests__/html-element.spec.ts | 33 +--
.../src/framework/__tests__/root.spec.ts | 223 +++++++++++++++++-
.../modules/__tests__/styles.spec.ts | 14 +-
5 files changed, 255 insertions(+), 37 deletions(-)
diff --git a/packages/lwc-engine/src/framework/__tests__/class-list.spec.ts b/packages/lwc-engine/src/framework/__tests__/class-list.spec.ts
index 984a6ec89b..2900869fe7 100644
--- a/packages/lwc-engine/src/framework/__tests__/class-list.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/class-list.spec.ts
@@ -17,7 +17,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('foo');
});
@@ -33,7 +33,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('foo');
});
@@ -53,7 +53,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('bar baz foo');
});
@@ -73,7 +73,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('');
});
@@ -93,7 +93,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('foo');
});
@@ -113,7 +113,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('bar foo');
});
diff --git a/packages/lwc-engine/src/framework/__tests__/events.spec.ts b/packages/lwc-engine/src/framework/__tests__/events.spec.ts
index 93ed3d9ba6..a7d98fcf12 100644
--- a/packages/lwc-engine/src/framework/__tests__/events.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/events.spec.ts
@@ -95,7 +95,7 @@ describe('Events on Custom Elements', () => {
elm = createElement('x-foo', { is: Foo });
elm.addEventListener('click', clicked2);
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toEqual([1, 2]);
});
@@ -120,7 +120,7 @@ describe('Events on Custom Elements', () => {
}
elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toEqual([1]);
});
@@ -145,7 +145,7 @@ describe('Events on Custom Elements', () => {
elm = createElement('x-foo', { is: Foo });
elm.addEventListener('click', clicked2);
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toEqual([1]);
});
@@ -168,7 +168,7 @@ describe('Events on Custom Elements', () => {
}
elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
- cmp.root.querySelector('div').dispatchEvent(new CustomEvent('test', { bubbles: true })); // intentionally without composed: true to see if the root captures can that
+ cmp.template.querySelector('div').dispatchEvent(new CustomEvent('test', { bubbles: true })); // intentionally without composed: true to see if the root captures can that
expect(result).toHaveLength(1);
});
@@ -191,7 +191,7 @@ describe('Events on Custom Elements', () => {
}
elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toHaveLength(2);
expect(result[0]).toBe(undefined); // context must be the component
expect(result[1]).toBeInstanceOf(Event);
diff --git a/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts b/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts
index 39b4ab9727..557630dd7e 100644
--- a/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts
@@ -7,27 +7,28 @@ import { VNode } from "../../3rdparty/snabbdom/types";
import { Component } from "../component";
import { unwrap } from "../main";
import { querySelector } from "../dom";
+import { callbackify } from "util";
describe('html-element', () => {
describe('#setAttributeNS()', () => {
it('should set attribute on host element when element is nested in template', () => {
- class MyComponent extends Element {
+ class Child extends Element {
setFoo() {
this.setAttributeNS('x', 'foo', 'bar');
}
}
- MyComponent.publicMethods = ['setFoo'];
+ Child.publicMethods = ['setFoo'];
class Parent extends Element {
render() {
return ($api) => {
- return [$api.c('should-set-attribute-on-host-element-when-element-is-nested-in-template-child', MyComponent, {})]
+ return [$api.c('x-child', Child, {})]
}
}
}
const element = createElement('should-set-attribute-on-host-element-when-element-is-nested-in-template', { is: Parent });
document.body.appendChild(element);
- const child = querySelector.call(element, 'should-set-attribute-on-host-element-when-element-is-nested-in-template-child');
+ const child = querySelector.call(element, 'x-child');
child.setFoo();
expect(child.hasAttributeNS('x', 'foo')).toBe(true);
expect(child.getAttributeNS('x', 'foo')).toBe('bar');
@@ -61,23 +62,23 @@ describe('html-element', () => {
describe('#setAttribute()', () => {
it('should set attribute on host element when element is nested in template', () => {
- class MyComponent extends Element {
+ class Child extends Element {
setFoo() {
this.setAttribute('foo', 'bar');
}
}
- MyComponent.publicMethods = ['setFoo'];
+ Child.publicMethods = ['setFoo'];
class Parent extends Element {
render() {
return ($api) => {
- return [$api.c('should-set-attribute-on-host-element-when-element-is-nested-in-template-child', MyComponent, {})]
+ return [$api.c('x-child', Child, {})]
}
}
}
const element = createElement('should-set-attribute-on-host-element-when-element-is-nested-in-template', { is: Parent });
document.body.appendChild(element);
- const child = querySelector.call(element, 'should-set-attribute-on-host-element-when-element-is-nested-in-template-child');
+ const child = querySelector.call(element, 'x-child');
child.setFoo();
expect(child.hasAttribute('foo')).toBe(true);
expect(child.getAttribute('foo')).toBe('bar');
@@ -111,17 +112,17 @@ describe('html-element', () => {
describe('#removeAttributeNS()', () => {
it('should remove namespaced attribute on host element when element is nested in template', () => {
- class MyComponent extends Element {
+ class Child extends Element {
removeTitle() {
this.removeAttributeNS('x', 'title');
}
}
- MyComponent.publicMethods = ['removeTitle'];
+ Child.publicMethods = ['removeTitle'];
class Parent extends Element {
render() {
return ($api) => {
- return [$api.c('remove-namespaced-attribute-on-host-element-child', MyComponent, {
+ return [$api.c('x-child', Child, {
attrs: {
'x:title': 'foo',
}
@@ -131,7 +132,7 @@ describe('html-element', () => {
}
const element = createElement('remove-namespaced-attribute-on-host-element', { is: Parent });
document.body.appendChild(element);
- const child = querySelector.call(element, 'remove-namespaced-attribute-on-host-element-child');
+ const child = querySelector.call(element, 'x-child');
child.removeTitle();
expect(child.hasAttributeNS('x', 'title')).toBe(false);
});
@@ -152,17 +153,17 @@ describe('html-element', () => {
describe('#removeAttribute()', () => {
it('should remove attribute on host element when element is nested in template', () => {
- class MyComponent extends Element {
+ class Child extends Element {
removeTitle() {
this.removeAttribute('title');
}
}
- MyComponent.publicMethods = ['removeTitle'];
+ Child.publicMethods = ['removeTitle'];
class Parent extends Element {
render() {
return ($api) => {
- return [$api.c('element-is-nested-in-template-child', MyComponent, {
+ return [$api.c('x-child', Child, {
attrs: {
title: 'foo',
}
@@ -172,7 +173,7 @@ describe('html-element', () => {
}
const element = createElement('element-is-nested-in-template', { is: Parent });
document.body.appendChild(element);
- const child = querySelector.call(element, 'element-is-nested-in-template-child');
+ const child = querySelector.call(element, 'x-child');
child.removeTitle();
expect(child.hasAttribute('title')).toBe(false);
});
diff --git a/packages/lwc-engine/src/framework/__tests__/root.spec.ts b/packages/lwc-engine/src/framework/__tests__/root.spec.ts
index 0ec03a4cc3..2f3b17ff34 100644
--- a/packages/lwc-engine/src/framework/__tests__/root.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/root.spec.ts
@@ -30,7 +30,7 @@ describe('root', () => {
class MyComponent extends Element {}
const elm = createElement('x-foo', { is: MyComponent });
const vm = elm[ViewModelReflection] as VM;
- expect((vm.component as Component).root.mode).toBe('closed');
+ expect((vm.component as Component).template.mode).toBe('closed');
});
it('should allow searching for elements from template', () => {
@@ -43,7 +43,7 @@ describe('root', () => {
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
return Promise.resolve().then(() => {
- const nodes = (elm[ViewModelReflection].component as Component).root.querySelectorAll('p');
+ const nodes = (elm[ViewModelReflection].component as Component).template.querySelectorAll('p');
expect(nodes).toHaveLength(1);
});
});
@@ -92,7 +92,7 @@ describe('root', () => {
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
return Promise.resolve().then(() => {
- const node = (elm[ViewModelReflection].component as Component).root.querySelector('p');
+ const node = (elm[ViewModelReflection].component as Component).template.querySelector('p');
expect(node).toBeNull();
});
});
@@ -231,4 +231,221 @@ describe('root', () => {
});
});
});
+
+ describe('membrane', () => {
+
+ it('should querySelector on element from template', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [$api.h('li', { key: 1 }, [])])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ const ul = (elm[ViewModelReflection].component as Component).template.querySelector('ul');
+ expect(ul);
+ const li = ul.querySelector('li');
+ expect(li);
+ });
+ });
+
+ it('should not reach into child components template when querySelector invoked on child custom element', () => {
+ expect.assertions(1);
+ let childTemplate;
+ class MyChild extends Element {
+ render() {
+ return function ($api) {
+ return [$api.h('div', {
+ key: 0,
+ }, [])];
+ }
+ }
+ }
+
+ function html($api, $cmp) {
+ return [$api.c('membrane-parent-query-selector-child-custom-element-child', MyChild, {})];
+ }
+
+ class MyComponent extends Element {
+ queryChild() {
+ return this.template.querySelector('membrane-parent-query-selector-child-custom-element-child').querySelector('div');
+ }
+
+ render() {
+ return html;
+ }
+ }
+
+ MyComponent.publicMethods = ['queryChild'];
+
+ const elm = createElement('membrane-parent-query-selector-child-custom-element', { is: MyComponent });
+ document.body.appendChild(elm);
+ expect(elm.queryChild()).toBe(null);
+ });
+
+ it('should querySelectorAll on element from template', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [$api.h('li', { key: 1 }, [])])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ const ul = (elm[ViewModelReflection].component as Component).template.querySelectorAll('ul')[0];
+ expect(ul);
+ const li = ul.querySelectorAll('li')[0];
+ expect(li);
+ });
+ });
+
+ it('should ignore extraneous elements', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ const ul = (elm[ViewModelReflection].component as Component).template.querySelector('ul');
+ expect(ul);
+ ul.appendChild(document.createElement('li'));
+ const li1 = ul.querySelectorAll('li')[0];
+ expect(li1).toBeUndefined();
+ const li2 = ul.querySelector('li');
+ expect(li2).toBeNull();
+ });
+ });
+
+ it('should not throw error if querySelector does not match any elements', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ expect(() => {
+ (elm[ViewModelReflection].component as Component).template.querySelector('doesnotexist');
+ }).not.toThrow();
+ });
+ });
+
+ it('should return null if querySelector does not match any elements', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ expect((elm[ViewModelReflection].component as Component).template.querySelector('doesnotexist')).toBeNull();
+ });
+ });
+
+ it('should not throw error if querySelectorAll does not match any elements', () => {
+ function html($api) {
+ return [$api.h('ul', { key: 0 }, [])];
+ }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ expect(() => {
+ (elm[ViewModelReflection].component as Component).template.querySelectorAll('doesnotexist');
+ }).not.toThrow();
+ });
+ });
+
+ it('should allow walking back to the shadow root', () => {
+ function html($api) {
+ return [$api.h('div', { key: 0 }, [])];
+ }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ const root = (elm[ViewModelReflection].component as Component).template;
+ expect(root.querySelector('div').parentNode).toBe(root);
+ });
+ });
+
+ it('should not expose shadow root on child custom element', () => {
+ expect.assertions(1);
+ let childTemplate;
+ class MyChild extends Element {
+ constructor() {
+ super();
+ childTemplate = this.template;
+ }
+
+ clickDiv() {
+ this.template.querySelector('div').click();
+ }
+
+ render() {
+ return function ($api) {
+ return [$api.h('div', {
+ key: 0,
+ }, [])];
+ }
+ }
+ }
+
+ MyChild.publicMethods = ['clickDiv'];
+
+ function html($api, $cmp) {
+ return [$api.c('x-child-parent-shadow-root', MyChild, {
+ on: {
+ click: $api.b($cmp.handleClick)
+ }
+ })];
+ }
+
+ class MyComponent extends Element {
+ handleClick(evt) {
+ expect(evt.target.parentNode).not.toBe(childTemplate);
+ }
+
+ clickChildDiv() {
+ this.template.querySelector('x-child-parent-shadow-root').clickDiv();
+ }
+
+ render() {
+ return html;
+ }
+ }
+
+ MyComponent.publicMethods = ['clickChildDiv'];
+
+ const elm = createElement('membrane-child-parent-shadow-root-parent', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ elm.clickChildDiv();
+ });
+ });
+
+ });
+
});
diff --git a/packages/lwc-engine/src/framework/modules/__tests__/styles.spec.ts b/packages/lwc-engine/src/framework/modules/__tests__/styles.spec.ts
index 2afd618ca8..92e6f13ff9 100644
--- a/packages/lwc-engine/src/framework/modules/__tests__/styles.spec.ts
+++ b/packages/lwc-engine/src/framework/modules/__tests__/styles.spec.ts
@@ -21,7 +21,7 @@ describe('modules/styles', () => {
const elm = createElement('x-cmp', { is: Component });
document.body.appendChild(elm);
- expect(cmp.root.querySelector('div').style.display).toBe('inline');
+ expect(cmp.template.querySelector('div').style.display).toBe('inline');
});
it('should add style map to the element', () => {
const tmpl = $api => [
@@ -41,7 +41,7 @@ describe('modules/styles', () => {
const elm = createElement('x-cmp', { is: Component });
document.body.appendChild(elm);
- expect(cmp.root.querySelector('div').style.display).toBe('inline');
+ expect(cmp.template.querySelector('div').style.display).toBe('inline');
});
it('should patch style to the element', () => {
const tmpl = ($api, $cmp) => [
@@ -63,10 +63,10 @@ describe('modules/styles', () => {
};
const elm = createElement('x-cmp', { is: MyComponent });
document.body.appendChild(elm);
- expect(cmp.root.querySelector('div').style.display).toBe('inline');
+ expect(cmp.template.querySelector('div').style.display).toBe('inline');
cmp.counter++;
return Promise.resolve().then(() => {
- expect(cmp.root.querySelector('div').style.display).toBe('block');
+ expect(cmp.template.querySelector('div').style.display).toBe('block');
});
});
it('should patch style map to the element', () => {
@@ -89,11 +89,11 @@ describe('modules/styles', () => {
};
const elm = createElement('x-cmp', { is: MyComponent });
document.body.appendChild(elm);
- expect(cmp.root.querySelector('div').style.display).toBe('inline');
+ expect(cmp.template.querySelector('div').style.display).toBe('inline');
cmp.counter++;
return Promise.resolve().then(() => {
- expect(cmp.root.querySelector('div').style.position).toBe('relative');
- expect(cmp.root.querySelector('div').style.display).toBe('');
+ expect(cmp.template.querySelector('div').style.position).toBe('relative');
+ expect(cmp.template.querySelector('div').style.display).toBe('');
});
});
});
From a46695a06596e813a8b74092e9c78f59c862c348 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 17:43:39 -0700
Subject: [PATCH 06/24] wip: fix more tests
---
.../src/framework/__tests__/component.spec.ts | 6 +++---
.../framework/__tests__/error-boundary.spec.ts | 8 ++++----
.../src/framework/__tests__/template.spec.ts | 12 ++++++------
.../framework/modules/__tests__/events.spec.ts | 16 ++++++++--------
4 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/packages/lwc-engine/src/framework/__tests__/component.spec.ts b/packages/lwc-engine/src/framework/__tests__/component.spec.ts
index 06a1818dd9..947c7bb859 100644
--- a/packages/lwc-engine/src/framework/__tests__/component.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/component.spec.ts
@@ -51,7 +51,7 @@ describe('component', function() {
const elm = createElement('x-foo', { is: Parent });
document.body.appendChild(elm);
expect(elm.lunch).toBe('salad');
- expect(elm[ViewModelReflection].component.root.querySelector('x-component').breakfast).toBe('pancakes');
+ expect(elm[ViewModelReflection].component.template.querySelector('x-component').breakfast).toBe('pancakes');
});
it('should allow calling public getters when element is accessed by querySelector', function() {
@@ -358,7 +358,7 @@ describe('component', function() {
}
});
document.body.appendChild(elm);
- expect(elm[ViewModelReflection].component.root.querySelector('section').style.cssText).toBe('color: red;');
+ expect(elm[ViewModelReflection].component.template.querySelector('section').style.cssText).toBe('color: red;');
expect(calledCSSText).toBe(true);
});
@@ -455,7 +455,7 @@ describe('component', function() {
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const section = elm[ViewModelReflection].component.root.querySelector('section');
+ const section = elm[ViewModelReflection].component.template.querySelector('section');
section.style.removeProperty = function() {
called = true;
};
diff --git a/packages/lwc-engine/src/framework/__tests__/error-boundary.spec.ts b/packages/lwc-engine/src/framework/__tests__/error-boundary.spec.ts
index d0d05267c4..e5dd81a3bf 100644
--- a/packages/lwc-engine/src/framework/__tests__/error-boundary.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/error-boundary.spec.ts
@@ -76,7 +76,7 @@ describe('error boundary component', () => {
return html;
}
}
- const boundaryHostElm = createElement('x-boundary', {is: BoundryHost});
+ const boundaryHostElm = createElement('x-parent', {is: BoundryHost});
document.body.appendChild(boundaryHostElm);
expect(querySelectorAll.call(boundaryHostElm, 'x-boundary-sibling').length).toBe(1);
@@ -198,7 +198,7 @@ describe('error boundary component', () => {
return html;
}
}
- const boundaryHostElm = createElement('x-boundary', {is: BoundryHost});
+ const boundaryHostElm = createElement('x-parent', {is: BoundryHost});
document.body.appendChild(boundaryHostElm);
expect(querySelectorAll.call(boundaryHostElm, 'x-boundary-sibling').length).toBe(1);
@@ -434,7 +434,7 @@ describe('error boundary component', () => {
return html;
}
}
- const boundaryHostElm = createElement('x-boundary', {is: BoundryHost});
+ const boundaryHostElm = createElement('x-parent', {is: BoundryHost});
document.body.appendChild(boundaryHostElm);
expect(querySelectorAll.call(boundaryHostElm, 'x-boundary-sibling').length).toBe(1);
@@ -530,7 +530,7 @@ describe('error boundary component', () => {
return html;
}
}
- const boundaryHostElm = createElement('x-boundary', {is: BoundryHost});
+ const boundaryHostElm = createElement('x-parent', {is: BoundryHost});
document.body.appendChild(boundaryHostElm);
expect(querySelectorAll.call(boundaryHostElm, 'x-boundary-sibling').length).toBe(1);
diff --git a/packages/lwc-engine/src/framework/__tests__/template.spec.ts b/packages/lwc-engine/src/framework/__tests__/template.spec.ts
index 1db7e81eb3..5cda1ae02d 100644
--- a/packages/lwc-engine/src/framework/__tests__/template.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/template.spec.ts
@@ -58,9 +58,9 @@ describe('template', () => {
]);
});
});
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div').length).toBe(2);
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div')[0].textContent).toBe('a');
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div')[1].textContent).toBe('b');
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div').length).toBe(2);
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div')[0].textContent).toBe('a');
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div')[1].textContent).toBe('b');
});
it('should render sets correctly', function() {
@@ -74,9 +74,9 @@ describe('template', () => {
]);
});
});
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div').length).toBe(2);
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div')[0].textContent).toBe('a');
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div')[1].textContent).toBe('b');
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div').length).toBe(2);
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div')[0].textContent).toBe('a');
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div')[1].textContent).toBe('b');
});
// this test depends on the memoization
diff --git a/packages/lwc-engine/src/framework/modules/__tests__/events.spec.ts b/packages/lwc-engine/src/framework/modules/__tests__/events.spec.ts
index f385fb5705..ca363565ea 100644
--- a/packages/lwc-engine/src/framework/modules/__tests__/events.spec.ts
+++ b/packages/lwc-engine/src/framework/modules/__tests__/events.spec.ts
@@ -26,7 +26,7 @@ describe('module/events', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toHaveLength(1);
});
@@ -65,10 +65,10 @@ describe('module/events', () => {
MyComponent.track = { counter: 1 };
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- component.root.querySelector('div').click();
+ component.template.querySelector('div').click();
component.counter += 1;
return Promise.resolve().then( () => {
- component.root.querySelector('div').click();
+ component.template.querySelector('div').click();
expect(second).toBe(true);
expect(result).toEqual([1, 2]);
});
@@ -108,11 +108,11 @@ describe('module/events', () => {
MyComponent.track = { counter: 1 };
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- component.root.querySelector('p').click();
+ component.template.querySelector('p').click();
component.counter += 1;
return Promise.resolve().then( () => {
expect(second).toBe(true);
- component.root.querySelector('div').click();
+ component.template.querySelector('div').click();
expect(result).toEqual([1, 1]);
});
});
@@ -141,7 +141,7 @@ describe('module/events', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toHaveLength(2);
expect(result[0]).toBe(cmp);
expect(result[1]).toBeInstanceOf(Event);
@@ -166,7 +166,7 @@ describe('module/events', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- cmp.root.querySelector('x-child').click();
+ cmp.template.querySelector('x-child').click();
expect(result).toHaveLength(1);
});
@@ -189,7 +189,7 @@ describe('module/events', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- cmp.root.querySelector('x-child').dispatchEvent(new CustomEvent('test', {}));
+ cmp.template.querySelector('x-child').dispatchEvent(new CustomEvent('test', {}));
expect(result).toHaveLength(1);
});
From c9f2af75f5e40df43f262f74dbc399e1a869bf86 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Sun, 20 May 2018 09:04:49 -0700
Subject: [PATCH 07/24] test: refactor test config to be at the monorepo root
---
package.json | 2 +-
.../babel-plugin-transform-lwc-class/jest.config.js | 7 ++++---
packages/lwc-compiler/jest.config.js | 12 ++++--------
packages/lwc-engine/jest.config.js | 12 +++++-------
packages/lwc-module-resolver/jest.config.js | 7 ++++---
packages/lwc-template-compiler/jest.config.js | 11 ++++-------
packages/lwc-wire-service/jest.config.js | 11 ++++-------
packages/observable-membrane/jest.config.js | 11 ++++-------
packages/postcss-plugin-lwc/jest.config.js | 11 ++++-------
packages/rollup-plugin-lwc-compiler/jest.config.js | 7 ++++---
scripts/jest/base.config.js | 10 ++++++++++
jest.config.js => scripts/jest/root.config.js | 3 +++
12 files changed, 51 insertions(+), 53 deletions(-)
create mode 100644 scripts/jest/base.config.js
rename jest.config.js => scripts/jest/root.config.js (90%)
diff --git a/package.json b/package.json
index 4b58c6ab04..a66c95473e 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"clean": "lerna run clean && lerna clean --yes && rm -rf node_modules",
"lint": "tslint -p tsconfig.json && npm run types",
"types": "tsc --noEmit",
- "test": "jest",
+ "test": "jest --config ./scripts/jest/root.config.js",
"test:integration": "yarn run build && lerna exec --scope lwc-integration -- yarn sauce",
"test:performance": "lerna exec --scope benchmark -- best --runner remote",
"build": "lerna run build --ignore benchmark --ignore lwc-integration",
diff --git a/packages/babel-plugin-transform-lwc-class/jest.config.js b/packages/babel-plugin-transform-lwc-class/jest.config.js
index ef2879887a..45171e32f3 100644
--- a/packages/babel-plugin-transform-lwc-class/jest.config.js
+++ b/packages/babel-plugin-transform-lwc-class/jest.config.js
@@ -1,5 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- testMatch: [
- '/**/__tests__/**/*.spec.js'
- ],
+ ...BASE_CONFIG,
+ displayName: 'babel-plugin-transform-lwc-class',
};
diff --git a/packages/lwc-compiler/jest.config.js b/packages/lwc-compiler/jest.config.js
index 0f694e417f..42052a2c38 100644
--- a/packages/lwc-compiler/jest.config.js
+++ b/packages/lwc-compiler/jest.config.js
@@ -1,10 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.js': require.resolve('ts-jest/preprocessor.js'),
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.js'
- ],
+ ...BASE_CONFIG,
+ displayName: 'lwc-compiler',
};
diff --git a/packages/lwc-engine/jest.config.js b/packages/lwc-engine/jest.config.js
index c2e16e9c0b..03988822be 100644
--- a/packages/lwc-engine/jest.config.js
+++ b/packages/lwc-engine/jest.config.js
@@ -1,10 +1,8 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+
+ displayName: 'lwc-engine',
setupTestFrameworkScriptFile: '/scripts/jest/setup.ts',
};
diff --git a/packages/lwc-module-resolver/jest.config.js b/packages/lwc-module-resolver/jest.config.js
index ef2879887a..a40cdc9a5c 100644
--- a/packages/lwc-module-resolver/jest.config.js
+++ b/packages/lwc-module-resolver/jest.config.js
@@ -1,5 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- testMatch: [
- '/**/__tests__/**/*.spec.js'
- ],
+ ...BASE_CONFIG,
+ displayName: 'lwc-module-resolver',
};
diff --git a/packages/lwc-template-compiler/jest.config.js b/packages/lwc-template-compiler/jest.config.js
index f6a181e3c2..7562666402 100644
--- a/packages/lwc-template-compiler/jest.config.js
+++ b/packages/lwc-template-compiler/jest.config.js
@@ -1,9 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+ displayName: 'lwc-template-compiler',
};
diff --git a/packages/lwc-wire-service/jest.config.js b/packages/lwc-wire-service/jest.config.js
index f6a181e3c2..79c7ac2a82 100644
--- a/packages/lwc-wire-service/jest.config.js
+++ b/packages/lwc-wire-service/jest.config.js
@@ -1,9 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+ displayName: 'lwc-wire-service',
};
diff --git a/packages/observable-membrane/jest.config.js b/packages/observable-membrane/jest.config.js
index f6a181e3c2..0008c0a5e7 100644
--- a/packages/observable-membrane/jest.config.js
+++ b/packages/observable-membrane/jest.config.js
@@ -1,9 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+ displayName: 'observable-membrane',
};
diff --git a/packages/postcss-plugin-lwc/jest.config.js b/packages/postcss-plugin-lwc/jest.config.js
index f6a181e3c2..0badadb726 100644
--- a/packages/postcss-plugin-lwc/jest.config.js
+++ b/packages/postcss-plugin-lwc/jest.config.js
@@ -1,9 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+ displayName: 'postcss-plugin-lwc',
};
diff --git a/packages/rollup-plugin-lwc-compiler/jest.config.js b/packages/rollup-plugin-lwc-compiler/jest.config.js
index ef2879887a..10528cf76b 100644
--- a/packages/rollup-plugin-lwc-compiler/jest.config.js
+++ b/packages/rollup-plugin-lwc-compiler/jest.config.js
@@ -1,5 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- testMatch: [
- '/**/__tests__/**/*.spec.js'
- ],
+ ...BASE_CONFIG,
+ displayName: 'rollup-plugin-lwc-compiler',
};
diff --git a/scripts/jest/base.config.js b/scripts/jest/base.config.js
new file mode 100644
index 0000000000..b6195027a2
--- /dev/null
+++ b/scripts/jest/base.config.js
@@ -0,0 +1,10 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ '.js': require.resolve('ts-jest/preprocessor.js')
+ },
+ testMatch: [
+ '/*/**/__tests__/*.spec.(js|ts)'
+ ],
+};
diff --git a/jest.config.js b/scripts/jest/root.config.js
similarity index 90%
rename from jest.config.js
rename to scripts/jest/root.config.js
index e7ab5b7976..b0ef5ac17c 100644
--- a/jest.config.js
+++ b/scripts/jest/root.config.js
@@ -1,4 +1,7 @@
+const path = require('path');
+
module.exports = {
+ rootDir: '../..',
projects: [
'/packages/babel-plugin-transform-lwc-class',
'/packages/lwc-compiler',
From 803109b6796680d434c82e5accea85ec6f98cd90 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Mon, 21 May 2018 08:38:59 -0700
Subject: [PATCH 08/24] style: make jest.config.consistent
---
packages/lwc-engine/jest.config.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/lwc-engine/jest.config.js b/packages/lwc-engine/jest.config.js
index 03988822be..93550116e2 100644
--- a/packages/lwc-engine/jest.config.js
+++ b/packages/lwc-engine/jest.config.js
@@ -2,7 +2,6 @@ const BASE_CONFIG = require('../../scripts/jest/base.config');
module.exports = {
...BASE_CONFIG,
-
displayName: 'lwc-engine',
setupTestFrameworkScriptFile: '/scripts/jest/setup.ts',
};
From 7e7d3acbc2c0e36d1fdaa5433c6938ad14c919f6 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Mon, 21 May 2018 10:34:31 -0700
Subject: [PATCH 09/24] fix: remove unused import
---
scripts/jest/root.config.js | 2 --
1 file changed, 2 deletions(-)
diff --git a/scripts/jest/root.config.js b/scripts/jest/root.config.js
index b0ef5ac17c..1f40b544a0 100644
--- a/scripts/jest/root.config.js
+++ b/scripts/jest/root.config.js
@@ -1,5 +1,3 @@
-const path = require('path');
-
module.exports = {
rootDir: '../..',
projects: [
From e046412a414cb36232cdb438c02cce609a489cd0 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 16:06:31 -0700
Subject: [PATCH 10/24] test: move to proper jest project structure
---
jest.config.js | 19 +++++++++----------
.../jest.config.js | 5 +++++
packages/lwc-compiler/jest.config.js | 10 ++++++++++
packages/lwc-engine/jest.config.js | 9 +++++++++
.../src/framework/__tests__/api.spec.ts | 4 ++--
packages/lwc-module-resolver/jest.config.js | 5 +++++
packages/lwc-template-compiler/jest.config.js | 9 +++++++++
packages/lwc-wire-service/jest.config.js | 9 +++++++++
packages/observable-membrane/jest.config.js | 9 +++++++++
packages/postcss-plugin-lwc/jest.config.js | 9 +++++++++
.../rollup-plugin-lwc-compiler/jest.config.js | 5 +++++
11 files changed, 81 insertions(+), 12 deletions(-)
create mode 100644 packages/babel-plugin-transform-lwc-class/jest.config.js
create mode 100644 packages/lwc-compiler/jest.config.js
create mode 100644 packages/lwc-engine/jest.config.js
create mode 100644 packages/lwc-module-resolver/jest.config.js
create mode 100644 packages/lwc-template-compiler/jest.config.js
create mode 100644 packages/lwc-wire-service/jest.config.js
create mode 100644 packages/observable-membrane/jest.config.js
create mode 100644 packages/postcss-plugin-lwc/jest.config.js
create mode 100644 packages/rollup-plugin-lwc-compiler/jest.config.js
diff --git a/jest.config.js b/jest.config.js
index f7ae879312..e03078ad06 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,13 +1,12 @@
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- '.js': require.resolve('ts-jest/preprocessor.js')
- },
- testMatch: [
- '/packages/*/**/__tests__/*.spec.(js|ts)'
- ],
projects: [
- ''
- ]
+ '/packages/babel-plugin-transform-lwc-class',
+ '/packages/lwc-compiler',
+ '/packages/lwc-engine',
+ '/packages/lwc-module-resolver',
+ '/packages/lwc-template-compiler',
+ '/packages/lwc-wire-service',
+ '/packages/observable-membrane',
+ '/packages/postcss-plugin-lwc',
+ ],
};
diff --git a/packages/babel-plugin-transform-lwc-class/jest.config.js b/packages/babel-plugin-transform-lwc-class/jest.config.js
new file mode 100644
index 0000000000..ef2879887a
--- /dev/null
+++ b/packages/babel-plugin-transform-lwc-class/jest.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ testMatch: [
+ '/**/__tests__/**/*.spec.js'
+ ],
+};
diff --git a/packages/lwc-compiler/jest.config.js b/packages/lwc-compiler/jest.config.js
new file mode 100644
index 0000000000..0f694e417f
--- /dev/null
+++ b/packages/lwc-compiler/jest.config.js
@@ -0,0 +1,10 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.js': require.resolve('ts-jest/preprocessor.js'),
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.js'
+ ],
+};
diff --git a/packages/lwc-engine/jest.config.js b/packages/lwc-engine/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/lwc-engine/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/lwc-engine/src/framework/__tests__/api.spec.ts b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
index de588f65bb..f187c27623 100644
--- a/packages/lwc-engine/src/framework/__tests__/api.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
@@ -190,8 +190,8 @@ describe('api', () => {
});
});
- describe('#i()', () => {
- it('should support various types', () => {
+ describe.only('#i()', () => {
+ it.only('should support various types', () => {
expect(api.i([], () => null)).toEqual([]);
expect(api.i(undefined as any, () => null)).toEqual([]);
expect(api.i(null as any, () => null)).toEqual([]);
diff --git a/packages/lwc-module-resolver/jest.config.js b/packages/lwc-module-resolver/jest.config.js
new file mode 100644
index 0000000000..ef2879887a
--- /dev/null
+++ b/packages/lwc-module-resolver/jest.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ testMatch: [
+ '/**/__tests__/**/*.spec.js'
+ ],
+};
diff --git a/packages/lwc-template-compiler/jest.config.js b/packages/lwc-template-compiler/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/lwc-template-compiler/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/lwc-wire-service/jest.config.js b/packages/lwc-wire-service/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/lwc-wire-service/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/observable-membrane/jest.config.js b/packages/observable-membrane/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/observable-membrane/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/postcss-plugin-lwc/jest.config.js b/packages/postcss-plugin-lwc/jest.config.js
new file mode 100644
index 0000000000..f6a181e3c2
--- /dev/null
+++ b/packages/postcss-plugin-lwc/jest.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ },
+ testMatch: [
+ '/**/__tests__/**/*.spec.ts'
+ ],
+};
diff --git a/packages/rollup-plugin-lwc-compiler/jest.config.js b/packages/rollup-plugin-lwc-compiler/jest.config.js
new file mode 100644
index 0000000000..ef2879887a
--- /dev/null
+++ b/packages/rollup-plugin-lwc-compiler/jest.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ testMatch: [
+ '/**/__tests__/**/*.spec.js'
+ ],
+};
From 1a6d11a502ba4d48d8e72e840b1fc5ff63a9bda1 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 16:07:59 -0700
Subject: [PATCH 11/24] test: remove only
---
packages/lwc-engine/src/framework/__tests__/api.spec.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/lwc-engine/src/framework/__tests__/api.spec.ts b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
index f187c27623..de588f65bb 100644
--- a/packages/lwc-engine/src/framework/__tests__/api.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
@@ -190,8 +190,8 @@ describe('api', () => {
});
});
- describe.only('#i()', () => {
- it.only('should support various types', () => {
+ describe('#i()', () => {
+ it('should support various types', () => {
expect(api.i([], () => null)).toEqual([]);
expect(api.i(undefined as any, () => null)).toEqual([]);
expect(api.i(null as any, () => null)).toEqual([]);
From b0d93779981754922df7b76f9264e56ef27bbf9b Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 16:45:02 -0700
Subject: [PATCH 12/24] test: add setup script to clean up the registry after
each test
---
packages/lwc-engine/jest.config.js | 1 +
packages/lwc-engine/package.json | 6 +++---
packages/lwc-engine/scripts/jest/setup.ts | 7 +++++++
.../scripts/{ => rollup}/engine.rollup.config.util.js | 0
.../scripts/{ => rollup}/rollup.config.es-and-cjs.js | 8 ++++----
.../scripts/{ => rollup}/rollup.config.umd.dev.js | 6 +++---
.../scripts/{ => rollup}/rollup.config.umd.prod.js | 6 +++---
packages/lwc-engine/src/framework/def.ts | 9 ++++++++-
8 files changed, 29 insertions(+), 14 deletions(-)
create mode 100644 packages/lwc-engine/scripts/jest/setup.ts
rename packages/lwc-engine/scripts/{ => rollup}/engine.rollup.config.util.js (100%)
rename packages/lwc-engine/scripts/{ => rollup}/rollup.config.es-and-cjs.js (80%)
rename packages/lwc-engine/scripts/{ => rollup}/rollup.config.umd.dev.js (86%)
rename packages/lwc-engine/scripts/{ => rollup}/rollup.config.umd.prod.js (90%)
diff --git a/packages/lwc-engine/jest.config.js b/packages/lwc-engine/jest.config.js
index f6a181e3c2..c2e16e9c0b 100644
--- a/packages/lwc-engine/jest.config.js
+++ b/packages/lwc-engine/jest.config.js
@@ -6,4 +6,5 @@ module.exports = {
testMatch: [
'/**/__tests__/**/*.spec.ts'
],
+ setupTestFrameworkScriptFile: '/scripts/jest/setup.ts',
};
diff --git a/packages/lwc-engine/package.json b/packages/lwc-engine/package.json
index 1098513c06..893f56d57f 100644
--- a/packages/lwc-engine/package.json
+++ b/packages/lwc-engine/package.json
@@ -9,9 +9,9 @@
"clean": "rm -rf dist",
"build": "concurrently \"yarn build:es-and-cjs\" \"yarn build:umd:prod\" \"yarn build:umd:dev\"",
"test": "DIR=`pwd` && cd ../../ && yarn test $DIR",
- "build:umd:dev": "rollup -c scripts/rollup.config.umd.dev.js",
- "build:umd:prod": "rollup -c scripts/rollup.config.umd.prod.js",
- "build:es-and-cjs": "rollup -c scripts/rollup.config.es-and-cjs.js"
+ "build:umd:dev": "rollup -c scripts/rollup/rollup.config.umd.dev.js",
+ "build:umd:prod": "rollup -c scripts/rollup/rollup.config.umd.prod.js",
+ "build:es-and-cjs": "rollup -c scripts/rollup/rollup.config.es-and-cjs.js"
},
"devDependencies": {
"concurrently": "^3.5.1",
diff --git a/packages/lwc-engine/scripts/jest/setup.ts b/packages/lwc-engine/scripts/jest/setup.ts
new file mode 100644
index 0000000000..d30838ebe7
--- /dev/null
+++ b/packages/lwc-engine/scripts/jest/setup.ts
@@ -0,0 +1,7 @@
+import { flushComponentRegistry } from '../../src/framework/def';
+
+// Clean-up after each test the engine component registry. This avoid having the
+// engine warning that multiple component class are registered with the same name.
+afterEach(() => {
+ flushComponentRegistry();
+});
diff --git a/packages/lwc-engine/scripts/engine.rollup.config.util.js b/packages/lwc-engine/scripts/rollup/engine.rollup.config.util.js
similarity index 100%
rename from packages/lwc-engine/scripts/engine.rollup.config.util.js
rename to packages/lwc-engine/scripts/rollup/engine.rollup.config.util.js
diff --git a/packages/lwc-engine/scripts/rollup.config.es-and-cjs.js b/packages/lwc-engine/scripts/rollup/rollup.config.es-and-cjs.js
similarity index 80%
rename from packages/lwc-engine/scripts/rollup.config.es-and-cjs.js
rename to packages/lwc-engine/scripts/rollup/rollup.config.es-and-cjs.js
index 8e07fec4af..1a43c815ec 100644
--- a/packages/lwc-engine/scripts/rollup.config.es-and-cjs.js
+++ b/packages/lwc-engine/scripts/rollup/rollup.config.es-and-cjs.js
@@ -3,11 +3,11 @@ const typescript = require('rollup-plugin-typescript');
const nodeResolve = require('rollup-plugin-node-resolve');
const { generateTargetName, ignoreCircularDependencies } = require('./engine.rollup.config.util');
-const { version } = require('../package.json');
+const { version } = require('../../package.json');
-const entry = path.resolve(__dirname, '../src/framework/main.ts');
-const commonJSDirectory = path.resolve(__dirname, '../dist/commonjs');
-const modulesDirectory = path.resolve(__dirname, '../dist/modules');
+const entry = path.resolve(__dirname, '../../src/framework/main.ts');
+const commonJSDirectory = path.resolve(__dirname, '../../dist/commonjs');
+const modulesDirectory = path.resolve(__dirname, '../../dist/modules');
const banner = (`/* proxy-compat-disable */`);
const footer = `/** version: ${version} */`;
diff --git a/packages/lwc-engine/scripts/rollup.config.umd.dev.js b/packages/lwc-engine/scripts/rollup/rollup.config.umd.dev.js
similarity index 86%
rename from packages/lwc-engine/scripts/rollup.config.umd.dev.js
rename to packages/lwc-engine/scripts/rollup/rollup.config.umd.dev.js
index 25ecc78aa5..9aafc2afa2 100644
--- a/packages/lwc-engine/scripts/rollup.config.umd.dev.js
+++ b/packages/lwc-engine/scripts/rollup/rollup.config.umd.dev.js
@@ -3,11 +3,11 @@ const replace = require('rollup-plugin-replace');
const typescript = require('rollup-plugin-typescript');
const nodeResolve = require('rollup-plugin-node-resolve');
-const { version } = require('../package.json');
+const { version } = require('../../package.json');
const { generateTargetName, ignoreCircularDependencies } = require('./engine.rollup.config.util');
-const input = path.resolve(__dirname, '../src/framework/main.ts');
-const outputDir = path.resolve(__dirname, '../dist/umd');
+const input = path.resolve(__dirname, '../../src/framework/main.ts');
+const outputDir = path.resolve(__dirname, '../../dist/umd');
const banner = (`/* proxy-compat-disable */`);
const footer = `/** version: ${version} */`;
diff --git a/packages/lwc-engine/scripts/rollup.config.umd.prod.js b/packages/lwc-engine/scripts/rollup/rollup.config.umd.prod.js
similarity index 90%
rename from packages/lwc-engine/scripts/rollup.config.umd.prod.js
rename to packages/lwc-engine/scripts/rollup/rollup.config.umd.prod.js
index 0d8c61f967..4aad8e6786 100644
--- a/packages/lwc-engine/scripts/rollup.config.umd.prod.js
+++ b/packages/lwc-engine/scripts/rollup/rollup.config.umd.prod.js
@@ -5,11 +5,11 @@ const typescript = require('typescript');
const rollupTypescriptPlugin = require('rollup-plugin-typescript');
const nodeResolve = require('rollup-plugin-node-resolve');
const babelMinify = require('babel-minify');
-const { version } = require('../package.json');
+const { version } = require('../../package.json');
const { generateTargetName, ignoreCircularDependencies } = require('./engine.rollup.config.util');
-const entry = path.resolve(__dirname, '../src/framework/main.ts');
-const outputDir = path.resolve(__dirname, '../dist/umd');
+const entry = path.resolve(__dirname, '../../src/framework/main.ts');
+const outputDir = path.resolve(__dirname, '../../dist/umd');
const banner = (`/* proxy-compat-disable */`);
const footer = `/** version: ${version} */`;
diff --git a/packages/lwc-engine/src/framework/def.ts b/packages/lwc-engine/src/framework/def.ts
index bfc7339cd4..6e7145435c 100644
--- a/packages/lwc-engine/src/framework/def.ts
+++ b/packages/lwc-engine/src/framework/def.ts
@@ -504,7 +504,7 @@ export function getComponentDef(Ctor: ComponentConstructor): ComponentDef {
return def;
}
-const TagNameToCtor: HashTable = create(null);
+let TagNameToCtor: HashTable = create(null);
export function getCtorByTagName(tagName: string): ComponentConstructor | undefined {
return TagNameToCtor[tagName];
@@ -525,3 +525,10 @@ export function registerComponent(tagName: string, Ctor: ComponentConstructor) {
}
TagNameToCtor[tagName] = Ctor;
}
+
+// This method is internal to the engine and should only be used for testing purposes!
+// The component registry need to get flushed between each test to avoid having the
+// engine warning about multiple class registration with the same tag name.
+export function flushComponentRegistry() {
+ TagNameToCtor = create(null);
+}
From 52da269f0e99df0bd53a181a0221a6225a664213 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 17:03:11 -0700
Subject: [PATCH 13/24] wip: fix more tests
---
jest.config.js | 1 +
packages/lwc-engine/src/framework/__tests__/invoker.spec.ts | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/jest.config.js b/jest.config.js
index e03078ad06..e7ab5b7976 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -8,5 +8,6 @@ module.exports = {
'/packages/lwc-wire-service',
'/packages/observable-membrane',
'/packages/postcss-plugin-lwc',
+ '/packages/rollup-plugin-lwc-compiler',
],
};
diff --git a/packages/lwc-engine/src/framework/__tests__/invoker.spec.ts b/packages/lwc-engine/src/framework/__tests__/invoker.spec.ts
index a7a2b1b2ee..6ed1337dcc 100644
--- a/packages/lwc-engine/src/framework/__tests__/invoker.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/invoker.spec.ts
@@ -155,7 +155,7 @@ describe('invoker', () => {
}
}
function html($api) {
- return [$api.c('x-foo', Child, {})];
+ return [$api.c('x-child', Child, {})];
}
class MyComponent3 extends Element {
renderedCallback() {
From 2839cdc73c17974c592cfe3c950465e473a5d069 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 17:36:50 -0700
Subject: [PATCH 14/24] wip: fix more warnings
---
.../framework/__tests__/class-list.spec.ts | 12 +-
.../src/framework/__tests__/events.spec.ts | 10 +-
.../framework/__tests__/html-element.spec.ts | 33 +--
.../src/framework/__tests__/root.spec.ts | 223 +++++++++++++++++-
.../modules/__tests__/styles.spec.ts | 14 +-
5 files changed, 255 insertions(+), 37 deletions(-)
diff --git a/packages/lwc-engine/src/framework/__tests__/class-list.spec.ts b/packages/lwc-engine/src/framework/__tests__/class-list.spec.ts
index 984a6ec89b..2900869fe7 100644
--- a/packages/lwc-engine/src/framework/__tests__/class-list.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/class-list.spec.ts
@@ -17,7 +17,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('foo');
});
@@ -33,7 +33,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('foo');
});
@@ -53,7 +53,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('bar baz foo');
});
@@ -73,7 +73,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('');
});
@@ -93,7 +93,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('foo');
});
@@ -113,7 +113,7 @@ describe('class-list', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const childElm = elm[ViewModelReflection].component.root.querySelector('x-child');
+ const childElm = elm[ViewModelReflection].component.template.querySelector('x-child');
expect(childElm.className).toBe('bar foo');
});
diff --git a/packages/lwc-engine/src/framework/__tests__/events.spec.ts b/packages/lwc-engine/src/framework/__tests__/events.spec.ts
index 93ed3d9ba6..a7d98fcf12 100644
--- a/packages/lwc-engine/src/framework/__tests__/events.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/events.spec.ts
@@ -95,7 +95,7 @@ describe('Events on Custom Elements', () => {
elm = createElement('x-foo', { is: Foo });
elm.addEventListener('click', clicked2);
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toEqual([1, 2]);
});
@@ -120,7 +120,7 @@ describe('Events on Custom Elements', () => {
}
elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toEqual([1]);
});
@@ -145,7 +145,7 @@ describe('Events on Custom Elements', () => {
elm = createElement('x-foo', { is: Foo });
elm.addEventListener('click', clicked2);
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toEqual([1]);
});
@@ -168,7 +168,7 @@ describe('Events on Custom Elements', () => {
}
elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
- cmp.root.querySelector('div').dispatchEvent(new CustomEvent('test', { bubbles: true })); // intentionally without composed: true to see if the root captures can that
+ cmp.template.querySelector('div').dispatchEvent(new CustomEvent('test', { bubbles: true })); // intentionally without composed: true to see if the root captures can that
expect(result).toHaveLength(1);
});
@@ -191,7 +191,7 @@ describe('Events on Custom Elements', () => {
}
elm = createElement('x-foo', { is: Foo });
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toHaveLength(2);
expect(result[0]).toBe(undefined); // context must be the component
expect(result[1]).toBeInstanceOf(Event);
diff --git a/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts b/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts
index 39b4ab9727..557630dd7e 100644
--- a/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts
@@ -7,27 +7,28 @@ import { VNode } from "../../3rdparty/snabbdom/types";
import { Component } from "../component";
import { unwrap } from "../main";
import { querySelector } from "../dom";
+import { callbackify } from "util";
describe('html-element', () => {
describe('#setAttributeNS()', () => {
it('should set attribute on host element when element is nested in template', () => {
- class MyComponent extends Element {
+ class Child extends Element {
setFoo() {
this.setAttributeNS('x', 'foo', 'bar');
}
}
- MyComponent.publicMethods = ['setFoo'];
+ Child.publicMethods = ['setFoo'];
class Parent extends Element {
render() {
return ($api) => {
- return [$api.c('should-set-attribute-on-host-element-when-element-is-nested-in-template-child', MyComponent, {})]
+ return [$api.c('x-child', Child, {})]
}
}
}
const element = createElement('should-set-attribute-on-host-element-when-element-is-nested-in-template', { is: Parent });
document.body.appendChild(element);
- const child = querySelector.call(element, 'should-set-attribute-on-host-element-when-element-is-nested-in-template-child');
+ const child = querySelector.call(element, 'x-child');
child.setFoo();
expect(child.hasAttributeNS('x', 'foo')).toBe(true);
expect(child.getAttributeNS('x', 'foo')).toBe('bar');
@@ -61,23 +62,23 @@ describe('html-element', () => {
describe('#setAttribute()', () => {
it('should set attribute on host element when element is nested in template', () => {
- class MyComponent extends Element {
+ class Child extends Element {
setFoo() {
this.setAttribute('foo', 'bar');
}
}
- MyComponent.publicMethods = ['setFoo'];
+ Child.publicMethods = ['setFoo'];
class Parent extends Element {
render() {
return ($api) => {
- return [$api.c('should-set-attribute-on-host-element-when-element-is-nested-in-template-child', MyComponent, {})]
+ return [$api.c('x-child', Child, {})]
}
}
}
const element = createElement('should-set-attribute-on-host-element-when-element-is-nested-in-template', { is: Parent });
document.body.appendChild(element);
- const child = querySelector.call(element, 'should-set-attribute-on-host-element-when-element-is-nested-in-template-child');
+ const child = querySelector.call(element, 'x-child');
child.setFoo();
expect(child.hasAttribute('foo')).toBe(true);
expect(child.getAttribute('foo')).toBe('bar');
@@ -111,17 +112,17 @@ describe('html-element', () => {
describe('#removeAttributeNS()', () => {
it('should remove namespaced attribute on host element when element is nested in template', () => {
- class MyComponent extends Element {
+ class Child extends Element {
removeTitle() {
this.removeAttributeNS('x', 'title');
}
}
- MyComponent.publicMethods = ['removeTitle'];
+ Child.publicMethods = ['removeTitle'];
class Parent extends Element {
render() {
return ($api) => {
- return [$api.c('remove-namespaced-attribute-on-host-element-child', MyComponent, {
+ return [$api.c('x-child', Child, {
attrs: {
'x:title': 'foo',
}
@@ -131,7 +132,7 @@ describe('html-element', () => {
}
const element = createElement('remove-namespaced-attribute-on-host-element', { is: Parent });
document.body.appendChild(element);
- const child = querySelector.call(element, 'remove-namespaced-attribute-on-host-element-child');
+ const child = querySelector.call(element, 'x-child');
child.removeTitle();
expect(child.hasAttributeNS('x', 'title')).toBe(false);
});
@@ -152,17 +153,17 @@ describe('html-element', () => {
describe('#removeAttribute()', () => {
it('should remove attribute on host element when element is nested in template', () => {
- class MyComponent extends Element {
+ class Child extends Element {
removeTitle() {
this.removeAttribute('title');
}
}
- MyComponent.publicMethods = ['removeTitle'];
+ Child.publicMethods = ['removeTitle'];
class Parent extends Element {
render() {
return ($api) => {
- return [$api.c('element-is-nested-in-template-child', MyComponent, {
+ return [$api.c('x-child', Child, {
attrs: {
title: 'foo',
}
@@ -172,7 +173,7 @@ describe('html-element', () => {
}
const element = createElement('element-is-nested-in-template', { is: Parent });
document.body.appendChild(element);
- const child = querySelector.call(element, 'element-is-nested-in-template-child');
+ const child = querySelector.call(element, 'x-child');
child.removeTitle();
expect(child.hasAttribute('title')).toBe(false);
});
diff --git a/packages/lwc-engine/src/framework/__tests__/root.spec.ts b/packages/lwc-engine/src/framework/__tests__/root.spec.ts
index 0ec03a4cc3..2f3b17ff34 100644
--- a/packages/lwc-engine/src/framework/__tests__/root.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/root.spec.ts
@@ -30,7 +30,7 @@ describe('root', () => {
class MyComponent extends Element {}
const elm = createElement('x-foo', { is: MyComponent });
const vm = elm[ViewModelReflection] as VM;
- expect((vm.component as Component).root.mode).toBe('closed');
+ expect((vm.component as Component).template.mode).toBe('closed');
});
it('should allow searching for elements from template', () => {
@@ -43,7 +43,7 @@ describe('root', () => {
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
return Promise.resolve().then(() => {
- const nodes = (elm[ViewModelReflection].component as Component).root.querySelectorAll('p');
+ const nodes = (elm[ViewModelReflection].component as Component).template.querySelectorAll('p');
expect(nodes).toHaveLength(1);
});
});
@@ -92,7 +92,7 @@ describe('root', () => {
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
return Promise.resolve().then(() => {
- const node = (elm[ViewModelReflection].component as Component).root.querySelector('p');
+ const node = (elm[ViewModelReflection].component as Component).template.querySelector('p');
expect(node).toBeNull();
});
});
@@ -231,4 +231,221 @@ describe('root', () => {
});
});
});
+
+ describe('membrane', () => {
+
+ it('should querySelector on element from template', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [$api.h('li', { key: 1 }, [])])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ const ul = (elm[ViewModelReflection].component as Component).template.querySelector('ul');
+ expect(ul);
+ const li = ul.querySelector('li');
+ expect(li);
+ });
+ });
+
+ it('should not reach into child components template when querySelector invoked on child custom element', () => {
+ expect.assertions(1);
+ let childTemplate;
+ class MyChild extends Element {
+ render() {
+ return function ($api) {
+ return [$api.h('div', {
+ key: 0,
+ }, [])];
+ }
+ }
+ }
+
+ function html($api, $cmp) {
+ return [$api.c('membrane-parent-query-selector-child-custom-element-child', MyChild, {})];
+ }
+
+ class MyComponent extends Element {
+ queryChild() {
+ return this.template.querySelector('membrane-parent-query-selector-child-custom-element-child').querySelector('div');
+ }
+
+ render() {
+ return html;
+ }
+ }
+
+ MyComponent.publicMethods = ['queryChild'];
+
+ const elm = createElement('membrane-parent-query-selector-child-custom-element', { is: MyComponent });
+ document.body.appendChild(elm);
+ expect(elm.queryChild()).toBe(null);
+ });
+
+ it('should querySelectorAll on element from template', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [$api.h('li', { key: 1 }, [])])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ const ul = (elm[ViewModelReflection].component as Component).template.querySelectorAll('ul')[0];
+ expect(ul);
+ const li = ul.querySelectorAll('li')[0];
+ expect(li);
+ });
+ });
+
+ it('should ignore extraneous elements', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ const ul = (elm[ViewModelReflection].component as Component).template.querySelector('ul');
+ expect(ul);
+ ul.appendChild(document.createElement('li'));
+ const li1 = ul.querySelectorAll('li')[0];
+ expect(li1).toBeUndefined();
+ const li2 = ul.querySelector('li');
+ expect(li2).toBeNull();
+ });
+ });
+
+ it('should not throw error if querySelector does not match any elements', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ expect(() => {
+ (elm[ViewModelReflection].component as Component).template.querySelector('doesnotexist');
+ }).not.toThrow();
+ });
+ });
+
+ it('should return null if querySelector does not match any elements', () => {
+ function html($api) { return [$api.h('ul', { key: 0 }, [])]; }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ expect((elm[ViewModelReflection].component as Component).template.querySelector('doesnotexist')).toBeNull();
+ });
+ });
+
+ it('should not throw error if querySelectorAll does not match any elements', () => {
+ function html($api) {
+ return [$api.h('ul', { key: 0 }, [])];
+ }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ expect(() => {
+ (elm[ViewModelReflection].component as Component).template.querySelectorAll('doesnotexist');
+ }).not.toThrow();
+ });
+ });
+
+ it('should allow walking back to the shadow root', () => {
+ function html($api) {
+ return [$api.h('div', { key: 0 }, [])];
+ }
+ class MyComponent extends Element {
+ render() {
+ return html;
+ }
+ }
+
+ const elm = createElement('x-foo', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ const root = (elm[ViewModelReflection].component as Component).template;
+ expect(root.querySelector('div').parentNode).toBe(root);
+ });
+ });
+
+ it('should not expose shadow root on child custom element', () => {
+ expect.assertions(1);
+ let childTemplate;
+ class MyChild extends Element {
+ constructor() {
+ super();
+ childTemplate = this.template;
+ }
+
+ clickDiv() {
+ this.template.querySelector('div').click();
+ }
+
+ render() {
+ return function ($api) {
+ return [$api.h('div', {
+ key: 0,
+ }, [])];
+ }
+ }
+ }
+
+ MyChild.publicMethods = ['clickDiv'];
+
+ function html($api, $cmp) {
+ return [$api.c('x-child-parent-shadow-root', MyChild, {
+ on: {
+ click: $api.b($cmp.handleClick)
+ }
+ })];
+ }
+
+ class MyComponent extends Element {
+ handleClick(evt) {
+ expect(evt.target.parentNode).not.toBe(childTemplate);
+ }
+
+ clickChildDiv() {
+ this.template.querySelector('x-child-parent-shadow-root').clickDiv();
+ }
+
+ render() {
+ return html;
+ }
+ }
+
+ MyComponent.publicMethods = ['clickChildDiv'];
+
+ const elm = createElement('membrane-child-parent-shadow-root-parent', { is: MyComponent });
+ document.body.appendChild(elm);
+ return Promise.resolve().then(() => {
+ elm.clickChildDiv();
+ });
+ });
+
+ });
+
});
diff --git a/packages/lwc-engine/src/framework/modules/__tests__/styles.spec.ts b/packages/lwc-engine/src/framework/modules/__tests__/styles.spec.ts
index 2afd618ca8..92e6f13ff9 100644
--- a/packages/lwc-engine/src/framework/modules/__tests__/styles.spec.ts
+++ b/packages/lwc-engine/src/framework/modules/__tests__/styles.spec.ts
@@ -21,7 +21,7 @@ describe('modules/styles', () => {
const elm = createElement('x-cmp', { is: Component });
document.body.appendChild(elm);
- expect(cmp.root.querySelector('div').style.display).toBe('inline');
+ expect(cmp.template.querySelector('div').style.display).toBe('inline');
});
it('should add style map to the element', () => {
const tmpl = $api => [
@@ -41,7 +41,7 @@ describe('modules/styles', () => {
const elm = createElement('x-cmp', { is: Component });
document.body.appendChild(elm);
- expect(cmp.root.querySelector('div').style.display).toBe('inline');
+ expect(cmp.template.querySelector('div').style.display).toBe('inline');
});
it('should patch style to the element', () => {
const tmpl = ($api, $cmp) => [
@@ -63,10 +63,10 @@ describe('modules/styles', () => {
};
const elm = createElement('x-cmp', { is: MyComponent });
document.body.appendChild(elm);
- expect(cmp.root.querySelector('div').style.display).toBe('inline');
+ expect(cmp.template.querySelector('div').style.display).toBe('inline');
cmp.counter++;
return Promise.resolve().then(() => {
- expect(cmp.root.querySelector('div').style.display).toBe('block');
+ expect(cmp.template.querySelector('div').style.display).toBe('block');
});
});
it('should patch style map to the element', () => {
@@ -89,11 +89,11 @@ describe('modules/styles', () => {
};
const elm = createElement('x-cmp', { is: MyComponent });
document.body.appendChild(elm);
- expect(cmp.root.querySelector('div').style.display).toBe('inline');
+ expect(cmp.template.querySelector('div').style.display).toBe('inline');
cmp.counter++;
return Promise.resolve().then(() => {
- expect(cmp.root.querySelector('div').style.position).toBe('relative');
- expect(cmp.root.querySelector('div').style.display).toBe('');
+ expect(cmp.template.querySelector('div').style.position).toBe('relative');
+ expect(cmp.template.querySelector('div').style.display).toBe('');
});
});
});
From b222796a77d62d90a11389316bd875378d77960c Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Fri, 18 May 2018 17:43:39 -0700
Subject: [PATCH 15/24] wip: fix more tests
---
.../src/framework/__tests__/component.spec.ts | 6 +++---
.../framework/__tests__/error-boundary.spec.ts | 8 ++++----
.../src/framework/__tests__/template.spec.ts | 12 ++++++------
.../framework/modules/__tests__/events.spec.ts | 16 ++++++++--------
4 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/packages/lwc-engine/src/framework/__tests__/component.spec.ts b/packages/lwc-engine/src/framework/__tests__/component.spec.ts
index 06a1818dd9..947c7bb859 100644
--- a/packages/lwc-engine/src/framework/__tests__/component.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/component.spec.ts
@@ -51,7 +51,7 @@ describe('component', function() {
const elm = createElement('x-foo', { is: Parent });
document.body.appendChild(elm);
expect(elm.lunch).toBe('salad');
- expect(elm[ViewModelReflection].component.root.querySelector('x-component').breakfast).toBe('pancakes');
+ expect(elm[ViewModelReflection].component.template.querySelector('x-component').breakfast).toBe('pancakes');
});
it('should allow calling public getters when element is accessed by querySelector', function() {
@@ -358,7 +358,7 @@ describe('component', function() {
}
});
document.body.appendChild(elm);
- expect(elm[ViewModelReflection].component.root.querySelector('section').style.cssText).toBe('color: red;');
+ expect(elm[ViewModelReflection].component.template.querySelector('section').style.cssText).toBe('color: red;');
expect(calledCSSText).toBe(true);
});
@@ -455,7 +455,7 @@ describe('component', function() {
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- const section = elm[ViewModelReflection].component.root.querySelector('section');
+ const section = elm[ViewModelReflection].component.template.querySelector('section');
section.style.removeProperty = function() {
called = true;
};
diff --git a/packages/lwc-engine/src/framework/__tests__/error-boundary.spec.ts b/packages/lwc-engine/src/framework/__tests__/error-boundary.spec.ts
index d0d05267c4..e5dd81a3bf 100644
--- a/packages/lwc-engine/src/framework/__tests__/error-boundary.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/error-boundary.spec.ts
@@ -76,7 +76,7 @@ describe('error boundary component', () => {
return html;
}
}
- const boundaryHostElm = createElement('x-boundary', {is: BoundryHost});
+ const boundaryHostElm = createElement('x-parent', {is: BoundryHost});
document.body.appendChild(boundaryHostElm);
expect(querySelectorAll.call(boundaryHostElm, 'x-boundary-sibling').length).toBe(1);
@@ -198,7 +198,7 @@ describe('error boundary component', () => {
return html;
}
}
- const boundaryHostElm = createElement('x-boundary', {is: BoundryHost});
+ const boundaryHostElm = createElement('x-parent', {is: BoundryHost});
document.body.appendChild(boundaryHostElm);
expect(querySelectorAll.call(boundaryHostElm, 'x-boundary-sibling').length).toBe(1);
@@ -434,7 +434,7 @@ describe('error boundary component', () => {
return html;
}
}
- const boundaryHostElm = createElement('x-boundary', {is: BoundryHost});
+ const boundaryHostElm = createElement('x-parent', {is: BoundryHost});
document.body.appendChild(boundaryHostElm);
expect(querySelectorAll.call(boundaryHostElm, 'x-boundary-sibling').length).toBe(1);
@@ -530,7 +530,7 @@ describe('error boundary component', () => {
return html;
}
}
- const boundaryHostElm = createElement('x-boundary', {is: BoundryHost});
+ const boundaryHostElm = createElement('x-parent', {is: BoundryHost});
document.body.appendChild(boundaryHostElm);
expect(querySelectorAll.call(boundaryHostElm, 'x-boundary-sibling').length).toBe(1);
diff --git a/packages/lwc-engine/src/framework/__tests__/template.spec.ts b/packages/lwc-engine/src/framework/__tests__/template.spec.ts
index 1db7e81eb3..5cda1ae02d 100644
--- a/packages/lwc-engine/src/framework/__tests__/template.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/template.spec.ts
@@ -58,9 +58,9 @@ describe('template', () => {
]);
});
});
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div').length).toBe(2);
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div')[0].textContent).toBe('a');
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div')[1].textContent).toBe('b');
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div').length).toBe(2);
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div')[0].textContent).toBe('a');
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div')[1].textContent).toBe('b');
});
it('should render sets correctly', function() {
@@ -74,9 +74,9 @@ describe('template', () => {
]);
});
});
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div').length).toBe(2);
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div')[0].textContent).toBe('a');
- expect(elm[ViewModelReflection].component.root.querySelectorAll('div')[1].textContent).toBe('b');
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div').length).toBe(2);
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div')[0].textContent).toBe('a');
+ expect(elm[ViewModelReflection].component.template.querySelectorAll('div')[1].textContent).toBe('b');
});
// this test depends on the memoization
diff --git a/packages/lwc-engine/src/framework/modules/__tests__/events.spec.ts b/packages/lwc-engine/src/framework/modules/__tests__/events.spec.ts
index f385fb5705..ca363565ea 100644
--- a/packages/lwc-engine/src/framework/modules/__tests__/events.spec.ts
+++ b/packages/lwc-engine/src/framework/modules/__tests__/events.spec.ts
@@ -26,7 +26,7 @@ describe('module/events', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toHaveLength(1);
});
@@ -65,10 +65,10 @@ describe('module/events', () => {
MyComponent.track = { counter: 1 };
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- component.root.querySelector('div').click();
+ component.template.querySelector('div').click();
component.counter += 1;
return Promise.resolve().then( () => {
- component.root.querySelector('div').click();
+ component.template.querySelector('div').click();
expect(second).toBe(true);
expect(result).toEqual([1, 2]);
});
@@ -108,11 +108,11 @@ describe('module/events', () => {
MyComponent.track = { counter: 1 };
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- component.root.querySelector('p').click();
+ component.template.querySelector('p').click();
component.counter += 1;
return Promise.resolve().then( () => {
expect(second).toBe(true);
- component.root.querySelector('div').click();
+ component.template.querySelector('div').click();
expect(result).toEqual([1, 1]);
});
});
@@ -141,7 +141,7 @@ describe('module/events', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- cmp.root.querySelector('div').click();
+ cmp.template.querySelector('div').click();
expect(result).toHaveLength(2);
expect(result[0]).toBe(cmp);
expect(result[1]).toBeInstanceOf(Event);
@@ -166,7 +166,7 @@ describe('module/events', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- cmp.root.querySelector('x-child').click();
+ cmp.template.querySelector('x-child').click();
expect(result).toHaveLength(1);
});
@@ -189,7 +189,7 @@ describe('module/events', () => {
}
const elm = createElement('x-foo', { is: MyComponent });
document.body.appendChild(elm);
- cmp.root.querySelector('x-child').dispatchEvent(new CustomEvent('test', {}));
+ cmp.template.querySelector('x-child').dispatchEvent(new CustomEvent('test', {}));
expect(result).toHaveLength(1);
});
From 385e839f950ed91541fd8485cc619d30453d4e72 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Sun, 20 May 2018 09:04:49 -0700
Subject: [PATCH 16/24] test: refactor test config to be at the monorepo root
---
package.json | 2 +-
.../babel-plugin-transform-lwc-class/jest.config.js | 7 ++++---
packages/lwc-compiler/jest.config.js | 12 ++++--------
packages/lwc-engine/jest.config.js | 12 +++++-------
packages/lwc-module-resolver/jest.config.js | 7 ++++---
packages/lwc-template-compiler/jest.config.js | 11 ++++-------
packages/lwc-wire-service/jest.config.js | 11 ++++-------
packages/observable-membrane/jest.config.js | 11 ++++-------
packages/postcss-plugin-lwc/jest.config.js | 11 ++++-------
packages/rollup-plugin-lwc-compiler/jest.config.js | 7 ++++---
scripts/jest/base.config.js | 10 ++++++++++
jest.config.js => scripts/jest/root.config.js | 3 +++
12 files changed, 51 insertions(+), 53 deletions(-)
create mode 100644 scripts/jest/base.config.js
rename jest.config.js => scripts/jest/root.config.js (90%)
diff --git a/package.json b/package.json
index 4b58c6ab04..a66c95473e 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"clean": "lerna run clean && lerna clean --yes && rm -rf node_modules",
"lint": "tslint -p tsconfig.json && npm run types",
"types": "tsc --noEmit",
- "test": "jest",
+ "test": "jest --config ./scripts/jest/root.config.js",
"test:integration": "yarn run build && lerna exec --scope lwc-integration -- yarn sauce",
"test:performance": "lerna exec --scope benchmark -- best --runner remote",
"build": "lerna run build --ignore benchmark --ignore lwc-integration",
diff --git a/packages/babel-plugin-transform-lwc-class/jest.config.js b/packages/babel-plugin-transform-lwc-class/jest.config.js
index ef2879887a..45171e32f3 100644
--- a/packages/babel-plugin-transform-lwc-class/jest.config.js
+++ b/packages/babel-plugin-transform-lwc-class/jest.config.js
@@ -1,5 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- testMatch: [
- '/**/__tests__/**/*.spec.js'
- ],
+ ...BASE_CONFIG,
+ displayName: 'babel-plugin-transform-lwc-class',
};
diff --git a/packages/lwc-compiler/jest.config.js b/packages/lwc-compiler/jest.config.js
index 0f694e417f..42052a2c38 100644
--- a/packages/lwc-compiler/jest.config.js
+++ b/packages/lwc-compiler/jest.config.js
@@ -1,10 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.js': require.resolve('ts-jest/preprocessor.js'),
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.js'
- ],
+ ...BASE_CONFIG,
+ displayName: 'lwc-compiler',
};
diff --git a/packages/lwc-engine/jest.config.js b/packages/lwc-engine/jest.config.js
index c2e16e9c0b..03988822be 100644
--- a/packages/lwc-engine/jest.config.js
+++ b/packages/lwc-engine/jest.config.js
@@ -1,10 +1,8 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+
+ displayName: 'lwc-engine',
setupTestFrameworkScriptFile: '/scripts/jest/setup.ts',
};
diff --git a/packages/lwc-module-resolver/jest.config.js b/packages/lwc-module-resolver/jest.config.js
index ef2879887a..a40cdc9a5c 100644
--- a/packages/lwc-module-resolver/jest.config.js
+++ b/packages/lwc-module-resolver/jest.config.js
@@ -1,5 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- testMatch: [
- '/**/__tests__/**/*.spec.js'
- ],
+ ...BASE_CONFIG,
+ displayName: 'lwc-module-resolver',
};
diff --git a/packages/lwc-template-compiler/jest.config.js b/packages/lwc-template-compiler/jest.config.js
index f6a181e3c2..7562666402 100644
--- a/packages/lwc-template-compiler/jest.config.js
+++ b/packages/lwc-template-compiler/jest.config.js
@@ -1,9 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+ displayName: 'lwc-template-compiler',
};
diff --git a/packages/lwc-wire-service/jest.config.js b/packages/lwc-wire-service/jest.config.js
index f6a181e3c2..79c7ac2a82 100644
--- a/packages/lwc-wire-service/jest.config.js
+++ b/packages/lwc-wire-service/jest.config.js
@@ -1,9 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+ displayName: 'lwc-wire-service',
};
diff --git a/packages/observable-membrane/jest.config.js b/packages/observable-membrane/jest.config.js
index f6a181e3c2..0008c0a5e7 100644
--- a/packages/observable-membrane/jest.config.js
+++ b/packages/observable-membrane/jest.config.js
@@ -1,9 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+ displayName: 'observable-membrane',
};
diff --git a/packages/postcss-plugin-lwc/jest.config.js b/packages/postcss-plugin-lwc/jest.config.js
index f6a181e3c2..0badadb726 100644
--- a/packages/postcss-plugin-lwc/jest.config.js
+++ b/packages/postcss-plugin-lwc/jest.config.js
@@ -1,9 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- moduleFileExtensions: ['ts', 'js', 'json'],
- transform: {
- '.ts': require.resolve('ts-jest/preprocessor.js'),
- },
- testMatch: [
- '/**/__tests__/**/*.spec.ts'
- ],
+ ...BASE_CONFIG,
+ displayName: 'postcss-plugin-lwc',
};
diff --git a/packages/rollup-plugin-lwc-compiler/jest.config.js b/packages/rollup-plugin-lwc-compiler/jest.config.js
index ef2879887a..10528cf76b 100644
--- a/packages/rollup-plugin-lwc-compiler/jest.config.js
+++ b/packages/rollup-plugin-lwc-compiler/jest.config.js
@@ -1,5 +1,6 @@
+const BASE_CONFIG = require('../../scripts/jest/base.config');
+
module.exports = {
- testMatch: [
- '/**/__tests__/**/*.spec.js'
- ],
+ ...BASE_CONFIG,
+ displayName: 'rollup-plugin-lwc-compiler',
};
diff --git a/scripts/jest/base.config.js b/scripts/jest/base.config.js
new file mode 100644
index 0000000000..b6195027a2
--- /dev/null
+++ b/scripts/jest/base.config.js
@@ -0,0 +1,10 @@
+module.exports = {
+ moduleFileExtensions: ['ts', 'js', 'json'],
+ transform: {
+ '.ts': require.resolve('ts-jest/preprocessor.js'),
+ '.js': require.resolve('ts-jest/preprocessor.js')
+ },
+ testMatch: [
+ '/*/**/__tests__/*.spec.(js|ts)'
+ ],
+};
diff --git a/jest.config.js b/scripts/jest/root.config.js
similarity index 90%
rename from jest.config.js
rename to scripts/jest/root.config.js
index e7ab5b7976..b0ef5ac17c 100644
--- a/jest.config.js
+++ b/scripts/jest/root.config.js
@@ -1,4 +1,7 @@
+const path = require('path');
+
module.exports = {
+ rootDir: '../..',
projects: [
'/packages/babel-plugin-transform-lwc-class',
'/packages/lwc-compiler',
From 32c340e31eee7b790466ab47e8ed4e59bd8c206f Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Mon, 21 May 2018 08:38:59 -0700
Subject: [PATCH 17/24] style: make jest.config.consistent
---
packages/lwc-engine/jest.config.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/lwc-engine/jest.config.js b/packages/lwc-engine/jest.config.js
index 03988822be..93550116e2 100644
--- a/packages/lwc-engine/jest.config.js
+++ b/packages/lwc-engine/jest.config.js
@@ -2,7 +2,6 @@ const BASE_CONFIG = require('../../scripts/jest/base.config');
module.exports = {
...BASE_CONFIG,
-
displayName: 'lwc-engine',
setupTestFrameworkScriptFile: '/scripts/jest/setup.ts',
};
From bfe25cf89050df3f1564857d33015422af6b2a5d Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Mon, 21 May 2018 10:34:31 -0700
Subject: [PATCH 18/24] fix: remove unused import
---
scripts/jest/root.config.js | 2 --
1 file changed, 2 deletions(-)
diff --git a/scripts/jest/root.config.js b/scripts/jest/root.config.js
index b0ef5ac17c..1f40b544a0 100644
--- a/scripts/jest/root.config.js
+++ b/scripts/jest/root.config.js
@@ -1,5 +1,3 @@
-const path = require('path');
-
module.exports = {
rootDir: '../..',
projects: [
From 064ca91b24e40ac290c22f9a654bebc7fd149c9a Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Tue, 29 May 2018 09:36:06 -0700
Subject: [PATCH 19/24] fix: remove unused deps in engine unit tests
---
packages/lwc-engine/src/framework/__tests__/html-element.spec.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts b/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts
index 557630dd7e..f35f6824b6 100644
--- a/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/html-element.spec.ts
@@ -7,7 +7,6 @@ import { VNode } from "../../3rdparty/snabbdom/types";
import { Component } from "../component";
import { unwrap } from "../main";
import { querySelector } from "../dom";
-import { callbackify } from "util";
describe('html-element', () => {
describe('#setAttributeNS()', () => {
From ba09e2aa055327be488efd37d6455bedd0bbc329 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Wed, 30 May 2018 07:07:36 -0700
Subject: [PATCH 20/24] wip: remove internal engine registry
---
packages/lwc-engine/jest.config.js | 1 -
packages/lwc-engine/scripts/jest/setup.ts | 7 ----
.../src/framework/__tests__/api.spec.ts | 18 +++++++----
packages/lwc-engine/src/framework/api.ts | 7 ++--
packages/lwc-engine/src/framework/def.ts | 32 ++-----------------
packages/lwc-engine/src/framework/upgrade.ts | 14 ++++----
packages/lwc-engine/src/framework/vm.ts | 3 +-
7 files changed, 26 insertions(+), 56 deletions(-)
delete mode 100644 packages/lwc-engine/scripts/jest/setup.ts
diff --git a/packages/lwc-engine/jest.config.js b/packages/lwc-engine/jest.config.js
index 93550116e2..9ec582e029 100644
--- a/packages/lwc-engine/jest.config.js
+++ b/packages/lwc-engine/jest.config.js
@@ -3,5 +3,4 @@ const BASE_CONFIG = require('../../scripts/jest/base.config');
module.exports = {
...BASE_CONFIG,
displayName: 'lwc-engine',
- setupTestFrameworkScriptFile: '/scripts/jest/setup.ts',
};
diff --git a/packages/lwc-engine/scripts/jest/setup.ts b/packages/lwc-engine/scripts/jest/setup.ts
deleted file mode 100644
index d30838ebe7..0000000000
--- a/packages/lwc-engine/scripts/jest/setup.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { flushComponentRegistry } from '../../src/framework/def';
-
-// Clean-up after each test the engine component registry. This avoid having the
-// engine warning that multiple component class are registered with the same name.
-afterEach(() => {
- flushComponentRegistry();
-});
diff --git a/packages/lwc-engine/src/framework/__tests__/api.spec.ts b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
index de588f65bb..2364e2d257 100644
--- a/packages/lwc-engine/src/framework/__tests__/api.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/api.spec.ts
@@ -106,22 +106,28 @@ describe('api', () => {
expect(span.getAttribute('is')).toEqual('x-bar');
});
- it('should throw when forceTagName cannot have a shadow root attached to it', () => {
+ it('should throw if the forceTagName value is a reserved standard element name', () => {
class Bar extends Element {
- static forceTagName = 'div'; // it can't be a div
+ static forceTagName = 'div';
}
+
expect(() => {
createElement('x-foo', { is: Bar });
- }).toThrow();
+ }).toThrow(
+ /Invalid static forceTagName property set to "div"/
+ );
});
- it('should throw when forceTagName cannot have a shadow root attached to it', () => {
+ it('should throw if the forceTagName is a custom element name', () => {
class Bar extends Element {
- static forceTagName = 'x-bar'; // it can't be a custom element name
+ static forceTagName = 'x-bar';
}
+
expect(() => {
createElement('x-foo', { is: Bar });
- }).toThrow();
+ }).toThrow(
+ /Invalid static forceTagName property set to "x-bar"/
+ );
});
});
diff --git a/packages/lwc-engine/src/framework/api.ts b/packages/lwc-engine/src/framework/api.ts
index fa363fc69c..b7bbc333c7 100644
--- a/packages/lwc-engine/src/framework/api.ts
+++ b/packages/lwc-engine/src/framework/api.ts
@@ -3,7 +3,6 @@ import { freeze, isArray, isUndefined, isNull, isFunction, isObject, isString, A
import { vmBeingRendered, invokeEventListener, EventListenerContext } from "./invoker";
import { EmptyArray, SPACE_CHAR } from "./utils";
import { renderVM, createVM, appendVM, removeVM, VM, getCustomElementVM } from "./vm";
-import { registerComponent } from "./def";
import { ComponentConstructor, markComponentAsDirty } from "./component";
import { VNode, VNodeData, VNodes, VElement, VComment, VText, Hooks } from "../3rdparty/snabbdom/types";
import { patchShadowDomEvent, isValidEventForCustomElement } from "./events";
@@ -85,7 +84,8 @@ const hook: Hooks = {
renderVM(vm);
},
create(oldVNode: VNode, vnode: VNode) {
- createVM(vnode.sel as string, vnode.elm as HTMLElement, vnode.data.slotset);
+ const { slotset, ctor } = vnode.data;
+ createVM(vnode.sel as string, vnode.elm as HTMLElement, ctor, slotset);
},
destroy(vnode: VNode) {
removeVM(getCustomElementVM(vnode.elm as HTMLElement));
@@ -210,9 +210,8 @@ export function c(sel: string, Ctor: ComponentConstructor, data: VNodeData): VEl
attrs = assign({}, attrs);
attrs.is = sel;
}
- registerComponent(sel, Ctor);
- data = { hook, key, slotset, attrs, on, props };
+ data = { hook, key, slotset, attrs, on, props, ctor: Ctor };
data.class = classMap || getMapFromClassName(normalizeStyleString(className));
data.style = styleMap || normalizeStyleString(style);
data.token = getCurrentTplToken();
diff --git a/packages/lwc-engine/src/framework/def.ts b/packages/lwc-engine/src/framework/def.ts
index 6e7145435c..28b69d20bf 100644
--- a/packages/lwc-engine/src/framework/def.ts
+++ b/packages/lwc-engine/src/framework/def.ts
@@ -136,10 +136,13 @@ function isElementComponent(Ctor: any, protoSet?: any[]): boolean {
function createComponentDef(Ctor: ComponentConstructor): ComponentDef {
if (process.env.NODE_ENV !== 'production') {
assert.isTrue(isElementComponent(Ctor), `${Ctor} is not a valid component, or does not extends Element from "engine". You probably forgot to add the extend clause on the class declaration.`);
+
// local to dev block
const ctorName = Ctor.name;
assert.isTrue(ctorName && isString(ctorName), `${toString(Ctor)} should have a "name" property with string value, but found ${ctorName}.`);
assert.isTrue(Ctor.constructor, `Missing ${ctorName}.constructor, ${ctorName} should have a "constructor" property.`);
+
+ assertValidForceTagName(Ctor);
}
const name: string = Ctor.name;
@@ -503,32 +506,3 @@ export function getComponentDef(Ctor: ComponentConstructor): ComponentDef {
CtorToDefMap.set(Ctor, def);
return def;
}
-
-let TagNameToCtor: HashTable = create(null);
-
-export function getCtorByTagName(tagName: string): ComponentConstructor | undefined {
- return TagNameToCtor[tagName];
- /////// TODO: what is this?
-}
-
-export function registerComponent(tagName: string, Ctor: ComponentConstructor) {
- if (process.env.NODE_ENV !== 'production') {
- assertValidForceTagName(Ctor);
- }
- if (!isUndefined(TagNameToCtor[tagName])) {
- if (TagNameToCtor[tagName] === Ctor) {
- return;
- } else if (process.env.NODE_ENV !== 'production') {
- // TODO: eventually we should throw, this is only needed for the tests today
- assert.logWarning(`Different component class cannot be registered to the same tagName="${tagName}".`);
- }
- }
- TagNameToCtor[tagName] = Ctor;
-}
-
-// This method is internal to the engine and should only be used for testing purposes!
-// The component registry need to get flushed between each test to avoid having the
-// engine warning about multiple class registration with the same tag name.
-export function flushComponentRegistry() {
- TagNameToCtor = create(null);
-}
diff --git a/packages/lwc-engine/src/framework/upgrade.ts b/packages/lwc-engine/src/framework/upgrade.ts
index 454878ae59..1025bd71df 100644
--- a/packages/lwc-engine/src/framework/upgrade.ts
+++ b/packages/lwc-engine/src/framework/upgrade.ts
@@ -1,7 +1,7 @@
import assert from "./assert";
import { isUndefined, isFunction, assign, hasOwnProperty, defineProperties } from "./language";
import { createVM, removeVM, appendVM, renderVM, getCustomElementVM } from "./vm";
-import { registerComponent, getCtorByTagName, prepareForAttributeMutationFromTemplate, ViewModelReflection } from "./def";
+import { prepareForAttributeMutationFromTemplate, ViewModelReflection } from "./def";
import { ComponentConstructor } from "./component";
import { EmptyNodeList } from "./dom";
@@ -61,15 +61,15 @@ function querySelectorAllPatchedRoot() {
* If the value of `is` attribute is not a constructor,
* then it throws a TypeError.
*/
-export function createElement(sel: string, options: any = {}): HTMLElement {
+export function createElement(sel: string, options: { is: ComponentConstructor }): HTMLElement {
if (isUndefined(options) || !isFunction(options.is)) {
throw new TypeError();
}
- registerComponent(sel, options.is);
- // extracting the registered constructor just in case we need to force the tagName
- const Ctor = getCtorByTagName(sel);
- const { forceTagName } = Ctor as ComponentConstructor;
+
+ const Ctor = options.is;
+ const { forceTagName } = Ctor;
const tagName = isUndefined(forceTagName) ? sel : forceTagName;
+
// Create element with correct tagName
const element = document.createElement(tagName);
if (hasOwnProperty.call(element, ViewModelReflection)) {
@@ -77,7 +77,7 @@ export function createElement(sel: string, options: any = {}): HTMLElement {
}
// In case the element is not initialized already, we need to carry on the manual creation
- createVM(sel, element);
+ createVM(sel, element, Ctor);
// We don't support slots on root nodes
defineProperties(element, {
diff --git a/packages/lwc-engine/src/framework/vm.ts b/packages/lwc-engine/src/framework/vm.ts
index 9c45975571..da215cc879 100644
--- a/packages/lwc-engine/src/framework/vm.ts
+++ b/packages/lwc-engine/src/framework/vm.ts
@@ -162,14 +162,13 @@ export function removeVM(vm: VM) {
patchShadowRoot(vm, []);
}
-export function createVM(tagName: string, elm: HTMLElement, cmpSlots?: Slotset) {
+export function createVM(tagName: string, elm: HTMLElement, Ctor: ComponentConstructor, cmpSlots?: Slotset) {
if (process.env.NODE_ENV !== 'production') {
assert.invariant(elm instanceof HTMLElement, `VM creation requires a DOM element instead of ${elm}.`);
}
if (hasOwnProperty.call(elm, ViewModelReflection)) {
return; // already created
}
- const Ctor = getCtorByTagName(tagName) as ComponentConstructor;
const def = getComponentDef(Ctor);
const isRoot = arguments.length === 2; // root elements can't provide slotset
uid += 1;
From d0d32427067e88c08adf00a70355798b7b0f4610 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Wed, 30 May 2018 07:39:01 -0700
Subject: [PATCH 21/24] style: fix engine linting
---
packages/lwc-engine/src/framework/def.ts | 3 ---
packages/lwc-engine/src/framework/vm.ts | 2 +-
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/packages/lwc-engine/src/framework/def.ts b/packages/lwc-engine/src/framework/def.ts
index 28b69d20bf..f94e4f6bf7 100644
--- a/packages/lwc-engine/src/framework/def.ts
+++ b/packages/lwc-engine/src/framework/def.ts
@@ -50,9 +50,6 @@ import { lightDomQuerySelector, lightDomQuerySelectorAll } from "./traverse";
// TODO: refactor all the references to this
export { ViewModelReflection } from "./utils";
-declare interface HashTable {
- [key: string]: T;
-}
export interface PropDef {
config: number;
type: string; // TODO: make this an enum
diff --git a/packages/lwc-engine/src/framework/vm.ts b/packages/lwc-engine/src/framework/vm.ts
index da215cc879..3c469ee99b 100644
--- a/packages/lwc-engine/src/framework/vm.ts
+++ b/packages/lwc-engine/src/framework/vm.ts
@@ -4,7 +4,7 @@ import { createComponent, linkComponent, renderComponent, clearReactiveListeners
import { patchChildren } from "./patch";
import { ArrayPush, isUndefined, isNull, ArrayUnshift, ArraySlice, create, hasOwnProperty } from "./language";
import { addCallbackToNextTick, EmptyObject, EmptyArray, usesNativeSymbols } from "./utils";
-import { ViewModelReflection, getCtorByTagName } from "./def";
+import { ViewModelReflection } from "./def";
import { invokeServiceHook, Services } from "./services";
import { invokeComponentCallback } from "./invoker";
import { parentNodeGetter, parentElementGetter } from "./dom";
From 56d1a1b411ea258b498693af9c3b8840973ba19d Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Thu, 31 May 2018 08:44:56 -0700
Subject: [PATCH 22/24] fix: make sure to resolve circular deps in
createElement
---
.../src/framework/__tests__/upgrade.spec.ts | 9 +++++++++
packages/lwc-engine/src/framework/api.ts | 9 ++-------
packages/lwc-engine/src/framework/def.ts | 19 ++++++++++---------
packages/lwc-engine/src/framework/upgrade.ts | 6 ++++--
packages/lwc-engine/src/framework/utils.ts | 15 +++++++++++++++
5 files changed, 40 insertions(+), 18 deletions(-)
diff --git a/packages/lwc-engine/src/framework/__tests__/upgrade.spec.ts b/packages/lwc-engine/src/framework/__tests__/upgrade.spec.ts
index 114b11df9f..b641c1dda6 100644
--- a/packages/lwc-engine/src/framework/__tests__/upgrade.spec.ts
+++ b/packages/lwc-engine/src/framework/__tests__/upgrade.spec.ts
@@ -4,6 +4,15 @@ import { ComponentConstructor } from "../component";
describe('upgrade', () => {
describe('#createElement()', () => {
+ it('should support constructors with circular dependencies', () => {
+ const factory = () => class extends Element { };
+ factory.__circular__ = true;
+
+ expect(
+ () => createElement('x-foo', { is: factory })
+ ).not.toThrow();
+ });
+
it('should allow access to profixied default values for public props', () => {
const x = [1, 2, 3], y = { foo: 1 };
type MyComponentElement = HTMLElement & {
diff --git a/packages/lwc-engine/src/framework/api.ts b/packages/lwc-engine/src/framework/api.ts
index 9d6c005e98..d88a4ada63 100644
--- a/packages/lwc-engine/src/framework/api.ts
+++ b/packages/lwc-engine/src/framework/api.ts
@@ -1,7 +1,7 @@
import assert from "./assert";
import { vmBeingRendered, invokeEventListener, EventListenerContext } from "./invoker";
import { freeze, isArray, isUndefined, isNull, isFunction, isObject, isString, ArrayPush, assign, create, forEach, StringSlice, StringCharCodeAt, isNumber, hasOwnProperty, isTrue } from "./language";
-import { EmptyArray, SPACE_CHAR, ViewModelReflection } from "./utils";
+import { EmptyArray, SPACE_CHAR, ViewModelReflection, resolveCircularModuleDependency } from "./utils";
import { renderVM, createVM, appendVM, removeVM, VM, getCustomElementVM, Slotset, allocateInSlot } from "./vm";
import { ComponentConstructor } from "./component";
import { VNode, VNodeData, VNodes, VElement, VComment, VText, Hooks } from "../3rdparty/snabbdom/types";
@@ -214,12 +214,7 @@ export function s(slotName: string, data: VNodeData, children: VNodes, slotset:
// [c]ustom element node
export function c(sel: string, Ctor: ComponentConstructor, data: VNodeData, children?: VNodes): VElement {
- // The compiler produce AMD modules that do not support circular dependencies
- // We need to create an indirection to circumvent those cases.
- // We could potentially move this check to the definition
- if (hasOwnProperty.call(Ctor, '__circular__')) {
- Ctor = Ctor();
- }
+ Ctor = resolveCircularModuleDependency(Ctor);
if (process.env.NODE_ENV !== 'production') {
assert.isTrue(isString(sel), `c() 1st argument sel must be a string.`);
diff --git a/packages/lwc-engine/src/framework/def.ts b/packages/lwc-engine/src/framework/def.ts
index ab4cb4842e..c33da2aa3c 100644
--- a/packages/lwc-engine/src/framework/def.ts
+++ b/packages/lwc-engine/src/framework/def.ts
@@ -45,7 +45,14 @@ import wireDecorator from "./decorators/wire";
import trackDecorator from "./decorators/track";
import apiDecorator from "./decorators/api";
import { Element as BaseElement } from "./html-element";
-import { EmptyObject, getPropNameFromAttrName, assertValidForceTagName, ViewModelReflection, getAttrNameFromPropName } from "./utils";
+import {
+ EmptyObject,
+ getPropNameFromAttrName,
+ assertValidForceTagName,
+ ViewModelReflection,
+ getAttrNameFromPropName,
+ resolveCircularModuleDependency
+} from "./utils";
import { OwnerKey, VM, VMElement, getCustomElementVM } from "./vm";
export interface PropDef {
@@ -103,14 +110,8 @@ const reducedDefaultHTMLPropertyNames: PropsDef = ArrayReduce.call(defaultDefHTM
const HTML_PROPS: PropsDef = ArrayReduce.call(getOwnPropertyNames(GlobalAOMProperties), propertiesReducer, reducedDefaultHTMLPropertyNames);
function getCtorProto(Ctor: any): any {
- let proto = getPrototypeOf(Ctor);
- // The compiler produce AMD modules that do not support circular dependencies
- // We need to create an indirection to circumvent those cases.
- // We could potentially move this check to the definition
- if (hasOwnProperty.call(proto, '__circular__')) {
- proto = proto();
- }
- return proto;
+ const proto = getPrototypeOf(Ctor);
+ return resolveCircularModuleDependency(proto);
}
function isElementComponent(Ctor: any, protoSet?: any[]): boolean {
diff --git a/packages/lwc-engine/src/framework/upgrade.ts b/packages/lwc-engine/src/framework/upgrade.ts
index bfaa1a52d5..9bd4819c01 100644
--- a/packages/lwc-engine/src/framework/upgrade.ts
+++ b/packages/lwc-engine/src/framework/upgrade.ts
@@ -3,7 +3,7 @@ import { isUndefined, assign, hasOwnProperty, defineProperties, isNull, isObject
import { createVM, removeVM, appendVM, renderVM, getCustomElementVM } from "./vm";
import { ComponentConstructor } from "./component";
import { EmptyNodeList } from "./dom/node";
-import { ViewModelReflection } from "./utils";
+import { ViewModelReflection, resolveCircularModuleDependency } from "./utils";
import { setAttribute } from "./dom/element";
import { shadowRootQuerySelector, shadowRootQuerySelectorAll } from "./dom/traverse";
@@ -91,7 +91,9 @@ export function createElement(sel: string, options: any = {}): HTMLElement {
throw new TypeError();
}
- const { is: Ctor } = (options as any);
+ let { is: Ctor } = (options as any);
+ Ctor = resolveCircularModuleDependency(Ctor);
+
let { mode, fallback } = (options as any);
// TODO: for now, we default to open, but eventually it should default to 'closed'
if (mode !== 'closed') { mode = 'open'; }
diff --git a/packages/lwc-engine/src/framework/utils.ts b/packages/lwc-engine/src/framework/utils.ts
index b78067f3db..fc36a352dc 100644
--- a/packages/lwc-engine/src/framework/utils.ts
+++ b/packages/lwc-engine/src/framework/utils.ts
@@ -86,4 +86,19 @@ export function assertValidForceTagName(Ctor: ComponentConstructor) {
}
}
+/**
+ * When LWC is used in the context of an Aura application, the compiler produces AMD
+ * modules, that doesn't resolve properly circular dependencies between modules. In order
+ * to circumvent this issue, the module loader returns a factory with a symbol attached
+ * to it.
+ *
+ * This method returns the resolved value if it received a factory as argument. Otherwise
+ * it returns the original value.
+ */
+export function resolveCircularModuleDependency(valueOrFactory: any): any {
+ return hasOwnProperty.call(valueOrFactory, '__circular__') ?
+ valueOrFactory() :
+ valueOrFactory;
+}
+
export const usesNativeSymbols = typeof Symbol() === 'symbol';
From 7c31f720e91cb12c1343d6749996d15158a4426a Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Thu, 31 May 2018 08:52:42 -0700
Subject: [PATCH 23/24] style: fix linting errors
---
packages/lwc-engine/src/framework/api.ts | 2 +-
packages/lwc-engine/src/framework/def.ts | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/packages/lwc-engine/src/framework/api.ts b/packages/lwc-engine/src/framework/api.ts
index d88a4ada63..d9964ddbf7 100644
--- a/packages/lwc-engine/src/framework/api.ts
+++ b/packages/lwc-engine/src/framework/api.ts
@@ -1,6 +1,6 @@
import assert from "./assert";
import { vmBeingRendered, invokeEventListener, EventListenerContext } from "./invoker";
-import { freeze, isArray, isUndefined, isNull, isFunction, isObject, isString, ArrayPush, assign, create, forEach, StringSlice, StringCharCodeAt, isNumber, hasOwnProperty, isTrue } from "./language";
+import { freeze, isArray, isUndefined, isNull, isFunction, isObject, isString, ArrayPush, assign, create, forEach, StringSlice, StringCharCodeAt, isNumber, isTrue } from "./language";
import { EmptyArray, SPACE_CHAR, ViewModelReflection, resolveCircularModuleDependency } from "./utils";
import { renderVM, createVM, appendVM, removeVM, VM, getCustomElementVM, Slotset, allocateInSlot } from "./vm";
import { ComponentConstructor } from "./component";
diff --git a/packages/lwc-engine/src/framework/def.ts b/packages/lwc-engine/src/framework/def.ts
index c33da2aa3c..607ba02e99 100644
--- a/packages/lwc-engine/src/framework/def.ts
+++ b/packages/lwc-engine/src/framework/def.ts
@@ -25,7 +25,6 @@ import {
ArraySlice,
isNull,
ArrayReduce,
- hasOwnProperty,
} from "./language";
import {
GlobalAOMProperties,
From c90ef6c31e29d18c933426777185e18a41935037 Mon Sep 17 00:00:00 2001
From: Pierre-Marie
Date: Thu, 31 May 2018 09:05:23 -0700
Subject: [PATCH 24/24] style: update code based on feedback
---
packages/lwc-engine/src/framework/upgrade.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/packages/lwc-engine/src/framework/upgrade.ts b/packages/lwc-engine/src/framework/upgrade.ts
index 9bd4819c01..c19a9a4782 100644
--- a/packages/lwc-engine/src/framework/upgrade.ts
+++ b/packages/lwc-engine/src/framework/upgrade.ts
@@ -91,8 +91,7 @@ export function createElement(sel: string, options: any = {}): HTMLElement {
throw new TypeError();
}
- let { is: Ctor } = (options as any);
- Ctor = resolveCircularModuleDependency(Ctor);
+ const Ctor = resolveCircularModuleDependency((options as any).is);
let { mode, fallback } = (options as any);
// TODO: for now, we default to open, but eventually it should default to 'closed'