11import { expect , fixture , html } from '@open-wc/testing'
2- import { initializeAttrs , defineObservedAttributes , attr } from '../src/attr.js'
3-
4- describe ( 'initializeAttrs' , ( ) => {
5- class InitializeAttrTestElement extends HTMLElement { }
6- window . customElements . define ( 'initialize-attr-test-element' , InitializeAttrTestElement )
2+ import { controller } from '../src/controller.js'
3+ import { attr } from '../src/attr.js'
4+
5+ describe ( 'Attr' , ( ) => {
6+ @controller
7+ class InitializeAttrTest extends HTMLElement {
8+ @attr foo = 'hello'
9+ bar = 1
10+ }
711
812 let instance
913 beforeEach ( async ( ) => {
10- instance = await fixture ( html `< initialize-attr-test-element /> ` )
14+ instance = await fixture ( html `< initialize-attr-test /> ` )
15+ } )
16+
17+ it ( 'does not error during creation' , ( ) => {
18+ document . createElement ( 'initialize-attr-test' )
19+ } )
20+
21+ it ( 'marks attrs as observedAttributes' , ( ) => {
22+ expect ( InitializeAttrTest . observedAttributes ) . to . eql ( [ 'data-foo' ] )
1123 } )
1224
1325 it ( 'creates a getter/setter pair for each given attr name' , ( ) => {
14- expect ( instance ) . to . not . have . ownPropertyDescriptor ( 'foo' )
15- initializeAttrs ( instance , [ 'foo' ] )
26+ expect ( instance . foo ) . to . equal ( 'hello' )
1627 expect ( instance ) . to . have . ownPropertyDescriptor ( 'foo' )
1728 } )
1829
30+ it ( 'sets the attribute to a previously defined value on the key' , ( ) => {
31+ expect ( instance . foo ) . to . equal ( 'hello' )
32+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-foo' )
33+ expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( 'hello' )
34+ } )
35+
1936 it ( 'reflects the `data-*` attribute name of the given key' , ( ) => {
20- initializeAttrs ( instance , [ 'foo' ] )
21- expect ( instance . foo ) . to . equal ( '' )
37+ expect ( instance . foo ) . to . equal ( 'hello' )
2238 instance . foo = 'bar'
23- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-foo' ] )
39+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-foo' )
2440 expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( 'bar' )
2541 instance . setAttribute ( 'data-foo' , 'baz' )
2642 expect ( instance . foo ) . to . equal ( 'baz' )
2743 } )
2844
2945 it ( 'sets the attribute to a previously defined value on the key' , ( ) => {
3046 instance . foo = 'hello'
31- initializeAttrs ( instance , [ 'foo' ] )
3247 expect ( instance . foo ) . to . equal ( 'hello' )
33- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-foo' ] )
48+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-foo' )
3449 expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( 'hello' )
3550 } )
3651
37- it ( 'prioritises the value in the attribute over the property' , ( ) => {
38- instance . foo = 'goodbye'
39- instance . setAttribute ( 'data-foo' , 'hello' )
40- initializeAttrs ( instance , [ 'foo' ] )
41- expect ( instance . foo ) . to . equal ( 'hello' )
42- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-foo' ] )
43- expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( 'hello' )
52+ it ( 'prioritises the value in the attribute over the property' , async ( ) => {
53+ instance = await fixture ( html `< initialize-attr-test data-foo ="goodbye " /> ` )
54+ expect ( instance . foo ) . to . equal ( 'goodbye' )
55+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-foo' )
56+ expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( 'goodbye' )
4457 } )
4558
4659 describe ( 'types' , ( ) => {
47- it ( 'infers number types from property and casts as number always' , ( ) => {
48- instance . foo = 1
49- initializeAttrs ( instance , [ 'foo' ] )
60+ it ( 'infers number types from property and casts as number always' , async ( ) => {
61+ @controller
62+ class NumberAttrTest extends HTMLElement {
63+ @attr foo = 1
64+ }
65+ expect ( NumberAttrTest ) . to . have . property ( 'observedAttributes' ) . include ( 'data-foo' )
66+ instance = await fixture ( html `< number-attr-test /> ` )
5067 expect ( instance . foo ) . to . equal ( 1 )
51- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-foo' ] )
68+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-foo' )
5269 expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( '1' )
5370 instance . setAttribute ( 'data-foo' , '7' )
5471 expect ( instance . foo ) . to . equal ( 7 )
@@ -62,11 +79,15 @@ describe('initializeAttrs', () => {
6279 expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( '3.14' )
6380 } )
6481
65- it ( 'infers boolean types from property and uses has/toggleAttribute' , ( ) => {
66- instance . foo = false
67- initializeAttrs ( instance , [ 'foo' ] )
82+ it ( 'infers boolean types from property and uses has/toggleAttribute' , async ( ) => {
83+ @controller
84+ class BooleanAttrTest extends HTMLElement {
85+ @attr foo = false
86+ }
87+ expect ( BooleanAttrTest ) . to . have . property ( 'observedAttributes' ) . include ( 'data-foo' )
88+ instance = await fixture ( html `< boolean-attr-test /> ` )
6889 expect ( instance . foo ) . to . equal ( false )
69- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ ] )
90+ expect ( instance . getAttributeNames ( ) ) . to . not . include ( 'data-foo' )
7091 expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( null )
7192 instance . setAttribute ( 'data-foo' , '7' )
7293 expect ( instance . foo ) . to . equal ( true )
@@ -78,166 +99,56 @@ describe('initializeAttrs', () => {
7899 expect ( instance . foo ) . to . equal ( false )
79100 instance . foo = '1'
80101 expect ( instance . foo ) . to . equal ( true )
81- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-foo' ] )
102+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-foo' )
82103 expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( '' )
83104 instance . foo = false
84- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ ] )
105+ expect ( instance . getAttributeNames ( ) ) . to . not . include ( 'data-foo' )
85106 } )
86107
87- it ( 'defaults to inferring string type for non-boolean non-number types' , ( ) => {
88- instance . foo = / ^ a r e g e x p $ /
89- initializeAttrs ( instance , [ 'foo' ] )
108+ it ( 'defaults to inferring string type for non-boolean non-number types' , async ( ) => {
109+ @controller
110+ class RegExpAttrTest extends HTMLElement {
111+ @attr foo = / ^ a r e g e x p $ /
112+ }
113+ expect ( RegExpAttrTest ) . to . have . property ( 'observedAttributes' ) . include ( 'data-foo' )
114+ instance = await fixture ( html `< reg-exp-attr-test /> ` )
90115 expect ( instance . foo ) . to . equal ( '/^a regexp$/' )
91- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-foo' ] )
116+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-foo' )
92117 expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( '/^a regexp$/' )
93118 } )
94119 } )
95120
96121 describe ( 'naming' , ( ) => {
97- it ( 'converts camel cased property names to their HTML dasherized equivalents' , ( ) => {
98- initializeAttrs ( instance , [ 'fooBarBazBing' ] )
99- expect ( instance . fooBarBazBing ) . to . equal ( '' )
100- instance . fooBarBazBing = 'bar'
101- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-foo-bar-baz-bing' ] )
102- } )
103-
104- it ( 'will intuitively dasherize acryonyms' , ( ) => {
105- initializeAttrs ( instance , [ 'URLBar' ] )
106- expect ( instance . URLBar ) . to . equal ( '' )
107- instance . URLBar = 'bar'
108- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-url-bar' ] )
109- } )
110-
111- it ( 'dasherizes cap suffixed names correctly' , ( ) => {
112- initializeAttrs ( instance , [ 'ClipX' ] )
113- expect ( instance . ClipX ) . to . equal ( '' )
114- instance . ClipX = 'bar'
115- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-clip-x' ] )
116- } )
117- } )
118-
119- describe ( 'class fields' , ( ) => {
120- class ClassFieldAttrTestElement extends HTMLElement {
121- foo = 1
122+ @controller
123+ class NamingAttrTest extends HTMLElement {
124+ @attr fooBarBazBing = 'a'
125+ @attr URLBar = 'b'
126+ @attr ClipX = 'c'
122127 }
123- customElements . define ( 'class-field-attr-test-element' , ClassFieldAttrTestElement )
124128
125129 beforeEach ( async ( ) => {
126- instance = await fixture ( html `< class-field- attr-test-element /> ` )
130+ instance = await fixture ( html `< naming- attr-test /> ` )
127131 } )
128132
129- it ( 'overrides any getters assigned in constructor (like class fields)' , ( ) => {
130- initializeAttrs ( instance , [ 'foo' ] )
131- instance . foo = 2
132- expect ( instance . foo ) . to . equal ( 2 )
133- expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( '2' )
134- instance . setAttribute ( 'data-foo' , '3' )
135- expect ( instance . foo ) . to . equal ( 3 )
133+ it ( 'converts camel cased property names to their HTML dasherized equivalents' , async ( ) => {
134+ expect ( NamingAttrTest ) . to . have . property ( 'observedAttributes' ) . include ( 'data-foo-bar-baz-bing' )
135+ expect ( instance . fooBarBazBing ) . to . equal ( 'a' )
136+ instance . fooBarBazBing = 'bar'
137+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-foo-bar-baz-bing' )
136138 } )
137139
138- it ( 'defaults to class field value attribute not present' , ( ) => {
139- initializeAttrs ( instance , [ 'foo' ] )
140- expect ( instance . foo ) . to . equal ( 1 )
141- expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( '1' )
140+ it ( 'will intuitively dasherize acryonyms' , async ( ) => {
141+ expect ( NamingAttrTest ) . to . have . property ( 'observedAttributes' ) . include ( 'data-url-bar' )
142+ expect ( instance . URLBar ) . to . equal ( 'b' )
143+ instance . URLBar = 'bar'
144+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-url-bar' )
142145 } )
143146
144- it ( 'ignores class field value if element has attribute already' , ( ) => {
145- instance . setAttribute ( 'data-foo' , '2 ')
146- initializeAttrs ( instance , [ 'foo' ] )
147- expect ( instance . foo ) . to . equal ( 2 )
148- expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( '2 ')
147+ it ( 'dasherizes cap suffixed names correctly' , async ( ) => {
148+ expect ( NamingAttrTest ) . to . have . property ( 'observedAttributes' ) . include ( 'data-clip-x ')
149+ expect ( instance . ClipX ) . to . equal ( 'c' )
150+ instance . ClipX = 'bar'
151+ expect ( instance . getAttributeNames ( ) ) . to . include ( 'data-clip-x ')
149152 } )
150153 } )
151154} )
152-
153- describe ( 'attr' , ( ) => {
154- class AttrTestElement extends HTMLElement {
155- @attr foo
156- @attr bar
157- }
158- window . customElements . define ( 'attr-test-element' , AttrTestElement )
159-
160- class ExtendedAttrTestElement extends AttrTestElement {
161- @attr baz
162- }
163- window . customElements . define ( 'extended-attr-test-element' , ExtendedAttrTestElement )
164-
165- let instance
166- beforeEach ( async ( ) => {
167- instance = await fixture ( html `< attr-test-element /> ` )
168- } )
169-
170- it ( 'populates the "default" list for initializeAttrs' , ( ) => {
171- instance . foo = 'hello'
172- initializeAttrs ( instance )
173- expect ( instance ) . to . have . property ( 'foo' , 'hello' )
174- expect ( instance ) . to . have . property ( 'bar' , '' )
175- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-foo' , 'data-bar' ] )
176- expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( 'hello' )
177- expect ( instance . getAttribute ( 'data-bar' ) ) . to . equal ( '' )
178- } )
179-
180- it ( 'includes attrs from extended elements' , async ( ) => {
181- instance = await fixture ( html `< extended-attr-test-element /> ` )
182- instance . bar = 'hello'
183- instance . baz = 'world'
184- initializeAttrs ( instance )
185- expect ( instance ) . to . have . property ( 'foo' , '' )
186- expect ( instance ) . to . have . property ( 'bar' , 'hello' )
187- expect ( instance ) . to . have . property ( 'baz' , 'world' )
188- expect ( instance . getAttributeNames ( ) ) . to . eql ( [ 'data-foo' , 'data-bar' , 'data-baz' ] )
189- expect ( instance . getAttribute ( 'data-foo' ) ) . to . equal ( '' )
190- expect ( instance . getAttribute ( 'data-bar' ) ) . to . equal ( 'hello' )
191- expect ( instance . getAttribute ( 'data-baz' ) ) . to . equal ( 'world' )
192- } )
193-
194- it ( 'can be initialized multiple times without error' , async ( ) => {
195- instance = await fixture ( html `< initialize-attr-test-element /> ` )
196- expect ( instance ) . to . not . have . ownPropertyDescriptor ( 'foo' )
197- initializeAttrs ( instance , [ 'foo' ] )
198- expect ( instance ) . to . have . ownPropertyDescriptor ( 'foo' )
199- initializeAttrs ( instance , [ 'foo' ] )
200- } )
201- } )
202-
203- describe ( 'defineObservedAttributes' , ( ) => {
204- it ( 'defines `observedAttributes` getter/setter on class' , ( ) => {
205- class TestElement extends HTMLElement { }
206- defineObservedAttributes ( TestElement )
207- expect ( TestElement ) . to . have . ownPropertyDescriptor ( 'observedAttributes' )
208- expect ( TestElement . observedAttributes ) . to . eql ( [ ] )
209- } )
210-
211- it ( 'can be set after definition' , ( ) => {
212- class TestElement extends HTMLElement { }
213- defineObservedAttributes ( TestElement )
214- TestElement . observedAttributes = [ 'a' , 'b' , 'c' ]
215- expect ( TestElement . observedAttributes ) . to . eql ( [ 'a' , 'b' , 'c' ] )
216- } )
217-
218- it ( 'will reflect values from attr calls' , ( ) => {
219- class TestElement extends HTMLElement {
220- @attr foo
221- }
222- defineObservedAttributes ( TestElement )
223- expect ( TestElement . observedAttributes ) . to . eql ( [ 'data-foo' ] )
224- } )
225-
226- it ( 'will reflect values even if set after definition' , ( ) => {
227- class TestElement extends HTMLElement {
228- @attr foo
229- }
230- defineObservedAttributes ( TestElement )
231- TestElement . observedAttributes = [ 'a' , 'b' , 'c' ]
232- expect ( TestElement . observedAttributes ) . to . eql ( [ 'data-foo' , 'a' , 'b' , 'c' ] )
233- } )
234-
235- it ( 'will reflect values from extended elements' , ( ) => {
236- class TestElement extends HTMLElement {
237- @attr foo
238- }
239- class ExtendedTestElement extends TestElement { }
240- defineObservedAttributes ( ExtendedTestElement )
241- expect ( ExtendedTestElement . observedAttributes ) . to . eql ( [ 'data-foo' ] )
242- } )
243- } )
0 commit comments