Skip to content

Commit 9c68a5d

Browse files
authored
Merge branch 'main' into marks
2 parents 43fa844 + df0e263 commit 9c68a5d

6 files changed

Lines changed: 112 additions & 129 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
{
5454
"path": "lib/index.js",
5555
"import": "{controller, attr, target, targets}",
56-
"limit": "1.64kb"
56+
"limit": "1.66kb"
5757
}
5858
]
5959
}

src/dasherize.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
export const dasherize = (str: unknown): string =>
2-
String(str)
2+
String(typeof str === 'symbol' ? str.description : str)
33
.replace(/([A-Z]($|[a-z]))/g, '-$1')
44
.replace(/--/g, '-')
55
.replace(/^-|-$/, '')
66
.toLowerCase()
7+
8+
export const mustDasherize = (str: unknown, type = 'property'): string => {
9+
const dashed = dasherize(str)
10+
if (!dashed.includes('-')) {
11+
throw new DOMException(`${type}: ${String(str)} is not a valid ${type} name`, 'SyntaxError')
12+
}
13+
return dashed
14+
}

test/dasherize.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ describe('dasherize', () => {
88
['FooBar', 'foo-bar'],
99
['autofocusWhenReady', 'autofocus-when-ready'],
1010
['URLBar', 'url-bar'],
11-
['ClipX', 'clip-x']
11+
['ClipX', 'clip-x'],
12+
[Symbol('helloWorld'), 'hello-world']
1213
]
1314

1415
tests.map(([input, output]) =>
15-
it(`transforms ${input} to ${output}`, () => expect(dasherize(input)).to.equal(output))
16+
it(`transforms ${String(input)} to ${output}`, () => expect(dasherize(input)).to.equal(output))
1617
)
1718
})

test/findtarget.ts

Lines changed: 0 additions & 124 deletions
This file was deleted.

test/target.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import {expect, fixture, html} from '@open-wc/testing'
2+
import {target, targets} from '../src/target.js'
3+
import {controller} from '../src/controller.js'
4+
5+
describe('Targetable', () => {
6+
@controller
7+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
8+
class TargetTestElement extends HTMLElement {
9+
@target foo
10+
bar = 'hello'
11+
@target baz
12+
@target qux
13+
@target shadow
14+
15+
@target bing
16+
@targets foos
17+
bars = 'hello'
18+
@target quxs
19+
@target shadows
20+
}
21+
22+
let instance
23+
beforeEach(async () => {
24+
instance = await fixture(html`<target-test>
25+
<target-test>
26+
<div id="el1" data-target="target-test.barfoo target-test.foobar"></div>
27+
<div id="el2" data-target="target-test.foo" data-targets="target-test.foos"></div>
28+
<div id="el3" data-target="target-test.bing"></div>
29+
</target-test>
30+
<div id="el4" data-target="target-test.foo" data-targets="target-test.foos"></div>
31+
<div id="el5" data-target="target-test.baz" data-targets="target-test.foos"></div>
32+
<div id="el6" data-target="target-test.bar target-test.bing"></div>
33+
<div id="el7" data-target="target-test.bazbaz"></div>
34+
<div id="el8" data-target="other-target.qux target-test.qux"></div>
35+
</target-test>`)
36+
})
37+
38+
describe('target', () => {
39+
it('returns the first element where closest tag is the controller', async () => {
40+
expect(instance).to.have.property('foo').exist.with.attribute('id', 'el4')
41+
expect(instance.querySelector('target-test')).to.have.property('foo').exist.with.attribute('id', 'el2')
42+
})
43+
44+
it('does not assign to non-target decorated properties', async () => {
45+
expect(instance).to.have.property('bar', 'hello')
46+
})
47+
48+
it('returns the first element that has the exact target name', async () => {
49+
expect(instance).to.have.property('baz').exist.with.attribute('id', 'el5')
50+
})
51+
52+
it('returns target when there are mutliple target values', async () => {
53+
expect(instance).to.have.property('bing').exist.with.attribute('id', 'el6')
54+
})
55+
56+
it('returns targets when there are mutliple target values with different controllers', async () => {
57+
expect(instance).to.have.property('qux').exist.with.attribute('id', 'el8')
58+
})
59+
60+
it('returns targets from the shadowRoot, if available', async () => {
61+
instance.attachShadow({mode: 'open'})
62+
const el = document.createElement('div')
63+
el.setAttribute('data-target', 'target-test.shadow')
64+
instance.shadowRoot.appendChild(el)
65+
expect(instance).to.have.property('shadow', el)
66+
})
67+
68+
it('prioritises shadowRoot targets over others', async () => {
69+
instance.attachShadow({mode: 'open'})
70+
const shadowEl = document.createElement('div')
71+
shadowEl.setAttribute('data-target', 'target-test.foo')
72+
instance.shadowRoot.appendChild(shadowEl)
73+
expect(instance).to.have.property('foo', shadowEl)
74+
})
75+
})
76+
77+
describe('targets', () => {
78+
it('returns all elements where closest tag is the controller', async () => {
79+
expect(instance).to.have.property('foos').with.lengthOf(2)
80+
expect(instance).to.have.nested.property('foos[0]').with.attribute('id', 'el4')
81+
expect(instance).to.have.nested.property('foos[1]').with.attribute('id', 'el5')
82+
})
83+
84+
it('returns all elements inside a shadow root', async () => {
85+
instance.attachShadow({mode: 'open'})
86+
const els = [document.createElement('div'), document.createElement('div'), document.createElement('div')]
87+
for (const el of els) el.setAttribute('data-targets', 'target-test.foos')
88+
instance.shadowRoot.append(...els)
89+
90+
expect(instance).to.have.property('foos').with.lengthOf(5)
91+
expect(instance).to.have.nested.property('foos[0]', els[0])
92+
expect(instance).to.have.nested.property('foos[1]', els[1])
93+
expect(instance).to.have.nested.property('foos[2]', els[2])
94+
expect(instance).to.have.nested.property('foos[3]').with.attribute('id', 'el4')
95+
expect(instance).to.have.nested.property('foos[4]').with.attribute('id', 'el5')
96+
})
97+
})
98+
})

web-test-runner.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import {esbuildPlugin} from '@web/dev-server-esbuild'
22

33
export default {
44
files: ['test/*'],
5-
plugins: [esbuildPlugin({ts: true})]
5+
plugins: [esbuildPlugin({ts: true, target: 'es2020'})]
66
}

0 commit comments

Comments
 (0)