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"
18output_file="../build/verses.txt"
19test_timeout=${1:-1}
20
21# Test counters
22total_tests=0
23passed_tests=0
24
25# Cleanup function
26cleanup() {
27 rm -f "$temp_file" "$output_file"
28}
29
30# Error trap
31trap cleanup EXIT ERR
32
33# Function to print test results
34print_result() {
35 local test_name="$1"
36 local result="$2"
37 local message="$3"
38
39 total_tests=$((total_tests + 1))
40
41 if [ "$result" = "PASS" ]; then
42 echo -e "${GREEN}[PASS]${NC} $test_name: $message"
43 passed_tests=$((passed_tests + 1))
44 elif [ "$result" = "TIMEOUT" ]; then
45 echo -e "${YELLOW}[TIMEOUT]${NC} $test_name: $message"
46 else
47 echo -e "${RED}[FAIL]${NC} $test_name: $message"
48 fi
49}
50
51# Function to print test section header
52print_section() {
53 echo -e "\n${BLUE}=== $1 ===${NC}"
54}
55
56# Build program if needed
57if [ ! -f "$program" ]; then
58 print_section "Building Program"
59 cd .. && make lab66 > /dev/null 2>&1
60 build_result=$?
61 cd test
62 if [ $build_result -ne 0 ]; then
63 print_result "Program Build" "FAIL" "Could not build $program"
64 exit 1
65 fi
66 print_result "Program Build" "PASS" "Program built successfully"
67fi
68
69# Test 1: Program compilation/existence
70if [ ! -f "$program" ]; then
71 print_section "Test 1: Program Availability"
72 print_result "Program Existence" "FAIL" "Program $program not found"
73 exit 1
74fi
75
76# Test 2: Basic Bible Verse Lookup Test (Genesis 1:1)
77print_section "Basic Bible Verse Lookup Test"
78
79# Test with known valid verse
80basic_input="Genesis\n1\n1"
81resp=$(timeout "$test_timeout" bash -c "echo -e '$basic_input' | '$program' OT.txt '$output_file'" 2>&1)
82exit_code=$?
83
84# Print the output
85if [ -n "$resp" ]; then
86 echo "$resp"
87else
88 echo "(No output produced)"
89fi
90echo
91
92if [ $exit_code -eq 124 ]; then
93 print_result "Basic Execution" "TIMEOUT" "Program timed out after ${test_timeout}s"
94 exit 1
95elif [ $exit_code -ne 0 ]; then
96 print_result "Basic Execution" "FAIL" "Program exited with code $exit_code"
97 exit 1
98else
99 print_result "Basic Execution" "PASS" "Program executed successfully"
100fi
101
102# Check if output contains required prompts
103if [[ "$resp" == *"Please enter the reference of the verse you would like"* ]]; then
104 print_result "Initial Prompt" "PASS" "Program shows initial prompt"
105else
106 print_result "Initial Prompt" "FAIL" "Program missing initial prompt"
107fi
108
109if [[ "$resp" == *"the book:"* ]]; then
110 print_result "Book Prompt" "PASS" "Program prompts for book"
111else
112 print_result "Book Prompt" "FAIL" "Program missing book prompt"
113fi
114
115if [[ "$resp" == *"the chapter:"* ]]; then
116 print_result "Chapter Prompt" "PASS" "Program prompts for chapter"
117else
118 print_result "Chapter Prompt" "FAIL" "Program missing chapter prompt"
119fi
120
121if [[ "$resp" == *"the verse:"* ]]; then
122 print_result "Verse Prompt" "PASS" "Program prompts for verse"
123else
124 print_result "Verse Prompt" "FAIL" "Program missing verse prompt"
125fi
126
127# Check for verse output format
128if [[ "$resp" == *"1 In the beginning God created the heaven and the earth"* ]]; then
129 print_result "Verse Format" "PASS" "Program outputs verse in correct format"
130else
131 print_result "Verse Format" "FAIL" "Program missing or incorrect verse format"
132fi
133
134# Check if test/verses.txt file was created
135if [ -f "$output_file" ]; then
136 verses_content=$(cat "$output_file")
137 if [[ "$verses_content" == *"In the beginning God created the heaven and the earth"* ]]; then
138 print_result "File Output" "PASS" "verses.txt created with correct content in build directory"
139 else
140 print_result "File Output" "FAIL" "verses.txt has incorrect content"
141 fi
142else
143 print_result "File Output" "FAIL" "verses.txt file not created in build directory"
144fi
145
146# Function to run verse lookup test
147run_verse_test() {
148 local test_name="$1"
149 local book="$2"
150 local chapter="$3"
151 local verse="$4"
152 local expected_pattern="$5"
153 local should_create_file="$6"
154
155 # Clean up previous test
156 rm -f "$output_file"
157
158 input="$book\n$chapter\n$verse"
159 output=$(timeout "$test_timeout" bash -c "echo -e '$input' | '$program' OT.txt '$output_file'" 2>&1)
160 exit_code=$?
161
162 if [ $exit_code -eq 124 ]; then
163 print_result "$test_name" "TIMEOUT" "Program timed out after ${test_timeout}s"
164 return
165 elif [ $exit_code -ne 0 ]; then
166 print_result "$test_name" "FAIL" "Program crashed (exit code $exit_code)"
167 return
168 fi
169
170 # Check if expected pattern is found in output
171 pattern_found=false
172 if [[ "$output" == *"$expected_pattern"* ]]; then
173 pattern_found=true
174 fi
175
176 # For tests expecting specific output, pattern must be found
177 if [ -n "$expected_pattern" ] && [ "$pattern_found" = "false" ]; then
178 print_result "$test_name" "FAIL" "Expected '$expected_pattern' not found in output"
179 return
180 fi
181
182 # Check file creation expectations
183 if [ "$should_create_file" = "true" ]; then
184 if [ -f "$output_file" ] && [ "$pattern_found" = "true" ]; then
185 print_result "$test_name" "PASS" "Expected output found and file created"
186 elif [ ! -f "$output_file" ]; then
187 print_result "$test_name" "FAIL" "Expected file verses.txt not created in build directory"
188 else
189 print_result "$test_name" "FAIL" "File created but expected output not found"
190 fi
191 else
192 if [ ! -f "$output_file" ] && [ "$pattern_found" = "true" ]; then
193 print_result "$test_name" "PASS" "Expected error output and no file created"
194 elif [ -f "$output_file" ]; then
195 print_result "$test_name" "FAIL" "verses.txt file should not be created for error cases"
196 else
197 print_result "$test_name" "FAIL" "Expected error message not found"
198 fi
199 fi
200}
201
202# Valid Verse Tests
203print_section "Valid Verse Tests"
204
205run_verse_test "Exodus 20:3" "Exodus" "20" "3" "3 Thou shalt have no other gods before me" true
206run_verse_test "Psalm 23:1" "Psalm" "23" "1" "1 The LORD [is] my shepherd; I shall not want." true
207
208# Error Case Tests
209print_section "Error Case Tests"
210
211run_verse_test "Invalid Book" "Matthew" "1" "1" "Matthew does not exist in the Old Testament" false
212run_verse_test "Invalid Chapter" "Esther" "18" "3" "Chapter 18 does not exist in Esther" false
213run_verse_test "Invalid Verse" "Psalm" "117" "5" "Verse 5 does not exist in Psalm 117" false
214
215# Adversarial Testing Section
216print_section "Adversarial Tests"
217
218# Test edge cases
219run_verse_test "Empty Book Name" "" "1" "1" "Please enter the reference" false
220run_verse_test "Non-numeric Chapter" "Genesis" "abc" "1" "Please enter the reference" false
221run_verse_test "Non-numeric Verse" "Genesis" "1" "xyz" "Please enter the reference" false
222run_verse_test "Zero Chapter" "Genesis" "0" "1" "Please enter the reference" false
223run_verse_test "Zero Verse" "Genesis" "1" "0" "Please enter the reference" false
224run_verse_test "Negative Chapter" "Genesis" "-1" "1" "Please enter the reference" false
225run_verse_test "Negative Verse" "Genesis" "1" "-1" "Please enter the reference" false
226run_verse_test "Very Large Chapter" "Genesis" "999999" "1" "Please enter the reference" false
227run_verse_test "Very Large Verse" "Genesis" "1" "999999" "Please enter the reference" false
228
229# Test case sensitivity
230run_verse_test "Lowercase Book" "genesis" "1" "1" "1 In the beginning God created the heaven and the earth." true
231run_verse_test "Mixed Case Book" "GEnesis" "1" "1" "1 In the beginning God created the heaven and the earth." true
232
233# Test two-word books
234run_verse_test "First Samuel" "First Samuel" "1" "1" "1 Now there was a certain man of Ramathaim-zophim, of mount Ephraim, and his name [was] Elkanah, the son of Jeroham, the son of Elihu, the son of Tohu, the son of Zuph, an Ephrathite:" true
235run_verse_test "Second Kings" "Second Kings" "1" "1" "1 Then Moab rebelled against Israel after the death of Ahab" true
236
237# Appending Tests
238print_section "Appending & File Path Tests"
239
240# Function to run appending test
241run_appending_test() {
242 local test_name="$1"
243
244 # Clean up previous test
245 rm -f "$output_file"
246
247 # First verse lookup
248 input1="Genesis\n1\n1"
249 output1=$(timeout "$test_timeout" bash -c "echo -e '$input1' | '$program' OT.txt '$output_file'" 2>&1)
250 exit_code1=$?
251
252 if [ $exit_code1 -ne 0 ]; then
253 print_result "$test_name - First Lookup" "FAIL" "First verse lookup failed"
254 return
255 fi
256
257 # Check first verse was written
258 if [ ! -f "$output_file" ]; then
259 print_result "$test_name - First File" "FAIL" "First verse file not created"
260 return
261 fi
262
263 first_content=$(cat "$output_file")
264
265 # Second verse lookup
266 input2="Genesis\n1\n2"
267 output2=$(timeout "$test_timeout" bash -c "echo -e '$input2' | '$program' OT.txt '$output_file'" 2>&1)
268 exit_code2=$?
269
270 if [ $exit_code2 -ne 0 ]; then
271 print_result "$test_name - Second Lookup" "FAIL" "Second verse lookup failed"
272 return
273 fi
274
275 # Check if file still exists and has content
276 if [ ! -f "$output_file" ]; then
277 print_result "$test_name - Second File" "FAIL" "File disappeared after second lookup"
278 return
279 fi
280
281 second_content=$(cat "$output_file")
282
283 # Check if both verses are in the file (appending behavior)
284 if [[ "$second_content" == *"1 In the beginning God created the heaven and the earth"* ]] && [[ "$second_content" == *"2 And the earth was without form, and void"* ]]; then
285 print_result "$test_name" "PASS" "Both verses found in file (appending works)"
286 elif [[ "$second_content" == *"2 And the earth was without form, and void"* ]] && [[ "$second_content" != *"1 In the beginning God created the heaven and the earth"* ]]; then
287 print_result "$test_name" "FAIL" "Only second verse found (overwriting instead of appending)"
288 else
289 print_result "$test_name" "FAIL" "Unexpected file content after second lookup"
290 fi
291}
292
293run_appending_test "Multiple Verse Appending"
294
295# Function to run file path test
296run_file_path_test() {
297 local test_name="$1"
298 local file_path="$2"
299 local expected_pattern="$3"
300 local should_succeed="$4"
301
302 # Clean up previous test
303 rm -f "$output_file"
304
305 # Provide verse lookup input for file path tests
306 input="Genesis\n1\n1"
307
308 if [ -n "$file_path" ]; then
309 output=$(timeout "$test_timeout" bash -c "echo -e '$input' | '$program' '$file_path' '$output_file'" 2>&1)
310 else
311 output=$(timeout "$test_timeout" bash -c "echo -e '$input' | '$program' OT.txt '$output_file'" 2>&1)
312 fi
313 exit_code=$?
314
315 if [ $exit_code -eq 124 ]; then
316 print_result "$test_name" "TIMEOUT" "Program timed out after ${test_timeout}s"
317 return
318 fi
319
320 if [ "$should_succeed" = "true" ]; then
321 if [ $exit_code -eq 0 ]; then
322 print_result "$test_name" "PASS" "Program accepted file path successfully"
323 else
324 print_result "$test_name" "FAIL" "Program failed with exit code $exit_code: $output"
325 fi
326 else
327 if [ $exit_code -ne 0 ] && [[ "$output" == *"$expected_pattern"* ]]; then
328 print_result "$test_name" "PASS" "Program correctly rejected invalid file path"
329 elif [ $exit_code -eq 0 ]; then
330 print_result "$test_name" "FAIL" "Program should have failed with invalid file path"
331 else
332 print_result "$test_name" "FAIL" "Expected error message '$expected_pattern' not found: $output"
333 fi
334 fi
335}
336
337# Test with existing file (absolute path)
338run_file_path_test "Existing File (Absolute)" "/Users/kierank/code/school/lab-6/test/OT.txt" "" true
339
340# Test with existing file (relative path)
341run_file_path_test "Existing File (Relative)" "OT.txt" "" true
342
343# Test with non-existing file
344run_file_path_test "Non-existing File" "nonexistent.txt" "failed to open file" false
345
346# Test with invalid path
347run_file_path_test "Invalid Path" "/invalid/path/file.txt" "failed to open file" false
348
349# Test with empty path
350run_file_path_test "Empty Path" "" "" true
351
352# Test summary
353print_section "Test Summary"
354echo -e "${BLUE}Tests passed: $passed_tests/$total_tests${NC}"
355
356if [ $passed_tests -eq $total_tests ]; then
357 echo -e "${GREEN}All tests passed!${NC}"
358 exit 0
359else
360 echo -e "${RED}Some tests failed!${NC}"
361 exit 1
362fi