Skip to content

Commit 7bb7e74

Browse files
Support Typescript, Jest (#16)
* update prettier-eslint-cli * switch to yarn * move mocha stuff to separate file * add peerDeps as devDeps, too And move configs to regular deps. See https://eslint.org/docs/latest/developer-guide/shareable-configs#publishing-a-shareable-config * add babel eslint * add tests... may remove this * temporary...add config * add a test * 0 -> off, 1 -> warn, etc; remove redund prefer-const * remove redund no-unreachable * specify google version * specify keywords instead of 0/1/2 * start configuring ts * remove some redundant react rules * add separate jest config * move ts to overrides * remove prettier, no need * allow spec or test files * restore flow * add tests * add a ci test * remove printed rules * update readme
1 parent d9353bf commit 7bb7e74

15 files changed

+6073
-84
lines changed

.github/workflows/test.yaml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: unit tests
2+
3+
env:
4+
CI: True
5+
6+
on: [push]
7+
8+
jobs:
9+
test-linting:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v3
13+
- uses: actions/setup-node@v3
14+
with:
15+
node-version: "16"
16+
cache: "yarn"
17+
- run: yarn install --immutable
18+
- run: yarn run test

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
11
node_modules/
22
*.tgz
3+
4+
.pnp.*
5+
.yarn/*
6+
!.yarn/patches
7+
!.yarn/plugins
8+
!.yarn/releases
9+
!.yarn/sdks
10+
!.yarn/versions

.yarn/releases/yarn-3.2.3.cjs

+783
Large diffs are not rendered by default.

.yarnrc.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
yarnPath: .yarn/releases/yarn-3.2.3.cjs
2+
nodeLinker: "node-modules"
3+
supportedArchitectures:
4+
os: [linux, darwin]
5+
cpu: [x64, arm64]

README.md

+26-3
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,45 @@
22

33
This is our preferred configuration for `eslint`. To use it:
44

5-
```
5+
```sh
66
yarn add eslint-config-mitodl
77
```
8-
8+
There are four configs included. They are:
9+
```
10+
eslint-config-mitodl // base config with support for Typescript and JS
11+
eslint-config-mitodl/jest
12+
eslint-config-mitodl/mocha
13+
eslint-config-mitodl/flow
14+
```
915
and then change your `.eslintrc` to have:
1016

17+
```json
18+
{
19+
"extends": [
20+
"eslint-config-mitodl",
21+
"eslint-config-mitodl/jest"
22+
]
23+
}
1124
```
25+
Or, to support FlowType and Mocha in older projects:
26+
27+
```json
1228
{
13-
"extends": "eslint-config-mitodl"
29+
"extends": [
30+
"eslint-config-mitodl",
31+
"eslint-config-mitodl/flow",
32+
"eslint-config-mitodl/mocha"
33+
]
1434
}
1535
```
1636

1737
This package has several peer dependencies (eslint plugins for react and
1838
flow, prettier, etc) so make sure you satisfy those! Once you do you
1939
should be in linting heaven.
2040

41+
## Local development
42+
Run tests with `yarn run test`. The tests are very basic, just checking that some simple eslint errors are raised where expected.
43+
2144
## JavaScript style
2245

2346
This is an opinionated setup. It enforces a number of things which

flow.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module.exports = {
2+
"parser": "babel-eslint",
3+
plugins: [
4+
"flowtype",
5+
"flow-vars",
6+
],
7+
rules: {
8+
"flow-vars/define-flow-type": ["error"],
9+
"flow-vars/use-flow-type": ["error"],
10+
"flowtype/space-after-type-colon": ["off"],
11+
"flowtype/space-before-type-colon": ["error", "never"],
12+
"flowtype/generic-spacing": ["error", "never"],
13+
"flowtype/no-dupe-keys": ["error"],
14+
"flowtype/no-primitive-constructor-types": ["error"],
15+
"flowtype/object-type-delimiter": ["error", "comma"],
16+
}
17+
}

index.js

+76-67
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
module.exports = {
2-
"parser": "babel-eslint",
2+
"parser": "@typescript-eslint/parser",
3+
"plugins": [
4+
"react",
5+
"react-hooks",
6+
],
7+
settings: {
8+
react: {
9+
version: 'detect',
10+
},
11+
},
12+
"env": {
13+
"es6": true,
14+
"browser": true,
15+
"node": true,
16+
},
317
"extends": [
418
"google",
519
"eslint:recommended",
620
"plugin:react/recommended",
7-
"plugin:react-hooks/recommended"
21+
"plugin:react-hooks/recommended",
822
],
923
"rules": {
10-
"prefer-const": [2],
11-
"key-spacing": [2, {
24+
"key-spacing": ["error", {
1225
"beforeColon": false,
1326
"afterColon": true,
1427
"align": {
@@ -18,77 +31,73 @@ module.exports = {
1831
"on": "value"
1932
}
2033
}],
21-
"quotes": [0], // no opinion on ' vs "
22-
"object-curly-spacing": [0],
23-
"new-cap": [0], // allows function calls like Immutable.Map(...)
24-
"max-len": [0, {
25-
"code": 80,
26-
"ignoreComments": true,
27-
}],
28-
"indent": [2, 2], // no tabs, indent is 2 spaces
29-
"newline-after-var": [0],
30-
"react/jsx-indent-props": [2, 2], // no tabs, indent is two spaces
31-
"react/jsx-key": [2], // validate that key prop exists
32-
"react/jsx-no-undef": [2], // disallow undeclared variables in JSX
33-
"react/prop-types": [0],
34-
"react/display-name" : [0],
35-
"react/no-find-dom-node": [0],
36-
"react/no-unescaped-entities": [0],
37-
"no-unused-vars": [ 2, {
34+
"quotes": ["off"], // no opinion on ' vs ", let Prettier decide
35+
"object-curly-spacing": ["off"], // no opinion, let Prettier decide
36+
"new-cap": ["off"], // allows function calls like Immutable.Map(...)
37+
"max-len": ["off"], // no opinion, let Prettier decide
38+
"indent": ["error", 2],
39+
"newline-after-var": ["off"],
40+
"no-unused-vars": [ "error", {
3841
"vars": "local",
3942
"argsIgnorePattern": "action"
4043
}],
41-
"comma-dangle": [0],
42-
"no-unreachable": [2],
43-
"semi": [2, "never"],
44-
"eqeqeq": [2],
45-
"no-var": [2],
46-
"camelcase": [2, {
44+
"comma-dangle": ["off"],
45+
"semi": ["error", "never"],
46+
"eqeqeq": ["error"],
47+
"no-var": ["error"],
48+
"camelcase": ["error", {
4749
"properties": "never"
4850
}],
49-
"guard-for-in": [2],
50-
"prefer-template": [2],
51-
"space-infix-ops": [2],
52-
"space-before-blocks": [2],
53-
"space-in-parens": [2],
54-
"mocha/no-exclusive-tests": [2],
55-
"mocha/no-skipped-tests": [2],
56-
"mocha/no-sibling-hooks": [2],
57-
"mocha/no-global-tests": [2],
58-
"mocha/handle-done-callback": [2],
59-
"mocha/no-top-level-hooks": [2],
60-
"mocha/no-identical-title": [2],
61-
"mocha/no-nested-tests": [2],
62-
"no-throw-literal": [2],
63-
"arrow-parens": [2, "as-needed"],
64-
"valid-jsdoc": 0,
65-
"require-jsdoc": 0,
66-
"spaced-comment": 0,
67-
"no-invalid-this": 0,
68-
"one-var": [2, {
51+
"guard-for-in": ["error"],
52+
"prefer-template": ["error"],
53+
"space-infix-ops": ["error"],
54+
"space-before-blocks": ["error"],
55+
"space-in-parens": ["error"],
56+
"no-throw-literal": ["error"],
57+
"arrow-parens": ["error", "as-needed"],
58+
"valid-jsdoc": ["off"],
59+
"require-jsdoc": ["off"],
60+
"spaced-comment": ["off"],
61+
"no-invalid-this": ["off"],
62+
"one-var": ["error", {
6963
"uninitialized": "always"
7064
}],
71-
"no-multi-spaces": 0,
72-
"prefer-promise-reject-errors": 0,
73-
"quote-props": [2, "as-needed"],
74-
"no-prototype-builtins": [0],
75-
"react-hooks/rules-of-hooks": "error",
76-
"react-hooks/exhaustive-deps": "warn"
65+
"no-multi-spaces": ["off"],
66+
"prefer-promise-reject-errors": ["off"],
67+
"quote-props": ["error", "as-needed"],
68+
"no-prototype-builtins": ["off"],
69+
"react/jsx-indent-props": ["error", 2], // no tabs, indent is two spaces
70+
"react/jsx-key": ["error"], // validate that key prop exists
71+
"react/jsx-no-undef": ["error"], // disallow undeclared variables in JSX
72+
"react/prop-types": ["off"],
73+
"react/display-name" : ["off"],
74+
"react/no-unescaped-entities": ["off"],
7775
},
78-
"env": {
79-
"es6": true,
80-
"browser": true,
81-
"node": true,
82-
"mocha": true
83-
},
84-
"parserOptions": {
85-
"ecmaFeatures": {
86-
"jsx": true
76+
overrides: [
77+
{
78+
files: ["*.ts", "*.tsx"],
79+
plugins: ["@typescript-eslint"],
80+
extends: ["plugin:@typescript-eslint/recommended"],
81+
rules: {
82+
"no-unused-vars": "off",
83+
"@typescript-eslint/no-unused-vars": [
84+
"error",
85+
{
86+
varsIgnorePattern: "^_",
87+
argsIgnorePattern: "^_",
88+
destructuredArrayIgnorePattern: "^_",
89+
ignoreRestSiblings: true,
90+
}
91+
],
92+
},
93+
overrides: [
94+
{
95+
files: ["*.test.ts?(x)", "*.spec.ts?(x)"],
96+
rules: {
97+
"@typescript-eslint/no-non-null-assertion": "off",
98+
}
99+
}
100+
]
87101
},
88-
},
89-
"plugins": [
90-
"react",
91-
"mocha",
92-
"react-hooks"
93102
]
94103
}

jest.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module.exports = {
2+
overrides: [
3+
{
4+
files: ["**/?(*.)+(test|spec).[jt]s?(x)"],
5+
env: {
6+
"jest/globals": true
7+
},
8+
"extends": ["plugin:jest/recommended"],
9+
rules: {
10+
/**
11+
* We sometimes have custom expectation functions.
12+
* You can add custom expectations to the rule (including patterns)
13+
* but without a more helpful error message, let's just turn this off
14+
* for now.
15+
*/
16+
"jest/expect-expect": "off",
17+
/**
18+
* Conditionals in tests can be confusing. But we fairly often write
19+
* tests along the lines of `test.each([true, false])` that toggle a
20+
* particular behavior. Combining the test cases but toggling behavior
21+
* with `.each` is nice because it highlights what actually controls the
22+
* change in behavior. However, this can require legitimate uses of
23+
* conditional expectations.
24+
*
25+
* Rather than littering our tests with "eslint-disable" comments, lets
26+
* turn this off.
27+
*/
28+
"jest/no-conditional-expect": "off"
29+
},
30+
},
31+
],
32+
};

