File size: 5,473 Bytes
cd8bd0a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import test from "node:test";
import assert from "node:assert/strict";
// @ts-expect-error — .mjs helper has no type declarations; runtime shape is known.
import { parseKnipMetrics } from "../../../scripts/check/check-dead-code.mjs";

// ---------------------------------------------------------------------------
// Fixtures — JSON sintético com formato do knip --reporter json
// O reporter emite: { issues: Array<{ file, exports?, files?, types?, ... }> }
// ---------------------------------------------------------------------------

/** Retorna um JSON vazio válido (nenhum problema encontrado). */
function makeEmptyReport() {
  return { issues: [] };
}

/** Arquivo com 2 exports mortos e 1 tipo morto. */
function makeReportWithExports() {
  return {
    issues: [
      {
        file: "src/lib/utils.ts",
        exports: [
          { name: "unusedHelper", line: 10, col: 0 },
          { name: "deadFn", line: 20, col: 0 },
        ],
        types: [
          { name: "DeadType", line: 5, col: 0 },
        ],
      },
    ],
  };
}

/** Arquivo morto (inteiro não importado em lugar nenhum). */
function makeReportWithDeadFile() {
  return {
    issues: [
      {
        file: "src/lib/orphan.ts",
        files: [{ name: "src/lib/orphan.ts" }],
      },
    ],
  };
}

/** Misto: 1 arquivo morto + 3 exports mortos em outro arquivo. */
function makeReportMixed() {
  return {
    issues: [
      {
        file: "src/lib/orphan.ts",
        files: [{ name: "src/lib/orphan.ts" }],
      },
      {
        file: "src/lib/active.ts",
        exports: [
          { name: "deadExport1", line: 1, col: 0 },
          { name: "deadExport2", line: 2, col: 0 },
        ],
        nsExports: [
          { name: "deadNsExport", line: 3, col: 0 },
        ],
      },
    ],
  };
}

/** Múltiplos tipos de dead exports: types, nsExports, nsTypes, enumMembers. */
function makeReportAllExportTypes() {
  return {
    issues: [
      {
        file: "src/lib/all-types.ts",
        exports: [{ name: "e1", line: 1, col: 0 }],
        types: [{ name: "t1", line: 2, col: 0 }],
        nsExports: [{ name: "ns1", line: 3, col: 0 }],
        nsTypes: [{ name: "nst1", line: 4, col: 0 }],
        enumMembers: [{ name: "em1", line: 5, col: 0 }],
        namespaceMembers: [{ name: "nm1", line: 6, col: 0 }],
      },
    ],
  };
}

// ---------------------------------------------------------------------------
// Testes
// ---------------------------------------------------------------------------

test("parseKnipMetrics: report vazio retorna tudo zero", () => {
  const result = parseKnipMetrics(makeEmptyReport());
  assert.deepEqual(result, { deadExports: 0, deadFiles: 0, deadTotal: 0 });
});

test("parseKnipMetrics: conta exports mortos e tipos mortos corretamente", () => {
  const result = parseKnipMetrics(makeReportWithExports());
  // 2 exports + 1 type = 3 deadExports, 0 deadFiles
  assert.equal(result.deadExports, 3);
  assert.equal(result.deadFiles, 0);
  assert.equal(result.deadTotal, 3);
});

test("parseKnipMetrics: conta arquivos mortos corretamente", () => {
  const result = parseKnipMetrics(makeReportWithDeadFile());
  assert.equal(result.deadExports, 0);
  assert.equal(result.deadFiles, 1);
  assert.equal(result.deadTotal, 1);
});

test("parseKnipMetrics: relatório misto — arquivos mortos + exports mortos", () => {
  const result = parseKnipMetrics(makeReportMixed());
  // 1 arquivo morto + (2 exports + 1 nsExport) = 4 total
  assert.equal(result.deadExports, 3);
  assert.equal(result.deadFiles, 1);
  assert.equal(result.deadTotal, 4);
});

test("parseKnipMetrics: soma todos os tipos de dead export (exports/types/nsExports/nsTypes/enumMembers/namespaceMembers)", () => {
  const result = parseKnipMetrics(makeReportAllExportTypes());
  // 1 de cada tipo × 6 tipos = 6 deadExports
  assert.equal(result.deadExports, 6);
  assert.equal(result.deadFiles, 0);
  assert.equal(result.deadTotal, 6);
});

test("parseKnipMetrics: null retorna zeros (input inválido)", () => {
  const result = parseKnipMetrics(null);
  assert.deepEqual(result, { deadExports: 0, deadFiles: 0, deadTotal: 0 });
});

test("parseKnipMetrics: input sem campo issues retorna zeros", () => {
  const result = parseKnipMetrics({ otherField: 123 });
  assert.deepEqual(result, { deadExports: 0, deadFiles: 0, deadTotal: 0 });
});

test("parseKnipMetrics: entry sem campos de export não incrementa contador", () => {
  // Arquivo que aparece na lista mas sem exports mortos e sem files
  const report = {
    issues: [
      { file: "src/lib/clean.ts" },
    ],
  };
  const result = parseKnipMetrics(report);
  assert.deepEqual(result, { deadExports: 0, deadFiles: 0, deadTotal: 0 });
});

test("parseKnipMetrics: deadTotal == deadExports + deadFiles sempre", () => {
  const report = makeReportMixed();
  const result = parseKnipMetrics(report);
  assert.equal(result.deadTotal, result.deadExports + result.deadFiles);
});

test("parseKnipMetrics: múltiplos arquivos mortos no mesmo relatório", () => {
  const report = {
    issues: [
      { file: "src/lib/orphan1.ts", files: [{ name: "src/lib/orphan1.ts" }] },
      { file: "src/lib/orphan2.ts", files: [{ name: "src/lib/orphan2.ts" }] },
      { file: "src/lib/orphan3.ts", files: [{ name: "src/lib/orphan3.ts" }] },
    ],
  };
  const result = parseKnipMetrics(report);
  assert.equal(result.deadFiles, 3);
  assert.equal(result.deadExports, 0);
  assert.equal(result.deadTotal, 3);
});