eslint-plugin-test-governance 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -1
- package/dist/utils/analyze.js +42 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,14 @@ All notable changes to this project are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.11.1] - 2026-11-03
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- A skip declared through `Function.prototype.call`, `apply` or `bind`, such as
|
|
14
|
+
`test.skip.call(null, 'places an order', fn)` or `test.skip.bind(null)('places an order', fn)`, is
|
|
15
|
+
checked like the plain call, so it needs its ticket.
|
|
16
|
+
|
|
9
17
|
## [0.11.0] - 2026-11-01
|
|
10
18
|
|
|
11
19
|
### Added
|
|
@@ -439,7 +447,8 @@ First release.
|
|
|
439
447
|
- Support for ESLint 9 and 10 flat config, JavaScript and TypeScript test files, `.extend()`
|
|
440
448
|
fixtures, describe blocks, runtime skips and tags in titles or the `tag` option.
|
|
441
449
|
|
|
442
|
-
[Unreleased]: https://github.com/Huldoser/eslint-plugin-test-governance/compare/v0.11.
|
|
450
|
+
[Unreleased]: https://github.com/Huldoser/eslint-plugin-test-governance/compare/v0.11.1...HEAD
|
|
451
|
+
[0.11.1]: https://github.com/Huldoser/eslint-plugin-test-governance/compare/v0.11.0...v0.11.1
|
|
443
452
|
[0.11.0]: https://github.com/Huldoser/eslint-plugin-test-governance/compare/v0.10.1...v0.11.0
|
|
444
453
|
[0.10.1]: https://github.com/Huldoser/eslint-plugin-test-governance/compare/v0.10.0...v0.10.1
|
|
445
454
|
[0.10.0]: https://github.com/Huldoser/eslint-plugin-test-governance/compare/v0.9.0...v0.10.0
|
package/dist/utils/analyze.js
CHANGED
|
@@ -312,6 +312,46 @@ function isLocalVariable(sourceCode, id) {
|
|
|
312
312
|
}
|
|
313
313
|
const STATEMENT_CONTAINERS = new Set(['Program', 'BlockStatement', 'StaticBlock', 'SwitchCase', 'TSModuleBlock']);
|
|
314
314
|
/** The statement a call belongs to; its marker block sits above that statement. */
|
|
315
|
+
/**
|
|
316
|
+
* The declaration a call makes through `Function.prototype.call`, `apply` or `bind`, read as if it were
|
|
317
|
+
* written plainly: `it.skip.call(null, 'title', fn)`, `it.skip.apply(null, ['title', fn])` and
|
|
318
|
+
* `it.skip.bind(null)('title', fn)` all declare the test that `it.skip('title', fn)` declares. A call that
|
|
319
|
+
* isn't read this way, such as an `apply` with a list this file can't see, comes back unchanged.
|
|
320
|
+
*/
|
|
321
|
+
function throughFunctionMethods(original) {
|
|
322
|
+
let call = original;
|
|
323
|
+
// `it.skip.bind(null).call(null, 'title', fn)` unwraps twice; two more steps cost nothing and end the loop.
|
|
324
|
+
for (let step = 0; step < 4; step += 1) {
|
|
325
|
+
const callee = unwrap(call.callee);
|
|
326
|
+
// `it.skip.call(null, ...)`: the first argument is the receiver the method is called on.
|
|
327
|
+
if (callee.type === 'MemberExpression' && memberName(callee) === 'call') {
|
|
328
|
+
call = { ...call, callee: callee.object, arguments: call.arguments.slice(1) };
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
// `it.skip.apply(null, ['title', fn])`: the arguments are the elements of an array written here.
|
|
332
|
+
if (callee.type === 'MemberExpression' && memberName(callee) === 'apply') {
|
|
333
|
+
const list = call.arguments.at(1);
|
|
334
|
+
const elements = list === undefined ? undefined : unwrap(list);
|
|
335
|
+
if (elements?.type !== 'ArrayExpression' ||
|
|
336
|
+
elements.elements.some((e) => e === null || e.type === 'SpreadElement')) {
|
|
337
|
+
return call;
|
|
338
|
+
}
|
|
339
|
+
call = { ...call, callee: callee.object, arguments: elements.elements.filter((e) => e !== null) };
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
// `it.skip.bind(null, 'title', fn)()` and `it.skip.bind(null)('title', fn)`: `bind` returns the test
|
|
343
|
+
// function with the arguments it was given already in place.
|
|
344
|
+
if (callee.type === 'CallExpression') {
|
|
345
|
+
const bind = unwrap(callee.callee);
|
|
346
|
+
if (bind.type !== 'MemberExpression' || memberName(bind) !== 'bind')
|
|
347
|
+
return call;
|
|
348
|
+
call = { ...call, callee: bind.object, arguments: [...callee.arguments.slice(1), ...call.arguments] };
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
return call;
|
|
352
|
+
}
|
|
353
|
+
return call;
|
|
354
|
+
}
|
|
315
355
|
function anchorOf(call) {
|
|
316
356
|
let node = call;
|
|
317
357
|
// A call always sits inside a statement container, so the walk stops before it runs out of parents.
|
|
@@ -1184,7 +1224,8 @@ function runAnalysis(sourceCode, options) {
|
|
|
1184
1224
|
? declare(call, declaration, bodyInfos(call.arguments, []))
|
|
1185
1225
|
: undefined;
|
|
1186
1226
|
};
|
|
1187
|
-
const visitCall = (
|
|
1227
|
+
const visitCall = (original) => {
|
|
1228
|
+
const call = throughFunctionMethods(original);
|
|
1188
1229
|
const callee = target(chainOf(call.callee, framework.factories));
|
|
1189
1230
|
if (callee === undefined)
|
|
1190
1231
|
return subtestOf(call) ?? pickedDeclaration(call) ?? { subject: runtimeCall(call) };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-test-governance",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "ESLint rules that require a ticket comment above skipped, fixme, todo and tagged Playwright, Jest, Vitest, Mocha, Cypress, WebdriverIO, node:test and Jasmine tests.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json",
|
|
53
53
|
"typecheck": "tsc -p tsconfig.json",
|
|
54
54
|
"test": "node --test \"tests/**/*.test.ts\"",
|
|
55
|
-
"test:coverage": "node
|
|
55
|
+
"test:coverage": "node scripts/coverage.mjs",
|
|
56
56
|
"test:pack": "node scripts/pack-smoke.mjs",
|
|
57
57
|
"docs": "npm run build && eslint-doc-generator",
|
|
58
58
|
"docs:check": "npm run build && eslint-doc-generator --check",
|