(re, expectMatch, expectNoMatch = [], negationValid = true)
| 81 | {length: 127}, (v, i) => { return String.fromCharCode(i); }); |
| 82 | |
| 83 | function check(re, expectMatch, expectNoMatch = [], negationValid = true) { |
| 84 | if (expectNoMatch === undefined) { |
| 85 | const expectSet = new Set(expectMatch.map(val => { |
| 86 | return (typeof val == 'number') ? String(val) : val; })); |
| 87 | expectNoMatch = allAscii.filter(val => !expectSet.has(val)); |
| 88 | } |
| 89 | for (const match of expectMatch) { |
| 90 | assertTrue(re.test(match), `${re}.test(${match})`); |
| 91 | } |
| 92 | for (const noMatch of expectNoMatch) { |
| 93 | assertFalse(re.test(noMatch), `${re}.test(${noMatch})`); |
| 94 | } |
| 95 | if (!negationValid) { |
| 96 | // Negation of classes containing strings is an error. |
| 97 | const negated = `[^${re.source}]`; |
| 98 | assertThrows(() => { new RegExp(negated, `${re.flags}`); }, SyntaxError, |
| 99 | `Invalid regular expression: /${negated}/${re.flags}: ` + |
| 100 | `Negated character class may contain strings`); |
| 101 | } else { |
| 102 | // Nest the current RegExp in a negated class and check expectations are |
| 103 | // inversed. |
| 104 | const inverted = new RegExp(`[^${re.source}]`, re.flags); |
| 105 | for (const match of expectMatch) { |
| 106 | assertFalse(inverted.test(match), `${inverted}.test(${match})`); |
| 107 | } |
| 108 | for (const noMatch of expectNoMatch) { |
| 109 | assertTrue(inverted.test(noMatch), `${inverted}.test(${noMatch})`); |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | // Union with nested class |
| 115 | check( |
no test coverage detected