Skip to content

Commit

Permalink
Initial push (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamhamlin authored Jan 16, 2023
1 parent bb84d96 commit 4a9a790
Show file tree
Hide file tree
Showing 19 changed files with 12,913 additions and 2 deletions.
23 changes: 23 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

module.exports = {
extends: ['@adamhamlin/eslint-config', 'plugin:eslint-plugin/recommended'],
rules: {
'eslint-plugin/require-meta-docs-description': 'error',
},
overrides: [
{
files: ['__tests__/**'],
plugins: ['jest'],
extends: ['plugin:jest/all'],
rules: {
'jest/prefer-expect-assertions': 'off',
'jest/prefer-lowercase-title': 'off',
'jest/max-expects': ['error', { max: 8 }],
'jest/require-hook': 'off',
'jest/unbound-method': ['error', { ignoreStatic: true }],
'@typescript-eslint/unbound-method': 'off', // disable in favor of jest/unbound-method
},
},
],
};
17 changes: 17 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: CI

on:
pull_request:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout/install
uses: adamhamlin/checkout-node-project@v0.1.0

- name: Run Tests
run: npm run test:ci
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Ignore artifacts:
dist
coverage

# Ignore changelog since auto-updated by standard-version
CHANGELOG.md
5 changes: 5 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = {
...require('@adamhamlin/eslint-config/prettier'),
};
54 changes: 52 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,52 @@
# eslint-custom-rules
Custom ESLint rules!
# ESLint Plugin

[![CI Status Badge](https://github.com/adamhamlin/eslint-plugin/actions/workflows/ci.yaml/badge.svg)](https://github.com/adamhamlin/eslint-plugin/actions/workflows/ci.yaml)

My collection of miscellaneous custom ESLint rules!

## Install

```bash
npm install eslint-plugin-adamhamlin --save-dev
```

## Usage

Add `adamhamlin` to the plugins section of your `.eslintrc` configuration file:

```json
{
"plugins": ["adamhamlin"]
}
```

Then configure the rules you want to use under the rules section.

```json
{
"rules": {
"adamhamlin/no-empty-block-comment": "error",
"adamhamlin/forbid-pattern-everywhere": [
"error",
{
"patterns": ["^(bleep|bloop)"]
}
]
}
}
```

## Rules

This plugin makes the following lint rules available:

- [forbid-pattern-everywhere](./docs/rules/forbid-pattern-everywhere.md) - Specified pattern(s) are disallowed **everywhere**--in variables, functions, literals, property names, classes, types, interfaces, etc.
- [no-emppty-block-comment](./docs/rules/no-empty-block-comment.md) - Block comments must have non-empty content.

<!-- begin auto-generated rules list -->

<!-- end auto-generated rules list -->

## TODO

- Use eslint-doc-generator to generate the rules list?
6 changes: 6 additions & 0 deletions __tests__/rule-tester.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { RuleTester } from '@typescript-eslint/utils/dist/eslint-utils';

export const ruleTester = new RuleTester({
parser: '@typescript-eslint/parser',
parserOptions: { ecmaVersion: 2018, sourceType: 'module' },
});
190 changes: 190 additions & 0 deletions __tests__/rules/forbid-pattern-everywhere.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import { TestCaseError } from '@typescript-eslint/utils/dist/ts-eslint';
import dedent from 'dedent';

import rule from '../../src/rules/forbid-pattern-everywhere';
import { ruleTester } from '../rule-tester';

describe('Rule Tests', () => {
function getErrors(pattern: string): TestCaseError<'disallowedPattern'>[] {
return [{ messageId: `disallowedPattern`, data: { pattern } }];
}

ruleTester.run('forbid-pattern-everywhere', rule, {
valid: [
{
// No options/patterns specified
code: dedent`
const myVar = 5;
`,
},
{
// Identifier doesn't match any configured pattern
code: dedent`
const myVar = 5;
`,
options: [
{
patterns: ['Bleep', 'Bloop'],
},
],
},
],

invalid: [
{
code: dedent`
const doNotAllowBlahInVarName = 5;
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
function doNotAllowBlahInFunctionName() {
return 'ok';
};
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
function myFunc(doNotAllowBlahInParameterName) {
return 'ok';
};
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
function myFunc() {
return 'do not allow Blah in string literal';
};
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
const myStr = \`This is a \${type} template literal with BlahBlahBlah\`;
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
class DoNotAllowBlahInClassName {
constructor(arg) {
this.arg = arg;
}
};
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
class MyClass {
constructor(arg) {
this.doNotAllowBlahInMemberVar = arg;
}
};
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
const myObj = {
doNotAllowBlahInPropertyName: 'myValue'
};
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
const doNotAllowBlahCaseInsensitive = 5;
`,
options: [
{
patterns: [/BLAH/i],
},
],
errors: getErrors('/BLAH/i'),
},
{
code: dedent`
interface BlahInterface {
someProp: string;
}
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
type BlahType = {
someProp: string;
};
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
{
code: dedent`
interface MyInterface {
someBlahProp: string;
}
`,
options: [
{
patterns: ['Blah'],
},
],
errors: getErrors('/Blah/'),
},
],
});
});
76 changes: 76 additions & 0 deletions __tests__/rules/no-empty-block-comment.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import dedent from 'dedent';

import rule from '../../src/rules/no-empty-block-comment';
import { ruleTester } from '../rule-tester';

describe('Rule Tests', () => {
const errors = [{ messageId: 'nonEmptyBlockComment' as const }];

ruleTester.run('no-empty-block-comment', rule, {
valid: [
{
code: dedent`
/**
* Not empty
*/
`,
},
{
code: dedent`
/**
*
* Still not empty
*/
`,
},
{
// Ignore empty line comments
code: dedent`
//
`,
},
],

invalid: [
{
code: `/**/`,
errors,
},
{
code: `/* */`,
errors,
},
{
code: dedent`
/**
*
*/
`,
errors,
},
{
// Trailing whitespace on middle line
code: dedent`
/**
*
*/
`,
errors,
},
{
code: dedent`
/**
* Good comment, followed by empty comment
*/
const bleep = 4;
/**
*
*/
const bloop = 5;
`,
errors,
},
],
});
});
Loading

0 comments on commit 4a9a790

Please sign in to comment.