a gleam implementation of a CS assignment originally written in cpp
1#!/bin/bash
2
3# Test script with configurable timeout support
4# Usage: ./test.sh [timeout_seconds]
5# Example: ./test.sh 5 (uses 5 second timeout)
6# Default: 1 second timeout
7
8# Colors for output
9RED='\033[0;31m'
10GREEN='\033[0;32m'
11YELLOW='\033[1;33m'
12BLUE='\033[0;34m'
13NC='\033[0m' # No Color
14
15# Test configuration
16temp_file="lab66.output"
17program="../build/lab66"
18test_timeout=${1:-1}
19
20# Test counters
21total_tests=0
22passed_tests=0
23
24# Cleanup function
25cleanup() {
26 rm -f "$temp_file" verses.txt
27}
28
29# Error trap
30trap cleanup EXIT ERR
31
32# Function to print test results
33print_result() {
34 local test_name="$1"
35 local result="$2"
36 local message="$3"
37
38 total_tests=$((total_tests + 1))
39
40 if [ "$result" = "PASS" ]; then
41 echo -e "${GREEN}[PASS]${NC} $test_name: $message"
42 passed_tests=$((passed_tests + 1))
43 elif [ "$result" = "TIMEOUT" ]; then
44 echo -e "${YELLOW}[TIMEOUT]${NC} $test_name: $message"
45 else
46 echo -e "${RED}[FAIL]${NC} $test_name: $message"
47 fi
48}
49
50# Function to print test section header
51print_section() {
52 echo -e "\n${BLUE}=== $1 ===${NC}"
53}
54
55# Build program if needed
56if [ ! -f "$program" ]; then
57 print_section "Building Program"
58 cd .. && make lab66 > /dev/null 2>&1
59 build_result=$?
60 cd test
61 if [ $build_result -ne 0 ]; then
62 print_result "Program Build" "FAIL" "Could not build $program"
63 exit 1
64 fi
65 print_result "Program Build" "PASS" "Program built successfully"
66fi
67
68# Test 1: Program compilation/existence
69if [ ! -f "$program" ]; then
70 print_section "Test 1: Program Availability"
71 print_result "Program Existence" "FAIL" "Program $program not found"
72 exit 1
73fi
74
75# Test 2: Basic Bible Verse Lookup Test (Genesis 1:1)
76print_section "Basic Bible Verse Lookup Test"
77
78# Test with known valid verse
79basic_input="Genesis\n1\n1"
80resp=$(timeout "$test_timeout" bash -c "echo -e '$basic_input' | '$program'" 2>&1)
81exit_code=$?
82
83# Print the output
84if [ -n "$resp" ]; then
85 echo "$resp"
86else
87 echo "(No output produced)"
88fi
89echo
90
91if [ $exit_code -eq 124 ]; then
92 print_result "Basic Execution" "TIMEOUT" "Program timed out after ${test_timeout}s"
93 exit 1
94elif [ $exit_code -ne 0 ]; then
95 print_result "Basic Execution" "FAIL" "Program exited with code $exit_code"
96 exit 1
97else
98 print_result "Basic Execution" "PASS" "Program executed successfully"
99fi
100
101# Check if output contains required prompts
102if [[ "$resp" == *"Please enter the reference of the verse you would like"* ]]; then
103 print_result "Initial Prompt" "PASS" "Program shows initial prompt"
104else
105 print_result "Initial Prompt" "FAIL" "Program missing initial prompt"
106fi
107
108if [[ "$resp" == *"the book:"* ]]; then
109 print_result "Book Prompt" "PASS" "Program prompts for book"
110else
111 print_result "Book Prompt" "FAIL" "Program missing book prompt"
112fi
113
114if [[ "$resp" == *"the chapter:"* ]]; then
115 print_result "Chapter Prompt" "PASS" "Program prompts for chapter"
116else
117 print_result "Chapter Prompt" "FAIL" "Program missing chapter prompt"
118fi
119
120if [[ "$resp" == *"the verse:"* ]]; then
121 print_result "Verse Prompt" "PASS" "Program prompts for verse"
122else
123 print_result "Verse Prompt" "FAIL" "Program missing verse prompt"
124fi
125
126# Check for verse output format
127if [[ "$resp" == *"GENESIS 1:1"* ]]; then
128 print_result "Verse Format" "PASS" "Program outputs verse in correct format"
129else
130 print_result "Verse Format" "FAIL" "Program missing or incorrect verse format"
131fi
132
133# Check if verses.txt file was created
134if [ -f "verses.txt" ]; then
135 verses_content=$(cat verses.txt)
136 if [[ "$verses_content" == *"In the beginning God created the heaven and the earth"* ]]; then
137 print_result "File Output" "PASS" "verses.txt created with correct content"
138 else
139 print_result "File Output" "FAIL" "verses.txt has incorrect content"
140 fi
141else
142 print_result "File Output" "FAIL" "verses.txt file not created"
143fi
144
145# Function to run verse lookup test
146run_verse_test() {
147 local test_name="$1"
148 local book="$2"
149 local chapter="$3"
150 local verse="$4"
151 local expected_pattern="$5"
152 local should_create_file="$6"
153
154 # Clean up previous test
155 rm -f verses.txt
156
157 input="$book\n$chapter\n$verse"
158 output=$(timeout "$test_timeout" bash -c "echo -e '$input' | '$program'" 2>&1)
159 exit_code=$?
160
161 if [ $exit_code -eq 124 ]; then
162 print_result "$test_name" "TIMEOUT" "Program timed out after ${test_timeout}s"
163 return
164 elif [ $exit_code -ne 0 ]; then
165 print_result "$test_name" "FAIL" "Program crashed (exit code $exit_code)"
166 return
167 fi
168
169 # Check if expected pattern is found in output
170 pattern_found=false
171 if [[ "$output" == *"$expected_pattern"* ]]; then
172 pattern_found=true
173 fi
174
175 # For tests expecting specific output, pattern must be found
176 if [ -n "$expected_pattern" ] && [ "$pattern_found" = "false" ]; then
177 print_result "$test_name" "FAIL" "Expected '$expected_pattern' not found in output"
178 return
179 fi
180
181 # Check file creation expectations
182 if [ "$should_create_file" = "true" ]; then
183 if [ -f "verses.txt" ] && [ "$pattern_found" = "true" ]; then
184 print_result "$test_name" "PASS" "Expected output found and file created"
185 elif [ ! -f "verses.txt" ]; then
186 print_result "$test_name" "FAIL" "Expected file verses.txt not created"
187 else
188 print_result "$test_name" "FAIL" "File created but expected output not found"
189 fi
190 else
191 if [ ! -f "verses.txt" ] && [ "$pattern_found" = "true" ]; then
192 print_result "$test_name" "PASS" "Expected error output and no file created"
193 elif [ -f "verses.txt" ]; then
194 print_result "$test_name" "FAIL" "verses.txt file should not be created for error cases"
195 else
196 print_result "$test_name" "FAIL" "Expected error message not found"
197 fi
198 fi
199}
200
201# Valid Verse Tests
202print_section "Valid Verse Tests"
203
204run_verse_test "Exodus 20:3" "Exodus" "20" "3" "EXODUS 20:3" true
205run_verse_test "Psalm 23:1" "Psalm" "23" "1" "PSALM 23:1" true
206
207# Error Case Tests
208print_section "Error Case Tests"
209
210run_verse_test "Invalid Book" "Matthew" "1" "1" "Matthew does not exist in the Old Testament" false
211run_verse_test "Invalid Chapter" "Esther" "18" "3" "Chapter 18 does not exist in Esther" false
212run_verse_test "Invalid Verse" "Psalm" "117" "5" "Verse 5 does not exist in Psalm 117" false
213
214# Adversarial Testing Section
215print_section "Adversarial Tests"
216
217# Test edge cases
218run_verse_test "Empty Book Name" "" "1" "1" "Please enter the reference" false
219run_verse_test "Non-numeric Chapter" "Genesis" "abc" "1" "Please enter the reference" false
220run_verse_test "Non-numeric Verse" "Genesis" "1" "xyz" "Please enter the reference" false
221run_verse_test "Zero Chapter" "Genesis" "0" "1" "Please enter the reference" false
222run_verse_test "Zero Verse" "Genesis" "1" "0" "Please enter the reference" false
223run_verse_test "Negative Chapter" "Genesis" "-1" "1" "Please enter the reference" false
224run_verse_test "Negative Verse" "Genesis" "1" "-1" "Please enter the reference" false
225run_verse_test "Very Large Chapter" "Genesis" "999999" "1" "Please enter the reference" false
226run_verse_test "Very Large Verse" "Genesis" "1" "999999" "Please enter the reference" false
227
228# Test case sensitivity
229run_verse_test "Lowercase Book" "genesis" "1" "1" "genesis does not exist in the Old Testament" false
230run_verse_test "Mixed Case Book" "GEnesis" "1" "1" "GEnesis does not exist in the Old Testament" false
231
232# Test two-word books
233run_verse_test "First Samuel" "First Samuel" "1" "1" "FIRST SAMUEL 1:1" true
234run_verse_test "Second Kings" "Second Kings" "1" "1" "SECOND KINGS 1:1" true
235
236# Function to run file path test
237run_file_path_test() {
238 local test_name="$1"
239 local file_path="$2"
240 local expected_pattern="$3"
241 local should_succeed="$4"
242
243 # Clean up previous test
244 rm -f verses.txt
245
246 # Provide verse lookup input for file path tests
247 input="Genesis\n1\n1"
248
249 if [ -n "$file_path" ]; then
250 output=$(timeout "$test_timeout" bash -c "echo -e '$input' | '$program' '$file_path'" 2>&1)
251 else
252 output=$(timeout "$test_timeout" bash -c "echo -e '$input' | '$program'" 2>&1)
253 fi
254 exit_code=$?
255
256 if [ $exit_code -eq 124 ]; then
257 print_result "$test_name" "TIMEOUT" "Program timed out after ${test_timeout}s"
258 return
259 fi
260
261 if [ "$should_succeed" = "true" ]; then
262 if [ $exit_code -eq 0 ]; then
263 print_result "$test_name" "PASS" "Program accepted file path successfully"
264 else
265 print_result "$test_name" "FAIL" "Program failed with exit code $exit_code: $output"
266 fi
267 else
268 if [ $exit_code -ne 0 ] && [[ "$output" == *"$expected_pattern"* ]]; then
269 print_result "$test_name" "PASS" "Program correctly rejected invalid file path"
270 elif [ $exit_code -eq 0 ]; then
271 print_result "$test_name" "FAIL" "Program should have failed with invalid file path"
272 else
273 print_result "$test_name" "FAIL" "Expected error message '$expected_pattern' not found: $output"
274 fi
275 fi
276}
277
278# Test with existing file (absolute path)
279run_file_path_test "Existing File (Absolute)" "/Users/kierank/code/school/lab-6/test/OT.txt" "" true
280
281# Test with existing file (relative path)
282run_file_path_test "Existing File (Relative)" "OT.txt" "" true
283
284# Test with non-existing file
285run_file_path_test "Non-existing File" "nonexistent.txt" "failed to open file" false
286
287# Test with invalid path
288run_file_path_test "Invalid Path" "/invalid/path/file.txt" "failed to open file" false
289
290# Test with empty path
291run_file_path_test "Empty Path" "" "" true
292
293# Test summary
294print_section "Test Summary"
295echo -e "${BLUE}Tests passed: $passed_tests/$total_tests${NC}"
296
297if [ $passed_tests -eq $total_tests ]; then
298 echo -e "${GREEN}All tests passed!${NC}"
299 exit 0
300else
301 echo -e "${RED}Some tests failed!${NC}"
302 exit 1
303fi