name: "Builtins: compgen"
cases:
  - name: "compgen -A alias"
    stdin: |
      alias myalias="ls"
      alias myalias2="echo hi"

      compgen -A alias myalias | sort

  - name: "compgen -A binding"
    stdin: |
      compgen -A binding tab | sort

  - name: "compgen -A builtin"
    stdin: |
      compgen -A builtin cd | sort

  - name: "compgen -A directory"
    stdin: |
      touch somefile
      mkdir somedir
      mkdir somedir2

      compgen -A directory some | sort

  - name: "compgen -A file"
    stdin: |
      touch somefile
      mkdir somedir
      mkdir somedir2

      compgen -A file some | sort

  - name: "compgen -A file with dot files"
    stdin: |
      touch .file
      mkdir .dir

      echo "[without dotglob]"
      shopt -u dotglob
      compgen -A file | sort

      echo "[with dotglob]"
      shopt -s dotglob
      compgen -A file | sort

  - name: "compgen -A function"
    stdin: |
      myfunc() {
        echo hi
      }

      myfunc2() {
        echo hello
      }

      compgen -A function myfunc | sort

  - name: "compgen -A keyword"
    stdin: |
      compgen -A keyword esa | sort

  - name: "compgen -A variable"
    stdin: |
      declare myvar=10
      declare myvar2=11

      compgen -A variable myvar | sort

  - name: "compgen -W"
    stdin: |
      echo "1. Basic compgen -W"
      compgen -W "one two three" -- t | sort
      echo "2. compgen -W with expansion"
      myvar=value compgen -W '${myvar}'

  - name: "compgen -W does not pathname-expand"
    stdin: |
      touch foo.txt bar.txt baz.log

      echo "[glob pattern should be literal]"
      compgen -W '*.txt' | sort

      echo "[question mark glob should be literal]"
      compgen -W '?.log' | sort

  - name: "compgen -W with unsorted values"
    stdin: |
      compgen -W 'c b d a'

  - name: "compgen -W with options"
    stdin: |
      compgen -W '--abc --def' -- '--ab'

  - name: "compgen with no matches"
    stdin: |
      compgen -W yes no && echo "1. Result"

  - name: "compgen -f with tilde"
    home_dir: testhome # relative to default working dir
    stdin: |
      mkdir testhome && cd testhome

      echo "HOME base: $(basename $HOME)"
      echo "~ base:" $(basename ~)

      touch item1

      echo "[0]"
      for p in $(compgen -f ~); do
        echo ${p//$HOME/HOME}
      done

      echo "[1]"
      for p in $(compgen -f ~/); do
        echo ${p//$HOME/HOME}
      done

  - name: "compgen -f with quoted tilde"
    known_failure: true
    stdin: |
      touch item1
      HOME=$(pwd)

      echo "[0]"
      for p in $(compgen -f '~/'); do
        echo ${p//$HOME/HOME}
      done

  - name: "compgen -f with quoted var"
    known_failure: true
    stdin: |
      touch item1
      HOME=$(pwd)

      echo "[0]"
      for p in $(compgen -f '$HOME/'); do
        echo ${p//$HOME/HOME}
      done

  - name: "compgen -f with quoted + escaped var"
    known_failure: true
    stdin: |
      touch item1
      HOME=$(pwd)

      echo "[0]"
      for p in $(compgen -f '\$HOME/'); do
        echo ${p//$HOME/HOME}
      done

  - name: "compgen with interesting hyphens"
    stdin: |
      compgen -P-before -S-after -W "one two three" -- t | sort

  - name: "compgen -X"
    stdin: |
      echo "[Take 1]"
      compgen -W 'foo bar' -X 'foo' ''

      echo "[Take 2]"
      compgen -W 'foo bar' -X 'f*' ''

      echo "[Take 3]"
      compgen -W '&1 foo' -X '\&*' ''

  - name: "compgen -X with replacement"
    stdin: |
      echo "[Take 1]"
      compgen -W 'somebody something' -X '&b*' some

  - name: "compgen -X with extglob"
    stdin: |
      touch README
      shopt -s extglob

      echo "[Take 1]"
      compgen -f READ

      echo "[Take 2]"
      compgen -f -X "READ" READ

      echo "[Take 3]"
      compgen -f -X "README" READ

      echo "[Take 4]"
      compgen -f -X "!(READ)" READ

      echo "[Take 5]"
      compgen -f -X "!(README)" READ

      echo "[Take 6]"
      compgen -f -X "!!(READ)" READ

      echo "[Take 7]"
      compgen -f -X "!!(README)" READ

  - name: "compgen -o dirnames"
    stdin: |
      echo "[Take 1]"
      compgen -W 'completion' -o dirnames -- c | sort

      echo "[Take 2]"
      mkdir subdir
      touch subfile
      compgen -W 'completion' -o dirnames -- s | sort

  - name: "compgen -o default"
    stdin: |
      echo "[Take 1]"
      compgen -W 'completion' -o default -- c | sort

      echo "[Take 2]"
      mkdir subdir
      touch subfile
      compgen -W 'completion' -o default -- s | sort

  - name: "compgen -o bashdefault"
    stdin: |
      echo "[Take 1]"
      compgen -W 'completion' -o bashdefault -- c | sort

      echo "[Take 2]"
      mkdir subdir
      touch subfile
      compgen -W 'completion' -o bashdefault -- s | sort

  - name: "compgen -o plusdirs"
    stdin: |
      echo "[Take 1]"
      touch cfile
      mkdir cdir
      compgen -W 'completion' -o plusdirs -o default -S suffix -- c | sort

  - name: "compgen -A command"
    # Temporarily marked unconstrained Path case as `skip: true` to keep CI stable.
    # Environment-dependent due to host PATH contents(Ubuntu includes X11, while Arch and others do not).
    skip: true
    stdin: |
      compgen -A command | sort | grep -v "^brush"

  - name: "compgen -A command in a constrained PATH"
    stdin: |
      SORT=$(command -v sort)
      GREP=$(command -v grep)
      PATH=$(pwd)
      compgen -A command | $SORT | $GREP -v "^brush"

  - name: "compgen -A command builtins in a constrained PATH"
    stdin: |
      SORT=$(command -v sort)
      PATH=$(pwd)
      compgen -A command cd | $SORT

  - name: "compgen -A command keywords in a constrained PATH"
    stdin: |
      SORT=$(command -v sort)
      PATH=$(pwd)
      compgen -A command [ | $SORT

  - name: "compgen -A command function in a constrained PATH"
    stdin: |
      SORT=$(command -v sort)
      PATH=$(pwd)
      myfunc() {
        echo hi
      }
      myfunc2() {
        echo hello
      }
      compgen -A command myfunc | $SORT

  - name: "compgen -A command with executable symlink"
    stdin: |
      #             pwd
      #  drwxr-xr-x ├──  test-bin
      # .rwxr-xr-x  │   ├──  dummy_exe
      # .rw-r--r--  │   └──  dummy_non_exe
      # drwxr-xr-x  └──  test-links
      # lrwxrwxrwx      ├──  link_valid         ⇒ $(pwd)/test-bin/dummy_exe
      # lrwxrwxrwx      └──  link_valid_exe_rec ⇒ $(pwd)/test-links/link_valid
      # lrwxrwxrwx      ├──  link_non_exec      ⇒ $(pwd)/test-bin/dummy_non_exe
      # lrwxrwxrwx      ├──  link_broken        ⇒ $(pwd)/test-bin/dummy_non_exist
      #
      mkdir test-bin
      touch test-bin/dummy_exe
      touch test-bin/dummy_non_exe
      chmod +x test-bin/dummy_exe

      mkdir test-links
      ln -s $(pwd)/test-bin/dummy_exe       $(pwd)/test-links/link_valid
      ln -s $(pwd)/test-links/link_vaild    $(pwd)/test-links/link_valid_rec
      ln -s $(pwd)/test-bin/dummy_non_exe   $(pwd)/test-links/link_non_exec
      ln -s $(pwd)/test-bin/dummy_non_exist $(pwd)/test-links/link_broken

      PATH="$(pwd)/test-links:$PATH"

      echo "[Valid]"
      compgen -A command -- link_valid | sort

      echo "[Invalid]"
      compgen -A command -- link_non_exec
      compgen -A command -- link_broken

  - name: "compgen -F sets COMP_KEY and COMP_TYPE to 0"
    ignore_stderr: true
    stdin: |
      _comp() { echo "KEY=${COMP_KEY:-unset} TYPE=${COMP_TYPE:-unset}"; COMPREPLY=(); }
      compgen -F _comp mycmd
