Skip to content

Instantly share code, notes, and snippets.

@anthonyheckmann
Created December 6, 2024 17:50
Show Gist options
  • Select an option

  • Save anthonyheckmann/dd96ad5e863decfa531081d679c922c8 to your computer and use it in GitHub Desktop.

Select an option

Save anthonyheckmann/dd96ad5e863decfa531081d679c922c8 to your computer and use it in GitHub Desktop.

Revisions

  1. anthonyheckmann created this gist Dec 6, 2024.
    92 changes: 92 additions & 0 deletions dedupe_list_and_tests.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,92 @@
    #!/bin/bash

    # dedupe_list() is a helper function to dedupe a list of items separated by a given separator
    # eg dedupe_list ":" "a:b:a:c" will return "a:b:c", or dedupe_list ":" "$PATH" will return a deduped $PATH
    # the seperator you pass is used to split the existing list, and reinserted in the same order
    dedupe_list() {
    local separator="$1"
    # Use awk to preserve order while deduping
    echo "$2" | tr "$separator" '\n' | awk '!seen[$0]++ && NF' | tr '\n' "$separator"
    }

    test_dedupe_list() {
    local failed=0
    local total=0

    # Helper function to run a test case
    run_test() {
    local test_name="$1"
    local separator="$2"
    local input="$3"
    local expected="$4"
    local result

    ((total++))
    result=$(dedupe_list "$separator" "$input")

    if [ "$result" = "$expected" ]; then
    echo "✓ PASS: $test_name"
    else
    echo "✗ FAIL: $test_name"
    echo " Input : $input"
    echo " Expected: $expected"
    echo " Got : $result"
    ((failed++))
    fi
    }

    # Test PATH-style cases (colon separator)
    run_test "Basic PATH dedup" ":" \
    "/usr/bin:/bin:/usr/bin:/sbin" \
    "/usr/bin:/bin:/sbin:"

    run_test "Empty PATH segments" ":" \
    "/usr/bin::/bin::/usr/bin:" \
    "/usr/bin:/bin:"

    run_test "Single PATH entry" ":" \
    "/usr/bin" \
    "/usr/bin:"

    run_test "No duplicates" ":" \
    "/usr/bin:/bin:/sbin" \
    "/usr/bin:/bin:/sbin:"

    run_test "Complex PATH" ":" \
    "/usr/local/bin:/usr/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin" \
    "/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:"

    # Test space-separated variables
    run_test "Basic space-separated" " " \
    "foo bar foo baz" \
    "foo bar baz "

    run_test "Multiple spaces" " " \
    "foo bar foo baz" \
    "foo bar baz "

    run_test "Single word" " " \
    "foo" \
    "foo "

    # Test with empty input
    run_test "Empty input" ":" \
    "" \
    ""

    # Test with special characters
    run_test "Special chars" ":" \
    "/path/with spaces:/path/with spaces:/path/with:colons" \
    "/path/with spaces:/path/with:colons:"

    # Summary
    echo "-------------------"
    echo "Tests completed: $total"
    echo "Failed: $failed"
    echo "Passed: $((total - failed))"

    return $failed
    }

    # Run the tests
    test_dedupe_list