Skip to content

Commit

Permalink
Add tests for <input pattern> enabling the RegExp v flag
Browse files Browse the repository at this point in the history
  • Loading branch information
mathiasbynens committed Apr 3, 2023
1 parent 680ad01 commit 7640b5b
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
{conditions: {pattern: null, value: "abc"}, expected: false, name: "[target] The pattern attribute is not set"},
{conditions: {pattern: "[A-Z]+", value: ""}, expected: false, name: "[target] The value attibute is empty string"},
{conditions: {pattern: "[A-Z]{1}", value: "A"}, expected: false, name: "[target] The value attribute matches the pattern attribute"},
{conditions: {pattern: "[A-Z]+", value: "\u0041\u0042\u0043"}, expected: false, name: "[target] The value(ABC) in unicode attribute matches the pattern attribute"},
{conditions: {pattern: "[A-Z]+", value: "\x41\x42\x43"}, expected: false, name: "[target] The value(ABC) in unicode attribute matches the pattern attribute"},
{conditions: {pattern: "[a-z]{3,}", value: "ABCD"}, expected: true, name: "[target] The value attribute mismatches the pattern attribute"},
{conditions: {pattern: "[A-Z]+", value: "ABC123"}, expected: true, name: "[target] The value attribute mismatches the pattern attribute even when a subset matches"},
{conditions: {pattern: "(abc", value: "de"}, expected: false, name: "[target] Invalid regular expression gets ignored"},
{conditions: {pattern: "a)(b", value: "de"}, expected: false, name: "[target] The pattern attribute tries to escape a group"},
{conditions: {pattern: "a\\u{10FFFF}", value: "a\u{10FFFF}"}, expected: false, name: "[target] The pattern attribute uses Unicode features"},
{conditions: {pattern: "\\u1234\\cx[5-[]{2}", value: "\u1234\x18[6"}, expected: false, name: "[target] The value attribute matches JavaScript-specific regular expression"},
{conditions: {pattern: "\\u1234\\cx[5-[]{2}", value: "\u1234\x18[4"}, expected: true, name: "[target] The value attribute mismatches JavaScript-specific regular expression"},
{conditions: {pattern: "\\u1234\\cx[5-\\[]{2}", value: "\u1234\x18[6"}, expected: false, name: "[target] The value attribute matches JavaScript-specific regular expression"},
{conditions: {pattern: "\\u1234\\cx[5-\\[]{2}", value: "\u1234\x18[4"}, expected: true, name: "[target] The value attribute mismatches JavaScript-specific regular expression"},
]
},
{
Expand All @@ -34,14 +34,14 @@
{conditions: {multiple: true, pattern: null, value: "abc,abc"}, expected: false, name: "[target] The pattern attribute is not set, if multiple is present"},
{conditions: {multiple: true, pattern: "[A-Z]+", value: ""}, expected: false, name: "[target] The value attibute is empty string, if multiple is present"},
{conditions: {multiple: true, pattern: "[A-Z]{1}", value: "A,A"}, expected: false, name: "[target] The value attribute matches the pattern attribute, if multiple is present"},
{conditions: {multiple: true, pattern: "[A-Z]+", value: "\u0041\u0042\u0043,\u0041\u0042\u0043"}, expected: false, name: "[target] The value(ABC) in unicode attribute matches the pattern attribute, if multiple is present"},
{conditions: {multiple: true, pattern: "[A-Z]+", value: "\x41\x42\x43,\x41\x42\x43"}, expected: false, name: "[target] The value(ABC) in unicode attribute matches the pattern attribute, if multiple is present"},
{conditions: {multiple: true, pattern: "[a-z]{3,}", value: "abcd,ABCD"}, expected: true, name: "[target] The value attribute mismatches the pattern attribute, if multiple is present"},
{conditions: {multiple: true, pattern: "[A-Z]+", value: "ABCD,ABC123"}, expected: true, name: "[target] The value attribute mismatches the pattern attribute even when a subset matches, if multiple is present"},
{conditions: {multiple: true, pattern: "(abc", value: "de,de"}, expected: false, name: "[target] Invalid regular expression gets ignored, if multiple is present"},
{conditions: {multiple: true, pattern: "a)(b", value: "de,de"}, expected: false, name: "[target] The pattern attribute tries to escape a group, if multiple is present"},
{conditions: {multiple: true, pattern: "a\\u{10FFFF}", value: "a\u{10FFFF},a\u{10FFFF}"}, expected: false, name: "[target] The pattern attribute uses Unicode features, if multiple is present"},
{conditions: {multiple: true, pattern: "\\u1234\\cx[5-[]{2}", value: "\u1234\x18[6,\u1234\x18[Z"}, expected: false, name: "[target] The value attribute matches JavaScript-specific regular expression, if multiple is present"},
{conditions: {multiple: true, pattern: "\\u1234\\cx[5-[]{2}", value: "\u1234\x18[4,\u1234\x18[6"}, expected: true, name: "[target] The value attribute mismatches JavaScript-specific regular expression, if multiple is present"},
{conditions: {multiple: true, pattern: "\\u1234\\cx[5-\\[]{2}", value: "\u1234\x18[6,\u1234\x18[Z"}, expected: false, name: "[target] The value attribute matches JavaScript-specific regular expression, if multiple is present"},
{conditions: {multiple: true, pattern: "\\u1234\\cx[5-\\[]{2}", value: "\u1234\x18[4,\u1234\x18[6"}, expected: true, name: "[target] The value attribute mismatches JavaScript-specific regular expression, if multiple is present"},
{conditions: {multiple: true, pattern: "a,", value: "a,"}, expected: true, name: "[target] Commas should be stripped from regex input, if multiple is present"},
]
}
Expand Down
75 changes: 73 additions & 2 deletions html/semantics/forms/the-input-element/pattern_attribute.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,42 @@
<h1><code>pattern</code> attribute</h1>
<div style="display: none">
<input pattern="[a-z]{3}" value="abcd" id="basic">

