Spaces:
Runtime error
Runtime error
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);
});
|