Skip to content

Commit ff25588

Browse files
authored
chore(deps): removed dependency on micromatch for expect-expect (#517)
* chore: removed dependency on micromatch for expect-expect * chore(deps): removed dependency on micromatch for expect-expect * fix: wildcards should always match to the end of string or a dot
1 parent 38bbe93 commit ff25588

File tree

5 files changed

+129
-72
lines changed

5 files changed

+129
-72
lines changed

docs/rules/expect-expect.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ it('should work with callbacks/async', () => {
4343
### `assertFunctionNames`
4444

4545
This array option whitelists the assertion function names to look for. Function
46-
names can be a glob pattern like `request.*.expect` (see
47-
[micromatch](https://github.com/micromatch/micromatch) for syntax)
46+
names can use wildcards like `request.*.expect`, `request.**.expect`,
47+
`request.*.expect*`
4848

4949
Examples of **incorrect** code for the `{ "assertFunctionNames": ["expect"] }`
5050
option:

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@
3737
"typecheck": "tsc -p ."
3838
},
3939
"dependencies": {
40-
"@typescript-eslint/experimental-utils": "^2.5.0",
41-
"micromatch": "^4.0.2"
40+
"@typescript-eslint/experimental-utils": "^2.5.0"
4241
},
4342
"devDependencies": {
4443
"@babel/cli": "^7.4.4",
@@ -51,7 +50,6 @@
5150
"@semantic-release/git": "^7.0.17",
5251
"@types/eslint": "^6.1.3",
5352
"@types/jest": "^24.0.15",
54-
"@types/micromatch": "^4.0.0",
5553
"@types/node": "^12.6.6",
5654
"@typescript-eslint/eslint-plugin": "^2.5.0",
5755
"@typescript-eslint/parser": "^2.5.0",

src/rules/__tests__/expect-expect.test.ts

Lines changed: 97 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -28,65 +28,15 @@ ruleTester.run('expect-expect', rule, {
2828
options: [{ assertFunctionNames: ['expectSaga'] }],
2929
},
3030
{
31-
code: `test('verifies expect method call', () => {
32-
class Foo {
33-
expect(k) {
34-
return k;
35-
}
36-
}
37-
new Foo().expect(123);
38-
});`,
31+
code: `test('verifies expect method call', () => new Foo().expect(123));`,
3932
options: [{ assertFunctionNames: ['Foo.expect'] }],
4033
},
4134
{
42-
code: `test('verifies deep expect method call', () => {
43-
class Foo {
44-
expect(k) {
45-
return k;
46-
}
47-
}
48-
let tester = {
49-
foo: function() {
50-
return new Foo()
51-
}
52-
}
53-
tester.foo().expect(123);
54-
});`,
35+
code: `test('verifies deep expect method call', () => tester.foo().expect(123));`,
5536
options: [{ assertFunctionNames: ['tester.foo.expect'] }],
5637
},
5738
{
58-
code: `test('wildcard chained function', () => {
59-
class Foo {
60-
expect(k) {
61-
return k;
62-
}
63-
}
64-
let tester = {
65-
foo: function() {
66-
return new Foo()
67-
}
68-
}
69-
tester.foo().expect(123);
70-
});`,
71-
options: [{ assertFunctionNames: ['tester.*.expect'] }],
72-
},
73-
{
74-
code: `test('verifies recursive expect method call', () => {
75-
class Foo {
76-
expect(k) {
77-
return this;
78-
}
79-
bar() {
80-
return this;
81-
}
82-
}
83-
let tester = {
84-
foo: function() {
85-
return new Foo()
86-
}
87-
}
88-
tester.foo().bar().expect(456);
89-
});`,
39+
code: `test('verifies recursive expect method call', () => tester.foo().bar().expect(456));`,
9040
options: [{ assertFunctionNames: ['tester.foo.bar.expect'] }],
9141
},
9242
{
@@ -162,3 +112,97 @@ ruleTester.run('expect-expect', rule, {
162112
},
163113
],
164114
});
115+
116+
// {
117+
// code: `test('wildcard chained function', () => tester.foo().expect(123));`,
118+
// options: [{ assertFunctionNames: ['tester.*.expect'] }],
119+
// },
120+
121+
ruleTester.run('wildcards', rule, {
122+
valid: [
123+
{
124+
code: `test('should pass', () => tester.foo().expect(123));`,
125+
options: [{ assertFunctionNames: ['tester.*.expect'] }],
126+
},
127+
{
128+
code: `test('should pass **', () => tester.foo().expect(123));`,
129+
options: [{ assertFunctionNames: ['**'] }],
130+
},
131+
{
132+
code: `test('should pass *', () => tester.foo().expect(123));`,
133+
options: [{ assertFunctionNames: ['*'] }],
134+
},
135+
{
136+
code: `test('should pass', () => tester.foo().expect(123));`,
137+
options: [{ assertFunctionNames: ['tester.**'] }],
138+
},
139+
{
140+
code: `test('should pass', () => tester.foo().expect(123));`,
141+
options: [{ assertFunctionNames: ['tester.*'] }],
142+
},
143+
{
144+
code: `test('should pass', () => tester.foo().bar().expectIt(456));`,
145+
options: [{ assertFunctionNames: ['tester.**.expect*'] }],
146+
},
147+
{
148+
code: `test('should pass', () => request.get().foo().expect(456));`,
149+
options: [{ assertFunctionNames: ['request.**.expect'] }],
150+
},
151+
{
152+
code: `test('should pass', () => request.get().foo().expect(456));`,
153+
options: [{ assertFunctionNames: ['request.**.e*e*t'] }],
154+
},
155+
],
156+
invalid: [
157+
{
158+
code: `test('should fail', () => request.get().foo().expect(456));`,
159+
options: [{ assertFunctionNames: ['request.*.expect'] }],
160+
errors: [
161+
{
162+
messageId: 'noAssertions',
163+
type: AST_NODE_TYPES.CallExpression,
164+
},
165+
],
166+
},
167+
{
168+
code: `test('should fail', () => request.get().foo().bar().expect(456));`,
169+
options: [{ assertFunctionNames: ['request.foo**.expect'] }],
170+
errors: [
171+
{
172+
messageId: 'noAssertions',
173+
type: AST_NODE_TYPES.CallExpression,
174+
},
175+
],
176+
},
177+
{
178+
code: `test('should fail', () => tester.request(123));`,
179+
options: [{ assertFunctionNames: ['request.*'] }],
180+
errors: [
181+
{
182+
messageId: 'noAssertions',
183+
type: AST_NODE_TYPES.CallExpression,
184+
},
185+
],
186+
},
187+
{
188+
code: `test('should fail', () => request(123));`,
189+
options: [{ assertFunctionNames: ['request.*'] }],
190+
errors: [
191+
{
192+
messageId: 'noAssertions',
193+
type: AST_NODE_TYPES.CallExpression,
194+
},
195+
],
196+
},
197+
{
198+
code: `test('should fail', () => request(123));`,
199+
options: [{ assertFunctionNames: ['request.**'] }],
200+
errors: [
201+
{
202+
messageId: 'noAssertions',
203+
type: AST_NODE_TYPES.CallExpression,
204+
},
205+
],
206+
},
207+
],
208+
});

src/rules/expect-expect.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,38 @@ import {
77
AST_NODE_TYPES,
88
TSESTree,
99
} from '@typescript-eslint/experimental-utils';
10-
import micromatch from 'micromatch';
1110
import {
1211
TestCaseName,
1312
createRule,
1413
getNodeName,
1514
getTestCallExpressionsFromDeclaredVariables,
1615
} from './utils';
1716

17+
/**
18+
* Checks if node names returned by getNodeName matches any of the given star patterns
19+
* Pattern examples:
20+
* request.*.expect
21+
* request.**.expect
22+
* request.**.expect*
23+
*/
24+
function matchesAssertFunctionName(
25+
nodeName: string,
26+
patterns: readonly string[],
27+
): boolean {
28+
return patterns.some(p =>
29+
new RegExp(
30+
`^${p
31+
.split('.')
32+
.map(x => {
33+
if (x === '**') return '[a-z\\.]*';
34+
return x.replace(/\*/g, '[a-z]*');
35+
})
36+
.join('\\.')}(\\.|$)`,
37+
'ui',
38+
).test(nodeName),
39+
);
40+
}
41+
1842
export default createRule<
1943
[Partial<{ assertFunctionNames: readonly string[] }>],
2044
'noAssertions'
@@ -75,7 +99,10 @@ export default createRule<
7599
const name = getNodeName(node.callee);
76100
if (name === TestCaseName.it || name === TestCaseName.test) {
77101
unchecked.push(node);
78-
} else if (name && micromatch.isMatch(name, assertFunctionNames)) {
102+
} else if (
103+
name &&
104+
matchesAssertFunctionName(name, assertFunctionNames)
105+
) {
79106
// Return early in case of nested `it` statements.
80107
checkCallExpressionUsed(context.getAncestors());
81108
}

yarn.lock

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,11 +1279,6 @@
12791279
dependencies:
12801280
"@babel/types" "^7.3.0"
12811281

1282-
"@types/braces@*":
1283-
version "3.0.0"
1284-
resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb"
1285-
integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==
1286-
12871282
"@types/color-name@^1.1.1":
12881283
version "1.1.1"
12891284
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
@@ -1353,13 +1348,6 @@
13531348
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
13541349
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==
13551350

1356-
"@types/micromatch@^4.0.0":
1357-
version "4.0.0"
1358-
resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.0.tgz#c57e0b11518c930465ce923f44342e1bb4bef309"
1359-
integrity sha512-bavSCssCRRlbUI639WG0Y30AOowkI5CdxyyrC5eVbsb0BJIbgS5ROfwlwDYHsOmgS59iYlre9sstIA5wfVNKBA==
1360-
dependencies:
1361-
"@types/braces" "*"
1362-
13631351
"@types/minimatch@*":
13641352
version "3.0.3"
13651353
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"

0 commit comments

Comments
 (0)