@markuplint/rules 3.8.0 → 3.9.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/helpers.d.ts +2 -5
- package/lib/index.d.ts +240 -99
- package/lib/permitted-contents/utils.d.ts +90 -41
- package/lib/wai-aria/checkings/_.d.ts +12 -6
- package/lib/wai-aria/checkings/disallowed-prop.d.ts +8 -4
- package/lib/wai-aria/checkings/required-prop copy.d.ts +12 -6
- package/lib/wai-aria/checkings/unadopted-explicit-roles.d.ts +12 -6
- package/lib/xxx/index.d.ts +2 -0
- package/lib/xxx/index.js +32 -0
- package/package.json +11 -13
- 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,50 @@
|
|
|
1
|
+
const { mlRuleTest } = require('markuplint');
|
|
2
|
+
|
|
3
|
+
const rule = require('../../lib/doctype').default;
|
|
4
|
+
|
|
5
|
+
test('valid', async () => {
|
|
6
|
+
const { violations } = await mlRuleTest(
|
|
7
|
+
rule,
|
|
8
|
+
`
|
|
9
|
+
<!doctype html>
|
|
10
|
+
<html></html>
|
|
11
|
+
`,
|
|
12
|
+
);
|
|
13
|
+
expect(violations.length).toBe(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('missing doctype', async () => {
|
|
17
|
+
const { violations } = await mlRuleTest(rule, '<html></html>');
|
|
18
|
+
expect(violations).toStrictEqual([
|
|
19
|
+
{
|
|
20
|
+
severity: 'error',
|
|
21
|
+
message: 'Require doctype',
|
|
22
|
+
line: 1,
|
|
23
|
+
col: 1,
|
|
24
|
+
raw: '',
|
|
25
|
+
},
|
|
26
|
+
]);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('document fragment', async () => {
|
|
30
|
+
const { violations } = await mlRuleTest(rule, '<div></div>');
|
|
31
|
+
expect(violations.length).toBe(0);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('obsolete doctypes', async () => {
|
|
35
|
+
const { violations } = await mlRuleTest(
|
|
36
|
+
rule,
|
|
37
|
+
`
|
|
38
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
39
|
+
<div></div>
|
|
40
|
+
`,
|
|
41
|
+
{ rule: 'always' },
|
|
42
|
+
);
|
|
43
|
+
expect(violations[0]).toStrictEqual({
|
|
44
|
+
severity: 'error',
|
|
45
|
+
raw: '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
|
|
46
|
+
line: 2,
|
|
47
|
+
col: 3,
|
|
48
|
+
message: 'Never declare obsolete doctype',
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
const { mlRuleTest } = require('markuplint');
|
|
2
|
+
|
|
3
|
+
const rule = require('../../lib/end-tag').default;
|
|
4
|
+
|
|
5
|
+
it('basic', async () => {
|
|
6
|
+
expect((await mlRuleTest(rule, '<html><body></body></html>')).violations.length).toBe(0);
|
|
7
|
+
expect((await mlRuleTest(rule, '<html><body></body>')).violations).toStrictEqual([
|
|
8
|
+
{
|
|
9
|
+
severity: 'warning',
|
|
10
|
+
line: 1,
|
|
11
|
+
col: 1,
|
|
12
|
+
message: 'Missing the end tag',
|
|
13
|
+
raw: '<html>',
|
|
14
|
+
},
|
|
15
|
+
]);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('HTML', async () => {
|
|
19
|
+
expect((await mlRuleTest(rule, '<div><span><span /></div>')).violations).toStrictEqual([
|
|
20
|
+
{
|
|
21
|
+
severity: 'warning',
|
|
22
|
+
line: 1,
|
|
23
|
+
col: 6,
|
|
24
|
+
message: 'Missing the end tag',
|
|
25
|
+
raw: '<span>',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
severity: 'warning',
|
|
29
|
+
line: 1,
|
|
30
|
+
col: 12,
|
|
31
|
+
message: 'Missing the end tag',
|
|
32
|
+
raw: '<span />',
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('HTML', async () => {
|
|
38
|
+
expect((await mlRuleTest(rule, '<div><img><img /></div>')).violations).toStrictEqual([]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('SVG', async () => {
|
|
42
|
+
expect(
|
|
43
|
+
(
|
|
44
|
+
await mlRuleTest(
|
|
45
|
+
rule,
|
|
46
|
+
`<svg>
|
|
47
|
+
<defs>
|
|
48
|
+
<clipPath>
|
|
49
|
+
<circle />
|
|
50
|
+
<circle></circle>
|
|
51
|
+
</clipPath>
|
|
52
|
+
</defs>
|
|
53
|
+
</svg>`,
|
|
54
|
+
)
|
|
55
|
+
).violations,
|
|
56
|
+
).toStrictEqual([]);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('pug', async () => {
|
|
60
|
+
expect(
|
|
61
|
+
(
|
|
62
|
+
await mlRuleTest(
|
|
63
|
+
rule,
|
|
64
|
+
`html
|
|
65
|
+
body
|
|
66
|
+
p text`,
|
|
67
|
+
{
|
|
68
|
+
parser: {
|
|
69
|
+
'.*': '@markuplint/pug-parser',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
)
|
|
73
|
+
).violations.length,
|
|
74
|
+
).toBe(0);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('React', async () => {
|
|
78
|
+
expect(
|
|
79
|
+
(
|
|
80
|
+
await mlRuleTest(rule, '<div><span><span /></div>', {
|
|
81
|
+
parser: {
|
|
82
|
+
'.*': '@markuplint/jsx-parser',
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
).violations,
|
|
86
|
+
).toStrictEqual([
|
|
87
|
+
{
|
|
88
|
+
severity: 'error',
|
|
89
|
+
line: 1,
|
|
90
|
+
col: 6,
|
|
91
|
+
message: "JSX element 'span' has no corresponding closing tag.",
|
|
92
|
+
raw: '',
|
|
93
|
+
},
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('Vue', async () => {
|
|
98
|
+
expect(
|
|
99
|
+
(
|
|
100
|
+
await mlRuleTest(rule, '<template><div><span><span /></div></template>', {
|
|
101
|
+
parser: {
|
|
102
|
+
'.*': '@markuplint/vue-parser',
|
|
103
|
+
},
|
|
104
|
+
})
|
|
105
|
+
).violations,
|
|
106
|
+
).toStrictEqual([
|
|
107
|
+
{
|
|
108
|
+
severity: 'warning',
|
|
109
|
+
line: 1,
|
|
110
|
+
col: 16,
|
|
111
|
+
message: 'Missing the end tag',
|
|
112
|
+
raw: '<span>',
|
|
113
|
+
},
|
|
114
|
+
]);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('Svelte', async () => {
|
|
118
|
+
expect(
|
|
119
|
+
(
|
|
120
|
+
await mlRuleTest(rule, '<div><span><span /></div>', {
|
|
121
|
+
parser: {
|
|
122
|
+
'.*': '@markuplint/svelte-parser',
|
|
123
|
+
},
|
|
124
|
+
})
|
|
125
|
+
).violations,
|
|
126
|
+
).toStrictEqual([
|
|
127
|
+
{
|
|
128
|
+
severity: 'warning',
|
|
129
|
+
line: 1,
|
|
130
|
+
col: 6,
|
|
131
|
+
message: 'Missing the end tag',
|
|
132
|
+
raw: '<span>',
|
|
133
|
+
},
|
|
134
|
+
]);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('Astro', async () => {
|
|
138
|
+
expect(
|
|
139
|
+
(
|
|
140
|
+
await mlRuleTest(rule, '<div><span><span /></div>', {
|
|
141
|
+
parser: {
|
|
142
|
+
'.*': '@markuplint/astro-parser',
|
|
143
|
+
},
|
|
144
|
+
})
|
|
145
|
+
).violations,
|
|
146
|
+
).toStrictEqual([
|
|
147
|
+
{
|
|
148
|
+
severity: 'warning',
|
|
149
|
+
line: 1,
|
|
150
|
+
col: 1,
|
|
151
|
+
message: 'Missing the end tag',
|
|
152
|
+
raw: '<div>',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
severity: 'warning',
|
|
156
|
+
line: 1,
|
|
157
|
+
col: 6,
|
|
158
|
+
message: 'Missing the end tag',
|
|
159
|
+
raw: '<span>',
|
|
160
|
+
},
|
|
161
|
+
]);
|
|
162
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const { mlRuleTest } = require('markuplint');
|
|
2
|
+
|
|
3
|
+
const rule = require('../../lib/id-duplication').default;
|
|
4
|
+
|
|
5
|
+
test('id-duplication', async () => {
|
|
6
|
+
const { violations } = await mlRuleTest(rule, '<div id="a"><p id="a"></p></div>');
|
|
7
|
+
expect(violations).toStrictEqual([
|
|
8
|
+
{
|
|
9
|
+
severity: 'error',
|
|
10
|
+
message: 'The value of the "id" attribute is duplicated',
|
|
11
|
+
line: 1,
|
|
12
|
+
col: 16,
|
|
13
|
+
raw: 'id="a"',
|
|
14
|
+
},
|
|
15
|
+
]);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('id-duplication', async () => {
|
|
19
|
+
const { violations } = await mlRuleTest(rule, '<div id="a"></div>');
|
|
20
|
+
expect(violations.length).toBe(0);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('id-duplication', async () => {
|
|
24
|
+
const { violations } = await mlRuleTest(rule, '<div id="a"></div><div id="a"></div><div id="a"></div>');
|
|
25
|
+
expect(violations.length).toBe(2);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('id-duplication', async () => {
|
|
29
|
+
const { violations } = await mlRuleTest(rule, '<div id="a"></div><div id="b"></div><div id="c"></div>');
|
|
30
|
+
expect(violations.length).toBe(0);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('in Vue', async () => {
|
|
34
|
+
const { violations } = await mlRuleTest(
|
|
35
|
+
rule,
|
|
36
|
+
`<template>
|
|
37
|
+
<div v-if="bool"><span :id="uuid"></span></div>
|
|
38
|
+
<div v-else><span :id="uuid"></span></div>
|
|
39
|
+
</template>`,
|
|
40
|
+
{
|
|
41
|
+
parser: {
|
|
42
|
+
'.*': '@markuplint/vue-parser',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
expect(violations.length).toBe(0);
|
|
47
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const { mlRuleTest } = require('markuplint');
|
|
2
|
+
|
|
3
|
+
const rule = require('../../lib/ineffective-attr').default;
|
|
4
|
+
|
|
5
|
+
test('script[defer]', async () => {
|
|
6
|
+
const { violations } = await mlRuleTest(rule, '<script defer>const foo = "foo";</script>');
|
|
7
|
+
|
|
8
|
+
expect(violations).toStrictEqual([
|
|
9
|
+
{
|
|
10
|
+
severity: 'warning',
|
|
11
|
+
line: 1,
|
|
12
|
+
col: 9,
|
|
13
|
+
message: 'The "defer" attribute is ineffective. It doesn\'t need the attribute',
|
|
14
|
+
raw: 'defer',
|
|
15
|
+
},
|
|
16
|
+
]);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('script[src][type=module][defer]', async () => {
|
|
20
|
+
const { violations } = await mlRuleTest(rule, '<script type="module" src="path/to" defer></script>');
|
|
21
|
+
|
|
22
|
+
expect(violations).toStrictEqual([
|
|
23
|
+
{
|
|
24
|
+
severity: 'warning',
|
|
25
|
+
line: 1,
|
|
26
|
+
col: 37,
|
|
27
|
+
message: 'The "defer" attribute is ineffective. It doesn\'t need the attribute',
|
|
28
|
+
raw: 'defer',
|
|
29
|
+
},
|
|
30
|
+
]);
|
|
31
|
+
});
|