Skip to content
Commits on Source (28)
......@@ -81,10 +81,10 @@ Node:
parallel:
matrix:
- VERSION:
- 14
- 16
- 17
- 18
- 20
image: "node:${VERSION}"
HTML-validate:
......@@ -92,7 +92,6 @@ HTML-validate:
parallel:
matrix:
- VERSION:
- 4
- 5
- 6
- 7
......
# html-validate-vue changelog
## [6.0.0](https://gitlab.com/html-validate/html-validate-vue/compare/v5.1.4...v6.0.0) (2023-06-04)
### ⚠ BREAKING CHANGES
- **deps:** require html-validate v5 or later
- **deps:** require nodejs v16 or later
### Features
- **deps:** require html-validate v5 or later ([3423114](https://gitlab.com/html-validate/html-validate-vue/commit/34231143743ae2a860b4efe892d39a4396f90718))
- **deps:** require nodejs v16 or later ([0ab86ce](https://gitlab.com/html-validate/html-validate-vue/commit/0ab86ce390a92bef64c27e6a01753914285e4cff))
### Dependency upgrades
- **deps:** pin dependency @html-validate/plugin-utils to 1.0.1 ([2a9da0a](https://gitlab.com/html-validate/html-validate-vue/commit/2a9da0a0c2da96e338fe2f227008030b3f4be05c))
- **deps:** support html-validate v8 ([b4f17a8](https://gitlab.com/html-validate/html-validate-vue/commit/b4f17a8919d7673f15cd05a4d560ca2921243ae7))
- **deps:** support html-validate v8 ([8abf789](https://gitlab.com/html-validate/html-validate-vue/commit/8abf789308edcdb2db5fc7e75409aa7028cf44ea))
- **deps:** update dependency @html-validate/plugin-utils to v1.0.2 ([e9cb34e](https://gitlab.com/html-validate/html-validate-vue/commit/e9cb34e4fbc7b793b93c39e5df795dcb1b2c0ffe))
## [5.1.4](https://gitlab.com/html-validate/html-validate-vue/compare/v5.1.3...v5.1.4) (2023-05-14)
### Dependency upgrades
......
source diff could not be displayed: it is too large. Options to address this: view the blob.
{
"name": "html-validate-vue",
"version": "5.1.4",
"version": "6.0.0",
"description": "vue transform for html-validate",
"keywords": [
"html",
......@@ -29,7 +29,7 @@
],
"scripts": {
"prebuild": "tsc",
"build": "esbuild src/index.ts --bundle --platform=node --target=node14.0 --external:html-validate --external:./package.json --external:html-validate-vue/package.json --sourcemap --analyze --outdir=dist",
"build": "esbuild src/index.ts --bundle --platform=node --target=node14.0 --external:html-validate --external:@html-validate/plugin-utils --external:./package.json --external:html-validate-vue/package.json --sourcemap --analyze --outdir=dist",
"postbuild": "dts-bundle-generator --no-banner -o dist/index.d.ts src/index.ts",
"eslint": "eslint --cache .",
"eslint:fix": "eslint --cache --fix .",
......@@ -56,26 +56,27 @@
"preset": "@html-validate/jest-config"
},
"dependencies": {
"@html-validate/plugin-utils": "1.0.2",
"semver": "7.5.1"
},
"devDependencies": {
"@html-validate/commitlint-config": "3.0.15",
"@html-validate/eslint-config": "5.9.4",
"@html-validate/commitlint-config": "3.0.16",
"@html-validate/eslint-config": "5.9.8",
"@html-validate/eslint-config-jest": "5.9.0",
"@html-validate/eslint-config-typescript": "5.9.4",
"@html-validate/eslint-config-typescript": "5.9.8",
"@html-validate/eslint-config-typescript-typeinfo": "5.9.0",
"@html-validate/jest-config": "3.7.5",
"@html-validate/prettier-config": "2.3.10",
"@html-validate/release-scripts": "4.0.6",
"@html-validate/release-scripts": "4.1.0",
"@types/estree": "1.0.1",
"@types/glob": "8.1.0",
"@types/jest": "29.5.1",
"@types/node": "14.18.46",
"@types/jest": "29.5.2",
"@types/node": "16.18.34",
"@types/semver": "7.5.0",
"dts-bundle-generator": "8.0.1",
"esbuild": "0.17.19",
"glob": "10.2.3",
"html-validate": "7.16.0",
"glob": "10.2.6",
"html-validate": "8.0.0",
"husky": "8.0.3",
"jest": "29.5.0",
"jest-environment-jsdom": "29.5.0",
......@@ -83,14 +84,17 @@
"npm-pkg-lint": "1.14.1",
"prettier": "2.8.8",
"ts-jest": "29.1.0",
"typescript": "5.0.4"
"typescript": "5.1.3"
},
"peerDependencies": {
"html-validate": "^4.14.1 || ^5.3 || ^6.0.2 || ^7"
"html-validate": "^5.3 || ^6.0.2 || ^7 || ^8"
},
"engines": {
"node": ">= 14.0"
"node": ">= 16.0"
},
"externalDependencies": [
"@html-validate/plugin-utils"
],
"renovate": {
"extends": [
"gitlab>html-validate/renovate-config",
......
......@@ -9,6 +9,8 @@ import {
ProcessElementContext,
TextNode,
} from "html-validate";
import html5 from "html-validate/elements/html5";
import elements from "../../elements.json";
import schema from "../schema.json";
import { processElement } from "./element";
......@@ -89,8 +91,8 @@ describe("dynamic component", () => {
/* load metadata table and fetch meta for <component> */
table = new MetaTable();
table.extendValidationSchema(schema);
table.loadFromFile(require.resolve("html-validate/elements/html5.js"));
table.loadFromFile(require.resolve("../../elements.json"));
table.loadFromObject(html5);
table.loadFromObject(elements);
table.loadFromObject({
"mock-element:foo": {
component: "wrap",
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`vue/available-slots should contain contextual documentation 1`] = `
exports[`vue/available-slots should contain documentation 1`] = `
{
"description": "The <my-component> component does not have a slot named "missing-slot". Only known slots can be specified.
......@@ -10,9 +10,3 @@ The following slots are available
- baz",
}
`;
exports[`vue/available-slots should contain documentation 1`] = `
{
"description": "Only known slots can be specified.",
}
`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`vue/prefer-slot-shorthand should contain contextual documentation 1`] = `
{
"description": "Prefer to use \`#foo\` over \`v-slot:foo\`.
Vue.js supports a shorthand syntax for slots using \`#\` instead of \`v-slot:\` or the deprecated \`slot\` attribute, e.g. using \`#header\` instead of \`v-slot:header\`.",
}
`;
exports[`vue/prefer-slot-shorthand should contain documentation 1`] = `
{
"description": "Prefer to use \`#my-slot\` over \`v-slot:my-slot\`.
"description": "Prefer to use \`#foo\` over \`v-slot:foo\`.
Vue.js supports a shorthand syntax for slots using \`#\` instead of \`v-slot:\` or the deprecated \`slot\` attribute, e.g. using \`#header\` instead of \`v-slot:header\`.",
}
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`vue/required-slots should contain contextual documentation 1`] = `
exports[`vue/required-slots should contain documentation 1`] = `
{
"description": "The <my-component> component requires slot "missing-slot" to be implemented. Add \`<template v-slot:missing-slot>\`
......@@ -10,9 +10,3 @@ The following slots are required
- baz",
}
`;
exports[`vue/required-slots should contain documentation 1`] = `
{
"description": "All required slots must be implemented.",
}
`;
import { HtmlValidate } from "html-validate";
import { ConfigData, FileSystemConfigLoader, HtmlValidate } from "html-validate";
import "html-validate/jest";
import Plugin from "..";
jest.mock("html-validate-vue", () => Plugin, { virtual: true });
const config: ConfigData = {
root: true,
plugins: ["html-validate-vue"],
elements: [
{
"my-component": {
slots: ["foo", "with-dashes"],
},
},
],
rules: { "vue/available-slots": "error" },
};
const loader = new FileSystemConfigLoader(config);
describe("vue/available-slots", () => {
let htmlvalidate: HtmlValidate;
beforeAll(() => {
htmlvalidate = new HtmlValidate({
plugins: ["html-validate-vue"],
elements: [
{
"my-component": {
slots: ["foo", "with-dashes"],
},
},
],
rules: { "vue/available-slots": "error" },
});
htmlvalidate = new HtmlValidate(loader);
});
it("should not report error when component uses no slots", () => {
it("should not report error when component uses no slots", async () => {
expect.assertions(1);
const report = htmlvalidate.validateString("<my-component></my-component>");
const report = await htmlvalidate.validateString("<my-component></my-component>");
expect(report).toBeValid();
});
it("should not report error when component uses available slot", () => {
it("should not report error when component uses available slot", async () => {
expect.assertions(1);
const report = htmlvalidate.validateString(
const report = await htmlvalidate.validateString(
"<my-component><template v-slot:foo></template></my-component>"
);
expect(report).toBeValid();
});
it("should not report error when component uses dynamic slot", () => {
it("should not report error when component uses dynamic slot", async () => {
expect.assertions(1);
const report = htmlvalidate.validateString(
const report = await htmlvalidate.validateString(
"<my-component><template v-slot:[foo]></template></my-component>"
);
expect(report).toBeValid();
});
it("should not report error for slot with dashes", () => {
it("should not report error for slot with dashes", async () => {
expect.assertions(1);
const report = htmlvalidate.validateString(
const report = await htmlvalidate.validateString(
"<my-component><template v-slot:with-dashes></template></my-component>"
);
expect(report).toBeValid();
});
it("should report error when element has invalid attribute value (v-slot)", () => {
it("should report error when element has invalid attribute value (v-slot)", async () => {
expect.assertions(2);
const report = htmlvalidate.validateString(
const report = await htmlvalidate.validateString(
"<my-component><template v-slot:bar></template></my-component>"
);
expect(report).toBeInvalid();
expect(report).toHaveError("vue/available-slots", '<my-component> component has no slot "bar"');
});
it("should report error when element has invalid attribute value (shorthand)", () => {
it("should report error when element has invalid attribute value (shorthand)", async () => {
expect.assertions(2);
const report = htmlvalidate.validateString(
const report = await htmlvalidate.validateString(
"<my-component><template #bar></template></my-component>"
);
expect(report).toBeInvalid();
expect(report).toHaveError("vue/available-slots", '<my-component> component has no slot "bar"');
});
it("should report error when element has invalid attribute value (slot)", () => {
it("should report error when element has invalid attribute value (slot)", async () => {
expect.assertions(2);
const report = htmlvalidate.validateString(
const report = await htmlvalidate.validateString(
'<my-component><template slot="bar"></template></my-component>'
);
expect(report).toBeInvalid();
expect(report).toHaveError("vue/available-slots", '<my-component> component has no slot "bar"');
});
it("should contain documentation", () => {
expect.assertions(1);
expect(htmlvalidate.getRuleDocumentation("vue/available-slots")).toMatchSnapshot();
});
it("should contain contextual documentation", () => {
it("should contain documentation", async () => {
expect.assertions(1);
const context = {
element: "my-component",
slot: "missing-slot",
available: ["foo", "bar", "baz"],
};
expect(
htmlvalidate.getRuleDocumentation("vue/available-slots", null, context)
).toMatchSnapshot();
const config = loader.getConfigFor("inline");
const docs = await htmlvalidate.getRuleDocumentation("vue/available-slots", config, context);
expect(docs).toMatchSnapshot();
});
});
import { HtmlValidate } from "html-validate";
import { ConfigData, FileSystemConfigLoader, HtmlValidate } from "html-validate";
import "html-validate/jest";
import Plugin from "..";
import { processAttribute } from "../hooks";
jest.mock("html-validate-vue", () => Plugin, { virtual: true });
const config: ConfigData = {
root: true,
plugins: ["html-validate-vue"],
rules: { "vue/prefer-slot-shorthand": "error" },
};
const loader = new FileSystemConfigLoader(config);
describe("vue/prefer-slot-shorthand", () => {
let htmlvalidate: HtmlValidate;
beforeAll(() => {
htmlvalidate = new HtmlValidate({
plugins: ["html-validate-vue"],
rules: { "vue/prefer-slot-shorthand": "error" },
});
htmlvalidate = new HtmlValidate(loader);
});
it("should not report error when using shorthand", () => {
it("should not report error when using shorthand", async () => {
expect.assertions(1);
const markup = /* HTML */ `<template #foo></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeValid();
});
it("should not report error for other attributes", () => {
it("should not report error for other attributes", async () => {
expect.assertions(1);
const markup = /* HTML */ `<template id="foo"></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeValid();
});
it("should not report error when using dynamic v-slot", () => {
it("should not report error when using dynamic v-slot", async () => {
expect.assertions(1);
const markup = /* HTML */ `<template v-slot:[dynamicSlotName]></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeValid();
});
it("should not report error when using deprecated dynamic slot-slot", () => {
it("should not report error when using deprecated dynamic slot-slot", async () => {
expect.assertions(1);
const markup = /* HTML */ `<template :slot="dynamicSlotName"></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeValid();
});
it("should report error when using v-slot syntax", () => {
it("should report error when using v-slot syntax", async () => {
expect.assertions(2);
const markup = /* HTML */ `<template v-slot:foobar></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeInvalid();
expect(report).toHaveError(
"vue/prefer-slot-shorthand",
......@@ -54,10 +58,10 @@ describe("vue/prefer-slot-shorthand", () => {
);
});
it("should report error when using deprecated slot syntax", () => {
it("should report error when using deprecated slot syntax", async () => {
expect.assertions(2);
const markup = /* HTML */ `<template slot="foobar"></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeInvalid();
expect(report).toHaveError(
"vue/prefer-slot-shorthand",
......@@ -65,17 +69,17 @@ describe("vue/prefer-slot-shorthand", () => {
);
});
it("should handle scope in shorthand", () => {
it("should handle scope in shorthand", async () => {
expect.assertions(1);
const markup = /* HTML */ `<template #foobar="{ scope }"></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeValid();
});
it("should handle scope in v-slot", () => {
it("should handle scope in v-slot", async () => {
expect.assertions(2);
const markup = /* HTML */ `<template v-slot:foobar="{ scope }"></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeInvalid();
expect(report).toHaveError(
"vue/prefer-slot-shorthand",
......@@ -83,32 +87,31 @@ describe("vue/prefer-slot-shorthand", () => {
);
});
it("should handle incomplete v-slot", () => {
it("should handle incomplete v-slot", async () => {
expect.assertions(1);
const markup = /* HTML */ `<template v-slot v-slot:></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeValid();
});
it("should handle incomplete slot", () => {
it("should handle incomplete slot", async () => {
expect.assertions(1);
const markup = /* HTML */ `<template slot></template><template slot=""></template>`;
const report = htmlvalidate.validateString(markup, { processAttribute });
const report = await htmlvalidate.validateString(markup, { processAttribute });
expect(report).toBeValid();
});
it("should contain documentation", () => {
expect.assertions(1);
expect(htmlvalidate.getRuleDocumentation("vue/prefer-slot-shorthand")).toMatchSnapshot();
});
it("should contain contextual documentation", () => {
it("should contain documentation", async () => {
expect.assertions(1);
const context = {
slot: "foo",
};
expect(
htmlvalidate.getRuleDocumentation("vue/prefer-slot-shorthand", null, context)
).toMatchSnapshot();
const config = loader.getConfigFor("inline");
const docs = await htmlvalidate.getRuleDocumentation(
"vue/prefer-slot-shorthand",
config,
context
);
expect(docs).toMatchSnapshot();
});
});
import { HtmlValidate } from "html-validate";
import { ConfigData, FileSystemConfigLoader, HtmlValidate } from "html-validate";
import "html-validate/jest";
import Plugin from "..";
jest.mock("html-validate-vue", () => Plugin, { virtual: true });
const config: ConfigData = {
root: true,
plugins: ["html-validate-vue"],
elements: [
{
"my-component": {
requiredSlots: ["foo"],
},
},
],
rules: { "vue/required-slots": "error" },
};
const loader = new FileSystemConfigLoader(config);
describe("vue/required-slots", () => {
let htmlvalidate: HtmlValidate;
beforeAll(() => {
htmlvalidate = new HtmlValidate({
plugins: ["html-validate-vue"],
elements: [
{
"my-component": {
requiredSlots: ["foo"],
},
},
],
rules: { "vue/required-slots": "error" },
});
htmlvalidate = new HtmlValidate(loader);
});
it("should not report error when all required slots are implemented (v-slot)", () => {
it("should not report error when all required slots are implemented (v-slot)", async () => {
expect.assertions(1);
const report = htmlvalidate.validateString(
const report = await htmlvalidate.validateString(
"<my-component><template v-slot:foo></template></my-component>"
);
expect(report).toBeValid();
});
it("should not report error when all required slots are implemented (shorthand)", () => {
it("should not report error when all required slots are implemented (shorthand)", async () => {
expect.assertions(1);
const report = htmlvalidate.validateString(
const report = await htmlvalidate.validateString(
"<my-component><template #foo></template></my-component>"
);
expect(report).toBeValid();
});
it("should not report error when all required slots are implemented (slot)", () => {
it("should not report error when all required slots are implemented (slot)", async () => {
expect.assertions(1);
const report = htmlvalidate.validateString(
const report = await htmlvalidate.validateString(
'<my-component><template slot="foo"></template></my-component>'
);
expect(report).toBeValid();
});
it("should report error when component is missing a required slot", () => {
it("should report error when component is missing a required slot", async () => {
expect.assertions(2);
const report = htmlvalidate.validateString("<my-component></my-component>");
const report = await htmlvalidate.validateString("<my-component></my-component>");
expect(report).toBeInvalid();
expect(report).toHaveError(
"vue/required-slots",
......@@ -55,20 +59,15 @@ describe("vue/required-slots", () => {
);
});
it("should contain documentation", () => {
expect.assertions(1);
expect(htmlvalidate.getRuleDocumentation("vue/required-slots")).toMatchSnapshot();
});
it("should contain contextual documentation", () => {
it("should contain documentation", async () => {
expect.assertions(1);
const context = {
element: "my-component",
slot: "missing-slot",
required: ["foo", "bar", "baz"],
};
expect(
htmlvalidate.getRuleDocumentation("vue/required-slots", null, context)
).toMatchSnapshot();
const config = loader.getConfigFor("inline");
const docs = await htmlvalidate.getRuleDocumentation("vue/required-slots", config, context);
expect(docs).toMatchSnapshot();
});
});
import { type Source, TemplateExtractor } from "html-validate";
import { type Source } from "html-validate";
import { TemplateExtractor } from "@html-validate/plugin-utils";
import { processAttribute, processElement } from "../hooks";
/**
......
import path from "path";
import { HtmlValidate, ConfigData } from "html-validate";
import { HtmlValidate, ConfigData, FileSystemConfigLoader } from "html-validate";
import "html-validate/jest";
import Plugin from "../src";
......@@ -15,6 +15,7 @@ const config: ConfigData = {
"\\.(vue|js)$": "html-validate-vue:html",
},
};
const loader = new FileSystemConfigLoader(config);
describe("should handle <keep-alive> as transparent", () => {
it.each`
......@@ -23,20 +24,20 @@ describe("should handle <keep-alive> as transparent", () => {
${"flow in phrasing"} | ${"<span><keep-alive><div></div></keep-alive></span>"} | ${false}
${"phrasing in phrasing"} | ${"<span><keep-alive><span></span></keep-alive></span>"} | ${true}
${"phrasing in flow"} | ${"<div><keep-alive><span></span></keep-alive></div>"} | ${true}
`("$scenario", ({ markup, expected }) => {
`("$scenario", async ({ markup, expected }) => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(markup);
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(markup);
expect(report.valid).toEqual(expected);
});
});
describe("<portal>", () => {
it("should be deprecated", () => {
it("should be deprecated", async () => {
expect.assertions(1);
const markup = "<portal></portal>";
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(markup);
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(markup);
expect(report).toHaveError(
"deprecated",
"<portal> is deprecated: the <portal> element has been renamed to <teleport>"
......@@ -51,41 +52,41 @@ describe("should handle <router-link> as transparent", () => {
${"flow in phrasing"} | ${"<span><router-link><div></div></router-link></span>"} | ${false}
${"phrasing in phrasing"} | ${"<span><router-link><span></span></router-link></span>"} | ${true}
${"phrasing in flow"} | ${"<div><router-link><span></span></router-link></div>"} | ${true}
`("$scenario", ({ markup, expected }) => {
`("$scenario", async ({ markup, expected }) => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(markup);
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(markup);
expect(report.valid).toEqual(expected);
});
});
describe("<router-view>", () => {
it("should be allowed under @flow", () => {
it("should be allowed under @flow", async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString("<div><router-view></router-view></div>");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString("<div><router-view></router-view></div>");
expect(report).toBeValid();
});
it("should not be allowed under @phrasing", () => {
it("should not be allowed under @phrasing", async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString("<span><router-view></router-view></span>");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString("<span><router-view></router-view></span>");
expect(report).toBeInvalid();
});
it("should not allow content", () => {
it("should not allow content", async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString("<router-view><span></span></router-view>");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString("<router-view><span></span></router-view>");
expect(report).toBeInvalid();
});
});
it("should allow <slot> when script-supporting elements is expected", () => {
it("should allow <slot> when script-supporting elements is expected", async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString("<ul><slot></slot></ul>");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString("<ul><slot></slot></ul>");
expect(report).toBeValid();
});
......@@ -97,29 +98,29 @@ describe("<suspense>", () => {
${"flow in phrasing"} | ${"<span><suspense><div></div></suspense></span>"} | ${false}
${"phrasing in phrasing"} | ${"<span><suspense><span></span></suspense></span>"} | ${true}
${"phrasing in flow"} | ${"<div><suspense><span></span></suspense></div>"} | ${true}
`("$scenario", ({ markup, expected }) => {
`("$scenario", async ({ markup, expected }) => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(markup);
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(markup);
expect(report.valid).toEqual(expected);
});
});
});
describe("<teleport>", () => {
it("should be allowed as content in phrasing", () => {
it("should be allowed as content in phrasing", async () => {
expect.assertions(1);
const markup = "<span><teleport></teleport></span>";
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(markup);
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(markup);
expect(report).toBeValid();
});
it("should allow flow as content", () => {
it("should allow flow as content", async () => {
expect.assertions(1);
const markup = "<span><teleport><div></div></teleport></span>";
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(markup);
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(markup);
expect(report).toBeValid();
});
});
......@@ -131,10 +132,10 @@ describe("should handle <transition> as transparent", () => {
${"flow in phrasing"} | ${"<span><transition><div></div></transition></span>"} | ${false}
${"phrasing in phrasing"} | ${"<span><transition><span></span></transition></span>"} | ${true}
${"phrasing in flow"} | ${"<div><transition><span></span></transition></div>"} | ${true}
`("$scenario", ({ markup, expected }) => {
`("$scenario", async ({ markup, expected }) => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(markup);
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(markup);
expect(report.valid).toEqual(expected);
});
});
......@@ -147,15 +148,15 @@ describe("<transition-group>", () => {
${"flow in phrasing"} | ${"<span><transition-group><div></div></transition-group></span>"} | ${false}
${"phrasing in phrasing"} | ${"<span><transition-group><span></span></transition-group></span>"} | ${true}
${"phrasing in flow"} | ${"<div><transition-group><span></span></transition-group></div>"} | ${true}
`("$scenario", ({ markup, expected }) => {
`("$scenario", async ({ markup, expected }) => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(markup);
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(markup);
expect(report.valid).toEqual(expected);
});
});
it("should handle as given tagName when tag attribute is used", () => {
it("should handle as given tagName when tag attribute is used", async () => {
expect.assertions(1);
const markup = /* HTML */ `
<div>
......@@ -165,8 +166,8 @@ describe("<transition-group>", () => {
<transition-group tag="span"><div></div></transition-group>
</span>
`;
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(markup, "my-file.vue");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(markup, "my-file.vue");
expect(report).toHaveErrors([
{
ruleId: "element-permitted-content",
......@@ -183,10 +184,10 @@ describe("<transition-group>", () => {
});
describe("<component>", () => {
it('should report error if missing "is" attribute', () => {
it('should report error if missing "is" attribute', async () => {
expect.assertions(2);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString("<component></component>");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString("<component></component>");
expect(report).toBeInvalid();
expect(report).toHaveError(
"element-required-attributes",
......@@ -194,10 +195,10 @@ describe("<component>", () => {
);
});
it('should load meta for tagname provided by "is"', () => {
it('should load meta for tagname provided by "is"', async () => {
expect.assertions(2);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(
'<template>\n<component is="label"><div></div></component>\n</template>',
"myfile.vue"
);
......@@ -208,50 +209,50 @@ describe("<component>", () => {
);
});
it('should handle unknown tagname in "is"', () => {
it('should handle unknown tagname in "is"', async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(
'<template>\n<component is="missing"><div></div></component>\n</template>',
"myfile.vue"
);
expect(report).toBeValid();
});
it("should handle :it", () => {
it("should handle :it", async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(
'<template>\n<component :is="tagname"><div></div></component>\n</template>',
"myfile.vue"
);
expect(report).toBeValid();
});
it("should allow dynamic :is in @flow", () => {
it("should allow dynamic :is in @flow", async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(
'<template>\n<div><component :is="tagname"></component></div>\n</template>',
"myfile.vue"
);
expect(report).toBeValid();
});
it("should allow dynamic :is in @phrasing", () => {
it("should allow dynamic :is in @phrasing", async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(
'<template>\n<span><component :is="tagname"></component></span>\n</template>',
"myfile.vue"
);
expect(report).toBeValid();
});
it("should handle dynamic :is as transparent", () => {
it("should handle dynamic :is as transparent", async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(
'<template>\n<span><component :is="tagname"><div></div></component></span>\n</template>',
"myfile.vue"
);
......@@ -261,10 +262,10 @@ describe("<component>", () => {
);
});
it('should load meta onto slot for tagname provided by "is" on component', () => {
it('should load meta onto slot for tagname provided by "is" on component', async () => {
expect.assertions(2);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString(
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString(
'<template>\n<dynamic-component tagname="label"><template #foo><div></div></template></dynamic-component>\n</template>',
"myfile.vue"
);
......
......@@ -3,7 +3,7 @@
*/
import path from "path";
import { HtmlValidate, ConfigData, Report, Message } from "html-validate";
import { HtmlValidate, ConfigData, Report, Message, FileSystemConfigLoader } from "html-validate";
import "html-validate/jest";
import Plugin from "../src";
......@@ -23,6 +23,7 @@ const config: ConfigData = {
"^html$": "html-validate-vue:html",
},
};
const loader = new FileSystemConfigLoader(config);
/**
* Filter out properties not present in all supported versions of html-validate (see
......@@ -39,37 +40,37 @@ function filterReport(report: Report): void {
}
}
it('should find errors in "component.vue"', () => {
it('should find errors in "component.vue"', async () => {
expect.assertions(2);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateFile("test/component.vue");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateFile("test/component.vue");
filterReport(report);
expect(report.valid).toBeFalsy();
expect(report.results).toMatchSnapshot();
});
it('should find errors in "component.js"', () => {
it('should find errors in "component.js"', async () => {
expect.assertions(2);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateFile("test/component.js");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateFile("test/component.js");
filterReport(report);
expect(report.valid).toBeFalsy();
expect(report.results).toMatchSnapshot();
});
it('should find no errors in "lang.vue"', () => {
it('should find no errors in "lang.vue"', async () => {
expect.assertions(2);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateFile("test/lang.vue");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateFile("test/lang.vue");
filterReport(report);
expect(report.valid).toBeTruthy();
expect(report.results).toMatchSnapshot();
});
it('should find errors in "slot-metadata.vue"', () => {
it('should find errors in "slot-metadata.vue"', async () => {
expect.assertions(2);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateFile("test/slot-metadata.vue");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateFile("test/slot-metadata.vue");
filterReport(report);
expect(report.valid).toBeFalsy();
expect(report.results).toMatchSnapshot();
......@@ -81,10 +82,10 @@ it("should support jest matchers", () => {
expect('<h1 v-html="prop"></h1>').toHTMLValidate();
});
it("should support matching with validateString", () => {
it("should support matching with validateString", async () => {
expect.assertions(1);
const htmlvalidate = new HtmlValidate(config);
const report = htmlvalidate.validateString('<h1 v-html="prop"></h1>', "html");
const htmlvalidate = new HtmlValidate(loader);
const report = await htmlvalidate.validateString('<h1 v-html="prop"></h1>', "html");
filterReport(report);
expect(report).toBeValid();
});
import { HtmlValidate } from "html-validate";
import { ConfigData, FileSystemConfigLoader, HtmlValidate } from "html-validate";
import "html-validate/jest";
import Plugin from "../src";
jest.mock("html-validate-vue", () => Plugin, { virtual: true });
const config: ConfigData = {
root: true,
plugins: ["html-validate-vue"],
extends: ["html-validate:recommended", "html-validate-vue:recommended"],
elements: ["html5"],
};
const loader = new FileSystemConfigLoader(config);
let htmlvalidate: HtmlValidate;
beforeAll(() => {
htmlvalidate = new HtmlValidate({
root: true,
plugins: ["html-validate-vue"],
extends: ["html-validate:recommended", "html-validate-vue:recommended"],
elements: ["html5"],
});
htmlvalidate = new HtmlValidate(loader);
});
it("should not report error for camelcase modifiers", () => {
it("should not report error for camelcase modifiers", async () => {
expect.assertions(1);
const report = htmlvalidate.validateString("<div v-foo.barBaz></div>");
const report = await htmlvalidate.validateString("<div v-foo.barBaz></div>");
expect(report).toBeValid();
});
import path from "path";
import { globSync } from "glob";
import { HtmlValidate, Message, Report } from "html-validate";
import { ConfigData, FileSystemConfigLoader, HtmlValidate, Message, Report } from "html-validate";
import "html-validate/jest";
import Plugin from "../src";
jest.mock("html-validate-vue", () => Plugin, { virtual: true });
const config: ConfigData = {
root: true,
plugins: ["html-validate-vue"],
extends: ["htmlvalidate:recommended", "html-validate-vue:recommended"],
elements: ["html5", path.join(__dirname, "custom.json")],
transform: {
"^.*\\.vue$": "html-validate-vue",
},
};
const loader = new FileSystemConfigLoader(config);
/**
* Filter out properties not present in all supported versions of html-validate (see
* peerDependencies). This required in the version matrix integration test.
......@@ -26,20 +37,12 @@ describe("smoketest", () => {
let htmlvalidate: HtmlValidate;
beforeAll(() => {
htmlvalidate = new HtmlValidate({
root: true,
plugins: ["html-validate-vue"],
extends: ["htmlvalidate:recommended", "html-validate-vue:recommended"],
elements: ["html5", path.join(__dirname, "custom.json")],
transform: {
"^.*\\.vue$": "html-validate-vue",
},
});
htmlvalidate = new HtmlValidate(loader);
});
it.each(files)("%s", (filename) => {
it.each(files)("%s", async (filename) => {
expect.assertions(2);
const report = htmlvalidate.validateFile(filename);
const report = await htmlvalidate.validateFile(filename);
filterReport(report);
expect(report).toBeInvalid();
expect(report.results[0].messages).toMatchSnapshot();
......