diff --git a/package.json b/package.json
index 036ca99..fd1dda9 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
"rules": {
"brace-style": "off",
"jest/expect-expect": "off",
+ "lines-around-comment": "off",
"comma-dangle": "off",
"no-unused-vars": [
2,
diff --git a/src/index.test.jsx b/src/index.test.jsx
index 00606eb..77b5b2d 100644
--- a/src/index.test.jsx
+++ b/src/index.test.jsx
@@ -4,248 +4,230 @@ import { useContext } from 'preact/hooks';
import { act } from 'preact/test-utils';
import registerElement from './index';
-function Clock({ time }) {
- return {time};
-}
+describe('web components', () => {
+ /** @type {HTMLDivElement} */
+ let root;
-registerElement(Clock, 'x-clock', ['time', 'custom-date']);
-
-it('renders ok, updates on attr change', () => {
- const root = document.createElement('div');
- const el = document.createElement('x-clock');
- el.setAttribute('time', '10:28:57 PM');
-
- root.appendChild(el);
- document.body.appendChild(root);
-
- assert.equal(
- root.innerHTML,
- '10:28:57 PM'
- );
-
- el.setAttribute('time', '11:01:10 AM');
-
- assert.equal(
- root.innerHTML,
- '11:01:10 AM'
- );
-
- document.body.removeChild(root);
-});
-
-it('passes property changes to props', () => {
- const root = document.createElement('div');
- const el = document.createElement('x-clock');
-
- el.time = '10:28:57 PM';
- assert.equal(el.time, '10:28:57 PM');
-
- root.appendChild(el);
- document.body.appendChild(root);
- assert.equal(
- root.innerHTML,
- '10:28:57 PM'
- );
-
- el.time = '11:01:10 AM';
- assert.equal(el.time, '11:01:10 AM');
-
- assert.equal(
- root.innerHTML,
- '11:01:10 AM'
- );
-
- document.body.removeChild(root);
-});
-
-function DummyButton({ onClick, text = 'click' }) {
- return ;
-}
-
-registerElement(DummyButton, 'x-dummy-button', ['onClick', 'text']);
-
-it('passes simple properties changes to props', () => {
- const root = document.createElement('div');
- const el = document.createElement('x-dummy-button');
-
- el.text = 'foo';
- assert.equal(el.text, 'foo');
-
- root.appendChild(el);
- document.body.appendChild(root);
- assert.equal(
- root.innerHTML,
- ''
- );
+ beforeEach(() => {
+ root = document.createElement('div');
+ document.body.appendChild(root);
+ });
- // Update
- el.text = 'bar';
- assert.equal(
- root.innerHTML,
- ''
- );
+ afterEach(() => {
+ document.body.removeChild(root);
+ });
- document.body.removeChild(root);
-});
+ function Clock({ time }) {
+ return {time};
+ }
-it('passes complex properties changes to props', () => {
- const root = document.createElement('div');
- const el = document.createElement('x-dummy-button');
+ registerElement(Clock, 'x-clock', ['time', 'custom-date']);
- let clicks = 0;
- const onClick = () => clicks++;
- el.onClick = onClick;
- assert.equal(el.onClick, onClick);
+ it('renders ok, updates on attr change', () => {
+ const el = document.createElement('x-clock');
+ el.setAttribute('time', '10:28:57 PM');
- root.appendChild(el);
- document.body.appendChild(root);
- assert.equal(
- root.innerHTML,
- ''
- );
+ root.appendChild(el);
+ assert.equal(
+ root.innerHTML,
+ '10:28:57 PM'
+ );
- act(() => {
- el.querySelector('button').click();
+ el.setAttribute('time', '11:01:10 AM');
+ assert.equal(
+ root.innerHTML,
+ '11:01:10 AM'
+ );
});
- assert.equal(clicks, 1);
- // Update
- let other = 0;
- el.onClick = () => other++;
- act(() => {
- el.querySelector('button').click();
+ describe('DOM properties', () => {
+ it('passes property changes to props', () => {
+ const el = document.createElement('x-clock');
+
+ el.time = '10:28:57 PM';
+ assert.equal(el.time, '10:28:57 PM');
+
+ root.appendChild(el);
+ assert.equal(
+ root.innerHTML,
+ '10:28:57 PM'
+ );
+
+ el.time = '11:01:10 AM';
+ assert.equal(el.time, '11:01:10 AM');
+
+ assert.equal(
+ root.innerHTML,
+ '11:01:10 AM'
+ );
+ });
+
+ function DummyButton({ onClick, text = 'click' }) {
+ return ;
+ }
+
+ registerElement(DummyButton, 'x-dummy-button', ['onClick', 'text']);
+
+ it('passes simple properties changes to props', () => {
+ const el = document.createElement('x-dummy-button');
+
+ el.text = 'foo';
+ assert.equal(el.text, 'foo');
+
+ root.appendChild(el);
+ assert.equal(
+ root.innerHTML,
+ ''
+ );
+
+ // Update
+ el.text = 'bar';
+ assert.equal(
+ root.innerHTML,
+ ''
+ );
+ });
+
+ it('passes complex properties changes to props', () => {
+ const el = document.createElement('x-dummy-button');
+
+ let clicks = 0;
+ const onClick = () => clicks++;
+ el.onClick = onClick;
+ assert.equal(el.onClick, onClick);
+
+ root.appendChild(el);
+ assert.equal(
+ root.innerHTML,
+ ''
+ );
+
+ act(() => {
+ el.querySelector('button').click();
+ });
+ assert.equal(clicks, 1);
+
+ // Update
+ let other = 0;
+ el.onClick = () => other++;
+ act(() => {
+ el.querySelector('button').click();
+ });
+ assert.equal(other, 1);
+ });
});
- assert.equal(other, 1);
- document.body.removeChild(root);
-});
-
-function Foo({ text, children }) {
- return (
-
- {children}
- {text}
-
- );
-}
-
-registerElement(Foo, 'x-foo', [], { shadow: true });
-
-it('renders slots as props with shadow DOM', () => {
- const root = document.createElement('div');
- const el = document.createElement('x-foo');
-
- // here is a slot
- const slot = document.createElement('span');
- slot.textContent = 'here is a slot';
- slot.slot = 'text';
- el.appendChild(slot);
-
- //
no slot
- const noSlot = document.createElement('div');
- noSlot.textContent = 'no slot';
- el.appendChild(noSlot);
- el.appendChild(slot);
-
- root.appendChild(el);
- document.body.appendChild(root);
-
- assert.equal(
- root.innerHTML,
- 'no slot
here is a slot'
- );
-
- const shadowHTML = document.querySelector('x-foo').shadowRoot.innerHTML;
- assert.equal(
- shadowHTML,
- 'here is a slot
'
- );
-
- document.body.removeChild(root);
-});
-
-const kebabName = 'custom-date-long-name';
-const camelName = 'customDateLongName';
-const lowerName = camelName.toLowerCase();
-function PropNameTransform(props) {
- return (
-
- {props[kebabName]} {props[lowerName]} {props[camelName]}
-
- );
-}
-registerElement(PropNameTransform, 'x-prop-name-transform', [
- kebabName,
- camelName,
-]);
-
-it('handles kebab-case attributes with passthrough', () => {
- const root = document.createElement('div');
- const el = document.createElement('x-prop-name-transform');
- el.setAttribute(kebabName, '11/11/2011');
- el.setAttribute(camelName, 'pretended to be camel');
-
- root.appendChild(el);
- document.body.appendChild(root);
-
- assert.equal(
- root.innerHTML,
- `11/11/2011 pretended to be camel 11/11/2011`
- );
-
- el.setAttribute(kebabName, '01/01/2001');
-
- assert.equal(
- root.innerHTML,
- `01/01/2001 pretended to be camel 01/01/2001`
- );
-
- document.body.removeChild(root);
-});
+ function Foo({ text, children }) {
+ return (
+
+ {children}
+ {text}
+
+ );
+ }
+
+ registerElement(Foo, 'x-foo', [], { shadow: true });
+
+ it('renders slots as props with shadow DOM', () => {
+ const el = document.createElement('x-foo');
+
+ // here is a slot
+ const slot = document.createElement('span');
+ slot.textContent = 'here is a slot';
+ slot.slot = 'text';
+ el.appendChild(slot);
+
+ // no slot
+ const noSlot = document.createElement('div');
+ noSlot.textContent = 'no slot';
+ el.appendChild(noSlot);
+ el.appendChild(slot);
+
+ root.appendChild(el);
+ assert.equal(
+ root.innerHTML,
+ 'no slot
here is a slot'
+ );
+
+ const shadowHTML = document.querySelector('x-foo').shadowRoot.innerHTML;
+ assert.equal(
+ shadowHTML,
+ 'here is a slot
'
+ );
+ });
-const Theme = createContext('light');
+ const kebabName = 'custom-date-long-name';
+ const camelName = 'customDateLongName';
+ const lowerName = camelName.toLowerCase();
+ function PropNameTransform(props) {
+ return (
+
+ {props[kebabName]} {props[lowerName]} {props[camelName]}
+
+ );
+ }
+ registerElement(PropNameTransform, 'x-prop-name-transform', [
+ kebabName,
+ camelName,
+ ]);
+
+ it('handles kebab-case attributes with passthrough', () => {
+ const el = document.createElement('x-prop-name-transform');
+ el.setAttribute(kebabName, '11/11/2011');
+ el.setAttribute(camelName, 'pretended to be camel');
+
+ root.appendChild(el);
+ assert.equal(
+ root.innerHTML,
+ `11/11/2011 pretended to be camel 11/11/2011`
+ );
+
+ el.setAttribute(kebabName, '01/01/2001');
+ assert.equal(
+ root.innerHTML,
+ `01/01/2001 pretended to be camel 01/01/2001`
+ );
+ });
-function DisplayTheme() {
- const theme = useContext(Theme);
- return Active theme: {theme}
;
-}
+ const Theme = createContext('light');
-registerElement(DisplayTheme, 'x-display-theme', [], { shadow: true });
+ function DisplayTheme() {
+ const theme = useContext(Theme);
+ return Active theme: {theme}
;
+ }
-function Parent({ children, theme = 'dark' }) {
- return (
-
- {children}
-
- );
-}
+ registerElement(DisplayTheme, 'x-display-theme', [], { shadow: true });
-registerElement(Parent, 'x-parent', ['theme'], { shadow: true });
+ function Parent({ children, theme = 'dark' }) {
+ return (
+
+ {children}
+
+ );
+ }
-it('passes context over custom element boundaries', async () => {
- const root = document.createElement('div');
- const el = document.createElement('x-parent');
+ registerElement(Parent, 'x-parent', ['theme'], { shadow: true });
- const noSlot = document.createElement('x-display-theme');
- el.appendChild(noSlot);
+ it('passes context over custom element boundaries', async () => {
+ const el = document.createElement('x-parent');
- root.appendChild(el);
- document.body.appendChild(root);
+ const noSlot = document.createElement('x-display-theme');
+ el.appendChild(noSlot);
- assert.equal(
- root.innerHTML,
- ''
- );
+ root.appendChild(el);
+ assert.equal(
+ root.innerHTML,
+ ''
+ );
- const getShadowHTML = () =>
- document.querySelector('x-display-theme').shadowRoot.innerHTML;
- assert.equal(getShadowHTML(), 'Active theme: dark
');
+ const getShadowHTML = () =>
+ document.querySelector('x-display-theme').shadowRoot.innerHTML;
+ assert.equal(getShadowHTML(), 'Active theme: dark
');
- // Trigger context update
- act(() => {
- el.setAttribute('theme', 'sunny');
+ // Trigger context update
+ act(() => {
+ el.setAttribute('theme', 'sunny');
+ });
+ assert.equal(getShadowHTML(), 'Active theme: sunny
');
});
- assert.equal(getShadowHTML(), 'Active theme: sunny
');
-
- document.body.removeChild(root);
});