Skip to content

Commit

Permalink
feat: implement linting tests (#2333)
Browse files Browse the repository at this point in the history
- created linting tests for the following rules:
 - import-playwright-a11y.cjs
 - no-shadow-native-events.cjs
 - require-root-class

- removed unnessesary testing from require-root-class because it's
already tested on default.
  • Loading branch information
ChristianBusshoff authored Dec 19, 2024
1 parent 63993e9 commit 4c31ef1
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 31 deletions.
3 changes: 3 additions & 0 deletions packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"author": "Schwarz IT KG",
"license": "Apache-2.0",
"main": "./src/index.cjs",
"scripts": {
"test:eslint-plugins": " node ./src/tests/index.cjs "
},
"peerDependencies": {
"eslint": ">= 8"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ module.exports = {
context.report({
node,
loc: node.loc ?? undefined,
message: `Import "${node.imported.name}" from "../../playwright/a11y" instead because onyx uses custom Playwright fixtures for providing a global configuration for accessability testing.`,
message: `Import "${node.imported.name}" from "../../playwright/a11y" instead because onyx uses custom Playwright fixtures for providing a global configuration for accessibility testing.`,
});
}
},
Expand Down
30 changes: 0 additions & 30 deletions packages/eslint-plugin/src/rules/require-root-class.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ module.exports = {
fixable: null,
schema: [],
messages: {
multipleRoot: "The template root requires exactly one element.",
textRoot: "The template root requires an element rather than texts.",
disallowedDirective: "The template root disallows 'v-for' directives.",
missingClass: "The root element is missing the 'onyx-component' class.",
},
},
Expand All @@ -65,8 +62,6 @@ module.exports = {
* @returns {RuleListener} AST event handlers.
*/
create(context) {
const sourceCode = context.getSourceCode();

return {
Program(program) {
const element = program.templateBody;
Expand All @@ -87,15 +82,7 @@ module.exports = {
} else if (vIf && hasDirective(child, "else")) {
rootElements.push(child);
vIf = false;
} else {
extraElement = child;
}
} else if (sourceCode.getText(child).trim() !== "") {
context.report({
node: child,
messageId: "textRoot",
});
return;
}
}

Expand Down Expand Up @@ -165,24 +152,7 @@ module.exports = {
messageId: "missingClass",
});
}

if (hasDirective(element, "for")) {
context.report({
node: tag,
loc: tag.loc,
messageId: "disallowedDirective",
});
}
}
} else if (extraElement?.name === "teleport") {
// Exclude teleport from this rule
return true;
} else {
context.report({
node: extraElement,
loc: extraElement.loc,
messageId: "multipleRoot",
});
}
},
};
Expand Down
64 changes: 64 additions & 0 deletions packages/eslint-plugin/src/tests/import-playwright-a11y.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"use strict";

const { RuleTester } = require("eslint");
const rule = require("../rules/import-playwright-a11y.cjs");

const tester = new RuleTester({
languageOptions: {
parser: require("vue-eslint-parser"),
ecmaVersion: 2020,
sourceType: "module",
},
});

tester.run("no-playwright-imports-when-fixture-available", rule, {
valid: [
{
code: `
import { someOtherFunction } from "@playwright/experimental-ct-vue";
`,
filename: "/some/other/path/to/file.js",
},
{
code: `
import { expect } from "../../playwright/a11y";
`,
filename: "/path/to/playwright/a11y.ts",
},
],

invalid: [
{
code: `
import { test, expect } from "@playwright/test";
`,
errors: [
{
message:
'Import "test" from "../../playwright/a11y" instead because onyx uses custom Playwright fixtures for providing a global configuration for accessibility testing.',
},
{
message:
'Import "expect" from "../../playwright/a11y" instead because onyx uses custom Playwright fixtures for providing a global configuration for accessibility testing.',
},
],
filename: "/path/to/file.js",
},
{
code: `
import { test, expect } from "@playwright/experimental-ct-vue";
`,
errors: [
{
message:
'Import "test" from "../../playwright/a11y" instead because onyx uses custom Playwright fixtures for providing a global configuration for accessibility testing.',
},
{
message:
'Import "expect" from "../../playwright/a11y" instead because onyx uses custom Playwright fixtures for providing a global configuration for accessibility testing.',
},
],
filename: "/path/to/file.js",
},
],
});
3 changes: 3 additions & 0 deletions packages/eslint-plugin/src/tests/index.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require("./import-playwright-a11y.cjs");
require("./no-shadow-native-events.cjs");
require("./require-root-class.cjs");
89 changes: 89 additions & 0 deletions packages/eslint-plugin/src/tests/no-shadow-native-events.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"use strict";

