From 185b33fdee0355a569c8cab6cc9b218c7513111c Mon Sep 17 00:00:00 2001 From: Tunahan Caner YILDIZ Date: Sun, 19 Apr 2026 19:22:40 +0300 Subject: [PATCH 1/2] feat(problems): Upgrade miniinventory to V3 with search capability --- problems/miniinventory/SPEC-v3.txt | 193 +++++++++++++++++++++++ problems/miniinventory/problem.json | 5 +- problems/miniinventory/test-v3.sh | 236 ++++++++++++++++++++++++++++ 3 files changed, 433 insertions(+), 1 deletion(-) create mode 100644 problems/miniinventory/SPEC-v3.txt create mode 100644 problems/miniinventory/test-v3.sh diff --git a/problems/miniinventory/SPEC-v3.txt b/problems/miniinventory/SPEC-v3.txt new file mode 100644 index 00000000..9e2fe95a --- /dev/null +++ b/problems/miniinventory/SPEC-v3.txt @@ -0,0 +1,193 @@ +PROJECT: mini-inventory +AUTHOR: Tunahan Caner YILDIZ (251478112) +VERSION: v3 +DATE: 2026-04-19 + +======================================== +OVERVIEW +======================================== + +mini-inventory is a command-line inventory manager. +It stores product records in a plain text file and supports +initializing the system, adding products, listing products, +updating stock quantities, deleting products, and searching products. + +All data is stored in a directory called .miniinventory/ +in the current working directory. + +======================================== +COMMANDS +======================================== + +--- init --- +Usage: miniinventory init + +Creates a .miniinventory/ directory and an empty inventory.dat file. +If .miniinventory/ already exists, print "Already initialized" and exit. + +Output: +- Success: "Initialized empty mini-inventory in .miniinventory/" +- Error: "Already initialized" + +--- add --- +Usage: miniinventory add "Pencil" 50 + +Appends a new product to inventory.dat. +Each product has: +- id (auto-increment) +- name +- quantity +- created_date + +Validation rules: +- Quantity must be a non-negative integer +- Product name must not be empty or whitespace only +- Product name must be unique in the inventory + +Output: +- Success: "Added product #: ()" +- Error if system is not initialized: + "Not initialized. Run: miniinventory init" +- Error if quantity is invalid: + "Invalid quantity" +- Error if product with the same name already exists: + "Product already exists" +- Error if name is empty or only whitespace: + "Invalid product name" +- Error if arguments are missing: + "Usage: miniinventory add " + +--- list --- +Usage: miniinventory list + +Prints all products, one per line, in this format: +[1] Pencil - Quantity: 50 (2026-03-15) +[2] Notebook - Quantity: 20 (2026-03-15) + +Listing rules: +- Products are listed in ascending order by ID +- Each stored product is printed on its own line +- If no products exist, print "No products found." + +Output: +- Success: prints all products in the required format +- Error if system is not initialized: + "Not initialized. Run: miniinventory init" +- Output if inventory is empty: + "No products found." + +--- update --- +Usage: miniinventory update 1 80 + +Updates the quantity of product #1 to 80. +The given quantity must be a non-negative integer. + +Output: +- Success: "Product #1 updated to quantity 80." +- Error if product does not exist: + "Product #1 not found." +- Error if quantity is invalid: + "Invalid quantity" +- Error if arguments are missing: + "Usage: miniinventory update " +- Error if system is not initialized: + "Not initialized. Run: miniinventory init" + +--- delete --- +Usage: miniinventory delete 1 + +Removes product #1 from inventory.dat. + +Output: +- Success: "Deleted product #1." +- Error if product does not exist: + "Product #1 not found." +- Error if arguments are missing: + "Usage: miniinventory delete " +- Error if system is not initialized: + "Not initialized. Run: miniinventory init" + +--- search --- +Usage: miniinventory search "Pen" + +Searches for products whose name contains the search query. + +Validation and filtering rules: +- The search must be case-insensitive (e.g., searching "pEn" must find "Pencil"). +- Products must be listed in ascending order by ID, matching the exact format of 'list'. +- The query can be a substring anywhere in the product name. + +Output: +- Success matches: + [1] Pencil - Quantity: 50 (2026-03-15) + [3] Blue Pen - Quantity: 10 (2026-03-15) +- No matches found: + "No products match the search." +- Error if arguments are missing: + "Usage: miniinventory search " +- Error if system is not initialized: + "Not initialized. Run: miniinventory init" + +======================================== +DATA FORMAT +======================================== + +File: .miniinventory/inventory.dat + +Format: +One product per line, fields separated by | + +Fields: +id|name|quantity|created_date + +Example: +1|Pencil|50|2026-03-15 +2|Notebook|20|2026-03-15 + +ID RULES: +- IDs start from 1 +- Each new product gets the next highest ID +- Deleted IDs are NOT reused + +======================================== +ERROR HANDLING +======================================== + +- Running any command before "init": + print "Not initialized. Run: miniinventory init" + +- Invalid command: + print "Unknown command: " + +- Missing main command: + print "Usage: miniinventory [args]" + +- Invalid quantity: + print "Invalid quantity" + +- Invalid product name: + print "Invalid product name" + +- Duplicate product name: + print "Product already exists" + +======================================== +VERSION v3 SCOPE +======================================== + +The v3 implementation expands the v2 tool with powerful data filtering. + +Implemented commands: +- init +- add +- list +- update +- delete +- search + +v3 TASKS COMPLETED: +1. Implemented the "search" command to perform case-insensitive substring queries on product names. + +v2 -> v3 SUMMARY: +- v2 supported full CRUD capabilities +- v3 adds case-insensitive search capability to dynamically filter the listing output diff --git a/problems/miniinventory/problem.json b/problems/miniinventory/problem.json index 4f8e1dcb..6f3b2d08 100644 --- a/problems/miniinventory/problem.json +++ b/problems/miniinventory/problem.json @@ -6,5 +6,8 @@ "v1_prompt": "Implement {{binary_name}} as described in SPEC-v1.txt using {{language}}. The executable must be named '{{binary_name}}' and be runnable as ./{{binary_name}}. For compiled languages, include a Makefile or build script. For interpreted languages, ensure the {{binary_name}} file has a proper shebang line and is executable. Verify your implementation passes all tests by running: bash test-v1.sh", "v2_spec": "SPEC-v2.txt", "v2_test": "test-v2.sh", - "v2_prompt": "Read SPEC-v2.txt and extend the existing {{binary_name}} implementation. Update the code to implement list, update, and delete commands. Verify your implementation passes all tests by running: bash test-v2.sh" + "v2_prompt": "Read SPEC-v2.txt and extend the existing {{binary_name}} implementation. Update the code to implement list, update, and delete commands. Verify your implementation passes all tests by running: bash test-v2.sh", + "v3_spec": "SPEC-v3.txt", + "v3_test": "test-v3.sh", + "v3_prompt": "Read SPEC-v3.txt and extend the existing {{binary_name}} implementation. Update the code to implement the new 'search' command with case-insensitive filtering. Verify your implementation passes all tests by running: bash test-v3.sh" } \ No newline at end of file diff --git a/problems/miniinventory/test-v3.sh b/problems/miniinventory/test-v3.sh new file mode 100644 index 00000000..da89fed1 --- /dev/null +++ b/problems/miniinventory/test-v3.sh @@ -0,0 +1,236 @@ +#!/usr/bin/env bash +set -e + +PASS_COUNT=0 +FAIL_COUNT=0 + +fail() { + echo "FAIL: $1" + FAIL_COUNT=$((FAIL_COUNT+1)) +} + +pass() { + echo "PASS: $1" + PASS_COUNT=$((PASS_COUNT+1)) +} + +cleanup() { + cd "$(dirname "$0")" + rm -rf testrepo +} + +# Build if needed +cd "$(dirname "$0")" + +if [ -f Makefile ] || [ -f makefile ]; then + make -s 2>/dev/null || true +fi +if [ -f build.sh ]; then + bash build.sh 2>/dev/null || true +fi +chmod +x miniinventory 2>/dev/null || true + +###################################### +# Setup +###################################### + +cleanup +mkdir testrepo +cd testrepo + +###################################### +# Test 1: init +###################################### +if ../miniinventory init && [ -d .miniinventory ] && [ -f .miniinventory/inventory.dat ]; then + OUTPUT=$(../miniinventory init 2>&1 || true) + if echo "$OUTPUT" | grep -q "Already initialized"; then + pass "init creates directory and handles duplicate" + else + fail "init creates directory and handles duplicate (duplicate missing)" + fi +else + fail "init creates directory and handles duplicate (dir missing)" +fi + +###################################### +# Test 2: before init errors +###################################### +rm -rf .miniinventory +if ../miniinventory add Pencil 50 2>&1 | grep -q "Not initialized"; then pass "add before init"; else fail "add before init"; fi +if ../miniinventory list 2>&1 | grep -q "Not initialized"; then pass "list before init"; else fail "list before init"; fi +if ../miniinventory update 1 80 2>&1 | grep -q "Not initialized"; then pass "update before init"; else fail "update before init"; fi +if ../miniinventory delete 1 2>&1 | grep -q "Not initialized"; then pass "delete before init"; else fail "delete before init"; fi +if ../miniinventory search Pen 2>&1 | grep -q "Not initialized"; then pass "search before init"; else fail "search before init"; fi + +###################################### +# Test 3: add and duplicate check +###################################### +../miniinventory init >/dev/null 2>&1 +../miniinventory add Pencil 50 >/dev/null 2>&1 +if ../miniinventory add Pencil 30 2>&1 | grep -q "Product already exists"; then + pass "add duplicate product fails" +else + fail "add duplicate product fails" +fi + +if ../miniinventory add " " 10 2>&1 | grep -q "Invalid product name"; then + pass "add invalid name fails" +else + fail "add invalid name fails" +fi + +if ../miniinventory add Pencil 2>&1 | grep -q "Usage"; then + pass "add missing arguments" +else + fail "add missing arguments" +fi + +###################################### +# Test 4: list products +###################################### +../miniinventory add Notebook 20 >/dev/null 2>&1 +OUTPUT=$(../miniinventory list 2>&1) +if echo "$OUTPUT" | grep -q "\[1\] Pencil - Quantity: 50" && echo "$OUTPUT" | grep -q "\[2\] Notebook - Quantity: 20"; then + pass "list shows products" +else + fail "list shows products" +fi + +###################################### +# Test 5: list empty +###################################### +rm -rf .miniinventory +../miniinventory init >/dev/null 2>&1 +if ../miniinventory list 2>&1 | grep -q "No products found"; then + pass "list empty inventory" +else + fail "list empty inventory" +fi + +###################################### +# Test 6: update product +###################################### +../miniinventory add Pencil 50 >/dev/null 2>&1 +if ../miniinventory update 1 80 2>&1 | grep -q "Product #1 updated to quantity 80"; then + pass "update product success" +else + fail "update product success" +fi + +if ../miniinventory update 1 -1 2>&1 | grep -q "Invalid quantity"; then + pass "update invalid quantity fails" +else + fail "update invalid quantity fails" +fi + +if ../miniinventory update 99 80 2>&1 | grep -q "Product #99 not found"; then + pass "update missing product fails" +else + fail "update missing product fails" +fi + +if ../miniinventory update 1 2>&1 | grep -q "Usage"; then + pass "update missing arguments" +else + fail "update missing arguments" +fi + +###################################### +# Test 7: delete product & ID reuse +###################################### +../miniinventory add Notebook 20 >/dev/null 2>&1 +if ../miniinventory delete 1 2>&1 | grep -q "Deleted product #1"; then + pass "delete product success" +else + fail "delete product success" +fi + +if ../miniinventory delete 99 2>&1 | grep -q "Product #99 not found"; then + pass "delete missing product fails" +else + fail "delete missing product fails" +fi + +if ../miniinventory delete 2>&1 | grep -q "Usage"; then + pass "delete missing arguments" +else + fail "delete missing arguments" +fi + +# ID check (new product should be #3 since 1 was deleted, 2 exists) +if ../miniinventory add Eraser 10 2>&1 | grep -q "Added product #3: Eraser (10)"; then + pass "deleted IDs are not reused" +else + fail "deleted IDs are not reused" +fi + +###################################### +# Test 8: search product +###################################### +rm -rf .miniinventory +../miniinventory init >/dev/null 2>&1 +../miniinventory add Pencil 50 >/dev/null 2>&1 +../miniinventory add Notebook 20 >/dev/null 2>&1 +../miniinventory add "Blue Pen" 10 >/dev/null 2>&1 + +OUTPUT=$(../miniinventory search "Notebook" 2>&1) +if echo "$OUTPUT" | grep -q "\[2\] Notebook - Quantity: 20" && ! echo "$OUTPUT" | grep -q "Pencil"; then + pass "search finds exact match" +else + fail "search finds exact match" +fi + +OUTPUT=$(../miniinventory search "pEn" 2>&1) +if echo "$OUTPUT" | grep -q "\[1\] Pencil" && echo "$OUTPUT" | grep -q "\[3\] Blue Pen" && ! echo "$OUTPUT" | grep -q "Notebook"; then + pass "search is case insensitive and finds multiple" +else + fail "search is case insensitive and finds multiple" +fi + +if ../miniinventory search "NotExists" 2>&1 | grep -q "No products match the search."; then + pass "search no match" +else + fail "search no match" +fi + +if ../miniinventory search 2>&1 | grep -q "Usage"; then + pass "search missing arguments" +else + fail "search missing arguments" +fi + +###################################### +# Test 9: unknown/missing command +###################################### +if ../miniinventory fly 2>&1 | grep -q "Unknown command: fly"; then + pass "unknown command" +else + fail "unknown command" +fi + +if ../miniinventory 2>&1 | grep -q "Usage"; then + pass "missing command" +else + fail "missing command" +fi + +###################################### +# Cleanup & Summary +###################################### + +cd .. +rm -rf testrepo + +echo "" +echo "========================" +echo "PASSED: $PASS_COUNT" +echo "FAILED: $FAIL_COUNT" +echo "TOTAL: $((PASS_COUNT + FAIL_COUNT))" +echo "========================" + +if [ "$FAIL_COUNT" -eq 0 ]; then + echo "ALL TESTS PASSED" + exit 0 +else + exit 1 +fi From 66674682b04aa7cc295835f1691ec3debf8ece84 Mon Sep 17 00:00:00 2001 From: Tunahan Caner YILDIZ Date: Sun, 19 Apr 2026 19:28:28 +0300 Subject: [PATCH 2/2] fix(problems): merge search feature back into v2 to comply with 5-file guideline --- problems/miniinventory/SPEC-v2.txt | 31 +++- problems/miniinventory/SPEC-v3.txt | 193 ----------------------- problems/miniinventory/problem.json | 5 +- problems/miniinventory/test-v2.sh | 38 ++++- problems/miniinventory/test-v3.sh | 236 ---------------------------- 5 files changed, 64 insertions(+), 439 deletions(-) delete mode 100644 problems/miniinventory/SPEC-v3.txt delete mode 100644 problems/miniinventory/test-v3.sh diff --git a/problems/miniinventory/SPEC-v2.txt b/problems/miniinventory/SPEC-v2.txt index 2e2c5b67..ccbbb1d4 100644 --- a/problems/miniinventory/SPEC-v2.txt +++ b/problems/miniinventory/SPEC-v2.txt @@ -1,7 +1,7 @@ PROJECT: mini-inventory AUTHOR: Tunahan Caner YILDIZ (251478112) VERSION: v2 -DATE: 2026-03-29 +DATE: 2026-04-19 ======================================== OVERVIEW @@ -10,7 +10,7 @@ OVERVIEW mini-inventory is a command-line inventory manager. It stores product records in a plain text file and supports initializing the system, adding products, listing products, -updating stock quantities, and deleting products. +updating stock quantities, deleting products, and searching products. All data is stored in a directory called .miniinventory/ in the current working directory. @@ -107,6 +107,27 @@ Output: - Error if system is not initialized: "Not initialized. Run: miniinventory init" +--- search --- +Usage: miniinventory search "Pen" + +Searches for products whose name contains the search query. + +Validation and filtering rules: +- The search must be case-insensitive (e.g., searching "pEn" must find "Pencil"). +- Products must be listed in ascending order by ID, matching the exact format of 'list'. +- The query can be a substring anywhere in the product name. + +Output: +- Success matches: + [1] Pencil - Quantity: 50 (2026-03-15) + [3] Blue Pen - Quantity: 10 (2026-03-15) +- No matches found: + "No products match the search." +- Error if arguments are missing: + "Usage: miniinventory search " +- Error if system is not initialized: + "Not initialized. Run: miniinventory init" + ======================================== DATA FORMAT ======================================== @@ -162,14 +183,14 @@ Implemented commands: - list - update - delete +- search v2 TASKS COMPLETED: 1. Implemented the "list" command to display all stored products 2. Implemented the "update" command to modify product quantity 3. Implemented the "delete" command to remove a product +4. Implemented the "search" command to perform case-insensitive substring queries v1 -> v2 SUMMARY: - v1 supported only initialization and adding products -- v2 adds full inventory management through list, update, and delete -- validation rules were clarified to improve consistency and usability - +- v2 adds full inventory management through list, update,, delete, and case-insensitive search logic. diff --git a/problems/miniinventory/SPEC-v3.txt b/problems/miniinventory/SPEC-v3.txt deleted file mode 100644 index 9e2fe95a..00000000 --- a/problems/miniinventory/SPEC-v3.txt +++ /dev/null @@ -1,193 +0,0 @@ -PROJECT: mini-inventory -AUTHOR: Tunahan Caner YILDIZ (251478112) -VERSION: v3 -DATE: 2026-04-19 - -======================================== -OVERVIEW -======================================== - -mini-inventory is a command-line inventory manager. -It stores product records in a plain text file and supports -initializing the system, adding products, listing products, -updating stock quantities, deleting products, and searching products. - -All data is stored in a directory called .miniinventory/ -in the current working directory. - -======================================== -COMMANDS -======================================== - ---- init --- -Usage: miniinventory init - -Creates a .miniinventory/ directory and an empty inventory.dat file. -If .miniinventory/ already exists, print "Already initialized" and exit. - -Output: -- Success: "Initialized empty mini-inventory in .miniinventory/" -- Error: "Already initialized" - ---- add --- -Usage: miniinventory add "Pencil" 50 - -Appends a new product to inventory.dat. -Each product has: -- id (auto-increment) -- name -- quantity -- created_date - -Validation rules: -- Quantity must be a non-negative integer -- Product name must not be empty or whitespace only -- Product name must be unique in the inventory - -Output: -- Success: "Added product #: ()" -- Error if system is not initialized: - "Not initialized. Run: miniinventory init" -- Error if quantity is invalid: - "Invalid quantity" -- Error if product with the same name already exists: - "Product already exists" -- Error if name is empty or only whitespace: - "Invalid product name" -- Error if arguments are missing: - "Usage: miniinventory add " - ---- list --- -Usage: miniinventory list - -Prints all products, one per line, in this format: -[1] Pencil - Quantity: 50 (2026-03-15) -[2] Notebook - Quantity: 20 (2026-03-15) - -Listing rules: -- Products are listed in ascending order by ID -- Each stored product is printed on its own line -- If no products exist, print "No products found." - -Output: -- Success: prints all products in the required format -- Error if system is not initialized: - "Not initialized. Run: miniinventory init" -- Output if inventory is empty: - "No products found." - ---- update --- -Usage: miniinventory update 1 80 - -Updates the quantity of product #1 to 80. -The given quantity must be a non-negative integer. - -Output: -- Success: "Product #1 updated to quantity 80." -- Error if product does not exist: - "Product #1 not found." -- Error if quantity is invalid: - "Invalid quantity" -- Error if arguments are missing: - "Usage: miniinventory update " -- Error if system is not initialized: - "Not initialized. Run: miniinventory init" - ---- delete --- -Usage: miniinventory delete 1 - -Removes product #1 from inventory.dat. - -Output: -- Success: "Deleted product #1." -- Error if product does not exist: - "Product #1 not found." -- Error if arguments are missing: - "Usage: miniinventory delete " -- Error if system is not initialized: - "Not initialized. Run: miniinventory init" - ---- search --- -Usage: miniinventory search "Pen" - -Searches for products whose name contains the search query. - -Validation and filtering rules: -- The search must be case-insensitive (e.g., searching "pEn" must find "Pencil"). -- Products must be listed in ascending order by ID, matching the exact format of 'list'. -- The query can be a substring anywhere in the product name. - -Output: -- Success matches: - [1] Pencil - Quantity: 50 (2026-03-15) - [3] Blue Pen - Quantity: 10 (2026-03-15) -- No matches found: - "No products match the search." -- Error if arguments are missing: - "Usage: miniinventory search " -- Error if system is not initialized: - "Not initialized. Run: miniinventory init" - -======================================== -DATA FORMAT -======================================== - -File: .miniinventory/inventory.dat - -Format: -One product per line, fields separated by | - -Fields: -id|name|quantity|created_date - -Example: -1|Pencil|50|2026-03-15 -2|Notebook|20|2026-03-15 - -ID RULES: -- IDs start from 1 -- Each new product gets the next highest ID -- Deleted IDs are NOT reused - -======================================== -ERROR HANDLING -======================================== - -- Running any command before "init": - print "Not initialized. Run: miniinventory init" - -- Invalid command: - print "Unknown command: " - -- Missing main command: - print "Usage: miniinventory [args]" - -- Invalid quantity: - print "Invalid quantity" - -- Invalid product name: - print "Invalid product name" - -- Duplicate product name: - print "Product already exists" - -======================================== -VERSION v3 SCOPE -======================================== - -The v3 implementation expands the v2 tool with powerful data filtering. - -Implemented commands: -- init -- add -- list -- update -- delete -- search - -v3 TASKS COMPLETED: -1. Implemented the "search" command to perform case-insensitive substring queries on product names. - -v2 -> v3 SUMMARY: -- v2 supported full CRUD capabilities -- v3 adds case-insensitive search capability to dynamically filter the listing output diff --git a/problems/miniinventory/problem.json b/problems/miniinventory/problem.json index 6f3b2d08..a607efbd 100644 --- a/problems/miniinventory/problem.json +++ b/problems/miniinventory/problem.json @@ -6,8 +6,5 @@ "v1_prompt": "Implement {{binary_name}} as described in SPEC-v1.txt using {{language}}. The executable must be named '{{binary_name}}' and be runnable as ./{{binary_name}}. For compiled languages, include a Makefile or build script. For interpreted languages, ensure the {{binary_name}} file has a proper shebang line and is executable. Verify your implementation passes all tests by running: bash test-v1.sh", "v2_spec": "SPEC-v2.txt", "v2_test": "test-v2.sh", - "v2_prompt": "Read SPEC-v2.txt and extend the existing {{binary_name}} implementation. Update the code to implement list, update, and delete commands. Verify your implementation passes all tests by running: bash test-v2.sh", - "v3_spec": "SPEC-v3.txt", - "v3_test": "test-v3.sh", - "v3_prompt": "Read SPEC-v3.txt and extend the existing {{binary_name}} implementation. Update the code to implement the new 'search' command with case-insensitive filtering. Verify your implementation passes all tests by running: bash test-v3.sh" + "v2_prompt": "Read SPEC-v2.txt and extend the existing {{binary_name}} implementation. Update the code to implement list, update, delete, and search commands. Verify your implementation passes all tests by running: bash test-v2.sh" } \ No newline at end of file diff --git a/problems/miniinventory/test-v2.sh b/problems/miniinventory/test-v2.sh index 74c5487e..da89fed1 100644 --- a/problems/miniinventory/test-v2.sh +++ b/problems/miniinventory/test-v2.sh @@ -60,6 +60,7 @@ if ../miniinventory add Pencil 50 2>&1 | grep -q "Not initialized"; then pass "a if ../miniinventory list 2>&1 | grep -q "Not initialized"; then pass "list before init"; else fail "list before init"; fi if ../miniinventory update 1 80 2>&1 | grep -q "Not initialized"; then pass "update before init"; else fail "update before init"; fi if ../miniinventory delete 1 2>&1 | grep -q "Not initialized"; then pass "delete before init"; else fail "delete before init"; fi +if ../miniinventory search Pen 2>&1 | grep -q "Not initialized"; then pass "search before init"; else fail "search before init"; fi ###################################### # Test 3: add and duplicate check @@ -164,7 +165,42 @@ else fi ###################################### -# Test 8: unknown/missing command +# Test 8: search product +###################################### +rm -rf .miniinventory +../miniinventory init >/dev/null 2>&1 +../miniinventory add Pencil 50 >/dev/null 2>&1 +../miniinventory add Notebook 20 >/dev/null 2>&1 +../miniinventory add "Blue Pen" 10 >/dev/null 2>&1 + +OUTPUT=$(../miniinventory search "Notebook" 2>&1) +if echo "$OUTPUT" | grep -q "\[2\] Notebook - Quantity: 20" && ! echo "$OUTPUT" | grep -q "Pencil"; then + pass "search finds exact match" +else + fail "search finds exact match" +fi + +OUTPUT=$(../miniinventory search "pEn" 2>&1) +if echo "$OUTPUT" | grep -q "\[1\] Pencil" && echo "$OUTPUT" | grep -q "\[3\] Blue Pen" && ! echo "$OUTPUT" | grep -q "Notebook"; then + pass "search is case insensitive and finds multiple" +else + fail "search is case insensitive and finds multiple" +fi + +if ../miniinventory search "NotExists" 2>&1 | grep -q "No products match the search."; then + pass "search no match" +else + fail "search no match" +fi + +if ../miniinventory search 2>&1 | grep -q "Usage"; then + pass "search missing arguments" +else + fail "search missing arguments" +fi + +###################################### +# Test 9: unknown/missing command ###################################### if ../miniinventory fly 2>&1 | grep -q "Unknown command: fly"; then pass "unknown command" diff --git a/problems/miniinventory/test-v3.sh b/problems/miniinventory/test-v3.sh deleted file mode 100644 index da89fed1..00000000 --- a/problems/miniinventory/test-v3.sh +++ /dev/null @@ -1,236 +0,0 @@ -#!/usr/bin/env bash -set -e - -PASS_COUNT=0 -FAIL_COUNT=0 - -fail() { - echo "FAIL: $1" - FAIL_COUNT=$((FAIL_COUNT+1)) -} - -pass() { - echo "PASS: $1" - PASS_COUNT=$((PASS_COUNT+1)) -} - -cleanup() { - cd "$(dirname "$0")" - rm -rf testrepo -} - -# Build if needed -cd "$(dirname "$0")" - -if [ -f Makefile ] || [ -f makefile ]; then - make -s 2>/dev/null || true -fi -if [ -f build.sh ]; then - bash build.sh 2>/dev/null || true -fi -chmod +x miniinventory 2>/dev/null || true - -###################################### -# Setup -###################################### - -cleanup -mkdir testrepo -cd testrepo - -###################################### -# Test 1: init -###################################### -if ../miniinventory init && [ -d .miniinventory ] && [ -f .miniinventory/inventory.dat ]; then - OUTPUT=$(../miniinventory init 2>&1 || true) - if echo "$OUTPUT" | grep -q "Already initialized"; then - pass "init creates directory and handles duplicate" - else - fail "init creates directory and handles duplicate (duplicate missing)" - fi -else - fail "init creates directory and handles duplicate (dir missing)" -fi - -###################################### -# Test 2: before init errors -###################################### -rm -rf .miniinventory -if ../miniinventory add Pencil 50 2>&1 | grep -q "Not initialized"; then pass "add before init"; else fail "add before init"; fi -if ../miniinventory list 2>&1 | grep -q "Not initialized"; then pass "list before init"; else fail "list before init"; fi -if ../miniinventory update 1 80 2>&1 | grep -q "Not initialized"; then pass "update before init"; else fail "update before init"; fi -if ../miniinventory delete 1 2>&1 | grep -q "Not initialized"; then pass "delete before init"; else fail "delete before init"; fi -if ../miniinventory search Pen 2>&1 | grep -q "Not initialized"; then pass "search before init"; else fail "search before init"; fi - -###################################### -# Test 3: add and duplicate check -###################################### -../miniinventory init >/dev/null 2>&1 -../miniinventory add Pencil 50 >/dev/null 2>&1 -if ../miniinventory add Pencil 30 2>&1 | grep -q "Product already exists"; then - pass "add duplicate product fails" -else - fail "add duplicate product fails" -fi - -if ../miniinventory add " " 10 2>&1 | grep -q "Invalid product name"; then - pass "add invalid name fails" -else - fail "add invalid name fails" -fi - -if ../miniinventory add Pencil 2>&1 | grep -q "Usage"; then - pass "add missing arguments" -else - fail "add missing arguments" -fi - -###################################### -# Test 4: list products -###################################### -../miniinventory add Notebook 20 >/dev/null 2>&1 -OUTPUT=$(../miniinventory list 2>&1) -if echo "$OUTPUT" | grep -q "\[1\] Pencil - Quantity: 50" && echo "$OUTPUT" | grep -q "\[2\] Notebook - Quantity: 20"; then - pass "list shows products" -else - fail "list shows products" -fi - -###################################### -# Test 5: list empty -###################################### -rm -rf .miniinventory -../miniinventory init >/dev/null 2>&1 -if ../miniinventory list 2>&1 | grep -q "No products found"; then - pass "list empty inventory" -else - fail "list empty inventory" -fi - -###################################### -# Test 6: update product -###################################### -../miniinventory add Pencil 50 >/dev/null 2>&1 -if ../miniinventory update 1 80 2>&1 | grep -q "Product #1 updated to quantity 80"; then - pass "update product success" -else - fail "update product success" -fi - -if ../miniinventory update 1 -1 2>&1 | grep -q "Invalid quantity"; then - pass "update invalid quantity fails" -else - fail "update invalid quantity fails" -fi - -if ../miniinventory update 99 80 2>&1 | grep -q "Product #99 not found"; then - pass "update missing product fails" -else - fail "update missing product fails" -fi - -if ../miniinventory update 1 2>&1 | grep -q "Usage"; then - pass "update missing arguments" -else - fail "update missing arguments" -fi - -###################################### -# Test 7: delete product & ID reuse -###################################### -../miniinventory add Notebook 20 >/dev/null 2>&1 -if ../miniinventory delete 1 2>&1 | grep -q "Deleted product #1"; then - pass "delete product success" -else - fail "delete product success" -fi - -if ../miniinventory delete 99 2>&1 | grep -q "Product #99 not found"; then - pass "delete missing product fails" -else - fail "delete missing product fails" -fi - -if ../miniinventory delete 2>&1 | grep -q "Usage"; then - pass "delete missing arguments" -else - fail "delete missing arguments" -fi - -# ID check (new product should be #3 since 1 was deleted, 2 exists) -if ../miniinventory add Eraser 10 2>&1 | grep -q "Added product #3: Eraser (10)"; then - pass "deleted IDs are not reused" -else - fail "deleted IDs are not reused" -fi - -###################################### -# Test 8: search product -###################################### -rm -rf .miniinventory -../miniinventory init >/dev/null 2>&1 -../miniinventory add Pencil 50 >/dev/null 2>&1 -../miniinventory add Notebook 20 >/dev/null 2>&1 -../miniinventory add "Blue Pen" 10 >/dev/null 2>&1 - -OUTPUT=$(../miniinventory search "Notebook" 2>&1) -if echo "$OUTPUT" | grep -q "\[2\] Notebook - Quantity: 20" && ! echo "$OUTPUT" | grep -q "Pencil"; then - pass "search finds exact match" -else - fail "search finds exact match" -fi - -OUTPUT=$(../miniinventory search "pEn" 2>&1) -if echo "$OUTPUT" | grep -q "\[1\] Pencil" && echo "$OUTPUT" | grep -q "\[3\] Blue Pen" && ! echo "$OUTPUT" | grep -q "Notebook"; then - pass "search is case insensitive and finds multiple" -else - fail "search is case insensitive and finds multiple" -fi - -if ../miniinventory search "NotExists" 2>&1 | grep -q "No products match the search."; then - pass "search no match" -else - fail "search no match" -fi - -if ../miniinventory search 2>&1 | grep -q "Usage"; then - pass "search missing arguments" -else - fail "search missing arguments" -fi - -###################################### -# Test 9: unknown/missing command -###################################### -if ../miniinventory fly 2>&1 | grep -q "Unknown command: fly"; then - pass "unknown command" -else - fail "unknown command" -fi - -if ../miniinventory 2>&1 | grep -q "Usage"; then - pass "missing command" -else - fail "missing command" -fi - -###################################### -# Cleanup & Summary -###################################### - -cd .. -rm -rf testrepo - -echo "" -echo "========================" -echo "PASSED: $PASS_COUNT" -echo "FAILED: $FAIL_COUNT" -echo "TOTAL: $((PASS_COUNT + FAIL_COUNT))" -echo "========================" - -if [ "$FAIL_COUNT" -eq 0 ]; then - echo "ALL TESTS PASSED" - exit 0 -else - exit 1 -fi