#!/usr/bin/env bun import { TeamcityReporter } from "../tests/TeamcityReporter.ts"; const isTeamCity = process.env.TEAMCITY_VERSION !== undefined; // Strip ANSI color codes function stripAnsi(str: string): string { // eslint-disable-next-line no-control-regex return str.replace(/\x1b\[[0-9;]*m/g, ""); } async function runTests() { if (!isTeamCity) { // Just pass through if not in TeamCity const proc = Bun.spawn(["bun", "test", ...process.argv.slice(2)], { stdout: "inherit", stderr: "inherit", env: { ...process.env }, }); const exitCode = await proc.exited; process.exit(exitCode); return; } console.error("TeamCity reporter enabled"); // Run tests and capture output const proc = Bun.spawn(["bun", "test", ...process.argv.slice(2)], { stdout: "pipe", stderr: "pipe", env: { ...process.env }, }); const suiteStack: string[] = []; // Read stdout as text const output = await new Response(proc.stdout).text(); const lines = output.split("\n"); for (const rawLine of lines) { // Pass through original output (with colors) console.log(rawLine); // Parse without colors const line = stripAnsi(rawLine).trim(); // Check for test suite/describe blocks (files ending with .test.ts) if (line.match(/tests\/.+\.test\.ts:$/)) { const fileName = line .replace(":", "") .replace("tests/", "") .replace(".test.ts", ""); // End previous suite if exists while (suiteStack.length > 0) { const oldSuite = suiteStack.pop(); if (oldSuite) { TeamcityReporter.reportSuiteEnd(oldSuite); } } suiteStack.push(fileName); TeamcityReporter.reportSuiteStart(fileName); } // Check for test pass: (pass) HashMap > constructor > should create an empty map... const passMatch = line.match(/^\(pass\)\s+(.+?)(?:\s+\[[\d.]+m?s\])?$/); if (passMatch) { const testName = passMatch[1].trim(); TeamcityReporter.reportTestStart(testName); TeamcityReporter.reportTestEnd(testName); } // Check for test fail: (fail) HashMap > constructor > should... const failMatch = line.match(/^\(fail\)\s+(.+?)(?:\s+\[[\d.]+m?s\])?$/); if (failMatch) { const testName = failMatch[1].trim(); TeamcityReporter.reportTestStart(testName); TeamcityReporter.reportTestFailed(testName, "Test failed", line, { comparisonFailure: false, expected: "", actual: "", }); TeamcityReporter.reportTestEnd(testName); } } // Capture stderr const errorOutput = await new Response(proc.stderr).text(); if (errorOutput) { console.error(errorOutput); } const exitCode = await proc.exited; // Close all open suites while (suiteStack.length > 0) { const suite = suiteStack.pop(); if (suite) { TeamcityReporter.reportSuiteEnd(suite); } } console.error("TeamCity reporter finished"); process.exit(exitCode); } runTests().catch((error) => { console.error("Error running tests:", error); process.exit(1); });