@markuplint/rules 3.0.0-canary.3 → 3.0.0-dev.176

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 (163) hide show
  1. package/README.md +1 -1
  2. package/lib/attr-check.d.ts +20 -8
  3. package/lib/attr-check.js +31 -22
  4. package/lib/attr-duplication/index.d.ts +3 -1
  5. package/lib/attr-duplication/index.js +2 -1
  6. package/lib/attr-value-quotes/index.d.ts +2 -2
  7. package/lib/case-sensitive-attr-name/index.d.ts +1 -1
  8. package/lib/case-sensitive-tag-name/index.d.ts +1 -1
  9. package/lib/character-reference/index.d.ts +1 -1
  10. package/lib/class-naming/index.d.ts +1 -1
  11. package/lib/class-naming/index.js +2 -4
  12. package/lib/create-message.d.ts +13 -2
  13. package/lib/create-message.js +4 -3
  14. package/lib/debug.js +1 -1
  15. package/lib/deprecated-attr/index.d.ts +3 -1
  16. package/lib/deprecated-element/index.d.ts +3 -1
  17. package/lib/deprecated-element/index.js +2 -2
  18. package/lib/disallowed-element/index.d.ts +1 -1
  19. package/lib/doctype/index.d.ts +2 -2
  20. package/lib/end-tag/index.d.ts +1 -1
  21. package/lib/helpers.d.ts +37 -22
  22. package/lib/helpers.js +27 -14
  23. package/lib/id-duplication/index.d.ts +3 -1
  24. package/lib/index.d.ts +243 -3
  25. package/lib/index.js +6 -1
  26. package/lib/ineffective-attr/index.d.ts +3 -1
  27. package/lib/ineffective-attr/index.js +2 -5
  28. package/lib/invalid-attr/index.d.ts +39 -12
  29. package/lib/invalid-attr/index.js +153 -27
  30. package/lib/label-has-control/index.d.ts +3 -1
  31. package/lib/landmark-roles/index.d.ts +3 -3
  32. package/lib/landmark-roles/index.js +9 -5
  33. package/lib/no-boolean-attr-value/index.d.ts +3 -1
  34. package/lib/no-default-value/index.d.ts +3 -1
  35. package/lib/no-empty-palpable-content/index.d.ts +3 -3
  36. package/lib/no-empty-palpable-content/index.js +11 -3
  37. package/lib/no-hard-code-id/index.d.ts +3 -1
  38. package/lib/no-refer-to-non-existent-id/index.d.ts +9 -4
  39. package/lib/no-refer-to-non-existent-id/index.js +65 -5
  40. package/lib/no-use-event-handler-attr/index.d.ts +2 -2
  41. package/lib/no-use-event-handler-attr/index.js +4 -4
  42. package/lib/permitted-contents/choice.d.ts +8 -1
  43. package/lib/permitted-contents/choice.js +37 -2
  44. package/lib/permitted-contents/complex-branch.d.ts +8 -1
  45. package/lib/permitted-contents/complex-branch.js +4 -2
  46. package/lib/permitted-contents/content-model.d.ts +1 -1
  47. package/lib/permitted-contents/content-model.js +7 -3
  48. package/lib/permitted-contents/count-pattern.d.ts +18 -2
  49. package/lib/permitted-contents/count-pattern.js +71 -64
  50. package/lib/permitted-contents/debug.browser.d.ts +30 -0
  51. package/lib/permitted-contents/debug.browser.js +14 -0
  52. package/lib/permitted-contents/debug.d.ts +2 -1
  53. package/lib/permitted-contents/debug.js +9 -1
  54. package/lib/permitted-contents/index.d.ts +1 -1
  55. package/lib/permitted-contents/index.js +12 -15
  56. package/lib/permitted-contents/matches-selector.d.ts +7 -2
  57. package/lib/permitted-contents/matches-selector.js +8 -6
  58. package/lib/permitted-contents/order.d.ts +8 -1
  59. package/lib/permitted-contents/order.js +25 -15
  60. package/lib/permitted-contents/recursive-branch.d.ts +8 -1
  61. package/lib/permitted-contents/recursive-branch.js +5 -3
  62. package/lib/permitted-contents/represent-transparent-nodes.d.ts +7 -3
  63. package/lib/permitted-contents/represent-transparent-nodes.js +4 -5
  64. package/lib/permitted-contents/start.d.ts +7 -1
  65. package/lib/permitted-contents/start.js +5 -3
  66. package/lib/permitted-contents/transparent.d.ts +2 -2
  67. package/lib/permitted-contents/transparent.js +11 -14
  68. package/lib/permitted-contents/types.d.ts +35 -28
  69. package/lib/permitted-contents/utils.d.ts +96 -28
  70. package/lib/permitted-contents/utils.js +135 -17
  71. package/lib/placeholder-label-option/index.d.ts +2 -0
  72. package/lib/placeholder-label-option/index.js +88 -0
  73. package/lib/require-accessible-name/index.d.ts +2 -2
  74. package/lib/require-accessible-name/index.js +5 -5
  75. package/lib/require-datetime/index.d.ts +6 -0
  76. package/lib/require-datetime/index.js +34 -0
  77. package/lib/require-datetime/types.d.ts +10 -0
  78. package/lib/require-datetime/types.js +2 -0
  79. package/lib/require-datetime/utils.d.ts +11 -0
  80. package/lib/require-datetime/utils.js +137 -0
  81. package/lib/required-attr/index.d.ts +3 -3
  82. package/lib/required-attr/index.js +19 -16
  83. package/lib/required-element/index.d.ts +2 -2
  84. package/lib/required-element/index.js +3 -2
  85. package/lib/required-h1/index.d.ts +3 -3
  86. package/lib/required-h1/index.js +4 -3
  87. package/lib/use-list/index.d.ts +3 -3
  88. package/lib/use-list/index.js +7 -5
  89. package/lib/wai-aria/checkings/_.d.ts +15 -0
  90. package/lib/wai-aria/checkings/_.js +27 -0
  91. package/lib/wai-aria/checkings/abstract-role.js +1 -1
  92. package/lib/wai-aria/checkings/default-value.d.ts +7 -3
  93. package/lib/wai-aria/checkings/deprecated-props.d.ts +8 -4
  94. package/lib/wai-aria/checkings/disallowed-prop.d.ts +8 -4
  95. package/lib/wai-aria/checkings/disallowed-prop.js +27 -3
  96. package/lib/wai-aria/checkings/implicit-props.d.ts +8 -4
  97. package/lib/wai-aria/checkings/implicit-props.js +3 -2
  98. package/lib/wai-aria/checkings/implicit-role.js +1 -1
  99. package/lib/wai-aria/checkings/interaction-in-hidden.js +3 -1
  100. package/lib/wai-aria/checkings/no-global-prop.d.ts +7 -3
  101. package/lib/wai-aria/checkings/non-existent-role.js +1 -1
  102. package/lib/wai-aria/checkings/permitted-roles.js +1 -1
  103. package/lib/wai-aria/checkings/presentational-children.js +4 -2
  104. package/lib/wai-aria/checkings/required-owned-elements.d.ts +7 -3
  105. package/lib/wai-aria/checkings/required-owned-elements.js +28 -12
  106. package/lib/wai-aria/checkings/required-prop copy.d.ts +15 -0
  107. package/lib/wai-aria/checkings/required-prop copy.js +27 -0
  108. package/lib/wai-aria/checkings/required-prop.d.ts +12 -6
  109. package/lib/wai-aria/checkings/unadopted-explicit-roles.d.ts +15 -0
  110. package/lib/wai-aria/checkings/unadopted-explicit-roles.js +17 -0
  111. package/lib/wai-aria/checkings/value.d.ts +15 -6
  112. package/lib/wai-aria/checkings/value.js +3 -1
  113. package/lib/wai-aria/index.d.ts +1 -1
  114. package/lib/wai-aria/index.js +13 -12
  115. package/lib/wai-aria/types.d.ts +10 -10
  116. package/lib/xxx/index.d.ts +2 -0
  117. package/lib/xxx/index.js +32 -0
  118. package/package.json +16 -11
  119. package/schema.json +6 -0
  120. package/test/attr-check.spec.js +77 -0
  121. package/test/attr-duplication/index.spec.js +159 -0
  122. package/test/attr-value-quotes/index.spec.js +133 -0
  123. package/test/case-sensitive-attr-name/index.spec.js +65 -0
  124. package/test/case-sensitive-tag-name/index.spec.js +80 -0
  125. package/test/character-reference/index.spec.js +57 -0
  126. package/test/class-naming/index.spec.js +470 -0
  127. package/test/create-message.spec.js +497 -0
  128. package/test/deprecated-attr/index.spec.js +48 -0
  129. package/test/deprecated-element/index.spec.js +48 -0
  130. package/test/disallowed-element/index.spec.js +90 -0
  131. package/test/doctype/index.spec.js +50 -0
  132. package/test/end-tag/index.spec.js +162 -0
  133. package/test/id-duplication/index.spec.js +47 -0
  134. package/test/ineffective-attr/index.spec.js +31 -0
  135. package/test/invalid-attr/index.spec.js +1632 -0
  136. package/test/label-has-control/index.spec.js +29 -0
  137. package/test/landmark-roles/index.spec.js +187 -0
  138. package/test/no-boolean-attr-value/index.spec.js +41 -0
  139. package/test/no-default-value/index.spec.js +74 -0
  140. package/test/no-empty-palpable-content/index.spec.js +115 -0
  141. package/test/no-hard-code-id/index.spec.js +100 -0
  142. package/test/no-refer-to-non-existent-id/index.spec.js +254 -0
  143. package/test/no-use-event-handler-attr/index.spec.js +57 -0
  144. package/test/permitted-contents/choice.spec.js +174 -0
  145. package/test/permitted-contents/count-pattern.spec.js +308 -0
  146. package/test/permitted-contents/index.spec.js +1371 -0
  147. package/test/permitted-contents/matches-selector.spec.js +59 -0
  148. package/test/permitted-contents/order.spec.js +351 -0
  149. package/test/permitted-contents/recursive-branch.spec.js +41 -0
  150. package/test/permitted-contents/represent-transparent-nodes.spec.js +24 -0
  151. package/test/permitted-contents/start.spec.js +67 -0
  152. package/test/placeholder-label-option/index.spec.js +113 -0
  153. package/test/require-accessible-name/index.spec.js +446 -0
  154. package/test/require-datetime/index.spec.js +54 -0
  155. package/test/require-datetime/utils.spec.js +52 -0
  156. package/test/required-attr/index.spec.js +414 -0
  157. package/test/required-element/index.spec.js +188 -0
  158. package/test/required-h1/index.spec.js +69 -0
  159. package/test/use-list/index.spec.js +109 -0
  160. package/test/wai-aria/checkings/value.spec.js +33 -0
  161. package/test/wai-aria/index.spec.js +1173 -0
  162. package/tsconfig.test.json +0 -3
  163. package/tsconfig.tsbuildinfo +0 -1
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ml_core_1 = require("@markuplint/ml-core");
4
+ const ml_spec_1 = require("@markuplint/ml-spec");
4
5
  const helpers_1 = require("../helpers");
