···11----
22-Project: "#6"
33-Professor: "Professor Knoerr"
44-Class: "CS 1210 – Fall 2025"
55-Author: "Kieran Klukas"
66----
77-88-# Requirements
99-1010-<!--Restate the problem specifications in your own words-->
1111-1212-Search a provided old testament text file for arbitrary reference. It prompts the user for book, chapter, and verse and then searches for that verse. If book is not found then output `Book does not exist in the Old Testament`. If chapter isn't found then `Chapter # does not exist in Book`. Finally if the verse isn't found then output `Verse # does not exist in Book #`. Once the verse is found then append the verse to `verses.txt`.
1313-1414-# Design
1515-1616-<!--How did you attack the problem? What choices did you make in your design, and why?-->
1717-1818-I started with outlining the basic input system [`532c6cf`](https://github.com/cu-cs1210/lab-6-kieranklukas/commit/5b2ced23798fc7cbce79eb445c9592cccf16d6a6). Then worked on setting up a while loop to read the file line by line. I spent a while puzzling over exactly how I wanted to implement this and I am not entirely satisfied with my current solution. It would be interesting to try this problem in a functional language like gleam or erlang and see how much more cleanly I can parse the file. I implemented each reference part sequentially and then went back and made it check for barrier strings to stay within the proper book and chapter. I ended up realizing that the book of Psalms is referenced differently and so made some logic to permit its idiosyncracies [`7c18fff`](https://github.com/cu-cs1210/lab-6-kieranklukas/commit/7c18fffa30ab3e43bcb05ad4dff44f275987cbb8).
1919-2020-# Implementation
2121-2222-<!--Outline any interesting implementation details.-->
2323-2424-I used a single input variable to parse the file word by word until we get to the correct verse. I also check if the input book is listed as `Psalm` or `Psalms` and add or remove an `s` when doing checks or output as appropriate. The output file is also never opened until we find the verse and is immediately closed afterward. Also a minor note of intrest is that you can change the default paths that the program loads from and saves to by adding the paths as arguments (eg. `lab66 test/OT.txt build/verses.txt`).
2525-2626-# Testing
2727-2828-<!--
2929-Explain how you tested your program, enumerating the tests if possible.
3030-Explain why your test set was sufficient to believe that the software is working properly,
3131-i.e., what were the range of possibilities of errors that you were testing for.
3232--->
3333-3434-I updated the `makefile` to add `make run` so I could compile and run it more easily and updated the test file to have the Zylabs test states as well as more granularly check a happy path and some adversarial paths.
3535-3636-# Outside Help
3737-3838-<!--Did you get help from anyone else on this project? Document their contribution to your learning.-->
3939-4040-No outside help was used beyond minor googling for how to capitalize an entire string and the proper syntax for appending (not covered in zybooks as far as I can tell but I'm sure you will cover it in lectures next week).
4141-4242-# Summary/Conclusion
4343-4444-<!--Present your results. Did it work properly? Are there any limitations?-->
4545-4646-The program works well and should cover most edgecases! As far as I can tell there isn't anything that should be able to break it beyond changing the `OT.txt` to be several GB in size.
4747-4848-# AI Use
4949-5050-<!--How did you use Generative AI in this project?-->
5151-5252-I used claude to generate a more complex test file and then modified it to add the rest of the zybooks tests as I got closer to finishing the project.
5353-5454-# Lessons Learned
5555-5656-<!--List any lessons learned. What might you have done differently if you were going to attack this again.-->
5757-5858-I would definetly want to try a different language for sure if I was doing this independantly but overal I think this implementation is fairly solid and I wouldn't change much. I did find out in this lab that it is always a good idea to check the whole input or you might run into weird bugs like how `PSALMS` is formatted.
5959-6060-# Time Spent
6161-6262-<!--Approximately how many hours did you spend on this project?-->
6363-6464-
···11+name = "bible_search"
22+version = "1.0.0"
33+44+# Fill out these fields if you intend to generate HTML documentation or publish
55+# your project to the Hex package manager.
66+#
77+# description = ""
88+# licences = ["Apache-2.0"]
99+# repository = { type = "github", user = "", repo = "" }
1010+# links = [{ title = "Website", href = "" }]
1111+#
1212+# For a full reference of all the available options, you can have a look at
1313+# https://gleam.run/writing-gleam/gleam-toml/.
1414+1515+[dependencies]
1616+gleam_stdlib = ">= 0.44.0 and < 2.0.0"
1717+simplifile = ">= 2.3.0 and < 3.0.0"
1818+input = ">= 1.0.1 and < 2.0.0"
1919+2020+[dev-dependencies]
2121+gleeunit = ">= 1.0.0 and < 2.0.0"
···11+# This file was generated by Gleam
22+# You typically do not need to edit this file
33+44+packages = [
55+ { name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" },
66+ { name = "gleam_stdlib", version = "0.65.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "7C69C71D8C493AE11A5184828A77110EB05A7786EBF8B25B36A72F879C3EE107" },
77+ { name = "gleeunit", version = "1.6.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "FDC68A8C492B1E9B429249062CD9BAC9B5538C6FBF584817205D0998C42E1DAC" },
88+ { name = "input", version = "1.0.1", build_tools = ["gleam"], requirements = [], otp_app = "input", source = "hex", outer_checksum = "FE84CDADC78A1367E4AFD561A529825A8FEC88D165CBDF511FD3226CABCDEE6F" },
99+ { name = "simplifile", version = "2.3.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0A868DAC6063D9E983477981839810DC2E553285AB4588B87E3E9C96A7FB4CB4" },
1010+]
1111+1212+[requirements]
1313+gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
1414+gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
1515+input = { version = ">= 1.0.1 and < 2.0.0" }
1616+simplifile = { version = ">= 2.3.0 and < 3.0.0" }
+47
src/bible_search.gleam
···11+import gleam/int
22+import gleam/io
33+import gleam/list
44+import gleam/string
55+import input.{input}
66+import simplifile
77+88+const filepath = "./OT.txt"
99+1010+pub type Reference {
1111+ Reference(book: String, chapter: Int, verse: Int)
1212+}
1313+1414+pub fn parse_reference(input: String) -> Result(Reference, String) {
1515+ let parts = string.split(input, on: " ")
1616+1717+ case parts {
1818+ [book, chapter_s, verse_s] ->
1919+ case int.parse(chapter_s) {
2020+ Ok(chapter) ->
2121+ case int.parse(verse_s) {
2222+ Ok(verse) ->
2323+ Ok(Reference(book: string.uppercase(book), chapter:, verse:))
2424+ Error(_) -> Error("Invalid verse" <> verse_s)
2525+ }
2626+ Error(_) -> Error("Invalid chapter" <> chapter_s)
2727+ }
2828+ _ -> Error("invalid parse")
2929+ }
3030+}
3131+3232+pub fn main() -> Nil {
3333+ let assert Ok(bible) = simplifile.read(from: filepath)
3434+3535+ let biblelines = string.split(bible, on: "\n")
3636+3737+ let assert Ok(search) = input(prompt: "> ")
3838+3939+ let assert Ok(reference) = parse_reference(search)
4040+4141+ list.each(biblelines, fn(line) {
4242+ case line {
4343+ "THE BOOK OF " <> book if book == reference.book -> io.println(book)
4444+ _ -> io.print("")
4545+ }
4646+ })
4747+}
-143
src/lab66.cpp
···11-/*********************************************************
22-* Summary: find verses from the old testament
33-* appending them to file as found
44-*
55-* Author: Kieran Klukas
66-* Created: October 2025
77-*
88-********************************************************/
99-1010-#include <iostream>
1111-#include <cstdlib>
1212-#include <fstream>
1313-1414-using namespace std;
1515-1616-int main(int argc, char **argv) {
1717-1818- ifstream OT;
1919- ofstream OF;
2020- string inputFilename = "OT.txt";
2121- string outputFilename = "verses.txt";
2222-2323- string book;
2424- string normalizedBook;
2525- int chapter;
2626- int verse;
2727-2828- // get path to OT.txt if provided otherwise use default path
2929- // and then do the same for the verses.txt
3030- if (argc >= 2) inputFilename = argv[1];
3131- if (argc >= 3) outputFilename = argv[2];
3232-3333- OT.open(inputFilename);
3434-3535- if (!OT.is_open()) {
3636- cout << inputFilename << ": failed to open file";
3737- return 1;
3838- }
3939-4040- cout << "Please enter the reference of the verse you would like" << endl;
4141-4242- cout << "the book: ";
4343- getline(cin, book);
4444- for (int i = 0; i < book.length(); i++)
4545- normalizedBook += toupper(book[i]);
4646- if (normalizedBook == "PSALMS")
4747- normalizedBook = "PSALM";
4848-4949- cout << "the chapter: ";
5050- cin >> chapter;
5151-5252- cout << "the verse: ";
5353- cin >> verse;
5454-5555- cout << endl;
5656-5757- bool foundBook = false;
5858- bool foundChapter = false;
5959- bool foundVerse = false;
6060- string verseString;
6161- while (!OT.eof()) {
6262- string input;
6363-6464- if (!foundBook) {
6565- OT >> input; // THE
6666- if (input != "THE") continue;
6767- OT >> input; // BOOK
6868- if (input != "BOOK") continue;
6969- OT >> input; // OF
7070- if (input != "OF") continue;
7171-7272- OT.ignore(); // skip the single space
7373-7474- getline(OT, input); // handle multi word books
7575-7676- // second check is for the book of psalms
7777- if (input == normalizedBook || input == (normalizedBook + "S")) {
7878- foundBook = true;
7979-8080- getline(OT, input); // discard empty line
8181- continue;
8282- }
8383- } else {
8484- if (!foundChapter) {
8585- OT >> input;
8686- if (input != "CHAPTER" && input != "PSALM") {
8787- if (input == "THE") break;
8888-8989- continue;
9090- }
9191-9292- OT >> input;
9393- if (input == to_string(chapter)) {
9494- foundChapter = true;
9595- continue;
9696- }
9797- } else {
9898- OT >> input;
9999-100100- if (input == "CHAPTER" || input == "PSALM") break;
101101-102102- if (input == to_string(verse)) {
103103- foundVerse = true;
104104- OT.ignore(); // ignore space
105105- getline(OT, verseString);
106106- break;
107107- }
108108- }
109109- }
110110- }
111111-112112- if (foundVerse) {
113113- cout << verse << " " << verseString << endl;
114114-115115- OF.open(outputFilename, ios_base::app);
116116-117117- if (!OF.is_open()) {
118118- cout << outputFilename << ": error saving file" << endl;
119119- return 1;
120120- }
121121-122122- OF << verse << " " << verseString << endl;
123123-124124- OF.close();
125125- } else {
126126- if (!foundBook) {
127127- cout << (normalizedBook == "PSALM" ? book += "s" : book) << " does not exist in the Old Testament";
128128- } else {
129129- if (!foundChapter) {
130130- cout << (normalizedBook == "PSALM" ? "Psalm " : "Chapter ") << chapter;
131131- cout << " does not exist in " << (normalizedBook == "PSALM" ? book += "s" : book);
132132- } else if (!foundVerse) {
133133- cout << "Verse " << verse << " does not exist in " << book << " " << chapter;
134134- }
135135- }
136136-137137- cout << endl;
138138- }
139139-140140- OT.close();
141141-142142- return 0;
143143-}
test/OT.txt
OT.txt
+13
test/bible_search_gleam_test.gleam
···11+import gleeunit
22+33+pub fn main() -> Nil {
44+ gleeunit.main()
55+}
66+77+// gleeunit test functions end in `_test`
88+pub fn hello_world_test() {
99+ let name = "Joe"
1010+ let greeting = "Hello, " <> name <> "!"
1111+1212+ assert greeting == "Hello, Joe!"
1313+}
-362
test/test.sh
···11-#!/bin/bash
22-33-# Test script with configurable timeout support
44-# Usage: ./test.sh [timeout_seconds]
55-# Example: ./test.sh 5 (uses 5 second timeout)
66-# Default: 1 second timeout
77-88-# Colors for output
99-RED='\033[0;31m'
1010-GREEN='\033[0;32m'
1111-YELLOW='\033[1;33m'
1212-BLUE='\033[0;34m'
1313-NC='\033[0m' # No Color
1414-1515-# Test configuration
1616-temp_file="lab66.output"
1717-program="../build/lab66"
1818-output_file="../build/verses.txt"
1919-test_timeout=${1:-1}
2020-2121-# Test counters
2222-total_tests=0
2323-passed_tests=0
2424-2525-# Cleanup function
2626-cleanup() {
2727- rm -f "$temp_file" "$output_file"
2828-}
2929-3030-# Error trap
3131-trap cleanup EXIT ERR
3232-3333-# Function to print test results
3434-print_result() {
3535- local test_name="$1"
3636- local result="$2"
3737- local message="$3"
3838-3939- total_tests=$((total_tests + 1))
4040-4141- if [ "$result" = "PASS" ]; then
4242- echo -e "${GREEN}[PASS]${NC} $test_name: $message"
4343- passed_tests=$((passed_tests + 1))
4444- elif [ "$result" = "TIMEOUT" ]; then
4545- echo -e "${YELLOW}[TIMEOUT]${NC} $test_name: $message"
4646- else
4747- echo -e "${RED}[FAIL]${NC} $test_name: $message"
4848- fi
4949-}
5050-5151-# Function to print test section header
5252-print_section() {
5353- echo -e "\n${BLUE}=== $1 ===${NC}"
5454-}
5555-5656-# Build program if needed
5757-if [ ! -f "$program" ]; then
5858- print_section "Building Program"
5959- cd .. && make lab66 > /dev/null 2>&1
6060- build_result=$?
6161- cd test
6262- if [ $build_result -ne 0 ]; then
6363- print_result "Program Build" "FAIL" "Could not build $program"
6464- exit 1
6565- fi
6666- print_result "Program Build" "PASS" "Program built successfully"
6767-fi
6868-6969-# Test 1: Program compilation/existence
7070-if [ ! -f "$program" ]; then
7171- print_section "Test 1: Program Availability"
7272- print_result "Program Existence" "FAIL" "Program $program not found"
7373- exit 1
7474-fi
7575-7676-# Test 2: Basic Bible Verse Lookup Test (Genesis 1:1)
7777-print_section "Basic Bible Verse Lookup Test"
7878-7979-# Test with known valid verse
8080-basic_input="Genesis\n1\n1"
8181-resp=$(timeout "$test_timeout" bash -c "echo -e '$basic_input' | '$program' OT.txt '$output_file'" 2>&1)
8282-exit_code=$?
8383-8484-# Print the output
8585-if [ -n "$resp" ]; then
8686- echo "$resp"
8787-else
8888- echo "(No output produced)"
8989-fi
9090-echo
9191-9292-if [ $exit_code -eq 124 ]; then
9393- print_result "Basic Execution" "TIMEOUT" "Program timed out after ${test_timeout}s"
9494- exit 1
9595-elif [ $exit_code -ne 0 ]; then
9696- print_result "Basic Execution" "FAIL" "Program exited with code $exit_code"
9797- exit 1
9898-else
9999- print_result "Basic Execution" "PASS" "Program executed successfully"
100100-fi
101101-102102-# Check if output contains required prompts
103103-if [[ "$resp" == *"Please enter the reference of the verse you would like"* ]]; then
104104- print_result "Initial Prompt" "PASS" "Program shows initial prompt"
105105-else
106106- print_result "Initial Prompt" "FAIL" "Program missing initial prompt"
107107-fi
108108-109109-if [[ "$resp" == *"the book:"* ]]; then
110110- print_result "Book Prompt" "PASS" "Program prompts for book"
111111-else
112112- print_result "Book Prompt" "FAIL" "Program missing book prompt"
113113-fi
114114-115115-if [[ "$resp" == *"the chapter:"* ]]; then
116116- print_result "Chapter Prompt" "PASS" "Program prompts for chapter"
117117-else
118118- print_result "Chapter Prompt" "FAIL" "Program missing chapter prompt"
119119-fi
120120-121121-if [[ "$resp" == *"the verse:"* ]]; then
122122- print_result "Verse Prompt" "PASS" "Program prompts for verse"
123123-else
124124- print_result "Verse Prompt" "FAIL" "Program missing verse prompt"
125125-fi
126126-127127-# Check for verse output format
128128-if [[ "$resp" == *"1 In the beginning God created the heaven and the earth"* ]]; then
129129- print_result "Verse Format" "PASS" "Program outputs verse in correct format"
130130-else
131131- print_result "Verse Format" "FAIL" "Program missing or incorrect verse format"
132132-fi
133133-134134-# Check if test/verses.txt file was created
135135-if [ -f "$output_file" ]; then
136136- verses_content=$(cat "$output_file")
137137- if [[ "$verses_content" == *"In the beginning God created the heaven and the earth"* ]]; then
138138- print_result "File Output" "PASS" "verses.txt created with correct content in build directory"
139139- else
140140- print_result "File Output" "FAIL" "verses.txt has incorrect content"
141141- fi
142142-else
143143- print_result "File Output" "FAIL" "verses.txt file not created in build directory"
144144-fi
145145-146146-# Function to run verse lookup test
147147-run_verse_test() {
148148- local test_name="$1"
149149- local book="$2"
150150- local chapter="$3"
151151- local verse="$4"
152152- local expected_pattern="$5"
153153- local should_create_file="$6"
154154-155155- # Clean up previous test
156156- rm -f "$output_file"
157157-158158- input="$book\n$chapter\n$verse"
159159- output=$(timeout "$test_timeout" bash -c "echo -e '$input' | '$program' OT.txt '$output_file'" 2>&1)
160160- exit_code=$?
161161-162162- if [ $exit_code -eq 124 ]; then
163163- print_result "$test_name" "TIMEOUT" "Program timed out after ${test_timeout}s"
164164- return
165165- elif [ $exit_code -ne 0 ]; then
166166- print_result "$test_name" "FAIL" "Program crashed (exit code $exit_code)"
167167- return
168168- fi
169169-170170- # Check if expected pattern is found in output
171171- pattern_found=false
172172- if [[ "$output" == *"$expected_pattern"* ]]; then
173173- pattern_found=true
174174- fi
175175-176176- # For tests expecting specific output, pattern must be found
177177- if [ -n "$expected_pattern" ] && [ "$pattern_found" = "false" ]; then
178178- print_result "$test_name" "FAIL" "Expected '$expected_pattern' not found in output"
179179- return
180180- fi
181181-182182- # Check file creation expectations
183183- if [ "$should_create_file" = "true" ]; then
184184- if [ -f "$output_file" ] && [ "$pattern_found" = "true" ]; then
185185- print_result "$test_name" "PASS" "Expected output found and file created"
186186- elif [ ! -f "$output_file" ]; then
187187- print_result "$test_name" "FAIL" "Expected file verses.txt not created in build directory"
188188- else
189189- print_result "$test_name" "FAIL" "File created but expected output not found"
190190- fi
191191- else
192192- if [ ! -f "$output_file" ] && [ "$pattern_found" = "true" ]; then
193193- print_result "$test_name" "PASS" "Expected error output and no file created"
194194- elif [ -f "$output_file" ]; then
195195- print_result "$test_name" "FAIL" "verses.txt file should not be created for error cases"
196196- else
197197- print_result "$test_name" "FAIL" "Expected error message not found"
198198- fi
199199- fi
200200-}
201201-202202-# Valid Verse Tests
203203-print_section "Valid Verse Tests"
204204-205205-run_verse_test "Exodus 20:3" "Exodus" "20" "3" "3 Thou shalt have no other gods before me" true
206206-run_verse_test "Psalm 23:1" "Psalm" "23" "1" "1 The LORD [is] my shepherd; I shall not want." true
207207-208208-# Error Case Tests
209209-print_section "Error Case Tests"
210210-211211-run_verse_test "Invalid Book" "Matthew" "1" "1" "Matthew does not exist in the Old Testament" false
212212-run_verse_test "Invalid Chapter" "Esther" "18" "3" "Chapter 18 does not exist in Esther" false
213213-run_verse_test "Invalid Verse" "Psalm" "117" "5" "Verse 5 does not exist in Psalm 117" false
214214-215215-# Adversarial Testing Section
216216-print_section "Adversarial Tests"
217217-218218-# Test edge cases
219219-run_verse_test "Empty Book Name" "" "1" "1" "Please enter the reference" false
220220-run_verse_test "Non-numeric Chapter" "Genesis" "abc" "1" "Please enter the reference" false
221221-run_verse_test "Non-numeric Verse" "Genesis" "1" "xyz" "Please enter the reference" false
222222-run_verse_test "Zero Chapter" "Genesis" "0" "1" "Please enter the reference" false
223223-run_verse_test "Zero Verse" "Genesis" "1" "0" "Please enter the reference" false
224224-run_verse_test "Negative Chapter" "Genesis" "-1" "1" "Please enter the reference" false
225225-run_verse_test "Negative Verse" "Genesis" "1" "-1" "Please enter the reference" false
226226-run_verse_test "Very Large Chapter" "Genesis" "999999" "1" "Please enter the reference" false
227227-run_verse_test "Very Large Verse" "Genesis" "1" "999999" "Please enter the reference" false
228228-229229-# Test case sensitivity
230230-run_verse_test "Lowercase Book" "genesis" "1" "1" "1 In the beginning God created the heaven and the earth." true
231231-run_verse_test "Mixed Case Book" "GEnesis" "1" "1" "1 In the beginning God created the heaven and the earth." true
232232-233233-# Test two-word books
234234-run_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
235235-run_verse_test "Second Kings" "Second Kings" "1" "1" "1 Then Moab rebelled against Israel after the death of Ahab" true
236236-237237-# Appending Tests
238238-print_section "Appending & File Path Tests"
239239-240240-# Function to run appending test
241241-run_appending_test() {
242242- local test_name="$1"
243243-244244- # Clean up previous test
245245- rm -f "$output_file"
246246-247247- # First verse lookup
248248- input1="Genesis\n1\n1"
249249- output1=$(timeout "$test_timeout" bash -c "echo -e '$input1' | '$program' OT.txt '$output_file'" 2>&1)
250250- exit_code1=$?
251251-252252- if [ $exit_code1 -ne 0 ]; then
253253- print_result "$test_name - First Lookup" "FAIL" "First verse lookup failed"
254254- return
255255- fi
256256-257257- # Check first verse was written
258258- if [ ! -f "$output_file" ]; then
259259- print_result "$test_name - First File" "FAIL" "First verse file not created"
260260- return
261261- fi
262262-263263- first_content=$(cat "$output_file")
264264-265265- # Second verse lookup
266266- input2="Genesis\n1\n2"
267267- output2=$(timeout "$test_timeout" bash -c "echo -e '$input2' | '$program' OT.txt '$output_file'" 2>&1)
268268- exit_code2=$?
269269-270270- if [ $exit_code2 -ne 0 ]; then
271271- print_result "$test_name - Second Lookup" "FAIL" "Second verse lookup failed"
272272- return
273273- fi
274274-275275- # Check if file still exists and has content
276276- if [ ! -f "$output_file" ]; then
277277- print_result "$test_name - Second File" "FAIL" "File disappeared after second lookup"
278278- return
279279- fi
280280-281281- second_content=$(cat "$output_file")
282282-283283- # Check if both verses are in the file (appending behavior)
284284- 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
285285- print_result "$test_name" "PASS" "Both verses found in file (appending works)"
286286- 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
287287- print_result "$test_name" "FAIL" "Only second verse found (overwriting instead of appending)"
288288- else
289289- print_result "$test_name" "FAIL" "Unexpected file content after second lookup"
290290- fi
291291-}
292292-293293-run_appending_test "Multiple Verse Appending"
294294-295295-# Function to run file path test
296296-run_file_path_test() {
297297- local test_name="$1"
298298- local file_path="$2"
299299- local expected_pattern="$3"
300300- local should_succeed="$4"
301301-302302- # Clean up previous test
303303- rm -f "$output_file"
304304-305305- # Provide verse lookup input for file path tests
306306- input="Genesis\n1\n1"
307307-308308- if [ -n "$file_path" ]; then
309309- output=$(timeout "$test_timeout" bash -c "echo -e '$input' | '$program' '$file_path' '$output_file'" 2>&1)
310310- else
311311- output=$(timeout "$test_timeout" bash -c "echo -e '$input' | '$program' OT.txt '$output_file'" 2>&1)
312312- fi
313313- exit_code=$?
314314-315315- if [ $exit_code -eq 124 ]; then
316316- print_result "$test_name" "TIMEOUT" "Program timed out after ${test_timeout}s"
317317- return
318318- fi
319319-320320- if [ "$should_succeed" = "true" ]; then
321321- if [ $exit_code -eq 0 ]; then
322322- print_result "$test_name" "PASS" "Program accepted file path successfully"
323323- else
324324- print_result "$test_name" "FAIL" "Program failed with exit code $exit_code: $output"
325325- fi
326326- else
327327- if [ $exit_code -ne 0 ] && [[ "$output" == *"$expected_pattern"* ]]; then
328328- print_result "$test_name" "PASS" "Program correctly rejected invalid file path"
329329- elif [ $exit_code -eq 0 ]; then
330330- print_result "$test_name" "FAIL" "Program should have failed with invalid file path"
331331- else
332332- print_result "$test_name" "FAIL" "Expected error message '$expected_pattern' not found: $output"
333333- fi
334334- fi
335335-}
336336-337337-# Test with existing file (absolute path)
338338-run_file_path_test "Existing File (Absolute)" "/Users/kierank/code/school/lab-6/test/OT.txt" "" true
339339-340340-# Test with existing file (relative path)
341341-run_file_path_test "Existing File (Relative)" "OT.txt" "" true
342342-343343-# Test with non-existing file
344344-run_file_path_test "Non-existing File" "nonexistent.txt" "failed to open file" false
345345-346346-# Test with invalid path
347347-run_file_path_test "Invalid Path" "/invalid/path/file.txt" "failed to open file" false
348348-349349-# Test with empty path
350350-run_file_path_test "Empty Path" "" "" true
351351-352352-# Test summary
353353-print_section "Test Summary"
354354-echo -e "${BLUE}Tests passed: $passed_tests/$total_tests${NC}"
355355-356356-if [ $passed_tests -eq $total_tests ]; then
357357- echo -e "${GREEN}All tests passed!${NC}"
358358- exit 0
359359-else
360360- echo -e "${RED}Some tests failed!${NC}"
361361- exit 1
362362-fi