Files
2026-07-13 13:39:12 +08:00

165 lines
5.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
});