5
6
  const abstract_role_1 = require("./checkings/abstract-role");
6
7
  const default_value_1 = require("./checkings/default-value");
@@ -27,7 +28,7 @@ exports.default = (0, ml_core_1.createRule)({
27
28
  disallowSetImplicitRole: true,
28
29
  disallowSetImplicitProps: true,
29
30
  disallowDefaultValue: false,
30
- version: '1.2',
31
+ version: ml_spec_1.ARIA_RECOMMENDED_VERSION,
31
32
  },
32
33
  async verify({ document, report, t }) {
33
34
  await document.walkOn('Element', el => {
@@ -47,8 +48,8 @@ exports.default = (0, ml_core_1.createRule)({
47
48
  }
48
49
  return;
49
50
  }
50
- const computed = (0, ml_core_1.getComputedRole)(document.specs, el, el.rule.option.version);
51
- const { props: propSpecs } = (0, ml_core_1.ariaSpecs)(document.specs, el.rule.option.version);
51
+ const computed = (0, ml_core_1.getComputedRole)(document.specs, el, el.rule.options.version);
52
+ const { props: propSpecs } = (0, ml_core_1.ariaSpecs)(document.specs, el.rule.options.version);
52
53
  if (roleAttr) {
53
54
  if (report((0, non_existent_role_1.checkingNonExistentRole)({ attr: roleAttr }))) {
54
55
  return;
@@ -57,39 +58,39 @@ exports.default = (0, ml_core_1.createRule)({
57
58
  return;
58
59
  }
59
60
  report((0, required_prop_1.checkingRequiredProp)({ el, role: computed.role, propSpecs }));
60
- if (el.rule.option.disallowSetImplicitRole) {
61
+ if (el.rule.options.disallowSetImplicitRole) {
61
62
  report((0, implicit_role_1.checkingImplicitRole)({ attr: roleAttr }));
62
63
  }
63
- if (el.rule.option.permittedAriaRoles) {
64
+ if (el.rule.options.permittedAriaRoles) {
64
65
  report((0, permitted_roles_1.checkingPermittedRoles)({ attr: roleAttr }));
65
66
  }
66
67
  }
67
68
  for (const attr of propAttrs) {
68
69
  report((0, disallowed_prop_1.checkingDisallowedProp)({ attr, role: computed.role, propSpecs }));
69
- if (el.rule.option.checkingDeprecatedProps) {
70
+ if (el.rule.options.checkingDeprecatedProps) {
70
71
  report((0, deprecated_props_1.checkingDeprecatedProps)({ attr, role: computed.role, propSpecs }));
71
72
  }
72
- if (el.rule.option.disallowSetImplicitProps) {
73
+ if (el.rule.options.disallowSetImplicitProps) {
73
74
  const attrSpecs = (0, ml_core_1.getAttrSpecs)(el, document.specs);
74
75
  report((0, implicit_props_1.checkingImplicitProps)({ attr, propSpecs, attrSpecs }));
75
76
  }
76
- if (el.rule.option.checkingValue) {
77
+ if (el.rule.options.checkingValue) {
77
78
  report((0, value_1.checkingValue)({ attr, role: computed.role, propSpecs, booleanish: document.booleanish }));
78
79
  }
79
- if (el.rule.option.disallowDefaultValue) {
80
+ if (el.rule.options.disallowDefaultValue) {
80
81
  report((0, default_value_1.checkingDefaultValue)({ attr, propSpecs }));
81
82
  }
82
83
  if (!computed.role) {
83
84
  report((0, no_global_prop_1.checkingNoGlobalProp)({ attr, propSpecs }));
84
85
  }
85
86
  }
86
- if (el.rule.option.checkingRequiredOwnedElements) {
87
+ if (el.rule.options.checkingRequiredOwnedElements) {
87
88
  report((0, required_owned_elements_1.checkingRequiredOwnedElements)({ el, role: computed.role }));
88
89
  }
89
- if (el.rule.option.checkingPresentationalChildren) {
90
+ if (el.rule.options.checkingPresentationalChildren) {
90
91
  report((0, presentational_children_1.checkingPresentationalChildren)({ el }));
91
92
  }
92
- if (el.rule.option.checkingInteractionInHidden) {
93
+ if (el.rule.options.checkingInteractionInHidden) {
93
94
  report((0, interaction_in_hidden_1.checkingInteractionInHidden)({ el }));
94
95
  }
95
96
  });
@@ -1,13 +1,13 @@
1
1
  import type { ARIAVersion } from '@markuplint/ml-spec';
2
2
  export type Options = {
3
- checkingValue: boolean;
4
- checkingDeprecatedProps: boolean;
5
- permittedAriaRoles: boolean;
6
- checkingRequiredOwnedElements: boolean;
7
- checkingPresentationalChildren: boolean;
8
- checkingInteractionInHidden: boolean;
9
- disallowSetImplicitRole: boolean;
10
- disallowSetImplicitProps: boolean;
11
- disallowDefaultValue: boolean;
12
- version: ARIAVersion;
3
+ checkingValue: boolean;
4
+ checkingDeprecatedProps: boolean;
5
+ permittedAriaRoles: boolean;
6
+ checkingRequiredOwnedElements: boolean;
7
+ checkingPresentationalChildren: boolean;
8
+ checkingInteractionInHidden: boolean;
9
+ disallowSetImplicitRole: boolean;
10
+ disallowSetImplicitProps: boolean;
11
+ disallowDefaultValue: boolean;
12
+ version: ARIAVersion;
13
13
  };
@@ -0,0 +1,2 @@
1
+ declare const _default: Readonly<import('@markuplint/ml-core').RuleSeed<boolean, null>>;
2
+ export default _default;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ml_core_1 = require("@markuplint/ml-core");
4
+ exports.default = (0, ml_core_1.createRule)({
5
+ defaultValue: true,
6
+ defaultOptions: null,
7
+ async verify({ document, report, t }) {
8
+ // Element
9
+ await document.walkOn("Element", (el) => {
10
+ const raw = el.raw.trim();
11
+ if (/./i.test(raw)) {
12
+ report({
13
+ scope: el,
14
+ message: t("It is {0}", "issue"),
15
+ });
16
+ }
17
+ });
18
+ // Attribute
19
+ await document.walkOn("Attr", (attr) => {
20
+ var _a, _b, _c;
21
+ if (/./i.test(attr.name)) {
22
+ report({
23
+ scope: attr,
24
+ line: (_a = attr.nameNode) === null || _a === void 0 ? void 0 : _a.startLine,
25
+ col: (_b = attr.nameNode) === null || _b === void 0 ? void 0 : _b.startCol,
26
+ raw: (_c = attr.nameNode) === null || _c === void 0 ? void 0 : _c.raw,
27
+ message: t("It is {0}", "issue"),
28
+ });
29
+ }
30
+ });
31
+ },
32
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markuplint/rules",
3
- "version": "3.0.0-canary.3+382d1365",
3
+ "version": "3.0.0-dev.176+f6ad62e9",
4
4
  "description": "Built-in rules of markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
@@ -16,18 +16,23 @@
16
16
  "dev": "tsc --build --watch",
17
17
  "clean": "tsc --build --clean"
18
18
  },
19
+ "browser": {
20
+ "./lib/permitted-contents/debug.js": "./lib/permitted-contents/debug.browser.js"
21
+ },
19
22
  "dependencies": {
20
- "@markuplint/html-spec": "3.0.0-canary.5+382d1365",
21
- "@markuplint/ml-core": "3.0.0-canary.5+382d1365",
22
- "@markuplint/ml-spec": "3.0.0-canary.5+382d1365",
23
- "@markuplint/types": "3.0.0-canary.5+382d1365",
23
+ "@markuplint/html-spec": "3.0.0-dev.176+f6ad62e9",
24
+ "@markuplint/ml-core": "3.0.0-dev.176+f6ad62e9",
25
+ "@markuplint/ml-spec": "3.0.0-dev.176+f6ad62e9",
26
+ "@markuplint/selector": "3.0.0-dev.176+f6ad62e9",
27
+ "@markuplint/shared": "3.5.1-dev.3129+f6ad62e9",
28
+ "@markuplint/types": "3.0.0-dev.176+f6ad62e9",
29
+ "@types/debug": "^4.1.7",
24
30
  "@ungap/structured-clone": "^1.0.1",
31
+ "ansi-colors": "^4.1.3",
32
+ "chrono-node": "^2.5.0",
25
33
  "debug": "^4.3.4",
26
- "html-entities": "^2.3.3",
27
- "tslib": "^2.4.0"
28
- },
29
- "devDependencies": {
30
- "@types/debug": "^4.1.7"
34
+ "tslib": "^2.4.1",
35
+ "type-fest": "^3.8.0"
31
36
  },
32
- "gitHead": "382d13653071bd02210d5430403d1a87c840398c"
37
+ "gitHead": "f6ad62e992e1569be4067f1e90d2d6017a658f57"
33
38
  }
package/schema.json CHANGED
@@ -75,9 +75,15 @@
75
75
  "permitted-contents": {
76
76
  "$ref": "https://raw.githubusercontent.com/markuplint/markuplint/main/packages/%40markuplint/rules/src/permitted-contents/schema.json"
77
77
  },
78
+ "placeholder-label-option": {
79
+ "$ref": "https://raw.githubusercontent.com/markuplint/markuplint/main/packages/%40markuplint/rules/src/placeholder-label-option/schema.json"
80
+ },
78
81
  "require-accessible-name": {
79
82
  "$ref": "https://raw.githubusercontent.com/markuplint/markuplint/main/packages/%40markuplint/rules/src/require-accessible-name/schema.json"
80
83
  },
84
+ "require-datetime": {
85
+ "$ref": "https://raw.githubusercontent.com/markuplint/markuplint/main/packages/%40markuplint/rules/src/require-datetime/schema.json"
86
+ },
81
87
  "required-attr": {
82
88
  "$ref": "https://raw.githubusercontent.com/markuplint/markuplint/main/packages/%40markuplint/rules/src/required-attr/schema.json"
83
89
  },
@@ -0,0 +1,77 @@
1
+ const { translator } = require('@markuplint/i18n');
2
+ const { i18n } = require('markuplint');
3
+
4
+ const { valueCheck } = require('../lib/attr-check');
5
+
6
+ let t;
7
+
8
+ beforeAll(async () => {
9
+ const locale = await i18n('en');
10
+ t = translator(locale);
11
+ });
12
+
13
+ test('OneCodePointChar List', () => {
14
+ expect(
15
+ valueCheck(t, 'accesskey', '@ 12', {
16
+ token: 'OneCodePointChar',
17
+ separator: 'space',
18
+ unique: true,
19
+ }),
20
+ ).toStrictEqual([
21
+ 'the "accesskey" attribute expects space-separated list. the the content of the list part includes unexpected characters. It expects one code point character (https://html.spec.whatwg.org/multipage/interaction.html#the-accesskey-attribute)',
22
+ {
23
+ col: 2,
24
+ line: 0,
25
+ raw: '12',
26
+ },
27
+ ]);
28
+ });
29
+
30
+ test('BrowsingContextNameOrKeyword', () => {
31
+ expect(valueCheck(t, 'target', '', 'BrowsingContextNameOrKeyword')).toStrictEqual([
32
+ 'the "target" attribute must not be empty. It expects either "_blank", "_self", "_parent", "_top", "browsing context name" (https://html.spec.whatwg.org/multipage/browsers.html#valid-browsing-context-name-or-keyword)',
33
+ {
34
+ col: 0,
35
+ line: 0,
36
+ raw: '',
37
+ },
38
+ ]);
39
+ });
40
+
41
+ test('BCP47', () => {
42
+ expect(valueCheck(t, 'lang', '', 'BCP47')).toStrictEqual([
43
+ 'the "lang" attribute must not be empty. It expects the BCP47 format (https://tools.ietf.org/rfc/bcp/bcp47.html)',
44
+ {
45
+ col: 0,
46
+ line: 0,
47
+ raw: '',
48
+ },
49
+ ]);
50
+ });
51
+
52
+ test('DateTime', () => {
53
+ expect(valueCheck(t, 'datetime', '200-1-1', 'DateTime')).toStrictEqual([
54
+ 'the year part of the "datetime" attribute expects four or more digits (https://html.spec.whatwg.org/multipage/text-level-semantics.html#datetime-value)',
55
+ {
56
+ col: 0,
57
+ line: 0,
58
+ raw: '200',
59
+ },
60
+ ]);
61
+ expect(valueCheck(t, 'datetime', '2000-1-1', 'DateTime')).toStrictEqual([
62
+ 'the month part of the "datetime" attribute expects two digits (https://html.spec.whatwg.org/multipage/text-level-semantics.html#datetime-value)',
63
+ {
64
+ col: 5,
65
+ line: 0,
66
+ raw: '1',
67
+ },
68
+ ]);
69
+ expect(valueCheck(t, 'datetime', '00:00:00.0000', 'DateTime')).toStrictEqual([
70
+ 'the fractional part part of the "datetime" attribute expects one to three digits (https://html.spec.whatwg.org/multipage/text-level-semantics.html#datetime-value)',
71
+ {
72
+ col: 9,
73
+ line: 0,
74
+ raw: '0000',
75
+ },
76
+ ]);
77
+ });
@@ -0,0 +1,159 @@
1
+ const { mlRuleTest } = require('markuplint');
2
+
3
+ const rule = require('../../lib/attr-duplication').default;
4
+
5
+ test('is test 1', async () => {
6
+ const { violations } = await mlRuleTest(
7
+ rule,
8
+ `
9
+ <div data-attr="value" data-Attr='db' data-attR=tr>
10
+ lorem
11
+ <p>ipsam</p>
12
+ </div>
13
+ `,
14
+ );
15
+
16
+ expect(violations).toStrictEqual([
17
+ {
18
+ severity: 'error',
19
+ message: 'The attribute name is duplicated',
20
+ line: 2,
21
+ col: 26,
22
+ raw: 'data-Attr',
23
+ },
24
+ {
25
+ severity: 'error',
26
+ message: 'The attribute name is duplicated',
27
+ line: 2,
28
+ col: 41,
29
+ raw: 'data-attR',
30
+ },
31
+ ]);
32
+ });
33
+
34
+ test('is test 2', async () => {
35
+ const { violations } = await mlRuleTest(
36
+ rule,
37
+ `
38
+ <div
39
+ data-attr="value"
40
+ data-Attr='db'
41
+ data-attR=tr>
42
+ lorem
43
+ <p>ipsam</p>
44
+ </div>
45
+ `,
46
+ );
47
+
48
+ expect(violations).toStrictEqual([
49
+ {
50
+ severity: 'error',
51
+ message: 'The attribute name is duplicated',
52
+ line: 4,
53
+ col: 4,
54
+ raw: 'data-Attr',
55
+ },
56
+ {
57
+ severity: 'error',
58
+ message: 'The attribute name is duplicated',
59
+ line: 5,
60
+ col: 4,
61
+ raw: 'data-attR',
62
+ },
63
+ ]);
64
+ });
65
+
66
+ test('is test 3', async () => {
67
+ const { violations } = await mlRuleTest(rule, '<img src="/" SRC="/" >', undefined, false, 'ja');
68
+
69
+ expect(violations.map(_ => _.message)).toStrictEqual(['属性名が重複しています']);
70
+ });
71
+
72
+ test('nodeRules disable', async () => {
73
+ const { violations } = await mlRuleTest(rule, '<div><span attr attr></span></div>', {
74
+ nodeRule: [
75
+ {
76
+ selector: 'span',
77
+ rule: false,
78
+ },
79
+ ],
80
+ });
81
+
82
+ expect(violations.length).toStrictEqual(0);
83
+ });
84
+
85
+ test('Vue', async () => {
86
+ const { violations } = await mlRuleTest(rule, '<template><div attr v-bind:attr /></template>', {
87
+ parser: {
88
+ '.*': '@markuplint/vue-parser',
89
+ },
90
+ });
91
+
92
+ expect(violations).toStrictEqual([
93
+ {
94
+ severity: 'error',
95
+ line: 1,
96
+ col: 21,
97
+ message: 'The attribute name is duplicated',
98
+ raw: 'v-bind:attr',
99
+ },
100
+ ]);
101
+ });
102
+
103
+ test('Vue (exception)', async () => {
104
+ const { violations } = await mlRuleTest(
105
+ rule,
106
+ '<template><div class="foo" v-bind:class="bar" style="a: b;" :style="{c: d}" /></template>',
107
+ {
108
+ parser: {
109
+ '.*': '@markuplint/vue-parser',
110
+ },
111
+ },
112
+ );
113
+
114
+ expect(violations.length).toBe(0);
115
+ });
116
+
117
+ test('React', async () => {
118
+ const { violations } = await mlRuleTest(rule, '<div tabindex tabIndex />', {
119
+ parser: {
120
+ '.*': '@markuplint/vue-parser',
121
+ },
122
+ });
123
+
124
+ expect(violations).toStrictEqual([]);
125
+ });
126
+
127
+ test('Pug', async () => {
128
+ const { violations } = await mlRuleTest(rule, '.hoge(class="hoge2")&attributes({class: "hoge3"})', {
129
+ parser: {
130
+ '.*': '@markuplint/pug-parser',
131
+ },
132
+ });
133
+
134
+ expect(violations.length).toBe(0);
135
+ });
136
+
137
+ test('Svelte', async () => {
138
+ const { violations } = await mlRuleTest(
139
+ rule,
140
+ '<div class:selected="{isSelected}" class:focused="{isFocused}"></div>',
141
+ {
142
+ parser: {
143
+ '.*': '@markuplint/svelte-parser',
144
+ },
145
+ },
146
+ );
147
+
148
+ expect(violations.length).toBe(0);
149
+ });
150
+
151
+ test('Astro', async () => {
152
+ const { violations } = await mlRuleTest(rule, '<div class:list="a" class="b"></div>', {
153
+ parser: {
154
+ '.*': '@markuplint/astro-parser',
155
+ },
156
+ });
157
+
158
+ expect(violations.length).toBe(1);
159
+ });
@@ -0,0 +1,133 @@
1
+ const { mlRuleTest } = require('markuplint');
2
+
3
+ const rule = require('../../lib/attr-value-quotes').default;
4
+
5
+ describe('verify', () => {
6
+ test('default', async () => {
7
+ const { violations } = await mlRuleTest(
8
+ rule,
9
+ `
10
+ <div data-attr="value" data-Attr='db' data-attR=tr>
11
+ lorem
12
+ <p>ipsam</p>
13
+ </div>
14
+ `,
15
+ );
16
+ expect(violations).toStrictEqual([
17
+ {
18
+ severity: 'warning',
19
+ message: 'Attribute value is must quote on double quotation mark',
20
+ line: 2,
21
+ col: 26,
22
+ raw: "data-Attr='db'",
23
+ },
24
+ {
25
+ severity: 'warning',
26
+ message: 'Attribute value is must quote on double quotation mark',
27
+ line: 2,
28
+ col: 41,
29
+ raw: 'data-attR=tr',
30
+ },
31
+ ]);
32
+ });
33
+
34
+ test('double', async () => {
35
+ const { violations } = await mlRuleTest(
36
+ rule,
37
+ `
38
+ <div data-attr="value" data-Attr='db' data-attR=tr>
39
+ lorem
40
+ <p>ipsam</p>
41
+ </div>
42
+ `,
43
+ {
44
+ rule: {
45
+ severity: 'error',
46
+ value: 'double',
47
+ options: null,
48
+ },
49
+ },
50
+ );
51
+ expect(violations).toStrictEqual([
52
+ {
53
+ severity: 'error',
54
+ message: 'Attribute value is must quote on double quotation mark',
55
+ line: 2,
56
+ col: 26,
57
+ raw: "data-Attr='db'",
58
+ },
59
+ {
60
+ severity: 'error',
61
+ message: 'Attribute value is must quote on double quotation mark',
62
+ line: 2,
63
+ col: 41,
64
+ raw: 'data-attR=tr',
65
+ },
66
+ ]);
67
+ });
68
+
69
+ test('single', async () => {
70
+ const { violations } = await mlRuleTest(
71
+ rule,
72
+ `
73
+ <div data-attr="value" data-Attr='db' data-attR=tr>
74
+ lorem
75
+ <p>ipsam</p>
76
+ </div>
77
+ `,
78
+ {
79
+ rule: {
80
+ severity: 'error',
81
+ value: 'single',
82
+ options: null,
83
+ },
84
+ },
85
+ );
86
+ expect(violations).toStrictEqual([
87
+ {
88
+ severity: 'error',
89
+ message: 'Attribute value is must quote on single quotation mark',
90
+ line: 2,
91
+ col: 8,
92
+ raw: 'data-attr="value"',
93
+ },
94
+ {
95
+ severity: 'error',
96
+ message: 'Attribute value is must quote on single quotation mark',
97
+ line: 2,
98
+ col: 41,
99
+ raw: 'data-attR=tr',
100
+ },
101
+ ]);
102
+ });
103
+
104
+ test('empty', async () => {
105
+ const { violations } = await mlRuleTest(
106
+ rule,
107
+ `
108
+ <div data-attr>
109
+ lorem
110
+ <p>ipsam</p>
111
+ </div>
112
+ `,
113
+ );
114
+ expect(violations.length).toBe(0);
115
+ });
116
+ });
117
+
118
+ // describe('fix', () => {
119
+ // test('empty', async () => {
120
+ // const { fixedCode } = await mlRuleTest(rule, '<div attr noop=noop foo="bar" hoge=\'fuga\'>', undefined, true);
121
+ // expect(fixedCode).toEqual('<div attr noop="noop" foo="bar" hoge="fuga">');
122
+ // });
123
+
124
+ // test('empty', async () => {
125
+ // const { fixedCode } = await mlRuleTest(
126
+ // rule,
127
+ // '<div attr noop=noop foo="bar" hoge=\'fuga\'>',
128
+ // { rule: 'single' },
129
+ // true,
130
+ // );
131
+ // expect(fixedCode).toEqual("<div attr noop='noop' foo='bar' hoge='fuga'>");
132
+ // });
133
+ // });
@@ -0,0 +1,65 @@
1
+ const { mlRuleTest } = require('markuplint');
2
+
3
+ const rule = require('../../lib/case-sensitive-attr-name').default;
4
+
5
+ describe('verify', () => {
6
+ test('lower case', async () => {
7
+ const { violations } = await mlRuleTest(rule, '<div data-lowercase></div>');
8
+ expect(violations).toStrictEqual([]);
9
+ });
10
+
11
+ test('upper case', async () => {
12
+ const { violations } = await mlRuleTest(rule, '<div data-UPPERCASE="value"></div>');
13
+ expect(violations[0].severity).toBe('warning');
14
+ expect(violations[0].message).toBe('Attribute names of HTML elements should be lowercase');
15
+ expect(violations[0].raw).toBe('data-UPPERCASE');
16
+ });
17
+
18
+ test('upper case', async () => {
19
+ const { violations } = await mlRuleTest(rule, '<div data-UPPERCASE="value"></div>', {
20
+ rule: {
21
+ severity: 'error',
22
+ value: 'upper',
23
+ options: null,
24
+ },
25
+ });
26
+ expect(violations[0].severity).toBe('error');
27
+ expect(violations[0].message).toBe('Attribute names of HTML elements must be uppercase');
28
+ });
29
+
30
+ test('upper case', async () => {
31
+ const { violations } = await mlRuleTest(rule, '<div data-uppercase="value"></div>', {
32
+ rule: {
33
+ severity: 'error',
34
+ value: 'upper',
35
+ options: null,
36
+ },
37
+ });
38
+ expect(violations[0].severity).toBe('error');
39
+ expect(violations[0].message).toBe('Attribute names of HTML elements must be uppercase');
40
+ });
41
+
42
+ test('upper case', async () => {
43
+ const { violations } = await mlRuleTest(rule, '<div DATA-UPPERCASE="value"></div>', {
44
+ rule: { severity: 'error', value: 'upper' },
45
+ });
46
+ expect(violations.length).toBe(0);
47
+ });
48
+
49
+ test('svg', async () => {
50
+ const { violations } = await mlRuleTest(rule, '<svg viewBox="0 0 100 100"></svg>');
51
+ expect(violations.length).toBe(0);
52
+ });
53
+ });
54
+
55
+ // describe('fix', () => {
56
+ // test('upper case', async () => {
57
+ // const { fixedCode } = await mlRuleTest(rule, '<DIV DATA-LOWERCASE></DIV>', undefined, true);
58
+ // expect(fixedCode).toBe('<DIV data-lowercase></DIV>');
59
+ // });
60
+
61
+ // test('upper case', async () => {
62
+ // const { fixedCode } = await mlRuleTest(rule, '<DIV data-lowercase></DIV>', { rule: 'upper' }, true);
63
+ // expect(fixedCode).toBe('<DIV DATA-LOWERCASE></DIV>');
64
+ // });
65
+ // });