@markuplint/rules 3.8.0 → 3.10.0
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.
- package/lib/attr-duplication/index.d.ts +1 -3
- package/lib/attr-value-quotes/index.d.ts +2 -2
- package/lib/case-sensitive-attr-name/index.d.ts +1 -1
- package/lib/case-sensitive-tag-name/index.d.ts +1 -1
- package/lib/character-reference/index.d.ts +1 -1
- package/lib/class-naming/index.d.ts +1 -1
- package/lib/create-message.d.ts +2 -12
- package/lib/deprecated-attr/index.d.ts +1 -3
- package/lib/deprecated-element/index.d.ts +1 -3
- package/lib/disallowed-element/index.d.ts +1 -1
- package/lib/doctype/index.d.ts +2 -2
- package/lib/end-tag/index.d.ts +1 -1
- package/lib/helpers.d.ts +18 -39
- package/lib/id-duplication/index.d.ts +1 -3
- package/lib/index.d.ts +7 -7
- package/lib/ineffective-attr/index.d.ts +1 -3
- package/lib/invalid-attr/index.d.ts +31 -38
- package/lib/label-has-control/index.d.ts +1 -3
- package/lib/landmark-roles/index.d.ts +3 -3
- package/lib/no-boolean-attr-value/index.d.ts +1 -3
- package/lib/no-default-value/index.d.ts +1 -3
- package/lib/no-empty-palpable-content/index.d.ts +3 -3
- package/lib/no-hard-code-id/index.d.ts +1 -3
- package/lib/no-refer-to-non-existent-id/index.d.ts +4 -9
- package/lib/no-use-event-handler-attr/index.d.ts +2 -2
- package/lib/permitted-contents/choice.d.ts +1 -7
- package/lib/permitted-contents/complex-branch.d.ts +1 -7
- package/lib/permitted-contents/count-pattern.d.ts +2 -17
- package/lib/permitted-contents/debug.browser.d.ts +15 -15
- package/lib/permitted-contents/debug.d.ts +1 -1
- package/lib/permitted-contents/index.d.ts +1 -1
- package/lib/permitted-contents/matches-selector.d.ts +1 -6
- package/lib/permitted-contents/order.d.ts +1 -7
- package/lib/permitted-contents/recursive-branch.d.ts +1 -7
- package/lib/permitted-contents/represent-transparent-nodes.d.ts +3 -7
- package/lib/permitted-contents/start.d.ts +1 -6
- package/lib/permitted-contents/types.d.ts +29 -29
- package/lib/permitted-contents/utils.d.ts +1 -1
- package/lib/placeholder-label-option/index.d.ts +1 -1
- package/lib/require-accessible-name/index.d.ts +2 -2
- package/lib/require-datetime/index.d.ts +2 -2
- package/lib/require-datetime/types.d.ts +2 -2
- package/lib/required-attr/index.d.ts +3 -3
- package/lib/required-element/index.d.ts +2 -2
- package/lib/required-h1/index.d.ts +3 -3
- package/lib/use-list/index.d.ts +2 -2
- package/lib/wai-aria/checkings/_.d.ts +12 -6
- package/lib/wai-aria/checkings/default-value.d.ts +3 -7
- package/lib/wai-aria/checkings/deprecated-props.d.ts +4 -8
- package/lib/wai-aria/checkings/implicit-props.d.ts +4 -8
- package/lib/wai-aria/checkings/no-global-prop.d.ts +3 -7
- package/lib/wai-aria/checkings/required-owned-elements.d.ts +3 -7
- package/lib/wai-aria/checkings/required-prop copy.d.ts +12 -6
- package/lib/wai-aria/checkings/required-prop.d.ts +6 -12
- package/lib/wai-aria/checkings/unadopted-explicit-roles.d.ts +12 -6
- package/lib/wai-aria/checkings/value.d.ts +6 -15
- package/lib/wai-aria/index.d.ts +1 -1
- package/lib/wai-aria/types.d.ts +10 -10
- package/lib/xxx/index.d.ts +2 -0
- package/lib/xxx/index.js +32 -0
- package/package.json +13 -15
- package/test/attr-check.spec.js +77 -0
- package/test/attr-duplication/index.spec.js +159 -0
- package/test/attr-value-quotes/index.spec.js +133 -0
- package/test/case-sensitive-attr-name/index.spec.js +65 -0
- package/test/case-sensitive-tag-name/index.spec.js +80 -0
- package/test/character-reference/index.spec.js +57 -0
- package/test/class-naming/index.spec.js +470 -0
- package/test/create-message.spec.js +497 -0
- package/test/deprecated-attr/index.spec.js +48 -0
- package/test/deprecated-element/index.spec.js +48 -0
- package/test/disallowed-element/index.spec.js +90 -0
- package/test/doctype/index.spec.js +50 -0
- package/test/end-tag/index.spec.js +162 -0
- package/test/id-duplication/index.spec.js +47 -0
- package/test/ineffective-attr/index.spec.js +31 -0
- package/test/invalid-attr/index.spec.js +1632 -0
- package/test/label-has-control/index.spec.js +29 -0
- package/test/landmark-roles/index.spec.js +187 -0
- package/test/no-boolean-attr-value/index.spec.js +41 -0
- package/test/no-default-value/index.spec.js +74 -0
- package/test/no-empty-palpable-content/index.spec.js +115 -0
- package/test/no-hard-code-id/index.spec.js +100 -0
- package/test/no-refer-to-non-existent-id/index.spec.js +254 -0
- package/test/no-use-event-handler-attr/index.spec.js +57 -0
- package/test/permitted-contents/choice.spec.js +174 -0
- package/test/permitted-contents/count-pattern.spec.js +308 -0
- package/test/permitted-contents/index.spec.js +1371 -0
- package/test/permitted-contents/matches-selector.spec.js +59 -0
- package/test/permitted-contents/order.spec.js +351 -0
- package/test/permitted-contents/recursive-branch.spec.js +41 -0
- package/test/permitted-contents/represent-transparent-nodes.spec.js +24 -0
- package/test/permitted-contents/start.spec.js +67 -0
- package/test/placeholder-label-option/index.spec.js +113 -0
- package/test/require-accessible-name/index.spec.js +446 -0
- package/test/require-datetime/index.spec.js +54 -0
- package/test/require-datetime/utils.spec.js +52 -0
- package/test/required-attr/index.spec.js +414 -0
- package/test/required-element/index.spec.js +188 -0
- package/test/required-h1/index.spec.js +69 -0
- package/test/use-list/index.spec.js +109 -0
- package/test/wai-aria/checkings/value.spec.js +33 -0
- package/test/wai-aria/index.spec.js +1173 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
const { mlRuleTest } = require('markuplint');
|
|
2
|
+
|
|
3
|
+
const rule = require('../../lib/class-naming').default;
|
|
4
|
+
|
|
5
|
+
test('pass class name', async () => {
|
|
6
|
+
const { violations } = await mlRuleTest(
|
|
7
|
+
rule,
|
|
8
|
+
`
|
|
9
|
+
<div class="c-root">
|
|
10
|
+
<div class="c-root__el"></div>
|
|
11
|
+
<div class="c-root__el2"></div>
|
|
12
|
+
</div>
|
|
13
|
+
`,
|
|
14
|
+
{
|
|
15
|
+
rule: {
|
|
16
|
+
severity: 'error',
|
|
17
|
+
value: '/^c-[a-z]+/',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
);
|
|
21
|
+
expect(violations.length).toBe(0);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('unmatched class name', async () => {
|
|
25
|
+
const { violations } = await mlRuleTest(
|
|
26
|
+
rule,
|
|
27
|
+
`
|
|
28
|
+
<div class="c-root">
|
|
29
|
+
<div class="c-root__el"></div>
|
|
30
|
+
<div class="c-root__el2"></div>
|
|
31
|
+
</div>
|
|
32
|
+
`,
|
|
33
|
+
{
|
|
34
|
+
rule: {
|
|
35
|
+
severity: 'error',
|
|
36
|
+
value: '/^c-[a-z]+/',
|
|
37
|
+
},
|
|
38
|
+
nodeRule: [
|
|
39
|
+
{
|
|
40
|
+
selector: '[class^="c-"]:not([class*="__"])',
|
|
41
|
+
rule: {
|
|
42
|
+
severity: 'error',
|
|
43
|
+
value: '/^c-[a-z]+__[a-z0-9]+/',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
expect(violations).toStrictEqual([
|
|
50
|
+
{
|
|
51
|
+
severity: 'error',
|
|
52
|
+
message: 'The "c-root" class name is unmatched with the below patterns: "/^c-[a-z]+__[a-z0-9]+/"',
|
|
53
|
+
line: 2,
|
|
54
|
+
col: 15,
|
|
55
|
+
raw: 'c-root',
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('childNodeRules', async () => {
|
|
61
|
+
const { violations } = await mlRuleTest(
|
|
62
|
+
rule,
|
|
63
|
+
`
|
|
64
|
+
<div class="c-root">
|
|
65
|
+
<div class="c-root_x"></div>
|
|
66
|
+
</div>
|
|
67
|
+
`,
|
|
68
|
+
{
|
|
69
|
+
rule: {
|
|
70
|
+
severity: 'error',
|
|
71
|
+
value: '/^c-[a-z]+/',
|
|
72
|
+
},
|
|
73
|
+
childNodeRule: [
|
|
74
|
+
{
|
|
75
|
+
selector: '[class^="c-"]:not([class*="__"])',
|
|
76
|
+
rule: {
|
|
77
|
+
severity: 'error',
|
|
78
|
+
value: '/^c-[a-z]+__[a-z0-9]+/',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
expect(violations).toStrictEqual([
|
|
85
|
+
{
|
|
86
|
+
severity: 'error',
|
|
87
|
+
message: 'The "c-root_x" class name is unmatched with the below patterns: "/^c-[a-z]+__[a-z0-9]+/"',
|
|
88
|
+
line: 3,
|
|
89
|
+
col: 16,
|
|
90
|
+
raw: 'c-root_x',
|
|
91
|
+
},
|
|
92
|
+
]);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('unmatched class name (2)', async () => {
|
|
96
|
+
const { violations } = await mlRuleTest(
|
|
97
|
+
rule,
|
|
98
|
+
`
|
|
99
|
+
<div class="c-root">
|
|
100
|
+
<div class="c-root__x">
|
|
101
|
+
<div class="c-root__y"></div>
|
|
102
|
+
<main>
|
|
103
|
+
<div class="hoge"></div>
|
|
104
|
+
</main>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
`,
|
|
108
|
+
{
|
|
109
|
+
rule: {
|
|
110
|
+
severity: 'error',
|
|
111
|
+
value: '/^c-[a-z]+/',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
);
|
|
115
|
+
expect(violations).toStrictEqual([
|
|
116
|
+
{
|
|
117
|
+
severity: 'error',
|
|
118
|
+
message: 'The "hoge" class name is unmatched with the below patterns: "/^c-[a-z]+/"',
|
|
119
|
+
line: 6,
|
|
120
|
+
col: 18,
|
|
121
|
+
raw: 'hoge',
|
|
122
|
+
},
|
|
123
|
+
]);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('multi pattern', async () => {
|
|
127
|
+
const { violations } = await mlRuleTest(
|
|
128
|
+
rule,
|
|
129
|
+
`
|
|
130
|
+
<div class="c-root">
|
|
131
|
+
<div class="c-root__el"></div>
|
|
132
|
+
<div class="exceptional"></div>
|
|
133
|
+
</div>
|
|
134
|
+
`,
|
|
135
|
+
{
|
|
136
|
+
rule: {
|
|
137
|
+
severity: 'error',
|
|
138
|
+
value: ['/^c-[a-z]+/', 'exceptional'],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
);
|
|
142
|
+
expect(violations.length).toBe(0);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('childNodeRules multi selectors', async () => {
|
|
146
|
+
const { violations } = await mlRuleTest(
|
|
147
|
+
rule,
|
|
148
|
+
`
|
|
149
|
+
<div class="c-root">
|
|
150
|
+
<div class="c-root__x">
|
|
151
|
+
<div class="c-root__y"></div>
|
|
152
|
+
<main>
|
|
153
|
+
<div class="hoge"></div>
|
|
154
|
+
</main>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
`,
|
|
158
|
+
{
|
|
159
|
+
rule: {
|
|
160
|
+
severity: 'error',
|
|
161
|
+
value: '/^c-[a-z]+/',
|
|
162
|
+
},
|
|
163
|
+
childNodeRule: [
|
|
164
|
+
{
|
|
165
|
+
selector: ':where([class^="c-"]:not([class*="__"]))',
|
|
166
|
+
rule: {
|
|
167
|
+
severity: 'error',
|
|
168
|
+
value: '/^c-[a-z]+__[a-z0-9]+/',
|
|
169
|
+
},
|
|
170
|
+
inheritance: true,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
selector: 'main',
|
|
174
|
+
rule: {
|
|
175
|
+
severity: 'error',
|
|
176
|
+
value: 'hoge2',
|
|
177
|
+
},
|
|
178
|
+
inheritance: true,
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
);
|
|
183
|
+
expect(violations).toStrictEqual([
|
|
184
|
+
{
|
|
185
|
+
severity: 'error',
|
|
186
|
+
message: 'The "hoge" class name is unmatched with the below patterns: "hoge2"',
|
|
187
|
+
line: 6,
|
|
188
|
+
col: 18,
|
|
189
|
+
raw: 'hoge',
|
|
190
|
+
},
|
|
191
|
+
]);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test('childNodeRules multi selectors (No error)', async () => {
|
|
195
|
+
const { violations } = await mlRuleTest(
|
|
196
|
+
rule,
|
|
197
|
+
`
|
|
198
|
+
<div class="c-root">
|
|
199
|
+
<div class="c-root__x">
|
|
200
|
+
<div class="c-root__y"></div>
|
|
201
|
+
<main>
|
|
202
|
+
<div class="hoge"></div>
|
|
203
|
+
</main>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
`,
|
|
207
|
+
{
|
|
208
|
+
rule: {
|
|
209
|
+
severity: 'error',
|
|
210
|
+
value: '/^c-[a-z]+/',
|
|
211
|
+
},
|
|
212
|
+
childNodeRule: [
|
|
213
|
+
{
|
|
214
|
+
selector: ':where([class^="c-"]:not([class*="__"]))',
|
|
215
|
+
rule: {
|
|
216
|
+
severity: 'error',
|
|
217
|
+
value: '/^c-[a-z]+__[a-z0-9]+/',
|
|
218
|
+
},
|
|
219
|
+
inheritance: true,
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
selector: 'main',
|
|
223
|
+
rule: {
|
|
224
|
+
severity: 'error',
|
|
225
|
+
value: '/^(?!c-).+$/',
|
|
226
|
+
},
|
|
227
|
+
inheritance: true,
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
);
|
|
232
|
+
expect(violations.length).toBe(0);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
test('Dynamic value', async () => {
|
|
236
|
+
const { violations } = await mlRuleTest(rule, '<div className={style}></div>', {
|
|
237
|
+
rule: {
|
|
238
|
+
value: '/^c-[a-z]+/',
|
|
239
|
+
},
|
|
240
|
+
parser: {
|
|
241
|
+
'.*': '@markuplint/jsx-parser',
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
expect(violations.length).toBe(0);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test('regexSelector', async () => {
|
|
248
|
+
const { violations } = await mlRuleTest(
|
|
249
|
+
rule,
|
|
250
|
+
`<section class="Card">
|
|
251
|
+
<div class="Card__header">
|
|
252
|
+
<div class="Heading"><h3 class="Heading__lv3">Title</h3></div>
|
|
253
|
+
</div>
|
|
254
|
+
<div class="Card__body">
|
|
255
|
+
<div class="List">
|
|
256
|
+
<ul class="List__group">
|
|
257
|
+
<li>...</li>
|
|
258
|
+
<li>...</li>
|
|
259
|
+
<li>...</li>
|
|
260
|
+
</ul>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
</section>
|
|
264
|
+
|
|
265
|
+
<section class="Card">
|
|
266
|
+
<div class="Card__header">
|
|
267
|
+
<!-- 👎 It is "Card" scope, Don't use the element owned "Heading" -->
|
|
268
|
+
<h3 class="Heading__lv3">Title</h3>
|
|
269
|
+
</div>
|
|
270
|
+
<div class="Card__body">
|
|
271
|
+
<div class="Card__body-el">...</div>
|
|
272
|
+
<!-- 👎 It is "Card" scope, Don't use the element owned "List" -->
|
|
273
|
+
<ul class="List__group">
|
|
274
|
+
<li>...</li>
|
|
275
|
+
<li>...</li>
|
|
276
|
+
<li>...</li>
|
|
277
|
+
</ul>
|
|
278
|
+
<div class="List">
|
|
279
|
+
<!-- 👎 It is not "Card" scope instead of "List" scope here -->
|
|
280
|
+
<ul class="Card__list">
|
|
281
|
+
<li>...</li>
|
|
282
|
+
<li>...</li>
|
|
283
|
+
<li>...</li>
|
|
284
|
+
</ul>
|
|
285
|
+
</div>
|
|
286
|
+
</div>
|
|
287
|
+
</section>
|
|
288
|
+
`,
|
|
289
|
+
{
|
|
290
|
+
rule: '/.+/',
|
|
291
|
+
childNodeRule: [
|
|
292
|
+
{
|
|
293
|
+
regexSelector: {
|
|
294
|
+
attrName: 'class',
|
|
295
|
+
attrValue: '/^(?<BlockName>[A-Z][a-z0-9]+)(?:__[a-z][a-z0-9-]+)?$/',
|
|
296
|
+
},
|
|
297
|
+
rule: {
|
|
298
|
+
value: ['/^{{BlockName}}__[a-z][a-z0-9-]+$/', '/^([A-Z][a-z0-9]+)$/'],
|
|
299
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
},
|
|
304
|
+
);
|
|
305
|
+
expect(violations).toStrictEqual([
|
|
306
|
+
{
|
|
307
|
+
severity: 'warning',
|
|
308
|
+
line: 19,
|
|
309
|
+
col: 14,
|
|
310
|
+
raw: 'Heading__lv3',
|
|
311
|
+
message:
|
|
312
|
+
'The "Heading__lv3" class name is unmatched with the below patterns: "/^Card__[a-z][a-z0-9-]+$/", "/^([A-Z][a-z0-9]+)$/"',
|
|
313
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
severity: 'warning',
|
|
317
|
+
line: 24,
|
|
318
|
+
col: 14,
|
|
319
|
+
raw: 'List__group',
|
|
320
|
+
message:
|
|
321
|
+
'The "List__group" class name is unmatched with the below patterns: "/^Card__[a-z][a-z0-9-]+$/", "/^([A-Z][a-z0-9]+)$/"',
|
|
322
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
severity: 'warning',
|
|
326
|
+
line: 31,
|
|
327
|
+
col: 15,
|
|
328
|
+
raw: 'Card__list',
|
|
329
|
+
message:
|
|
330
|
+
'The "Card__list" class name is unmatched with the below patterns: "/^List__[a-z][a-z0-9-]+$/", "/^([A-Z][a-z0-9]+)$/"',
|
|
331
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
332
|
+
},
|
|
333
|
+
]);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
test('regexSelector inheritance', async () => {
|
|
337
|
+
const { violations } = await mlRuleTest(
|
|
338
|
+
rule,
|
|
339
|
+
`<html>
|
|
340
|
+
<body class="Card">
|
|
341
|
+
<div class="Card__heading">
|
|
342
|
+
<div class="Heading">
|
|
343
|
+
<div class="Heading__text"></div>
|
|
344
|
+
</div>
|
|
345
|
+
</div>
|
|
346
|
+
<div class="Card__text"></div>
|
|
347
|
+
<div class="Heading_text"></div>
|
|
348
|
+
<div class="Card_text"></div>
|
|
349
|
+
</body>
|
|
350
|
+
</html>
|
|
351
|
+
`,
|
|
352
|
+
{
|
|
353
|
+
rule: '/.+/',
|
|
354
|
+
childNodeRule: [
|
|
355
|
+
{
|
|
356
|
+
regexSelector: {
|
|
357
|
+
attrName: 'class',
|
|
358
|
+
attrValue: '/^(?<BlockName>[A-Z][a-z0-9]+)(?:__[a-z][a-z0-9-]+)?$/',
|
|
359
|
+
},
|
|
360
|
+
inheritance: true,
|
|
361
|
+
rule: {
|
|
362
|
+
value: ['/^{{BlockName}}__[a-z][a-z0-9-]+$/', '/^([A-Z][a-z0-9]+)$/'],
|
|
363
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
364
|
+
},
|
|
365
|
+
},
|
|
366
|
+
],
|
|
367
|
+
},
|
|
368
|
+
);
|
|
369
|
+
expect(violations).toStrictEqual([
|
|
370
|
+
{
|
|
371
|
+
severity: 'warning',
|
|
372
|
+
line: 9,
|
|
373
|
+
col: 14,
|
|
374
|
+
message:
|
|
375
|
+
'The "Heading_text" class name is unmatched with the below patterns: "/^Card__[a-z][a-z0-9-]+$/", "/^([A-Z][a-z0-9]+)$/"',
|
|
376
|
+
raw: 'Heading_text',
|
|
377
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
severity: 'warning',
|
|
381
|
+
line: 10,
|
|
382
|
+
col: 14,
|
|
383
|
+
message:
|
|
384
|
+
'The "Card_text" class name is unmatched with the below patterns: "/^Card__[a-z][a-z0-9-]+$/", "/^([A-Z][a-z0-9]+)$/"',
|
|
385
|
+
raw: 'Card_text',
|
|
386
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
387
|
+
},
|
|
388
|
+
]);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
test('pug + regexSelector', async () => {
|
|
392
|
+
const { violations } = await mlRuleTest(
|
|
393
|
+
rule,
|
|
394
|
+
`section.Card
|
|
395
|
+
.Card__header
|
|
396
|
+
.Heading
|
|
397
|
+
h3.Heading__lv3 Title
|
|
398
|
+
.Card__body
|
|
399
|
+
.List
|
|
400
|
+
ul.List__group
|
|
401
|
+
li ...
|
|
402
|
+
li ...
|
|
403
|
+
li ...
|
|
404
|
+
section.Card
|
|
405
|
+
.Card__header
|
|
406
|
+
// 👎 It is "Card" scope, Don't use the element owned "Heading"
|
|
407
|
+
h3.Heading__lv3 Title
|
|
408
|
+
.Card__body
|
|
409
|
+
.Card__body-el ...
|
|
410
|
+
// 👎 It is "Card" scope, Don't use the element owned "List"
|
|
411
|
+
ul.List__group
|
|
412
|
+
li ...
|
|
413
|
+
li ...
|
|
414
|
+
li ...
|
|
415
|
+
.List
|
|
416
|
+
// 👎 It is not "Card" scope instead of "List" scope here
|
|
417
|
+
ul.Card__list
|
|
418
|
+
li ...
|
|
419
|
+
li ...
|
|
420
|
+
li ...
|
|
421
|
+
`,
|
|
422
|
+
{
|
|
423
|
+
parser: {
|
|
424
|
+
'.*': '@markuplint/pug-parser',
|
|
425
|
+
},
|
|
426
|
+
rule: '/.+/',
|
|
427
|
+
childNodeRule: [
|
|
428
|
+
{
|
|
429
|
+
regexSelector: {
|
|
430
|
+
attrName: 'class',
|
|
431
|
+
attrValue: '/^(?<BlockName>[A-Z][a-z0-9]+)(?:__[a-z][a-z0-9-]+)?$/',
|
|
432
|
+
},
|
|
433
|
+
rule: {
|
|
434
|
+
value: ['/^{{BlockName}}__[a-z][a-z0-9-]+$/', '/^([A-Z][a-z0-9]+)$/'],
|
|
435
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
],
|
|
439
|
+
},
|
|
440
|
+
);
|
|
441
|
+
expect(violations).toStrictEqual([
|
|
442
|
+
{
|
|
443
|
+
severity: 'warning',
|
|
444
|
+
line: 14,
|
|
445
|
+
col: 5,
|
|
446
|
+
message:
|
|
447
|
+
'The "Heading__lv3" class name is unmatched with the below patterns: "/^Card__[a-z][a-z0-9-]+$/", "/^([A-Z][a-z0-9]+)$/"',
|
|
448
|
+
raw: '.Heading__lv3',
|
|
449
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
severity: 'warning',
|
|
453
|
+
line: 18,
|
|
454
|
+
col: 5,
|
|
455
|
+
message:
|
|
456
|
+
'The "List__group" class name is unmatched with the below patterns: "/^Card__[a-z][a-z0-9-]+$/", "/^([A-Z][a-z0-9]+)$/"',
|
|
457
|
+
raw: '.List__group',
|
|
458
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
severity: 'warning',
|
|
462
|
+
line: 24,
|
|
463
|
+
col: 6,
|
|
464
|
+
message:
|
|
465
|
+
'The "Card__list" class name is unmatched with the below patterns: "/^List__[a-z][a-z0-9-]+$/", "/^([A-Z][a-z0-9]+)$/"',
|
|
466
|
+
raw: '.Card__list',
|
|
467
|
+
reason: 'Do not allow include the element in a no-own block.',
|
|
468
|
+
},
|
|
469
|
+
]);
|
|
470
|
+
});
|