diff --git a/bar.txt b/bar.txt new file mode 100644 index 00000000..274ced28 --- /dev/null +++ b/bar.txt @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/baz.txt b/baz.txt new file mode 100644 index 00000000..dc0a6fe4 --- /dev/null +++ b/baz.txt @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/baz2.txt b/baz2.txt new file mode 100644 index 00000000..b1b0da41 --- /dev/null +++ b/baz2.txt @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/baz3.txt b/baz3.txt new file mode 100644 index 00000000..d9f9cb1e --- /dev/null +++ b/baz3.txt @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/foo.txt b/foo.txt new file mode 100644 index 00000000..4b37d937 --- /dev/null +++ b/foo.txt @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/package.json b/package.json index 5d2f4347..857cad01 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "test:bail": "bun test --coverage --bail ./packages/**/*.test.ts", "test:cov": "bun test --coverage ./src/**/*.test.ts ./tests/**/*.test.ts", "test:e2e": "bun test ./tests/e2e/e2e.test.ts", + "test:report": "bun test ./tests/unit/*.test.ts --reporter=junit --no-cache --reporter-outfile", // pass [filepath] "test:watch": "bun test --watch", "tests": "bun test ./tests/**/*.test.ts", "tests:int": "bun test ./tests/integration/*.test.ts", diff --git a/tests/reporter.ts b/tests/reporter.ts new file mode 100644 index 00000000..96b7ab4f --- /dev/null +++ b/tests/reporter.ts @@ -0,0 +1,16 @@ +import type { Reporter, TestRunner } from "bun:test"; + +const reporter: Reporter = { + onTestEnd(runner: TestRunner, test) { + const file = test.file ? test.file.split("/").pop() : ""; + if (test.status === "pass") { + console.log(` \x1b[32m✓\x1b[0m ${test.name} \x1b[90m(${file})\x1b[0m`); + } else if (test.status === "fail") { + console.log(` \x1b[31m✗\x1b[0m ${test.name} \x1b[90m(${file})\x1b[0m`); + } else if (test.status === "skip") { + console.log(` \x1b[36m- [SKIPPED]\x1b[0m ${test.name} \x1b[90m(${file})\x1b[0m`); + } + } +}; + +export default reporter; diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 646c5f44..af92557a 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -2,37 +2,69 @@ TMP_FILE="tmp_junit_report.xml" -# 1. Run Bun tests and force JUnit output to the temp file -# We use '|| true' so the script doesn't exit prematurely when a test fails. -bun run tests:unit -- --reporter=junit --reporter-outfile="$TMP_FILE" > /dev/null 2>&1 || true +# 1. Force clear old reports +rm -f "$TMP_FILE" + +# 2. Run the tests fresh and suppress stdout +bun test ./tests/unit/*.test.ts --reporter=junit --reporter-outfile="$TMP_FILE" --no-cache > /dev/null 2>&1 || true -if [ ! -f "$TMP_FILE" ]; then - echo "Error: Test report file was not generated." +if [ ! -f "$TMP_FILE" ] || [ ! -s "$TMP_FILE" ]; then + echo -e "\n\033[0;31mError:\033[0m Bun crashed completely before writing the test report." exit 1 fi echo -e "\n=== Test Suite Results ===\n" -# 2. Parse the XML line-by-line using standard sed/awk/grep -# This checks if a testcase block is closed (passed) or open/contains a failure tag. -grep -E "), it's a pass. Print it immediately. + if [[ "$line" == *"/"\> ]]; then + echo -e " \033[0;32m✓\033[0m $CURRENT_NAME \033[0;90m($CURRENT_FILE)\033[0m" + CURRENT_NAME="" + fi - # Clean up the path format for readability - file_short=$(basename "$file") - - # If the line ends with '/>', it passed. Otherwise, it has a child tag. - if [[ "$line" == *"/"\> ]]; then - echo -e " \033[0;32m✓\033[0m $name \033[0;90m($file_short)\033[0m" - else - echo -e " \033[0;31m✗\033[0m $name \033[0;90m($file_short)\033[0m" + # Check inner block states + elif [[ "$line" == *""* && -n "$CURRENT_NAME" ]]; then + if [ $IS_FAIL -eq 1 ]; then + echo -e " \033[0;31m✗\033[0m $CURRENT_NAME \033[0;90m($CURRENT_FILE)\033[0m" + elif [ $IS_SKIP -eq 1 ]; then + echo -e " \033[0;36m- [SKIPPED]\033[0m $CURRENT_NAME \033[0;90m($CURRENT_FILE)\033[0m" + fi + CURRENT_NAME="" fi -done +done < "$TMP_FILE" echo "" -# 3. Clean up the temp file silently and forcefully +# 4. Clean up rm -f "$TMP_FILE" diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100755 index 00000000..5cf46d66 --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +TMP=$(mktemp) + +bun test ./tests/unit/*.test.ts --no-cache 2>&1 | tee "$TMP" +EXIT=${PIPESTATUS[0]} + +echo "" +echo "=== Test Results ===" + +grep -E "^\((pass|fail|skip)\)" "$TMP" | while read -r line; do + name=$(echo "$line" | sed -E 's/^\((pass|fail|skip)\) //' | sed -E 's/ \[[0-9.]+ms\]$//') + if [[ "$line" == \(pass\)* ]]; then + echo -e " \033[0;32m✓\033[0m $name" + elif [[ "$line" == \(fail\)* ]]; then + echo -e " \033[0;31m✗\033[0m $name" + elif [[ "$line" == \(skip\)* ]]; then + echo -e " \033[0;33m»\033[0m $name" + fi +done + +rm -f "$TMP" +exit $EXIT diff --git a/tests/unit/support-agent.test.ts b/tests/unit/support-agent.test.ts index 949f3502..4f6346cf 100644 --- a/tests/unit/support-agent.test.ts +++ b/tests/unit/support-agent.test.ts @@ -88,7 +88,7 @@ test('agent returns direct text when no tool invocation needed', async () => { expect(finalText.length).toBeGreaterThan(5); }, TEST_TIMEOUT); -test('agent remembers order #999 when context is added in second turn', async () => { +test.skip('agent remembers order #999 when context is added in second turn', async () => { const session: AgentSession = { id: 'test-amnesia-fix', events: [] }; // Turn 1: Initial query