Skip to content

Commit

Permalink
docs: Custom rule & plugin tutorial (#17024)
Browse files Browse the repository at this point in the history
* Start copy edits

* checkpoint

* docs update

* docs update

* Add intro

* Copy edits

* remove old draft of tutorial

* Fix take ii

* update tutorial

* Apply suggestions from code review

Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>

* update src code names

* rename tutorial

* update code examples to match updated code

* additional fixes

* implement additional NZ feedback

* Apply suggestions from code review

Co-authored-by: Nitin Kumar <snitin315@gmail.com>
Co-authored-by: Samuel Roldan <sroldan24@gmail.com>
Co-authored-by: moniuch <moniuch@gmail.com>

* draft tutorial changes

* copy edits

* fix lint err

* Apply suggestions from code review

Co-authored-by: Nitin Kumar <snitin315@gmail.com>

* add file overviews

* copy edits on step 8 intro

* Apply suggestions from code review

Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>

* implement NZ feedback

* Apply suggestions from code review

Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>

* Apply suggestions from code review

Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>

* Apply suggestions from code review

* Apply suggestions from code review

* Apply suggestions from code review

* update rule name to "enforce-foo-bar"

* Apply suggestions from code review

* implement MD feedback

* Apply suggestions from code review

Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>

* implement MD feedback

* copy edit

* Apply suggestions from code review

Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>

* move tutorial to _examples dir

* undo big change

* Fix broken example

* Apply suggestions from code review

Co-authored-by: Nitin Kumar <snitin315@gmail.com>

---------

Co-authored-by: Nicholas C. Zakas <nicholas@humanwhocodes.com>
Co-authored-by: Nitin Kumar <snitin315@gmail.com>
Co-authored-by: Samuel Roldan <sroldan24@gmail.com>
Co-authored-by: moniuch <moniuch@gmail.com>
Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
  • Loading branch information
6 people committed Jun 12, 2023
1 parent 8e51ea9 commit e0cf0d8
Show file tree
Hide file tree
Showing 11 changed files with 652 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/_examples/custom-rule-tutorial-code/.gitignore
@@ -0,0 +1 @@
node_modules
57 changes: 57 additions & 0 deletions docs/_examples/custom-rule-tutorial-code/enforce-foo-bar.js
@@ -0,0 +1,57 @@
/**
* @fileoverview Rule to enforce that `const foo` is assigned "bar".
* @author Ben Perlmutter
*/

"use strict";

// The enforce-foo-bar rule definition
module.exports = {
meta: {
type: "problem",
docs: {
description: "Enforce that a variable named `foo` can only be assigned a value of 'bar'."
},
fixable: "code",
schema: []
},
create(context) {
return {

// Performs action in the function on every variable declarator
VariableDeclarator(node) {

// Check if a `const` variable declaration
if (node.parent.kind === "const") {

// Check if variable name is `foo`
if (node.id.type === "Identifier" && node.id.name === "foo") {

// Check if value of variable is "bar"
if (node.init && node.init.type === "Literal" && node.init.value !== "bar") {

/*
* Report error to ESLint. Error message uses
* a message placeholder to include the incorrect value
* in the error message.
* Also includes a `fix(fixer)` function that replaces
* any values assigned to `const foo` with "bar".
*/
context.report({
node,
message: 'Value other than "bar" assigned to `const foo`. Unexpected value: {{ notBar }}.',
data: {
notBar: node.init.value
},
fix(fixer) {
return fixer.replaceText(node.init, '"bar"');
}
});
}
}
}
}
};
}
};

34 changes: 34 additions & 0 deletions docs/_examples/custom-rule-tutorial-code/enforce-foo-bar.test.js
@@ -0,0 +1,34 @@
/**
* @fileoverview Tests for enforce-foo-bar.js rule.
* @author Ben Perlmutter
*/
"use strict";

const {RuleTester} = require("eslint");
const fooBarRule = require("./enforce-foo-bar");

const ruleTester = new RuleTester({
// Must use at least ecmaVersion 2015 because
// that's when `const` variable were introduced.
parserOptions: { ecmaVersion: 2015 }
});

// Throws error if the tests in ruleTester.run() do not pass
ruleTester.run(
"enforce-foo-bar", // rule name
fooBarRule, // rule code
{ // checks
// 'valid' checks cases that should pass
valid: [{
code: "const foo = 'bar';",
}],
// 'invalid' checks cases that should not pass
invalid: [{
code: "const foo = 'baz';",
output: 'const foo = "bar";',
errors: 1,
}],
}
);

console.log("All tests passed!");
@@ -0,0 +1,9 @@
/**
* @fileoverview Example an ESLint plugin with a custom rule.
* @author Ben Perlmutter
*/
"use strict";

const fooBarRule = require("./enforce-foo-bar");
const plugin = { rules: { "enforce-foo-bar": fooBarRule } };
module.exports = plugin;
23 changes: 23 additions & 0 deletions docs/_examples/custom-rule-tutorial-code/eslint.config.js
@@ -0,0 +1,23 @@
/**
* @fileoverview Example ESLint config file that uses the custom rule from this tutorial.
* @author Ben Perlmutter
*/
"use strict";

// Import the ESLint plugin
const eslintPluginExample = require("./eslint-plugin-example");

module.exports = [
{
files: ["**/*.js"],
languageOptions: {
sourceType: "commonjs",
ecmaVersion: "latest",
},
// Using the eslint-plugin-example plugin defined locally
plugins: {"example": eslintPluginExample},
rules: {
"example/enforce-foo-bar": "error",
},
}
]
22 changes: 22 additions & 0 deletions docs/_examples/custom-rule-tutorial-code/example.js
@@ -0,0 +1,22 @@
/**
* @fileoverview Example of a file that will fail the custom rule in this tutorial.
* @author Ben Perlmutter
*/
"use strict";

/* eslint-disable no-unused-vars -- Disable other rule causing problem for this file */

// To see the error in the terminal, run the following command:
// npx eslint example.js

// To fix the error, run the following command:
// npx eslint example.js --fix

function correctFooBar() {
const foo = "bar";
}

function incorrectFoo(){
const foo = "baz"; // Problem!
}

22 changes: 22 additions & 0 deletions docs/_examples/custom-rule-tutorial-code/package.json
@@ -0,0 +1,22 @@
{
"name": "eslint-plugin-example",
"version": "1.0.0",
"description": "ESLint plugin for enforce-foo-bar rule.",
"main": "eslint-plugin-example.js",
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin"
],
"peerDependencies": {
"eslint": ">=8.0.0"
},
"scripts": {
"test": "node enforce-foo-bar.test.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"eslint": "^8.36.0"
}
}
2 changes: 1 addition & 1 deletion docs/src/extend/custom-processors.md
Expand Up @@ -4,7 +4,7 @@ eleventyNavigation:
key: custom processors
parent: create plugins
title: Custom Processors
order: 2
order: 3

---

Expand Down

0 comments on commit e0cf0d8

Please sign in to comment.