@zgeoff/format-codemod 0.0.7 → 0.0.8

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/README.md CHANGED
@@ -38,8 +38,11 @@ between two kinds takes a blank line:
38
38
  - `const`/`let`/`var` declarations
39
39
  - `using`/`await using` declarations
40
40
  - bare calls and method calls — two distinct kinds, split by the first call in reading order:
41
- `expect(x).toBe(y)` opens with a bare function, `fs.writeFileSync(…)` opens with a member, and a
41
+ `use(x).report()` opens with a bare function, `fs.writeFileSync(…)` opens with a member, and a
42
42
  member call chained onto a bare call's result is still a bare call
43
+ - `expect` assertions — a statement whose first call in reading order is `expect` or an `expect.*`
44
+ helper (`expect(x).toBe(y)`, `expect.assertions(1)`) is its own kind, so a run of assertions stays
45
+ glued while the boundary with any acting statement is padded
43
46
  - assignments and increments
44
47
 
45
48
  Two axes overlay the kinds and pad their own boundaries:
package/dist/cli.js CHANGED
@@ -302,10 +302,19 @@ function getStatementKind(node) {
302
302
  return "declaration";
303
303
  }
304
304
  if (isExpressionStatementOf(node, CALL_TYPES)) {
305
- return pickCallKind(node);
305
+ return isExpectHeaded(node) ? "expect" : pickCallKind(node);
306
306
  }
307
307
  return isExpressionStatementOf(node, MUTATION_TYPES) ? "mutation" : null;
308
308
  }
309
+ function isExpectHeaded(node) {
310
+ const expression = node["expression"];
311
+ const callee = isASTNode(expression) ? findDeepestCallee(expression) : null;
312
+ if (callee === null) {
313
+ return false;
314
+ }
315
+ const head = collectHeadChain(callee).at(-1);
316
+ return head?.type === "Identifier" && head["name"] === "expect";
317
+ }
309
318
  function pickCallKind(node) {
310
319
  const expression = node["expression"];
311
320
  const callee = isASTNode(expression) ? findDeepestCallee(expression) : null;
package/dist/index.js CHANGED
@@ -135,10 +135,19 @@ function getStatementKind(node) {
135
135
  return "declaration";
136
136
  }
137
137
  if (isExpressionStatementOf(node, CALL_TYPES)) {
138
- return pickCallKind(node);
138
+ return isExpectHeaded(node) ? "expect" : pickCallKind(node);
139
139
  }
140
140
  return isExpressionStatementOf(node, MUTATION_TYPES) ? "mutation" : null;
141
141
  }
142
+ function isExpectHeaded(node) {
143
+ const expression = node["expression"];
144
+ const callee = isASTNode(expression) ? findDeepestCallee(expression) : null;
145
+ if (callee === null) {
146
+ return false;
147
+ }
148
+ const head = collectHeadChain(callee).at(-1);
149
+ return head?.type === "Identifier" && head["name"] === "expect";
150
+ }
142
151
  function pickCallKind(node) {
143
152
  const expression = node["expression"];
144
153
  const callee = isASTNode(expression) ? findDeepestCallee(expression) : null;
@@ -7,7 +7,8 @@ import type { ASTNode } from '../types.ts';
7
7
  * declaration, on both sides of a control-flow block — its closing brace
8
8
  * ends a visual unit just like its opening keyword starts one —
9
9
  * and at the boundary between statement kinds: bare call vs method call vs
10
- * mutation, instantiation vs anything else, and awaited vs non-awaited. Any
10
+ * expect assertion vs mutation, instantiation vs anything else, and awaited
11
+ * vs non-awaited. Any
11
12
  * match means exactly one blank line; a pair matching no rule sits flush.
12
13
  */
13
14
  export declare function needsBlankLine(container: ASTNode, prev: ASTNode, next: ASTNode): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zgeoff/format-codemod",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Enforce blank-line padding conventions in TypeScript via a fast text-splice codemod",
5
5
  "license": "MIT",
6
6
  "repository": {