diff --git a/src/core/defaults.js b/src/core/defaults.js index 625182ac0a..d73627b537 100644 --- a/src/core/defaults.js +++ b/src/core/defaults.js @@ -2,6 +2,7 @@ * Sets the core defaults */ export const name = "core/defaults"; +import { rule as checkCharset } from "./linter-rules/check-charset"; import { rule as checkInternalSlots } from "./linter-rules/check-internal-slots"; import { rule as checkPunctuation } from "./linter-rules/check-punctuation"; import linter from "./linter"; @@ -14,7 +15,8 @@ linter.register( noHeadinglessSectionsRule, checkPunctuation, localRefsExist, - checkInternalSlots + checkInternalSlots, + checkCharset ); export const coreDefaults = { @@ -24,6 +26,7 @@ export const coreDefaults = { "check-punctuation": false, "local-refs-exist": true, "check-internal-slots": false, + "check-charset": false, }, pluralize: false, specStatus: "base", diff --git a/src/core/linter-rules/check-charset.js b/src/core/linter-rules/check-charset.js new file mode 100644 index 0000000000..fc38015106 --- /dev/null +++ b/src/core/linter-rules/check-charset.js @@ -0,0 +1,52 @@ +/** + * Linter rule "check-charset". + * + * Checks whether the document has `` properly. + */ +import LinterRule from "../LinterRule"; +import { lang as defaultLang } from "../l10n"; + +const name = "check-charset"; +const meta = { + en: { + description: `Document must only contain one \`\` tag with charset set to 'utf-8'`, + howToFix: `Add this line in your document \`\` section - \`\` or set charset to "utf-8" if not set already.`, + }, +}; + +// Fall back to english, if language is missing +const lang = defaultLang in meta ? defaultLang : "en"; + +/** + * Runs linter rule. + * + * @param {Object} conf The ReSpec config. + * @param {Document} doc The document to be checked. + */ +function linterFunction(conf, doc) { + const metas = doc.querySelectorAll("meta[charset]"); + const val = []; + for (const meta of metas) { + val.push( + meta + .getAttribute("charset") + .trim() + .toLowerCase() + ); + } + const utfExists = val.includes("utf-8"); + + //only a single meta[charset] and is set to utf-8, correct case + if (utfExists && metas.length === 1) { + return []; + } + //if more than one meta[charset] tag defined along with utf-8 + //or + //no meta[charset] present in the document + return { + name, + occurrences: metas.length, + ...meta[lang], + }; +} +export const rule = new LinterRule(name, linterFunction); diff --git a/tests/spec/core/linter-rules/check-charset-spec.js b/tests/spec/core/linter-rules/check-charset-spec.js new file mode 100644 index 0000000000..37cc837ca9 --- /dev/null +++ b/tests/spec/core/linter-rules/check-charset-spec.js @@ -0,0 +1,72 @@ +describe("Core Linter Rule - 'check-charset'", () => { + const ruleName = "check-charset"; + const config = { + lint: { [ruleName]: true }, + }; + let rule; + beforeAll(async () => { + rule = await new Promise(resolve => { + require([`core/linter-rules/${ruleName}`], ({ rule }) => resolve(rule)); + }); + }); + + it("checks if meta[charset] is set to utf-8", async () => { + const doc = document.implementation.createHTMLDocument("test doc"); + doc.head.innerHTML = ` + + + ReSpec + `; + + const results = await rule.lint(config, doc); + expect(results.length).toBe(0); + }); + + it("doesn't give an error when written in capitals", async () => { + const doc = document.implementation.createHTMLDocument("test doc"); + doc.head.innerHTML = ` + + + ReSpec + `; + + const results = await rule.lint(config, doc); + expect(results.length).toBe(0); + }); + + it("checks if meta[charset] is present or not", async () => { + const doc = document.implementation.createHTMLDocument("test doc"); + doc.head.innerHTML = ` + + ReSpec + `; + + const results = await rule.lint(config, doc); + expect(results.occurrences).toBe(0); + }); + + it("returns error when more then one meta[charset] present", async () => { + const doc = document.implementation.createHTMLDocument("test doc"); + doc.head.innerHTML = ` + + + + ReSpec + `; + + const results = await rule.lint(config, doc); + expect(results.occurrences).toBe(2); + }); + + it("return error when some other charset defined", async () => { + const doc = document.implementation.createHTMLDocument("test doc"); + doc.head.innerHTML = ` + + + ReSpec + `; + + const results = await rule.lint(config, doc); + expect(results.occurrences).toBe(1); + }); +}); diff --git a/tests/spec/w3c/defaults-spec.js b/tests/spec/w3c/defaults-spec.js index 33e897acda..7da93ddf46 100644 --- a/tests/spec/w3c/defaults-spec.js +++ b/tests/spec/w3c/defaults-spec.js @@ -15,6 +15,7 @@ describe("W3C — Defaults", () => { "local-refs-exist": true, "check-punctuation": false, "check-internal-slots": false, + "check-charset": false, }); expect(rsConf.highlightVars).toEqual(true); expect(rsConf.license).toEqual("w3c-software-doc"); @@ -51,6 +52,7 @@ describe("W3C — Defaults", () => { "check-punctuation": false, "fake-linter-rule": "foo", "check-internal-slots": true, + "check-charset": false, }); expect(rsConf.highlightVars).toEqual(false); expect(rsConf.license).toEqual("c0");