Commit b694ddfa authored by David Sveningsson's avatar David Sveningsson
Browse files

feat: support `.htmlvalidate.js`

fixes #111
parent 43252317
Pipeline #268622855 passed with stages
in 13 minutes and 42 seconds
......@@ -29,6 +29,13 @@ Run with:
## Configuration
Configuration can be added to:
- `.htmlvalidate.js`
- `.htmlvalidate.json`
Configuration files will be searched from the target file and up until either no more parent folders exist or `"root": true` is found.
### `extends`
Configuration can be extended from bundled preset or shareable configurations.
......@@ -148,11 +155,11 @@ path to use a local script (use `<rootDir>` to refer to the path to
By default, configuration is search in the file structure until the root
directory (typically `/`) is found:
- `/home/user/project/src/.htmlvalidate.json`
- `/home/user/project/.htmlvalidate.json`
- `/home/user/.htmlvalidate.json`
- `/home/.htmlvalidate.json`
- `/.htmlvalidate.json`
- `/home/user/project/src/.htmlvalidate.{js,json}`
- `/home/user/project/.htmlvalidate.{js,json}`
- `/home/user/.htmlvalidate.{js,json}`
- `/home/.htmlvalidate.{js,json}`
- `/.htmlvalidate.{js,json}`
By setting the `root` property to `true` the search is stopped. This can be used
to prevent searching from outside the project directory or to use a specific
......@@ -168,8 +175,8 @@ For instance, if `/home/project/.htmlvalidate.json` contains:
only the following files would be searched:
- `/home/user/project/src/.htmlvalidate.json`
- `/home/user/project/.htmlvalidate.json`
- `/home/user/project/src/.htmlvalidate.{js,json}`
- `/home/user/project/.htmlvalidate.{js,json}`
This also affects CLI `--config` and the API, e.g. when using `--config` with a
configuration using `"root": true` will prevent any additional files to be
......
......@@ -11,6 +11,7 @@ Object {
"deprecated": "error",
"element-permitted-content": "off",
"no-self-closing": "error",
"void-content": "error",
},
"transform": Object {},
}
......@@ -70,6 +71,7 @@ Object {
"deprecated": "error",
"element-permitted-content": "off",
"no-self-closing": "error",
"void-content": "error",
},
"transform": Object {},
}
......@@ -162,6 +164,7 @@ Object {
"deprecated": "error",
"element-permitted-content": "off",
"no-self-closing": "error",
"void-content": "error",
},
"transform": Object {},
}
......@@ -222,6 +225,7 @@ Object {
"deprecated": "error",
"element-permitted-content": "off",
"no-self-closing": "error",
"void-content": "error",
},
"transform": Object {},
}
......@@ -282,6 +286,7 @@ Object {
"deprecated": "error",
"element-permitted-content": "error",
"no-self-closing": "error",
"void-content": "error",
},
"transform": Object {},
}
......@@ -343,6 +348,7 @@ Object {
"deprecated": "error",
"element-permitted-content": "error",
"no-self-closing": "error",
"void-content": "error",
},
"transform": Object {},
}
......@@ -374,6 +380,25 @@ Array [
]
`;
exports[`ConfigLoader smoketest test-files/config/js-config/file.html 1`] = `
Object {
"extends": Array [
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "error",
"no-self-closing": "error",
"void-content": "off",
},
"transform": Object {},
}
`;
exports[`ConfigLoader smoketest test-files/config/js-config/file.html 2`] = `Array []`;
exports[`ConfigLoader smoketest test-files/config/off/error/file.html 1`] = `
Object {
"extends": Array [
......@@ -385,6 +410,7 @@ Object {
"deprecated": "error",
"element-permitted-content": "error",
"no-self-closing": "error",
"void-content": "error",
},
"transform": Object {},
}
......@@ -427,6 +453,7 @@ Object {
"deprecated": "error",
"element-permitted-content": "error",
"no-self-closing": "error",
"void-content": "off",
},
"transform": Object {},
}
......@@ -445,6 +472,7 @@ Object {
"deprecated": "error",
"element-permitted-content": "error",
"no-self-closing": "error",
"void-content": "warn",
},
"transform": Object {},
}
......
......@@ -97,8 +97,11 @@ describe("ConfigLoader", () => {
expect.objectContaining({
mockFilenames: [
/* ConfigMock adds all visited filenames to this array */
path.resolve("/.htmlvalidate.js"),
path.resolve("/.htmlvalidate.json"),
path.resolve("/path/.htmlvalidate.js"),
path.resolve("/path/.htmlvalidate.json"),
path.resolve("/path/to/.htmlvalidate.js"),
path.resolve("/path/to/.htmlvalidate.json"),
],
})
......@@ -113,7 +116,9 @@ describe("ConfigLoader", () => {
expect.objectContaining({
mockFilenames: [
/* ConfigMock adds all visited filenames to this array */
path.resolve("/project/root/.htmlvalidate.js"),
path.resolve("/project/root/.htmlvalidate.json"),
path.resolve("/project/root/src/.htmlvalidate.js"),
path.resolve("/project/root/src/.htmlvalidate.json"),
],
})
......@@ -137,8 +142,11 @@ describe("ConfigLoader", () => {
expect.objectContaining({
mockFilenames: [
/* ConfigMock adds all visited filenames to this array */
path.resolve("/.htmlvalidate.js"),
path.resolve("/.htmlvalidate.json"),
path.resolve("/path/.htmlvalidate.js"),
path.resolve("/path/.htmlvalidate.json"),
path.resolve("/path/to/.htmlvalidate.js"),
path.resolve("/path/to/.htmlvalidate.json"),
],
})
......@@ -159,8 +167,11 @@ describe("ConfigLoader", () => {
expect.objectContaining({
mockFilenames: [
/* ConfigMock adds all visited filenames to this array */
path.resolve("/.htmlvalidate.js"),
path.resolve("/.htmlvalidate.json"),
path.resolve("/path/.htmlvalidate.js"),
path.resolve("/path/.htmlvalidate.json"),
path.resolve("/path/to/.htmlvalidate.js"),
path.resolve("/path/to/.htmlvalidate.json"),
],
})
......@@ -207,7 +218,12 @@ describe("ConfigLoader", () => {
/* extract only relevant rules from configuration to avoid bloat when new
* rules are added to recommended config */
function filter(src: Config): ConfigData {
const whitelisted = ["no-self-closing", "deprecated", "element-permitted-content"];
const whitelisted = [
"no-self-closing",
"deprecated",
"element-permitted-content",
"void-content",
];
const data = { rules: {}, ...src.get() };
data.rules = Object.keys(data.rules)
.filter((key) => whitelisted.includes(key))
......
......@@ -63,10 +63,16 @@ export class ConfigLoader {
// eslint-disable-next-line no-constant-condition
while (true) {
const search = path.join(current, ".htmlvalidate.json");
const jsonFile = path.join(current, ".htmlvalidate.json");
if (fs.existsSync(jsonFile)) {
const local = this.configClass.fromFile(jsonFile);
found = true;
config = local.merge(config);
}
if (fs.existsSync(search)) {
const local = this.configClass.fromFile(search);
const jsFile = path.join(current, ".htmlvalidate.js");
if (fs.existsSync(jsFile)) {
const local = this.configClass.fromFile(jsFile);
found = true;
config = local.merge(config);
}
......
module.exports = {
rules: {
"void-content": "off",
},
};
<!-- configuration to disable rule, should not yield anything -->
<br></br>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment