testaro-issues 0.1.0 → 0.2.1

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/dist/index.cjs CHANGED
@@ -4709,7 +4709,7 @@ const rulesData = {
4709
4709
  "what": "font element is obsolete"
4710
4710
  }
4711
4711
  },
4712
- "variable": { "E-^AAA.4_1_2.H91.Input[-a-zA-Z]+.Name": {
4712
+ "variable": { "E-AAA\\.4_1_2\\.H91\\.Input[-a-zA-Z]+\\.Name": {
4713
4713
  "issueID": "inputNoText",
4714
4714
  "quality": 1,
4715
4715
  "what": "input element has no accessible name"
@@ -6384,7 +6384,7 @@ const rulesData = {
6384
6384
  "quality": 1,
6385
6385
  "what": "script-src content attribute blocks a script"
6386
6386
  },
6387
- "Discarding unrecognized token .+ from value of attribute role. Browsers ignore any token that is not a defined ARIA non-abstract role.*": {
6387
+ "Discarding unrecognized token .+ from value of attribute role\\. Browsers ignore any token that is not a defined ARIA non-abstract role.*": {
6388
6388
  "issueID": "roleBad",
6389
6389
  "quality": 1,
6390
6390
  "what": "Invalid role"
@@ -6444,7 +6444,7 @@ const rulesData = {
6444
6444
  "quality": 1,
6445
6445
  "what": "Attribute has an empty value"
6446
6446
  },
6447
- "Potentially bad value .+ for attribute .+ on element .+Typo for .+?.*": {
6447
+ "Potentially bad value .+ for attribute .+ on element .+Typo for .+\\?.*": {
6448
6448
  "issueID": "attributeValueRisk",
6449
6449
  "quality": 1,
6450
6450
  "what": "Attribute value may be a typographical error"
@@ -6699,7 +6699,7 @@ const rulesData = {
6699
6699
  "quality": 1,
6700
6700
  "what": "Invalid closing tag"
6701
6701
  },
6702
- "End tag [a-z]+.": {
6702
+ "End tag [a-z]+\\.": {
6703
6703
  "issueID": "elementClosure",
6704
6704
  "quality": 1,
6705
6705
  "what": "Closing tag of an ineligible element"
@@ -7930,7 +7930,7 @@ const rulesData = {
7930
7930
  "quality": 1,
7931
7931
  "what": "script-src content attribute blocks a script"
7932
7932
  },
7933
- "Discarding unrecognized token .+ from value of attribute role. Browsers ignore any token that is not a defined ARIA non-abstract role.*": {
7933
+ "Discarding unrecognized token .+ from value of attribute role\\. Browsers ignore any token that is not a defined ARIA non-abstract role.*": {
7934
7934
  "issueID": "roleBad",
7935
7935
  "quality": 1,
7936
7936
  "what": "Invalid role"
@@ -7990,7 +7990,7 @@ const rulesData = {
7990
7990
  "quality": 1,
7991
7991
  "what": "Attribute has an empty value"
7992
7992
  },
7993
- "Potentially bad value .+ for attribute .+ on element .+Typo for .+?.*": {
7993
+ "Potentially bad value .+ for attribute .+ on element .+Typo for .+\\?.*": {
7994
7994
  "issueID": "attributeValueRisk",
7995
7995
  "quality": 1,
7996
7996
  "what": "Attribute value may be a typographical error"
@@ -8245,7 +8245,7 @@ const rulesData = {
8245
8245
  "quality": 1,
8246
8246
  "what": "Invalid closing tag"
8247
8247
  },
8248
- "End tag [a-z]+.": {
8248
+ "End tag [a-z]+\\.": {
8249
8249
  "issueID": "elementClosure",
8250
8250
  "quality": 1,
8251
8251
  "what": "Closing tag of an ineligible element"
@@ -9678,33 +9678,42 @@ const issues = deepFreeze(issuesData);
9678
9678
  const rules = deepFreeze(rulesData);
9679
9679
  const makeIssueRules = (ruleTable, issueTable = issues) => {
9680
9680
  const errors = [];
9681
- const checkEntry = (toolID, groupName, ruleID, entry) => {
9681
+ const checkEntry = (engineID, variabilityName, ruleID, entry) => {
9682
9682
  const { issueID, quality, what } = entry;
9683
- if (typeof issueID !== "string" || !(issueID in issueTable)) errors.push(`${toolID}.${groupName}.${ruleID} has an invalid issueID (${JSON.stringify(issueID)})`);
9684
- if (typeof quality !== "number") errors.push(`${toolID}.${groupName}.${ruleID} has a non-numeric quality (${JSON.stringify(quality)})`);
9685
- if (typeof what !== "string") errors.push(`${toolID}.${groupName}.${ruleID} has a non-string what (${JSON.stringify(what)})`);
9683
+ if (!ruleID.length) errors.push(`${engineID}.${variabilityName} has a rule with an empty ruleID`);
9684
+ if (typeof issueID !== "string" || !issueID.length || !(issueID in issueTable)) errors.push(`${engineID}.${variabilityName}.${ruleID} has an invalid issueID (${JSON.stringify(issueID)})`);
9685
+ if (typeof quality !== "number") errors.push(`${engineID}.${variabilityName}.${ruleID} has a non-numeric quality (${JSON.stringify(quality)})`);
9686
+ if (typeof what !== "string" || !what.length) errors.push(`${engineID}.${variabilityName}.${ruleID} has a non-string or empty what (${JSON.stringify(what)})`);
9687
+ if (variabilityName === "variable") {
9688
+ if (!/[.*+?^${}()|[\]\\]/.test(ruleID)) errors.push(`${engineID}.${variabilityName}.${ruleID} has no regex metacharacters, so it should be an invariant rule`);
9689
+ else try {
9690
+ new RegExp(ruleID);
9691
+ } catch (error) {
9692
+ errors.push(`${engineID}.${variabilityName}.${ruleID} is not a valid regular expression (${error.message})`);
9693
+ }
9694
+ }
9686
9695
  };
9687
9696
  const issueRules = {};
9688
- Object.entries(ruleTable).forEach(([toolID, { invariant, variable }]) => {
9697
+ Object.entries(ruleTable).forEach(([engineID, { invariant, variable }]) => {
9689
9698
  Object.entries(invariant).forEach(([ruleID, entry]) => {
9690
- checkEntry(toolID, "invariant", ruleID, entry);
9699
+ checkEntry(engineID, "invariant", ruleID, entry);
9691
9700
  const { issueID } = entry;
9692
9701
  issueRules[issueID] ??= {};
9693
- issueRules[issueID][toolID] ??= {
9702
+ issueRules[issueID][engineID] ??= {
9694
9703
  invariant: [],
9695
9704
  variable: []
9696
9705
  };
9697
- issueRules[issueID][toolID].invariant.push(ruleID);
9706
+ issueRules[issueID][engineID].invariant.push(ruleID);
9698
9707
  });
9699
9708
  Object.entries(variable).forEach(([ruleID, entry]) => {
9700
- checkEntry(toolID, "variable", ruleID, entry);
9709
+ checkEntry(engineID, "variable", ruleID, entry);
9701
9710
  const { issueID } = entry;
9702
9711
  issueRules[issueID] ??= {};
9703
- issueRules[issueID][toolID] ??= {
9712
+ issueRules[issueID][engineID] ??= {
9704
9713
  invariant: [],
9705
9714
  variable: []
9706
9715
  };
9707
- issueRules[issueID][toolID].variable.push(ruleID);
9716
+ issueRules[issueID][engineID].variable.push(ruleID);
9708
9717
  });
9709
9718
  });
9710
9719
  if (errors.length) throw new Error(`${errors[0]} (1 of ${errors.length} problems found)`);
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  //#region src/index.d.ts
2
+ type IssueID = keyof typeof issuesData;
2
3
  interface Issue {
3
4
  summary: string;
4
5
  why: string;
@@ -15,11 +16,10 @@ interface RuleEntry {
15
16
  quality: number;
16
17
  what: string;
17
18
  }
18
- interface ToolRules {
19
+ interface EngineRules {
19
20
  invariant: Record<string, RuleEntry>;
20
21
  variable: Record<string, RuleEntry>;
21
22
  }
22
- type IssueID = keyof typeof issuesData;
23
23
  declare const issuesData: {
24
24
  readonly ignorable: {
25
25
  readonly summary: 'ignorable';
@@ -2236,11 +2236,11 @@ declare const issuesData: {
2236
2236
  };
2237
2237
  };
2238
2238
  declare const issues: Readonly<Record<string, Issue>>;
2239
- declare const rules: Readonly<Record<string, ToolRules>>;
2240
- declare const makeIssueRules: (ruleTable: Record<string, ToolRules>, issueTable?: Record<string, Issue>) => Record<string, Record<string, IssueRuleGroup>>;
2239
+ declare const rules: Readonly<Record<string, EngineRules>>;
2240
+ declare const makeIssueRules: (ruleTable: Record<string, EngineRules>, issueTable?: Record<string, Issue>) => Record<string, Record<string, IssueRuleGroup>>;
2241
2241
  declare const getEditableData: () => {
2242
2242
  issues: Readonly<Record<string, Issue>>;
2243
- rules: Readonly<Record<string, ToolRules>>;
2243
+ rules: Readonly<Record<string, EngineRules>>;
2244
2244
  issueRules: Record<string, Record<string, IssueRuleGroup>>;
2245
2245
  };
2246
2246
  declare const issueRules: Record<string, Record<string, IssueRuleGroup>>;
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  //#region src/index.d.ts
2
+ type IssueID = keyof typeof issuesData;
2
3
  interface Issue {
3
4
  summary: string;
4
5
  why: string;
@@ -15,11 +16,10 @@ interface RuleEntry {
15
16
  quality: number;
16
17
  what: string;
17
18
  }
18
- interface ToolRules {
19
+ interface EngineRules {
19
20
  invariant: Record<string, RuleEntry>;
20
21
  variable: Record<string, RuleEntry>;
21
22
  }
22
- type IssueID = keyof typeof issuesData;
23
23
  declare const issuesData: {
24
24
  readonly ignorable: {
25
25
  readonly summary: 'ignorable';
@@ -2236,11 +2236,11 @@ declare const issuesData: {
2236
2236
  };
2237
2237
  };
2238
2238
  declare const issues: Readonly<Record<string, Issue>>;
2239
- declare const rules: Readonly<Record<string, ToolRules>>;
2240
- declare const makeIssueRules: (ruleTable: Record<string, ToolRules>, issueTable?: Record<string, Issue>) => Record<string, Record<string, IssueRuleGroup>>;
2239
+ declare const rules: Readonly<Record<string, EngineRules>>;
2240
+ declare const makeIssueRules: (ruleTable: Record<string, EngineRules>, issueTable?: Record<string, Issue>) => Record<string, Record<string, IssueRuleGroup>>;
2241
2241
  declare const getEditableData: () => {
2242
2242
  issues: Readonly<Record<string, Issue>>;
2243
- rules: Readonly<Record<string, ToolRules>>;
2243
+ rules: Readonly<Record<string, EngineRules>>;
2244
2244
  issueRules: Record<string, Record<string, IssueRuleGroup>>;
2245
2245
  };
2246
2246
  declare const issueRules: Record<string, Record<string, IssueRuleGroup>>;
package/dist/index.mjs CHANGED
@@ -4708,7 +4708,7 @@ const rulesData = {
4708
4708
  "what": "font element is obsolete"
4709
4709
  }
4710
4710
  },
4711
- "variable": { "E-^AAA.4_1_2.H91.Input[-a-zA-Z]+.Name": {
4711
+ "variable": { "E-AAA\\.4_1_2\\.H91\\.Input[-a-zA-Z]+\\.Name": {
4712
4712
  "issueID": "inputNoText",
4713
4713
  "quality": 1,
4714
4714
  "what": "input element has no accessible name"
@@ -6383,7 +6383,7 @@ const rulesData = {
6383
6383
  "quality": 1,
6384
6384
  "what": "script-src content attribute blocks a script"
6385
6385
  },
6386
- "Discarding unrecognized token .+ from value of attribute role. Browsers ignore any token that is not a defined ARIA non-abstract role.*": {
6386
+ "Discarding unrecognized token .+ from value of attribute role\\. Browsers ignore any token that is not a defined ARIA non-abstract role.*": {
6387
6387
  "issueID": "roleBad",
6388
6388
  "quality": 1,
6389
6389
  "what": "Invalid role"
@@ -6443,7 +6443,7 @@ const rulesData = {
6443
6443
  "quality": 1,
6444
6444
  "what": "Attribute has an empty value"
6445
6445
  },
6446
- "Potentially bad value .+ for attribute .+ on element .+Typo for .+?.*": {
6446
+ "Potentially bad value .+ for attribute .+ on element .+Typo for .+\\?.*": {
6447
6447
  "issueID": "attributeValueRisk",
6448
6448
  "quality": 1,
6449
6449
  "what": "Attribute value may be a typographical error"
@@ -6698,7 +6698,7 @@ const rulesData = {
6698
6698
  "quality": 1,
6699
6699
  "what": "Invalid closing tag"
6700
6700
  },
6701
- "End tag [a-z]+.": {
6701
+ "End tag [a-z]+\\.": {
6702
6702
  "issueID": "elementClosure",
6703
6703
  "quality": 1,
6704
6704
  "what": "Closing tag of an ineligible element"
@@ -7929,7 +7929,7 @@ const rulesData = {
7929
7929
  "quality": 1,
7930
7930
  "what": "script-src content attribute blocks a script"
7931
7931
  },
7932
- "Discarding unrecognized token .+ from value of attribute role. Browsers ignore any token that is not a defined ARIA non-abstract role.*": {
7932
+ "Discarding unrecognized token .+ from value of attribute role\\. Browsers ignore any token that is not a defined ARIA non-abstract role.*": {
7933
7933
  "issueID": "roleBad",
7934
7934
  "quality": 1,
7935
7935
  "what": "Invalid role"
@@ -7989,7 +7989,7 @@ const rulesData = {
7989
7989
  "quality": 1,
7990
7990
  "what": "Attribute has an empty value"
7991
7991
  },
7992
- "Potentially bad value .+ for attribute .+ on element .+Typo for .+?.*": {
7992
+ "Potentially bad value .+ for attribute .+ on element .+Typo for .+\\?.*": {
7993
7993
  "issueID": "attributeValueRisk",
7994
7994
  "quality": 1,
7995
7995
  "what": "Attribute value may be a typographical error"
@@ -8244,7 +8244,7 @@ const rulesData = {
8244
8244
  "quality": 1,
8245
8245
  "what": "Invalid closing tag"
8246
8246
  },
8247
- "End tag [a-z]+.": {
8247
+ "End tag [a-z]+\\.": {
8248
8248
  "issueID": "elementClosure",
8249
8249
  "quality": 1,
8250
8250
  "what": "Closing tag of an ineligible element"
@@ -9677,33 +9677,42 @@ const issues = deepFreeze(issuesData);
9677
9677
  const rules = deepFreeze(rulesData);
9678
9678
  const makeIssueRules = (ruleTable, issueTable = issues) => {
9679
9679
  const errors = [];
9680
- const checkEntry = (toolID, groupName, ruleID, entry) => {
9680
+ const checkEntry = (engineID, variabilityName, ruleID, entry) => {
9681
9681
  const { issueID, quality, what } = entry;
9682
- if (typeof issueID !== "string" || !(issueID in issueTable)) errors.push(`${toolID}.${groupName}.${ruleID} has an invalid issueID (${JSON.stringify(issueID)})`);
9683
- if (typeof quality !== "number") errors.push(`${toolID}.${groupName}.${ruleID} has a non-numeric quality (${JSON.stringify(quality)})`);
9684
- if (typeof what !== "string") errors.push(`${toolID}.${groupName}.${ruleID} has a non-string what (${JSON.stringify(what)})`);
9682
+ if (!ruleID.length) errors.push(`${engineID}.${variabilityName} has a rule with an empty ruleID`);
9683
+ if (typeof issueID !== "string" || !issueID.length || !(issueID in issueTable)) errors.push(`${engineID}.${variabilityName}.${ruleID} has an invalid issueID (${JSON.stringify(issueID)})`);
9684
+ if (typeof quality !== "number") errors.push(`${engineID}.${variabilityName}.${ruleID} has a non-numeric quality (${JSON.stringify(quality)})`);
9685
+ if (typeof what !== "string" || !what.length) errors.push(`${engineID}.${variabilityName}.${ruleID} has a non-string or empty what (${JSON.stringify(what)})`);
9686
+ if (variabilityName === "variable") {
9687
+ if (!/[.*+?^${}()|[\]\\]/.test(ruleID)) errors.push(`${engineID}.${variabilityName}.${ruleID} has no regex metacharacters, so it should be an invariant rule`);
9688
+ else try {
9689
+ new RegExp(ruleID);
9690
+ } catch (error) {
9691
+ errors.push(`${engineID}.${variabilityName}.${ruleID} is not a valid regular expression (${error.message})`);
9692
+ }
9693
+ }
9685
9694
  };
9686
9695
  const issueRules = {};
9687
- Object.entries(ruleTable).forEach(([toolID, { invariant, variable }]) => {
9696
+ Object.entries(ruleTable).forEach(([engineID, { invariant, variable }]) => {
9688
9697
  Object.entries(invariant).forEach(([ruleID, entry]) => {
9689
- checkEntry(toolID, "invariant", ruleID, entry);
9698
+ checkEntry(engineID, "invariant", ruleID, entry);
9690
9699
  const { issueID } = entry;
9691
9700
  issueRules[issueID] ??= {};
9692
- issueRules[issueID][toolID] ??= {
9701
+ issueRules[issueID][engineID] ??= {
9693
9702
  invariant: [],
9694
9703
  variable: []
9695
9704
  };
9696
- issueRules[issueID][toolID].invariant.push(ruleID);
9705
+ issueRules[issueID][engineID].invariant.push(ruleID);
9697
9706
  });
9698
9707
  Object.entries(variable).forEach(([ruleID, entry]) => {
9699
- checkEntry(toolID, "variable", ruleID, entry);
9708
+ checkEntry(engineID, "variable", ruleID, entry);
9700
9709
  const { issueID } = entry;
9701
9710
  issueRules[issueID] ??= {};
9702
- issueRules[issueID][toolID] ??= {
9711
+ issueRules[issueID][engineID] ??= {
9703
9712
  invariant: [],
9704
9713
  variable: []
9705
9714
  };
9706
- issueRules[issueID][toolID].variable.push(ruleID);
9715
+ issueRules[issueID][engineID].variable.push(ruleID);
9707
9716
  });
9708
9717
  });
9709
9718
  if (errors.length) throw new Error(`${errors[0]} (1 of ${errors.length} problems found)`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testaro-issues",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "A classification of about 1300 rules of 10 rule engines into about 300 issues. The rule engines are those in the ensemble of Testaro, which tests web pages for front-end quality (accessibility, usability, and standards conformance).",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -15,7 +15,8 @@
15
15
  "dist"
16
16
  ],
17
17
  "scripts": {
18
- "build": "tsdown src/index.ts --format cjs,esm --dts",
18
+ "build": "npm run typecheck && tsdown src/index.ts --format cjs,esm --dts",
19
+ "typecheck": "tsc --noEmit",
19
20
  "prepublishOnly": "npm run build"
20
21
  },
21
22
  "keywords": [