@pythonidaer/complexity-report 1.0.6 → 1.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/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.8] - 2026-02-08
9
+
10
+ ### Fixed
11
+ - **Function Complexity Breakdown:** Switch `default` branch now appears in its own "default" column instead of under "case".
12
+ - **Function Complexity Breakdown:** `else if` statements now counted in the "else if" column instead of "if".
13
+ - **Function Complexity Breakdown:** `do { } while` loops now counted in the "do...while" column instead of "while".
14
+
15
+ ## [1.0.7] - 2026-02-08
16
+
17
+ - (Published; no additional changes in this changelog.)
18
+
8
19
  ## [1.0.6] - 2026-02-08
9
20
 
10
21
  ### Fixed
package/README.md CHANGED
@@ -30,7 +30,7 @@ On **Angular 21** or other projects using **ESLint 10**, install may fail with p
30
30
 
31
31
  The package bundles ESLint and uses your project's config to run complexity analysis. You do not need to install ESLint or TypeScript in your project for the tool to work.
32
32
 
33
- **Performance:** The tool runs ESLint with `lintFiles(['.'])` and applies built-in ignores for `complexity/**`, `dist/**`, `build/**`, `.angular/**`, `**/coverage/**`, and `node_modules/**` so the run does not hang on report output or build dirs. Your ESLint config's own ignores also apply; add any other large or generated dirs there if needed.
33
+ **Performance:** The tool runs ESLint with `lintFiles(['.'])` and applies built-in ignores for `complexity/**`, `dist/**`, `build/**`, `.angular/**`, `**/coverage/**`, and `node_modules/**` so the run does not hang on report output or build dirs. You do not need to add these to your ESLint config—the tool ignores them automatically. Your config's own ignores also apply; add any other large or generated dirs there if needed.
34
34
 
35
35
  ## Quick Start
36
36
 
@@ -108,7 +108,7 @@ console.log(`Total functions: ${result.stats.allFunctionsCount}`);
108
108
 
109
109
  ### Report seems to hang on "Running ESLint to collect complexity..."
110
110
 
111
- The tool already ignores `complexity/**`, `dist/**`, `build/**`, `.angular/**`, `**/coverage/**`, and `node_modules/**`. If it still hangs, add other large or generated directories to your ESLint config's `ignore` (e.g. `.next/**`, `out/**`, `*.min.js`).
111
+ The tool ignores `complexity/**`, `dist/**`, `build/**`, `.angular/**`, `**/coverage/**`, and `node_modules/**` by default, so you don't need those in your ESLint config. If it still hangs, add other large or generated directories to your ESLint config's `ignore` (e.g. `.next/**`, `out/**`, `*.min.js`).
112
112
 
113
113
  ### npm install fails with peer dependency errors (e.g. Angular 21, ESLint 10)
114
114
 
@@ -25,6 +25,7 @@ export function calculateComplexityBreakdown(
25
25
  'do...while': 0,
26
26
  'switch': 0,
27
27
  'case': 0,
28
+ 'default': 0,
28
29
  'catch': 0,
29
30
  'ternary': 0,
30
31
  '&&': 0,
@@ -11,20 +11,22 @@ const CONTROL_FLOW_TYPE_MAP = {
11
11
  ForInStatement: 'for',
12
12
  ForOfStatement: 'for',
13
13
  WhileStatement: 'while',
14
- DoWhileStatement: 'while',
14
+ DoWhileStatement: 'do...while',
15
15
  SwitchStatement: 'switch',
16
16
  CatchClause: 'catch',
17
17
  };
18
18
 
19
19
  /**
20
20
  * Gets decision point type for control flow statements
21
+ * @param {Object} node - AST node (used for SwitchCase to distinguish default)
21
22
  * @param {string} nodeType - Node type
22
23
  * @param {string} variant - 'classic' or 'modified'
23
24
  * @returns {string|null} Decision point type or null
24
25
  */
25
- export function getControlFlowDecisionType(nodeType, variant) {
26
+ export function getControlFlowDecisionType(node, nodeType, variant) {
26
27
  if (nodeType === 'SwitchCase') {
27
- return variant === 'modified' ? null : 'case';
28
+ if (variant === 'modified') return null;
29
+ return node && node.test === null ? 'default' : 'case';
28
30
  }
29
31
  return CONTROL_FLOW_TYPE_MAP[nodeType] ?? null;
30
32
  }
@@ -76,8 +78,16 @@ export function getDecisionPointType(node, parentMap, ast, variant) {
76
78
 
77
79
  const nodeType = node.type;
78
80
 
79
- const controlFlowType = getControlFlowDecisionType(nodeType, variant);
80
- if (controlFlowType) return controlFlowType;
81
+ let controlFlowType = getControlFlowDecisionType(node, nodeType, variant);
82
+ if (controlFlowType) {
83
+ if (controlFlowType === 'if' && parentMap) {
84
+ const parent = parentMap.get(node);
85
+ if (parent?.type === 'IfStatement' && parent.alternate === node) {
86
+ return 'else if';
87
+ }
88
+ }
89
+ return controlFlowType;
90
+ }
81
91
 
82
92
  const expressionType = getExpressionDecisionType(node, nodeType);
83
93
  if (expressionType) return expressionType;
@@ -36,7 +36,7 @@ export function getBreakdownColumnStructure(variant = 'classic') {
36
36
  { key: 'for...in', label: 'for...in' },
37
37
  { key: 'while', label: 'while' },
38
38
  { key: 'do...while', label: 'do...while' },
39
- ...(variant === 'modified' ? [{ key: 'switch', label: 'switch' }] : [{ key: 'case', label: 'case' }]),
39
+ ...(variant === 'modified' ? [{ key: 'switch', label: 'switch' }] : [{ key: 'case', label: 'case' }, { key: 'default', label: 'default' }]),
40
40
  { key: 'catch', label: 'catch' },
41
41
  ];
42
42
  return {
@@ -137,6 +137,7 @@ export function calculateDecisionPointTotalsFromBreakdowns(
137
137
  'do...while',
138
138
  'switch',
139
139
  'case',
140
+ 'default',
140
141
  'catch',
141
142
  ];
142
143
  const expressionTypes = ['ternary', '&&', '||', '??', '?.'];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pythonidaer/complexity-report",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "AST-based cyclomatic complexity analyzer with interactive HTML reports and detailed function breakdowns",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/report/index.js CHANGED
@@ -49,6 +49,7 @@ async function calculateDecisionPointTotals(
49
49
  'do...while',
50
50
  'switch',
51
51
  'case',
52
+ 'default',
52
53
  'catch',
53
54
  ];
54
55
  const expressionTypes = ['ternary', '&&', '||', '??', '?.'];