Skip to content

Commit 1cb5088

Browse files
committed
Refactor test suite to use more robust TAP-compliant test runner
- Modernize test scripts to track passed/failed tests independently - Remove reliance on external assert functions - Improve error handling and test result tracking - Make test files more executable and self-contained - Enhance test output with better diagnostics and TAP formatting
1 parent a90dc78 commit 1cb5088

File tree

5 files changed

+369
-124
lines changed

5 files changed

+369
-124
lines changed

test/test_runner.sh

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#!/bin/bash
22

3-
# test_runner.sh - Main test runner for context script
4-
5-
# Exit on error
6-
set -e
3+
# test_runner.sh - Main test runner for context script (TAP-compliant)
74

85
# Get the directory where the test_runner.sh script is located
96
TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -12,32 +9,58 @@ PROJECT_ROOT="$(cd "$TEST_DIR/.." && pwd)"
129
# Source test utilities
1310
source "$TEST_DIR/test_utils.sh"
1411

15-
# Print header
16-
echo "===================================="
17-
echo "Running tests for context script"
18-
echo "===================================="
12+
# Initialize counters
13+
TESTS_PASSED=0
14+
TESTS_FAILED=0
15+
TEST_NUMBER=0
16+
17+
# Print TAP header
18+
echo "TAP version 13"
19+
20+
# Find all test files
21+
test_files=("$TEST_DIR"/unit/test_*.sh)
22+
total_test_files=${#test_files[@]}
23+
echo "1..$total_test_files"
24+
25+
# Create or clear the test results file
26+
echo "PASSED:0" > "$TEST_DIR/test_results.txt"
27+
echo "FAILED:0" >> "$TEST_DIR/test_results.txt"
28+
29+
# Make test utilities executable
30+
chmod +x "$TEST_DIR/test_utils.sh"
31+
32+
# Make test scripts executable
33+
for test_file in "${test_files[@]}"; do
34+
chmod +x "$test_file"
35+
done
1936

2037
# Run all test files
21-
for test_file in "$TEST_DIR"/unit/test_*.sh; do
38+
for test_file in "${test_files[@]}"; do
2239
if [ -f "$test_file" ]; then
23-
echo ""
24-
echo "Running tests in $(basename "$test_file")"
25-
echo "------------------------------------"
26-
bash "$test_file"
40+
TEST_NUMBER=$((TEST_NUMBER + 1))
41+
test_name=$(basename "$test_file" .sh | sed 's/^test_//')
2742

28-
# Capture exit status
43+
# Run the test and capture its output
44+
test_output=$("$test_file" 2>&1)
2945
test_status=$?
30-
if [ $test_status -ne 0 ]; then
31-
echo "Test file $(basename "$test_file") failed with status $test_status"
46+
47+
if [ $test_status -eq 0 ]; then
48+
echo "ok $TEST_NUMBER - $test_name"
49+
TESTS_PASSED=$((TESTS_PASSED + 1))
50+
else
51+
echo "not ok $TEST_NUMBER - $test_name"
52+
echo "# Test output:"
53+
echo "$test_output" | sed 's/^/# /'
54+
TESTS_FAILED=$((TESTS_FAILED + 1))
3255
fi
3356
fi
3457
done
3558

3659
# Print summary
37-
echo ""
38-
echo "===================================="
39-
echo "Test Results: $TESTS_PASSED passed, $TESTS_FAILED failed"
40-
echo "===================================="
60+
total_tests=$((TESTS_PASSED + TESTS_FAILED))
61+
echo "# Tests: $total_tests"
62+
echo "# Pass: $TESTS_PASSED"
63+
echo "# Fail: $TESTS_FAILED"
4164

4265
# Return non-zero exit code if any tests failed
4366
if [ $TESTS_FAILED -gt 0 ]; then

test/test_utils.sh

100644100755
Lines changed: 109 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,155 @@
11
#!/bin/bash
22

3-
# test_utils.sh - Utilities for testing the context script
3+
# test_utils.sh - Utilities for testing the context script (TAP-compliant)
4+
5+
# Get the directory where the test_utils.sh script is located
6+
TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
47

58
# Initialize test counters
69
TESTS_PASSED=0
710
TESTS_FAILED=0
11+
TEST_NUMBER_INTERNAL=0
12+
13+
# Function to update test result counts
14+
update_test_results() {
15+
echo "PASSED:$TESTS_PASSED" > "$TEST_DIR/test_results.txt"
16+
echo "FAILED:$TESTS_FAILED" >> "$TEST_DIR/test_results.txt"
17+
}
818

9-
# Function to run a test
10-
# Usage: run_test "test_name" "command_to_run"
19+
# Function to run a test and output TAP-compliant results
20+
# Usage: run_test "test_description" "command_to_run"
1121
run_test() {
12-
local test_name=$1
13-
local command=$2
22+
local description="$1"
23+
local command="$2"
24+
local skip_reason="${3:-}"
25+
26+
TEST_NUMBER_INTERNAL=$((TEST_NUMBER_INTERNAL + 1))
27+
28+
# Skip test if reason provided
29+
if [ -n "$skip_reason" ]; then
30+
echo "ok $TEST_NUMBER_INTERNAL # SKIP $description - $skip_reason"
31+
return 0
32+
fi
1433

15-
echo -n "- Testing $test_name... "
34+
# Create temporary files for command output and error
35+
local output_file=$(mktemp)
36+
local error_file=$(mktemp)
1637

17-
# Run the command and capture output and exit status
18-
output=$(eval "$command" 2>&1)
19-
status=$?
38+
# Run the command
39+
eval "$command" > "$output_file" 2> "$error_file"
40+
local status=$?
2041

42+
local output=$(cat "$output_file")
43+
local error=$(cat "$error_file")
44+
45+
# Handle the result
2146
if [ $status -eq 0 ]; then
22-
echo "PASSED"
47+
echo "ok $TEST_NUMBER_INTERNAL - $description"
2348
TESTS_PASSED=$((TESTS_PASSED + 1))
2449
else
25-
echo "FAILED"
26-
echo " Command: $command"
27-
echo " Output: $output"
50+
echo "not ok $TEST_NUMBER_INTERNAL - $description"
51+
echo "# Command: $command"
52+
53+
if [ -n "$output" ]; then
54+
echo "# Output:"
55+
echo "$output" | sed 's/^/# /'
56+
fi
57+
58+
if [ -n "$error" ]; then
59+
echo "# Error:"
60+
echo "$error" | sed 's/^/# /'
61+
fi
62+
2863
TESTS_FAILED=$((TESTS_FAILED + 1))
2964
fi
3065

66+
# Clean up temporary files
67+
rm -f "$output_file" "$error_file"
68+
update_test_results
69+
3170
return $status
3271
}
3372

3473
# Function to create a temporary directory for tests
3574
# Usage: create_test_dir
3675
create_test_dir() {
37-
mktemp -d -t context-test-XXXXXX
76+
local tmp_dir=$(mktemp -d -t "context-test-XXXXXX")
77+
echo "$tmp_dir"
3878
}
3979

4080
# Function to clean up a temporary directory
4181
# Usage: cleanup_test_dir "$test_dir"
4282
cleanup_test_dir() {
43-
local test_dir=$1
83+
local test_dir="$1"
4484
if [ -d "$test_dir" ]; then
4585
rm -rf "$test_dir"
4686
fi
4787
}
4888

49-
# Function to assert that a string contains another string
50-
# Usage: assert_contains "haystack" "needle"
51-
assert_contains() {
52-
local haystack=$1
53-
local needle=$2
54-
55-
if [[ "$haystack" == *"$needle"* ]]; then
56-
return 0
57-
else
58-
return 1
59-
fi
89+
# Function to print a message in TAP diagnostic format
90+
# Usage: tap_diag "message"
91+
tap_diag() {
92+
echo "# $1"
6093
}
6194

62-
# Function to assert that a string does not contain another string
63-
# Usage: assert_not_contains "haystack" "needle"
64-
assert_not_contains() {
65-
local haystack=$1
66-
local needle=$2
95+
# Function to assert that a condition is true
96+
# Usage: assert "test expr" "description"
97+
assert() {
98+
local condition="$1"
99+
local description="$2"
67100

68-
if [[ "$haystack" != *"$needle"* ]]; then
69-
return 0
101+
TEST_NUMBER_INTERNAL=$((TEST_NUMBER_INTERNAL + 1))
102+
103+
if eval "$condition"; then
104+
echo "ok $TEST_NUMBER_INTERNAL - $description"
105+
TESTS_PASSED=$((TESTS_PASSED + 1))
70106
else
71-
return 1
107+
echo "not ok $TEST_NUMBER_INTERNAL - $description"
108+
echo "# Failed condition: $condition"
109+
TESTS_FAILED=$((TESTS_FAILED + 1))
72110
fi
111+
112+
update_test_results
73113
}
74114

75115
# Function to create a test file with a specific size
76116
# Usage: create_test_file "$dir/file.txt" 1024 # Creates a 1KB file
77117
create_test_file() {
78-
local file_path=$1
79-
local size_bytes=$2
118+
local file_path="$1"
119+
local size_bytes="$2"
120+
121+
# Create a file with human-readable content at the start
122+
echo "This is a test file created for context script testing." > "$file_path"
123+
echo "It contains exactly $size_bytes bytes of data." >> "$file_path"
80124

81-
dd if=/dev/zero of="$file_path" bs=1 count="$size_bytes" status=none 2>/dev/null
125+
# Calculate how many bytes we need to add to reach the desired size
126+
local current_size=$(wc -c < "$file_path")
127+
local remaining_bytes=$((size_bytes - current_size))
128+
129+
if [ $remaining_bytes -gt 0 ]; then
130+
# Add remaining bytes to reach desired size
131+
dd if=/dev/zero bs=1 count=$remaining_bytes >> "$file_path" 2>/dev/null
132+
fi
133+
134+
# Verify the file is the right size
135+
local final_size=$(wc -c < "$file_path")
136+
if [ $final_size -ne $size_bytes ]; then
137+
echo "# Warning: Created file size ($final_size) doesn't match requested size ($size_bytes)" >&2
138+
fi
139+
}
140+
141+
# Print TAP plan for individual test files
142+
plan() {
143+
local count="$1"
144+
echo "1..$count"
82145
}
83146

84-
# Export variables to be available in subprocesses
85-
export TESTS_PASSED
86-
export TESTS_FAILED
147+
# Export functions and variables for use in subshells
148+
export -f run_test
149+
export -f create_test_dir
150+
export -f cleanup_test_dir
151+
export -f tap_diag
152+
export -f assert
153+
export -f create_test_file
154+
export -f plan
155+
export -f update_test_results

0 commit comments

Comments
 (0)