mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-12 22:13:05 +00:00
163 lines
5.1 KiB
TypeScript
163 lines
5.1 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
inventoryE2ESource,
|
|
parseVitestStdout,
|
|
renderE2EInventoryTable,
|
|
renderSlowestFilesTable,
|
|
summarizeVitestReport,
|
|
} from '../../scripts/lib/testing-audit-metrics-core.mjs'
|
|
|
|
const reportFixture = () => ({
|
|
numTotalTests: 3,
|
|
numFailedTests: 0,
|
|
testResults: [
|
|
{
|
|
name: '/abs/repo/tests/unit/b.unit.spec.ts',
|
|
endTime: 1600,
|
|
startTime: 500,
|
|
assertionResults: [
|
|
{ title: 'slow one', status: 'passed', duration: 400 },
|
|
{ title: 'fast one', status: 'passed', duration: 10 },
|
|
],
|
|
},
|
|
{
|
|
name: '/abs/repo/tests/unit/a.unit.spec.ts',
|
|
endTime: 2000,
|
|
startTime: 1000,
|
|
assertionResults: [{ title: 'only one', status: 'passed', duration: 50 }],
|
|
},
|
|
],
|
|
})
|
|
|
|
describe('summarizeVitestReport', () => {
|
|
it('totals files and tests and sorts rows by duration desc', () => {
|
|
const summary = summarizeVitestReport(reportFixture())
|
|
|
|
expect(summary.totals).toEqual({ files: 2, tests: 3, failedTests: 0, durationMs: 2100 })
|
|
expect(summary.rows.map((row) => row.file)).toEqual([
|
|
'tests/unit/b.unit.spec.ts',
|
|
'tests/unit/a.unit.spec.ts',
|
|
])
|
|
})
|
|
|
|
it('keeps the slowest assertion per file', () => {
|
|
const summary = summarizeVitestReport(reportFixture())
|
|
|
|
expect(summary.rows[0].slowestTest).toBe('slow one')
|
|
expect(summary.rows[0].slowestMs).toBe(400)
|
|
})
|
|
|
|
it('falls back to summed durations when the payload lacks timestamps', () => {
|
|
const payload = {
|
|
testResults: [
|
|
{ name: '/x/y.unit.spec.ts', assertionResults: [{ title: 't', duration: 120 }] },
|
|
],
|
|
}
|
|
|
|
expect(summarizeVitestReport(payload).rows[0].durationMs).toBe(120)
|
|
})
|
|
|
|
it('rejects payloads without testResults', () => {
|
|
expect(() => summarizeVitestReport({})).toThrow('missing testResults')
|
|
})
|
|
|
|
it('falls back to counted totals and a placeholder when fields are absent', () => {
|
|
const payload = {
|
|
testResults: [{ assertionResults: [{ title: 't' }] }],
|
|
}
|
|
const summary = summarizeVitestReport(payload)
|
|
|
|
expect(summary.totals.files).toBe(1)
|
|
expect(summary.totals.tests).toBe(1)
|
|
expect(summary.totals.failedTests).toBe(0)
|
|
expect(summary.rows[0].file).toBe('(desconhecido)')
|
|
expect(summary.rows[0].slowestTest).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('parseVitestStdout', () => {
|
|
const json = '{"numTotalTestSuites":1,"numTotalTests":3,"numFailedTests":1,"testResults":[]}'
|
|
|
|
it('parses the payload when pnpm echoes the script before and appends noise after (red suite)', () => {
|
|
const stdout = `\n> teqo@1.0.0 test:int /repo\n> cross-env … vitest run\n\n${json}\n ELIFECYCLE Command failed with exit code 1.\n`
|
|
|
|
expect(parseVitestStdout(stdout)).toEqual({
|
|
numTotalTestSuites: 1,
|
|
numTotalTests: 3,
|
|
numFailedTests: 1,
|
|
testResults: [],
|
|
})
|
|
})
|
|
|
|
it('parses the payload when test console noise with braces follows the report', () => {
|
|
const stdout = `${json}\nconsole output { "not": "json" } trailing\n`
|
|
|
|
expect(parseVitestStdout(stdout).numTotalTests).toBe(3)
|
|
})
|
|
|
|
it('parses a bare payload with surrounding whitespace', () => {
|
|
expect(parseVitestStdout(` ${json}\n`).numFailedTests).toBe(1)
|
|
})
|
|
|
|
it('rejects output without the vitest anchor', () => {
|
|
expect(() => parseVitestStdout('no json here')).toThrow(
|
|
'vitest não produziu relatório JSON no stdout',
|
|
)
|
|
})
|
|
|
|
it('rejects an anchor without a valid JSON boundary', () => {
|
|
expect(() => parseVitestStdout('{"numTotal"not json')).toThrow('relatório JSON inválido')
|
|
})
|
|
})
|
|
|
|
describe('renderSlowestFilesTable', () => {
|
|
it('renders a markdown table limited to top N rows', () => {
|
|
const table = renderSlowestFilesTable(summarizeVitestReport(reportFixture()), { top: 1 })
|
|
|
|
expect(table.split('\n')).toHaveLength(3)
|
|
expect(table).toContain('| tests/unit/b.unit.spec.ts | 2 | 1.1s | slow one (0.4s) |')
|
|
})
|
|
|
|
it('renders a placeholder for rows without a slowest test', () => {
|
|
const table = renderSlowestFilesTable(
|
|
summarizeVitestReport({ testResults: [{ name: '/x/y.unit.spec.ts', assertionResults: [] }] }),
|
|
{ top: 5 },
|
|
)
|
|
|
|
expect(table).toContain('| /x/y.unit.spec.ts | 0 | 0.0s | — |')
|
|
})
|
|
})
|
|
|
|
describe('inventoryE2ESource', () => {
|
|
it('counts describe and test blocks statically', () => {
|
|
const row = inventoryE2ESource({
|
|
file: 'tests/e2e/x.e2e.spec.ts',
|
|
content: "test('a', () => {})\n describe('d', () => { test('b', () => {}) })",
|
|
})
|
|
|
|
expect(row).toEqual({ file: 'tests/e2e/x.e2e.spec.ts', describes: 1, tests: 2 })
|
|
})
|
|
|
|
it('does not count words merely containing the keywords', () => {
|
|
const row = inventoryE2ESource({
|
|
file: 'tests/e2e/x.e2e.spec.ts',
|
|
content: '// contest( and described( are not blocks',
|
|
})
|
|
|
|
expect(row.tests).toBe(0)
|
|
expect(row.describes).toBe(0)
|
|
})
|
|
})
|
|
|
|
describe('renderE2EInventoryTable', () => {
|
|
it('marks durations as not measured overnight', () => {
|
|
const table = renderE2EInventoryTable([
|
|
{ file: 'tests/e2e/x.e2e.spec.ts', describes: 1, tests: 4 },
|
|
])
|
|
|
|
expect(table).toContain(
|
|
'| tests/e2e/x.e2e.spec.ts | 1 | 4 | não medido — execução noturna proibida |',
|
|
)
|
|
})
|
|
})
|