Skip to content

Commit 271aa69

Browse files
Willem WyndhamColinEberhardt
Willem Wyndham
authored andcommitted
fix: switch to eslint and add husky
1 parent 8c2e624 commit 271aa69

17 files changed

+1391
-368
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

.eslintrc.js

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
module.exports = {
2+
root: true,
3+
parser: "@typescript-eslint/parser",
4+
plugins: [
5+
"@typescript-eslint",
6+
],
7+
extends: [
8+
"eslint:recommended",
9+
"plugin:@typescript-eslint/eslint-recommended",
10+
"plugin:@typescript-eslint/recommended",
11+
],
12+
parserOptions: {
13+
ecmaVersion: 2020,
14+
sourceType: "module",
15+
ecmaFeatures: {}
16+
},
17+
ignorePatterns: ["node_modules/**/*"],
18+
// === General rules =========================================================
19+
20+
rules: {
21+
// Omitted semicolons are hugely popular, yet within the compiler it makes
22+
// sense to be better safe than sorry.
23+
"semi": "error",
24+
25+
// Our code bases uses 2 spaces for indentation, and we enforce it here so
26+
// files don't mix spaces, tabs or different indentation levels.
27+
"indent": ["error", 2, {
28+
"SwitchCase": 1,
29+
"VariableDeclarator": "first",
30+
"offsetTernaryExpressions": true,
31+
"ignoredNodes": [ // FIXME: something's odd here
32+
"ConditionalExpression > *",
33+
"ConditionalExpression > * > *",
34+
"ConditionalExpression > * > * > *"
35+
]
36+
}],
37+
38+
// This is mostly visual style, making comments look uniform.
39+
"spaced-comment": ["error", "always", {
40+
"markers": ["/"], // triple-slash
41+
"exceptions": ["/"] // all slashes
42+
}],
43+
44+
// This tends to be annoying as it encourages developers to make everything
45+
// that is never reassigned a 'const', sometimes semantically incorrect so,
46+
// typically leading to huge diffs in follow-up PRs modifying affected code.
47+
"prefer-const": "off",
48+
49+
// It is perfectly fine to declare top-level variables with `var`, yet this
50+
// rule doesn't provide configuration options that would help.
51+
"no-var": "off",
52+
53+
// Quite often, dealing with multiple related cases at once or otherwise
54+
// falling through is exactly the point of using a switch.
55+
"no-fallthrough": "off",
56+
57+
// Typical false-positives here are `do { ... } while (true)` statements or
58+
// similar, but the only option provided here is not checking any loops.
59+
"no-constant-condition": ["error", { checkLoops: false }],
60+
61+
// Functions are nested in blocks occasionally, and there haven't been any
62+
// problems with this so far, so turning the check off.
63+
"no-inner-declarations": "off",
64+
65+
// Quite common in scenarios where an iteration starts at `current = this`.
66+
"@typescript-eslint/no-this-alias": "off",
67+
68+
// Disabled here, but enabled again for JavaScript files.
69+
"no-unused-vars": "off",
70+
71+
// Disabled here, but enabled again for TypeScript files.
72+
"@typescript-eslint/no-unused-vars": "off"
73+
},
74+
overrides: [
75+
76+
// === TypeScript rules ====================================================
77+
78+
{
79+
files: [
80+
"**/assembly/**/*.ts"
81+
],
82+
rules: {
83+
// Enforcing to remove function parameters on stubs makes code less
84+
// maintainable, so we instead allow unused function parameters.
85+
"@typescript-eslint/no-unused-vars": [
86+
"warn", {
87+
"vars": "local",
88+
"varsIgnorePattern": "^_|^[A-Z](?:From|To)?$", // ignore type params
89+
"args": "none",
90+
"ignoreRestSiblings": false
91+
}
92+
],
93+
94+
// Namespaces are quite useful in AssemblyScript
95+
"@typescript-eslint/no-namespace": "off",
96+
97+
// There is actually codegen difference here
98+
"@typescript-eslint/no-array-constructor": "off",
99+
100+
// Sometimes it can't be avoided to add a @ts-ignore
101+
"@typescript-eslint/ban-ts-comment": "off",
102+
103+
// Utilized to achieve portability in some cases
104+
"@typescript-eslint/no-non-null-assertion": "off",
105+
}
106+
},
107+
108+
// === Compiler rules (extends AssemblyScript rules) =======================
109+
110+
{
111+
files: [
112+
"**/assembly/**/*.ts"
113+
],
114+
rules: {
115+
// There is an actual codegen difference here - TODO: revisit
116+
"no-cond-assign": "off",
117+
118+
// Not all types can be omitted in AS yet - TODO: revisit
119+
"@typescript-eslint/no-inferrable-types": "off",
120+
121+
// Used rarely to reference internals that are not user-visible
122+
"@typescript-eslint/triple-slash-reference": "off",
123+
124+
// The compiler has its own `Function` class for example
125+
"no-shadow-restricted-names": "off",
126+
"@typescript-eslint/ban-types": "off"
127+
}
128+
},
129+
130+
// === Standard Library rules (extends AssemblyScript rules) ===============
131+
132+
{
133+
files: [
134+
"**/assembly/**/*.ts"
135+
],
136+
rules: {
137+
// We are implementing with --noLib, so we shadow all the time
138+
"no-shadow-restricted-names": "off",
139+
140+
// Similarly, sometimes we need the return type to be String, not string
141+
"@typescript-eslint/ban-types": "off"
142+
}
143+
},
144+
145+
// === Standard Definition rules (extends TypeScript rules) ================
146+
147+
{
148+
files: [
149+
"**/assembly/**/*.d.ts"
150+
],
151+
rules: {
152+
// Often required to achieve compatibility with TypeScript
153+
"@typescript-eslint/no-explicit-any": "off",
154+
155+
// Interfaces can be stubs here, i.e. not yet fully implemented
156+
"@typescript-eslint/no-empty-interface": "off",
157+
158+
// Definitions make use of `object` to model rather unusual constraints
159+
"@typescript-eslint/ban-types": "off"
160+
}
161+
},
162+
163+
164+
165+
// === Test rules (extends TypeScript rules) ===============================
166+
167+
{
168+
files: [
169+
"**/assembly/__tests__/**/*.ts"
170+
],
171+
rules: {
172+
// Tests typically include unusual code patterns on purpose. This is
173+
// very likely not an extensive list, but covers what's there so far.
174+
"no-empty": "off",
175+
"no-cond-assign": "off",
176+
"no-compare-neg-zero": "off",
177+
"no-inner-declarations": "off",
178+
"no-constant-condition": "off",
179+
"use-isnan": "off",
180+
"@typescript-eslint/no-namespace": "off",
181+
"@typescript-eslint/no-unused-vars": "off",
182+
"@typescript-eslint/no-empty-function": "off",
183+
"@typescript-eslint/no-non-null-assertion": "off",
184+
"@typescript-eslint/no-extra-semi": "off",
185+
"@typescript-eslint/no-inferrable-types": "off",
186+
"@typescript-eslint/ban-types": "off",
187+
"@typescript-eslint/triple-slash-reference": "off",
188+
"@typescript-eslint/ban-ts-comment": "off",
189+
"@typescript-eslint/no-extra-non-null-assertion": "off",
190+
"@typescript-eslint/no-empty-interface": "off"
191+
}
192+
},
193+
]
194+
};
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { expectMatch, expectNotMatch } from "./utils";
2+
3+
it("or", () => {
4+
expectMatch("a|b", ["b", "a"]);
5+
expectNotMatch("a|b", ["c"]);
6+
expectMatch("a|br", ["br", "a"]);
7+
expectNotMatch("a|br", ["b", "c"]);
8+
});
9+
10+
it("or multi-term", () => {
11+
expectMatch("a|b|c", ["b", "a", "c"]);
12+
expectNotMatch("a|b|c", ["d"]);
13+
expectMatch("a|br|pc", ["br", "a", "pc"]);
14+
expectNotMatch("a|br|pc", ["b", "pr"]);
15+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { expectMatch, expectNotMatch, exec} from "./utils";
2+
3+
it("matches end of string", () => {
4+
const match = exec("a$", "ba");
5+
expect(match.index).toBe(1);
6+
expect(match.matches[0]).toBe("a");
7+
expectNotMatch("a$", ["ab"]);
8+
});
9+
10+
it("matches start of string", () => {
11+
expectMatch("^a", ["a"]);
12+
expectNotMatch("^a", ["ba"]);
13+
});
14+
15+
it("handles escaped boundaries", () => {
16+
expectMatch("\\^a", ["^a"]);
17+
expectMatch("a\\$", ["a$"]);
18+
});
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expectMatch, expectNotMatch, exec} from "./utils";
2+
3+
it("supports capture groups", () => {
4+
let match = exec("a(\\d)a", "a3a");
5+
expect(match.index).toBe(0);
6+
expect(match.input).toBe("a3a");
7+
expect(match.matches[0]).toBe("a3a");
8+
expect(match.matches[1]).toBe("3");
9+
10+
match = exec("a(\\d)a", " a3a");
11+
expect(match.index).toBe(2);
12+
expect(match.input).toBe(" a3a");
13+
expect(match.matches[0]).toBe("a3a");
14+
expect(match.matches[1]).toBe("3");
15+
16+
match = exec("a(\\d*)a", "a3456a");
17+
expect(match.index).toBe(0);
18+
expect(match.input).toBe("a3456a");
19+
expect(match.matches[0]).toBe("a3456a");
20+
expect(match.matches[1]).toBe("3456");
21+
22+
match = exec("a*(\\d*)(a*)", "aaa456aaa");
23+
expect(match.index).toBe(0);
24+
expect(match.input).toBe("aaa456aaa");
25+
expect(match.matches[0]).toBe("aaa456aaa");
26+
expect(match.matches[1]).toBe("456");
27+
expect(match.matches[2]).toBe("aaa");
28+
});
29+
30+
xit("should not return captured values for non-matching alternations", () => {
31+
const match = exec("(a|b)c|a(b|c)", "ab");
32+
expect(match.matches[0]).toBe("ab");
33+
expect(match.matches[1]).toBe("");
34+
expect(match.matches[2]).toBe("b");
35+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { RegExp } from "..";
2+
import { expectMatch, expectNotMatch, exec} from "./utils";
3+
4+
xit("should throw with un-supported classes", () => {
5+
// expect(() => new RegExp("\\o")).toThrow();
6+
});
7+
8+
it("dot", () => {
9+
expectMatch(".", [" ", "B", "|", "9"]);
10+
expectNotMatch(".", ["", "\n"]);
11+
});
12+
13+
it("digit", () => {
14+
expectMatch("\\d", ["0", "9"]);
15+
expectNotMatch("\\d", ["", "b"]);
16+
});
17+
18+
it("non-digit", () => {
19+
expectNotMatch("\\D", ["0", "9", ""]);
20+
expectMatch("\\D", ["b", "|"]);
21+
});
22+
23+
it("word", () => {
24+
expectMatch("\\w", ["A", "a", "Z", "z", "0", "9", "_"]);
25+
expectNotMatch("\\w", ["", "$"]);
26+
});
27+
28+
it("not word", () => {
29+
expectNotMatch("\\W", ["A", "a", "Z", "z", "0", "9", "_", ""]);
30+
expectMatch("\\W", ["&", "$"]);
31+
});
32+
33+
it("whitespace", () => {
34+
expectMatch("\\s", ["\f", "\n", "\r", "\t", "\v"]);
35+
expectNotMatch("\\s", ["", "a", "0"]);
36+
});
37+
38+
it("not whitespace", () => {
39+
expectNotMatch("\\S", ["", "\f", "\n", "\r", "\t", "\v"]);
40+
expectMatch("\\S", ["a", "0"]);
41+
});
42+
43+
it("tab, cr, lf, vt, ff", () => {
44+
expectMatch("\\t", ["\t"]);
45+
expectMatch("\\r", ["\r"]);
46+
expectMatch("\\n", ["\n"]);
47+
expectMatch("\\v", ["\v"]);
48+
expectMatch("\\f", ["\f"]);
49+
expectNotMatch("\\t", ["a", " ", ""]);
50+
});
51+
52+
it("escaped dot", () => {
53+
expectMatch("\\.", ["."]);
54+
expectNotMatch("\\.", ["", "a"]);
55+
});
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { expectMatch, expectNotMatch } from "./utils";
2+
3+
it("throws an error if no closing bracket is found", () => {
4+
// expect(() => new RegExp("[abce")).toThrow();
5+
});
6+
7+
it("matches discrete characters", () => {
8+
expectMatch("[abce]", ["a", "b", "c", "e"]);
9+
expectNotMatch("[abce]", ["", "f", "h"]);
10+
});
11+
12+
it("matches character ranges", () => {
13+
expectMatch("[a-c]", ["a", "b", "c"]);
14+
expectNotMatch("[a-c]", ["d", "e", ""]);
15+
expectMatch("[K-M]", ["K", "L", "M"]);
16+
expectNotMatch("[K-M]", ["9", "J"]);
17+
expectMatch("[0-9]", ["0", "9"]);
18+
expectNotMatch("[0-9]", ["a", "A"]);
19+
});
20+
21+
it("matches multiple ranges", () => {
22+
expectMatch("[a-ce-f]", ["a", "b", "c", "e", "f"]);
23+
expectNotMatch("[a-ce-f]", ["d"]);
24+
});
25+
26+
it("supports closing brackets", () => {
27+
expectMatch("[]a]", ["]", "a"]);
28+
});
29+
30+
it("supports negated sets", () => {
31+
expectNotMatch("[^a-c]", ["a", "b", "c"]);
32+
expectMatch("[^a-c]", ["d", "e"]);
33+
expectNotMatch("[^a-ce-f]", ["a", "b", "c", "e", "f"]);
34+
expectMatch("[^a-ce-f]", ["d"]);
35+
});
36+
37+
it("treats - as a literal", () => {
38+
expectMatch("[-abc]", ["-", "a", "b", "c"]);
39+
expectMatch("[abc-]", ["-", "a", "b", "c"]);
40+
});
41+
42+
it("treats - as a literal in negated sets", () => {
43+
expectNotMatch("[^-abc]", ["-", "a", "b", "c"]);
44+
expectMatch("[^-abc]", ["1", "A"]);
45+
});

assembly/__tests__/characters.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { expectMatch, expectNotMatch } from "./utils";
2+
3+
it("single character", () => {
4+
expectMatch("a", ["a"]);
5+
expectNotMatch("a", ["fish", ""]);
6+
});
7+
8+
it("concatenation", () => {
9+
expectMatch("ab", ["ab"]);
10+
expectNotMatch("ab", ["aac", "aa", ""]);
11+
});

0 commit comments

Comments
 (0)