update 'test bench'
Authored by
mfwolffe <wolffemf@dukes.jmu.edu>
- SHA
cceeb7cbe5131ef4fa945b26770614b76427cebe- Parents
-
63d0695 - Tree
643ed62
cceeb7c
cceeb7cbe5131ef4fa945b26770614b76427cebe63d0695
643ed62| Status | File | + | - |
|---|---|---|---|
| M |
test_shtick.py
|
212 | 14 |
| D |
test_shtick.sh
|
0 | 236 |
test_shtick.pymodified@@ -1,7 +1,7 @@ | ||
| 1 | 1 | #!/usr/bin/env python3 |
| 2 | 2 | """ |
| 3 | -test_shtick_fixed.py - Comprehensive test suite for shtick commands | |
| 4 | -Fixed to handle interactive prompts | |
| 3 | +test_shtick_enhanced.py - Comprehensive test suite for shtick commands | |
| 4 | +Enhanced with backup and group management tests | |
| 5 | 5 | """ |
| 6 | 6 | |
| 7 | 7 | import subprocess |
@@ -58,6 +58,9 @@ class ShtickTester: | ||
| 58 | 58 | """Set up test environment""" |
| 59 | 59 | self.test_dir = tempfile.mkdtemp(prefix="shtick_test_") |
| 60 | 60 | os.environ["HOME"] = self.test_dir |
| 61 | + os.environ["SHTICK_ORIGINAL_HOME"] = ( | |
| 62 | + self.original_home | |
| 63 | + ) # For security.py to work | |
| 61 | 64 | os.makedirs(os.path.join(self.test_dir, ".config", "shtick"), exist_ok=True) |
| 62 | 65 | |
| 63 | 66 | # Create a settings file that disables auto_source_prompt to avoid timeouts |
@@ -86,6 +89,7 @@ interactive_mode = false | ||
| 86 | 89 | os.environ["HOME"] = self.original_home |
| 87 | 90 | else: |
| 88 | 91 | os.environ.pop("HOME", None) |
| 92 | + os.environ.pop("SHTICK_ORIGINAL_HOME", None) | |
| 89 | 93 | |
| 90 | 94 | def run_command(self, args, input_text=None, env_override=None): |
| 91 | 95 | """Run a shtick command and return (output, return_code)""" |
@@ -97,6 +101,7 @@ interactive_mode = false | ||
| 97 | 101 | |
| 98 | 102 | # Always ensure we're using our test HOME |
| 99 | 103 | env["HOME"] = self.test_dir |
| 104 | + env["SHTICK_ORIGINAL_HOME"] = self.original_home # For security.py | |
| 100 | 105 | |
| 101 | 106 | try: |
| 102 | 107 | # For commands that might prompt, always provide 'n' as input |
@@ -128,6 +133,8 @@ interactive_mode = false | ||
| 128 | 133 | description, |
| 129 | 134 | input_text=None, |
| 130 | 135 | env_override=None, |
| 136 | + check_output=None, | |
| 137 | + check_not_output=None, | |
| 131 | 138 | ): |
| 132 | 139 | """Run a test and check the result""" |
| 133 | 140 | self.tests_run += 1 |
@@ -136,12 +143,28 @@ interactive_mode = false | ||
| 136 | 143 | |
| 137 | 144 | output, actual_status = self.run_command(args, input_text, env_override) |
| 138 | 145 | |
| 139 | - if actual_status == expected_status: | |
| 146 | + # Check status code | |
| 147 | + status_ok = actual_status == expected_status | |
| 148 | + | |
| 149 | + # Check output if requested | |
| 150 | + output_ok = True | |
| 151 | + if check_output is not None: | |
| 152 | + output_ok = check_output in output | |
| 153 | + if check_not_output is not None and output_ok: | |
| 154 | + output_ok = check_not_output not in output | |
| 155 | + | |
| 156 | + if status_ok and output_ok: | |
| 140 | 157 | print(f"{GREEN}PASS{NC}") |
| 141 | 158 | self.tests_passed += 1 |
| 142 | 159 | else: |
| 143 | 160 | print(f"{RED}FAIL{NC}") |
| 144 | - print(f" Expected status: {expected_status}, Got: {actual_status}") | |
| 161 | + if not status_ok: | |
| 162 | + print(f" Expected status: {expected_status}, Got: {actual_status}") | |
| 163 | + if not output_ok: | |
| 164 | + if check_output is not None: | |
| 165 | + print(f" Expected output to contain: {check_output}") | |
| 166 | + if check_not_output is not None: | |
| 167 | + print(f" Expected output NOT to contain: {check_not_output}") | |
| 145 | 168 | print(f" Command: {' '.join(self.shtick_cmd + args)}") |
| 146 | 169 | print(f" Output: {output[:500]}...") # Truncate long output |
| 147 | 170 | self.tests_failed += 1 |
@@ -162,7 +185,7 @@ interactive_mode = false | ||
| 162 | 185 | def run_all_tests(self): |
| 163 | 186 | """Run all tests""" |
| 164 | 187 | print("===================================") |
| 165 | - print("Shtick Command Test Suite (Python)") | |
| 188 | + print("Shtick Command Test Suite (Enhanced)") | |
| 166 | 189 | print("===================================\n") |
| 167 | 190 | |
| 168 | 191 | self.setup() |
@@ -238,7 +261,7 @@ interactive_mode = false | ||
| 238 | 261 | "deactivate-inactive", |
| 239 | 262 | ["deactivate", "work"], |
| 240 | 263 | 0, |
| 241 | - "Deactivate already inactive group", | |
| 264 | + "Deactivate already inactive group (idempotent)", | |
| 242 | 265 | ) |
| 243 | 266 | |
| 244 | 267 | # Test 5: Remove operations - provide input for selection |
@@ -254,7 +277,7 @@ interactive_mode = false | ||
| 254 | 277 | "remove-nonexistent", |
| 255 | 278 | ["remove-persistent", "alias", "nonexistent"], |
| 256 | 279 | 0, |
| 257 | - "Remove non-existent item", | |
| 280 | + "Remove non-existent item (no-op)", | |
| 258 | 281 | ) |
| 259 | 282 | |
| 260 | 283 | # Re-add for next test |
@@ -408,23 +431,198 @@ interactive_mode = false | ||
| 408 | 431 | |
| 409 | 432 | # Test 13: Backup functionality |
| 410 | 433 | print(f"\n{YELLOW}Testing backup functionality:{NC}") |
| 434 | + # Add some content first | |
| 435 | + self.run_command(["alias", "backup_test=echo backup"]) | |
| 411 | 436 | self.test_command("backup-create", ["backup", "create"], 0, "Create backup") |
| 437 | + self.test_command( | |
| 438 | + "backup-create-named", | |
| 439 | + ["backup", "create", "-n", "test_backup"], | |
| 440 | + 0, | |
| 441 | + "Create named backup", | |
| 442 | + ) | |
| 412 | 443 | self.test_command("backup-list", ["backup", "list"], 0, "List backups") |
| 413 | 444 | |
| 414 | - # Test 14: Group management | |
| 415 | - print(f"\n{YELLOW}Testing group management:{NC}") | |
| 445 | + # Modify config | |
| 446 | + self.run_command(["alias", "after_backup=echo after"]) | |
| 447 | + | |
| 448 | + # Restore and verify | |
| 449 | + self.test_command( | |
| 450 | + "backup-restore", | |
| 451 | + ["backup", "restore", "test_backup"], | |
| 452 | + 0, | |
| 453 | + "Restore from backup", | |
| 454 | + ) | |
| 455 | + | |
| 456 | + # Verify restore worked by checking if the new alias is gone | |
| 457 | + output, _ = self.run_command(["list"]) | |
| 458 | + if "after_backup" not in output: | |
| 459 | + print( | |
| 460 | + f"[{self.tests_run + 1}] verify-restore: Backup restore worked correctly ... {GREEN}PASS{NC}" | |
| 461 | + ) | |
| 462 | + self.tests_passed += 1 | |
| 463 | + else: | |
| 464 | + print( | |
| 465 | + f"[{self.tests_run + 1}] verify-restore: Backup restore failed ... {RED}FAIL{NC}" | |
| 466 | + ) | |
| 467 | + self.tests_failed += 1 | |
| 468 | + self.tests_run += 1 | |
| 469 | + | |
| 470 | + # Test 14: Group management - NOW WITH REAL FUNCTIONALITY! | |
| 471 | + print(f"\n{YELLOW}Testing group management (enhanced):{NC}") | |
| 472 | + | |
| 473 | + # Test creating a new group | |
| 474 | + self.test_command( | |
| 475 | + "group-create", | |
| 476 | + ["group", "create", "testgroup"], | |
| 477 | + 0, | |
| 478 | + "Create new group", | |
| 479 | + check_output="✓ Created group 'testgroup'", | |
| 480 | + check_not_output="will be created when you add", | |
| 481 | + ) | |
| 482 | + | |
| 483 | + # Verify the group exists in status | |
| 484 | + output, _ = self.run_command(["status"]) | |
| 485 | + if "testgroup: 0 items" in output: | |
| 486 | + print( | |
| 487 | + f"[{self.tests_run + 1}] verify-group-exists: Created group shows in status ... {GREEN}PASS{NC}" | |
| 488 | + ) | |
| 489 | + self.tests_passed += 1 | |
| 490 | + else: | |
| 491 | + print( | |
| 492 | + f"[{self.tests_run + 1}] verify-group-exists: Created group should show in status ... {RED}FAIL{NC}" | |
| 493 | + ) | |
| 494 | + print(f" Status output: {output}") | |
| 495 | + self.tests_failed += 1 | |
| 496 | + self.tests_run += 1 | |
| 497 | + | |
| 498 | + # Verify we can activate the empty group | |
| 499 | + self.test_command( | |
| 500 | + "activate-empty-group", | |
| 501 | + ["activate", "testgroup"], | |
| 502 | + 0, | |
| 503 | + "Activate empty group", | |
| 504 | + ) | |
| 505 | + | |
| 506 | + # Verify the group shows as active | |
| 507 | + output, _ = self.run_command(["status"]) | |
| 508 | + if "testgroup: 0 items (ACTIVE)" in output: | |
| 509 | + print( | |
| 510 | + f"[{self.tests_run + 1}] verify-group-active: Empty group shows as active ... {GREEN}PASS{NC}" | |
| 511 | + ) | |
| 512 | + self.tests_passed += 1 | |
| 513 | + else: | |
| 514 | + print( | |
| 515 | + f"[{self.tests_run + 1}] verify-group-active: Empty group should show as active ... {RED}FAIL{NC}" | |
| 516 | + ) | |
| 517 | + print(f" Status output: {output}") | |
| 518 | + self.tests_failed += 1 | |
| 519 | + self.tests_run += 1 | |
| 520 | + | |
| 521 | + # Test adding to the newly created group | |
| 522 | + self.test_command( | |
| 523 | + "add-to-created-group", | |
| 524 | + ["add", "alias", "testgroup", "tg=echo testgroup"], | |
| 525 | + 0, | |
| 526 | + "Add item to newly created group", | |
| 527 | + ) | |
| 528 | + | |
| 529 | + # Verify the group now has 1 item | |
| 530 | + output, _ = self.run_command(["status"]) | |
| 531 | + if "testgroup: 1 items (ACTIVE)" in output: | |
| 532 | + print( | |
| 533 | + f"[{self.tests_run + 1}] verify-group-has-item: Group shows 1 item after add ... {GREEN}PASS{NC}" | |
| 534 | + ) | |
| 535 | + self.tests_passed += 1 | |
| 536 | + else: | |
| 537 | + print( | |
| 538 | + f"[{self.tests_run + 1}] verify-group-has-item: Group should show 1 item ... {RED}FAIL{NC}" | |
| 539 | + ) | |
| 540 | + print(f" Status output: {output}") | |
| 541 | + self.tests_failed += 1 | |
| 542 | + self.tests_run += 1 | |
| 543 | + | |
| 544 | + # Test creating duplicate group | |
| 416 | 545 | self.test_command( |
| 417 | - "group-create", ["group", "create", "testgroup"], 0, "Create new group" | |
| 546 | + "group-create-duplicate", | |
| 547 | + ["group", "create", "testgroup"], | |
| 548 | + 1, | |
| 549 | + "Cannot create duplicate group", | |
| 550 | + check_output="already exists", | |
| 418 | 551 | ) |
| 552 | + | |
| 553 | + # Check the TOML file contains empty sections | |
| 554 | + config_path = os.path.join( | |
| 555 | + self.test_dir, ".config", "shtick", "config.toml" | |
| 556 | + ) | |
| 557 | + if os.path.exists(config_path): | |
| 558 | + with open(config_path, "r") as f: | |
| 559 | + toml_content = f.read() | |
| 560 | + # Check for either nested format (with tomli_w) or flat format (fallback) | |
| 561 | + has_nested = ( | |
| 562 | + "[testgroup]" in toml_content | |
| 563 | + and "[testgroup.aliases]" in toml_content | |
| 564 | + ) | |
| 565 | + has_flat = "[testgroup.aliases]" in toml_content | |
| 566 | + if has_nested or has_flat: | |
| 567 | + print( | |
| 568 | + f"[{self.tests_run + 1}] verify-toml-structure: TOML has proper empty group structure ... {GREEN}PASS{NC}" | |
| 569 | + ) | |
| 570 | + self.tests_passed += 1 | |
| 571 | + else: | |
| 572 | + print( | |
| 573 | + f"[{self.tests_run + 1}] verify-toml-structure: TOML should have empty group sections ... {RED}FAIL{NC}" | |
| 574 | + ) | |
| 575 | + print(f" TOML content:\n{toml_content[:500]}") | |
| 576 | + self.tests_failed += 1 | |
| 577 | + self.tests_run += 1 | |
| 578 | + | |
| 579 | + # Still test unimplemented features | |
| 419 | 580 | self.test_command( |
| 420 | 581 | "group-rename", |
| 421 | 582 | ["group", "rename", "testgroup", "newgroup"], |
| 422 | - 0, | |
| 423 | - "Rename group", | |
| 583 | + 1, | |
| 584 | + "Rename group (not implemented)", | |
| 585 | + check_output="not yet implemented", | |
| 424 | 586 | ) |
| 425 | 587 | self.test_command( |
| 426 | - "group-remove", ["group", "remove", "newgroup", "-f"], 0, "Remove group" | |
| 588 | + "group-remove", | |
| 589 | + ["group", "remove", "testgroup", "-f"], | |
| 590 | + 1, | |
| 591 | + "Remove group (not implemented)", | |
| 592 | + check_output="not yet implemented", | |
| 593 | + ) | |
| 594 | + | |
| 595 | + # Test 15: Exit code consistency | |
| 596 | + print(f"\n{YELLOW}Testing exit code consistency:{NC}") | |
| 597 | + # Test that user cancellation uses exit code 2 | |
| 598 | + output, status = self.run_command( | |
| 599 | + ["settings", "init"], input_text="\x03" | |
| 600 | + ) # Ctrl+C | |
| 601 | + if status == 2 or "Cancelled" in output: | |
| 602 | + print( | |
| 603 | + f"[{self.tests_run + 1}] user-cancel-exit-code: User cancellation returns code 2 ... {GREEN}PASS{NC}" | |
| 604 | + ) | |
| 605 | + self.tests_passed += 1 | |
| 606 | + else: | |
| 607 | + print( | |
| 608 | + f"[{self.tests_run + 1}] user-cancel-exit-code: User cancellation should return code 2 ... {RED}FAIL{NC}" | |
| 609 | + ) | |
| 610 | + print(f" Got status: {status}, output: {output}") | |
| 611 | + self.tests_failed += 1 | |
| 612 | + self.tests_run += 1 | |
| 613 | + | |
| 614 | + # Test 16: No-output commands should still exit properly | |
| 615 | + print(f"\n{YELLOW}Testing commands with no output still exit properly:{NC}") | |
| 616 | + # Create an empty config scenario | |
| 617 | + empty_dir = tempfile.mkdtemp() | |
| 618 | + self.test_command( | |
| 619 | + "list-empty-explicit-exit", | |
| 620 | + ["list"], | |
| 621 | + 0, | |
| 622 | + "List with empty config exits 0", | |
| 623 | + env_override={"HOME": empty_dir}, | |
| 427 | 624 | ) |
| 625 | + shutil.rmtree(empty_dir) | |
| 428 | 626 | |
| 429 | 627 | finally: |
| 430 | 628 | self.cleanup() |
@@ -449,7 +647,7 @@ def main(): | ||
| 449 | 647 | """Run the test suite""" |
| 450 | 648 | # Check if we should run in non-interactive mode |
| 451 | 649 | if len(sys.argv) > 1 and sys.argv[1] == "--help": |
| 452 | - print("Usage: test_shtick_fixed.py") | |
| 650 | + print("Usage: test_shtick_enhanced.py") | |
| 453 | 651 | print("Run comprehensive tests for shtick command line tool") |
| 454 | 652 | return 0 |
| 455 | 653 | |
test_shtick.shdeleted@@ -1,236 +0,0 @@ | ||
| 1 | -#!/bin/bash | |
| 2 | -# test_shtick_fixed.sh - Test suite for shtick commands with proper PATH handling | |
| 3 | - | |
| 4 | -set -e # Exit on error | |
| 5 | - | |
| 6 | -# Colors for output | |
| 7 | -RED='\033[0;31m' | |
| 8 | -GREEN='\033[0;32m' | |
| 9 | -YELLOW='\033[1;33m' | |
| 10 | -NC='\033[0m' # No Color | |
| 11 | - | |
| 12 | -# Test counters | |
| 13 | -TESTS_RUN=0 | |
| 14 | -TESTS_PASSED=0 | |
| 15 | -TESTS_FAILED=0 | |
| 16 | - | |
| 17 | -# Test config directory | |
| 18 | -TEST_DIR="/tmp/shtick_test_$$" | |
| 19 | -export HOME="$TEST_DIR" | |
| 20 | -CONFIG_DIR="$TEST_DIR/.config/shtick" | |
| 21 | - | |
| 22 | -# Find shtick command - try multiple approaches | |
| 23 | -find_shtick() { | |
| 24 | - # Method 1: Check if shtick is in PATH | |
| 25 | - if command -v shtick >/dev/null 2>&1; then | |
| 26 | - SHTICK_CMD="shtick" | |
| 27 | - echo "Found shtick in PATH: $(command -v shtick)" | |
| 28 | - return 0 | |
| 29 | - fi | |
| 30 | - | |
| 31 | - # Method 2: Check if we're in development directory with cli.py | |
| 32 | - if [ -f "./shtick/cli.py" ]; then | |
| 33 | - SHTICK_CMD="python -m shtick.cli" | |
| 34 | - echo "Found shtick module in current directory, using: $SHTICK_CMD" | |
| 35 | - return 0 | |
| 36 | - fi | |
| 37 | - | |
| 38 | - # Method 3: Check parent directory | |
| 39 | - if [ -f "../shtick/cli.py" ]; then | |
| 40 | - SHTICK_CMD="python -m shtick.cli" | |
| 41 | - echo "Found shtick module in parent directory" | |
| 42 | - cd .. | |
| 43 | - return 0 | |
| 44 | - fi | |
| 45 | - | |
| 46 | - # Method 4: Try direct python execution | |
| 47 | - if [ -f "cli.py" ]; then | |
| 48 | - SHTICK_CMD="python cli.py" | |
| 49 | - echo "Found cli.py in current directory, using: $SHTICK_CMD" | |
| 50 | - return 0 | |
| 51 | - fi | |
| 52 | - | |
| 53 | - echo "ERROR: Cannot find shtick command!" | |
| 54 | - echo "Please ensure either:" | |
| 55 | - echo " 1. shtick is installed and in your PATH" | |
| 56 | - echo " 2. You're running this from the shtick source directory" | |
| 57 | - echo " 3. The shtick package is properly installed with 'pip install -e .'" | |
| 58 | - exit 1 | |
| 59 | -} | |
| 60 | - | |
| 61 | -# Clean up function | |
| 62 | -cleanup() { | |
| 63 | - rm -rf "$TEST_DIR" | |
| 64 | -} | |
| 65 | -trap cleanup EXIT | |
| 66 | - | |
| 67 | -# Setup test environment | |
| 68 | -setup() { | |
| 69 | - rm -rf "$TEST_DIR" | |
| 70 | - mkdir -p "$CONFIG_DIR" | |
| 71 | - cd "$TEST_DIR" | |
| 72 | -} | |
| 73 | - | |
| 74 | -# Test function | |
| 75 | -test_command() { | |
| 76 | - local test_name="$1" | |
| 77 | - local command="$2" | |
| 78 | - local expected_status="$3" | |
| 79 | - local description="$4" | |
| 80 | - | |
| 81 | - TESTS_RUN=$((TESTS_RUN + 1)) | |
| 82 | - | |
| 83 | - echo -n "[$TESTS_RUN] $test_name: $description ... " | |
| 84 | - | |
| 85 | - # Replace 'shtick' with actual command | |
| 86 | - command="${command//shtick/$SHTICK_CMD}" | |
| 87 | - | |
| 88 | - # Run command and capture status | |
| 89 | - set +e | |
| 90 | - output=$(eval "$command" 2>&1) | |
| 91 | - actual_status=$? | |
| 92 | - set -e | |
| 93 | - | |
| 94 | - if [ $actual_status -eq $expected_status ]; then | |
| 95 | - echo -e "${GREEN}PASS${NC}" | |
| 96 | - TESTS_PASSED=$((TESTS_PASSED + 1)) | |
| 97 | - else | |
| 98 | - echo -e "${RED}FAIL${NC}" | |
| 99 | - echo " Expected status: $expected_status, Got: $actual_status" | |
| 100 | - echo " Command: $command" | |
| 101 | - echo " Output: $output" | |
| 102 | - TESTS_FAILED=$((TESTS_FAILED + 1)) | |
| 103 | - fi | |
| 104 | -} | |
| 105 | - | |
| 106 | -# Verify shtick is working | |
| 107 | -verify_shtick() { | |
| 108 | - echo "Verifying shtick command..." | |
| 109 | - set +e | |
| 110 | - output=$($SHTICK_CMD --help 2>&1) | |
| 111 | - status=$? | |
| 112 | - set -e | |
| 113 | - | |
| 114 | - if [ $status -ne 0 ]; then | |
| 115 | - echo -e "${RED}ERROR: shtick command not working!${NC}" | |
| 116 | - echo "Command: $SHTICK_CMD --help" | |
| 117 | - echo "Status: $status" | |
| 118 | - echo "Output: $output" | |
| 119 | - exit 1 | |
| 120 | - fi | |
| 121 | - echo -e "${GREEN}✓ shtick command verified${NC}" | |
| 122 | - echo | |
| 123 | -} | |
| 124 | - | |
| 125 | -# Header | |
| 126 | -echo "===================================" | |
| 127 | -echo "Shtick Command Test Suite" | |
| 128 | -echo "===================================" | |
| 129 | -echo | |
| 130 | - | |
| 131 | -# Find shtick command | |
| 132 | -find_shtick | |
| 133 | - | |
| 134 | -# Setup | |
| 135 | -setup | |
| 136 | - | |
| 137 | -# Verify shtick works | |
| 138 | -verify_shtick | |
| 139 | - | |
| 140 | -# Save original directory to return to later | |
| 141 | -ORIGINAL_DIR=$(pwd) | |
| 142 | - | |
| 143 | -# Test 1: Basic commands without config | |
| 144 | -echo -e "${YELLOW}Testing basic commands without config:${NC}" | |
| 145 | -test_command "status-no-config" "shtick status" 0 "Status should work without config" | |
| 146 | -test_command "list-no-config" "shtick list" 0 "List should work without config" | |
| 147 | -test_command "shells" "shtick shells" 0 "Shells command should always work" | |
| 148 | - | |
| 149 | -# Test 2: Adding items (creates config) | |
| 150 | -echo -e "\n${YELLOW}Testing add commands:${NC}" | |
| 151 | -test_command "add-alias" "shtick alias ll='ls -la'" 0 "Add persistent alias" | |
| 152 | -test_command "add-env" "shtick env DEBUG=1" 0 "Add persistent env var" | |
| 153 | -test_command "add-function" "shtick function greet='echo Hello'" 0 "Add persistent function" | |
| 154 | - | |
| 155 | -# Test 3: Invalid add commands | |
| 156 | -echo -e "\n${YELLOW}Testing invalid add commands:${NC}" | |
| 157 | -test_command "add-invalid-key" "shtick alias '123bad=value'" 1 "Invalid key should fail" | |
| 158 | -test_command "add-no-equals" "shtick alias 'no_equals_sign'" 1 "Missing = should fail" | |
| 159 | -test_command "add-empty-key" "shtick alias '=value'" 1 "Empty key should fail" | |
| 160 | -test_command "add-empty-value" "shtick alias 'key='" 1 "Empty value should fail" | |
| 161 | - | |
| 162 | -# Test 4: Group operations | |
| 163 | -echo -e "\n${YELLOW}Testing group operations:${NC}" | |
| 164 | -test_command "add-to-group" "shtick add alias work ll='ls -la'" 0 "Add to specific group" | |
| 165 | -test_command "activate-group" "shtick activate work" 0 "Activate existing group" | |
| 166 | -test_command "activate-nonexistent" "shtick activate nonexistent" 1 "Activate non-existent group should fail" | |
| 167 | -test_command "deactivate-group" "shtick deactivate work" 0 "Deactivate active group" | |
| 168 | -test_command "deactivate-inactive" "shtick deactivate work" 0 "Deactivate already inactive group" | |
| 169 | - | |
| 170 | -# Test 5: Remove operations | |
| 171 | -echo -e "\n${YELLOW}Testing remove operations:${NC}" | |
| 172 | -test_command "remove-existing" "echo 1 | shtick remove-persistent alias ll" 0 "Remove existing alias" | |
| 173 | -test_command "remove-nonexistent" "shtick remove-persistent alias nonexistent" 0 "Remove non-existent item" | |
| 174 | -test_command "remove-fuzzy" "echo 1 | shtick remove alias work ll" 0 "Remove with fuzzy match" | |
| 175 | - | |
| 176 | -# Test 6: Generate command | |
| 177 | -echo -e "\n${YELLOW}Testing generate command:${NC}" | |
| 178 | -test_command "generate-default" "shtick generate --terse" 0 "Generate with default config" | |
| 179 | -test_command "generate-custom" "shtick generate $CONFIG_DIR/config.toml --terse" 0 "Generate with custom config path" | |
| 180 | -test_command "generate-nonexistent" "shtick generate /tmp/nonexistent.toml" 1 "Generate with non-existent config should fail" | |
| 181 | - | |
| 182 | -# Test 7: Source command | |
| 183 | -echo -e "\n${YELLOW}Testing source command:${NC}" | |
| 184 | -test_command "source-bash" "SHELL=/bin/bash shtick source" 0 "Source command for bash" | |
| 185 | -test_command "source-no-shell" "SHELL= shtick source" 1 "Source without shell should fail" | |
| 186 | - | |
| 187 | -# Test 8: Settings commands | |
| 188 | -echo -e "\n${YELLOW}Testing settings commands:${NC}" | |
| 189 | -test_command "settings-show" "shtick settings show" 0 "Show settings" | |
| 190 | -test_command "settings-init" "shtick settings init" 0 "Initialize settings" | |
| 191 | -test_command "settings-set-bool" "shtick settings set behavior.auto_source_prompt false" 0 "Set boolean setting" | |
| 192 | -test_command "settings-set-invalid" "shtick settings set invalid.key value" 1 "Set invalid setting should fail" | |
| 193 | - | |
| 194 | -# Test 9: Edge cases | |
| 195 | -echo -e "\n${YELLOW}Testing edge cases:${NC}" | |
| 196 | -test_command "persistent-activate" "shtick activate persistent" 1 "Cannot activate persistent group" | |
| 197 | -test_command "persistent-deactivate" "shtick deactivate persistent" 1 "Cannot deactivate persistent group" | |
| 198 | -test_command "very-long-key" "shtick alias $(printf 'a%.0s' {1..65})=value" 1 "Key over 64 chars should fail" | |
| 199 | - | |
| 200 | -# Test 10: Special characters and escaping | |
| 201 | -echo -e "\n${YELLOW}Testing special characters:${NC}" | |
| 202 | -test_command "alias-with-quotes" "shtick alias msg='echo \"Hello World\"'" 0 "Alias with quotes" | |
| 203 | -test_command "alias-with-dollar" 'shtick alias home="cd \$HOME"' 0 "Alias with dollar sign" | |
| 204 | -test_command "multiline-function" 'shtick function hello="echo line1 | |
| 205 | -echo line2"' 0 "Multiline function" | |
| 206 | - | |
| 207 | -# Test 11: List and status with content | |
| 208 | -echo -e "\n${YELLOW}Testing list and status with content:${NC}" | |
| 209 | -test_command "list-with-content" "shtick list" 0 "List with items" | |
| 210 | -test_command "list-long-format" "shtick list -l" 0 "List in long format" | |
| 211 | -test_command "status-with-content" "shtick status" 0 "Status with configuration" | |
| 212 | - | |
| 213 | -# Test 12: Conflict handling | |
| 214 | -echo -e "\n${YELLOW}Testing conflict handling:${NC}" | |
| 215 | -test_command "add-conflict-alias" "shtick add alias temp ll='ls -lah'" 0 "Add conflicting alias to different group" | |
| 216 | -test_command "check-conflict-warning" "shtick alias ll='ls -la' 2>&1 | grep -q 'exists in groups'" 0 "Should warn about conflicts" | |
| 217 | - | |
| 218 | -# Return to original directory | |
| 219 | -cd "$ORIGINAL_DIR" | |
| 220 | - | |
| 221 | -# Summary | |
| 222 | -echo | |
| 223 | -echo "===================================" | |
| 224 | -echo "Test Summary" | |
| 225 | -echo "===================================" | |
| 226 | -echo "Tests run: $TESTS_RUN" | |
| 227 | -echo -e "Tests passed: ${GREEN}$TESTS_PASSED${NC}" | |
| 228 | -echo -e "Tests failed: ${RED}$TESTS_FAILED${NC}" | |
| 229 | - | |
| 230 | -if [ $TESTS_FAILED -eq 0 ]; then | |
| 231 | - echo -e "\n${GREEN}All tests passed!${NC}" | |
| 232 | - exit 0 | |
| 233 | -else | |
| 234 | - echo -e "\n${RED}Some tests failed!${NC}" | |
| 235 | - exit 1 | |
| 236 | -fi | |