@@ -137,7 +137,7 @@ function parseAssertCssFalse(parser) {
137
137
138
138
function parseAssertObjPropertyInner ( parser , assertFalse , objName ) {
139
139
const elems = parser . elems ;
140
- const identifiers = [ 'CONTAINS' , 'ENDS_WITH' , 'STARTS_WITH' ] ;
140
+ const identifiers = [ 'CONTAINS' , 'ENDS_WITH' , 'STARTS_WITH' , 'NEAR' ] ;
141
141
142
142
if ( elems . length === 0 ) {
143
143
return { 'error' : 'expected a tuple or a JSON dict, found nothing' } ;
@@ -254,6 +254,27 @@ ENDS_WITH check)');
254
254
if (!String(${ objName } [${ varKey } ]).endsWith(${ varValue } )) {
255
255
nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + ${ objName } [${ varKey } ] + '\
256
256
\`) does not end with \`' + ${ varValue } + '\`');
257
+ }` ) ;
258
+ }
259
+ }
260
+ if ( enabled_checks [ 'NEAR' ] ) {
261
+ if ( assertFalse ) {
262
+ checks . push ( `\
263
+ if (Number.isNaN(${ objName } [${ varKey } ])) {
264
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + ${ objName } [${ varKey } ] + '\
265
+ \`) is NaN');
266
+ } else if (Math.abs(${ objName } [${ varKey } ] - ${ varValue } ) <= 1) {
267
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + ${ objName } [${ varKey } ] + '\
268
+ \`) is within 1 of \`' + ${ varValue } + '\`');
269
+ }` ) ;
270
+ } else {
271
+ checks . push ( `\
272
+ if (Number.isNaN(${ objName } [${ varKey } ])) {
273
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + ${ objName } [${ varKey } ] + '\
274
+ \`) is NaN');
275
+ } else if (Math.abs(${ objName } [${ varKey } ] - ${ varValue } ) > 1) {
276
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + ${ objName } [${ varKey } ] + '\
277
+ \`) is not within 1 of \`' + ${ varValue } + '\`');
257
278
}` ) ;
258
279
}
259
280
}
@@ -308,8 +329,8 @@ ${indentString(checks.join('\n'), 2)}
308
329
//
309
330
// * {"DOM property": "value"}
310
331
// * ({"DOM property": "value"})
311
- // * ({"DOM property": "value"}, CONTAINS|ENDS_WITH|STARTS_WITH)
312
- // * ({"DOM property": "value"}, [CONTAINS|ENDS_WITH|STARTS_WITH])
332
+ // * ({"DOM property": "value"}, CONTAINS|ENDS_WITH|STARTS_WITH|NEAR )
333
+ // * ({"DOM property": "value"}, [CONTAINS|ENDS_WITH|STARTS_WITH|NEAR ])
313
334
function parseAssertDocumentProperty ( parser ) {
314
335
return parseAssertObjPropertyInner ( parser , false , 'document' ) ;
315
336
}
@@ -318,8 +339,8 @@ function parseAssertDocumentProperty(parser) {
318
339
//
319
340
// * {"DOM property": "value"}
320
341
// * ({"DOM property": "value"})
321
- // * ({"DOM property": "value"}, CONTAINS|ENDS_WITH|STARTS_WITH)
322
- // * ({"DOM property": "value"}, [CONTAINS|ENDS_WITH|STARTS_WITH])
342
+ // * ({"DOM property": "value"}, CONTAINS|ENDS_WITH|STARTS_WITH|NEAR )
343
+ // * ({"DOM property": "value"}, [CONTAINS|ENDS_WITH|STARTS_WITH|NEAR ])
323
344
function parseAssertDocumentPropertyFalse ( parser ) {
324
345
return parseAssertObjPropertyInner ( parser , true , 'document' ) ;
325
346
}
@@ -328,8 +349,8 @@ function parseAssertDocumentPropertyFalse(parser) {
328
349
//
329
350
// * {"DOM property": "value"}
330
351
// * ({"DOM property": "value"})
331
- // * ({"DOM property": "value"}, CONTAINS|ENDS_WITH|STARTS_WITH)
332
- // * ({"DOM property": "value"}, [CONTAINS|ENDS_WITH|STARTS_WITH])
352
+ // * ({"DOM property": "value"}, CONTAINS|ENDS_WITH|STARTS_WITH|NEAR )
353
+ // * ({"DOM property": "value"}, [CONTAINS|ENDS_WITH|STARTS_WITH|NEAR ])
333
354
function parseAssertWindowProperty ( parser ) {
334
355
return parseAssertObjPropertyInner ( parser , false , 'window' ) ;
335
356
}
@@ -338,16 +359,16 @@ function parseAssertWindowProperty(parser) {
338
359
//
339
360
// * {"DOM property": "value"}
340
361
// * ({"DOM property": "value"})
341
- // * ({"DOM property": "value"}, CONTAINS|ENDS_WITH|STARTS_WITH)
342
- // * ({"DOM property": "value"}, [CONTAINS|ENDS_WITH|STARTS_WITH])
362
+ // * ({"DOM property": "value"}, CONTAINS|ENDS_WITH|STARTS_WITH|NEAR )
363
+ // * ({"DOM property": "value"}, [CONTAINS|ENDS_WITH|STARTS_WITH|NEAR ])
343
364
function parseAssertWindowPropertyFalse ( parser ) {
344
365
return parseAssertObjPropertyInner ( parser , true , 'window' ) ;
345
366
}
346
367
347
368
function parseAssertPropertyInner ( parser , assertFalse ) {
348
369
const err = 'Read the documentation to see the accepted inputs' ;
349
370
const elems = parser . elems ;
350
- const identifiers = [ 'ALL' , 'CONTAINS' , 'STARTS_WITH' , 'ENDS_WITH' ] ;
371
+ const identifiers = [ 'ALL' , 'CONTAINS' , 'STARTS_WITH' , 'ENDS_WITH' , 'NEAR' ] ;
351
372
const warnings = [ ] ;
352
373
const enabled_checks = Object . create ( null ) ;
353
374
@@ -432,6 +453,27 @@ ENDS_WITH check)');
432
453
if (!String(e[${ varKey } ]).endsWith(${ varValue } )) {
433
454
nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + e[${ varKey } ] + '\
434
455
\`) does not end with \`' + ${ varValue } + '\`');
456
+ }` ) ;
457
+ }
458
+ }
459
+ if ( enabled_checks [ 'NEAR' ] ) {
460
+ if ( assertFalse ) {
461
+ checks . push ( `\
462
+ if (Number.isNaN(e[${ varKey } ])) {
463
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + e[${ varKey } ] + '\
464
+ \`) is NaN');
465
+ } else if (Math.abs(e[${ varKey } ] - ${ varValue } ) <= 1) {
466
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + e[${ varKey } ] + '\
467
+ \`) is within 1 of \`' + ${ varValue } + '\`');
468
+ }` ) ;
469
+ } else {
470
+ checks . push ( `\
471
+ if (Number.isNaN(e[${ varKey } ])) {
472
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + e[${ varKey } ] + '\
473
+ \`) is NaN');
474
+ } else if (Math.abs(e[${ varKey } ] - ${ varValue } ) > 1) {
475
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + e[${ varKey } ] + '\
476
+ \`) is not within 1 of \`' + ${ varValue } + '\`');
435
477
}` ) ;
436
478
}
437
479
}
@@ -544,7 +586,7 @@ function parseAssertPropertyFalse(parser) {
544
586
function parseAssertAttributeInner ( parser , assertFalse ) {
545
587
const err = 'Read the documentation to see the accepted inputs' ;
546
588
const elems = parser . elems ;
547
- const identifiers = [ 'ALL' , 'CONTAINS' , 'STARTS_WITH' , 'ENDS_WITH' ] ;
589
+ const identifiers = [ 'ALL' , 'CONTAINS' , 'STARTS_WITH' , 'ENDS_WITH' , 'NEAR' ] ;
548
590
const warnings = [ ] ;
549
591
const enabled_checks = Object . create ( null ) ;
550
592
@@ -629,6 +671,27 @@ if (attr.endsWith(${varValue})) {
629
671
if (!attr.endsWith(${ varValue } )) {
630
672
nonMatchingAttrs.push("attribute \`" + ${ varKey } + "\` (\`" + attr + "\`) doesn't end with \`"\
631
673
+ ${ varValue } + "\`");
674
+ }` ) ;
675
+ }
676
+ }
677
+ if ( enabled_checks [ 'NEAR' ] ) {
678
+ if ( assertFalse ) {
679
+ checks . push ( `\
680
+ if (Number.isNaN(attr)) {
681
+ nonMatchingProps.push('attribute \`' + ${ varKey } + '\` (\`' + attr + '\
682
+ \`) is NaN');
683
+ } else if (Math.abs(attr] - ${ varValue } ) <= 1) {
684
+ nonMatchingProps.push('attribute \`' + ${ varKey } + '\` (\`' + attr + '\
685
+ \`) is within 1 of \`' + ${ varValue } '\`');
686
+ }` ) ;
687
+ } else {
688
+ checks . push ( `\
689
+ if (Number.isNaN(attr)) {
690
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + attr + '\
691
+ \`) is NaN');
692
+ } else if (Math.abs(attr - ${ varValue } ) > 1) {
693
+ nonMatchingProps.push('Property \`' + ${ varKey } + '\` (\`' + attr + '\
694
+ \`) is not within 1 of \`' + ${ varValue } '\`');
632
695
}` ) ;
633
696
}
634
697
}
@@ -1264,7 +1327,7 @@ function parseAssertVariableInner(parser, assertFalse) {
1264
1327
${ tuple [ 1 ] . getArticleKind ( ) } (\`${ tuple [ 1 ] . getErrorText ( ) } \`)`,
1265
1328
} ;
1266
1329
} else if ( tuple . length > 2 ) {
1267
- const identifiers = [ 'CONTAINS' , 'STARTS_WITH' , 'ENDS_WITH' ] ;
1330
+ const identifiers = [ 'CONTAINS' , 'STARTS_WITH' , 'ENDS_WITH' , 'NEAR' ] ;
1268
1331
const ret = fillEnabledChecks ( tuple [ 2 ] , identifiers , enabled_checks , warnings , 'third' ) ;
1269
1332
if ( ret !== null ) {
1270
1333
return ret ;
@@ -1309,6 +1372,23 @@ if (value1.endsWith(value2)) {
1309
1372
checks . push ( `\
1310
1373
if (!value1.endsWith(value2)) {
1311
1374
errors.push("\`" + value1 + "\` doesn't end with \`" + value2 + "\` (for ENDS_WITH check)");
1375
+ }` ) ;
1376
+ }
1377
+ }
1378
+ if ( enabled_checks [ 'NEAR' ] ) {
1379
+ if ( assertFalse ) {
1380
+ checks . push ( `\
1381
+ if (Number.isNaN(value1])) {
1382
+ nonMatchingProps.push('\`' + value1 + '\` is NaN');
1383
+ } else if (Math.abs(value1 - value2) <= 1) {
1384
+ nonMatchingProps.push('\`' + value1 + '\` is within 1 of \`' + value2 '\`');
1385
+ }` ) ;
1386
+ } else {
1387
+ checks . push ( `\
1388
+ if (Number.isNaN(value1])) {
1389
+ nonMatchingProps.push('\`' + value1 + '\` is NaN');
1390
+ } else if (Math.abs(value1 - value2) > 1) {
1391
+ nonMatchingProps.push('\`' + value1 + '\` is not within 1 of \`' + value2 '\`');
1312
1392
}` ) ;
1313
1393
}
1314
1394
}
0 commit comments