mocha.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
env: {
3+
mocha: true
4+
},
5+
rules: {
6+
"mocha/no-exclusive-tests": [2],
7+
"mocha/no-skipped-tests": [2],
8+
"mocha/no-sibling-hooks": [2],
9+
"mocha/no-global-tests": [2],
10+
"mocha/handle-done-callback": [2],
11+
"mocha/no-top-level-hooks": [2],
12+
"mocha/no-identical-title": [2],
13+
"mocha/no-nested-tests": [2],
14+
},
15+
plugins: [
16+
"mocha",
17+
]
18+
};

package-lock.json

-5
This file was deleted.

package.json

+37-9
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,50 @@
33
"version": "0.2.1",
44
"description": "JavaScript style rules for MITODL",
55
"main": "index.js",
6-
"scripts": {
7-
"test": "echo \"Error: no test specified\" && exit 1"
8-
},
96
"keywords": [
107
"eslint",
118
"mitodl",
129
"mit"
1310
],
11+
"scripts": {
12+
"test": "eslint --report-unused-disable-directives ./tests"
13+
},
1414
"author": "Alice Pote",
1515
"license": "ISC",
16+
"dependencies": {
17+
"@typescript-eslint/parser": "^5.39.0",
18+
"babel-eslint": "^10.1.0",
19+
"eslint-config-google": "^0.14.0"
20+
},
21+
"devDependencies": {
22+
"@typescript-eslint/eslint-plugin": "^5.39.0",
23+
"eslint": "^7.32.0",
24+
"eslint-plugin-flowtype": "4.x",
25+
"eslint-plugin-jest": "^27.1.1",
26+
"eslint-plugin-mocha": "6.x",
27+
"eslint-plugin-react": "^7.31.8",
28+
"eslint-plugin-react-hooks": "^4.6",
29+
"jest": "^29.2.1",
30+
"typescript": "^4.8.4"
31+
},
1632
"peerDependencies": {
17-
"eslint": "7.x",
18-
"eslint-config-google": "0.x",
33+
"@typescript-eslint/eslint-plugin": "^5.39.0",
34+
"eslint": "^7.32.0",
35+
"eslint-plugin-jest": "^27.1.1",
1936
"eslint-plugin-mocha": "6.x",
20-
"eslint-plugin-react": "7.x",
21-
"prettier-eslint-cli": "5.x",
22-
"eslint-plugin-react-hooks": "4.x"
23-
}
37+
"eslint-plugin-react": "^7.31.8",
38+
"eslint-plugin-react-hooks": "^4.6"
39+
},
40+
"peerDependenciesMeta": {
41+
"eslint-plugin-flowtype": {
42+
"optional": true
43+
},
44+
"eslint-plugin-jest": {
45+
"optional": true
46+
},
47+
"eslint-plugin-mocha": {
48+
"optional": true
49+
}
50+
},
51+
"packageManager": "[email protected]"
2452
}

0 commit comments

Comments
 (0)