@@ -176,14 +176,20 @@ describe("react-to-web-component 1", () => {
176
176
} )
177
177
178
178
it ( "options.props can specify and will convert the String attribute value into Number, Boolean, Array, and/or Object" , async ( ) => {
179
- expect . assertions ( 12 )
179
+ expect . assertions ( 18 )
180
180
181
181
type CastinProps = {
182
182
stringProp : string
183
183
numProp : number
184
184
floatProp : number
185
- trueProp : boolean
186
- falseProp : boolean
185
+ truePropWithValueTrue : boolean ,
186
+ truePropWithValueYes : boolean ,
187
+ truePropWithValueOne : boolean ,
188
+ truePropWithValueFive : boolean ,
189
+ truePropWithValueNine : boolean ,
190
+ falsePropWithValueFalse : boolean ,
191
+ falsePropWithValueNo : boolean ,
192
+ falsePropWithValueZero : boolean ,
187
193
arrayProp : any [ ]
188
194
objProp : object
189
195
}
@@ -194,17 +200,29 @@ describe("react-to-web-component 1", () => {
194
200
stringProp,
195
201
numProp,
196
202
floatProp,
197
- trueProp,
198
- falseProp,
203
+ truePropWithValueTrue,
204
+ truePropWithValueYes,
205
+ truePropWithValueOne,
206
+ truePropWithValueFive,
207
+ truePropWithValueNine,
208
+ falsePropWithValueFalse,
209
+ falsePropWithValueNo,
210
+ falsePropWithValueZero,
199
211
arrayProp,
200
212
objProp,
201
213
} : CastinProps ) {
202
214
global . castedValues = {
203
215
stringProp,
204
216
numProp,
205
217
floatProp,
206
- trueProp,
207
- falseProp,
218
+ truePropWithValueTrue,
219
+ truePropWithValueYes,
220
+ truePropWithValueOne,
221
+ truePropWithValueFive,
222
+ truePropWithValueNine,
223
+ falsePropWithValueFalse,
224
+ falsePropWithValueNo,
225
+ falsePropWithValueZero,
208
226
arrayProp,
209
227
objProp,
210
228
}
@@ -217,8 +235,14 @@ describe("react-to-web-component 1", () => {
217
235
stringProp : "string" ,
218
236
numProp : "number" ,
219
237
floatProp : "number" ,
220
- trueProp : "boolean" ,
221
- falseProp : "boolean" ,
238
+ truePropWithValueTrue : "boolean" ,
239
+ truePropWithValueYes : "boolean" ,
240
+ truePropWithValueOne : "boolean" ,
241
+ truePropWithValueFive : "boolean" ,
242
+ truePropWithValueNine : "boolean" ,
243
+ falsePropWithValueFalse : "boolean" ,
244
+ falsePropWithValueNo : "boolean" ,
245
+ falsePropWithValueZero : "boolean" ,
222
246
arrayProp : "json" ,
223
247
objProp : "json" ,
224
248
} ,
@@ -238,8 +262,14 @@ describe("react-to-web-component 1", () => {
238
262
string-prop="iloveyou"
239
263
num-prop="360"
240
264
float-prop="0.5"
241
- true-prop="true"
242
- false-prop="false"
265
+ true-prop-with-value-true="true"
266
+ true-prop-with-value-yes="yes"
267
+ true-prop-with-value-one="1"
268
+ true-prop-with-value-five="5"
269
+ true-prop-with-value-nine="9"
270
+ false-prop-with-value-false="false"
271
+ false-prop-with-value-no="no"
272
+ false-prop-with-value-zero="0"
243
273
array-prop='[true, 100.25, "👽", { "aliens": "welcome" }]'
244
274
obj-prop='{ "very": "object", "such": "wow!" }'
245
275
></attr-type-casting>
@@ -250,16 +280,28 @@ describe("react-to-web-component 1", () => {
250
280
stringProp,
251
281
numProp,
252
282
floatProp,
253
- trueProp,
254
- falseProp,
283
+ truePropWithValueTrue,
284
+ truePropWithValueYes,
285
+ truePropWithValueOne,
286
+ truePropWithValueFive,
287
+ truePropWithValueNine,
288
+ falsePropWithValueFalse,
289
+ falsePropWithValueNo,
290
+ falsePropWithValueZero,
255
291
arrayProp,
256
292
objProp,
257
293
} = global . castedValues
258
294
expect ( stringProp ) . toEqual ( "iloveyou" )
259
295
expect ( numProp ) . toEqual ( 360 )
260
296
expect ( floatProp ) . toEqual ( 0.5 )
261
- expect ( trueProp ) . toEqual ( true )
262
- expect ( falseProp ) . toEqual ( false )
297
+ expect ( truePropWithValueTrue ) . toEqual ( true )
298
+ expect ( truePropWithValueYes ) . toEqual ( true )
299
+ expect ( truePropWithValueOne ) . toEqual ( true )
300
+ expect ( truePropWithValueFive ) . toEqual ( true )
301
+ expect ( truePropWithValueNine ) . toEqual ( true )
302
+ expect ( falsePropWithValueFalse ) . toEqual ( false )
303
+ expect ( falsePropWithValueNo ) . toEqual ( false )
304
+ expect ( falsePropWithValueZero ) . toEqual ( false )
263
305
expect ( arrayProp . length ) . toEqual ( 4 )
264
306
expect ( arrayProp [ 0 ] ) . toEqual ( true )
265
307
expect ( arrayProp [ 1 ] ) . toEqual ( 100.25 )
@@ -269,6 +311,102 @@ describe("react-to-web-component 1", () => {
269
311
expect ( objProp . such ) . toEqual ( "wow!" )
270
312
} )
271
313
314
+ it ( "options.props handles HTML Boolean" , async ( ) => {
315
+ expect . assertions ( 11 )
316
+
317
+ type CastinProps = {
318
+ truePropPresent : boolean ,
319
+ truePropEmptyString : boolean ,
320
+ truePropWithValueEqualToName : boolean ,
321
+ falsePropAbsent : boolean ,
322
+ }
323
+
324
+ const global = window as any
325
+
326
+ function OptionsPropsTypeCasting ( {
327
+ truePropPresent,
328
+ truePropEmptyString,
329
+ truePropWithValueEqualToName,
330
+ falsePropAbsent,
331
+ } : CastinProps ) {
332
+ global . castedValues = {
333
+ truePropPresent,
334
+ truePropEmptyString,
335
+ truePropWithValueEqualToName,
336
+ falsePropAbsent,
337
+ }
338
+
339
+ return < > </ >
340
+ }
341
+
342
+ const WebOptionsPropsTypeCasting = r2wc ( OptionsPropsTypeCasting , {
343
+ props : {
344
+ truePropPresent : "boolean" ,
345
+ truePropEmptyString : "boolean" ,
346
+ truePropWithValueEqualToName : "boolean" ,
347
+ falsePropAbsent : "boolean" ,
348
+ } ,
349
+ } )
350
+
351
+ customElements . define ( "html-boolean-attr-type-casting" , WebOptionsPropsTypeCasting )
352
+
353
+ const body = document . body
354
+
355
+ console . error = function ( ...messages ) {
356
+ // propTypes will throw if any of the types passed into the underlying react component are wrong or missing
357
+ expect ( "propTypes should not have thrown" ) . toEqual ( messages . join ( "" ) )
358
+ }
359
+
360
+ body . innerHTML = `
361
+ <html-boolean-attr-type-casting
362
+ true-prop-present
363
+ true-prop-empty-string=""
364
+ true-prop-with-value-equal-to-name="true-html-prop-with-value-equal-to-name"
365
+ ></html-boolean-attr-type-casting>
366
+ `
367
+
368
+ await flushPromises ( )
369
+
370
+ expect ( global . castedValues . truePropPresent ,
371
+ 'Prop without value is cast to true on mount' ) . toEqual ( true )
372
+ expect ( global . castedValues . truePropEmptyString ,
373
+ 'Prop with value equal to empty string is cast to true on mount' ) . toEqual ( true )
374
+ expect ( global . castedValues . truePropWithValueEqualToName ,
375
+ 'Prop with value equal to attribute name is considered true on mount' ) . toEqual ( true )
376
+ expect ( global . castedValues . falsePropAbsent ,
377
+ 'Lack of prop is cast to false on mount' ) . toEqual ( false )
378
+
379
+ const element = body . querySelector ( 'html-boolean-attr-type-casting' ) !
380
+ expect ( element ) . toBeVisible ( ) ;
381
+
382
+ element . removeAttribute ( 'true-prop-present' ) ;
383
+ element . removeAttribute ( 'true-prop-empty-string' ) ;
384
+ element . removeAttribute ( 'true-prop-with-value-equal-to-name' ) ;
385
+ element . setAttribute ( 'false-prop-absent' , '' ) ;
386
+
387
+ await flushPromises ( ) ;
388
+
389
+ expect ( global . castedValues . truePropPresent ,
390
+ 'Prop without value is cast to false when attribute is removed' ) . toEqual ( false )
391
+ expect ( global . castedValues . truePropEmptyString ,
392
+ 'Prop with value equal to empty string is cast to false when attribute is removed' ) . toEqual ( false )
393
+ expect ( global . castedValues . truePropWithValueEqualToName ,
394
+ 'Prop with value equal to attribute name is cast to false when attribute is removed' ) . toEqual ( false )
395
+ expect ( global . castedValues . falsePropAbsent ,
396
+ 'Prop which attribute was absent on mount is cast to true when it appears' ) . toEqual ( true )
397
+
398
+ // @ts -ignore
399
+ element . falsePropAbsent = false ;
400
+
401
+ await flushPromises ( ) ;
402
+
403
+ expect ( element ,
404
+ 'Attribute of custom element is removed when property of custom element was set to false from outside' ) . not . toHaveAttribute ( 'false-prop-absent' )
405
+ expect ( global . castedValues . falsePropAbsent ,
406
+ 'Prop of React component is set to false when property of custom element was set to false from outside' ) . toEqual ( false )
407
+ } )
408
+
409
+
272
410
it ( "Props typed as Function convert the string value of attribute into global fn calls bound to the webcomponent instance" , async ( ) => {
273
411
expect . assertions ( 2 )
274
412
0 commit comments