const { RuleTester } = require("eslint");
const rule = require("../rules/no-shadow-native-events.cjs");

const tester = new RuleTester({
languageOptions: {
parser: require("vue-eslint-parser"),
ecmaVersion: 2020,
sourceType: "module",
},
});
tester.run("no-native-event-emits", rule, {
valid: [
{
code: `
<script setup>
defineEmits(['customClick']);
</script>
`,
},
{
code: `
<script>
export default {
emits: ['customSubmit'],
methods: {
emitSomething() {
this.$emit('customChange');
},
},
};
</script>
`,
},
{
code: `
<script>
export default {
emits: ['customHover'],
};
</script>
`,
},
],
invalid: [
{
code: `
<script setup>
defineEmits(['click']);
</script>
`,
errors: [
{
message:
'Use a different emit name to avoid shadowing the native event with name "click". Consider an emit name which communicates the users intent, if applicable.',
},
],
},
{
code: `
<script setup>
const emit = defineEmits(['focus']);
emit('focus');
</script>
`,
errors: [
{
message:
'Use a different emit name to avoid shadowing the native event with name "focus". Consider an emit name which communicates the users intent, if applicable.',
},
],
},
{
code: `
<template>
<div @click="$emit('submit')">
</div>
</template>
`,
errors: [
{
message:
'Use a different emit name to avoid shadowing the native event with name "submit". Consider an emit name which communicates the users intent, if applicable.',
},
],
},
],
});
105 changes: 105 additions & 0 deletions packages/eslint-plugin/src/tests/require-root-class.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"use strict";

const { RuleTester } = require("eslint");
const rule = require("../rules/require-root-class.cjs");

const tester = new RuleTester({
languageOptions: {
parser: require("vue-eslint-parser"),
ecmaVersion: 2020,
sourceType: "module",
},
});
tester.run("require-onyx-component-class", rule, {
valid: [
{
code: `
<template>
<div class="onyx-component">
<p>Valid component</p>
</div>
</template>
`,
},
{
code: `
<template>
<div :class="'onyx-component'">
<p>Dynamic class</p>
</div>
</template>
`,
},
{
code: `
<template>
<div :class="['class1', 'onyx-component']">
<p>Array class binding</p>
</div>
</template>
`,
},
{
code: `
<template>
<div :class="{ 'onyx-component': true, 'other-class': false }">
<p>Object class binding</p>
</div>
</template>
`,
},
{
code: `
<template>
<onyx-custom-element>
<p>Custom Onyx element</p>
</onyx-custom-element>
</template>
`,
},
],
invalid: [
{
code: `
<template>
<div>
<p>Missing class</p>
</div>
</template>
`,
errors: [
{
messageId: "missingClass",
},
],
},
{
code: `
<template>
<div :class="['class1', 'class2']">
<p>Array binding without onyx-component</p>
</div>
</template>
`,
errors: [
{
messageId: "missingClass",
},
],
},
{
code: `
<template>
<div :class="{ 'other-class': true }">
<p>Object binding without onyx-component</p>
</div>
</template>
`,
errors: [
{
messageId: "missingClass",
},
],
},
],
});

0 comments on commit 4c31ef1

Please sign in to comment.