@markuplint/rules 3.13.0 → 4.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/lib/attr-check.js +14 -19
  2. package/lib/attr-duplication/index.js +3 -6
  3. package/lib/attr-value-quotes/index.js +5 -9
  4. package/lib/case-sensitive-attr-name/index.js +9 -13
  5. package/lib/case-sensitive-tag-name/index.js +2 -4
  6. package/lib/character-reference/index.js +6 -8
  7. package/lib/class-naming/index.js +9 -11
  8. package/lib/create-message.js +9 -16
  9. package/lib/debug.js +2 -6
  10. package/lib/deprecated-attr/index.js +6 -9
  11. package/lib/deprecated-element/index.js +3 -5
  12. package/lib/disallowed-element/index.js +2 -4
  13. package/lib/doctype/index.js +2 -4
  14. package/lib/end-tag/index.js +5 -8
  15. package/lib/helpers.d.ts +1 -1
  16. package/lib/helpers.js +17 -28
  17. package/lib/id-duplication/index.js +2 -4
  18. package/lib/index.d.ts +15 -15
  19. package/lib/index.js +63 -66
  20. package/lib/ineffective-attr/index.js +5 -7
  21. package/lib/invalid-attr/index.js +30 -33
  22. package/lib/label-has-control/index.js +2 -4
  23. package/lib/landmark-roles/index.js +3 -6
  24. package/lib/no-boolean-attr-value/index.js +6 -9
  25. package/lib/no-default-value/index.js +9 -12
  26. package/lib/no-empty-palpable-content/index.js +5 -7
  27. package/lib/no-hard-code-id/index.js +2 -4
  28. package/lib/no-refer-to-non-existent-id/index.js +26 -30
  29. package/lib/no-use-event-handler-attr/index.js +4 -6
  30. package/lib/permitted-contents/choice.d.ts +1 -1
  31. package/lib/permitted-contents/choice.js +13 -18
  32. package/lib/permitted-contents/complex-branch.d.ts +1 -1
  33. package/lib/permitted-contents/complex-branch.js +10 -14
  34. package/lib/permitted-contents/content-model.d.ts +1 -1
  35. package/lib/permitted-contents/content-model.js +5 -9
  36. package/lib/permitted-contents/count-pattern.d.ts +1 -1
  37. package/lib/permitted-contents/count-pattern.js +19 -24
  38. package/lib/permitted-contents/debug.browser.js +9 -12
  39. package/lib/permitted-contents/debug.d.ts +8 -1
  40. package/lib/permitted-contents/debug.js +12 -13
  41. package/lib/permitted-contents/index.d.ts +1 -1
  42. package/lib/permitted-contents/index.js +10 -13
  43. package/lib/permitted-contents/matches-selector.d.ts +1 -1
  44. package/lib/permitted-contents/matches-selector.js +12 -17
  45. package/lib/permitted-contents/order.d.ts +1 -1
  46. package/lib/permitted-contents/order.js +17 -22
  47. package/lib/permitted-contents/recursive-branch.d.ts +2 -2
  48. package/lib/permitted-contents/recursive-branch.js +9 -13
  49. package/lib/permitted-contents/represent-transparent-nodes.d.ts +1 -1
  50. package/lib/permitted-contents/represent-transparent-nodes.js +15 -20
  51. package/lib/permitted-contents/start.d.ts +1 -1
  52. package/lib/permitted-contents/start.js +13 -21
  53. package/lib/permitted-contents/transparent.d.ts +1 -1
  54. package/lib/permitted-contents/transparent.js +4 -9
  55. package/lib/permitted-contents/types.js +1 -2
  56. package/lib/permitted-contents/utils.d.ts +1 -1
  57. package/lib/permitted-contents/utils.js +55 -74
  58. package/lib/placeholder-label-option/index.js +5 -9
  59. package/lib/require-accessible-name/index.js +10 -13
  60. package/lib/require-datetime/index.d.ts +1 -1
  61. package/lib/require-datetime/index.js +6 -8
  62. package/lib/require-datetime/types.js +1 -2
  63. package/lib/require-datetime/utils.d.ts +1 -1
  64. package/lib/require-datetime/utils.js +4 -11
  65. package/lib/required-attr/index.js +8 -11
  66. package/lib/required-element/index.js +3 -6
  67. package/lib/required-h1/index.js +3 -6
  68. package/lib/use-list/index.js +6 -10
  69. package/lib/wai-aria/checkings/abstract-role.d.ts +1 -1
  70. package/lib/wai-aria/checkings/abstract-role.js +5 -10
  71. package/lib/wai-aria/checkings/default-value.d.ts +1 -1
  72. package/lib/wai-aria/checkings/default-value.js +2 -6
  73. package/lib/wai-aria/checkings/deprecated-props.d.ts +1 -1
  74. package/lib/wai-aria/checkings/deprecated-props.js +3 -8
  75. package/lib/wai-aria/checkings/disallowed-prop.d.ts +1 -1
  76. package/lib/wai-aria/checkings/disallowed-prop.js +7 -12
  77. package/lib/wai-aria/checkings/implicit-props.d.ts +1 -1
  78. package/lib/wai-aria/checkings/implicit-props.js +6 -11
  79. package/lib/wai-aria/checkings/implicit-role.d.ts +1 -1
  80. package/lib/wai-aria/checkings/implicit-role.js +4 -9
  81. package/lib/wai-aria/checkings/interaction-in-hidden.d.ts +1 -1
  82. package/lib/wai-aria/checkings/interaction-in-hidden.js +4 -8
  83. package/lib/wai-aria/checkings/no-global-prop.d.ts +1 -1
  84. package/lib/wai-aria/checkings/no-global-prop.js +2 -7
  85. package/lib/wai-aria/checkings/non-existent-role.d.ts +1 -1
  86. package/lib/wai-aria/checkings/non-existent-role.js +4 -9
  87. package/lib/wai-aria/checkings/permitted-roles.d.ts +1 -1
  88. package/lib/wai-aria/checkings/permitted-roles.js +4 -9
  89. package/lib/wai-aria/checkings/presentational-children.d.ts +1 -1
  90. package/lib/wai-aria/checkings/presentational-children.js +4 -9
  91. package/lib/wai-aria/checkings/required-owned-elements.d.ts +1 -1
  92. package/lib/wai-aria/checkings/required-owned-elements.js +4 -8
  93. package/lib/wai-aria/checkings/required-prop.d.ts +1 -1
  94. package/lib/wai-aria/checkings/required-prop.js +2 -7
  95. package/lib/wai-aria/checkings/value.d.ts +1 -1
  96. package/lib/wai-aria/checkings/value.js +4 -10
  97. package/lib/wai-aria/index.d.ts +1 -1
  98. package/lib/wai-aria/index.js +38 -40
  99. package/lib/wai-aria/types.js +1 -2
  100. package/package.json +17 -12
  101. package/test/attr-check.spec.js +0 -77
  102. package/test/attr-duplication/index.spec.js +0 -159
  103. package/test/attr-value-quotes/index.spec.js +0 -133
  104. package/test/case-sensitive-attr-name/index.spec.js +0 -65
  105. package/test/case-sensitive-tag-name/index.spec.js +0 -80
  106. package/test/character-reference/index.spec.js +0 -72
  107. package/test/class-naming/index.spec.js +0 -470
  108. package/test/create-message.spec.js +0 -497
  109. package/test/deprecated-attr/index.spec.js +0 -48
  110. package/test/deprecated-element/index.spec.js +0 -35
  111. package/test/disallowed-element/index.spec.js +0 -90
  112. package/test/doctype/index.spec.js +0 -50
  113. package/test/end-tag/index.spec.js +0 -162
  114. package/test/id-duplication/index.spec.js +0 -47
  115. package/test/ineffective-attr/index.spec.js +0 -31
  116. package/test/invalid-attr/index.spec.js +0 -1631
  117. package/test/label-has-control/index.spec.js +0 -29
  118. package/test/landmark-roles/index.spec.js +0 -187
  119. package/test/no-boolean-attr-value/index.spec.js +0 -41
  120. package/test/no-default-value/index.spec.js +0 -74
  121. package/test/no-empty-palpable-content/index.spec.js +0 -115
  122. package/test/no-hard-code-id/index.spec.js +0 -100
  123. package/test/no-refer-to-non-existent-id/index.spec.js +0 -254
  124. package/test/no-use-event-handler-attr/index.spec.js +0 -57
  125. package/test/permitted-contents/choice.spec.js +0 -174
  126. package/test/permitted-contents/count-pattern.spec.js +0 -308
  127. package/test/permitted-contents/index.spec.js +0 -1395
  128. package/test/permitted-contents/matches-selector.spec.js +0 -59
  129. package/test/permitted-contents/order.spec.js +0 -351
  130. package/test/permitted-contents/recursive-branch.spec.js +0 -41
  131. package/test/permitted-contents/represent-transparent-nodes.spec.js +0 -24
  132. package/test/permitted-contents/start.spec.js +0 -67
  133. package/test/placeholder-label-option/index.spec.js +0 -113
  134. package/test/require-accessible-name/index.spec.js +0 -444
  135. package/test/require-datetime/index.spec.js +0 -54
  136. package/test/require-datetime/utils.spec.js +0 -52
  137. package/test/required-attr/index.spec.js +0 -414
  138. package/test/required-element/index.spec.js +0 -188
  139. package/test/required-h1/index.spec.js +0 -69
  140. package/test/use-list/index.spec.js +0 -109
  141. package/test/wai-aria/checkings/value.spec.js +0 -33
  142. package/test/wai-aria/index.spec.js +0 -1203
