From 2f5c6be46fd7028242328407021c1a7b53924ff1 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Sat, 28 Dec 2024 10:49:31 +0000 Subject: [PATCH 1/8] Move riot tests to use common tests --- libraries/__shared__/tests/package-lock.json | 111 +++++++++++++ libraries/__shared__/tests/package.json | 10 ++ .../__shared__/tests/src/advanced-tests.js | 107 ++++++++++++ libraries/__shared__/tests/src/basic-tests.js | 118 +++++++++++++ libraries/riot/karma.conf.js | 1 + libraries/riot/src/advanced-tests.js | 94 ++--------- libraries/riot/src/basic-tests.js | 155 +++--------------- package.json | 4 + scripts/install.mjs | 1 + 9 files changed, 393 insertions(+), 208 deletions(-) create mode 100644 libraries/__shared__/tests/package-lock.json create mode 100644 libraries/__shared__/tests/package.json create mode 100644 libraries/__shared__/tests/src/advanced-tests.js create mode 100644 libraries/__shared__/tests/src/basic-tests.js diff --git a/libraries/__shared__/tests/package-lock.json b/libraries/__shared__/tests/package-lock.json new file mode 100644 index 0000000000..f88209ad10 --- /dev/null +++ b/libraries/__shared__/tests/package-lock.json @@ -0,0 +1,111 @@ +{ + "name": "tests", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "chai": "4.3.10" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/chai": { + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + } + } +} diff --git a/libraries/__shared__/tests/package.json b/libraries/__shared__/tests/package.json new file mode 100644 index 0000000000..322556cbba --- /dev/null +++ b/libraries/__shared__/tests/package.json @@ -0,0 +1,10 @@ +{ + "name": "tests", + "version": "1.0.0", + "description": "", + "author": "", + "license": "ISC", + "devDependencies": { + "chai": "4.3.10" + } +} diff --git a/libraries/__shared__/tests/src/advanced-tests.js b/libraries/__shared__/tests/src/advanced-tests.js new file mode 100644 index 0000000000..08aa0a8685 --- /dev/null +++ b/libraries/__shared__/tests/src/advanced-tests.js @@ -0,0 +1,107 @@ +/** + * @license + * Copyright 2017 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai' + + +function skip() { + this.skip(); + return {}; +} +export default function ( + { + renderComponentWithProperties = skip, + renderComponentWithDeclarativeEvent = skip + } +) { + + + describe('advanced support', function () { + + describe('attributes and properties', function () { + it('will pass array data as a property', async function () { + this.weight = 2 + const { wc } = await renderComponentWithProperties.call(this) + let data = wc.arr + expect(data).to.eql(['r', 'i', 'o', 't']) + }) + + it('will pass object data as a property', async function () { + this.weight = 2 + const { wc } = await renderComponentWithProperties.call(this) + let data = wc.obj + expect(data).to.eql({org: 'riotjs', repo: 'riot'}) + }) + + it('will pass object data to a camelCase-named property', async function () { + this.weight = 2 + const { wc } = await renderComponentWithProperties.call(this) + let data = wc.camelCaseObj; + expect(data).to.eql({label: "passed"}); + }) + + }) + + describe('events', function () { + it('can declaratively listen to a lowercase DOM event dispatched by a Custom Element', async function () { + this.weight = 2 + const { wc } = await renderComponentWithDeclarativeEvent.call(this) + expect(wc).to.exist + let handled = document.querySelector('#lowercase') + expect(handled.textContent).to.eql('false') + wc.click() + expect(handled.textContent).to.eql('true') + }) + + it('can declaratively listen to a kebab-case DOM event dispatched by a Custom Element', async function () { + this.weight = 1 + const { wc } = await renderComponentWithDeclarativeEvent.call(this) + let handled = document.querySelector('#kebab') + expect(handled.textContent).to.eql('false') + wc.click() + expect(handled.textContent).to.eql('true') + }) + + it('can declaratively listen to a camelCase DOM event dispatched by a Custom Element', async function () { + this.weight = 1 + const { wc } = await renderComponentWithDeclarativeEvent.call(this) + let handled = document.querySelector('#camel') + expect(handled.textContent).to.eql('false') + wc.click() + expect(handled.textContent).to.eql('true') + }) + + it('can declaratively listen to a CAPScase DOM event dispatched by a Custom Element', async function () { + this.weight = 1 + const { wc } = await renderComponentWithDeclarativeEvent.call(this) + let handled = document.querySelector('#caps') + expect(handled.textContent).to.eql('false') + wc.click() + expect(handled.textContent).to.eql('true') + }) + + it('can declaratively listen to a PascalCase DOM event dispatched by a Custom Element', async function () { + this.weight = 1 + const { wc } = await renderComponentWithDeclarativeEvent.call(this) + let handled = document.querySelector('#pascal') + expect(handled.textContent).to.eql('false') + wc.click() + expect(handled.textContent).to.eql('true') + }) + }) + }) +} diff --git a/libraries/__shared__/tests/src/basic-tests.js b/libraries/__shared__/tests/src/basic-tests.js new file mode 100644 index 0000000000..85e238199d --- /dev/null +++ b/libraries/__shared__/tests/src/basic-tests.js @@ -0,0 +1,118 @@ +/** + * @license + * Copyright 2017 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {expect} from 'chai' + +function skip() { + this.skip(); + return {}; +} + +export default function ( + { + renderComponentWithoutChildren = skip, + renderComponentWithChildren = skip, + renderComponentWithChildrenRerender = skip, + renderComponentWithDifferentViews = skip, + renderComponentWithProperties = skip, + renderComponentWithImperativeEvent = skip, + }) { + + describe('basic support', function () { + + describe('no children', function () { + it('can display a Custom Element with no children', async function () { + this.weight = 3 + const { wc } = await renderComponentWithoutChildren.call(this); + expect(wc).to.exist + }) + }) + + describe('with children', function () { + function expectHasChildren(wc) { + expect(wc).to.exist + let shadowRoot = wc.shadowRoot + let heading = shadowRoot.querySelector('h1') + expect(heading).to.exist + expect(heading.textContent).to.eql('Test h1') + let paragraph = shadowRoot.querySelector('p') + expect(paragraph).to.exist + expect(paragraph.textContent).to.eql('Test p') + } + + it('can display a Custom Element with children in a Shadow Root', async function () { + this.weight = 3 + const { wc } = await renderComponentWithChildren.call(this); + expectHasChildren(wc) + }) + + it('can display a Custom Element with children in a Shadow Root and pass in Light DOM children', async function () { + this.weight = 3 + const { wc } = await renderComponentWithChildrenRerender.call(this); + expectHasChildren(wc) + expect(wc.textContent.includes('2')).to.be.true + }) + + it('can display a Custom Element with children in the Shadow DOM and handle hiding and showing the element', async function () { + this.weight = 3 + const { wc, toggle } = await renderComponentWithDifferentViews.call(this); + expectHasChildren(wc) + toggle() + let dummy = document.querySelector('#dummy') + expect(dummy).to.exist + expect(dummy.textContent).to.eql('Dummy view') + toggle() + expectHasChildren(wc) + }) + }) + + describe('attributes and properties', function () { + it('will pass boolean data as either an attribute or a property', async function () { + this.weight = 3 + const { wc } = await renderComponentWithProperties.call(this); + let data = wc.bool || wc.hasAttribute('bool') + expect(data).to.be.true + }) + + it('will pass numeric data as either an attribute or a property', async function () { + this.weight = 3 + const { wc } = await renderComponentWithProperties.call(this); + let data = wc.num || wc.getAttribute('num') + expect(parseInt(data, 10)).to.eql(42) + }) + + it('will pass string data as either an attribute or a property', async function () { + this.weight = 3 + const { wc } = await renderComponentWithProperties.call(this); + let data = wc.str || wc.getAttribute('str') + expect(data).to.eql('riot') + }) + }) + + describe('events', async function () { + it('can imperatively listen to a DOM event dispatched by a Custom Element', async function () { + this.weight = 3 + const { wc } = await renderComponentWithImperativeEvent.call(this) + expect(wc).to.exist + let handled = document.querySelector('#handled') + expect(handled.textContent).to.eql('false') + wc.click() + expect(handled.textContent).to.eql('true') + }) + }) + }) +} \ No newline at end of file diff --git a/libraries/riot/karma.conf.js b/libraries/riot/karma.conf.js index 56745e46b1..90ff5abaac 100644 --- a/libraries/riot/karma.conf.js +++ b/libraries/riot/karma.conf.js @@ -61,6 +61,7 @@ module.exports = function(config) { resolve: { modules: [ path.resolve(__dirname, '../__shared__/webcomponents/src'), + path.resolve(__dirname, '../__shared__/tests/src'), path.resolve(__dirname, './node_modules') ] }, diff --git a/libraries/riot/src/advanced-tests.js b/libraries/riot/src/advanced-tests.js index 0c34a6b8c0..88e3ec8160 100644 --- a/libraries/riot/src/advanced-tests.js +++ b/libraries/riot/src/advanced-tests.js @@ -19,9 +19,11 @@ import { expect } from 'chai' import { component } from 'riot' import { ComponentWithProperties, - ComponentWithDeclarativeEvent + ComponentWithDeclarativeEvent, } from './components' +import tests from 'advanced-tests'; + // Setup the test harness. This will get cleaned out with every test. let app = document.createElement('div') app.id = 'app' @@ -39,86 +41,18 @@ afterEach(function() { scratch = null }) -describe('advanced support', function() { - - describe('attributes and properties', function() { - it('will pass array data as a property', function() { - this.weight = 2 - component(ComponentWithProperties)(scratch) - let wc = scratch.querySelector('#wc') - let data = wc.arr - expect(data).to.eql(['r', 'i', 'o', 't']) - }) - - it('will pass object data as a property', function() { - this.weight = 2 - component(ComponentWithProperties)(scratch) - let wc = scratch.querySelector('#wc') - let data = wc.obj - expect(data).to.eql({ org: 'riotjs', repo: 'riot' }) - }) - - it('will pass object data to a camelCase-named property', function() { - this.weight = 2 - component(ComponentWithProperties)(scratch) - let wc = scratch.querySelector('#wc') - let data = wc.camelCaseObj; - expect(data).to.eql({ label: "passed" }); - }) - - }) - - describe('events', function() { - it('can declaratively listen to a lowercase DOM event dispatched by a Custom Element', function() { - this.weight = 2 - component(ComponentWithDeclarativeEvent)(scratch) - let wc = scratch.querySelector('#wc') - expect(wc).to.exist - let handled = scratch.querySelector('#lowercase') - expect(handled.textContent).to.eql('false') - wc.click() - expect(handled.textContent).to.eql('true') - }) - - it('can declaratively listen to a kebab-case DOM event dispatched by a Custom Element', function() { - this.weight = 1 - component(ComponentWithDeclarativeEvent)(scratch) - let wc = scratch.querySelector('#wc') - let handled = scratch.querySelector('#kebab') - expect(handled.textContent).to.eql('false') - wc.click() - expect(handled.textContent).to.eql('true') - }) - - it('can declaratively listen to a camelCase DOM event dispatched by a Custom Element', function() { - this.weight = 1 - component(ComponentWithDeclarativeEvent)(scratch) - let wc = scratch.querySelector('#wc') - let handled = scratch.querySelector('#camel') - expect(handled.textContent).to.eql('false') - wc.click() - expect(handled.textContent).to.eql('true') - }) - it('can declaratively listen to a CAPScase DOM event dispatched by a Custom Element', function() { - this.weight = 1 - component(ComponentWithDeclarativeEvent)(scratch) - let wc = scratch.querySelector('#wc') - let handled = scratch.querySelector('#caps') - expect(handled.textContent).to.eql('false') - wc.click() - expect(handled.textContent).to.eql('true') - }) +function render(Component) { + const el = component(Component)(scratch) + return {wc: scratch.querySelector('#wc'), el} +} - it('can declaratively listen to a PascalCase DOM event dispatched by a Custom Element', function() { - this.weight = 1 - component(ComponentWithDeclarativeEvent)(scratch) - let wc = scratch.querySelector('#wc') - let handled = scratch.querySelector('#pascal') - expect(handled.textContent).to.eql('false') - wc.click() - expect(handled.textContent).to.eql('true') - }) - }) +tests({ + renderComponentWithProperties() { + return render(ComponentWithProperties) + }, + renderComponentWithDeclarativeEvent() { + return render(ComponentWithDeclarativeEvent) + } }) diff --git a/libraries/riot/src/basic-tests.js b/libraries/riot/src/basic-tests.js index 83298d2284..1a533e952a 100644 --- a/libraries/riot/src/basic-tests.js +++ b/libraries/riot/src/basic-tests.js @@ -15,7 +15,6 @@ * limitations under the License. */ -import { expect } from 'chai' import { component } from 'riot' import { ComponentWithoutChildren, @@ -23,10 +22,11 @@ import { ComponentWithChildrenRerender, ComponentWithDifferentViews, ComponentWithProperties, - ComponentWithUnregistered, ComponentWithImperativeEvent } from './components' +import tests from 'basic-tests'; + // Setup the test harness. This will get cleaned out with every test. let app = document.createElement('div') app.id = 'app' @@ -44,130 +44,29 @@ afterEach(function() { scratch = null }) -describe('basic support', function() { - - describe('no children', function() { - it('can display a Custom Element with no children', function() { - this.weight = 3 - component(ComponentWithoutChildren)(scratch) - let wc = scratch.querySelector('#wc') - expect(wc).to.exist - }) - }) - - describe('with children', function() { - function expectHasChildren(wc) { - expect(wc).to.exist - let shadowRoot = wc.shadowRoot - let heading = shadowRoot.querySelector('h1') - expect(heading).to.exist - expect(heading.textContent).to.eql('Test h1') - let paragraph = shadowRoot.querySelector('p') - expect(paragraph).to.exist - expect(paragraph.textContent).to.eql('Test p') - } - - it('can display a Custom Element with children in a Shadow Root', function() { - this.weight = 3 - component(ComponentWithChildren)(scratch) - let wc = scratch.querySelector('#wc') - expectHasChildren(wc) - }) - - it('can display a Custom Element with children in a Shadow Root and pass in Light DOM children', function() { - this.weight = 3 - component(ComponentWithChildrenRerender)(scratch) - let wc = scratch.querySelector('#wc') - expectHasChildren(wc) - expect(wc.textContent.includes('2')).to.be.true - }) - - it('can display a Custom Element with children in the Shadow DOM and handle hiding and showing the element', function() { - this.weight = 3 - const el = component(ComponentWithDifferentViews)(scratch) - let wc = scratch.querySelector('#wc') - expectHasChildren(wc) - el.toggle() - let dummy = scratch.querySelector('#dummy') - expect(dummy).to.exist - expect(dummy.textContent).to.eql('Dummy view') - el.toggle() - wc = scratch.querySelector('#wc') - expectHasChildren(wc) - }) - }) - - describe('attributes and properties', function() { - it('will pass boolean data as either an attribute or a property', function() { - this.weight = 3 - component(ComponentWithProperties)(scratch) - let wc = scratch.querySelector('#wc') - let data = wc.bool || wc.hasAttribute('bool') - expect(data).to.be.true - }) - - it('will pass numeric data as either an attribute or a property', function() { - this.weight = 3 - component(ComponentWithProperties)(scratch) - let wc = scratch.querySelector('#wc') - let data = wc.num || wc.getAttribute('num') - expect(parseInt(data, 10)).to.eql(42) - }) - - it('will pass string data as either an attribute or a property', function() { - this.weight = 3 - component(ComponentWithProperties)(scratch) - let wc = scratch.querySelector('#wc') - let data = wc.str || wc.getAttribute('str') - expect(data).to.eql('riot') - }) - - // Riot.js passes all the following tests but they must be commented out - // being consistent with the other frameworks ¯\_(ツ)_/¯ - /* - it('will set boolean attributes on a Custom Element that has not already been defined and upgraded', function() { - component(ComponentWithUnregistered)(scratch) - let wc = scratch.querySelector('#wc') - expect(wc.hasAttribute('bool')).to.be.true - }) - - it('will set numeric attributes on a Custom Element that has not already been defined and upgraded', function() { - component(ComponentWithUnregistered)(scratch) - let wc = scratch.querySelector('#wc') - expect(wc.getAttribute('num')).to.eql('42') - }) - - it('will set string attributes on a Custom Element that has not already been defined and upgraded', function() { - component(ComponentWithUnregistered)(scratch) - let wc = scratch.querySelector('#wc') - expect(wc.getAttribute('str')).to.eql('riot') - }) - - it('will set array properties on a Custom Element that has not already been defined and upgraded', function() { - component(ComponentWithUnregistered)(scratch) - let wc = scratch.querySelector('#wc') - expect(wc.arr).to.eql(['r', 'i', 'o', 't']) - }) - - it('will set object properties on a Custom Element that has not already been defined and upgraded', function() { - component(ComponentWithUnregistered)(scratch) - let wc = scratch.querySelector('#wc') - expect(wc.obj).to.eql({ org: 'riotjs', repo: 'riot' }) - }) - */ - }) - - describe('events', function() { - it('can imperatively listen to a DOM event dispatched by a Custom Element', function() { - this.weight = 3 - component(ComponentWithImperativeEvent)(scratch) - let wc = scratch.querySelector('#wc') - expect(wc).to.exist - let handled = scratch.querySelector('#handled') - expect(handled.textContent).to.eql('false') - wc.click() - expect(handled.textContent).to.eql('true') - }) - }) - +function render(Component) { + const el = component(Component)(scratch) + return {wc: scratch.querySelector('#wc'), el} +} + +tests({ + renderComponentWithoutChildren() { + return render(ComponentWithoutChildren) + }, + renderComponentWithChildren() { + return render(ComponentWithChildren) + }, + renderComponentWithChildrenRerender() { + return render(ComponentWithChildrenRerender) + }, + renderComponentWithDifferentViews() { + const {wc, el} = render(ComponentWithDifferentViews) + return {wc, el, toggle: () => el.toggle()} + }, + renderComponentWithProperties() { + return render(ComponentWithProperties) + }, + renderComponentWithImperativeEvent() { + return render(ComponentWithImperativeEvent) + } }) diff --git a/package.json b/package.json index e1b797b737..79d48d5fbb 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,10 @@ "./libraries/__shared__/karma-plugins/karma-custom-html-reporter:build", "./libraries/__shared__/karma-plugins/karma-custom-json-reporter:build", "./libraries/__shared__/karma-plugins/karma-mocha:build" + ], + "files": [ + "./libraries/__shared__/tests/src/basic-tests.js", + "./libraries/__shared__/tests/src/advanced-tests.js" ] } } diff --git a/scripts/install.mjs b/scripts/install.mjs index f3af923e0e..b9eaec7556 100644 --- a/scripts/install.mjs +++ b/scripts/install.mjs @@ -18,6 +18,7 @@ async function install() { {name: join('__shared__', 'karma-plugins', 'karma-custom-html-reporter')}, {name: join('__shared__', 'karma-plugins' , 'karma-custom-json-reporter')}, {name: join('__shared__', 'karma-plugins', 'karma-mocha')}, + {name: join('__shared__', 'tests')}, {name: join('__shared__', 'webcomponents')}, ]; const packages = allLibs.map((lib) => join(__dirname, '..', 'libraries', lib.name)); From c9c9947d763447a78975fc4f3ae5aeddeaa0474e Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Sat, 28 Dec 2024 11:16:31 +0000 Subject: [PATCH 2/8] Move react to using common tests --- .../__shared__/tests/src/advanced-tests.js | 24 +- libraries/__shared__/tests/src/basic-tests.js | 8 +- libraries/react/karma.conf.js | 1 + libraries/react/src/advanced-tests.js | 171 ++----------- libraries/react/src/basic-tests.js | 234 ++++-------------- libraries/react/src/components.js | 20 +- .../components/ComponentWithProperties.riot | 6 +- 7 files changed, 100 insertions(+), 364 deletions(-) diff --git a/libraries/__shared__/tests/src/advanced-tests.js b/libraries/__shared__/tests/src/advanced-tests.js index 08aa0a8685..565f7b6da7 100644 --- a/libraries/__shared__/tests/src/advanced-tests.js +++ b/libraries/__shared__/tests/src/advanced-tests.js @@ -37,14 +37,14 @@ export default function ( this.weight = 2 const { wc } = await renderComponentWithProperties.call(this) let data = wc.arr - expect(data).to.eql(['r', 'i', 'o', 't']) + expect(data).to.eql(['c', 'u', 's', 't', 'o', 'm']) }) it('will pass object data as a property', async function () { this.weight = 2 const { wc } = await renderComponentWithProperties.call(this) let data = wc.obj - expect(data).to.eql({org: 'riotjs', repo: 'riot'}) + expect(data).to.eql({org: 'webcomponents', repo: 'custom-elements-everywhere'}) }) it('will pass object data to a camelCase-named property', async function () { @@ -59,47 +59,47 @@ export default function ( describe('events', function () { it('can declaratively listen to a lowercase DOM event dispatched by a Custom Element', async function () { this.weight = 2 - const { wc } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) expect(wc).to.exist let handled = document.querySelector('#lowercase') expect(handled.textContent).to.eql('false') - wc.click() + click() expect(handled.textContent).to.eql('true') }) it('can declaratively listen to a kebab-case DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#kebab') expect(handled.textContent).to.eql('false') - wc.click() + click() expect(handled.textContent).to.eql('true') }) it('can declaratively listen to a camelCase DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#camel') expect(handled.textContent).to.eql('false') - wc.click() + click() expect(handled.textContent).to.eql('true') }) it('can declaratively listen to a CAPScase DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#caps') expect(handled.textContent).to.eql('false') - wc.click() + click() expect(handled.textContent).to.eql('true') }) it('can declaratively listen to a PascalCase DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#pascal') expect(handled.textContent).to.eql('false') - wc.click() + click() expect(handled.textContent).to.eql('true') }) }) diff --git a/libraries/__shared__/tests/src/basic-tests.js b/libraries/__shared__/tests/src/basic-tests.js index 85e238199d..9afc202c24 100644 --- a/libraries/__shared__/tests/src/basic-tests.js +++ b/libraries/__shared__/tests/src/basic-tests.js @@ -72,7 +72,7 @@ export default function ( const { wc, toggle } = await renderComponentWithDifferentViews.call(this); expectHasChildren(wc) toggle() - let dummy = document.querySelector('#dummy') + const dummy = document.querySelector('#dummy') expect(dummy).to.exist expect(dummy.textContent).to.eql('Dummy view') toggle() @@ -99,18 +99,18 @@ export default function ( this.weight = 3 const { wc } = await renderComponentWithProperties.call(this); let data = wc.str || wc.getAttribute('str') - expect(data).to.eql('riot') + expect(data).to.eql('custom') }) }) describe('events', async function () { it('can imperatively listen to a DOM event dispatched by a Custom Element', async function () { this.weight = 3 - const { wc } = await renderComponentWithImperativeEvent.call(this) + const { wc, click = wc.click } = await renderComponentWithImperativeEvent.call(this) expect(wc).to.exist let handled = document.querySelector('#handled') expect(handled.textContent).to.eql('false') - wc.click() + click() expect(handled.textContent).to.eql('true') }) }) diff --git a/libraries/react/karma.conf.js b/libraries/react/karma.conf.js index 50d6252389..fe6c363fca 100644 --- a/libraries/react/karma.conf.js +++ b/libraries/react/karma.conf.js @@ -61,6 +61,7 @@ module.exports = function(config) { resolve: { modules: [ path.resolve(__dirname, '../__shared__/webcomponents/src'), + path.resolve(__dirname, '../__shared__/tests/src'), path.resolve(__dirname, './node_modules') ] }, diff --git a/libraries/react/src/advanced-tests.js b/libraries/react/src/advanced-tests.js index 3cf56cd669..1747f80fa6 100644 --- a/libraries/react/src/advanced-tests.js +++ b/libraries/react/src/advanced-tests.js @@ -30,6 +30,8 @@ import { ComponentWithDeclarativeEvent } from "./components"; +import tests from 'advanced-tests'; + // Setup the test harness. This will get cleaned out with every test. let app = document.createElement("div"); app.id = "app"; @@ -37,11 +39,6 @@ document.body.appendChild(app); let scratch; // This will hold the actual element under test. let reactRoot = null; -function render(element) { - act(() => { - reactRoot.render(element); - }); -} before(() => { window.IS_REACT_ACT_ENVIRONMENT = true; @@ -68,150 +65,32 @@ afterEach(function() { }); }); -describe("advanced support", function() { - describe("attributes and properties", function() { - it("will pass array data as a property", function() { - this.weight = 2; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let data = wc.arr; - expect(data).to.eql(["R", "e", "a", "c", "t"]); - }); - - it("will pass object data as a property", function() { - this.weight = 2; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let data = wc.obj; - expect(data).to.eql({ org: "facebook", repo: "react" }); - }); - - it("will pass object data to a camelCase-named property", function() { - this.weight = 2; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let data = wc.camelCaseObj; - expect(data).to.eql({ label: "passed" }); - }); +function render(Component) { + let root; + act(() => { + reactRoot.render( + { + root = current; + }} + /> + ); }); + return {wc: root.wc, root} +} - describe("events", function() { - it("can declaratively listen to a lowercase DOM event dispatched by a Custom Element", function() { - this.weight = 2; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let handled = root.lowercase; - expect(handled.textContent).to.eql("false"); - act(() => { - wc.click(); - }); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a kebab-case DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let handled = root.kebab; - expect(handled.textContent).to.eql("false"); - act(() => { - wc.click(); - }); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a camelCase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let handled = root.camel; - expect(handled.textContent).to.eql("false"); - act(() => { - wc.click(); - }); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a CAPScase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let handled = root.caps; - expect(handled.textContent).to.eql("false"); - act(() => { - wc.click(); - }); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a PascalCase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let handled = root.pascal; - expect(handled.textContent).to.eql("false"); +tests({ + renderComponentWithProperties() { + return render(ComponentWithProperties); + }, + renderComponentWithDeclarativeEvent() { + const { wc, root } = render(ComponentWithDeclarativeEvent) + function click() { act(() => { wc.click(); }); - expect(handled.textContent).to.eql("true"); - }); - }); - -}); + } + return { wc, root, click } + } +}) diff --git a/libraries/react/src/basic-tests.js b/libraries/react/src/basic-tests.js index 3400a37e8b..61ccaa93c8 100644 --- a/libraries/react/src/basic-tests.js +++ b/libraries/react/src/basic-tests.js @@ -16,10 +16,10 @@ */ import React from "react"; -import { createRoot } from "react-dom/client"; -import { act } from "react-dom/test-utils"; +import {createRoot} from "react-dom/client"; +import {act} from "react-dom/test-utils"; import * as ReactDOM from "react-dom"; -import { expect } from "chai"; +import {expect} from "chai"; import { ComponentWithoutChildren, ComponentWithChildren, @@ -31,6 +31,8 @@ import { ComponentWithDeclarativeEvent, } from "./components"; +import tests from 'basic-tests'; + // Setup the test harness. This will get cleaned out with every test. let app = document.createElement("div"); app.id = "app"; @@ -38,11 +40,6 @@ document.body.appendChild(app); let scratch; // This will hold the actual element under test. let reactRoot = null; -function render(element) { - act(() => { - reactRoot.render(element); - }); -} before(() => { window.IS_REACT_ACT_ENVIRONMENT = true; @@ -65,194 +62,53 @@ afterEach(function () { }); }); -describe("basic support", function () { - describe("no children", function () { - it("can display a Custom Element with no children", function () { - this.weight = 3; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - expect(wc).to.exist; - }); +function render(Component) { + let root; + act(() => { + reactRoot.render( + { + root = current; + }} + /> + ); }); + return {wc: root.wc, root} +} - describe("with children", function () { - function expectHasChildren(wc) { - expect(wc).to.exist; - let shadowRoot = wc.shadowRoot; - let heading = shadowRoot.querySelector("h1"); - expect(heading).to.exist; - expect(heading.textContent).to.eql("Test h1"); - let paragraph = shadowRoot.querySelector("p"); - expect(paragraph).to.exist; - expect(paragraph.textContent).to.eql("Test p"); - } - - it("can display a Custom Element with children in a Shadow Root", function () { - this.weight = 3; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - expectHasChildren(wc); - }); - - it("can display a Custom Element with children in a Shadow Root and pass in Light DOM children", async function () { - this.weight = 3; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - await act(async () => { - await Promise.resolve(); - }); - expectHasChildren(wc); - expect(wc.textContent.includes("2")).to.be.true; +tests({ + renderComponentWithoutChildren() { + return render(ComponentWithoutChildren); + }, + renderComponentWithChildren() { + return render(ComponentWithChildren); + }, + async renderComponentWithChildrenRerender() { + const results = render(ComponentWithChildrenRerender); + await act(async () => { + await Promise.resolve(); }); - - it("can display a Custom Element with children in the Shadow DOM and handle hiding and showing the element", function () { - this.weight = 3; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - expectHasChildren(wc); + return results; + }, + renderComponentWithProperties() { + return render(ComponentWithProperties); + }, + renderComponentWithDifferentViews() { + const { wc, root } = render(ComponentWithDifferentViews); + function toggle() { act(() => { root.toggle(); }); - let dummy = root.dummy.current; - expect(dummy).to.exist; - expect(dummy.textContent).to.eql("Dummy view"); - act(() => { - root.toggle(); - }); - wc = root.wc; - expectHasChildren(wc); - }); - }); - - describe("attributes and properties", function () { - it("will pass boolean data as either an attribute or a property", function () { - this.weight = 3; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let data = wc.bool || wc.hasAttribute("bool"); - expect(data).to.be.true; - }); - - it("will pass numeric data as either an attribute or a property", function () { - this.weight = 3; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let data = wc.num || wc.getAttribute("num"); - expect(parseInt(data, 10)).to.eql(42); - }); - - it("will pass string data as either an attribute or a property", function () { - this.weight = 3; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let data = wc.str || wc.getAttribute("str"); - expect(data).to.eql("React"); - }); - - // TODO: Is it the framework's responsibility to check if the underlying - // property is defined? Or should it just always assume it is and do its - // usual default behavior? Preact will actually check if it's defined and - // use an attribute if it is not, otherwise it prefers properties for - // everything. Is there a "right" answer in this situation? - - // it('will set boolean attributes on a Custom Element that has not already been defined and upgraded', function() { - // let root = ReactDOM.render(, scratch); - // let wc = ReactDOM.findDOMNode(root.refs.wc); - // expect(wc.hasAttribute('bool')).to.be.true; - // }); - - // it('will set numeric attributes on a Custom Element that has not already been defined and upgraded', function() { - // let root = ReactDOM.render(, scratch); - // let wc = ReactDOM.findDOMNode(root.refs.wc); - // expect(wc.getAttribute('num')).to.eql('42'); - // }); - - // it('will set string attributes on a Custom Element that has not already been defined and upgraded', function() { - // let root = ReactDOM.render(, scratch); - // let wc = ReactDOM.findDOMNode(root.refs.wc); - // expect(wc.getAttribute('str')).to.eql('React'); - // }); - - // it('will set array attributes on a Custom Element that has not already been defined and upgraded', function() { - // let root = ReactDOM.render(, scratch); - // let wc = ReactDOM.findDOMNode(root.refs.wc); - // expect(wc.getAttribute('arr')).to.eql(JSON.stringify(['R', 'e', 'a', 'c', 't'])); - // }); - - // it('will set object attributes on a Custom Element that has not already been defined and upgraded', function() { - // let root = ReactDOM.render(, scratch); - // let wc = ReactDOM.findDOMNode(root.refs.wc); - // expect(wc.getAttribute('obj')).to.eql(JSON.stringify({ org: 'facebook', repo: 'react' })); - // }); - }); - - describe("events", function () { - it("can imperatively listen to a DOM event dispatched by a Custom Element", function () { - this.weight = 3; - let root; - render( - { - root = current; - }} - /> - ); - let wc = root.wc; - let handled = root.handled; - expect(handled.textContent).to.eql("false"); + } + return { wc, root, toggle } + }, + renderComponentWithImperativeEvent() { + const { wc, root } = render(ComponentWithImperativeEvent) + function click() { act(() => { wc.click(); }); - expect(handled.textContent).to.eql("true"); - }); - }); + } + return { wc, root, click } + } }); diff --git a/libraries/react/src/components.js b/libraries/react/src/components.js index 20a7f82c23..63b721ee6c 100644 --- a/libraries/react/src/components.js +++ b/libraries/react/src/components.js @@ -78,7 +78,7 @@ export class ComponentWithDifferentViews extends Component { {showWC ? ( this.wc = el}> ) : ( -
Dummy view
+
Dummy view
)} ); @@ -90,9 +90,9 @@ export class ComponentWithProperties extends Component { const data = { bool: true, num: 42, - str: 'React', - arr: ['R', 'e', 'a', 'c', 't'], - obj: { org: 'facebook', repo: 'react' }, + str: 'custom', + arr: ['c', 'u', 's', 't', 'o', 'm'], + obj: { org: 'webcomponents', repo: 'custom-elements-everywhere' }, camelCaseObj: { label: "passed" } }; return ( @@ -153,7 +153,7 @@ export class ComponentWithImperativeEvent extends Component { let state = this.state; return (
-
this.handled = el}>{state.eventHandled.toString()}
+
this.handled = el}>{state.eventHandled.toString()}
this.wc = el}>
); @@ -195,11 +195,11 @@ export class ComponentWithDeclarativeEvent extends Component { let state = this.state; return (
-
this.lowercase = el}>{state.lowercaseHandled.toString()}
-
this.kebab = el}>{state.kebabHandled.toString()}
-
this.camel = el}>{state.camelHandled.toString()}
-
this.caps = el}>{state.capsHandled.toString()}
-
this.pascal = el}>{state.pascalHandled.toString()}
+
this.lowercase = el}>{state.lowercaseHandled.toString()}
+
this.kebab = el}>{state.kebabHandled.toString()}
+
this.camel = el}>{state.camelHandled.toString()}
+
this.caps = el}>{state.capsHandled.toString()}
+
this.pascal = el}>{state.pascalHandled.toString()}
this.wc = el} onlowercaseevent={this.handleLowercaseEvent} onkebab-event={this.handleKebabEvent} diff --git a/libraries/riot/src/components/ComponentWithProperties.riot b/libraries/riot/src/components/ComponentWithProperties.riot index dd975be44b..e102d76c99 100644 --- a/libraries/riot/src/components/ComponentWithProperties.riot +++ b/libraries/riot/src/components/ComponentWithProperties.riot @@ -5,9 +5,9 @@ state: { bool: true, num: 42, - str: 'riot', - arr: ['r', 'i', 'o', 't'], - obj: { org: 'riotjs', repo: 'riot' }, + str: 'custom', + arr: ['c', 'u', 's', 't', 'o', 'm'], + obj: { org: 'webcomponents', repo: 'custom-elements-everywhere' }, camelCaseObj: { label: "passed" }, } } From 1b04f61f70a143fa37e31709299767d256114c41 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Sat, 28 Dec 2024 13:31:11 +0000 Subject: [PATCH 3/8] +angular --- .../__shared__/tests/src/advanced-tests.js | 10 +- libraries/__shared__/tests/src/basic-tests.js | 2 +- libraries/angular/karma.conf.js | 1 + libraries/angular/src/advanced-tests.js | 121 +++----------- libraries/angular/src/basic-tests.js | 152 +++++------------- libraries/angular/src/components.ts | 6 +- 6 files changed, 68 insertions(+), 224 deletions(-) diff --git a/libraries/__shared__/tests/src/advanced-tests.js b/libraries/__shared__/tests/src/advanced-tests.js index 565f7b6da7..201fc23475 100644 --- a/libraries/__shared__/tests/src/advanced-tests.js +++ b/libraries/__shared__/tests/src/advanced-tests.js @@ -59,7 +59,7 @@ export default function ( describe('events', function () { it('can declaratively listen to a lowercase DOM event dispatched by a Custom Element', async function () { this.weight = 2 - const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) expect(wc).to.exist let handled = document.querySelector('#lowercase') expect(handled.textContent).to.eql('false') @@ -69,7 +69,7 @@ export default function ( it('can declaratively listen to a kebab-case DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#kebab') expect(handled.textContent).to.eql('false') click() @@ -78,7 +78,7 @@ export default function ( it('can declaratively listen to a camelCase DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#camel') expect(handled.textContent).to.eql('false') click() @@ -87,7 +87,7 @@ export default function ( it('can declaratively listen to a CAPScase DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#caps') expect(handled.textContent).to.eql('false') click() @@ -96,7 +96,7 @@ export default function ( it('can declaratively listen to a PascalCase DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc, click = wc.click } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#pascal') expect(handled.textContent).to.eql('false') click() diff --git a/libraries/__shared__/tests/src/basic-tests.js b/libraries/__shared__/tests/src/basic-tests.js index 9afc202c24..8b667b5f44 100644 --- a/libraries/__shared__/tests/src/basic-tests.js +++ b/libraries/__shared__/tests/src/basic-tests.js @@ -106,7 +106,7 @@ export default function ( describe('events', async function () { it('can imperatively listen to a DOM event dispatched by a Custom Element', async function () { this.weight = 3 - const { wc, click = wc.click } = await renderComponentWithImperativeEvent.call(this) + const { wc, click = wc.click.bind(wc) } = await renderComponentWithImperativeEvent.call(this) expect(wc).to.exist let handled = document.querySelector('#handled') expect(handled.textContent).to.eql('false') diff --git a/libraries/angular/karma.conf.js b/libraries/angular/karma.conf.js index 21091eeae4..5a35e4fc42 100644 --- a/libraries/angular/karma.conf.js +++ b/libraries/angular/karma.conf.js @@ -68,6 +68,7 @@ module.exports = function (config) { extensions: ['.js', '.ts'], modules: [ path.resolve(__dirname, '../__shared__/webcomponents/src'), + path.resolve(__dirname, '../__shared__/tests/src'), path.resolve(__dirname, './node_modules') ] }, diff --git a/libraries/angular/src/advanced-tests.js b/libraries/angular/src/advanced-tests.js index f0f516dec1..2e7ea158b2 100644 --- a/libraries/angular/src/advanced-tests.js +++ b/libraries/angular/src/advanced-tests.js @@ -17,8 +17,6 @@ import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; import { TestBed } from "@angular/core/testing"; -import { By } from "@angular/platform-browser"; -import { expect } from "chai"; import { ComponentWithoutChildren, ComponentWithChildren, @@ -30,6 +28,16 @@ import { ComponentWithDeclarativeEvent } from "./components"; +import tests from 'advanced-tests'; + +function render(Component) { + const fixture = TestBed.createComponent(Component); + fixture.detectChanges(); + const el = fixture.debugElement.nativeElement; + const wc = el.querySelector('#wc'); + return { wc, fixture } +} + beforeEach(function() { TestBed.configureTestingModule({ declarations: [ @@ -46,105 +54,16 @@ beforeEach(function() { }); }); -describe("advanced support", function() { - - describe("attributes and properties", function() { - it("will pass array data as a property", function() { - this.weight = 2; - let fixture = TestBed.createComponent(ComponentWithProperties); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let data = wc.arr; - expect(data).to.eql(["A", "n", "g", "u", "l", "a", "r"]); - }); - - it("will pass object data as a property", function() { - this.weight = 2; - let fixture = TestBed.createComponent(ComponentWithProperties); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let data = wc.obj; - expect(data).to.eql({ org: "angular", repo: "angular" }); - }); - - it("will pass object data to a camelCase-named property", function() { - this.weight = 2; - let fixture = TestBed.createComponent(ComponentWithProperties); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let data = wc.camelCaseObj; - expect(data).to.eql({ label: "passed" }); - }); - }); - - describe("events", function() { - it("can declaratively listen to a lowercase DOM event dispatched by a Custom Element", function() { - this.weight = 2; - let fixture = TestBed.createComponent(ComponentWithDeclarativeEvent); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#lowercase"); - expect(handled.textContent).to.eql("false"); - wc.click(); - fixture.detectChanges(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a kebab-case DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let fixture = TestBed.createComponent(ComponentWithDeclarativeEvent); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#kebab"); - expect(handled.textContent).to.eql("false"); +tests({ + renderComponentWithProperties() { + return render(ComponentWithProperties); + }, + renderComponentWithDeclarativeEvent() { + const { wc, fixture } = render(ComponentWithDeclarativeEvent); + function click() { wc.click(); fixture.detectChanges(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a camelCase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let fixture = TestBed.createComponent(ComponentWithDeclarativeEvent); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#camel"); - expect(handled.textContent).to.eql("false"); - wc.click(); - fixture.detectChanges(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a CAPScase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let fixture = TestBed.createComponent(ComponentWithDeclarativeEvent); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#caps"); - expect(handled.textContent).to.eql("false"); - wc.click(); - fixture.detectChanges(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a PascalCase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let fixture = TestBed.createComponent(ComponentWithDeclarativeEvent); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#pascal"); - expect(handled.textContent).to.eql("false"); - wc.click(); - fixture.detectChanges(); - expect(handled.textContent).to.eql("true"); - }); - }); - + } + return { wc, fixture, click }; + } }); diff --git a/libraries/angular/src/basic-tests.js b/libraries/angular/src/basic-tests.js index 80dba3fd4a..b895bbe8fe 100644 --- a/libraries/angular/src/basic-tests.js +++ b/libraries/angular/src/basic-tests.js @@ -17,8 +17,7 @@ import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; import { TestBed } from "@angular/core/testing"; -import { By } from "@angular/platform-browser"; -import { expect } from "chai"; + import { ComponentWithoutChildren, ComponentWithChildren, @@ -30,6 +29,8 @@ import { ComponentWithDeclarativeEvent } from "./components"; +import tests from 'basic-tests'; + beforeEach(function() { TestBed.configureTestingModule({ declarations: [ @@ -46,121 +47,44 @@ beforeEach(function() { }); }); -describe("basic support", function() { +function render(Component) { + const fixture = TestBed.createComponent(Component); + fixture.detectChanges(); + const el = fixture.debugElement.nativeElement; + const wc = el.querySelector('#wc'); + return { wc, fixture } +} - describe("no children", function() { - it("can display a Custom Element with no children", function() { - this.weight = 3; - let fixture = TestBed.createComponent(ComponentWithoutChildren); +tests({ + renderComponentWithoutChildren() { + return render(ComponentWithoutChildren); + }, + renderComponentWithChildren() { + return render(ComponentWithChildren); + }, + async renderComponentWithChildrenRerender() { + const results = render(ComponentWithChildrenRerender); + await new Promise((r) => setTimeout(r, 1000)); + results.fixture.detectChanges(); + return results; + }, + renderComponentWithDifferentViews() { + const { wc, fixture } = render(ComponentWithDifferentViews); + function toggle() { + fixture.componentInstance.toggle(); fixture.detectChanges(); - let el = fixture.debugElement.nativeElement; - let wc = el.querySelector("ce-without-children"); - expect(wc).to.exist; - }); - }); - - describe("with children", function() { - function expectHasChildren(wc) { - expect(wc).to.exist; - let shadowRoot = wc.shadowRoot; - let heading = shadowRoot.querySelector("h1"); - expect(heading).to.exist; - expect(heading.textContent).to.eql("Test h1"); - let paragraph = shadowRoot.querySelector("p"); - expect(paragraph).to.exist; - expect(paragraph.textContent).to.eql("Test p"); } - - it("can display a Custom Element with children in a Shadow Root", function() { - this.weight = 3; - let fixture = TestBed.createComponent(ComponentWithChildren); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - expectHasChildren(wc); - }); - - it("can display a Custom Element with children in a Shadow Root and pass in Light DOM children", function( - done - ) { - this.weight = 3; - let fixture = TestBed.createComponent(ComponentWithChildrenRerender); - fixture.detectChanges(); - setTimeout(function() { - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - expectHasChildren(wc); - expect(wc.textContent.includes("2")).to.be.true; - done(); - }, 1000); - }); - - it("can display a Custom Element with children in a Shadow Root and handle hiding and showing the element", function() { - this.weight = 3; - let fixture = TestBed.createComponent(ComponentWithDifferentViews); - fixture.detectChanges(); - let component = fixture.componentInstance; - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - expectHasChildren(wc); - component.toggle(); - fixture.detectChanges(); - let dummy = root.querySelector("#dummy"); - expect(dummy).to.exist; - expect(dummy.textContent).to.eql("Dummy view"); - component.toggle(); - fixture.detectChanges(); - wc = root.querySelector("#wc"); - expectHasChildren(wc); - }); - }); - - describe("attributes and properties", function() { - it("will pass boolean data as either an attribute or a property", function() { - this.weight = 3; - let fixture = TestBed.createComponent(ComponentWithProperties); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let data = wc.bool || wc.hasAttribute("bool"); - expect(data).to.be.true; - }); - - it("will pass numeric data as either an attribute or a property", function() { - this.weight = 3; - let fixture = TestBed.createComponent(ComponentWithProperties); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let data = wc.num || wc.getAttribute("num"); - expect(parseInt(data, 10)).to.eql(42); - }); - - it("will pass string data as either an attribute or a property", function() { - this.weight = 3; - let fixture = TestBed.createComponent(ComponentWithProperties); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let data = wc.str || wc.getAttribute("str"); - expect(data).to.eql("Angular"); - }); - }); - - describe("events", function() { - it("can imperatively listen to a DOM event dispatched by a Custom Element", function() { - this.weight = 3; - let fixture = TestBed.createComponent(ComponentWithImperativeEvent); - fixture.detectChanges(); - let root = fixture.debugElement.nativeElement; - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#handled"); - expect(handled.textContent).to.eql("false"); + return { wc, fixture, toggle } + }, + renderComponentWithProperties() { + return render(ComponentWithProperties); + }, + renderComponentWithImperativeEvent() { + const { wc, fixture } = render(ComponentWithImperativeEvent); + function click() { wc.click(); fixture.detectChanges(); - expect(handled.textContent).to.eql("true"); - }); - }); - + } + return { wc, fixture, click }; + } }); diff --git a/libraries/angular/src/components.ts b/libraries/angular/src/components.ts index fbb4cfe45e..ba1a5f59cd 100644 --- a/libraries/angular/src/components.ts +++ b/libraries/angular/src/components.ts @@ -98,9 +98,9 @@ export class ComponentWithProperties { data = { bool: true, num: 42, - str: 'Angular', - arr: ['A', 'n', 'g', 'u', 'l', 'a', 'r'], - obj: { org: 'angular', repo: 'angular' }, + str: 'custom', + arr: ['c', 'u', 's', 't', 'o', 'm'], + obj: { org: 'webcomponents', repo: 'custom-elements-everywhere' }, camelCaseObj: { label: "passed" } } } From 40904adff466f7d60032374b4333ae974fb14c9f Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Sun, 29 Dec 2024 16:33:16 +0000 Subject: [PATCH 4/8] +vue --- .../__shared__/tests/src/advanced-tests.js | 10 +- libraries/__shared__/tests/src/basic-tests.js | 6 +- libraries/vue/karma.conf.js | 1 + libraries/vue/src/advanced-tests.js | 128 ++---------- libraries/vue/src/basic-tests.js | 187 ++++-------------- libraries/vue/src/components.js | 6 +- 6 files changed, 73 insertions(+), 265 deletions(-) diff --git a/libraries/__shared__/tests/src/advanced-tests.js b/libraries/__shared__/tests/src/advanced-tests.js index 201fc23475..844119f0a3 100644 --- a/libraries/__shared__/tests/src/advanced-tests.js +++ b/libraries/__shared__/tests/src/advanced-tests.js @@ -63,7 +63,7 @@ export default function ( expect(wc).to.exist let handled = document.querySelector('#lowercase') expect(handled.textContent).to.eql('false') - click() + await click() expect(handled.textContent).to.eql('true') }) @@ -72,7 +72,7 @@ export default function ( const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#kebab') expect(handled.textContent).to.eql('false') - click() + await click() expect(handled.textContent).to.eql('true') }) @@ -81,7 +81,7 @@ export default function ( const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#camel') expect(handled.textContent).to.eql('false') - click() + await click() expect(handled.textContent).to.eql('true') }) @@ -90,7 +90,7 @@ export default function ( const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#caps') expect(handled.textContent).to.eql('false') - click() + await click() expect(handled.textContent).to.eql('true') }) @@ -99,7 +99,7 @@ export default function ( const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) let handled = document.querySelector('#pascal') expect(handled.textContent).to.eql('false') - click() + await click() expect(handled.textContent).to.eql('true') }) }) diff --git a/libraries/__shared__/tests/src/basic-tests.js b/libraries/__shared__/tests/src/basic-tests.js index 8b667b5f44..3d03642d54 100644 --- a/libraries/__shared__/tests/src/basic-tests.js +++ b/libraries/__shared__/tests/src/basic-tests.js @@ -71,11 +71,11 @@ export default function ( this.weight = 3 const { wc, toggle } = await renderComponentWithDifferentViews.call(this); expectHasChildren(wc) - toggle() + await toggle() const dummy = document.querySelector('#dummy') expect(dummy).to.exist expect(dummy.textContent).to.eql('Dummy view') - toggle() + await toggle() expectHasChildren(wc) }) }) @@ -110,7 +110,7 @@ export default function ( expect(wc).to.exist let handled = document.querySelector('#handled') expect(handled.textContent).to.eql('false') - click() + await click() expect(handled.textContent).to.eql('true') }) }) diff --git a/libraries/vue/karma.conf.js b/libraries/vue/karma.conf.js index 16f2c07276..a16e94190c 100644 --- a/libraries/vue/karma.conf.js +++ b/libraries/vue/karma.conf.js @@ -61,6 +61,7 @@ module.exports = function(config) { resolve: { modules: [ path.resolve(__dirname, '../__shared__/webcomponents/src'), + path.resolve(__dirname, '../__shared__/tests/src'), path.resolve(__dirname, './node_modules') ], alias: { diff --git a/libraries/vue/src/advanced-tests.js b/libraries/vue/src/advanced-tests.js index d0f0b7c4f5..03a8223234 100644 --- a/libraries/vue/src/advanced-tests.js +++ b/libraries/vue/src/advanced-tests.js @@ -16,17 +16,8 @@ */ import {createApp, nextTick} from 'vue'; -import { - ComponentWithoutChildren, - ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithUnregistered, - ComponentWithImperativeEvent, - ComponentWithDeclarativeEvent -} from "./components"; -import { expect } from "chai"; +import {ComponentWithDeclarativeEvent, ComponentWithProperties} from "./components"; +import tests from 'advanced-tests'; const isCustomElement = (tagName) => { return window.customElements.get(tagName) !== undefined; @@ -48,106 +39,25 @@ afterEach(function() { scratch = null; }); -describe("advanced support", function() { - describe("attributes and properties", function() { - it("will pass array data as a property", function() { - this.weight = 2; - const app = createApp(ComponentWithProperties) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const data = wc.arr; - expect(data).to.eql(["V", "u", "e"]); - }); - - it("will pass object data as a property", function() { - this.weight = 2; - const app = createApp(ComponentWithProperties) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const data = wc.obj; - expect(data).to.eql({ org: "vuejs", repo: "vue" }); - }); - - it("will pass object data to a camelCase-named property", function() { - this.weight = 2; - const app = createApp(ComponentWithProperties) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const data = wc.camelCaseObj; - expect(data).to.eql({ label: "passed" }); - }); - - }); - - describe("events", function() { - it("can declaratively listen to a lowercase DOM event dispatched by a Custom Element", async function() { - this.weight = 2; - const app = createApp(ComponentWithDeclarativeEvent) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const handled = scratch.querySelector("#lowercase"); - expect(handled.textContent).to.eql("false"); - wc.click(); - await nextTick(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a kebab-case DOM event dispatched by a Custom Element", async function() { - this.weight = 1; - const app = createApp(ComponentWithDeclarativeEvent) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const handled = scratch.querySelector("#kebab"); - expect(handled.textContent).to.eql("false"); - wc.click(); - await nextTick(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a camelCase DOM event dispatched by a Custom Element", async function() { - this.weight = 1; - const app = createApp(ComponentWithDeclarativeEvent) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const handled = scratch.querySelector("#camel"); - expect(handled.textContent).to.eql("false"); - wc.click(); - await nextTick(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a CAPScase DOM event dispatched by a Custom Element", async function() { - this.weight = 1; - const app = createApp(ComponentWithDeclarativeEvent) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const handled = scratch.querySelector("#caps"); - expect(handled.textContent).to.eql("false"); - wc.click(); - await nextTick(); - expect(handled.textContent).to.eql("true"); - }); +function render(Component) { + const app = createApp(Component) + app.config.compilerOptions.isCustomElement = isCustomElement; + app.mount(scratch); + const wc = scratch.querySelector("#wc"); + return {wc} +} - it("can declaratively listen to a PascalCase DOM event dispatched by a Custom Element", async function() { - this.weight = 1; - const app = createApp(ComponentWithDeclarativeEvent) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const handled = scratch.querySelector("#pascal"); - expect(handled.textContent).to.eql("false"); +tests({ + renderComponentWithProperties() { + return render(ComponentWithProperties); + }, + renderComponentWithDeclarativeEvent() { + const { wc } = render(ComponentWithDeclarativeEvent); + async function click() { wc.click(); await nextTick(); - expect(handled.textContent).to.eql("true"); - }); - }); - + } + return { wc, click } + } }); diff --git a/libraries/vue/src/basic-tests.js b/libraries/vue/src/basic-tests.js index 4e3a33bcf2..5351180825 100644 --- a/libraries/vue/src/basic-tests.js +++ b/libraries/vue/src/basic-tests.js @@ -22,11 +22,8 @@ import { ComponentWithChildrenRerender, ComponentWithDifferentViews, ComponentWithProperties, - ComponentWithUnregistered, ComponentWithImperativeEvent, - ComponentWithDeclarativeEvent } from "./components"; -import { expect } from "chai"; // Setup the test harness. This will get cleaned out with every test. const container = document.createElement("div"); @@ -37,160 +34,60 @@ const isCustomElement = (tagName) => { return window.customElements.get(tagName) !== undefined; } -beforeEach(function() { +beforeEach(function () { scratch = document.createElement("div"); scratch.id = "scratch"; container.appendChild(scratch); }); -afterEach(function() { +afterEach(function () { container.innerHTML = ""; scratch = null; }); -describe("basic support", function() { +import tests from 'basic-tests'; - describe("no children", function() { - it("can display a Custom Element with no children", function() { - this.weight = 3; - const app = createApp(ComponentWithoutChildren) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - expect(wc).to.exist; - }); - }); - - describe("with children", function() { - function expectHasChildren(wc) { - expect(wc).to.exist; - const shadowRoot = wc.shadowRoot; - const heading = shadowRoot.querySelector("h1"); - expect(heading).to.exist; - expect(heading.textContent).to.eql("Test h1"); - const paragraph = shadowRoot.querySelector("p"); - expect(paragraph).to.exist; - expect(paragraph.textContent).to.eql("Test p"); - } - - it("can display a Custom Element with children in a Shadow Root", function() { - this.weight = 3; - const app = createApp(ComponentWithChildren) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - expectHasChildren(wc); - }); - - it("can display a Custom Element with children in a Shadow Root and pass in Light DOM children", async function() { - this.weight = 3; - const app = createApp(ComponentWithChildrenRerender) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - // Waits for the tick in ComponentWithChildrenRerender's mount function - await nextTick(); - // Waits for the increment inside that tick to appear in the DOM. - await nextTick(); - expectHasChildren(wc); - expect(wc.textContent.includes("2")).to.be.true; - }); +function render(Component) { + const app = createApp(Component) + app.config.compilerOptions.isCustomElement = isCustomElement; + app.mount(scratch); + const wc = scratch.querySelector("#wc"); + return {wc} +} - it("can display a Custom Element with children in the Shadow DOM and handle hiding and showing the element", async function() { - this.weight = 3; - const app = createApp(ComponentWithDifferentViews) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const toggler = scratch.querySelector('#toggler'); - let wc = scratch.querySelector("#wc"); - expectHasChildren(wc); - toggler.click(); - await nextTick(); - const dummy = scratch.querySelector("#dummy"); - expect(dummy).to.exist; - expect(dummy.textContent).to.eql("Dummy view"); +tests({ + renderComponentWithoutChildren() { + return render(ComponentWithoutChildren); + }, + renderComponentWithChildren() { + return render(ComponentWithChildren); + }, + async renderComponentWithChildrenRerender() { + const result = render(ComponentWithChildrenRerender); + // Waits for the tick in ComponentWithChildrenRerender's mount function + await nextTick(); + // Waits for the increment inside that tick to appear in the DOM. + await nextTick(); + return result; + }, + renderComponentWithProperties() { + return render(ComponentWithProperties); + }, + renderComponentWithDifferentViews() { + const { wc } = render(ComponentWithDifferentViews); + const toggler = scratch.querySelector('#toggler'); + async function toggle() { toggler.click(); await nextTick(); - wc = scratch.querySelector("#wc"); - expectHasChildren(wc); - }); - }); - - describe("attributes and properties", function() { - it("will pass boolean data as either an attribute or a property", function() { - this.weight = 3; - const app = createApp(ComponentWithProperties) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const data = wc.bool || wc.hasAttribute("bool"); - expect(data).to.be.true; - }); - - it("will pass numeric data as either an attribute or a property", function() { - this.weight = 3; - const app = createApp(ComponentWithProperties) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const data = wc.num || wc.getAttribute("num"); - expect(parseInt(data, 10)).to.eql(42); - }); - - it("will pass string data as either an attribute or a property", function() { - this.weight = 3; - const app = createApp(ComponentWithProperties) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const data = wc.str || wc.getAttribute("str"); - expect(data).to.eql("Vue"); - }); - - // it('will set boolean attributes on a Custom Element that has not already been defined and upgraded', function() { - // let root = new ComponentWithUnregistered().$mount(scratch).$el; - // let wc = root.querySelector('#wc'); - // expect(wc.hasAttribute('bool')).to.be.true; - // }); - - // it('will set numeric attributes on a Custom Element that has not already been defined and upgraded', function() { - // let root = new ComponentWithUnregistered().$mount(scratch).$el; - // let wc = root.querySelector('#wc'); - // expect(wc.getAttribute('num')).to.eql('42'); - // }); - - // it('will set string attributes on a Custom Element that has not already been defined and upgraded', function() { - // let root = new ComponentWithUnregistered().$mount(scratch).$el; - // let wc = root.querySelector('#wc'); - // expect(wc.getAttribute('str')).to.eql('Vue'); - // }); - - // it('will set array properties on a Custom Element that has not already been defined and upgraded', function() { - // let root = new ComponentWithUnregistered().$mount(scratch).$el; - // let wc = root.querySelector('#wc'); - // expect(wc.arr).to.eql(['V', 'u', 'e']); - // }); - - // it('will set object properties on a Custom Element that has not already been defined and upgraded', function() { - // let root = new ComponentWithUnregistered().$mount(scratch).$el; - // let wc = root.querySelector('#wc'); - // expect(wc.obj).to.eql({ org: 'vuejs', repo: 'vue' }); - // }); - }); - - describe("events", function() { - it("can imperatively listen to a DOM event dispatched by a Custom Element", async function() { - this.weight = 3; - const app = createApp(ComponentWithImperativeEvent) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - const handled = scratch.querySelector("#handled"); - expect(handled.textContent).to.eql("false"); + } + return { wc, toggle } + }, + renderComponentWithImperativeEvent() { + const { wc } = render(ComponentWithImperativeEvent); + async function click() { wc.click(); await nextTick(); - expect(handled.textContent).to.eql("true"); - }); - }); - -}); + } + return { wc, click } + } +}) diff --git a/libraries/vue/src/components.js b/libraries/vue/src/components.js index 9a4ac360b8..64f2cf6c66 100644 --- a/libraries/vue/src/components.js +++ b/libraries/vue/src/components.js @@ -92,9 +92,9 @@ export const ComponentWithProperties = defineComponent({ return { bool: true, num: 42, - str: 'Vue', - arr: ['V', 'u', 'e'], - obj: { org: 'vuejs', repo: 'vue' }, + str: 'custom', + arr: ['c', 'u', 's', 't', 'o', 'm'], + obj: { org: 'webcomponents', repo: 'custom-elements-everywhere' }, camelCaseObj: { label: "passed" } } } From d96979689b35065f7f36b328999eb723f9949154 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Mon, 30 Dec 2024 13:18:23 +0000 Subject: [PATCH 5/8] +angularjs --- .../__shared__/tests/src/advanced-tests.js | 20 +-- libraries/__shared__/tests/src/basic-tests.js | 8 +- libraries/angularjs/karma.conf.js | 1 + libraries/angularjs/src/advanced-tests.js | 118 +++----------- libraries/angularjs/src/basic-tests.js | 147 +++++------------- libraries/angularjs/src/components.js | 6 +- libraries/react/src/advanced-tests.js | 4 +- libraries/react/src/basic-tests.js | 4 +- 8 files changed, 84 insertions(+), 224 deletions(-) diff --git a/libraries/__shared__/tests/src/advanced-tests.js b/libraries/__shared__/tests/src/advanced-tests.js index 844119f0a3..6bd3cf9037 100644 --- a/libraries/__shared__/tests/src/advanced-tests.js +++ b/libraries/__shared__/tests/src/advanced-tests.js @@ -59,9 +59,9 @@ export default function ( describe('events', function () { it('can declaratively listen to a lowercase DOM event dispatched by a Custom Element', async function () { this.weight = 2 - const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) + const { wc, click = wc.click.bind(wc), root = document } = await renderComponentWithDeclarativeEvent.call(this) expect(wc).to.exist - let handled = document.querySelector('#lowercase') + let handled = root.querySelector('#lowercase') expect(handled.textContent).to.eql('false') await click() expect(handled.textContent).to.eql('true') @@ -69,8 +69,8 @@ export default function ( it('can declaratively listen to a kebab-case DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) - let handled = document.querySelector('#kebab') + const { wc, click = wc.click.bind(wc), root = document } = await renderComponentWithDeclarativeEvent.call(this) + let handled = root.querySelector('#kebab') expect(handled.textContent).to.eql('false') await click() expect(handled.textContent).to.eql('true') @@ -78,8 +78,8 @@ export default function ( it('can declaratively listen to a camelCase DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) - let handled = document.querySelector('#camel') + const { wc, click = wc.click.bind(wc), root = document } = await renderComponentWithDeclarativeEvent.call(this) + let handled = root.querySelector('#camel') expect(handled.textContent).to.eql('false') await click() expect(handled.textContent).to.eql('true') @@ -87,8 +87,8 @@ export default function ( it('can declaratively listen to a CAPScase DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) - let handled = document.querySelector('#caps') + const { wc, click = wc.click.bind(wc), root = document } = await renderComponentWithDeclarativeEvent.call(this) + let handled = root.querySelector('#caps') expect(handled.textContent).to.eql('false') await click() expect(handled.textContent).to.eql('true') @@ -96,8 +96,8 @@ export default function ( it('can declaratively listen to a PascalCase DOM event dispatched by a Custom Element', async function () { this.weight = 1 - const { wc, click = wc.click.bind(wc) } = await renderComponentWithDeclarativeEvent.call(this) - let handled = document.querySelector('#pascal') + const { wc, click = wc.click.bind(wc), root = document } = await renderComponentWithDeclarativeEvent.call(this) + let handled = root.querySelector('#pascal') expect(handled.textContent).to.eql('false') await click() expect(handled.textContent).to.eql('true') diff --git a/libraries/__shared__/tests/src/basic-tests.js b/libraries/__shared__/tests/src/basic-tests.js index 3d03642d54..ad2ac649c6 100644 --- a/libraries/__shared__/tests/src/basic-tests.js +++ b/libraries/__shared__/tests/src/basic-tests.js @@ -69,10 +69,10 @@ export default function ( it('can display a Custom Element with children in the Shadow DOM and handle hiding and showing the element', async function () { this.weight = 3 - const { wc, toggle } = await renderComponentWithDifferentViews.call(this); + const { wc, toggle, root = document } = await renderComponentWithDifferentViews.call(this); expectHasChildren(wc) await toggle() - const dummy = document.querySelector('#dummy') + const dummy = root.querySelector('#dummy') expect(dummy).to.exist expect(dummy.textContent).to.eql('Dummy view') await toggle() @@ -106,9 +106,9 @@ export default function ( describe('events', async function () { it('can imperatively listen to a DOM event dispatched by a Custom Element', async function () { this.weight = 3 - const { wc, click = wc.click.bind(wc) } = await renderComponentWithImperativeEvent.call(this) + const { wc, click = wc.click.bind(wc), root = document } = await renderComponentWithImperativeEvent.call(this) expect(wc).to.exist - let handled = document.querySelector('#handled') + let handled = root.querySelector('#handled') expect(handled.textContent).to.eql('false') await click() expect(handled.textContent).to.eql('true') diff --git a/libraries/angularjs/karma.conf.js b/libraries/angularjs/karma.conf.js index e08f34e8fa..cb73da098a 100644 --- a/libraries/angularjs/karma.conf.js +++ b/libraries/angularjs/karma.conf.js @@ -62,6 +62,7 @@ module.exports = function (config) { extensions: ['.js'], modules: [ path.resolve(__dirname, '../__shared__/webcomponents/src'), + path.resolve(__dirname, '../__shared__/tests/src'), path.resolve(__dirname, './node_modules') ] }, diff --git a/libraries/angularjs/src/advanced-tests.js b/libraries/angularjs/src/advanced-tests.js index f0b98d8949..b0f6333e7b 100644 --- a/libraries/angularjs/src/advanced-tests.js +++ b/libraries/angularjs/src/advanced-tests.js @@ -1,114 +1,40 @@ -import { expect } from "chai"; import prodApp from "./app.module"; -describe("advanced support", () => { +import tests from 'advanced-tests'; +describe('', function () { beforeEach(angular.mock.module(prodApp)); let compile; let scope; let interval; + beforeEach( inject(($compile, $rootScope, $interval) => { compile = $compile; - scope = $rootScope.$new(); + scope = $rootScope; interval = $interval; }) ); - describe("attributes and properties", () => { - const prep = el => { - return compile(el)(scope)[0]; + function render(component) { + const root = compile(component)(scope)[0]; + scope.$apply(); + const wc = root.querySelector('#wc'); + return { wc, root } + } + + tests({ + renderComponentWithProperties() { + return render('') + }, + renderComponentWithDeclarativeEvent() { + const { wc, root } = render(''); + function click() { + wc.click(); + scope.$digest(); + } + return { wc, click, root }; } - - it("will pass array data as a property", function() { - this.weight = 2; - let root = prep("") - scope.$digest() - let wc = root.querySelector('#wc') - let data = wc.arr; - expect(data).to.eql(['A', 'n', 'g', 'u', 'l', 'a', 'r']); - }); - - it("will pass object data as a property", function() { - this.weight = 2; - let root = prep("") - scope.$digest() - let wc = root.querySelector('#wc') - let data = wc.obj; - expect(data).to.eql({ org: "angular", repo: "angular" }); - }); - - it("will pass object data to a camelCase-named property", function() { - this.weight = 2; - let root = prep("") - scope.$digest() - let wc = root.querySelector('#wc') - let data = wc.camelCaseObj; - expect(data).to.eql({ label: "passed" }); - }); - }); - - describe("events", () => { - it("can declaratively listen to a lowercase DOM event dispatched by a Custom Element", function() { - this.weight = 2; - const root = compile("")(scope)[0]; - scope.$digest(); - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#lowercase"); - expect(handled.textContent).to.eql("false"); - wc.click(); - scope.$digest(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a kebab-case DOM event dispatched by a Custom Element", function() { - this.weight = 1; - const root = compile("")(scope)[0]; - scope.$digest(); - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#kebab"); - expect(handled.textContent).to.eql("false"); - wc.click(); - scope.$digest(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a camelCase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - const root = compile("")(scope)[0]; - scope.$digest(); - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#camel"); - expect(handled.textContent).to.eql("false"); - wc.click(); - scope.$digest(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a CAPScase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - const root = compile("")(scope)[0]; - scope.$digest(); - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#caps"); - expect(handled.textContent).to.eql("false"); - wc.click(); - scope.$digest(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a PascalCase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - const root = compile("")(scope)[0]; - scope.$digest(); - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#pascal"); - expect(handled.textContent).to.eql("false"); - wc.click(); - scope.$digest(); - expect(handled.textContent).to.eql("true"); - }); }); - }); diff --git a/libraries/angularjs/src/basic-tests.js b/libraries/angularjs/src/basic-tests.js index f90ff3ab43..11bfc09292 100644 --- a/libraries/angularjs/src/basic-tests.js +++ b/libraries/angularjs/src/basic-tests.js @@ -1,13 +1,15 @@ -import { expect } from "chai"; +import {expect} from "chai"; import prodApp from "./app.module"; -describe("basic support", () => { +import tests from 'basic-tests'; +describe('', function () { beforeEach(angular.mock.module(prodApp)); let compile; let scope; let interval; + beforeEach( inject(($compile, $rootScope, $interval) => { compile = $compile; @@ -16,115 +18,46 @@ describe("basic support", () => { }) ); - describe("no children", () => { - it("can display a CE with no children", function() { - this.weight = 3; - const comp = compile("")(scope); - const wc = comp[0].querySelector("ce-without-children"); - expect(wc).to.exist; - }); - }); - - describe("with children", () => { - const prep = el => { - return compile(el)(scope)[0]; - }; - function expectHasChildren(wc) { - expect(wc).to.exist; - let shadowRoot = wc.shadowRoot; - let heading = shadowRoot.querySelector("h1"); - expect(heading).to.exist; - expect(heading.textContent).to.eql("Test h1"); - let paragraph = shadowRoot.querySelector("p"); - expect(paragraph).to.exist; - expect(paragraph.textContent).to.eql("Test p"); - } - - it("can display a Custom Element with children in a Shadow Root", function() { - this.weight = 3; - const root = prep(""); - let wc = root.querySelector("#wc"); - expectHasChildren(wc); - }); - - it("can display a Custom Element with children in a Shadow Root and pass in Light DOM children", function() { - this.weight = 3; - const root = prep(""); + function render(component) { + const root = compile(component)(scope)[0]; + scope.$apply(); + const wc = root.querySelector('#wc'); + return { wc, root } + } + + tests({ + renderComponentWithoutChildren() { + return render('') + }, + renderComponentWithChildren() { + return render('') + }, + renderComponentWithChildrenRerender() { + const result = render(''); interval.flush(1000); - let wc = root.querySelector("#wc"); - expectHasChildren(wc); - expect(wc.textContent.includes("2")).to.be.true; - }); - - it("can display a Custom Element with children in a Shadow Root and handle hiding and showing the element", function() { - this.weight = 3; - scope.showWc = true; - const root = prep(``); - scope.$apply(); - let wc = root.querySelector("#wc"); - expectHasChildren(wc); - - scope.showWc = false; - scope.$apply(); - - let dummy = root.querySelector("#dummy"); - expect(dummy).to.exist; - expect(dummy.textContent).to.eql("Dummy view"); - + return result; + }, + renderComponentWithDifferentViews() { scope.showWc = true; - scope.$apply(); + const { wc, root } = render(''); - wc = root.querySelector("#wc"); - expectHasChildren(wc); - }); - }); - - describe("attributes and properties", function() { - let wc; - beforeEach(() => { - const comp = compile("")(scope); - scope.$digest(); - - wc = comp[0].querySelector("#wc"); - }); - - it("will pass boolean data as either an attribute or a property", function() { - this.weight = 3; - let data = wc.bool || wc.hasAttribute("bool"); - expect(data).to.be.true; - // Extra test to see if AngularJS just left its binding syntax on - // the attribute and didn't actually set anything :P - if (!wc.bool) { - data = wc.getAttribute("bool"); - expect(data.includes("{{")).to.be.false; + function toggle() { + scope.showWc = !scope.showWc; + scope.$apply(); } - }); - - it("will pass numeric data as either an attribute or a property", function() { - this.weight = 3; - let data = wc.num || wc.getAttribute("num"); - expect(parseInt(data, 10)).to.eql(42); - }); - it("will pass string data as either an attribute or a property", function() { - this.weight = 3; - let data = wc.str || wc.getAttribute("str"); - expect(data).to.eql("Angular"); - }); - }); - - describe("events", () => { - it("can imperatively listen to a DOM event dispatched by a Custom Element", function() { - this.weight = 3; - const root = compile("")(scope)[0]; - scope.$digest(); - let wc = root.querySelector("#wc"); - let handled = root.querySelector("#handled"); - expect(handled.textContent).to.eql("false"); - wc.click(); - scope.$digest(); - expect(handled.textContent).to.eql("true"); - }); + return { wc, toggle, root } + }, + renderComponentWithProperties() { + return render('') + }, + renderComponentWithImperativeEvent() { + const { wc, root } = render(''); + function click() { + wc.click(); + scope.$digest(); + } + return { wc, click, root }; + } }); - }); diff --git a/libraries/angularjs/src/components.js b/libraries/angularjs/src/components.js index f7f7a0f369..a45d0bd1a5 100644 --- a/libraries/angularjs/src/components.js +++ b/libraries/angularjs/src/components.js @@ -72,9 +72,9 @@ const ComponentWithProps = { angular.extend(this, { bool: true, num: 42, - str: 'Angular', - arr: ['A', 'n', 'g', 'u', 'l', 'a', 'r'], - obj: { org: 'angular', repo: 'angular' }, + str: 'custom', + arr: ['c', 'u', 's', 't', 'o', 'm'], + obj: { org: 'webcomponents', repo: 'custom-elements-everywhere' }, camelCaseObj: { label: "passed" } }); } diff --git a/libraries/react/src/advanced-tests.js b/libraries/react/src/advanced-tests.js index 1747f80fa6..c72e4e1beb 100644 --- a/libraries/react/src/advanced-tests.js +++ b/libraries/react/src/advanced-tests.js @@ -85,12 +85,12 @@ tests({ return render(ComponentWithProperties); }, renderComponentWithDeclarativeEvent() { - const { wc, root } = render(ComponentWithDeclarativeEvent) + const { wc } = render(ComponentWithDeclarativeEvent) function click() { act(() => { wc.click(); }); } - return { wc, root, click } + return { wc, click } } }) diff --git a/libraries/react/src/basic-tests.js b/libraries/react/src/basic-tests.js index 61ccaa93c8..2a10a35c1f 100644 --- a/libraries/react/src/basic-tests.js +++ b/libraries/react/src/basic-tests.js @@ -100,7 +100,7 @@ tests({ root.toggle(); }); } - return { wc, root, toggle } + return { wc, toggle } }, renderComponentWithImperativeEvent() { const { wc, root } = render(ComponentWithImperativeEvent) @@ -109,6 +109,6 @@ tests({ wc.click(); }); } - return { wc, root, click } + return { wc, click } } }); From ce2bb8f4ef29ead78618a7d37eaf531d542773a2 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Mon, 30 Dec 2024 13:28:31 +0000 Subject: [PATCH 6/8] +dio --- libraries/dio/karma.conf.js | 1 + libraries/dio/src/advanced-tests.js | 125 +++++------------------- libraries/dio/src/basic-tests.js | 141 ++++++++-------------------- libraries/dio/src/components.js | 6 +- 4 files changed, 66 insertions(+), 207 deletions(-) diff --git a/libraries/dio/karma.conf.js b/libraries/dio/karma.conf.js index e7c1a6115f..ce033f94d2 100644 --- a/libraries/dio/karma.conf.js +++ b/libraries/dio/karma.conf.js @@ -61,6 +61,7 @@ module.exports = function(config) { resolve: { modules: [ path.resolve(__dirname, '../__shared__/webcomponents/src'), + path.resolve(__dirname, '../__shared__/tests/src'), path.resolve(__dirname, './node_modules') ] }, diff --git a/libraries/dio/src/advanced-tests.js b/libraries/dio/src/advanced-tests.js index b8ed66cd9a..b27fd53504 100644 --- a/libraries/dio/src/advanced-tests.js +++ b/libraries/dio/src/advanced-tests.js @@ -15,18 +15,10 @@ * limitations under the License. */ -import { h, render } from "dio.js"; -import { expect } from "chai"; -import { - ComponentWithoutChildren, - ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithUnregistered, - ComponentWithImperativeEvent, - ComponentWithDeclarativeEvent -} from "./components"; +import {h, render} from "dio.js"; +import {ComponentWithDeclarativeEvent, ComponentWithProperties} from "./components"; + +import tests from 'advanced-tests'; // Setup the test harness. This will get cleaned out with every test. let app = document.createElement("div"); @@ -45,96 +37,23 @@ afterEach(function() { scratch = null; }); -describe("advanced support", function() { - - describe("attributes and properties", function() { - it("will pass array data as a property", function() { - this.weight = 2; - render(, scratch); - let wc = scratch.querySelector("#wc"); - let data = wc.arr; - expect(data).to.eql(["D", "I", "O"]); - }); - - it("will pass object data as a property", function() { - this.weight = 2; - render(, scratch); - let wc = scratch.querySelector("#wc"); - let data = wc.obj; - expect(data).to.eql({ org: "thysultan", repo: "dio.js" }); - }); - - it("will pass object data to a camelCase-named property", function() { - this.weight = 2; - render(, scratch); - let wc = scratch.querySelector("#wc"); - let data = wc.camelCaseObj; - expect(data).to.eql({ label: "passed" }); - }); - - }); - - describe("events", function() { - it("can declaratively listen to a lowercase DOM event dispatched by a Custom Element", function() { - this.weight = 2; - let component; - render( {component = instance}} />, scratch); - let wc = scratch.querySelector("#wc"); - expect(wc).to.exist; - let handled = scratch.querySelector("#lowercase"); - expect(handled.textContent).to.eql("false"); - wc.click(); - component.forceUpdate(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a kebab-case DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let component; - render( {component = instance}} />, scratch); - let wc = scratch.querySelector("#wc"); - let handled = scratch.querySelector("#kebab"); - expect(handled.textContent).to.eql("false"); - wc.click(); - component.forceUpdate(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a camelCase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let component; - render( {component = instance}} />, scratch); - let wc = scratch.querySelector("#wc"); - let handled = scratch.querySelector("#camel"); - expect(handled.textContent).to.eql("false"); - wc.click(); - component.forceUpdate(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a CAPScase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let component; - render( {component = instance}} />, scratch); - let wc = scratch.querySelector("#wc"); - let handled = scratch.querySelector("#caps"); - expect(handled.textContent).to.eql("false"); +function _render(Component) { + let component + render( component = instance} />, scratch), scratch; + const wc = scratch.querySelector("#wc"); + return { wc, component } +} + +tests({ + renderComponentWithProperties() { + return _render(ComponentWithProperties); + }, + renderComponentWithDeclarativeEvent() { + const { wc, component } = _render(ComponentWithDeclarativeEvent); + function click() { wc.click(); component.forceUpdate(); - expect(handled.textContent).to.eql("true"); - }); - - it("can declaratively listen to a PascalCase DOM event dispatched by a Custom Element", function() { - this.weight = 1; - let component; - render( {component = instance}} />, scratch); - let wc = scratch.querySelector("#wc"); - let handled = scratch.querySelector("#pascal"); - expect(handled.textContent).to.eql("false"); - wc.click(); - component.forceUpdate(); - expect(handled.textContent).to.eql("true"); - }); - }); - -}); + } + return { wc, click }; + } +}) \ No newline at end of file diff --git a/libraries/dio/src/basic-tests.js b/libraries/dio/src/basic-tests.js index 4c597a0e99..925743e52a 100644 --- a/libraries/dio/src/basic-tests.js +++ b/libraries/dio/src/basic-tests.js @@ -15,134 +15,73 @@ * limitations under the License. */ -import { h, render } from "dio.js"; -import { expect } from "chai"; +import {h, render} from "dio.js"; +import {expect} from "chai"; import { ComponentWithoutChildren, ComponentWithChildren, ComponentWithChildrenRerender, ComponentWithDifferentViews, ComponentWithProperties, - ComponentWithUnregistered, ComponentWithImperativeEvent, - ComponentWithDeclarativeEvent } from "./components"; +import tests from 'basic-tests'; + // Setup the test harness. This will get cleaned out with every test. let app = document.createElement("div"); app.id = "app"; document.body.appendChild(app); let scratch; // This will hold the actual element under test. -beforeEach(function() { +beforeEach(function () { scratch = document.createElement("div"); scratch.id = "scratch"; app.appendChild(scratch); }); -afterEach(function() { +afterEach(function () { app.innerHTML = ""; scratch = null; }); -describe("basic support", function() { - - describe("no children", function() { - it("can display a Custom Element with no children", function() { - this.weight = 3; - render(, scratch), scratch; - let wc = scratch.querySelector("#wc"); - expect(wc).to.exist; - }); - }); - - describe("with children", function() { - function expectHasChildren(wc) { - expect(wc).to.exist; - let shadowRoot = wc.shadowRoot; - let heading = shadowRoot.querySelector("h1"); - expect(heading).to.exist; - expect(heading.textContent).to.eql("Test h1"); - let paragraph = shadowRoot.querySelector("p"); - expect(paragraph).to.exist; - expect(paragraph.textContent).to.eql("Test p"); - } - - it("can display a Custom Element with children in a Shadow Root", function() { - this.weight = 3; - render(, scratch) - let wc = scratch.querySelector("#wc"); - expectHasChildren(wc); - }); - - it("can display a Custom Element with children in a Shadow Root and pass in Light DOM children", async function() { - this.weight = 3; - let component; - render( {component = instance}} />, scratch) - let wc = scratch.querySelector("#wc"); - await Promise.resolve(); - component.forceUpdate(); - expectHasChildren(wc); - expect(wc.textContent.includes("2")).to.be.true; - }); +function _render(Component) { + let component + render( component = instance} />, scratch), scratch; + const wc = scratch.querySelector("#wc"); + return { wc, component } +} - it("can display a Custom Element with children in the Shadow DOM and handle hiding and showing the element", function() { - this.weight = 3; - let component; - render( {component = instance}} />, scratch); - let wc = scratch.querySelector("#wc"); - expectHasChildren(wc); - component.toggle(); - component.forceUpdate(); - let dummy = scratch.querySelector("#dummy"); - expect(dummy).to.exist; - expect(dummy.textContent).to.eql("Dummy view"); +tests({ + renderComponentWithoutChildren() { + return _render(ComponentWithChildren); + }, + renderComponentWithChildren() { + return _render(ComponentWithChildren); + }, + async renderComponentWithChildrenRerender() { + const { wc, component } = _render(ComponentWithChildrenRerender); + await Promise.resolve(); + component.forceUpdate(); + return { wc } + }, + renderComponentWithDifferentViews() { + const { wc, component } = _render(ComponentWithDifferentViews); + function toggle() { component.toggle(); component.forceUpdate(); - wc = scratch.querySelector("#wc"); - expectHasChildren(wc); - }); - }); - - describe("attributes and properties", function() { - it("will pass boolean data as either an attribute or a property", function() { - this.weight = 3; - render(, scratch); - let wc = scratch.querySelector("#wc"); - let data = wc.bool || wc.hasAttribute("bool"); - expect(data).to.be.true; - }); - - it("will pass numeric data as either an attribute or a property", function() { - this.weight = 3; - render(, scratch); - let wc = scratch.querySelector("#wc"); - let data = wc.num || wc.getAttribute("num"); - expect(parseInt(data, 10)).to.eql(42); - }); - - it("will pass string data as either an attribute or a property", function() { - this.weight = 3; - render(, scratch); - let wc = scratch.querySelector("#wc"); - let data = wc.str || wc.getAttribute("str"); - expect(data).to.eql("DIO"); - }); - }); - - describe("events", function() { - it("can imperatively listen to a DOM event dispatched by a Custom Element", function() { - this.weight = 3; - let component - render( {component = instance}} />, scratch); - let wc = scratch.querySelector("#wc"); - expect(wc).to.exist; - let handled = scratch.querySelector("#handled"); - expect(handled.textContent).to.eql("false"); + } + return { wc, toggle } + }, + renderComponentWithProperties() { + return _render(ComponentWithProperties); + }, + renderComponentWithImperativeEvent() { + const { wc, component } = _render(ComponentWithImperativeEvent); + function click() { wc.click(); component.forceUpdate(); - expect(handled.textContent).to.eql("true"); - }); - }); - + } + return { wc, click }; + } }); diff --git a/libraries/dio/src/components.js b/libraries/dio/src/components.js index 78df469ca7..e9d60e2b3a 100644 --- a/libraries/dio/src/components.js +++ b/libraries/dio/src/components.js @@ -89,9 +89,9 @@ export class ComponentWithProperties extends Component { const data = { bool: true, num: 42, - str: 'DIO', - arr: ['D', 'I', 'O'], - obj: { org: 'thysultan', repo: 'dio.js' }, + str: 'custom', + arr: ['c', 'u', 's', 't', 'o', 'm'], + obj: { org: 'webcomponents', repo: 'custom-elements-everywhere' }, camelCaseObj: { label: "passed" } }; return ( From 7608c276be466bb2183fa7f84fdaa55ba286b8da Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Tue, 31 Dec 2024 13:58:31 +0000 Subject: [PATCH 7/8] Even less boilerplate --- libraries/angular/karma.conf.js | 4 +- libraries/angular/package.json | 2 +- libraries/angular/src/advanced-tests.js | 69 ----------- .../{src/basic-tests.js => tests.webpack.js} | 65 +++++++--- libraries/angular/tests.webpack.ts | 48 -------- libraries/angularjs/src/advanced-tests.js | 40 ------ libraries/angularjs/src/basic-tests.js | 63 ---------- libraries/angularjs/tests.webpack.js | 76 +++++++++++- libraries/dio/src/advanced-tests.js | 59 --------- libraries/dio/src/basic-tests.js | 87 ------------- libraries/dio/tests.webpack.js | 86 ++++++++++++- libraries/react/src/advanced-tests.js | 96 --------------- libraries/react/src/basic-tests.js | 114 ------------------ libraries/react/tests.webpack.js | 110 ++++++++++++++++- libraries/riot/src/advanced-tests.js | 58 --------- libraries/riot/src/basic-tests.js | 72 ----------- libraries/riot/tests.webpack.js | 66 +++++++++- libraries/vue/src/advanced-tests.js | 63 ---------- libraries/vue/src/basic-tests.js | 93 -------------- libraries/vue/tests.webpack.js | 91 +++++++++++++- 20 files changed, 467 insertions(+), 895 deletions(-) delete mode 100644 libraries/angular/src/advanced-tests.js rename libraries/angular/{src/basic-tests.js => tests.webpack.js} (58%) delete mode 100644 libraries/angular/tests.webpack.ts delete mode 100644 libraries/angularjs/src/advanced-tests.js delete mode 100644 libraries/angularjs/src/basic-tests.js delete mode 100644 libraries/dio/src/advanced-tests.js delete mode 100644 libraries/dio/src/basic-tests.js delete mode 100644 libraries/react/src/advanced-tests.js delete mode 100644 libraries/react/src/basic-tests.js delete mode 100644 libraries/riot/src/advanced-tests.js delete mode 100644 libraries/riot/src/basic-tests.js delete mode 100644 libraries/vue/src/advanced-tests.js delete mode 100644 libraries/vue/src/basic-tests.js diff --git a/libraries/angular/karma.conf.js b/libraries/angular/karma.conf.js index 5a35e4fc42..d7db2487f7 100644 --- a/libraries/angular/karma.conf.js +++ b/libraries/angular/karma.conf.js @@ -43,10 +43,10 @@ module.exports = function (config) { // RxJs. { pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false }, { pattern: 'node_modules/rxjs/**/*.js.map', included: false, watched: false }, - 'tests.webpack.ts' + 'tests.webpack.js' ], preprocessors: { - 'tests.webpack.ts': ['webpack', 'sourcemap'] // preprocess with webpack and our sourcemap loader + 'tests.webpack.js': ['webpack', 'sourcemap'] // preprocess with webpack and our sourcemap loader }, mime: { 'text/x-typescript': ['ts'] diff --git a/libraries/angular/package.json b/libraries/angular/package.json index 12a7f0b240..2ea5fe6a21 100644 --- a/libraries/angular/package.json +++ b/libraries/angular/package.json @@ -42,7 +42,7 @@ ], "files": [ "karma.conf.js", - "tests.webpack.ts", + "tests.webpack.js", "tsconfig.json", "src", "meta" diff --git a/libraries/angular/src/advanced-tests.js b/libraries/angular/src/advanced-tests.js deleted file mode 100644 index 2e7ea158b2..0000000000 --- a/libraries/angular/src/advanced-tests.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; -import { TestBed } from "@angular/core/testing"; -import { - ComponentWithoutChildren, - ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithUnregistered, - ComponentWithImperativeEvent, - ComponentWithDeclarativeEvent -} from "./components"; - -import tests from 'advanced-tests'; - -function render(Component) { - const fixture = TestBed.createComponent(Component); - fixture.detectChanges(); - const el = fixture.debugElement.nativeElement; - const wc = el.querySelector('#wc'); - return { wc, fixture } -} - -beforeEach(function() { - TestBed.configureTestingModule({ - declarations: [ - ComponentWithoutChildren, - ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithUnregistered, - ComponentWithImperativeEvent, - ComponentWithDeclarativeEvent - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] - }); -}); - -tests({ - renderComponentWithProperties() { - return render(ComponentWithProperties); - }, - renderComponentWithDeclarativeEvent() { - const { wc, fixture } = render(ComponentWithDeclarativeEvent); - function click() { - wc.click(); - fixture.detectChanges(); - } - return { wc, fixture, click }; - } -}); diff --git a/libraries/angular/src/basic-tests.js b/libraries/angular/tests.webpack.js similarity index 58% rename from libraries/angular/src/basic-tests.js rename to libraries/angular/tests.webpack.js index b895bbe8fe..3d158f21a5 100644 --- a/libraries/angular/src/basic-tests.js +++ b/libraries/angular/tests.webpack.js @@ -15,24 +15,45 @@ * limitations under the License. */ +import 'reflect-metadata/Reflect'; +import 'zone.js/dist/zone'; +import 'zone.js/dist/webapis-shadydom'; // https://github.com/angular/zone.js/pull/784 +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/proxy'; +import 'zone.js/dist/sync-test'; +import 'zone.js/dist/mocha-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; -import { TestBed } from "@angular/core/testing"; - import { - ComponentWithoutChildren, ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithUnregistered, - ComponentWithImperativeEvent, - ComponentWithDeclarativeEvent -} from "./components"; + ComponentWithChildrenRerender, ComponentWithDeclarativeEvent, + ComponentWithDifferentViews, ComponentWithImperativeEvent, + ComponentWithoutChildren, ComponentWithProperties, ComponentWithUnregistered +} from "./src/components"; + +import basicTests from "basic-tests"; +import advancedTests from "advanced-tests"; + + +// Prevent Karma from running prematurely. +__karma__.loaded = function () {}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Run basic and advanced tests through Karma -import tests from 'basic-tests'; beforeEach(function() { - TestBed.configureTestingModule({ + getTestBed().configureTestingModule({ declarations: [ ComponentWithoutChildren, ComponentWithChildren, @@ -48,14 +69,14 @@ beforeEach(function() { }); function render(Component) { - const fixture = TestBed.createComponent(Component); + const fixture = getTestBed().createComponent(Component); fixture.detectChanges(); const el = fixture.debugElement.nativeElement; const wc = el.querySelector('#wc'); return { wc, fixture } } -tests({ +const renderers = { renderComponentWithoutChildren() { return render(ComponentWithoutChildren); }, @@ -86,5 +107,19 @@ tests({ fixture.detectChanges(); } return { wc, fixture, click }; + }, + renderComponentWithDeclarativeEvent() { + const { wc, fixture } = render(ComponentWithDeclarativeEvent); + function click() { + wc.click(); + fixture.detectChanges(); + } + return { wc, fixture, click }; } -}); +}; + +basicTests(renderers); +advancedTests(renderers); + +// Finally, start Karma to run the tests. +__karma__.start(); diff --git a/libraries/angular/tests.webpack.ts b/libraries/angular/tests.webpack.ts deleted file mode 100644 index f16e8cb48d..0000000000 --- a/libraries/angular/tests.webpack.ts +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import 'reflect-metadata/Reflect'; -import 'zone.js/dist/zone'; -import 'zone.js/dist/webapis-shadydom'; // https://github.com/angular/zone.js/pull/784 -import 'zone.js/dist/long-stack-trace-zone'; -import 'zone.js/dist/proxy'; -import 'zone.js/dist/sync-test'; -import 'zone.js/dist/mocha-patch'; -import 'zone.js/dist/async-test'; -import 'zone.js/dist/fake-async-test'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; - -declare var __karma__: any; -declare var require: any; - -// Prevent Karma from running prematurely. -__karma__.loaded = function () {}; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); -// Run basic and advanced tests through Karma -require('./src/basic-tests.js'); -require('./src/advanced-tests.js'); -// Finally, start Karma to run the tests. -__karma__.start(); diff --git a/libraries/angularjs/src/advanced-tests.js b/libraries/angularjs/src/advanced-tests.js deleted file mode 100644 index b0f6333e7b..0000000000 --- a/libraries/angularjs/src/advanced-tests.js +++ /dev/null @@ -1,40 +0,0 @@ -import prodApp from "./app.module"; - -import tests from 'advanced-tests'; - -describe('', function () { - beforeEach(angular.mock.module(prodApp)); - - let compile; - let scope; - let interval; - - beforeEach( - inject(($compile, $rootScope, $interval) => { - compile = $compile; - scope = $rootScope; - interval = $interval; - }) - ); - - function render(component) { - const root = compile(component)(scope)[0]; - scope.$apply(); - const wc = root.querySelector('#wc'); - return { wc, root } - } - - tests({ - renderComponentWithProperties() { - return render('') - }, - renderComponentWithDeclarativeEvent() { - const { wc, root } = render(''); - function click() { - wc.click(); - scope.$digest(); - } - return { wc, click, root }; - } - }); -}); diff --git a/libraries/angularjs/src/basic-tests.js b/libraries/angularjs/src/basic-tests.js deleted file mode 100644 index 11bfc09292..0000000000 --- a/libraries/angularjs/src/basic-tests.js +++ /dev/null @@ -1,63 +0,0 @@ -import {expect} from "chai"; -import prodApp from "./app.module"; - -import tests from 'basic-tests'; - -describe('', function () { - beforeEach(angular.mock.module(prodApp)); - - let compile; - let scope; - let interval; - - beforeEach( - inject(($compile, $rootScope, $interval) => { - compile = $compile; - scope = $rootScope; - interval = $interval; - }) - ); - - function render(component) { - const root = compile(component)(scope)[0]; - scope.$apply(); - const wc = root.querySelector('#wc'); - return { wc, root } - } - - tests({ - renderComponentWithoutChildren() { - return render('') - }, - renderComponentWithChildren() { - return render('') - }, - renderComponentWithChildrenRerender() { - const result = render(''); - interval.flush(1000); - return result; - }, - renderComponentWithDifferentViews() { - scope.showWc = true; - const { wc, root } = render(''); - - function toggle() { - scope.showWc = !scope.showWc; - scope.$apply(); - } - - return { wc, toggle, root } - }, - renderComponentWithProperties() { - return render('') - }, - renderComponentWithImperativeEvent() { - const { wc, root } = render(''); - function click() { - wc.click(); - scope.$digest(); - } - return { wc, click, root }; - } - }); -}); diff --git a/libraries/angularjs/tests.webpack.js b/libraries/angularjs/tests.webpack.js index 7db7248ea2..70ceef43f1 100644 --- a/libraries/angularjs/tests.webpack.js +++ b/libraries/angularjs/tests.webpack.js @@ -17,7 +17,77 @@ import 'angular'; import 'angular-mocks'; +import prodApp from "./src/app.module"; -// Run basic and advanced tests through Karma -require('./src/basic-tests.js'); -require('./src/advanced-tests.js'); +import basicTests from "basic-tests"; +import advancedTests from "advanced-tests" + +describe('', function () { + beforeEach(angular.mock.module(prodApp)); + + let compile; + let scope; + let interval; + + beforeEach( + inject(($compile, $rootScope, $interval) => { + compile = $compile; + scope = $rootScope; + interval = $interval; + }) + ); + + function render(component) { + const root = compile(component)(scope)[0]; + scope.$apply(); + const wc = root.querySelector('#wc'); + return { wc, root } + } + + const renderers = { + renderComponentWithoutChildren() { + return render('') + }, + renderComponentWithChildren() { + return render('') + }, + renderComponentWithChildrenRerender() { + const result = render(''); + interval.flush(1000); + return result; + }, + renderComponentWithDifferentViews() { + scope.showWc = true; + const { wc, root } = render(''); + + function toggle() { + scope.showWc = !scope.showWc; + scope.$apply(); + } + + return { wc, toggle, root } + }, + renderComponentWithProperties() { + return render('') + }, + renderComponentWithImperativeEvent() { + const { wc, root } = render(''); + function click() { + wc.click(); + scope.$digest(); + } + return { wc, click, root }; + }, + renderComponentWithDeclarativeEvent() { + const { wc, root } = render(''); + function click() { + wc.click(); + scope.$digest(); + } + return { wc, click, root }; + } + }; + + basicTests(renderers); + advancedTests(renderers); +}); diff --git a/libraries/dio/src/advanced-tests.js b/libraries/dio/src/advanced-tests.js deleted file mode 100644 index b27fd53504..0000000000 --- a/libraries/dio/src/advanced-tests.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {h, render} from "dio.js"; -import {ComponentWithDeclarativeEvent, ComponentWithProperties} from "./components"; - -import tests from 'advanced-tests'; - -// Setup the test harness. This will get cleaned out with every test. -let app = document.createElement("div"); -app.id = "app"; -document.body.appendChild(app); -let scratch; // This will hold the actual element under test. - -beforeEach(function() { - scratch = document.createElement("div"); - scratch.id = "scratch"; - app.appendChild(scratch); -}); - -afterEach(function() { - app.innerHTML = ""; - scratch = null; -}); - -function _render(Component) { - let component - render( component = instance} />, scratch), scratch; - const wc = scratch.querySelector("#wc"); - return { wc, component } -} - -tests({ - renderComponentWithProperties() { - return _render(ComponentWithProperties); - }, - renderComponentWithDeclarativeEvent() { - const { wc, component } = _render(ComponentWithDeclarativeEvent); - function click() { - wc.click(); - component.forceUpdate(); - } - return { wc, click }; - } -}) \ No newline at end of file diff --git a/libraries/dio/src/basic-tests.js b/libraries/dio/src/basic-tests.js deleted file mode 100644 index 925743e52a..0000000000 --- a/libraries/dio/src/basic-tests.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {h, render} from "dio.js"; -import {expect} from "chai"; -import { - ComponentWithoutChildren, - ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithImperativeEvent, -} from "./components"; - -import tests from 'basic-tests'; - -// Setup the test harness. This will get cleaned out with every test. -let app = document.createElement("div"); -app.id = "app"; -document.body.appendChild(app); -let scratch; // This will hold the actual element under test. - -beforeEach(function () { - scratch = document.createElement("div"); - scratch.id = "scratch"; - app.appendChild(scratch); -}); - -afterEach(function () { - app.innerHTML = ""; - scratch = null; -}); - -function _render(Component) { - let component - render( component = instance} />, scratch), scratch; - const wc = scratch.querySelector("#wc"); - return { wc, component } -} - -tests({ - renderComponentWithoutChildren() { - return _render(ComponentWithChildren); - }, - renderComponentWithChildren() { - return _render(ComponentWithChildren); - }, - async renderComponentWithChildrenRerender() { - const { wc, component } = _render(ComponentWithChildrenRerender); - await Promise.resolve(); - component.forceUpdate(); - return { wc } - }, - renderComponentWithDifferentViews() { - const { wc, component } = _render(ComponentWithDifferentViews); - function toggle() { - component.toggle(); - component.forceUpdate(); - } - return { wc, toggle } - }, - renderComponentWithProperties() { - return _render(ComponentWithProperties); - }, - renderComponentWithImperativeEvent() { - const { wc, component } = _render(ComponentWithImperativeEvent); - function click() { - wc.click(); - component.forceUpdate(); - } - return { wc, click }; - } -}); diff --git a/libraries/dio/tests.webpack.js b/libraries/dio/tests.webpack.js index a42a8d9a9d..cb392042eb 100644 --- a/libraries/dio/tests.webpack.js +++ b/libraries/dio/tests.webpack.js @@ -15,6 +15,86 @@ * limitations under the License. */ -// Run basic and advanced tests through Karma -require('./src/basic-tests.js'); -require('./src/advanced-tests.js'); +import {h, render} from "dio.js"; +import { + ComponentWithoutChildren, + ComponentWithChildren, + ComponentWithChildrenRerender, + ComponentWithDifferentViews, + ComponentWithProperties, + ComponentWithImperativeEvent, + ComponentWithDeclarativeEvent +} from "./src/components"; + +import basicTests from 'basic-tests'; +import advancedTests from 'advanced-tests'; + + +// Setup the test harness. This will get cleaned out with every test. +let app = document.createElement("div"); +app.id = "app"; +document.body.appendChild(app); +let scratch; // This will hold the actual element under test. + +beforeEach(function () { + scratch = document.createElement("div"); + scratch.id = "scratch"; + app.appendChild(scratch); +}); + +afterEach(function () { + app.innerHTML = ""; + scratch = null; +}); + +function _render(Component) { + let component + render( component = instance} />, scratch), scratch; + const wc = scratch.querySelector("#wc"); + return { wc, component } +} + +const renderers = { + renderComponentWithoutChildren() { + return _render(ComponentWithoutChildren); + }, + renderComponentWithChildren() { + return _render(ComponentWithChildren); + }, + async renderComponentWithChildrenRerender() { + const { wc, component } = _render(ComponentWithChildrenRerender); + await Promise.resolve(); + component.forceUpdate(); + return { wc } + }, + renderComponentWithDifferentViews() { + const { wc, component } = _render(ComponentWithDifferentViews); + function toggle() { + component.toggle(); + component.forceUpdate(); + } + return { wc, toggle } + }, + renderComponentWithProperties() { + return _render(ComponentWithProperties); + }, + renderComponentWithImperativeEvent() { + const { wc, component } = _render(ComponentWithImperativeEvent); + function click() { + wc.click(); + component.forceUpdate(); + } + return { wc, click }; + }, + renderComponentWithDeclarativeEvent() { + const { wc, component } = _render(ComponentWithDeclarativeEvent); + function click() { + wc.click(); + component.forceUpdate(); + } + return { wc, click }; + } +}; + +basicTests(renderers); +advancedTests(renderers); \ No newline at end of file diff --git a/libraries/react/src/advanced-tests.js b/libraries/react/src/advanced-tests.js deleted file mode 100644 index c72e4e1beb..0000000000 --- a/libraries/react/src/advanced-tests.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from "react"; -import { createRoot } from "react-dom/client"; -import { act } from "react-dom/test-utils"; -import { expect } from "chai"; -import { - ComponentWithoutChildren, - ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithUnregistered, - ComponentWithImperativeEvent, - ComponentWithDeclarativeEvent -} from "./components"; - -import tests from 'advanced-tests'; - -// Setup the test harness. This will get cleaned out with every test. -let app = document.createElement("div"); -app.id = "app"; -document.body.appendChild(app); -let scratch; // This will hold the actual element under test. - -let reactRoot = null; - -before(() => { - window.IS_REACT_ACT_ENVIRONMENT = true; -}) - -after(() => { - window.IS_REACT_ACT_ENVIRONMENT = false; -}) - -beforeEach(function() { - scratch = document.createElement("div"); - scratch.id = "scratch"; - app.appendChild(scratch); - - reactRoot = createRoot(scratch); -}); - -afterEach(function() { - app.innerHTML = ""; - scratch = null; - - act(() => { - reactRoot.unmount(); - }); -}); - - -function render(Component) { - let root; - act(() => { - reactRoot.render( - { - root = current; - }} - /> - ); - }); - return {wc: root.wc, root} -} - -tests({ - renderComponentWithProperties() { - return render(ComponentWithProperties); - }, - renderComponentWithDeclarativeEvent() { - const { wc } = render(ComponentWithDeclarativeEvent) - function click() { - act(() => { - wc.click(); - }); - } - return { wc, click } - } -}) diff --git a/libraries/react/src/basic-tests.js b/libraries/react/src/basic-tests.js deleted file mode 100644 index 2a10a35c1f..0000000000 --- a/libraries/react/src/basic-tests.js +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from "react"; -import {createRoot} from "react-dom/client"; -import {act} from "react-dom/test-utils"; -import * as ReactDOM from "react-dom"; -import {expect} from "chai"; -import { - ComponentWithoutChildren, - ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithUnregistered, - ComponentWithImperativeEvent, - ComponentWithDeclarativeEvent, -} from "./components"; - -import tests from 'basic-tests'; - -// Setup the test harness. This will get cleaned out with every test. -let app = document.createElement("div"); -app.id = "app"; -document.body.appendChild(app); -let scratch; // This will hold the actual element under test. - -let reactRoot = null; - -before(() => { - window.IS_REACT_ACT_ENVIRONMENT = true; -}); - -beforeEach(function () { - scratch = document.createElement("div"); - scratch.id = "scratch"; - app.appendChild(scratch); - - reactRoot = createRoot(scratch); -}); - -afterEach(function () { - app.innerHTML = ""; - scratch = null; - - act(() => { - reactRoot.unmount(); - }); -}); - -function render(Component) { - let root; - act(() => { - reactRoot.render( - { - root = current; - }} - /> - ); - }); - return {wc: root.wc, root} -} - -tests({ - renderComponentWithoutChildren() { - return render(ComponentWithoutChildren); - }, - renderComponentWithChildren() { - return render(ComponentWithChildren); - }, - async renderComponentWithChildrenRerender() { - const results = render(ComponentWithChildrenRerender); - await act(async () => { - await Promise.resolve(); - }); - return results; - }, - renderComponentWithProperties() { - return render(ComponentWithProperties); - }, - renderComponentWithDifferentViews() { - const { wc, root } = render(ComponentWithDifferentViews); - function toggle() { - act(() => { - root.toggle(); - }); - } - return { wc, toggle } - }, - renderComponentWithImperativeEvent() { - const { wc, root } = render(ComponentWithImperativeEvent) - function click() { - act(() => { - wc.click(); - }); - } - return { wc, click } - } -}); diff --git a/libraries/react/tests.webpack.js b/libraries/react/tests.webpack.js index a42a8d9a9d..89b02fda0f 100644 --- a/libraries/react/tests.webpack.js +++ b/libraries/react/tests.webpack.js @@ -15,6 +15,110 @@ * limitations under the License. */ -// Run basic and advanced tests through Karma -require('./src/basic-tests.js'); -require('./src/advanced-tests.js'); +import React from "react"; +import {createRoot} from "react-dom/client"; +import {act} from "react-dom/test-utils"; +import { + ComponentWithoutChildren, + ComponentWithChildren, + ComponentWithChildrenRerender, + ComponentWithDifferentViews, + ComponentWithProperties, + ComponentWithImperativeEvent, + ComponentWithDeclarativeEvent, +} from "./src/components"; + +import basicTests from 'basic-tests'; +import advancedTests from 'advanced-tests'; + +// Setup the test harness. This will get cleaned out with every test. +let app = document.createElement("div"); +app.id = "app"; +document.body.appendChild(app); +let scratch; // This will hold the actual element under test. + +let reactRoot = null; + +before(() => { + window.IS_REACT_ACT_ENVIRONMENT = true; +}); + +beforeEach(function () { + scratch = document.createElement("div"); + scratch.id = "scratch"; + app.appendChild(scratch); + + reactRoot = createRoot(scratch); +}); + +afterEach(function () { + app.innerHTML = ""; + scratch = null; + + act(() => { + reactRoot.unmount(); + }); +}); + +function render(Component) { + let root; + act(() => { + reactRoot.render( + { + root = current; + }} + /> + ); + }); + return {wc: root.wc, root} +} + +const renderers = { + renderComponentWithoutChildren() { + return render(ComponentWithoutChildren); + }, + renderComponentWithChildren() { + return render(ComponentWithChildren); + }, + async renderComponentWithChildrenRerender() { + const results = render(ComponentWithChildrenRerender); + await act(async () => { + await Promise.resolve(); + }); + return results; + }, + renderComponentWithProperties() { + return render(ComponentWithProperties); + }, + renderComponentWithDifferentViews() { + const { wc, root } = render(ComponentWithDifferentViews); + function toggle() { + act(() => { + root.toggle(); + }); + } + return { wc, toggle } + }, + renderComponentWithImperativeEvent() { + const { wc, root } = render(ComponentWithImperativeEvent) + function click() { + act(() => { + wc.click(); + }); + } + return { wc, click } + }, + renderComponentWithDeclarativeEvent() { + const { wc } = render(ComponentWithDeclarativeEvent) + function click() { + act(() => { + wc.click(); + }); + } + return { wc, click } + } +} + +basicTests(renderers); +advancedTests(renderers); diff --git a/libraries/riot/src/advanced-tests.js b/libraries/riot/src/advanced-tests.js deleted file mode 100644 index 88e3ec8160..0000000000 --- a/libraries/riot/src/advanced-tests.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { expect } from 'chai' -import { component } from 'riot' -import { - ComponentWithProperties, - ComponentWithDeclarativeEvent, -} from './components' - -import tests from 'advanced-tests'; - -// Setup the test harness. This will get cleaned out with every test. -let app = document.createElement('div') -app.id = 'app' -document.body.appendChild(app) -let scratch // This will hold the actual element under test. - -beforeEach(function() { - scratch = document.createElement('div') - scratch.id = 'scratch' - app.appendChild(scratch) -}) - -afterEach(function() { - app.innerHTML = '' - scratch = null -}) - - -function render(Component) { - const el = component(Component)(scratch) - return {wc: scratch.querySelector('#wc'), el} -} - - -tests({ - renderComponentWithProperties() { - return render(ComponentWithProperties) - }, - renderComponentWithDeclarativeEvent() { - return render(ComponentWithDeclarativeEvent) - } -}) diff --git a/libraries/riot/src/basic-tests.js b/libraries/riot/src/basic-tests.js deleted file mode 100644 index 1a533e952a..0000000000 --- a/libraries/riot/src/basic-tests.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { component } from 'riot' -import { - ComponentWithoutChildren, - ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithImperativeEvent -} from './components' - -import tests from 'basic-tests'; - -// Setup the test harness. This will get cleaned out with every test. -let app = document.createElement('div') -app.id = 'app' -document.body.appendChild(app) -let scratch // This will hold the actual element under test. - -beforeEach(function() { - scratch = document.createElement('div') - scratch.id = 'scratch' - app.appendChild(scratch) -}) - -afterEach(function() { - app.innerHTML = '' - scratch = null -}) - -function render(Component) { - const el = component(Component)(scratch) - return {wc: scratch.querySelector('#wc'), el} -} - -tests({ - renderComponentWithoutChildren() { - return render(ComponentWithoutChildren) - }, - renderComponentWithChildren() { - return render(ComponentWithChildren) - }, - renderComponentWithChildrenRerender() { - return render(ComponentWithChildrenRerender) - }, - renderComponentWithDifferentViews() { - const {wc, el} = render(ComponentWithDifferentViews) - return {wc, el, toggle: () => el.toggle()} - }, - renderComponentWithProperties() { - return render(ComponentWithProperties) - }, - renderComponentWithImperativeEvent() { - return render(ComponentWithImperativeEvent) - } -}) diff --git a/libraries/riot/tests.webpack.js b/libraries/riot/tests.webpack.js index cf620e9bd9..d1bacdc985 100644 --- a/libraries/riot/tests.webpack.js +++ b/libraries/riot/tests.webpack.js @@ -15,6 +15,66 @@ * limitations under the License. */ -// Run basic and advanced tests through Karma -require('./src/basic-tests.js') -require('./src/advanced-tests.js') +import { component } from 'riot' +import { + ComponentWithoutChildren, + ComponentWithChildren, + ComponentWithChildrenRerender, + ComponentWithDifferentViews, + ComponentWithProperties, + ComponentWithImperativeEvent, + ComponentWithDeclarativeEvent +} from './src/components' + +import basicTests from 'basic-tests'; +import advancedTests from 'advanced-tests'; + +// Setup the test harness. This will get cleaned out with every test. +let app = document.createElement('div') +app.id = 'app' +document.body.appendChild(app) +let scratch // This will hold the actual element under test. + +beforeEach(function() { + scratch = document.createElement('div') + scratch.id = 'scratch' + app.appendChild(scratch) +}) + +afterEach(function() { + app.innerHTML = '' + scratch = null +}) + +function render(Component) { + const el = component(Component)(scratch) + return {wc: scratch.querySelector('#wc'), el} +} + +const renderers = { + renderComponentWithoutChildren() { + return render(ComponentWithoutChildren) + }, + renderComponentWithChildren() { + return render(ComponentWithChildren) + }, + renderComponentWithChildrenRerender() { + return render(ComponentWithChildrenRerender) + }, + renderComponentWithDifferentViews() { + const {wc, el} = render(ComponentWithDifferentViews) + return {wc, el, toggle: () => el.toggle()} + }, + renderComponentWithProperties() { + return render(ComponentWithProperties) + }, + renderComponentWithImperativeEvent() { + return render(ComponentWithImperativeEvent) + }, + renderComponentWithDeclarativeEvent() { + return render(ComponentWithDeclarativeEvent) + } +} + +basicTests(renderers); +advancedTests(renderers); \ No newline at end of file diff --git a/libraries/vue/src/advanced-tests.js b/libraries/vue/src/advanced-tests.js deleted file mode 100644 index 03a8223234..0000000000 --- a/libraries/vue/src/advanced-tests.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {createApp, nextTick} from 'vue'; -import {ComponentWithDeclarativeEvent, ComponentWithProperties} from "./components"; -import tests from 'advanced-tests'; - -const isCustomElement = (tagName) => { - return window.customElements.get(tagName) !== undefined; -} - -// Setup the test harness. This will get cleaned out with every test. -const container = document.createElement("div"); -document.body.appendChild(container); -let scratch; // This will hold the actual element under test. - -beforeEach(function() { - scratch = document.createElement("div"); - scratch.id = "scratch"; - container.appendChild(scratch); -}); - -afterEach(function() { - container.innerHTML = ""; - scratch = null; -}); - - -function render(Component) { - const app = createApp(Component) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - return {wc} -} - -tests({ - renderComponentWithProperties() { - return render(ComponentWithProperties); - }, - renderComponentWithDeclarativeEvent() { - const { wc } = render(ComponentWithDeclarativeEvent); - async function click() { - wc.click(); - await nextTick(); - } - return { wc, click } - } -}); diff --git a/libraries/vue/src/basic-tests.js b/libraries/vue/src/basic-tests.js deleted file mode 100644 index 5351180825..0000000000 --- a/libraries/vue/src/basic-tests.js +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @license - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {createApp, nextTick} from 'vue'; -import { - ComponentWithoutChildren, - ComponentWithChildren, - ComponentWithChildrenRerender, - ComponentWithDifferentViews, - ComponentWithProperties, - ComponentWithImperativeEvent, -} from "./components"; - -// Setup the test harness. This will get cleaned out with every test. -const container = document.createElement("div"); -document.body.appendChild(container); -let scratch; // This will hold the actual element under test. - -const isCustomElement = (tagName) => { - return window.customElements.get(tagName) !== undefined; -} - -beforeEach(function () { - scratch = document.createElement("div"); - scratch.id = "scratch"; - container.appendChild(scratch); -}); - -afterEach(function () { - container.innerHTML = ""; - scratch = null; -}); - -import tests from 'basic-tests'; - -function render(Component) { - const app = createApp(Component) - app.config.compilerOptions.isCustomElement = isCustomElement; - app.mount(scratch); - const wc = scratch.querySelector("#wc"); - return {wc} -} - -tests({ - renderComponentWithoutChildren() { - return render(ComponentWithoutChildren); - }, - renderComponentWithChildren() { - return render(ComponentWithChildren); - }, - async renderComponentWithChildrenRerender() { - const result = render(ComponentWithChildrenRerender); - // Waits for the tick in ComponentWithChildrenRerender's mount function - await nextTick(); - // Waits for the increment inside that tick to appear in the DOM. - await nextTick(); - return result; - }, - renderComponentWithProperties() { - return render(ComponentWithProperties); - }, - renderComponentWithDifferentViews() { - const { wc } = render(ComponentWithDifferentViews); - const toggler = scratch.querySelector('#toggler'); - async function toggle() { - toggler.click(); - await nextTick(); - } - return { wc, toggle } - }, - renderComponentWithImperativeEvent() { - const { wc } = render(ComponentWithImperativeEvent); - async function click() { - wc.click(); - await nextTick(); - } - return { wc, click } - } -}) diff --git a/libraries/vue/tests.webpack.js b/libraries/vue/tests.webpack.js index a42a8d9a9d..637970640b 100644 --- a/libraries/vue/tests.webpack.js +++ b/libraries/vue/tests.webpack.js @@ -15,6 +15,91 @@ * limitations under the License. */ -// Run basic and advanced tests through Karma -require('./src/basic-tests.js'); -require('./src/advanced-tests.js'); +import {createApp, nextTick} from 'vue'; +import { + ComponentWithoutChildren, + ComponentWithChildren, + ComponentWithChildrenRerender, + ComponentWithDifferentViews, + ComponentWithProperties, + ComponentWithImperativeEvent, ComponentWithDeclarativeEvent, +} from "./src/components"; + +// Setup the test harness. This will get cleaned out with every test. +const container = document.createElement("div"); +document.body.appendChild(container); +let scratch; // This will hold the actual element under test. + +const isCustomElement = (tagName) => { + return window.customElements.get(tagName) !== undefined; +} + +beforeEach(function () { + scratch = document.createElement("div"); + scratch.id = "scratch"; + container.appendChild(scratch); +}); + +afterEach(function () { + container.innerHTML = ""; + scratch = null; +}); + +import basicTests from 'basic-tests'; +import advancedTests from 'advanced-tests'; + +function render(Component) { + const app = createApp(Component) + app.config.compilerOptions.isCustomElement = isCustomElement; + app.mount(scratch); + const wc = scratch.querySelector("#wc"); + return {wc} +} + +const renderers = { + renderComponentWithoutChildren() { + return render(ComponentWithoutChildren); + }, + renderComponentWithChildren() { + return render(ComponentWithChildren); + }, + async renderComponentWithChildrenRerender() { + const result = render(ComponentWithChildrenRerender); + // Waits for the tick in ComponentWithChildrenRerender's mount function + await nextTick(); + // Waits for the increment inside that tick to appear in the DOM. + await nextTick(); + return result; + }, + renderComponentWithProperties() { + return render(ComponentWithProperties); + }, + renderComponentWithDifferentViews() { + const { wc } = render(ComponentWithDifferentViews); + const toggler = scratch.querySelector('#toggler'); + async function toggle() { + toggler.click(); + await nextTick(); + } + return { wc, toggle } + }, + renderComponentWithImperativeEvent() { + const { wc } = render(ComponentWithImperativeEvent); + async function click() { + wc.click(); + await nextTick(); + } + return { wc, click } + }, + renderComponentWithDeclarativeEvent() { + const { wc } = render(ComponentWithDeclarativeEvent); + async function click() { + wc.click(); + await nextTick(); + } + return { wc, click } + } +} + +basicTests(renderers); +advancedTests(renderers); From e66024f4788c162f1ac503e744f261c949844e76 Mon Sep 17 00:00:00 2001 From: Bill Collins Date: Thu, 7 Aug 2025 07:55:51 +0100 Subject: [PATCH 8/8] Count skip tests --- scripts/copy-and-verify-results.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/copy-and-verify-results.mjs b/scripts/copy-and-verify-results.mjs index d890101ae8..306bcf5d53 100644 --- a/scripts/copy-and-verify-results.mjs +++ b/scripts/copy-and-verify-results.mjs @@ -68,7 +68,7 @@ function compareResultsAgainstGoldens(library) { // A constant, to make sure that if we add/remove any tests, that we add that test to all // tested libraries. const numberOfTests = 32; - chai.assert.equal(actual.success + actual.failed, numberOfTests, `${library.name} has incorrect total tests`); + chai.assert.equal(actual.success + actual.failed + actual.skipped, numberOfTests, `${library.name} has incorrect total tests`); chai.assert.deepEqual(actual, expected, `${library.name} has incorrect deep results equal`); }