#!/bin/bash set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Test counter TESTS_PASSED=0 TESTS_FAILED=0 # Function to run a test run_test() { local test_name="$1" local command="$2" local expected_exit_code="${3:-0}" echo -n "Testing $test_name... " # Run command and capture exit code set +e eval "$command" > /tmp/test_output.txt 2>&1 local exit_code=$? set -e if [ $exit_code -eq $expected_exit_code ]; then echo -e "${GREEN}PASSED${NC}" ((TESTS_PASSED++)) return 0 else echo -e "${RED}FAILED${NC}" echo " Expected exit code: $expected_exit_code, got: $exit_code" echo " Output:" cat /tmp/test_output.txt | sed 's/^/ /' ((TESTS_FAILED++)) return 1 fi } # Function to verify archive contents verify_archive_contents() { local archive="$1" local expected_files="$2" echo -n " Verifying contents of $archive... " if [[ "$archive" == *.tgz || "$archive" == *.tar.gz ]]; then actual_files=$(tar -tzf "$archive" | sort | tr '\n' ' ' | sed 's/ $//') elif [[ "$archive" == *.zip ]]; then actual_files=$(unzip -l "$archive" | grep -v "Archive:" | grep -v "Length" | grep -v -- "--------" | grep -v "files" | awk '{print $4}' | grep -v '^$' | sort | tr '\n' ' ' | sed 's/ $//') else echo -e "${RED}Unknown archive format${NC}" return 1 fi expected_sorted=$(echo "$expected_files" | tr ' ' '\n' | sort | tr '\n' ' ' | sed 's/ $//') if [ "$actual_files" = "$expected_sorted" ]; then echo -e "${GREEN}OK${NC}" return 0 else echo -e "${RED}FAILED${NC}" echo " Expected: $expected_sorted" echo " Got: $actual_files" return 1 fi } echo -e "${YELLOW}=== Collect CLI Test Suite ===${NC}\n" # Clean up any previous test artifacts echo "Cleaning up previous test artifacts..." rm -rf test test-*.tgz test-*.zip collect # Build the tool echo "Building collect tool..." if ! go build -o collect; then echo -e "${RED}Failed to build collect tool${NC}" exit 1 fi echo -e "${GREEN}Build successful${NC}\n" # Create test directory structure echo "Setting up test environment..." mkdir -p test/subdir/aet-bin test/subdir/aet-config test/other test/deep/nested/aet-tools echo "test config" > test/.mise.toml echo "another config" > test/subdir/.mise.toml echo "binary" > test/subdir/aet-bin/tool echo "config" > test/subdir/aet-config/settings.conf echo "other file" > test/other/file.txt echo "deep tool" > test/deep/nested/aet-tools/deep.sh echo "not in aet dir" > test/deep/nested/regular.txt echo -e "${GREEN}Test environment ready${NC}\n" # Test 1: Name matching with tar.gz run_test "name matching (.mise.toml) with tar.gz" \ "./collect --name .mise.toml test/ test-name.tgz" verify_archive_contents "test-name.tgz" ".mise.toml subdir/.mise.toml" # Test 2: Pattern matching with zip run_test "pattern matching (aet-*) with zip" \ "./collect --match 'aet-*' test/ test-pattern.zip" verify_archive_contents "test-pattern.zip" "subdir/aet-bin/tool subdir/aet-config/settings.conf deep/nested/aet-tools/deep.sh" # Test 3: Pattern matching with tgz run_test "pattern matching (aet-*) with tgz" \ "./collect --match 'aet-*' test/ test-pattern.tgz" verify_archive_contents "test-pattern.tgz" "deep/nested/aet-tools/deep.sh subdir/aet-bin/tool subdir/aet-config/settings.conf" # Test 4: No files found (should exit with code 1) run_test "no files found error" \ "./collect --name nonexistent.file test/ test-empty.zip" 1 # Test 5: Invalid arguments - no flags run_test "invalid arguments - no flags" \ "./collect test/ output.zip" 3 # Test 6: Invalid arguments - no positional args run_test "invalid arguments - no positional args" \ "./collect --name .mise.toml" 3 # Test 7: Invalid arguments - missing output file run_test "invalid arguments - missing output file" \ "./collect --name .mise.toml test/" 3 # Test 8: Invalid archive format run_test "invalid archive format" \ "./collect --name .mise.toml test/ output.txt" 3 # Test 9: Non-existent source directory run_test "non-existent source directory" \ "./collect --name .mise.toml nonexistent/ output.zip" 2 # Test 10: Help flag run_test "help flag output" \ "./collect --help" 0 # Test 11: Name matching with subdirectory pattern echo "subdir config" > test/subdir/aet-bin/.mise.toml run_test "name matching finds files in pattern dirs too" \ "./collect --name .mise.toml test/ test-name-all.tgz" verify_archive_contents "test-name-all.tgz" ".mise.toml subdir/.mise.toml subdir/aet-bin/.mise.toml" # Test 12: Multiple name flags echo "readme" > test/README.md echo "makefile" > test/Makefile echo "another makefile" > test/subdir/Makefile run_test "multiple name flags" \ "./collect --name .mise.toml --name README.md --name Makefile test/ test-multi-name.tgz" verify_archive_contents "test-multi-name.tgz" ".mise.toml Makefile README.md subdir/.mise.toml subdir/Makefile subdir/aet-bin/.mise.toml" # Test 13: Multiple match flags mkdir -p test/prefix-one test/prefix-two test/other-prefix echo "file1" > test/prefix-one/data.txt echo "file2" > test/prefix-two/config.yml echo "file3" > test/other-prefix/info.log run_test "multiple match flags" \ "./collect --match 'prefix-*' --match 'aet-*' test/ test-multi-match.tgz" verify_archive_contents "test-multi-match.tgz" "deep/nested/aet-tools/deep.sh prefix-one/data.txt prefix-two/config.yml subdir/aet-bin/.mise.toml subdir/aet-bin/tool subdir/aet-config/settings.conf" # Test 14: Combined name and match flags run_test "combined name and match flags" \ "./collect --name .mise.toml --match 'aet-*' --name README.md test/ test-combined.tgz" verify_archive_contents "test-combined.tgz" ".mise.toml README.md deep/nested/aet-tools/deep.sh subdir/.mise.toml subdir/aet-bin/.mise.toml subdir/aet-bin/tool subdir/aet-config/settings.conf" # Clean up echo -e "\nCleaning up..." rm -rf test test-*.tgz test-*.zip collect /tmp/test_output.txt # Summary echo -e "\n${YELLOW}=== Test Summary ===${NC}" echo -e "Tests passed: ${GREEN}$TESTS_PASSED${NC}" echo -e "Tests failed: ${RED}$TESTS_FAILED${NC}" if [ $TESTS_FAILED -eq 0 ]; then echo -e "\n${GREEN}All tests passed!${NC}" exit 0 else echo -e "\n${RED}Some tests failed!${NC}" exit 1 fi