<input pattern="a.b" value="a&#x1D306;b" id="unicode-code-points">
<input pattern="\p{ASCII_Hex_Digit}+" value="c0ff33" id="unicode-property-escape">
<input pattern="\p{ASCII_Hex_Digit}+" value="c0ff33" id="unicode-property">

<input pattern="\p{RGI_Emoji}+" value="&#x1F618;&#x1F48B;" id="unicode-property-of-strings">
<input pattern="[\p{ASCII_Hex_Digit}--[Ff]]" value="0123456789abcdefABCDEF" id="set-difference">
<input pattern="[_\q{a|bc|def}]" value="q" id="string-literal">

<input pattern="[(]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-01">
<input pattern="[)]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-02">
<input pattern="[[]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-03">
<input pattern="[{]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-04">
<input pattern="[}]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-05">
<input pattern="[/]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-06">
<input pattern="[-]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-07">
<input pattern="[|]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-08">

<input pattern="[&&]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-09">
<input pattern="[!!]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-10">
<input pattern="[##]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-11">
<input pattern="[$$]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-12">
<input pattern="[%%]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-13">
<input pattern="[**]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-14">
<input pattern="[++]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-15">
<input pattern="[,,]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-16">
<input pattern="[..]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-17">
<input pattern="[::]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-18">
<input pattern="[;;]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-19">
<input pattern="[&lt;&lt;]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-20">
<input pattern="[==]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-21">
<input pattern="[>>]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-22">
<input pattern="[??]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-23">
<input pattern="[@@]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-24">
<input pattern="[``]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-25">
<input pattern="[~~]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-26">
<input pattern="[_^^]" value="foo" class="breaking-change-from-u-to-v" id="breaking-change-from-u-to-v-27">
</div>
<div id="log"></div>
<script>
Expand All @@ -24,6 +58,7 @@ <h1><code>pattern</code> attribute</h1>

assert_inherits(input, "validity");
assert_false(input.validity.valid);
assert_true(input.validity.patternMismatch);

assert_true(input.matches(":invalid"));
}, "basic <input pattern> support");
Expand All @@ -32,11 +67,47 @@ <h1><code>pattern</code> attribute</h1>
const input = document.querySelector("#unicode-code-points");
assert_true(input.validity.valid);
assert_true(input.matches(":valid"));
assert_false(input.validity.patternMismatch);
}, "<input pattern> is Unicode code point-aware");

test(() => {
const input = document.querySelector("#unicode-property-escape");
const input = document.querySelector("#unicode-property");
assert_true(input.validity.valid);
assert_true(input.matches(":valid"));
assert_false(input.validity.patternMismatch);
}, "<input pattern> supports Unicode property escape syntax");

test(() => {
const input = document.querySelector("#unicode-property-of-strings");
assert_true(input.validity.valid);
assert_true(input.matches(":valid"));
assert_false(input.validity.patternMismatch);
}, "<input pattern> supports Unicode property escape syntax for properties of strings");

test(() => {
const input = document.querySelector("#set-difference");
assert_false(input.validity.valid);
assert_false(input.matches(":valid"));
assert_true(input.validity.patternMismatch);
}, "<input pattern> supports set difference syntax");

test(() => {
const input = document.querySelector("#string-literal");
assert_false(input.validity.valid);
assert_true(input.validity.patternMismatch);
assert_true(input.matches(":invalid"));
}, "<input pattern> supports string literal syntax");

test(() => {
const inputs = document.querySelectorAll("input.breaking-change-from-u-to-v");
// These examples are all written such that they’re all `:invalid`
// when using `u`, but would become `:valid` when using `v` because
// the pattern would error, in turn resulting in
// `validity.valid === true`.
for (const input of inputs) {
assert_true(input.validity.valid);
assert_true(input.matches(":valid"));
assert_false(input.validity.patternMismatch);
}
}, "<input pattern> enables the RegExp v flag");
</script>

0 comments on commit 7640b5b

Please sign in to comment.