@@ -1,308 +0,0 @@
1
- const specs = require('@markuplint/html-spec');
2
- const { createTestElement } = require('@markuplint/ml-core');
3
-
4
- const { countPattern } = require('../../lib/permitted-contents/count-pattern');
5
-
6
- function c(models, innerHtml) {
7
- const el = createTestElement(`<div>${innerHtml}</div>`);
8
- return countPattern(models, Array.from(el.childNodes), specs, { ignoreHasMutableChildren: true }, 0);
9
- }
10
-
11
- it('require: a', () => {
12
- expect(c({ require: 'a' }, '<a></a>').type).toBe('MATCHED');
13
- expect(c({ require: 'a' }, '<b></b>').type).toBe('MISSING_NODE_REQUIRED');
14
- expect(c({ require: 'a' }, '<c></c>').type).toBe('MISSING_NODE_REQUIRED');
15
- expect(c({ require: 'a' }, 'text').type).toBe('MISSING_NODE_REQUIRED');
16
- expect(c({ require: 'a' }, '').type).toBe('MISSING_NODE_REQUIRED');
17
-
18
- expect(c({ require: 'a' }, '<a></a>').matched.length).toBe(1);
19
- expect(c({ require: 'a' }, '<b></b>').matched.length).toBe(0);
20
- expect(c({ require: 'a' }, '<c></c>').matched.length).toBe(0);
21
- expect(c({ require: 'a' }, 'text').matched.length).toBe(0);
22
- expect(c({ require: 'a' }, '').matched.length).toBe(0);
23
- });
24
-
25
- it('optional: a', () => {
26
- expect(c({ optional: 'a' }, '<a></a>').type).toBe('MATCHED');
27
- expect(c({ optional: 'a' }, '<a></a><a></a>').type).toBe('UNEXPECTED_EXTRA_NODE');
28
- expect(c({ optional: 'a' }, '<b></b>').type).toBe('MATCHED_ZERO');
29
- expect(c({ optional: 'a' }, '<c></c>').type).toBe('MATCHED_ZERO');
30
- expect(c({ optional: 'a' }, 'text').type).toBe('MATCHED_ZERO');
31
- expect(c({ optional: 'a' }, '').type).toBe('MATCHED_ZERO');
32
-
33
- expect(c({ optional: 'a' }, '<a></a>').matched.length).toBe(1);
34
- expect(c({ optional: 'a' }, '<a></a><a></a>').matched.length).toBe(1);
35
- expect(c({ optional: 'a' }, '<b></b>').matched.length).toBe(0);
36
- expect(c({ optional: 'a' }, '<c></c>').matched.length).toBe(0);
37
- expect(c({ optional: 'a' }, 'text').matched.length).toBe(0);
38
- expect(c({ optional: 'a' }, '').matched.length).toBe(0);
39
- });
40
-
41
- it('oneOrMore: a', () => {
42
- expect(c({ oneOrMore: 'a' }, '<a></a>').type).toBe('MATCHED');
43
- expect(c({ oneOrMore: 'a' }, '<b></b>').type).toBe('MISSING_NODE_ONE_OR_MORE');
44
- expect(c({ oneOrMore: 'a' }, '<c></c>').type).toBe('MISSING_NODE_ONE_OR_MORE');
45
- expect(c({ oneOrMore: 'a' }, 'text').type).toBe('MISSING_NODE_ONE_OR_MORE');
46
- expect(c({ oneOrMore: 'a' }, '').type).toBe('MISSING_NODE_ONE_OR_MORE');
47
-
48
- expect(c({ oneOrMore: 'a' }, '<a></a>').matched.length).toBe(1);
49
- expect(c({ oneOrMore: 'a' }, '<b></b>').matched.length).toBe(0);
50
- expect(c({ oneOrMore: 'a' }, '<c></c>').matched.length).toBe(0);
51
- expect(c({ oneOrMore: 'a' }, 'text').matched.length).toBe(0);
52
- expect(c({ oneOrMore: 'a' }, '').matched.length).toBe(0);
53
-
54
- expect(c({ oneOrMore: 'a' }, '<a></a><a></a><a></a>').matched.length).toBe(3);
55
- expect(c({ oneOrMore: 'a' }, '<a></a><a></a><b></b>').matched.length).toBe(2);
56
- expect(c({ oneOrMore: 'a' }, '<a></a><c></c><c></c>').matched.length).toBe(1);
57
- });
58
-
59
- it('zeroOrMore: a', () => {
60
- expect(c({ zeroOrMore: 'a' }, '<a></a>').type).toBe('MATCHED');
61
- expect(c({ zeroOrMore: 'a' }, '<b></b>').type).toBe('MATCHED_ZERO');
62
- expect(c({ zeroOrMore: 'a' }, '<c></c>').type).toBe('MATCHED_ZERO');
63
- expect(c({ zeroOrMore: 'a' }, 'text').type).toBe('MATCHED_ZERO');
64
- expect(c({ zeroOrMore: 'a' }, '').type).toBe('MATCHED_ZERO');
65
-
66
- expect(c({ zeroOrMore: 'a' }, '<a></a>').matched.length).toBe(1);
67
- expect(c({ zeroOrMore: 'a' }, '<b></b>').matched.length).toBe(0);
68
- expect(c({ zeroOrMore: 'a' }, '<c></c>').matched.length).toBe(0);
69
- expect(c({ zeroOrMore: 'a' }, 'text').matched.length).toBe(0);
70
- expect(c({ zeroOrMore: 'a' }, '').matched.length).toBe(0);
71
-
72
- expect(c({ zeroOrMore: 'a' }, '<a></a><a></a><a></a>').matched.length).toBe(3);
73
- expect(c({ zeroOrMore: 'a' }, '<a></a><a></a><b></b>').matched.length).toBe(2);
74
- expect(c({ zeroOrMore: 'a' }, '<a></a><c></c><c></c>').matched.length).toBe(1);
75
- });
76
-
77
- it('require: #flow', () => {
78
- expect(c({ require: '#flow' }, '<a></a>').type).toBe('MATCHED');
79
- expect(c({ require: '#flow' }, '<b></b>').type).toBe('MATCHED');
80
- expect(c({ require: '#flow' }, '<c></c>').type).toBe('MATCHED_ZERO');
81
- expect(c({ require: '#flow' }, 'text').type).toBe('MATCHED');
82
- expect(c({ require: '#flow' }, '').type).toBe('MATCHED_ZERO');
83
-
84
- expect(c({ require: '#flow' }, '<a></a>').matched.length).toBe(1);
85
- expect(c({ require: '#flow' }, '<b></b>').matched.length).toBe(1);
86
- expect(c({ require: '#flow' }, '<c></c>').matched.length).toBe(0);
87
- expect(c({ require: '#flow' }, 'text').matched.length).toBe(1);
88
- expect(c({ require: '#flow' }, '').matched.length).toBe(0);
89
-
90
- expect(c({ require: '#flow' }, '<a></a><a></a><a></a>').matched.length).toBe(1);
91
- expect(c({ require: '#flow' }, '<b></b><a></a>').matched.length).toBe(1);
92
- expect(c({ require: '#flow' }, '<c></c><a></a>').matched.length).toBe(0);
93
- expect(c({ require: '#flow' }, 'text<a></a>').matched.length).toBe(1);
94
- expect(c({ require: '#flow' }, '<a></a>').matched.length).toBe(1);
95
-
96
- expect(c({ require: '#flow' }, '<a></a><a></a>').matched[0].nodeName).toBe('A');
97
- expect(c({ require: '#flow' }, '<b></b><a></a>').matched[0].nodeName).toBe('B');
98
- expect(c({ require: '#flow' }, 'text<a></a>').matched[0].nodeName).toBe('#text');
99
- expect(c({ require: '#flow' }, '<a></a>').matched[0].nodeName).toBe('A');
100
- });
101
-
102
- it('optional: #flow', () => {
103
- expect(c({ optional: '#flow' }, '<a></a>').type).toBe('MATCHED');
104
- expect(c({ optional: '#flow' }, '<b></b>').type).toBe('MATCHED');
105
- expect(c({ optional: '#flow' }, '<c></c>').type).toBe('MATCHED_ZERO');
106
- expect(c({ optional: '#flow' }, 'text').type).toBe('MATCHED');
107
- expect(c({ optional: '#flow' }, '').type).toBe('MATCHED_ZERO');
108
-
109
- expect(c({ optional: '#flow' }, '<a></a>').matched.length).toBe(1);
110
- expect(c({ optional: '#flow' }, '<b></b>').matched.length).toBe(1);
111
- expect(c({ optional: '#flow' }, '<c></c>').matched.length).toBe(0);
112
- expect(c({ optional: '#flow' }, 'text').matched.length).toBe(1);
113
- expect(c({ optional: '#flow' }, '').matched.length).toBe(0);
114
- });
115
-
116
- it('oneOrMore: #flow', () => {
117
- expect(c({ oneOrMore: '#flow' }, '<a></a>').type).toBe('MATCHED');
118
- expect(c({ oneOrMore: '#flow' }, '<b></b>').type).toBe('MATCHED');
119
- expect(c({ oneOrMore: '#flow' }, '<c></c>').type).toBe('MATCHED_ZERO');
120
- expect(c({ oneOrMore: '#flow' }, 'text').type).toBe('MATCHED');
121
- expect(c({ oneOrMore: '#flow' }, '').type).toBe('MATCHED_ZERO');
122
-
123
- expect(c({ oneOrMore: '#flow' }, '<a></a>').matched.length).toBe(1);
124
- expect(c({ oneOrMore: '#flow' }, '<b></b>').matched.length).toBe(1);
125
- expect(c({ oneOrMore: '#flow' }, '<c></c>').matched.length).toBe(0);
126
- expect(c({ oneOrMore: '#flow' }, 'text').matched.length).toBe(1);
127
- expect(c({ oneOrMore: '#flow' }, '').matched.length).toBe(0);
128
-
129
- expect(c({ oneOrMore: '#flow' }, '<a></a><a></a><a></a>').matched.length).toBe(3);
130
- expect(c({ oneOrMore: '#flow' }, '<a></a><a></a><b></b>').matched.length).toBe(3);
131
- expect(c({ oneOrMore: '#flow' }, '<a></a><c></c><c></c>').matched.length).toBe(1);
132
- });
133
-
134
- it('zeroOrMore: #flow', () => {
135
- expect(c({ zeroOrMore: '#flow' }, '<a></a>').type).toBe('MATCHED');
136
- expect(c({ zeroOrMore: '#flow' }, '<b></b>').type).toBe('MATCHED');
137
- expect(c({ zeroOrMore: '#flow' }, '<c></c>').type).toBe('MATCHED_ZERO');
138
- expect(c({ zeroOrMore: '#flow' }, 'text').type).toBe('MATCHED');
139
- expect(c({ zeroOrMore: '#flow' }, '').type).toBe('MATCHED_ZERO');
140
-
141
- expect(c({ zeroOrMore: '#flow' }, '<a></a>').matched.length).toBe(1);
142
- expect(c({ zeroOrMore: '#flow' }, '<b></b>').matched.length).toBe(1);
143
- expect(c({ zeroOrMore: '#flow' }, '<c></c>').matched.length).toBe(0);
144
- expect(c({ zeroOrMore: '#flow' }, 'text').matched.length).toBe(1);
145
- expect(c({ zeroOrMore: '#flow' }, '').matched.length).toBe(0);
146
-
147
- expect(c({ zeroOrMore: '#flow' }, '<a></a><a></a><a></a>').matched.length).toBe(3);
148
- expect(c({ zeroOrMore: '#flow' }, '<a></a><a></a><b></b>').matched.length).toBe(3);
149
- expect(c({ zeroOrMore: '#flow' }, '<a></a><c></c><c></c>').matched.length).toBe(1);
150
- });
151
-
152
- it('zeroOrMore: :model(script-supporting)', () => {
153
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<a></a>').type).toBe('MATCHED_ZERO');
154
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<b></b>').type).toBe('MATCHED_ZERO');
155
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<c></c>').type).toBe('MATCHED_ZERO');
156
- expect(c({ zeroOrMore: ':model(script-supporting)' }, 'text').type).toBe('MATCHED_ZERO');
157
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '').type).toBe('MATCHED_ZERO');
158
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<script></script>').type).toBe('MATCHED');
159
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<template></template>').type).toBe('MATCHED');
160
-
161
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<a></a>').matched.length).toBe(0);
162
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<b></b>').matched.length).toBe(0);
163
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<c></c>').matched.length).toBe(0);
164
- expect(c({ zeroOrMore: ':model(script-supporting)' }, 'text').matched.length).toBe(0);
165
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '').matched.length).toBe(0);
166
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<script></script>').matched.length).toBe(1);
167
- expect(c({ zeroOrMore: ':model(script-supporting)' }, '<template></template>').matched.length).toBe(1);
168
- });
169
-
170
- it('min/max', () => {
171
- expect(c({ require: 'c', min: 2 }, '').type).toBe('MISSING_NODE_REQUIRED');
172
- expect(c({ require: 'c', min: 2 }, '<c></c>').type).toBe('MISSING_NODE_REQUIRED');
173
- expect(c({ require: 'c', min: 2 }, '<c></c><c></c>').type).toBe('MATCHED');
174
- expect(c({ require: 'c', max: 1 }, '<c></c><c></c>').type).toBe('UNEXPECTED_EXTRA_NODE');
175
- expect(c({ require: 'c', max: 1 }, '<c></c><c></c>').hint?.max).toBe(1);
176
- });
177
-
178
- it('the dl element', () => {
179
- const models = {
180
- oneOrMore: [
181
- {
182
- zeroOrMore: ':model(script-supporting)',
183
- },
184
- {
185
- oneOrMore: 'dt',
186
- },
187
- {
188
- zeroOrMore: ':model(script-supporting)',
189
- },
190
- {
191
- oneOrMore: 'dd',
192
- },
193
- {
194
- zeroOrMore: ':model(script-supporting)',
195
- },
196
- ],
197
- };
198
-
199
- expect(c(models, '<dt></dt>').type).toBe('MISSING_NODE_ONE_OR_MORE');
200
- expect(c(models, '<dd></dd>').type).toBe('MISSING_NODE_ONE_OR_MORE');
201
- expect(c(models, '<dt></dt><dd></dd>').type).toBe('MATCHED');
202
- expect(c(models, '<dt></dt><dt></dt><dd></dd>').type).toBe('MATCHED');
203
- expect(c(models, '<dt></dt><dd></dd><dd></dd>').type).toBe('MATCHED');
204
- expect(c(models, '<dt></dt><dd></dd><dd></dd><dt></dt>').type).toBe('MISSING_NODE_ONE_OR_MORE');
205
- });
206
-
207
- it('part of the ruby element', () => {
208
- const models = {
209
- // 1. One or the other of the following:
210
- oneOrMore: [
211
- // - Phrasing content, but with no ruby elements and with no ruby element descendants
212
- ':model(phrasing):not(ruby, :has(ruby))',
213
- // - A single ruby element that itself has no ruby element descendants
214
- 'ruby:not(:has(ruby))',
215
- ],
216
- };
217
- expect(c(models, '<span></span>').type).toBe('MATCHED');
218
- expect(c(models, 'text').type).toBe('MATCHED');
219
- expect(c(models, 'text<span></span>').type).toBe('MATCHED');
220
- expect(c(models, 'text<span>text in span</span>').type).toBe('MATCHED');
221
- expect(c(models, '<ruby></ruby>').type).toBe('MATCHED');
222
- expect(c(models, '<ruby></ruby><span></span>').type).toBe('MATCHED');
223
- expect(c(models, '<span><ruby></ruby></span>').type).toBe('MISSING_NODE_ONE_OR_MORE');
224
- expect(c(models, '<span><ruby></ruby></span>').query).toBe('ruby:not(:has(ruby))');
225
- expect(c(models, '<ruby><ruby></ruby></ruby>').type).toBe('MISSING_NODE_ONE_OR_MORE');
226
- expect(c(models, '<ruby><ruby></ruby></ruby>').query).toBe('ruby:not(:has(ruby))');
227
- });
228
-
229
- it('part of the ruby element', () => {
230
- const models = {
231
- // The content model of ruby elements consists of one or more of the following sequences:
232
- oneOrMore: [
233
- {
234
- // 1. One or the other of the following:
235
- oneOrMore: [
236
- // - Phrasing content, but with no ruby elements and with no ruby element descendants
237
- ':model(phrasing):not(ruby, :has(ruby))',
238
- // - A single ruby element that itself has no ruby element descendants
239
- 'ruby:not(:has(rt, rp))',
240
- ],
241
- },
242
- {
243
- // 2. One or the other of the following:
244
- choice: [
245
- [
246
- {
247
- // - One or more rt elements
248
- oneOrMore: 'rt',
249
- },
250
- ],
251
- [
252
- {
253
- // - An rp element
254
- require: 'rp',
255
- },
256
- {
257
- // followed by one or more rt elements, each of which is itself followed by an rp element
258
- oneOrMore: [
259
- {
260
- require: 'rt',
261
- },
262
- {
263
- require: 'rp',
264
- },
265
- ],
266
- },
267
- ],
268
- ],
269
- },
270
- ],
271
- };
272
-
273
- expect(c(models, '<span></span>').type).toBe('MISSING_NODE_ONE_OR_MORE');
274
- expect(c(models, '<span></span>').query).toBe('rt');
275
- expect(c(models, '<span></span><rp></rp><rt></rt><rp></rp>').type).toBe('MATCHED');
276
- expect(c(models, '<span></span><rp></rp><rt></rt>').type).toBe('MISSING_NODE_REQUIRED');
277
- expect(c(models, '<span></span><rp></rp><rt></rt>').query).toBe('rp');
278
- expect(c(models, '<span></span><rp></rp><rt></rt><rp></rp>').type).toBe('MATCHED');
279
- expect(c(models, '<span></span><rp></rp><rt></rt><rp></rp><span></span><span></span>').type).toBe(
280
- 'UNEXPECTED_EXTRA_NODE',
281
- );
282
- expect(c(models, '<span></span><rp></rp><rt></rt><rp></rp><span></span><span></span>').query).toBe('rp');
283
- expect(c(models, '<span></span><rt></rt><span></span><rt></rt>').type).toBe('MATCHED');
284
- expect(c(models, 'text<rt></rt>text2<rt></rt>').type).toBe('MATCHED');
285
- expect(c(models, 'text<rt></rt><rt></rt>text2<rt></rt><rt></rt>').type).toBe('MATCHED');
286
- expect(c(models, 'text<rp></rp><rt></rt><rp></rp>text2<rt></rt>').type).toBe('MATCHED');
287
- });
288
-
289
- it('part of the ruby element', () => {
290
- const models = {
291
- // followed by one or more rt elements, each of which is itself followed by an rp element
292
- oneOrMore: [
293
- {
294
- require: 'rt',
295
- },
296
- {
297
- require: 'rp',
298
- },
299
- ],
300
- };
301
-
302
- expect(c(models, '<rt></rt>').type).toBe('MISSING_NODE_REQUIRED');
303
- expect(c(models, '<rt></rt>').query).toBe('rp');
304
- expect(c(models, '<rt></rt><rp></rp>').type).toBe('MATCHED');
305
- expect(c(models, '<rt></rt><rp></rp><rt></rt>').type).toBe('MISSING_NODE_REQUIRED');
306
- expect(c(models, '<rt></rt><rp></rp><rt></rt>').query).toBe('rp');
307
- expect(c(models, '<rt></rt><rp></rp><rt></rt><rp></rp>').type).toBe('MATCHED');
308
- });