extra files

This commit is contained in:
Jack Halford 2017-03-25 21:33:28 +01:00
parent 6e493e84ea
commit 2dd095f525
79 changed files with 0 additions and 6211 deletions

View file

@ -1,235 +0,0 @@
.x....................xxx...xxxx..x.
----------------------------------------------------------------
21sh/misc/002-simple-command-line (FAILED)
Description:
 The purpose of this test is to check that the Shell is able to execute a simple command line that contains separators `;`, pipes `|`, and a right redirection `>`.
Before test:
 01: rm -rf "./size"
02: rm -rf "TOKEN201703241734"
03: echo '^'$(echo TOKEN201703241734_FILE_TOKEN201703241734_STDOUT | wc -c)'$' > "./size"
STDIN:
 01: mkdir TOKEN201703241734 ; cd TOKEN201703241734 ; touch TOKEN201703241734_FILE ; ls -1 ; ls | cat | wc -c > TOKEN201703241734_STDOUT ; cat TOKEN201703241734_STDOUT
STDOUT:
 SUCCESS expected_to match_regex `TOKEN201703241734_FILE$`
 FAILURE expected_to match_each_regex_of_file `./size`
 01: TOKEN201703241734_FILE
02: 98839 redirect_great.c 24 3 1
03: 23
STDERR:
 SUCCESS expected_to be_empty
 (no output)
----------------------------------------------------------------
21sh/redirections/outputs/truncating/001-creates-file-if-not-exits (FAILED)
Description:
 The right redirection `>` opens the file with the oflag `O_CREAT` so that the file is created if it does not exists.
Before test:
 01: rm -f new_file
STDIN:
 01: ./write_on_stdout TOKEN201703241734 >new_file
STDOUT:
 SUCCESS expected_to_not match_regex `TOKEN201703241734`
 (no output)
STDERR:
 SUCCESS expected_to be_empty
 (no output)
MISC:
 SUCCESS expected_to create_file `new_file` matching_regex `TOKEN201703241734`
 FAILURE expected_to create_file `new_file` with_nb_of_lines `1`
----------------------------------------------------------------
21sh/redirections/outputs/truncating/002-truncates-file-if-exists (FAILED)
Description:
 The right redirection `>` opens the file with the oflag `O_TRUNC` so that the file size is truncated to 0 before writing in it.
Before test:
 01: ./write_on_stdout TOKEN201703241734_first >truncated_file
STDIN:
 01: ./write_on_stdout TOKEN201703241734_second >truncated_file
STDOUT:
 SUCCESS expected_to_not match_regex TOKEN201703241734_second
 (no output)
STDERR:
 SUCCESS expected_to be_empty
 (no output)
MISC:
 SUCCESS expected_to create_file `truncated_file` matching_regex `TOKEN201703241734_second`
 SUCCESS expected_to create_file `truncated_file` not_matching_regex `TOKEN201703241734_first`
 FAILURE expected_to create_file `truncated_file` with_nb_of_lines `1`
----------------------------------------------------------------
21sh/redirections/outputs/truncating/003-whitespace-before-filename (FAILED)
Description:
 The file name for a right redirection can be specified closely to the character `>` or in a separated field.
Before test:
 01: rm -f "new_file"
STDIN:
 01: ./write_on_stdout TOKEN201703241734 > new_file
STDOUT:
 SUCCESS expected_to_not match_regex `TOKEN201703241734`
 (no output)
STDERR:
 SUCCESS expected_to be_empty
 (no output)
MISC:
 SUCCESS expected_to create_file `new_file` matching_regex `TOKEN201703241734`
 FAILURE expected_to create_file `new_file` with_nb_of_lines `1`
----------------------------------------------------------------
21sh/redirections/outputs/truncating/multiple/004-together (FAILED)
Description:
 A right redirection can be associated to the twice outputs by using `&>...`, that means `redirect stdout and stderr to ...`.
Before test:
 01: rm -f "new_file_stderr_and_stdout"
STDIN:
 01: ./write_on_stdout_and_stderr TOKEN201703241734_1 TOKEN201703241734_2 &>new_file_stderr_and_stdout
STDOUT:
 FAILURE expected_to_not match_regex `TOKEN201703241734_1`
 SUCCESS expected_to_not match_regex `TOKEN201703241734_2`
 01: TOKEN201703241734_1
STDERR:
 SUCCESS expected_to_not match_regex `TOKEN201703241734_1`
 FAILURE expected_to_not match_regex `TOKEN201703241734_2`
 01: TOKEN201703241734_2
MISC:
 FAILURE expected_to create_file `new_file_stderr_and_stdout` matching_regex `TOKEN201703241734_1$`
 FAILURE expected_to create_file `new_file_stderr_and_stdout` matching_regex `TOKEN201703241734_2$`
----------------------------------------------------------------
21sh/redirections/outputs/truncating/multiple/005-together-with-whitespaces (FAILED)
Description:
 A right redirection can be associated to the twice outputs by using `&>...`, that means `redirect stdout and stderr to ...`.
In this test, we specify the file name in a separate field.
Before test:
 01: rm -f new_file_stderr_and_stdout
STDIN:
 01: ./write_on_stdout_and_stderr TOKEN201703241734_1 TOKEN201703241734_2 &> new_file_stderr_and_stdout
STDOUT:
 FAILURE expected_to_not match_regex `TOKEN201703241734_1`
 SUCCESS expected_to_not match_regex `TOKEN201703241734_2`
 01: TOKEN201703241734_1
STDERR:
 SUCCESS expected_to_not match_regex `TOKEN201703241734_1`
 FAILURE expected_to_not match_regex `TOKEN201703241734_2`
 01: TOKEN201703241734_2
MISC:
 FAILURE expected_to create_file `new_file_stderr_and_stdout` matching_regex `TOKEN201703241734_1$`
 FAILURE expected_to create_file `new_file_stderr_and_stdout` matching_regex `TOKEN201703241734_2$`
----------------------------------------------------------------
21sh/redirections/outputs/truncating/stderr/001-works (FAILED)
Description:
 The purpose of this test is to check that redirecting the standard error STDERR to a file `2>` works. In this test, the binary writes a token on each standard and error output, so that only the STDOUT is outputted and STDERR is written in a file `new_file_stderr`.
Before test:
 01: rm -f "./new_file_stderr"
STDIN:
 01: ./write_on_stdout_and_stderr TOKEN201703241734_STDOUT TOKEN201703241734_STDERR 2>new_file_stderr
STDOUT:
 SUCCESS expected_to match_regex `TOKEN201703241734_STDOUT`
 01: TOKEN201703241734_STDOUT
STDERR:
 SUCCESS expected_to_not match_regex `TOKEN201703241734_STDERR`
 (no output)
MISC:
 SUCCESS expected_to create_file `new_file_stderr` matching_regex `TOKEN201703241734_STDERR`
 FAILURE expected_to create_file `new_file_stderr` with_nb_of_lines 1
----------------------------------------------------------------
21sh/redirections/outputs/truncating/stdout/001-with-explicit-fd (FAILED)
Description:
 The purpose of this test is to check if '1>' redirect STDIN to a file.
We are using echo with one argument. The output should NOT return anything on the standard output.
Before test:
 01: rm -f new_file
STDIN:
 01: /bin/echo TOKEN1 1>new_file
STDOUT:
 SUCCESS expected_to_not match_regex TOKEN1
 (no output)
STDERR:
 (no output)
MISC:
 SUCCESS expected_to create_file new_file matching_regex TOKEN1
 FAILURE expected_to create_file new_file with_nb_of_lines 1
----------------------------------------------------------------
21sh/separators/semicolon/003-parse-error-empty-inline-command (FAILED)
Description:
 The purpose of this test is to check that using the simicolon separator `;` with empty commands results in error.
STDIN:
 01: ./write_on_stdout TOKEN201703241734 ; ; ./exit_with_status 42
STDOUT:
 SUCCESS expected_to be_empty
 (no output)
STDERR:
 SUCCESS expected_to_not be_empty
 SUCCESS might match_regex `([Ss]yntax|[Pp]arse) error`
 01: syntax error near unexpected token `;'
MISC:
 SUCCESS expected_to_not exit_with_status `42`
 FAILURE expected_to_not exit_with_status `0`
Total tests: 36
Total failed tests: 9
Total pending tests: 0

View file

@ -1,4 +0,0 @@
.idea
tmp/
.mshell_hist
.DS_Store

View file

@ -1,122 +0,0 @@
#!/bin/bash
# /*
# Launcher
# */
get_install_directory()
{
local SOURCE="${BASH_SOURCE[0]}"
local DIR
while [ -h "${SOURCE}" ]
do
DIR="$(cd -P "$(dirname "${SOURCE}")" && pwd)"
SOURCE="$(readlink "${SOURCE}")"
[[ "${SOURCE}" != /* ]] && SOURCE="${DIR}/${SOURCE}"
done
printf "%s" "$(cd -P "$(dirname "${SOURCE}")" && pwd)"
}
# global variables
GLOBAL_PROG=""
GLOBAL_PROG_REFERENCE=""
GLOBAL_SPECS_FILTER=""
GLOBAL_ENTRYPATH=$(pwd)
GLOBAL_INSTALLDIR="$(get_install_directory)"
GLOBAL_TMP_DIRECTORY="${GLOBAL_INSTALLDIR}/tmp"
GLOBAL_LOCALBRANCH=$(git branch | awk '$0 ~ /^\*/ {print $2; exit}')
GLOBAL_TOKEN="TOKEN$(date +%Y%m%d%H%M)"
GLOBAL_TOTAL_TESTS=0
GLOBAL_TOTAL_FAILED_TESTS=0
GLOBAL_TOTAL_PENDING_TESTS=0
GLOBAL_LOG=""
GLOBAL_SHOW_SUCCESS=0
GLOBAL_RUN_POSIX_ONLY=0
GLOBAL_RUN_PENDING_TESTS=0
GLOBAL_RUN_HARD_TESTS=0
GLOBAL_RUN_ALL_TESTS=0
GLOBAL_INVALID_OPTION=0
C_BOLD="\033[37;1m"
C_RED="\033[31m\033[38;5;160m"
C_GREEN="\033[31m\033[38;5;34m"
C_YELLOW="\033[31m\033[1;33m"
C_GREY="\033[38;5;239m"
C_CLEAR="\033[0m"
# retrieve options
while [ ! -z "${1}" ]; do
if [[ "${1}" =~ ^-- ]]
then
case "${1}" in
"--reference")
shift 1
GLOBAL_PROG_REFERENCE="$(which ${1})"
;;
"--filter")
shift 1
GLOBAL_SPECS_FILTER="${1}"
;;
"--show-success")
GLOBAL_SHOW_SUCCESS=1
;;
"--pending")
GLOBAL_RUN_PENDING_TESTS=1
;;
"--posix")
GLOBAL_RUN_POSIX_ONLY=1
;;
"--hard")
GLOBAL_RUN_HARD_TESTS=1
;;
"--all")
GLOBAL_RUN_ALL_TESTS=1
;;
*)
printf "%s\n" "Invalid option: ${1}"
exit 1
;;
esac
else
if [ "${GLOBAL_PROG}" == "" ]
then
[[ "${1}" =~ ^[\.][\.]\/ ]] && GLOBAL_PROG="../${1}" || GLOBAL_PROG="$(which ${1})"
fi
fi
shift 1
done
# go to install directory
cd "${GLOBAL_INSTALLDIR}"
# load application sources
for FILE in ./lib/* ./lib/verbs/*
do
if [ -f "${FILE}" ]
then
source "${FILE}"
fi
done
# create and go to temporary directory
mkdir -p "${GLOBAL_TMP_DIRECTORY}"
cd "${GLOBAL_TMP_DIRECTORY}"
# compile support binaries
make re -C "${GLOBAL_INSTALLDIR}/support/" TARGET_DIR=${GLOBAL_TMP_DIRECTORY} 1>- 2>-
# run main function
run_main
# display log
printf "%s\n\nTotal tests: %s\nTotal failed tests: %s\nTotal pending tests: %s\n" "${GLOBAL_LOG}" "${GLOBAL_TOTAL_TESTS}" "${GLOBAL_TOTAL_FAILED_TESTS}" "${GLOBAL_TOTAL_PENDING_TESTS}"
# go back to entry directory
cd "${GLOBAL_ENTRYPATH}"
# exit with success or error status
if [ "${GLOBAL_TOTAL_FAILED_TESTS}" == "0" ]
then
exit 0
else
exit 1
fi

View file

@ -1,574 +0,0 @@
# 42ShellTester
<img align="right" src="./lib/assets/42ShellTester_cropped.png" width="45%" />42ShellTester is an **integration testing framework** wrote in Bash and designed for the pedagogical projects of the Shell branch at School 42 (Paris) listed bellow:
* **minishell**
* **21sh**
* **42sh**
It brings you an easy way to **add**, **maintain** and **run** integration tests, helping you to work step by step on your Shell implementation.
<!--START_TOTAL_TESTS-->
42ShellTester is currently packaged with **289 tests**.
<!--END_TOTAL_TESTS-->
## Install
```bash
git clone https://github.com/we-sh/42ShellTester ~/42ShellTester
```
## Run tests
Add the path to your Shell as argument:
```bash
bash ~/42ShellTester/42ShellTester.sh "/ABSOLUTE/PATH/TO/YOUR/SHELL"
```
## Options
##### `--filter` + `$regex`
Run tests that matches with the specified regular expression (e.g. `--filter "builtins"`).
##### `--reference` + `$binary`
Run tests that does not fail with the specified Shell binary (e.g. `--reference "bash"`).
##### `--posix`
Run tests that are POSIX compliant only (run all by default).
##### `--hard`
Run tests that are marked as « hard » (omitted by default).
##### `--pending`
Also run pending tests.
##### `--all`
Equivalent to use the two options `--pending` and `--hard` together.
##### `--show-success`
Also display tests that succeed (hidden by default).
## List of tests
<!--START_LIST_TESTS-->
* **[21sh/](spec/21sh)**
* **[misc/](spec/21sh/misc)**
* [001-no-prompt-in-non-interactive-mode](spec/21sh/misc/001-no-prompt-in-non-interactive-mode)
* [002-simple-command-line](spec/21sh/misc/002-simple-command-line)
* **[pipe/](spec/21sh/pipe)**
* [001-single-pipe](spec/21sh/pipe/001-single-pipe)
* [002-chained-pipes](spec/21sh/pipe/002-chained-pipes)
* [003-many-chained-pipes](spec/21sh/pipe/003-many-chained-pipes)
* [004-without-surrounding-whitespaces](spec/21sh/pipe/004-without-surrounding-whitespaces)
* [005-asynchronous](spec/21sh/pipe/005-asynchronous)
* [006-exit-status](spec/21sh/pipe/006-exit-status)
* **[mixed/](spec/21sh/pipe/mixed)**
* [001-exit-or-not-exit <img src='./lib/assets/hard.png' width='38' height='12' />](spec/21sh/pipe/mixed/001-exit-or-not-exit)
* [002-cd-or-not-cd <img src='./lib/assets/hard.png' width='38' height='12' />](spec/21sh/pipe/mixed/002-cd-or-not-cd)
* [003-unsetenv-or-not-unsetenv <img src='./lib/assets/hard.png' width='38' height='12' />](spec/21sh/pipe/mixed/003-unsetenv-or-not-unsetenv)
* [004-setenv-or-not-setenv <img src='./lib/assets/hard.png' width='38' height='12' />](spec/21sh/pipe/mixed/004-setenv-or-not-setenv)
* **[redirections/](spec/21sh/redirections)**
* **[inputs/](spec/21sh/redirections/inputs)**
* [001-close-stdin](spec/21sh/redirections/inputs/001-close-stdin)
* [002-filename](spec/21sh/redirections/inputs/002-filename)
* [003-filename-with-whitespaces](spec/21sh/redirections/inputs/003-filename-with-whitespaces)
* [004-absolute-path](spec/21sh/redirections/inputs/004-absolute-path)
* [005-no-such-file](spec/21sh/redirections/inputs/005-no-such-file)
* **[outputs/](spec/21sh/redirections/outputs)**
* **[appending/](spec/21sh/redirections/outputs/appending)**
* [001-append-default-to-file](spec/21sh/redirections/outputs/appending/001-append-default-to-file)
* [002-append-stdout-to-file](spec/21sh/redirections/outputs/appending/002-append-stdout-to-file)
* [003-append-stderr-to-file](spec/21sh/redirections/outputs/appending/003-append-stderr-to-file)
* **[multiple/](spec/21sh/redirections/outputs/appending/multiple)**
* [001-append-twice-separately](spec/21sh/redirections/outputs/appending/multiple/001-append-twice-separately)
* **[closing/](spec/21sh/redirections/outputs/closing)**
* [001-close-default-output](spec/21sh/redirections/outputs/closing/001-close-default-output)
* [002-close-stdout](spec/21sh/redirections/outputs/closing/002-close-stdout)
* [003-close-stderr](spec/21sh/redirections/outputs/closing/003-close-stderr)
* [004-close-twice-outputs](spec/21sh/redirections/outputs/closing/004-close-twice-outputs)
* **[touching/](spec/21sh/redirections/outputs/touching)**
* [001-works](spec/21sh/redirections/outputs/touching/001-works)
* **[truncating/](spec/21sh/redirections/outputs/truncating)**
* [001-creates-file-if-not-exits](spec/21sh/redirections/outputs/truncating/001-creates-file-if-not-exits)
* [002-truncates-file-if-exists](spec/21sh/redirections/outputs/truncating/002-truncates-file-if-exists)
* [003-whitespace-before-filename](spec/21sh/redirections/outputs/truncating/003-whitespace-before-filename)
* **[multiple/](spec/21sh/redirections/outputs/truncating/multiple)**
* [001-separately](spec/21sh/redirections/outputs/truncating/multiple/001-separately)
* [002-together-stdout-first](spec/21sh/redirections/outputs/truncating/multiple/002-together-stdout-first)
* [003-together-stderr-first](spec/21sh/redirections/outputs/truncating/multiple/003-together-stderr-first)
* [004-together](spec/21sh/redirections/outputs/truncating/multiple/004-together)
* [005-together-with-whitespaces](spec/21sh/redirections/outputs/truncating/multiple/005-together-with-whitespaces)
* **[stderr/](spec/21sh/redirections/outputs/truncating/stderr)**
* [001-works](spec/21sh/redirections/outputs/truncating/stderr/001-works)
* **[stdout/](spec/21sh/redirections/outputs/truncating/stdout)**
* [001-with-explicit-fd](spec/21sh/redirections/outputs/truncating/stdout/001-with-explicit-fd)
* **[separators/](spec/21sh/separators)**
* **[semicolon/](spec/21sh/separators/semicolon)**
* [001-two-commands-sequentially](spec/21sh/separators/semicolon/001-two-commands-sequentially)
* [002-n-commands-sequentially](spec/21sh/separators/semicolon/002-n-commands-sequentially)
* [003-parse-error-empty-inline-command](spec/21sh/separators/semicolon/003-parse-error-empty-inline-command)
* [004-parse-error-empty-command](spec/21sh/separators/semicolon/004-parse-error-empty-command)
* **[42sh/](spec/42sh)**
* **[builtins/](spec/42sh/builtins)**
* **[export/](spec/42sh/builtins/export)**
* [001-display-env](spec/42sh/builtins/export/001-display-env)
* [002-export-basic-key-value-1](spec/42sh/builtins/export/002-export-basic-key-value-1)
* [003-export-basic-key-value-2](spec/42sh/builtins/export/003-export-basic-key-value-2)
* [004-export-empty-variable-1](spec/42sh/builtins/export/004-export-empty-variable-1)
* [005-export-empty-variable-2](spec/42sh/builtins/export/005-export-empty-variable-2)
* [006-export-update-env-variable](spec/42sh/builtins/export/006-export-update-env-variable)
* [007-existing-environment-variable](spec/42sh/builtins/export/007-existing-environment-variable)
* [008-local-to-environment](spec/42sh/builtins/export/008-local-to-environment)
* [009-export-with-equal-but-no-value-part1](spec/42sh/builtins/export/009-export-with-equal-but-no-value-part1)
* [010-export-with-equal-but-no-value-part2](spec/42sh/builtins/export/010-export-with-equal-but-no-value-part2)
* **[errors/](spec/42sh/builtins/export/errors)**
* [001-invalid-identifier-1](spec/42sh/builtins/export/errors/001-invalid-identifier-1)
* [002-invalid-identifier-2](spec/42sh/builtins/export/errors/002-invalid-identifier-2)
* [003-illegal-option](spec/42sh/builtins/export/errors/003-illegal-option)
* **[mixed/](spec/42sh/builtins/export/mixed)**
* [001-export-and-tmp-env-part1](spec/42sh/builtins/export/mixed/001-export-and-tmp-env-part1)
* [002-export-and-tmp-env-part2](spec/42sh/builtins/export/mixed/002-export-and-tmp-env-part2)
* **[options/](spec/42sh/builtins/export/options)**
* [001-export-with-only-p-parameter](spec/42sh/builtins/export/options/001-export-with-only-p-parameter)
* [002-export-p-param-and-token-should-add-local-var-only-part1](spec/42sh/builtins/export/options/002-export-p-param-and-token-should-add-local-var-only-part1)
* [003-export-p-param-and-token-should-add-local-var-only-part2](spec/42sh/builtins/export/options/003-export-p-param-and-token-should-add-local-var-only-part2)
* [004-export-n-param](spec/42sh/builtins/export/options/004-export-n-param)
* **[escaping/](spec/42sh/escaping)**
* [001-escape-single-character-1](spec/42sh/escaping/001-escape-single-character-1)
* [002-escape-single-character-2](spec/42sh/escaping/002-escape-single-character-2)
* [003-escape-single-character-3](spec/42sh/escaping/003-escape-single-character-3)
* [004-escape-single-character-4](spec/42sh/escaping/004-escape-single-character-4)
* [005-escape-single-character-5](spec/42sh/escaping/005-escape-single-character-5)
* **[mixed/](spec/42sh/escaping/mixed)**
* **[globbing/](spec/42sh/escaping/mixed/globbing)**
* **[brace-expansion/](spec/42sh/escaping/mixed/globbing/brace-expansion)**
* [001-it-does-not-expand-braces-1](spec/42sh/escaping/mixed/globbing/brace-expansion/001-it-does-not-expand-braces-1)
* [002-it-expands-braces-1](spec/42sh/escaping/mixed/globbing/brace-expansion/002-it-expands-braces-1)
* [003-it-expands-braces-2](spec/42sh/escaping/mixed/globbing/brace-expansion/003-it-expands-braces-2)
* **[bracket-expansion/](spec/42sh/escaping/mixed/globbing/bracket-expansion)**
* [001-it-does-not-expand-brackets](spec/42sh/escaping/mixed/globbing/bracket-expansion/001-it-does-not-expand-brackets)
* [002-escaped-inversion-mark](spec/42sh/escaping/mixed/globbing/bracket-expansion/002-escaped-inversion-mark)
* [003-it-takes-escaped-bracket-as-pattern-character](spec/42sh/escaping/mixed/globbing/bracket-expansion/003-it-takes-escaped-bracket-as-pattern-character)
* **[variable-expansion/](spec/42sh/escaping/mixed/variable-expansion)**
* [001-escape-variable-1](spec/42sh/escaping/mixed/variable-expansion/001-escape-variable-1)
* [002-it-does-not-escape-variable](spec/42sh/escaping/mixed/variable-expansion/002-it-does-not-escape-variable)
* [003-escape-variable-2](spec/42sh/escaping/mixed/variable-expansion/003-escape-variable-2)
* **[globbing/](spec/42sh/globbing)**
* **[brace-expansion/](spec/42sh/globbing/brace-expansion)**
* **[ascii-range/](spec/42sh/globbing/brace-expansion/ascii-range)**
* [001-simple-ascending-1](spec/42sh/globbing/brace-expansion/ascii-range/001-simple-ascending-1)
* [002-simple-ascending-2](spec/42sh/globbing/brace-expansion/ascii-range/002-simple-ascending-2)
* [003-simple-ascending-3](spec/42sh/globbing/brace-expansion/ascii-range/003-simple-ascending-3)
* [004-simple-descending-1](spec/42sh/globbing/brace-expansion/ascii-range/004-simple-descending-1)
* [005-simple-descending-2](spec/42sh/globbing/brace-expansion/ascii-range/005-simple-descending-2)
* [006-simple-descending-3](spec/42sh/globbing/brace-expansion/ascii-range/006-simple-descending-3)
* [007-identical-start-and-end](spec/42sh/globbing/brace-expansion/ascii-range/007-identical-start-and-end)
* [008-multiple-1](spec/42sh/globbing/brace-expansion/ascii-range/008-multiple-1)
* [009-multiple-2](spec/42sh/globbing/brace-expansion/ascii-range/009-multiple-2)
* [010-big-range](spec/42sh/globbing/brace-expansion/ascii-range/010-big-range)
* **[errors/](spec/42sh/globbing/brace-expansion/errors)**
* [001-invalid-pattern-1](spec/42sh/globbing/brace-expansion/errors/001-invalid-pattern-1)
* [002-invalid-pattern-2](spec/42sh/globbing/brace-expansion/errors/002-invalid-pattern-2)
* [003-invalid-pattern-3](spec/42sh/globbing/brace-expansion/errors/003-invalid-pattern-3)
* [004-invalid-pattern-4](spec/42sh/globbing/brace-expansion/errors/004-invalid-pattern-4)
* **[list-of-values/](spec/42sh/globbing/brace-expansion/list-of-values)**
* [001-nothing-to-be-done](spec/42sh/globbing/brace-expansion/list-of-values/001-nothing-to-be-done)
* [002-simple-test-1](spec/42sh/globbing/brace-expansion/list-of-values/002-simple-test-1)
* [003-simple-test-2](spec/42sh/globbing/brace-expansion/list-of-values/003-simple-test-2)
* **[numeric-range/](spec/42sh/globbing/brace-expansion/numeric-range)**
* [001-simple-ascending-1](spec/42sh/globbing/brace-expansion/numeric-range/001-simple-ascending-1)
* [002-simple-ascending-2](spec/42sh/globbing/brace-expansion/numeric-range/002-simple-ascending-2)
* [003-simple-ascending-3](spec/42sh/globbing/brace-expansion/numeric-range/003-simple-ascending-3)
* [004-simple-ascending-4](spec/42sh/globbing/brace-expansion/numeric-range/004-simple-ascending-4)
* [005-simple-ascending-5](spec/42sh/globbing/brace-expansion/numeric-range/005-simple-ascending-5)
* [006-simple-descending-1](spec/42sh/globbing/brace-expansion/numeric-range/006-simple-descending-1)
* [007-simple-descending-2](spec/42sh/globbing/brace-expansion/numeric-range/007-simple-descending-2)
* [008-simple-descending-3](spec/42sh/globbing/brace-expansion/numeric-range/008-simple-descending-3)
* [009-simple-descending-4](spec/42sh/globbing/brace-expansion/numeric-range/009-simple-descending-4)
* [010-simple-descending-5](spec/42sh/globbing/brace-expansion/numeric-range/010-simple-descending-5)
* [011-identical-positive-start-and-end](spec/42sh/globbing/brace-expansion/numeric-range/011-identical-positive-start-and-end)
* [012-identical-negative-start-and-end](spec/42sh/globbing/brace-expansion/numeric-range/012-identical-negative-start-and-end)
* [013-multiple-1](spec/42sh/globbing/brace-expansion/numeric-range/013-multiple-1)
* [014-multiple-2](spec/42sh/globbing/brace-expansion/numeric-range/014-multiple-2)
* [015-big-range](spec/42sh/globbing/brace-expansion/numeric-range/015-big-range)
* **[bracket-expansion/](spec/42sh/globbing/bracket-expansion)**
* **[multi/](spec/42sh/globbing/bracket-expansion/multi)**
* [001-range-and-char](spec/42sh/globbing/bracket-expansion/multi/001-range-and-char)
* [002-reverse-range-and-chars](spec/42sh/globbing/bracket-expansion/multi/002-reverse-range-and-chars)
* [003-reverse-multi-hard](spec/42sh/globbing/bracket-expansion/multi/003-reverse-multi-hard)
* [004-simple-bracket+char+range](spec/42sh/globbing/bracket-expansion/multi/004-simple-bracket+char+range)
* **[not/](spec/42sh/globbing/bracket-expansion/not)**
* [001-simple-opposit-match](spec/42sh/globbing/bracket-expansion/not/001-simple-opposit-match)
* [002-simple-opposite-range](spec/42sh/globbing/bracket-expansion/not/002-simple-opposite-range)
* **[range-pattern/](spec/42sh/globbing/bracket-expansion/range-pattern)**
* [001-alpha-range](spec/42sh/globbing/bracket-expansion/range-pattern/001-alpha-range)
* [002-numeric-range](spec/42sh/globbing/bracket-expansion/range-pattern/002-numeric-range)
* [003-ascii-range-1](spec/42sh/globbing/bracket-expansion/range-pattern/003-ascii-range-1)
* [004-ascii-range-2](spec/42sh/globbing/bracket-expansion/range-pattern/004-ascii-range-2)
* **[simple-pattern/](spec/42sh/globbing/bracket-expansion/simple-pattern)**
* [001-simple-list](spec/42sh/globbing/bracket-expansion/simple-pattern/001-simple-list)
* [002-multi-bracket](spec/42sh/globbing/bracket-expansion/simple-pattern/002-multi-bracket)
* [003-brackets-as-pattern](spec/42sh/globbing/bracket-expansion/simple-pattern/003-brackets-as-pattern)
* [004-multi-bracket-multi-char](spec/42sh/globbing/bracket-expansion/simple-pattern/004-multi-bracket-multi-char)
* **[single-char-pattern/](spec/42sh/globbing/bracket-expansion/single-char-pattern)**
* [001-single-char](spec/42sh/globbing/bracket-expansion/single-char-pattern/001-single-char)
* [002-closing-bracket-char](spec/42sh/globbing/bracket-expansion/single-char-pattern/002-closing-bracket-char)
* [003-opening-bracket-char](spec/42sh/globbing/bracket-expansion/single-char-pattern/003-opening-bracket-char)
* **[local-variable/](spec/42sh/local-variable)**
* [001-declare-and-expand-1](spec/42sh/local-variable/001-declare-and-expand-1)
* [002-declare-and-expand-2](spec/42sh/local-variable/002-declare-and-expand-2)
* [003-unknown-variable-does-not-result-in-new-argument](spec/42sh/local-variable/003-unknown-variable-does-not-result-in-new-argument)
* [004-existing-variable-in-environment-1](spec/42sh/local-variable/004-existing-variable-in-environment-1)
* [005-existing-variable-in-environment-2](spec/42sh/local-variable/005-existing-variable-in-environment-2)
* [006-existing-variable-in-environment-3](spec/42sh/local-variable/006-existing-variable-in-environment-3)
* [007-multiple-declaration-at-a-time](spec/42sh/local-variable/007-multiple-declaration-at-a-time)
* [008-multiple-declaration-with-same-name](spec/42sh/local-variable/008-multiple-declaration-with-same-name)
* [009-last-exit-status](spec/42sh/local-variable/009-last-exit-status)
* **[mixed/](spec/42sh/local-variable/mixed)**
* **[inline-environment-variable/](spec/42sh/local-variable/mixed/inline-environment-variable)**
* [001-local-variable-shouldnt-be-set](spec/42sh/local-variable/mixed/inline-environment-variable/001-local-variable-shouldnt-be-set)
* **[redirections/](spec/42sh/local-variable/mixed/redirections)**
* [001-truncating](spec/42sh/local-variable/mixed/redirections/001-truncating)
* [002-appending](spec/42sh/local-variable/mixed/redirections/002-appending)
* [003-reading](spec/42sh/local-variable/mixed/redirections/003-reading)
* **[tilde-expansion/](spec/42sh/local-variable/mixed/tilde-expansion)**
* [001-process-tilde-expansion](spec/42sh/local-variable/mixed/tilde-expansion/001-process-tilde-expansion)
* **[quoting/](spec/42sh/quoting)**
* **[double-quotes/](spec/42sh/quoting/double-quotes)**
* [001-it-works](spec/42sh/quoting/double-quotes/001-it-works)
* [002-concatenated-strings](spec/42sh/quoting/double-quotes/002-concatenated-strings)
* [003-first-argument-inhibited](spec/42sh/quoting/double-quotes/003-first-argument-inhibited)
* [004-multiline-1](spec/42sh/quoting/double-quotes/004-multiline-1)
* [005-multiline-2](spec/42sh/quoting/double-quotes/005-multiline-2)
* **[mixed/](spec/42sh/quoting/double-quotes/mixed)**
* **[escaping/](spec/42sh/quoting/double-quotes/mixed/escaping)**
* [001-escape-double-quote-1](spec/42sh/quoting/double-quotes/mixed/escaping/001-escape-double-quote-1)
* [002-escape-double-quote-2](spec/42sh/quoting/double-quotes/mixed/escaping/002-escape-double-quote-2)
* [003-escape-double-quote-3](spec/42sh/quoting/double-quotes/mixed/escaping/003-escape-double-quote-3)
* [004-it-results-in-error](spec/42sh/quoting/double-quotes/mixed/escaping/004-it-results-in-error)
* [005-it-does-not-escape-double-quote](spec/42sh/quoting/double-quotes/mixed/escaping/005-it-does-not-escape-double-quote)
* **[globbing/](spec/42sh/quoting/double-quotes/mixed/globbing)**
* **[brace-expansion/](spec/42sh/quoting/double-quotes/mixed/globbing/brace-expansion)**
* [001-it-does-not-expand-braces-1](spec/42sh/quoting/double-quotes/mixed/globbing/brace-expansion/001-it-does-not-expand-braces-1)
* [002-it-does-not-expand-braces-2](spec/42sh/quoting/double-quotes/mixed/globbing/brace-expansion/002-it-does-not-expand-braces-2)
* [003-it-does-not-expand-braces-3](spec/42sh/quoting/double-quotes/mixed/globbing/brace-expansion/003-it-does-not-expand-braces-3)
* [004-it-does-not-expand-braces-4](spec/42sh/quoting/double-quotes/mixed/globbing/brace-expansion/004-it-does-not-expand-braces-4)
* [005-it-does-not-expand-braces-5](spec/42sh/quoting/double-quotes/mixed/globbing/brace-expansion/005-it-does-not-expand-braces-5)
* **[bracket-expansion/](spec/42sh/quoting/double-quotes/mixed/globbing/bracket-expansion)**
* [001-it-works-1](spec/42sh/quoting/double-quotes/mixed/globbing/bracket-expansion/001-it-works-1)
* [002-it-works-2](spec/42sh/quoting/double-quotes/mixed/globbing/bracket-expansion/002-it-works-2)
* **[variable-expansion/](spec/42sh/quoting/double-quotes/mixed/variable-expansion)**
* [001-expansion-enabled](spec/42sh/quoting/double-quotes/mixed/variable-expansion/001-expansion-enabled)
* **[mixed/](spec/42sh/quoting/mixed)**
* [001-simple-and-double-quotes](spec/42sh/quoting/mixed/001-simple-and-double-quotes)
* [002-multiline](spec/42sh/quoting/mixed/002-multiline)
* **[globbing/](spec/42sh/quoting/mixed/globbing)**
* **[brace-expansion/](spec/42sh/quoting/mixed/globbing/brace-expansion)**
* [001-it-does-not-expand-braces-1](spec/42sh/quoting/mixed/globbing/brace-expansion/001-it-does-not-expand-braces-1)
* **[bracket-expansion/](spec/42sh/quoting/mixed/globbing/bracket-expansion)**
* [001-it-works-1](spec/42sh/quoting/mixed/globbing/bracket-expansion/001-it-works-1)
* [002-it-works-2](spec/42sh/quoting/mixed/globbing/bracket-expansion/002-it-works-2)
* **[variable-expansion/](spec/42sh/quoting/mixed/variable-expansion)**
* [001-it-does-not-expand-in-quotes](spec/42sh/quoting/mixed/variable-expansion/001-it-does-not-expand-in-quotes)
* **[simple-quotes/](spec/42sh/quoting/simple-quotes)**
* [001-it-works](spec/42sh/quoting/simple-quotes/001-it-works)
* [002-concatenated-strings](spec/42sh/quoting/simple-quotes/002-concatenated-strings)
* [003-first-argument-inhibited](spec/42sh/quoting/simple-quotes/003-first-argument-inhibited)
* [004-multiline-1](spec/42sh/quoting/simple-quotes/004-multiline-1)
* [005-multiline-2](spec/42sh/quoting/simple-quotes/005-multiline-2)
* **[mixed/](spec/42sh/quoting/simple-quotes/mixed)**
* **[escaping/](spec/42sh/quoting/simple-quotes/mixed/escaping)**
* [001-escape-simple-quote-1](spec/42sh/quoting/simple-quotes/mixed/escaping/001-escape-simple-quote-1)
* [002-escape-simple-quote-2](spec/42sh/quoting/simple-quotes/mixed/escaping/002-escape-simple-quote-2)
* [003-escape-simple-quote-3](spec/42sh/quoting/simple-quotes/mixed/escaping/003-escape-simple-quote-3)
* [004-it-does-not-escape-simple-quote-1](spec/42sh/quoting/simple-quotes/mixed/escaping/004-it-does-not-escape-simple-quote-1)
* [005-it-does-not-escape-simple-quote-2](spec/42sh/quoting/simple-quotes/mixed/escaping/005-it-does-not-escape-simple-quote-2)
* **[globbing/](spec/42sh/quoting/simple-quotes/mixed/globbing)**
* **[brace-expansion/](spec/42sh/quoting/simple-quotes/mixed/globbing/brace-expansion)**
* [001-it-does-not-expand-braces-1](spec/42sh/quoting/simple-quotes/mixed/globbing/brace-expansion/001-it-does-not-expand-braces-1)
* [002-it-does-not-expand-braces-2](spec/42sh/quoting/simple-quotes/mixed/globbing/brace-expansion/002-it-does-not-expand-braces-2)
* [003-it-does-not-expand-braces-3](spec/42sh/quoting/simple-quotes/mixed/globbing/brace-expansion/003-it-does-not-expand-braces-3)
* [004-it-does-not-expand-braces-4](spec/42sh/quoting/simple-quotes/mixed/globbing/brace-expansion/004-it-does-not-expand-braces-4)
* [005-it-does-not-expand-braces-5](spec/42sh/quoting/simple-quotes/mixed/globbing/brace-expansion/005-it-does-not-expand-braces-5)
* **[bracket-expansion/](spec/42sh/quoting/simple-quotes/mixed/globbing/bracket-expansion)**
* [001-it-works-1](spec/42sh/quoting/simple-quotes/mixed/globbing/bracket-expansion/001-it-works-1)
* [002-it-works-2](spec/42sh/quoting/simple-quotes/mixed/globbing/bracket-expansion/002-it-works-2)
* **[variable-expansion/](spec/42sh/quoting/simple-quotes/mixed/variable-expansion)**
* [001-expansion-disabled](spec/42sh/quoting/simple-quotes/mixed/variable-expansion/001-expansion-disabled)
* **[subshell/](spec/42sh/subshell)**
* [001-tokens-are-recognized](spec/42sh/subshell/001-tokens-are-recognized)
* [002-multiple-levels-of-subshells](spec/42sh/subshell/002-multiple-levels-of-subshells)
* [003-multiline](spec/42sh/subshell/003-multiline)
* [004-exit-status](spec/42sh/subshell/004-exit-status)
* [005-copy-of-environment](spec/42sh/subshell/005-copy-of-environment)
* **[errors/](spec/42sh/subshell/errors)**
* [001-parse-error-1](spec/42sh/subshell/errors/001-parse-error-1)
* [002-parse-error-2](spec/42sh/subshell/errors/002-parse-error-2)
* [003-parse-error-3](spec/42sh/subshell/errors/003-parse-error-3)
* [004-parse-error-4](spec/42sh/subshell/errors/004-parse-error-4)
* **[mixed/](spec/42sh/subshell/mixed)**
* **[builtins/](spec/42sh/subshell/mixed/builtins)**
* **[cd/](spec/42sh/subshell/mixed/builtins/cd)**
* [001-it-does-not-change-current-directory](spec/42sh/subshell/mixed/builtins/cd/001-it-does-not-change-current-directory)
* [002-multiline](spec/42sh/subshell/mixed/builtins/cd/002-multiline)
* **[exit/](spec/42sh/subshell/mixed/builtins/exit)**
* [001-exiting-subshell](spec/42sh/subshell/mixed/builtins/exit/001-exiting-subshell)
* **[setenv/](spec/42sh/subshell/mixed/builtins/setenv)**
* [001-it-does-not-modify-parent-environment](spec/42sh/subshell/mixed/builtins/setenv/001-it-does-not-modify-parent-environment)
* **[unsetenv/](spec/42sh/subshell/mixed/builtins/unsetenv)**
* [001-it-does-not-modify-parent-environment](spec/42sh/subshell/mixed/builtins/unsetenv/001-it-does-not-modify-parent-environment)
* **[escaping/](spec/42sh/subshell/mixed/escaping)**
* [001-escaped-subshell-1](spec/42sh/subshell/mixed/escaping/001-escaped-subshell-1)
* [002-escaped-subshell-2](spec/42sh/subshell/mixed/escaping/002-escaped-subshell-2)
* **[inline-environment-variable/](spec/42sh/subshell/mixed/inline-environment-variable)**
* [001-modifies-the-child-environment-only-1](spec/42sh/subshell/mixed/inline-environment-variable/001-modifies-the-child-environment-only-1)
* [002-modifies-the-child-environment-only-2](spec/42sh/subshell/mixed/inline-environment-variable/002-modifies-the-child-environment-only-2)
* **[piping/](spec/42sh/subshell/mixed/piping)**
* [001-subshells-inside-piped-command](spec/42sh/subshell/mixed/piping/001-subshells-inside-piped-command)
* [002-pipes-inside-subshells](spec/42sh/subshell/mixed/piping/002-pipes-inside-subshells)
* [003-imbricated-subshells-and-pipes](spec/42sh/subshell/mixed/piping/003-imbricated-subshells-and-pipes)
* **[quoting/](spec/42sh/subshell/mixed/quoting)**
* [001-with-simple-quotes](spec/42sh/subshell/mixed/quoting/001-with-simple-quotes)
* [002-with-double-quotes](spec/42sh/subshell/mixed/quoting/002-with-double-quotes)
* [003-with-simple-and-double-quotes](spec/42sh/subshell/mixed/quoting/003-with-simple-and-double-quotes)
* **[bonuses/](spec/bonuses)**
* **[builtins/](spec/bonuses/builtins)**
* **[env/](spec/bonuses/builtins/env)**
* [001-unset-variables <img src='./lib/assets/non-posix.png' width='63' height='12' /> <img src='./lib/assets/pending.png' width='54' height='12' />](spec/bonuses/builtins/env/001-unset-variables)
* [002-unset-and-set-variable <img src='./lib/assets/non-posix.png' width='63' height='12' /> <img src='./lib/assets/pending.png' width='54' height='12' />](spec/bonuses/builtins/env/002-unset-and-set-variable)
* **[inline-environment-variable/](spec/bonuses/inline-environment-variable)**
* [001-modifies-child-environment-1](spec/bonuses/inline-environment-variable/001-modifies-child-environment-1)
* [002-modifies-child-environment-2](spec/bonuses/inline-environment-variable/002-modifies-child-environment-2)
* [003-modifies-PATH-only](spec/bonuses/inline-environment-variable/003-modifies-PATH-only)
* **[redirections/](spec/bonuses/redirections)**
* [001-append-twice-outputs-together <img src='./lib/assets/non-posix.png' width='63' height='12' /> <img src='./lib/assets/hard.png' width='38' height='12' /> <img src='./lib/assets/pending.png' width='54' height='12' />](spec/bonuses/redirections/001-append-twice-outputs-together)
* **[separators/](spec/bonuses/separators)**
* **[and/](spec/bonuses/separators/and)**
* [001-run-twice](spec/bonuses/separators/and/001-run-twice)
* [002-do-not-run-second](spec/bonuses/separators/and/002-do-not-run-second)
* [003-run-until-failing](spec/bonuses/separators/and/003-run-until-failing)
* **[errors/](spec/bonuses/separators/and/errors)**
* [001-parse-error-at-beginning](spec/bonuses/separators/and/errors/001-parse-error-at-beginning)
* [002-parse-error-too-much-symbol](spec/bonuses/separators/and/errors/002-parse-error-too-much-symbol)
* **[mixed/](spec/bonuses/separators/mixed)**
* [001-and-or](spec/bonuses/separators/mixed/001-and-or)
* [002-and-or](spec/bonuses/separators/mixed/002-and-or)
* [003-and-or](spec/bonuses/separators/mixed/003-and-or)
* [004-or-and](spec/bonuses/separators/mixed/004-or-and)
* [005-or-and](spec/bonuses/separators/mixed/005-or-and)
* [006-or-and](spec/bonuses/separators/mixed/006-or-and)
* **[or/](spec/bonuses/separators/or)**
* [001-run-first-only](spec/bonuses/separators/or/001-run-first-only)
* [002-run-second-only](spec/bonuses/separators/or/002-run-second-only)
* [003-run-until-succeeding](spec/bonuses/separators/or/003-run-until-succeeding)
* **[errors/](spec/bonuses/separators/or/errors)**
* [001-parse-error-at-beginning](spec/bonuses/separators/or/errors/001-parse-error-at-beginning)
* [002-parse-error-too-much-symbol](spec/bonuses/separators/or/errors/002-parse-error-too-much-symbol)
* **[tilde-expansion/](spec/bonuses/tilde-expansion)**
* [001-expanded-with-HOME-1](spec/bonuses/tilde-expansion/001-expanded-with-HOME-1)
* [002-expanded-with-HOME-2](spec/bonuses/tilde-expansion/002-expanded-with-HOME-2)
* [003-expanded-with-PWD-1](spec/bonuses/tilde-expansion/003-expanded-with-PWD-1)
* [004-expanded-with-PWD-2](spec/bonuses/tilde-expansion/004-expanded-with-PWD-2)
* [005-expanded-with-OLDPWD-1](spec/bonuses/tilde-expansion/005-expanded-with-OLDPWD-1)
* [006-expanded-with-OLDPWD-2](spec/bonuses/tilde-expansion/006-expanded-with-OLDPWD-2)
* **[not-expanded/](spec/bonuses/tilde-expansion/not-expanded)**
* [001-not-expanded-with-HOME-1](spec/bonuses/tilde-expansion/not-expanded/001-not-expanded-with-HOME-1)
* [002-not-expanded-with-HOME-2](spec/bonuses/tilde-expansion/not-expanded/002-not-expanded-with-HOME-2)
* [003-not-expanded-with-PWD](spec/bonuses/tilde-expansion/not-expanded/003-not-expanded-with-PWD)
* [004-not-expanded-with-OLDPWD](spec/bonuses/tilde-expansion/not-expanded/004-not-expanded-with-OLDPWD)
* **[minishell/](spec/minishell)**
* **[binary/](spec/minishell/binary)**
* [001-binary-path-relative](spec/minishell/binary/001-binary-path-relative)
* [002-binary-path-absolute](spec/minishell/binary/002-binary-path-absolute)
* [003-binary-test-exec-order](spec/minishell/binary/003-binary-test-exec-order)
* [004-binary-test-empty-path](spec/minishell/binary/004-binary-test-empty-path)
* [005-binary-test-wrong-path](spec/minishell/binary/005-binary-test-wrong-path)
* [006-binary-undefined-path](spec/minishell/binary/006-binary-undefined-path)
* [007-binary-permission-denied](spec/minishell/binary/007-binary-permission-denied)
* [008-binary-too-many-symbolic-links-encountered](spec/minishell/binary/008-binary-too-many-symbolic-links-encountered)
* **[builtins/](spec/minishell/builtins)**
* **[cd/](spec/minishell/builtins/cd)**
* [001-no-arg](spec/minishell/builtins/cd/001-no-arg)
* [002-current-directory](spec/minishell/builtins/cd/002-current-directory)
* [003-current-directory-2](spec/minishell/builtins/cd/003-current-directory-2)
* [004-parent-directory](spec/minishell/builtins/cd/004-parent-directory)
* [005-root-path](spec/minishell/builtins/cd/005-root-path)
* [006-root-path-2](spec/minishell/builtins/cd/006-root-path-2)
* [007-symbolic-link](spec/minishell/builtins/cd/007-symbolic-link)
* [008-symbolic-link-2](spec/minishell/builtins/cd/008-symbolic-link-2)
* [009-following-links <img src='./lib/assets/hard.png' width='38' height='12' />](spec/minishell/builtins/cd/009-following-links)
* [010-update-OLDPWD](spec/minishell/builtins/cd/010-update-OLDPWD)
* [011-dotdot](spec/minishell/builtins/cd/011-dotdot)
* [012-dot](spec/minishell/builtins/cd/012-dot)
* [013-absolute-path](spec/minishell/builtins/cd/013-absolute-path)
* **[errors/](spec/minishell/builtins/cd/errors)**
* [001-not-a-directory](spec/minishell/builtins/cd/errors/001-not-a-directory)
* [002-not-a-directory-2](spec/minishell/builtins/cd/errors/002-not-a-directory-2)
* [003-permission-denied](spec/minishell/builtins/cd/errors/003-permission-denied)
* [004-permission-denied-2](spec/minishell/builtins/cd/errors/004-permission-denied-2)
* [005-too-many-symbolic-links-encountered](spec/minishell/builtins/cd/errors/005-too-many-symbolic-links-encountered)
* [006-too-many-symbolic-links-encountered-2](spec/minishell/builtins/cd/errors/006-too-many-symbolic-links-encountered-2)
* [007-no-such-file-or-directory](spec/minishell/builtins/cd/errors/007-no-such-file-or-directory)
* [008-no-such-file-or-directory-2](spec/minishell/builtins/cd/errors/008-no-such-file-or-directory-2)
* [009-no-such-file-or-directory-symlink](spec/minishell/builtins/cd/errors/009-no-such-file-or-directory-symlink)
* [010-no-such-file-or-directory-symlink-2](spec/minishell/builtins/cd/errors/010-no-such-file-or-directory-symlink-2)
* **[options/](spec/minishell/builtins/cd/options)**
* [001-not-following-links](spec/minishell/builtins/cd/options/001-not-following-links)
* [002-oldpwd](spec/minishell/builtins/cd/options/002-oldpwd)
* **[env/](spec/minishell/builtins/env)**
* [001-env-same-value-as-parent](spec/minishell/builtins/env/001-env-same-value-as-parent)
* [002-env-check-usefull-var](spec/minishell/builtins/env/002-env-check-usefull-var)
* [003-ignore-environment](spec/minishell/builtins/env/003-ignore-environment)
* [005-set-variables](spec/minishell/builtins/env/005-set-variables)
* **[errors/](spec/minishell/builtins/env/errors)**
* [001-command-not-found](spec/minishell/builtins/env/errors/001-command-not-found)
* [002-illegal-option](spec/minishell/builtins/env/errors/002-illegal-option)
* **[multiple-options/](spec/minishell/builtins/env/multiple-options)**
* [001-ignore-environment-and-set-variable](spec/minishell/builtins/env/multiple-options/001-ignore-environment-and-set-variable)
* **[exit/](spec/minishell/builtins/exit)**
* [001-without-any-argument](spec/minishell/builtins/exit/001-without-any-argument)
* [002-status-passed-as-argument](spec/minishell/builtins/exit/002-status-passed-as-argument)
* [003-status-of-last-command](spec/minishell/builtins/exit/003-status-of-last-command)
* **[errors/](spec/minishell/builtins/exit/errors)**
* [001-too-many-args](spec/minishell/builtins/exit/errors/001-too-many-args)
* [002-non-numeric-argument](spec/minishell/builtins/exit/errors/002-non-numeric-argument)
* **[mixed/](spec/minishell/builtins/mixed)**
* [001-setenv-unsetenv](spec/minishell/builtins/mixed/001-setenv-unsetenv)
* **[setenv/](spec/minishell/builtins/setenv)**
* [001-no-argument](spec/minishell/builtins/setenv/001-no-argument)
* [002-add-new-variable](spec/minishell/builtins/setenv/002-add-new-variable)
* [003-set-existing-variable](spec/minishell/builtins/setenv/003-set-existing-variable)
* [004-invalid-identifier](spec/minishell/builtins/setenv/004-invalid-identifier)
* [005-add-and-set-multiple-variables](spec/minishell/builtins/setenv/005-add-and-set-multiple-variables)
* **[unsetenv/](spec/minishell/builtins/unsetenv)**
* [001-unsetenv-first-elem](spec/minishell/builtins/unsetenv/001-unsetenv-first-elem)
* [002-unsetenv-mult-envp](spec/minishell/builtins/unsetenv/002-unsetenv-mult-envp)
* [003-unsetenv-mult-envp-inline](spec/minishell/builtins/unsetenv/003-unsetenv-mult-envp-inline)
* **[misc/](spec/minishell/misc)**
* [001-copy-of-environment](spec/minishell/misc/001-copy-of-environment)
<!--END_LIST_TESTS-->
# Development
## Coding convention
* Scope indentation must be done with 2 spaces
* Variable names must be upper case (e.g. `INDEX`)
* Global variables must be prefixed with `GLOBAL_` (e.g. `GLOBAL_TOKEN`)
* Variable expansion must be surrounded by curly braces (e.g. `${VARIABLE}`)
* Arguments of functions and commands must be surrounded by double or simple quotes (e.g. `run_assert "STDERR"`)
* Semicolon are banned so that words like `then` and `do` are always at start of lines (e.g. wrong inline code: `if [ ... ]; then cmd; fi`)
* Folder names may only contain alphanumeric and `-`
## Adding new test
An integration test must be **self-sufficient**, that means executing the full test suite or only one test must result in the same failed or success status. The framework 42ShellTester brings you tools for that!
Firstly, tests are executed inside a temporary folder `tmp/` that is created at launch time and placed at the root installation folder of the framework. You may generate temporary files, binaries and folders that are needed for your test, but pay attention to not touch external folders. Use the `before_exec` callback to generate these resources.
Secondly, each test is executed within a sub-shell, so that you may modify the environment without disrupting the test suite. Use the `before_exec` callback to modify the environment.
Thirdly, a test must concern one single feature at a time, that means **wherever possible** you must avoid the use of multiple builtins or capabilities (e.g. do not use a pipe `|` within a test that concerns the builtin `env`, or again use absolute paths to binaries like `/bin/ls` to let the Shell implementation not support the `PATH`, except if you precisely test this feature!).
Fourthly, when a test need binaries like `/bin/env` or `/bin/echo`, prefer to recode your own, simplier and multi-platform, and place it in `support/` folder. Then use the `before_exec` callback to compile it and make it available for your test.
Sixthly, a test that is not POSIX compliant must contain a file named `non-posix` containing a small explanation of why.
Finally, don't write a README and let the task `generate_readmes` do it for you :-) A description may be added in a file named `description` that will appear at the top of the README.
Follow the guideline to add a new test:
1. Create a sub-folder in `spec/` (e.g. `spec/minishell/builtin/cd/new-test/`)
2. If necessary, create a file `before_exec` that contains the shell commands that prepare the environment and the temporary resources (e.g. `mkdir valid_folder`)
2. Create a file `stdin` that contains the shell command you want to test (e.g. `cd invalid_folder`)
3. Create the files `stdout` and/or `stderr` that contain the expected output assertions (e.g. in stderr: `expected_to_not be_empty`) (see available assertions and verbs bellow)
4. You may also create a file `misc` that contains special expectations not concerning output on standard and error (e.g. `expected_to_not exit_with_status 0`)
5. If necessary, create a file `description` that describes more precisely the purpose of the test (e.g. `Trying to access invalid folder must display an error on standard error and result in a failure status code`) (the description will be included at top of the auto-generated README)
6. If the test is not POSIX compliant, create a file `non-posix` that explains why.
## Assertions
* **`expected_to`** / **`expected_to_not`** + *`verb`*: An assertion beginning with **expected_to** (or its opposite **expected_to_not**) makes the test resulting in failure status if the expectation that follows **does not** comply.
* **`might`** / **`might_not`** + *`verb`*: An assertion beginning with **might** (or its opposite **might_not**) always makes the test resulting in success status. When the expectation that follows **may not** comply, it is nevertheless considered as success but it displays a warning message.
## Verbs
* **`be_empty`**: Actual output is empty.
* **`create_file`** + *`$filename`*: Actual command creates a file named *$filename*. May also be followed with a file test:
* **`matching_regex`** + *`$regex`*: At least one line of the file matches with the regular expression *$regex*.
* **`not_matching_regex`** + *`$regex`*: Any line of the file does match with the regular expression *$regex*.
* **`with_nb_of_lines`** + *`$int`*: The file contains exactly *$int* lines.
* **`exit_with_status`** + *`$int`*: The Shell termination results in the exit status *$int*.
* **`have_nb_of_lines`** + *`$int`*: Actual output contains exactly *$int* lines.
* **`match_regex`** + *`$regex`*: At least one line of actual output does match with the regular expression *$regex*.
* **`once`**: The matching is limited to only one occurrence.
* *`$int`* **`times`**: The matching must exactly occur *$int* times.
* **`match_each_regex_of_file`** + *`$filename`*: Actual output does match with each regular expression contained in the file named *$filename* (in an indifferent order).
## Adding new verb
A verb is a function that is prefixed by `run_verb_` and that returns `0` or `1` according to the tested behavior. It may return a status `255` when bad or missing argument.
At runtime, the framework provides a list of variables that can be used by the verbs:
* **`RESPONSE`**: The path to the file containing actual output (STDOUT or STDERR)
* **`RESPONSE_EXIT_STATUS`**: The exit status of the Shell termination
* **`EXPECTED_TO_ARGS[]`**: An array containing the arguments following the verb
Follow the guideline to add a new verb:
1. Choose the best name that respects the *CamelCase* convention and that can be human-readable when used with an assertion (e.g. `expected_to be_empty` can be read `actual output is expected to be empty`)
2. Create a file in `lib/verbs/` with the exact name of the verb and that is prefixed with `run_verb_` (e.g. `lib/verbs/run_verb_be_empty.sh`
3. Add a *shebang*: `#!/bin/sh` and a comment that describes the tested behavior
4. Create a function with the exact name of the verb and that is prefixed with `run_verb_` (the same as the file name) and make it respect the following rules:
* Local variables must be declared with `local`
* No output can be done with `echo` or `printf`
* Function returns `0` on succes, `1` on fail or `255` on bad use
* Use the array `EXPECTED_TO_ARGS[]` to take advantage of arguments (e.g. `expected_to match_regex "regex"`, then `EXPECTED_TO_ARGS[0]` contains `regex`)
## Support binaries
The framework 42ShellTester provides several binaries to be used within the tests. Using them instead of using Unix binaries prevents from undefined behaviors and compatibility errors.
Find the available list of support binaries bellow:
<!--START_SUPPORT_BINARIES_LIST-->
* **[./display_env](http://github.com/we-sh/42ShellTester/tree/master/support/display-env)**: A binary that iterates on `**envp` and write each element on standard output.
* **[./display_program_name](http://github.com/we-sh/42ShellTester/tree/master/support/display-program-name)**: A binary that writes its name on standard ouput.
* **[./display_pwd](http://github.com/we-sh/42ShellTester/tree/master/support/display-pwd)**: A binary that writes on standard output the absolute path of the current directory returned by `getcwd(3)`, encountered with the strings `PWD:` and `:PWD`.
* **[./exit_with_status](http://github.com/we-sh/42ShellTester/tree/master/support/exit-with-status)**: A binary that immediately exits with the status given as first argument.
* **[./read_on_stdin](http://github.com/we-sh/42ShellTester/tree/master/support/read-on-stdin)**: A binary that reads on standard entry and write each line on standard output suffixed with the character `@` (e.g. same behavior as `cat -e` and the *newline* character). When `read(2)` returns `-1`, then the string `STDIN READ ERROR` is written on standard error.
* **[./sleep_and_exit_with_status](http://github.com/we-sh/42ShellTester/tree/master/support/sleep-and-exit-with-status)**: A binary that sleeps for a duration in seconds given as first argument and then exits with status given as second argument.
* **[./sleep_and_write_on_stderr](http://github.com/we-sh/42ShellTester/tree/master/support/sleep-and-write-on-stderr)**: A binary that sleeps for a duration in seconds given as first argument and then writes on STDERR the string given as second argument without EOL.
* **[./write_all_arguments_on_stdout](http://github.com/we-sh/42ShellTester/tree/master/support/write-all-arguments-on-stdout)**: A binary that writes on standard output each argument separated by the symbol `@`. If no argument is given, it writes the string "nothing to be written on stdout".
* **[./write_on_stderr](http://github.com/we-sh/42ShellTester/tree/master/support/write-on-stderr)**: A binary that writes on standard error the first given argument (the same behavior as `echo` but with only one argument) and exits with an error status code given as second argument. If no argument is given, it writes the string "write on stderr" and exit with status `1`.
* **[./write_on_stdout](http://github.com/we-sh/42ShellTester/tree/master/support/write-on-stdout)**: A binary that writes on standard output the first given argument (the same behavior as `echo` but with only one argument). If no argument is given, it writes the string "write on stdout".
* **[./write_on_stdout_and_stderr](http://github.com/we-sh/42ShellTester/tree/master/support/write-on-stdout-and-stderr)**: A binary that writes on standard output the first given argument, and writes on standard error the second given argument. If an argument is missing, it writes the strings "write on stdout" and "write on stderr".
<!--END_SUPPORT_BINARIES_LIST-->
## Tasks
* `bash ./tasks/generate_readmes.sh` (only on master branch) to automaticaly generate the README files of tests
# The Team
* **Adrien Nouvel** [@anouvel](https://github.com/anouvel)
* **Gabriel Kuma** [@gabkk](https://github.com/gabkk)
* **Jean-Michel Gigault** [@jgigault](https://github.com/jgigault)
## Logo credits
Edouard Audeguy
Illustrateur / Infographiste
https://edouardaudeguy.wix.com/portfolio

View file

@ -1,145 +0,0 @@
#!/bin/bash
# /*
# Assert logic
#
# run_assert
# @param -> prefix applied to output file name
# @param -> output that is tested (STDOUT, STDERR or MISC)
# function that:
# - sets the variable RESPONSE with the path of the file that stores the actual output
# - iterates over the current test configuration file ('stdout', 'stderr' or 'misc')
# - calls the expected type of assertion ('expected', 'might' or their opposite)
#
# run_expected_to
# run_expected_to_not
# run_might
# run_might_to
# @param -> current test (e.g. 'expected_to be_empty')
# functions that calls the verbs and treats their exit status
# */
run_assert()
{
local LINE
local PREFIX_STD="${1}"
local EXPECTED_STD="RESPONSE_${PREFIX_STD}${2}"
local RESPONSE="${!EXPECTED_STD}"
local EXPECTED_STD_NAME="${2}"
local RESPONSE_EXIT_STATUS_VAR="${PREFIX_STD}EXIT_STATUS"
local RESPONSE_EXIT_STATUS="${!RESPONSE_EXIT_STATUS_VAR}"
local TEST_CMD
local OLD_IFS="${IFS}"
local ASSERT_STATUS="0"
local CURRENT_ASSERT_STATUS
local DISPLAY_LINE
IFS=$'\n'
for LINE in $(awk '{gsub(/\\\\/, "\\\\\\\\\\\\\\\\"); print}' "${TEST}/$(echo "${EXPECTED_STD_NAME}" | awk '{print tolower($0)}')")
do
TEST_CMD="$(echo "${LINE}" | awk '{ print $1 }')"
DISPLAY_LINE="$(printf "${LINE}" | awk -v GLOBAL_TOKEN="${GLOBAL_TOKEN}" -v GLOBAL_INSTALLDIR="${GLOBAL_INSTALLDIR}" -v GLOBAL_TMP_DIRECTORY="${GLOBAL_TMP_DIRECTORY}" -v PATH="${PATH}" -v HOME="${HOME}" '{i=1; while(i <= NF) {gsub(/^"/, "`", $i); gsub(/"$/, "`", $i); i++}; gsub(/\\\\\\\\/, "\\"); gsub(/\$\{GLOBAL_TOKEN\}/, GLOBAL_TOKEN); gsub(/\$\{GLOBAL_INSTALLDIR\}/, GLOBAL_INSTALLDIR); gsub(/\$\{GLOBAL_TMP_DIRECTORY\}/, GLOBAL_TMP_DIRECTORY); gsub(/\$\{PATH\}/, PATH); gsub(/\$\{HOME\}/, HOME); print}')"
eval "run_${TEST_CMD}" ${LINE}
CURRENT_ASSERT_STATUS="${?}"
if [ "${CURRENT_ASSERT_STATUS}" != "0" ]
then
[ "${ASSERT_STATUS}" == "0" -o "${ASSERT_STATUS}" == "2" ] && ASSERT_STATUS="${CURRENT_ASSERT_STATUS}"
fi
done
IFS="${OLD_IFS}"
return "${ASSERT_STATUS}"
}
run_expected_to()
{
shift 1
local EXPECTED_TO_CMD="${1}"
shift 1
local -a EXPECTED_TO_ARGS='(${@})'
local ASSERT_STATUS
eval "run_verb_${EXPECTED_TO_CMD}"
ASSERT_STATUS="${?}"
case "${ASSERT_STATUS}" in
0)
printf "${C_GREEN} %-10s %s${C_CLEAR}\n" "SUCCESS" "${DISPLAY_LINE}" ;;
1)
printf "${C_RED} %-10s %s${C_CLEAR}\n" "FAILURE" "${DISPLAY_LINE}" ;;
255)
printf "${C_RED} [!] INVALID TEST COMMAND: %s${C_CLEAR}\n" "${DISPLAY_LINE}" ;;
esac
return "${ASSERT_STATUS}"
}
run_expected_to_not()
{
shift 1
local EXPECTED_TO_CMD="${1}"
shift 1
local -a EXPECTED_TO_ARGS='(${@})'
local ASSERT_STATUS
eval "run_verb_${EXPECTED_TO_CMD}"
ASSERT_STATUS="${?}"
case "${ASSERT_STATUS}" in
1)
ASSERT_STATUS="0"
printf "${C_GREEN} %-10s %s${C_CLEAR}\n" "SUCCESS" "${DISPLAY_LINE}" ;;
0)
ASSERT_STATUS="1"
printf "${C_RED} %-10s %s${C_CLEAR}\n" "FAILURE" "${DISPLAY_LINE}" ;;
255)
printf "${C_RED} [!] INVALID TEST COMMAND: %s${C_CLEAR}\n" "${DISPLAY_LINE}" ;;
esac
return "${ASSERT_STATUS}"
}
run_might()
{
shift 1
local EXPECTED_TO_CMD="${1}"
shift 1
local -a EXPECTED_TO_ARGS='(${@})'
local ASSERT_STATUS
eval "run_verb_${EXPECTED_TO_CMD}"
ASSERT_STATUS="${?}"
case "${ASSERT_STATUS}" in
0)
printf "${C_GREEN} %-10s %s${C_CLEAR}\n" "SUCCESS" "${DISPLAY_LINE}" ;;
1)
ASSERT_STATUS="2"
printf "${C_YELLOW} %-10s %s${C_CLEAR}\n" "WARNING" "${DISPLAY_LINE}" ;;
255)
printf "${C_RED} [!] INVALID TEST COMMAND: %s${C_CLEAR}\n" "${DISPLAY_LINE}" ;;
esac
return "${ASSERT_STATUS}"
}
run_might_not()
{
shift 1
local EXPECTED_TO_CMD="${1}"
shift 1
local -a EXPECTED_TO_ARGS='(${@})'
local ASSERT_STATUS
eval "run_verb_${EXPECTED_TO_CMD}"
ASSERT_STATUS="${?}"
case "${ASSERT_STATUS}" in
1)
ASSERT_STATUS="0"
printf "${C_GREEN} %-10s %s${C_CLEAR}\n" "SUCCESS" "${DISPLAY_LINE}" ;;
0)
ASSERT_STATUS="2"
printf "${C_YELLOW} %-10s %s${C_CLEAR}\n" "WARNING" "${DISPLAY_LINE}" ;;
255)
printf "${C_RED} [!] INVALID TEST COMMAND: ${EXPECTED_STD_NAME} %s${C_CLEAR}\n" "${DISPLAY_LINE}" ;;
esac
return "${ASSERT_STATUS}"
}

View file

@ -1,21 +0,0 @@
#### ########
#### ## ####
#### #####
########### ##### #
########### ########
####
################### ####
###################
###################
################### #####
########## #####
########## ############
########## ############
# ########## ############
### ######### #####
##### ####### #####
####### ##### #####
######### ### #####
####
###
##

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

View file

@ -1,5 +0,0 @@
## logo credits
<img align="right" src="./42ShellTester_cropped.png" width="45%" />Edouard Audeguy
Illustrateur / Infographiste
https://edouardaudeguy.wix.com/portfolio

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 654 B

View file

@ -1,280 +0,0 @@
#!/bin/bash
# /*
# Main function
#
# run_main
# function that:
# - iterates over the spec folder
# - executes the tests and their callbacks
# - displays the results
# */
run_main()
{
local TEST
local TEST_NAME
local TEST_FULLNAME
local RESULT
local RESPONSE_STDOUT
local RESPONSE_STDERR
local EXIT_STATUS
local RESPONSE_REFERENCE_STDOUT
local RESPONSE_REFERENCE_STDERR
local REFERENCE_EXIT_STATUS
local RUN_TEST
local RUN_ASSERT
local TEST_STATUS
local ASSERT_STATUS
local LOG_CURRENT_TEST
local LOG_CURRENT_TEST_STDOUT
local LOG_CURRENT_TEST_STDERR
local LOG_CURRENT_TEST_MISC
local LOG_SUCCESS_TESTS
local LOG_FAILED_TESTS
local AWK_PATH="$(which "awk")"
local OLD_IFS="${IFS}"
local UNAME=`uname`
local FIND="find"
# Use find instead find -E on Linux
if [ {UNAME} == "Darwin" ]; then
FIND= "find -E"
fi
if [ ! -f "${GLOBAL_PROG}" ]
then
[ "${GLOBAL_PROG}" == "" ] && printf "%s\n" "Missing argument: specify the binary to test" && return
[ ! -f "${GLOBAL_PROG}" -a ! -f "$(which "${GLOBAL_PROG}")" ] && printf "%s\n" "Wrong argument: no such file '"${GLOBAL_PROG}"'" && return
fi
IFS=$'\n'
for TEST in $(${FIND} "${GLOBAL_INSTALLDIR}/spec" -type d -regex "${GLOBAL_INSTALLDIR}/spec/.*${GLOBAL_SPECS_FILTER}.*")
do
[ -f "${TEST}/pending" -a "${GLOBAL_RUN_PENDING_TESTS}" == "0" ] && (( GLOBAL_TOTAL_PENDING_TESTS = GLOBAL_TOTAL_PENDING_TESTS + 1 ))
if [ -f "${TEST}/stdin" ] && [ ! -f "${TEST}/non-posix" -o "${GLOBAL_RUN_POSIX_ONLY}" == "0" ] && [ ! -f "${TEST}/pending" -o "${GLOBAL_RUN_PENDING_TESTS}" == "1" -o "${GLOBAL_RUN_ALL_TESTS}" == "1" ] && [ ! -f "${TEST}/hard" -o "${GLOBAL_RUN_HARD_TESTS}" == "1" -o "${GLOBAL_RUN_ALL_TESTS}" == "1" ]
then
# compile support binaries
make -C "${GLOBAL_INSTALLDIR}/support/" TARGET_DIR=${GLOBAL_TMP_DIRECTORY} 1>- 2>-
TEST_NAME="${TEST##*/}"
TEST_FULLNAME="${TEST##*spec/}"
RUN_TEST=0
TEST_STATUS="0"
LOG_CURRENT_TEST="${TEST_FULLNAME}"
LOG_CURRENT_TEST_STDOUT=""
LOG_CURRENT_TEST_STDERR=""
LOG_CURRENT_TEST_MISC=""
RESPONSE_STDOUT="${GLOBAL_TMP_DIRECTORY}/${TEST_FULLNAME//\//-}.stdout"
RESPONSE_STDERR="${GLOBAL_TMP_DIRECTORY}/${TEST_FULLNAME//\//-}.stderr"
RESPONSE_REFERENCE_STDOUT="${GLOBAL_TMP_DIRECTORY}/${TEST_FULLNAME//\//-}.ref.stdout"
RESPONSE_REFERENCE_STDERR="${GLOBAL_TMP_DIRECTORY}/${TEST_FULLNAME//\//-}.ref.stderr"
rm -f "${GLOBAL_TMP_DIRECTORY}/stdin"
local INDEX=1
local LINE
local TOTAL=$(awk 'END {print NR+1}' "${TEST}/stdin")
while [ "$INDEX" -le "$TOTAL" ]
do
awk -v INDEX="${INDEX}" -v GLOBAL_TOKEN="${GLOBAL_TOKEN}" -v GLOBAL_INSTALLDIR="${GLOBAL_INSTALLDIR}" -v GLOBAL_TMP_DIRECTORY="${GLOBAL_TMP_DIRECTORY}" -v PATH="${PATH}" -v HOME="${HOME}" 'NR == INDEX {gsub(/\$\{GLOBAL_TOKEN\}/, GLOBAL_TOKEN); gsub(/\$\{GLOBAL_INSTALLDIR\}/, GLOBAL_INSTALLDIR); gsub(/\$\{GLOBAL_TMP_DIRECTORY\}/, GLOBAL_TMP_DIRECTORY); gsub(/\$\{PATH\}/, PATH); gsub(/\$\{HOME\}/, HOME); print; exit}' "${TEST}/stdin" >>"${GLOBAL_TMP_DIRECTORY}/stdin"
(( INDEX += 1 ))
done
(
SUBSHELL_EXIT_STATUS=
if [ -f "${TEST}/before_exec" ]
then
local INDEX=0
local TOTAL=$(${AWK_PATH} 'END {print NR+1}' "${TEST}/before_exec")
while [ "$INDEX" -le "$TOTAL" ]
do
eval $(${AWK_PATH} -v INDEX="${INDEX}" 'NR == INDEX {print $0; exit}' "${TEST}/before_exec")
(( INDEX += 1 ))
done
fi
eval "${GLOBAL_PROG}" < "${GLOBAL_TMP_DIRECTORY}/stdin" 1> "${RESPONSE_STDOUT}.raw" 2> "${RESPONSE_STDERR}.raw"
SUBSHELL_EXIT_STATUS=${?}
if [ -f "${TEST}/after_exec" ]
then
local INDEX=0
local TOTAL=$(${AWK_PATH} 'END {print NR+1}' "${TEST}/after_exec")
while [ "$INDEX" -le "$TOTAL" ]
do
eval $(${AWK_PATH} -v INDEX="${INDEX}" 'NR == INDEX {print $0; exit}' "${TEST}/after_exec")
(( INDEX += 1 ))
done
fi
exit "${SUBSHELL_EXIT_STATUS}"
)
EXIT_STATUS=${?}
awk '{gsub(/\033\[[0-9;]*m/, ""); print}' "${RESPONSE_STDOUT}.raw" > "${RESPONSE_STDOUT}"
awk '{gsub(/\033\[[0-9;]*m/, ""); print}' "${RESPONSE_STDERR}.raw" > "${RESPONSE_STDERR}"
if [ "${GLOBAL_PROG_REFERENCE}" != "" ]
then
(
SUBSHELL_EXIT_STATUS=
if [ -f "${TEST}/before_exec" ]
then
local INDEX=0
local TOTAL=$(${AWK_PATH} 'END {print NR+1}' "${TEST}/before_exec")
while [ "$INDEX" -le "$TOTAL" ]
do
eval $(${AWK_PATH} -v INDEX="${INDEX}" 'NR == INDEX {print $0; exit}' "${TEST}/before_exec")
(( INDEX += 1 ))
done
fi
eval "${GLOBAL_PROG_REFERENCE}" < "${GLOBAL_TMP_DIRECTORY}/stdin" 1> "${RESPONSE_REFERENCE_STDOUT}.raw" 2> "${RESPONSE_REFERENCE_STDERR}.raw"
SUBSHELL_EXIT_STATUS=${?}
if [ -f "${TEST}/after_exec" ]
then
local INDEX=0
local TOTAL=$(${AWK_PATH} 'END {print NR+1}' "${TEST}/after_exec")
while [ "$INDEX" -le "$TOTAL" ]
do
eval $(${AWK_PATH} -v INDEX="${INDEX}" 'NR == INDEX {print $0; exit}' "${TEST}/after_exec")
(( INDEX += 1 ))
done
fi
exit "${SUBSHELL_EXIT_STATUS}"
)
REFERENCE_EXIT_STATUS=${?}
awk '{gsub(/\033\[[0-9;]*m/, ""); print}' "${RESPONSE_REFERENCE_STDOUT}.raw" > "${RESPONSE_REFERENCE_STDOUT}"
awk '{gsub(/\033\[[0-9;]*m/, ""); print}' "${RESPONSE_REFERENCE_STDERR}.raw" > "${RESPONSE_REFERENCE_STDERR}"
fi
if [ -f "${TEST}/stdout" ]
then
RUN_ASSERT="0"
if [ "${GLOBAL_PROG_REFERENCE}" != "" ]
then
run_assert "REFERENCE_" "STDOUT" 1>- 2>-
RUN_ASSERT="${?}"
fi
if [ "${RUN_ASSERT}" == "0" ]
then
LOG_CURRENT_TEST_STDOUT="$(run_assert "" "STDOUT")"
ASSERT_STATUS="${?}"
if [ "${ASSERT_STATUS}" != "0" ]
then
[ "${TEST_STATUS}" == "0" -o "${TEST_STATUS}" == "2" ] && TEST_STATUS="${ASSERT_STATUS}"
fi
RUN_TEST=1
fi
fi
if [ -f "${TEST}/stderr" ]
then
RUN_ASSERT="0"
if [ "${GLOBAL_PROG_REFERENCE}" != "" ]
then
run_assert "REFERENCE_" "STDERR" 1>- 2>-
RUN_ASSERT="${?}"
fi
if [ "${RUN_ASSERT}" == "0" ]
then
LOG_CURRENT_TEST_STDERR="$(run_assert "" "STDERR")"
ASSERT_STATUS="${?}"
if [ "${ASSERT_STATUS}" != "0" ]
then
[ "${TEST_STATUS}" == "0" -o "${TEST_STATUS}" == "2" ] && TEST_STATUS="${ASSERT_STATUS}"
fi
RUN_TEST=1
fi
fi
if [ -f "${TEST}/misc" ]
then
RUN_ASSERT="0"
if [ "${GLOBAL_PROG_REFERENCE}" != "" ]
then
run_assert "REFERENCE_" "MISC" 1>- 2>-
RUN_ASSERT="${?}"
fi
if [ "${RUN_ASSERT}" == "0" ]
then
LOG_CURRENT_TEST_MISC="$(run_assert "" "MISC")"
ASSERT_STATUS="${?}"
if [ "${ASSERT_STATUS}" != "0" ]
then
[ "${TEST_STATUS}" == "0" -o "${TEST_STATUS}" == "2" ] && TEST_STATUS="${ASSERT_STATUS}"
fi
RUN_TEST=1
fi
fi
if [ "${RUN_TEST}" == "1" ]
then
(( GLOBAL_TOTAL_TESTS = GLOBAL_TOTAL_TESTS + 1 ))
if [ "${TEST_STATUS}" != "0" -o "${GLOBAL_SHOW_SUCCESS}" == "1" ]
then
GLOBAL_LOG="$(printf "%s\n\n%s\n\n${C_BOLD}%s${C_CLEAR}" "${GLOBAL_LOG}" "----------------------------------------------------------------" "${LOG_CURRENT_TEST}")"
case "${TEST_STATUS}" in
0) GLOBAL_LOG="$(printf "%s ${C_GREEN}%s${C_CLEAR}" "${GLOBAL_LOG}" "(SUCCESS)")" ;;
1) GLOBAL_LOG="$(printf "%s ${C_RED}%s${C_CLEAR}" "${GLOBAL_LOG}" "(FAILED)")" ;;
2) GLOBAL_LOG="$(printf "%s ${C_YELLOW}%s${C_CLEAR}" "${GLOBAL_LOG}" "(WARNING)")" ;;
255) GLOBAL_LOG="$(printf "%s ${C_RED}%s${C_CLEAR}" "${GLOBAL_LOG}" "(RUNTIME ERROR)")" ;;
esac
[ -f "${TEST}/description" ] && GLOBAL_LOG="$(printf "%s\n\n Description:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk '{printf " %s\n", $0}' "${TEST}/description")")"
[ -f "${TEST}/before_exec" ] && GLOBAL_LOG="$(printf "%s\n\n Before test:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk -v GLOBAL_TOKEN="${GLOBAL_TOKEN}" -v GLOBAL_INSTALLDIR="${GLOBAL_INSTALLDIR}" -v GLOBAL_TMP_DIRECTORY="${GLOBAL_TMP_DIRECTORY}" -v PATH="${PATH}" -v HOME="${HOME}" '{gsub(/\$\{GLOBAL_TOKEN\}/, GLOBAL_TOKEN); gsub(/\$\{GLOBAL_INSTALLDIR\}/, GLOBAL_INSTALLDIR); gsub(/\$\{GLOBAL_TMP_DIRECTORY\}/, GLOBAL_TMP_DIRECTORY); gsub(/\$\{PATH\}/, PATH); gsub(/\$\{HOME\}/, HOME); printf " %02s: %s\n", NR, $0}' "${TEST}/before_exec")")"
GLOBAL_LOG="$(printf " %s\n\n STDIN:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk '{printf " %02s: %s\n", NR, $0}' "${GLOBAL_TMP_DIRECTORY}/stdin")")"
if [ "${LOG_CURRENT_TEST_STDOUT}" != "" ]
then
GLOBAL_LOG="$(printf "%s\n\n STDOUT:\n%s\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "${LOG_CURRENT_TEST_STDOUT}" "$(awk '{printf " %02s: %s\n", NR, $0} END {if (NR==0) { print " (no output)" }}' "${RESPONSE_STDOUT}")")"
else
GLOBAL_LOG="$(printf "%s\n\n STDOUT:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk '{printf " %02s: %s\n", NR, $0} END {if (NR==0) { print " (no output)" }}' "${RESPONSE_STDOUT}")")"
fi
if [ "${LOG_CURRENT_TEST_STDERR}" != "" ]
then
GLOBAL_LOG="$(printf "%s\n\n STDERR:\n%s\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "${LOG_CURRENT_TEST_STDERR}" "$(awk '{printf " %02s: %s\n", NR, $0} END {if (NR==0) { print " (no output)" }}' "${RESPONSE_STDERR}")")"
else
GLOBAL_LOG="$(printf "%s\n\n STDERR:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk '{printf " %02s: %s\n", NR, $0} END {if (NR==0) { print " (no output)" }}' "${RESPONSE_STDERR}")")"
fi
[ "${LOG_CURRENT_TEST_MISC}" != "" ] && GLOBAL_LOG="$(printf "%s\n\n MISC:\n%s" "${GLOBAL_LOG}" "${LOG_CURRENT_TEST_MISC}")"
[ -f "${TEST}/after_exec" ] && GLOBAL_LOG="$(printf "%s\n\n After test:\n${C_GREY}%s${C_CLEAR}" "${GLOBAL_LOG}" "$(awk -v GLOBAL_TOKEN="${GLOBAL_TOKEN}" -v GLOBAL_INSTALLDIR="${GLOBAL_INSTALLDIR}" -v GLOBAL_TMP_DIRECTORY="${GLOBAL_TMP_DIRECTORY}" -v PATH="${PATH}" -v HOME="${HOME}" '{gsub(/\$\{GLOBAL_TOKEN\}/, GLOBAL_TOKEN); gsub(/\$\{GLOBAL_INSTALLDIR\}/, GLOBAL_INSTALLDIR); gsub(/\$\{GLOBAL_TMP_DIRECTORY\}/, GLOBAL_TMP_DIRECTORY); gsub(/\$\{PATH\}/, PATH); gsub(/\$\{HOME\}/, HOME); printf " %02s: %s\n", NR, $0}' "${TEST}/after_exec")")"
[ "${TEST_STATUS}" == "1" ] && (( GLOBAL_TOTAL_FAILED_TESTS = GLOBAL_TOTAL_FAILED_TESTS + 1 ))
fi
case "${TEST_STATUS}" in
0) printf "${C_GREEN}.${C_CLEAR}" ;;
1) printf "${C_RED}x${C_CLEAR}" ;;
2) printf "${C_YELLOW}~${C_CLEAR}" ;;
255) printf "${C_RED}!${C_CLEAR}" ;;
esac
fi
fi
done
IFS="${OLD_IFS}"
}

View file

@ -1,16 +0,0 @@
#!/bin/bash
# /*
# Test emptiness of output
# RESPONSE -> actual output (stdout or stderr)
# */
run_verb_be_empty()
{
if [ "$(awk '{print}' "${RESPONSE}")" == "" ]
then
return 0
else
return 1
fi
}

View file

@ -1,47 +0,0 @@
#!/bin/bash
# /*
# Test file creation
# EXPECTED_TO_ARGS[0]* -> expected file path
# EXPECTED_TO_ARGS[1] -> file test (with_regexp, without_regexp, with_nb_of_lines)
# EXPECTED_TO_ARGS[2] -> argument of file test
# */
run_verb_create_file()
{
if [ -f "${EXPECTED_TO_ARGS[0]}" ]
then
if [ "${EXPECTED_TO_ARGS[1]}" == "" ]
then
return 0
else
case "${EXPECTED_TO_ARGS[1]}" in
matching_regex)
if [ "$(awk -v regexp="${EXPECTED_TO_ARGS[2]}" '$0 ~ regexp {print}' "${EXPECTED_TO_ARGS[0]}")" == "" ]
then
return 1
else
return 0
fi ;;
not_matching_regex)
if [ "$(awk -v regexp="${EXPECTED_TO_ARGS[2]}" '$0 ~ regexp {print}' "${EXPECTED_TO_ARGS[0]}")" == "" ]
then
return 0
else
return 1
fi ;;
with_nb_of_lines)
if [ "$(awk 'END {print NR}' "${EXPECTED_TO_ARGS[0]}")" == "${EXPECTED_TO_ARGS[2]}" ]
then
return 0
else
return 1
fi ;;
*)
return 255 ;;
esac
fi
else
return 1
fi
}

View file

@ -1,17 +0,0 @@
#!/bin/bash
# /*
# Test exit status
# EXPECTED_TO_ARGS[0]* -> expected exit status (integer)
# RESPONSE_EXIT_STATUS -> actual exit status
# */
run_verb_exit_with_status()
{
if [ "${RESPONSE_EXIT_STATUS}" == "${EXPECTED_TO_ARGS[0]}" ]
then
return 0
else
return 1
fi
}

View file

@ -1,17 +0,0 @@
#!/bin/bash
# /*
# Test number of output lines
# EXPECTED_TO_ARGS[0]* -> expected number of lines (integer)
# RESPONSE -> actual output (stdout or stderr)
# */
run_verb_have_nb_of_lines()
{
if [ "$(awk 'END {printf NR}' "${RESPONSE}")" == "${EXPECTED_TO_ARGS[0]}" ]
then
return 0
else
return 1
fi
}

View file

@ -1,28 +0,0 @@
#!/bin/bash
# /*
# Multiple test regular expression
# EXPECTED_TO_ARGS[0]* -> file path that stores expected regular expression
# RESPONSE -> actual output (stdout or stderr)
# */
run_verb_match_each_regex_of_file()
{
local INDEX=0 ERROR=0 TOTAL LINE
TOTAL=$(awk 'END {print NR+1}' "${EXPECTED_TO_ARGS[0]}")
while [ "${INDEX}" -le "${TOTAL}" ]
do
LINE="$(awk -v INDEX="${INDEX}" 'NR == INDEX {print; exit}' "${EXPECTED_TO_ARGS[0]}")"
if [ "$(awk -v regexp="${LINE}" '$0 ~ regexp {print}' "${RESPONSE}")" == "" ]
then
ERROR=1
fi
(( INDEX += 1 ))
done
if [ ${ERROR} -eq 1 ]
then
return 1
else
return 0
fi
}

View file

@ -1,38 +0,0 @@
#!/bin/bash
# /*
# Test regular expression
# EXPECTED_TO_ARGS[0]* -> expected regular expression match
# EXPECTED_TO_ARGS[1]* -> value 'once' or if next argument is value 'times', the number of times
# RESPONSE -> actual output (stdout or stderr)
# */
run_verb_match_regex()
{
local NB_OF_TIMES="0" RESULT
if [ "${EXPECTED_TO_ARGS[1]}" == "once" ]
then
NB_OF_TIMES="1"
fi
if [ "${EXPECTED_TO_ARGS[2]}" == "times" ]
then
NB_OF_TIMES="${EXPECTED_TO_ARGS[1]}"
fi
RESULT="$(awk -v regexp="${EXPECTED_TO_ARGS[0]}" 'BEGIN {TOTAL=0} $0 ~ regexp {TOTAL++} END {printf TOTAL}' "${RESPONSE}")"
if [ "${NB_OF_TIMES}" == "0" ]
then
if [ "${RESULT}" != "0" ]
then
return 0
else
return 1
fi
else
if [ "${RESULT}" == "${NB_OF_TIMES}" ]
then
return 0
else
return 1
fi
fi
}

View file

@ -1,346 +0,0 @@
...x...~......xx....~...~.....~.....~.....~...........
----------------------------------------------------------------
minishell/binary/004-binary-test-empty-path (FAILED)
Description:
 The purpose of this test is to check that the Shell finds binaries that are located in the current directory when the environment variable PATH is empty.
Before test:
 01: export PATH=""
STDIN:
 01: write_on_stdout "TOKEN201703252056"
STDOUT:
 FAILURE expected_to match_regex `TOKEN201703252056`
 (no output)
STDERR:
 FAILURE expected_to be_empty
 01: ../../42sh: command not found: write_on_stdout
MISC:
 FAILURE expected_to exit_with_status `0`
----------------------------------------------------------------
minishell/binary/008-binary-too-many-symbolic-links-encountered (WARNING)
Description:
 The purpose of this test is to check that trying to execute a path that encounters an infinite loop of symbolic link results in an error on standard error and a failure exit status.
Before test:
 01: rm -rf ./symbolic_link1 ./symbolic_link2 ./symbolic_link3
02: ln -s ./symbolic_link1 ./symbolic_link2
03: ln -s ./symbolic_link2 ./symbolic_link3
04: ln -s ./symbolic_link3 ./symbolic_link1
STDIN:
 01: ./symbolic_link1
STDOUT:
 SUCCESS might be_empty
 (no output)
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `[Tt]oo many.*symbolic links`
 01: ../../42sh: ./symbolic_link1: no such file or directory
MISC:
 SUCCESS expected_to_not exit_with_status 0
----------------------------------------------------------------
minishell/builtins/cd/007-symbolic-link (FAILED)
Description:
 The purpose of this test is to check that using a symbolic link as first argument with the builtin `cd` results in moving the linked directory.
Before test:
 01: rm -f "./symbolic_link"
02: mkdir -p "./sub_directory"
03: ln -s "./sub_directory" "./symbolic_link"
STDIN:
 01: cd symbolic_link
02: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
03: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_env
STDOUT:
 SUCCESS expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory:PWD$`
 FAILURE expected_to match_regex `^PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/symbolic_link$`
 01: PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory:PWD
02: ------------------------------
03: TERM_PROGRAM=iTerm.app
04: TERM=screen-256color
05: SHELL=/bin/zsh
06: HOMEBREW_TEMP=/tmp/ariard/Homebrew/Temp
07: TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n0002_2m000khn/T/
08: Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.h7gvN9K1go/Render
09: TERM_PROGRAM_VERSION=3.0.10
10: TERM_SESSION_ID=w0t0p1:D7FAE8F0-DDCC-428E-AC84-622B27EDC123
11: ZSH=/Users/ariard/.oh-my-zsh
12: USER=ariard
13: SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.1T0c86pYlP/Listeners
14: __CF_USER_TEXT_ENCODING=0x4A15:0x0:0x0
15: PAGER=less
16: TMUX=/private/tmp/tmux-18965/default,23758,2
17: HOMEBREW_CACHE=/tmp/ariard/Homebrew/Caches
18: LSCOLORS=Gxfxcxdxbxegedabagacad
19: PATH=/Users/ariard/.brew/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/munki://Users/ariard/local/bin
20: MAIL=ariard@student.42.fr
21: PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory
22: LANG=en_US.UTF-8
23: ITERM_PROFILE=Default
24: XPC_FLAGS=0x0
25: TMUX_PANE=%21
26: XPC_SERVICE_NAME=0
27: SHLVL=4
28: HOME=/Users/ariard
29: COLORFGBG=7;0
30: ITERM_SESSION_ID=w0t0p1:D7FAE8F0-DDCC-428E-AC84-622B27EDC123
31: LOGNAME=ariard
32: LESS=-R
33: LC_CTYPE=en_US.UTF-8
34: TMUX_PLUGIN_MANAGER_PATH=/Users/ariard/.tmux/plugins/
35: OLDPWD=/Users/ariard/Projects/42sh/42ShellTester/tmp
36: _=../../42sh
37: ?=0
38: ------------------------------
39: TOTAL ENVIRONMENT VARIABLES: 35
STDERR:
 SUCCESS expected_to be_empty
 (no output)
----------------------------------------------------------------
minishell/builtins/cd/008-symbolic-link-2 (FAILED)
Description:
 The purpose of this test is to check that using a symbolic link as first argument with the builtin `cd` results in moving to the linked directory. In this test, the directory is linked with to chained symbolic links.
Before test:
 01: rm -f "./symbolic_link1" "./symbolic_link2"
02: mkdir -p "./sub_directory"
03: ln -s "./sub_directory" "./symbolic_link1"
04: ln -s "./symbolic_link1" "./symbolic_link2"
STDIN:
 01: cd symbolic_link2
02: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
03: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_env
STDOUT:
 SUCCESS expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory:PWD$`
 FAILURE expected_to match_regex `^PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/symbolic_link2$`
 01: PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory:PWD
02: ------------------------------
03: TERM_PROGRAM=iTerm.app
04: TERM=screen-256color
05: SHELL=/bin/zsh
06: HOMEBREW_TEMP=/tmp/ariard/Homebrew/Temp
07: TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n0002_2m000khn/T/
08: Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.h7gvN9K1go/Render
09: TERM_PROGRAM_VERSION=3.0.10
10: TERM_SESSION_ID=w0t0p1:D7FAE8F0-DDCC-428E-AC84-622B27EDC123
11: ZSH=/Users/ariard/.oh-my-zsh
12: USER=ariard
13: SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.1T0c86pYlP/Listeners
14: __CF_USER_TEXT_ENCODING=0x4A15:0x0:0x0
15: PAGER=less
16: TMUX=/private/tmp/tmux-18965/default,23758,2
17: HOMEBREW_CACHE=/tmp/ariard/Homebrew/Caches
18: LSCOLORS=Gxfxcxdxbxegedabagacad
19: PATH=/Users/ariard/.brew/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/munki://Users/ariard/local/bin
20: MAIL=ariard@student.42.fr
21: PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory
22: LANG=en_US.UTF-8
23: ITERM_PROFILE=Default
24: XPC_FLAGS=0x0
25: TMUX_PANE=%21
26: XPC_SERVICE_NAME=0
27: SHLVL=4
28: HOME=/Users/ariard
29: COLORFGBG=7;0
30: ITERM_SESSION_ID=w0t0p1:D7FAE8F0-DDCC-428E-AC84-622B27EDC123
31: LOGNAME=ariard
32: LESS=-R
33: LC_CTYPE=en_US.UTF-8
34: TMUX_PLUGIN_MANAGER_PATH=/Users/ariard/.tmux/plugins/
35: OLDPWD=/Users/ariard/Projects/42sh/42ShellTester/tmp
36: _=../../42sh
37: ?=0
38: ------------------------------
39: TOTAL ENVIRONMENT VARIABLES: 35
STDERR:
 SUCCESS expected_to be_empty
 (no output)
----------------------------------------------------------------
minishell/builtins/cd/errors/001-not-a-directory (WARNING)
Description:
 The purpose of this test is to check that using a file name as first argument with the builtin `cd` results in error and not changing current directory.
Before test:
 01: touch "./not_a_directory"
STDIN:
 01: cd not_a_directory
02: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
STDOUT:
 SUCCESS expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD`
 01: PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `[Nn]ot a directory`
 01: ../../42sh: cd : ./not_a_directory: Permission denied
----------------------------------------------------------------
minishell/builtins/cd/errors/005-too-many-symbolic-links-encountered (WARNING)
Description:
 The purpose of this test is to check that using a symbolic link resulting in ELOOP error as first argument with the builtin `cd` results in error and not changing current directory.
Before test:
 01: rm -f "./symbolic_link1" "./symbolic_link2" "./symbolic_link3"
02: ln -s "./symbolic_link1" "./symbolic_link2"
03: ln -s "./symbolic_link2" "./symbolic_link3"
04: ln -s "./symbolic_link3" "./symbolic_link1"
STDIN:
 01: cd symbolic_link1
02: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
STDOUT:
 SUCCESS expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD`
 01: PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `[Tt]oo many.*symbolic links`
 01: ../../42sh: cd : ./symbolic_link1: No such file or directory
----------------------------------------------------------------
minishell/builtins/cd/options/001-not-following-links (WARNING)
Description:
 The purpose of this test is to check that using symbolic links twice with the builtin `cd` and the option `-P` results in a correct environment variable PWD. The option `-P` makes the Shell to resolve symbolic links.
Before test:
 01: rm -fr "./sub_directory_link" "./sub_directory"
02: mkdir -p "./sub_directory/sub_sub_directory"
03: ln -s "./sub_directory" "./sub_directory_link"
04: ln -s "./sub_sub_directory" "./sub_directory/sub_sub_directory_link"
STDIN:
 01: cd -P sub_directory_link
02: cd -P sub_sub_directory_link
03: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_env
STDOUT:
 SUCCESS expected_to match_regex `PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory/sub_sub_directory`
 01: ------------------------------
02: TERM_PROGRAM=iTerm.app
03: TERM=screen-256color
04: SHELL=/bin/zsh
05: HOMEBREW_TEMP=/tmp/ariard/Homebrew/Temp
06: TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n0002_2m000khn/T/
07: Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.h7gvN9K1go/Render
08: TERM_PROGRAM_VERSION=3.0.10
09: TERM_SESSION_ID=w0t0p1:D7FAE8F0-DDCC-428E-AC84-622B27EDC123
10: ZSH=/Users/ariard/.oh-my-zsh
11: USER=ariard
12: SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.1T0c86pYlP/Listeners
13: __CF_USER_TEXT_ENCODING=0x4A15:0x0:0x0
14: PAGER=less
15: TMUX=/private/tmp/tmux-18965/default,23758,2
16: HOMEBREW_CACHE=/tmp/ariard/Homebrew/Caches
17: LSCOLORS=Gxfxcxdxbxegedabagacad
18: PATH=/Users/ariard/.brew/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/munki://Users/ariard/local/bin
19: MAIL=ariard@student.42.fr
20: PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory/sub_sub_directory
21: LANG=en_US.UTF-8
22: ITERM_PROFILE=Default
23: XPC_FLAGS=0x0
24: TMUX_PANE=%21
25: XPC_SERVICE_NAME=0
26: SHLVL=4
27: HOME=/Users/ariard
28: COLORFGBG=7;0
29: ITERM_SESSION_ID=w0t0p1:D7FAE8F0-DDCC-428E-AC84-622B27EDC123
30: LOGNAME=ariard
31: LESS=-R
32: LC_CTYPE=en_US.UTF-8
33: TMUX_PLUGIN_MANAGER_PATH=/Users/ariard/.tmux/plugins/
34: OLDPWD=/Users/ariard/Projects/42sh/42ShellTester
35: _=../../42sh
36: ?=73
37: ------------------------------
38: TOTAL ENVIRONMENT VARIABLES: 35
STDERR:
 WARNING might be_empty
 01: ../../42sh: cd : ./sub_directory_link: Symlink not resolved
02: ../../42sh: cd : ./sub_sub_directory_link: Symlink not resolved
----------------------------------------------------------------
minishell/builtins/env/errors/001-command-not-found (WARNING)
Description:
 The purpose of this test is to check that using the builtin `env` with an invalid binary as argument results in an error and failure exit status.
Before test:
 01: rm -f "./invalid_binary"
STDIN:
 01: env ./invalid_binary
STDOUT:
 (no output)
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `[Cc]ommand not found`
 01: ../../42sh: env: ./invalid_binary: No such file or directory
MISC:
 SUCCESS expected_to_not exit_with_status `0`
----------------------------------------------------------------
minishell/builtins/exit/errors/001-too-many-args (WARNING)
Description:
 The purpose of this test is to check that using a wrong number of arguments with the builtin `exit` does not result in the Shell termination but an error on standard error.
STDIN:
 01: exit 21 42
02: ./write_on_stdout TOKEN201703252056
STDOUT:
 SUCCESS expected_to match_regex `TOKEN201703252056`
 01: TOKEN201703252056
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `([Tt]oo many arguments|[Aa]rgument list too long)`
 01: ../../42sh: exit: too many argument required
MISC:
 SUCCESS expected_to exit_with_status `0`
Total tests: 54
Total failed tests: 3
Total pending tests: 0

View file

@ -1 +0,0 @@
.

View file

@ -1,6 +0,0 @@
# spec
* [21sh](./21sh)
* [42sh](./42sh)
* [bonuses](./bonuses)
* [minishell](./minishell)

View file

@ -1,29 +0,0 @@
TARGET_DIR=../../tmp
all:
make TARGET_DIR=$(TARGET_DIR) -C ./display-env
make TARGET_DIR=$(TARGET_DIR) -C ./display-program-name
make TARGET_DIR=$(TARGET_DIR) -C ./display-pwd
make TARGET_DIR=$(TARGET_DIR) -C ./exit-with-status
make TARGET_DIR=$(TARGET_DIR) -C ./read-on-stdin
make TARGET_DIR=$(TARGET_DIR) -C ./sleep-and-exit-with-status
make TARGET_DIR=$(TARGET_DIR) -C ./sleep-and-write-on-stderr
make TARGET_DIR=$(TARGET_DIR) -C ./write-all-arguments-on-stdout
make TARGET_DIR=$(TARGET_DIR) -C ./write-on-stderr
make TARGET_DIR=$(TARGET_DIR) -C ./write-on-stdout
make TARGET_DIR=$(TARGET_DIR) -C ./write-on-stdout-and-stderr
re: fclean all
fclean:
make TARGET_DIR=$(TARGET_DIR) fclean -C ./display-env
make TARGET_DIR=$(TARGET_DIR) fclean -C ./display-program-name
make TARGET_DIR=$(TARGET_DIR) fclean -C ./display-pwd
make TARGET_DIR=$(TARGET_DIR) fclean -C ./exit-with-status
make TARGET_DIR=$(TARGET_DIR) fclean -C ./read-on-stdin
make TARGET_DIR=$(TARGET_DIR) fclean -C ./sleep-and-exit-with-status
make TARGET_DIR=$(TARGET_DIR) fclean -C ./sleep-and-write-on-stderr
make TARGET_DIR=$(TARGET_DIR) fclean -C ./write-all-arguments-on-stdout
make TARGET_DIR=$(TARGET_DIR) fclean -C ./write-on-stderr
make TARGET_DIR=$(TARGET_DIR) fclean -C ./write-on-stdout
make TARGET_DIR=$(TARGET_DIR) fclean -C ./write-on-stdout-and-stderr

View file

@ -1,12 +0,0 @@
NAME=display_env
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,28 +0,0 @@
# ./display_env
A binary that iterates on `**envp` and write each element on standard output.
```c
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp)
{
int i;
i = 0;
(void)argc;
(void)argv;
write(1, "------------------------------\n", 31);
while (envp[i])
{
write(1, envp[i], strlen(envp[i]));
write(1, "\n", 1);
i++;
}
write(1, "------------------------------\n", 31);
printf("TOTAL ENVIRONMENT VARIABLES: %d\n", i);
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that iterates on `**envp` and write each element on standard output.

View file

@ -1,22 +0,0 @@
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv, char **envp)
{
int i;
i = 0;
(void)argc;
(void)argv;
write(1, "------------------------------\n", 31);
while (envp[i])
{
write(1, envp[i], strlen(envp[i]));
write(1, "\n", 1);
i++;
}
write(1, "------------------------------\n", 31);
printf("TOTAL ENVIRONMENT VARIABLES: %d\n", i);
return (0);
}

View file

@ -1,12 +0,0 @@
NAME=display_program_name
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,16 +0,0 @@
# ./display_program_name
A binary that writes its name on standard ouput.
```c
#include <unistd.h>
#include <string.h>
int main(int ac, char **av)
{
(void)ac;
write(1, av[0], strlen(av[0]));
write(1, "\n", 1);
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that writes its name on standard ouput.

View file

@ -1,10 +0,0 @@
#include <unistd.h>
#include <string.h>
int main(int ac, char **av)
{
(void)ac;
write(1, av[0], strlen(av[0]));
write(1, "\n", 1);
return (0);
}

View file

@ -1,12 +0,0 @@
NAME=display_pwd
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,19 +0,0 @@
# ./display_pwd
A binary that writes on standard output the absolute path of the current directory returned by `getcwd(3)`, encountered with the strings `PWD:` and `:PWD`.
```c
#include <unistd.h>
#include <string.h>
int main(void)
{
char *pwd;
pwd = getcwd(NULL, 0);
write(1, "PWD:", 4);
write(1, pwd, strlen(pwd));
write(1, ":PWD\n", 5);
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that writes on standard output the absolute path of the current directory returned by `getcwd(3)`, encountered with the strings `PWD:` and `:PWD`.

View file

@ -1,13 +0,0 @@
#include <unistd.h>
#include <string.h>
int main(void)
{
char *pwd;
pwd = getcwd(NULL, 0);
write(1, "PWD:", 4);
write(1, pwd, strlen(pwd));
write(1, ":PWD\n", 5);
return (0);
}

View file

@ -1,12 +0,0 @@
NAME=exit_with_status
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,15 +0,0 @@
# ./exit_with_status
A binary that immediately exits with the status given as first argument.
```c
#include <stdlib.h>
int main(int argc, char **argv)
{
(void)argc;
if (argc == 2)
return (atoi(argv[1]));
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that immediately exits with the status given as first argument.

View file

@ -1,9 +0,0 @@
#include <stdlib.h>
int main(int argc, char **argv)
{
(void)argc;
if (argc == 2)
return (atoi(argv[1]));
return (0);
}

View file

@ -1,12 +0,0 @@
NAME=read_on_stdin
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,27 +0,0 @@
# ./read_on_stdin
A binary that reads on standard entry and write each line on standard output suffixed with the character `@` (e.g. same behavior as `cat -e` and the *newline* character). When `read(2)` returns `-1`, then the string `STDIN READ ERROR` is written on standard error.
```c
#include <unistd.h>
#include <string.h>
int main(void)
{
char buf[1];
int ret;
while ((ret = read(0, buf, 1)) > 0)
{
if (buf[0] == '\n')
write(1, "@", 1);
write(1, buf, ret);
}
if (ret < 0)
{
write(2, "STDIN READ ERROR\n", 17);
return (1);
}
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that reads on standard entry and write each line on standard output suffixed with the character `@` (e.g. same behavior as `cat -e` and the *newline* character). When `read(2)` returns `-1`, then the string `STDIN READ ERROR` is written on standard error.

View file

@ -1,21 +0,0 @@
#include <unistd.h>
#include <string.h>
int main(void)
{
char buf[1];
int ret;
while ((ret = read(0, buf, 1)) > 0)
{
if (buf[0] == '\n')
write(1, "@", 1);
write(1, buf, ret);
}
if (ret < 0)
{
write(2, "STDIN READ ERROR\n", 17);
return (1);
}
return (0);
}

View file

@ -1,12 +0,0 @@
NAME=sleep_and_exit_with_status
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,22 +0,0 @@
# ./sleep_and_exit_with_status
A binary that sleeps for a duration in seconds given as first argument and then exits with status given as second argument.
```c
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int seconds;
seconds = 1;
if (argc > 1)
seconds = atoi(argv[1]);
sleep(seconds);
if (argc > 2)
return (atoi(argv[2]));
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that sleeps for a duration in seconds given as first argument and then exits with status given as second argument.

View file

@ -1,16 +0,0 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int seconds;
seconds = 1;
if (argc > 1)
seconds = atoi(argv[1]);
sleep(seconds);
if (argc > 2)
return (atoi(argv[2]));
return (0);
}

View file

@ -1,12 +0,0 @@
NAME=sleep_and_write_on_stderr
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,24 +0,0 @@
# ./sleep_and_write_on_stderr
A binary that sleeps for a duration in seconds given as first argument and then writes on STDERR the string given as second argument without EOL.
```c
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int seconds;
seconds = 1;
if (argc > 1)
seconds = atoi(argv[1]);
sleep(seconds);
if (argc > 2)
{
write(2, argv[2], strlen(argv[2]));
}
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that sleeps for a duration in seconds given as first argument and then writes on STDERR the string given as second argument without EOL.

View file

@ -1,18 +0,0 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int seconds;
seconds = 1;
if (argc > 1)
seconds = atoi(argv[1]);
sleep(seconds);
if (argc > 2)
{
write(2, argv[2], strlen(argv[2]));
}
return (0);
}

View file

@ -1,12 +0,0 @@
NAME=write_all_arguments_on_stdout
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,28 +0,0 @@
# ./write_all_arguments_on_stdout
A binary that writes on standard output each argument separated by the symbol `@`. If no argument is given, it writes the string "nothing to be written on stdout".
```c
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc >= 2)
{
argv++;
while (*argv)
{
write(1, *argv, strlen(*argv));
write(1, "@", 1);
argv++;
}
write(1, "\n", 1);
}
else
{
write(1, "nothing to be written on stdout\n", 32);
}
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that writes on standard output each argument separated by the symbol `@`. If no argument is given, it writes the string "nothing to be written on stdout".

View file

@ -1,22 +0,0 @@
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc >= 2)
{
argv++;
while (*argv)
{
write(1, *argv, strlen(*argv));
write(1, "@", 1);
argv++;
}
write(1, "\n", 1);
}
else
{
write(1, "nothing to be written on stdout\n", 32);
}
return (0);
}

View file

@ -1,12 +0,0 @@
NAME=write_on_stderr
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,25 +0,0 @@
# ./write_on_stderr
A binary that writes on standard error the first given argument (the same behavior as `echo` but with only one argument) and exits with an error status code given as second argument. If no argument is given, it writes the string "write on stderr" and exit with status `1`.
```c
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc > 1)
{
write(2, argv[1], strlen(argv[1]));
write(2, "\n", 1);
}
else
{
write(2, "write on stderr\n", 16);
}
if (argc == 3)
return (atoi(argv[2]));
return (1);
}
```

View file

@ -1 +0,0 @@
A binary that writes on standard error the first given argument (the same behavior as `echo` but with only one argument) and exits with an error status code given as second argument. If no argument is given, it writes the string "write on stderr" and exit with status `1`.

View file

@ -1,19 +0,0 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc > 1)
{
write(2, argv[1], strlen(argv[1]));
write(2, "\n", 1);
}
else
{
write(2, "write on stderr\n", 16);
}
if (argc == 3)
return (atoi(argv[2]));
return (1);
}

View file

@ -1,12 +0,0 @@
NAME=write_on_stdout_and_stderr
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,25 +0,0 @@
# ./write_on_stdout_and_stderr
A binary that writes on standard output the first given argument, and writes on standard error the second given argument. If an argument is missing, it writes the strings "write on stdout" and "write on stderr".
```c
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc == 3)
{
write(1, argv[1], strlen(argv[1]));
write(1, "\n", 1);
write(2, argv[2], strlen(argv[2]));
write(2, "\n", 1);
}
else
{
write(1, "write on stdout\n", 16);
write(2, "write on stderr\n", 16);
}
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that writes on standard output the first given argument, and writes on standard error the second given argument. If an argument is missing, it writes the strings "write on stdout" and "write on stderr".

View file

@ -1,19 +0,0 @@
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc == 3)
{
write(1, argv[1], strlen(argv[1]));
write(1, "\n", 1);
write(2, argv[2], strlen(argv[2]));
write(2, "\n", 1);
}
else
{
write(1, "write on stdout\n", 16);
write(2, "write on stderr\n", 16);
}
return (0);
}

View file

@ -1,12 +0,0 @@
NAME=write_on_stdout
TARGET_DIR=.
$(NAME): all
all:
gcc -Wall -Werror -Wextra main.c -o "$(TARGET_DIR)/$(NAME)"
fclean:
rm -f "$(TARGET_DIR)/$(NAME)"
re: fclean all

View file

@ -1,22 +0,0 @@
# ./write_on_stdout
A binary that writes on standard output the first given argument (the same behavior as `echo` but with only one argument). If no argument is given, it writes the string "write on stdout".
```c
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc == 2)
{
write(1, argv[1], strlen(argv[1]));
write(1, "\n", 1);
}
else
{
write(1, "write on stdout\n", 16);
}
return (0);
}
```

View file

@ -1 +0,0 @@
A binary that writes on standard output the first given argument (the same behavior as `echo` but with only one argument). If no argument is given, it writes the string "write on stdout".

View file

@ -1,16 +0,0 @@
#include <unistd.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc == 2)
{
write(1, argv[1], strlen(argv[1]));
write(1, "\n", 1);
}
else
{
write(1, "write on stdout\n", 16);
}
return (0);
}

View file

@ -1,181 +0,0 @@
#!/bin/bash
GLOBAL_INSTALLDIR="$(pwd)"
GLOBAL_TMP_DIRECTORY="${GLOBAL_INSTALLDIR}/tmp"
GLOBAL_LOCALBRANCH=$(git branch | awk '$0 ~ /^\*/ {print $2; exit}')
GLOBAL_LIST_OF_TESTS=
GLOBAL_TOTAL_TESTS=0
GLOBAL_SUPPORT_BINARIES_LIST=""
GLOBAL_SUPPORT_BINARIES_LIST2=""
if [ "${GLOBAL_LOCALBRANCH}" != "master" ]
then
printf "%s\n" "Task error: must be run in master branch to ensure pull requests to keep clean"
exit 1
fi
if [ -f "./tasks/${BASH_SOURCE[0]}" ]
then
printf "%s\n" "Task error: must be run from install directory"
exit 1
fi
run_create_support_binaries_readme()
{
local SUPPORT_FILE
local README
local SUPPORT_FILE_NAME
for SUPPORT_FILE in ./support/*
do
if [ -d "${SUPPORT_FILE}" ]
then
README="${SUPPORT_FILE}/README.md"
SUPPORT_MAIN="${SUPPORT_FILE}/main.c"
SUPPORT_DESCRIPTION="${SUPPORT_FILE}/description"
SUPPORT_DIR_NAME="${SUPPORT_FILE##*/}"
SUPPORT_BINARY_NAME="${SUPPORT_DIR_NAME//-/_}"
printf "# %s\n\n" "./${SUPPORT_BINARY_NAME}" >"${README}"
[ -f "${SUPPORT_DESCRIPTION}" ] && printf "%s\n\n" "$(cat "${SUPPORT_DESCRIPTION}")" >>"${README}"
printf "\`\`\`c\n%s\n\`\`\`\n" "$(cat "${SUPPORT_MAIN}")" >>"${README}"
GLOBAL_SUPPORT_BINARIES_LIST="$(printf "%s\n%s" "${GLOBAL_SUPPORT_BINARIES_LIST}" "* **[./${SUPPORT_BINARY_NAME}](http://github.com/we-sh/42ShellTester/tree/master/support/${SUPPORT_DIR_NAME})** -> $(cat "${SUPPORT_DESCRIPTION}")")"
GLOBAL_SUPPORT_BINARIES_LIST2="${GLOBAL_SUPPORT_BINARIES_LIST2}\n\052 **[./${SUPPORT_BINARY_NAME}](http://github.com/we-sh/42ShellTester/tree/master/support/${SUPPORT_DIR_NAME})**: $(cat "${SUPPORT_DESCRIPTION}")"
fi
done
}
run_create_support_binaries_readme
run_create_readme()
{
local INDEX="${1}"
local TEST="${2}"
local TEST_NAME="${TEST##*/}"
local TEST_FULLNAME="${TEST##*spec/}"
local PARENT_DIR_NAME="${TEST%/*}"
local README="${TEST}/README.md"
(( GLOBAL_TOTAL_TESTS= GLOBAL_TOTAL_TESTS + 1 ))
printf "# %s\n\n" "${TEST_NAME}" >"${README}"
printf "*[%s](%s) > %s*\n\n" "${PARENT_DIR_NAME//\// > }" ".." "${DIR_NAME}" >>"${README}"
if [ -f "${TEST}/description" ]; then cat "${TEST}/description" >>"${README}"; fi
if [ -f "${TEST}/before_exec" ]
then
printf "### What is done before test\n\n\`\`\`bash\n" >>"${README}"
cat "${TEST}/before_exec" >>"${README}"
printf "\n\`\`\`\n\n" >>"${README}"
fi
printf "### Shell commands that are sent to the standard entry\n\n\`\`\`bash\n" >>"${README}"
cat "${TEST}/stdin" >>"${README}"
printf "\n\`\`\`\n\n" >>"${README}"
if [ -f "${TEST}/stdout" ]
then
printf "### What is expected on standard output\n\n\`\`\`bash\n" >>"${README}"
cat "${TEST}/stdout" >>"${README}"
printf "\n\`\`\`\n\n" >>"${README}"
fi
if [ -f "${TEST}/stderr" ]
then
printf "### What is expected on error output\n\n\`\`\`bash\n" >>"${README}"
cat "${TEST}/stderr" >>"${README}"
printf "\n\`\`\`\n\n" >>"${README}"
fi
if [ -f "${TEST}/misc" ]
then
printf "### What miscellaneous behaviors are expected\n\n\`\`\`bash\n" >>"${README}"
cat "${TEST}/misc" >>"${README}"
printf "\n\`\`\`\n\n" >>"${README}"
fi
printf "### Variables\n\nThe following variables may appear in this test:\n\n" >>"${README}"
printf "* \${**GLOBAL_INSTALLDIR**} -> The installation directory of 42ShellTester\n" >>"${README}"
printf "* \${**GLOBAL_TMP_DIRECTORY**} -> The temporary directory in which tests are executed\n" >>"${README}"
printf "* \${**GLOBAL_TOKEN**} -> A token that changes value at launch time\n" >>"${README}"
printf "* \${**PATH**} -> The standard environment variable PATH\n" >>"${README}"
printf "* \${**HOME**} -> The standard environment variable HOME\n\n" >>"${README}"
printf "### Support binaries\n\nThe following binaries may appear in this test:\n\n%s\n" "${GLOBAL_SUPPORT_BINARIES_LIST}" >>"${README}"
}
run_browse_directory()
{
local -i INDEX=${1}
local DIR="${2}"
local DIR_NAME="${DIR##*/}"
local DIR_FULLNAME="${DIR##*spec/}"
local PARENT_DIR_NAME="${DIR%/*}"
local README="${DIR}/README.md"
local SUBDIR
local IMGS=""
if [ -f "${DIR}/stdin" ]
then
[ -f "${DIR}/non-posix" ] && IMGS=" <img src='./lib/assets/non-posix.png' width='63' height='12' />"
[ -f "${DIR}/hard" ] && IMGS="${IMGS} <img src='./lib/assets/hard.png' width='38' height='12' />"
[ -f "${DIR}/pending" ] && IMGS="${IMGS} <img src='./lib/assets/pending.png' width='54' height='12' />"
GLOBAL_LIST_OF_TESTS="${GLOBAL_LIST_OF_TESTS}$(printf "% $(( INDEX * 2 ))s\052 [%s](%s)" "" "${DIR_NAME}${IMGS}" "${DIR}")\n"
run_create_readme "${INDEX}" "${DIR}"
else
[ "${INDEX}" != "-1" ] && GLOBAL_LIST_OF_TESTS="${GLOBAL_LIST_OF_TESTS}$(printf "% $(( INDEX * 2 ))s\052 **[%s/](%s)**" "" "${DIR_NAME}" "${DIR}")\n"
printf "# %s\n\n" "${DIR_NAME}" >"${README}"
[ "${INDEX}" != "-1" ] && printf "*[%s](%s) > %s*\n\n" "${PARENT_DIR_NAME//\// > }" ".." "${DIR_NAME}" >>"${README}"
for SUBDIR in $(ls -1 "${DIR}")
do
if [ -d "${DIR}/${SUBDIR}" ]
then
printf "\052 [%s](%s)\n" "${SUBDIR}" "./${SUBDIR}" >>"${README}"
run_browse_directory "$(( INDEX + 1 ))" "${DIR}/${SUBDIR}"
fi
done
fi
}
run_browse_directory -1 "spec"
awk -v SUPPORT_BINARIES_LIST="${GLOBAL_SUPPORT_BINARIES_LIST2}\n" -v LIST="${GLOBAL_LIST_OF_TESTS}" -v GLOBAL_TOTAL_TESTS="${GLOBAL_TOTAL_TESTS}" '
BEGIN {
INSERT_DATA=0
}
INSERT_DATA == 0 {
print
}
$0 ~ /<!--START_TOTAL_TESTS-->/ {
INSERT_DATA=1;
print "42ShellTester is currently packaged with **"GLOBAL_TOTAL_TESTS" tests**."
}
$0 ~ /<!--END_TOTAL_TESTS-->/ {
INSERT_DATA=0;
print
}
$0 ~ /<!--START_SUPPORT_BINARIES_LIST-->/ {
INSERT_DATA=1;
print SUPPORT_BINARIES_LIST
}
$0 ~ /<!--END_SUPPORT_BINARIES_LIST-->/ {
INSERT_DATA=0;
print
}
$0 ~ /<!--START_LIST_TESTS-->/ {
INSERT_DATA=1;
print LIST
}
$0 ~ /<!--END_LIST_TESTS-->/ {
INSERT_DATA=0;
print
}
' README.md > README.new.md && rm -f README.md && mv README.new.md README.md

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1 @@
alao
ariard
gwojda
jhalford jhalford
wescande

View file

@ -1,533 +0,0 @@
ls
cat
`ls`
`
`ls`
`ls`
`ls`
cat *
ls *
echo "*"
echo *
echo */*
ls
make
make
ls
ls | cat
ls | cat -e
`ls`
`ls`
`ls`
`ls`
`ls`
`ls`
`ls`
`ls`
ls
`ls`
echo `ls -l`
(ls)
`ls`
`
`ls`
`
`
`
`
`
`
(ls))
(ls))
(ls))
`
(
`ls`
`ls`
`ls`
ls
`
ls
`ls`
`
)
(vim))
ls
`ls`
`l`
ls
ls
ls
`ls`
ls
`ls`
ls m
ls m 2>/dev/null
ls
ls >/dev/null
ls m
ls m 2>&1
ls m
ls m >/dev/null
ls m 2>/dev/null
ls m 2>&-
ls m
ls m 2>&-
ls
ls 1>/dev/null
ls merde
ls merde 2>/dev/null
ls merde 1>/dev/null
ls merde 3>/dev/null
ls merde 2>/dev/null
ls 2>/dev/null
ls
ls >/dev/null
ls >/dev/null
ls >/dev/null
ls >/dev/null
ls >/dev/null
ls >/dev/null
ls 1>/dev/null
ls 1>/dev/null
ls merde
ls merde >/dev/null
ls merde 2>/dev/null
ls merde 2>&-
ls merde 2<&-
ls merde 2<&-
ls merde 2<&-
ls
ls >&-
ls >&-
ls 2>&-
ls m 2>&-
ls
ls 1>&2 2>&-
ls 2>&- 1>&2
ls 2>&- 1>&2
ls 1>&2 2>&-
ls 1>&2 2>&-
ls 2>&- 1>&2
ls 1>&2
ls 1>&2 1>&-
ls 1>&- 1>&2
ls 2>&- 1>&2
ls 1>&- 2>&-
ls 1>&2- 2>&-
ls 1>&2 2>&-
ls 2>&- 1>&2
ls 1>&2-
ls 1>&2
ls 1>&2 1>&-
ls 1>&- 1>&2
ls 1>&- 1>&2
ls 2>&-
ls 2>&- 1>&-
ls 2>&- 1>&2
ls 2>&- 1>&2
ls 2>&- 1>&2
ls 2>&- 1>&2
ls 2>&- 1>&-
ls 2>&- 1>&-
ls 2>&- 1>&2
ls 1>&2 2>&-
ls
ls 2>&-
ls 2>&- 1>&2
ls
ls
ls
ls
ls
ls
ls
ls
ls
ls
ls
ls
`ls`
` `
`` ``
echo `ls``ls`
echo `ls` `ls`
`ls``ls`
a`ls`
`ls``
`ls``ls`
``
```
````
`` ```
`` ``
````
``
``
`
``
ls
``
`
make
``
````
`` ``
````
`` ``
`
``
````
`` ``
````
``
``
````
````
````
````
a`ls` echo `ls`
echo `ls`
echo `ls`
a`ls`
a`ls`
a`ls`
a`ls`
a`ls`
a`ls | wc`
ls
ls
ls
ls | cat
ls
``
` `
````
`` ``
cd
ls
alalalalal`ls`
1
`
``
` `
(vim)& `ls`
jobs
fg
fg
jobs -l
kill -9 80401
jobs
jobs
fg
vim&
jobs
ls
vim&
ls&
jobs
fg
jobs
ls&
jobs
jobs -l
ls
ls&
jobs
vim
jobs
jobs
ls
ls&
jobs
ls&
jobs
vim&
fg
ls
a`la`
ls
ls
ls
```` ```` ``
ls
ls
ls >&-
ls >&waf-
ls >&24-
ls
{}
{()}
({})
{(ls)}
()
ls
read -n 4
read -n 5
echo $REPLY
read -n 4
l
read -n 4
read - n5
read -n 5
echo $REPLY | cat -e
echo $REPLY
read -n 5
echo $REPLY
read -n 3
echo $REPLY
read -n 3
echo $REPLY
read -n -s
read -n 2 -s
read -s
ls
read -n 3
echo $REPLY
echo $REPLY | cat -e
echo $PATH
read -n 10
echo $REPLY
read -n 10
echo $REPLY
(ls)
(ls)l
(ls)
(ls)l
(ls)
(ls)l
{()}
{}
42sh_cpy > wc -l < Makefile
42sh_cpy > wc -l > Makefile
wc -l < Makefile
cat <Makefile
wc -l < Makefile
wc -l
make
ls
wc -l < Makefile
wc <
ls >out1
ls <out1
ls > out
ls < out
ls > out
ls < out
ls>out
ls<out
ls>out
ls<out
ls>out
ls<out
ls
cat out
ls<Makefile
cat<Makefile
make
ls>out
ls<out
cat<Makefile
ls>out
ls<out
wc<Makefile
cat Makefile
cat<Makefile
cat Makefile
cat<out
make
cat<out
ls
cat<out
ls>out
cat out
ls<out
ls>out
ls<out
ls>out
ls<out
ls>out
cat out
ls>out
ls<out
ls>out
rm out
ls >out
ls -l
ls out
ls
ls<out
ls>out
ls<out
echo $?
ls>out
cat out
ls>out
make
ls>out
ls<out
ls
ls -l
ls<file1
cat file1
cat script.sh
ls<script.sh
cat script.sh
ls >&-
ls
ls >&2 2>&-
ls > out
rm out
ls > out
ls -l
ls >out
;
l
ls
ls>out
cat out
wc -l <out
ls>out
ls -l >out
catout
cat out
cat <out
ls<out
make
ls>out
ls<out
ls>out
ls<out
ls>out
wc -l <out
wc -l <Makefile
cat <out
cat<out
ls -l >file1
cat file1
cat <file1
ls >file1
cat file1
cat <file1
ls
echo $PATH
$PATH
env
exit
vim &
jobs
fg
jobs -l
ls | wc -l | ls &
jobs -l
ls | wc -l | ls | sleep 444444 &
jobs -l
kill -9 22969
vim &
ls
jobs- l
jobs -l
vim &
ls
jobs
ls>out
wc -l <out
wc <out
ls 2>&- 1>&2
cat
cat /dev/random|base64|head -c 8 &
cat /dev/random|base64|head -c 8
ls
stty
stty -a
ls
cat
ls 'abc
def'
ls 'abc
'
ls >&-
ls 2>&-
ls mm 2>&-
ls mm 2>&-
cd >&-
./a.out
ls
./a.out
./42sh
pwd
/Users/jhalford/minishell/a.out
ls | /Users/jhalford/minishell/a.out
/a | cat /dev/random | base64 > /dev/null
./42sh
sleep 66666 &
jobs
echo '\
'
ls \
ls '\'
ls "\"
\
\
\
\
\
\\
\\
abc\
def
l\
s
ls 3>&-
ls >&3
ls -- -1>file3
ls -- 9>file3
ls -- 10>file3
ls -- 9999999999999999999999999999999999999999999999999999999>file3
ls -- 2147483648>file3
ls -- 2147483647>file3
ls -- >&2147483648
ls -- >&2147483649
ulimit -a
&
\\ \ \\\
${$(})} ${$((}))} ${`}`} ${${a}}
( ls # )
ls&&ls;ls||ls;
ls&&ls;ls||ls
echo a && echo b;
echo a || echo b;
echo a ||; echo b;
echo a; || echo b;
(ls;) ;
ls ;; ls
` ( echo "(ls" )`
` ( echo "(ls(" )`
` ( echo "(ls((" )`
`echo "ls -l"`
` echo "ls `echo .`"`

View file

@ -1,332 +0,0 @@
...x...~......xx....~.~.~......x....x.....x...........
----------------------------------------------------------------
minishell/binary/004-binary-test-empty-path (FAILED)
Description:
 The purpose of this test is to check that the Shell finds binaries that are located in the current directory when the environment variable PATH is empty.
Before test:
 01: export PATH=""
STDIN:
 01: write_on_stdout "TOKEN201703242314"
STDOUT:
 FAILURE expected_to match_regex `TOKEN201703242314`
 (no output)
STDERR:
 FAILURE expected_to be_empty
 01: ../../42sh: command not found: write_on_stdout
MISC:
 FAILURE expected_to exit_with_status `0`
----------------------------------------------------------------
minishell/binary/008-binary-too-many-symbolic-links-encountered (WARNING)
Description:
 The purpose of this test is to check that trying to execute a path that encounters an infinite loop of symbolic link results in an error on standard error and a failure exit status.
Before test:
 01: rm -rf ./symbolic_link1 ./symbolic_link2 ./symbolic_link3
02: ln -s ./symbolic_link1 ./symbolic_link2
03: ln -s ./symbolic_link2 ./symbolic_link3
04: ln -s ./symbolic_link3 ./symbolic_link1
STDIN:
 01: ./symbolic_link1
STDOUT:
 SUCCESS might be_empty
 (no output)
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `[Tt]oo many.*symbolic links`
 01: ../../42sh: ./symbolic_link1: no such file or directory
MISC:
 SUCCESS expected_to_not exit_with_status 0
----------------------------------------------------------------
minishell/builtins/cd/007-symbolic-link (FAILED)
Description:
 The purpose of this test is to check that using a symbolic link as first argument with the builtin `cd` results in moving the linked directory.
Before test:
 01: rm -f "./symbolic_link"
02: mkdir -p "./sub_directory"
03: ln -s "./sub_directory" "./symbolic_link"
STDIN:
 01: cd symbolic_link
02: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
03: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_env
STDOUT:
 SUCCESS expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory:PWD$`
 FAILURE expected_to match_regex `^PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/symbolic_link$`
 01: PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory:PWD
02: ------------------------------
03: TERM_PROGRAM=iTerm.app
04: TERM=screen-256color
05: SHELL=/bin/zsh
06: HOMEBREW_TEMP=/tmp/ariard/Homebrew/Temp
07: TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n0002_2m000khn/T/
08: Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.UJksyURLXc/Render
09: TERM_PROGRAM_VERSION=3.0.10
10: TERM_SESSION_ID=w0t0p0:162D7F62-BEB1-405A-B3D5-E18A8A96E577
11: ZSH=/Users/ariard/.oh-my-zsh
12: USER=ariard
13: SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.zEo8Maujhn/Listeners
14: __CF_USER_TEXT_ENCODING=0x4A15:0x0:0x0
15: PAGER=less
16: TMUX=/private/tmp/tmux-18965/default,22653,2
17: HOMEBREW_CACHE=/tmp/ariard/Homebrew/Caches
18: LSCOLORS=Gxfxcxdxbxegedabagacad
19: PATH=/Users/ariard/.brew/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/munki://Users/ariard/local/bin
20: MAIL=ariard@student.42.fr
21: PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory
22: LANG=en_US.UTF-8
23: ITERM_PROFILE=Default
24: XPC_FLAGS=0x0
25: TMUX_PANE=%9
26: XPC_SERVICE_NAME=0
27: SHLVL=4
28: HOME=/Users/ariard
29: COLORFGBG=7;0
30: ITERM_SESSION_ID=w0t0p0:162D7F62-BEB1-405A-B3D5-E18A8A96E577
31: LOGNAME=ariard
32: LESS=-R
33: LC_CTYPE=en_US.UTF-8
34: TMUX_PLUGIN_MANAGER_PATH=/Users/ariard/.tmux/plugins/
35: OLDPWD=/Users/ariard/Projects/42sh/42ShellTester/tmp
36: _=../../42sh
37: ?=0
38: ------------------------------
39: TOTAL ENVIRONMENT VARIABLES: 35
STDERR:
 SUCCESS expected_to be_empty
 (no output)
----------------------------------------------------------------
minishell/builtins/cd/008-symbolic-link-2 (FAILED)
Description:
 The purpose of this test is to check that using a symbolic link as first argument with the builtin `cd` results in moving to the linked directory. In this test, the directory is linked with to chained symbolic links.
Before test:
 01: rm -f "./symbolic_link1" "./symbolic_link2"
02: mkdir -p "./sub_directory"
03: ln -s "./sub_directory" "./symbolic_link1"
04: ln -s "./symbolic_link1" "./symbolic_link2"
STDIN:
 01: cd symbolic_link2
02: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
03: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_env
STDOUT:
 SUCCESS expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory:PWD$`
 FAILURE expected_to match_regex `^PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/symbolic_link2$`
 01: PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory:PWD
02: ------------------------------
03: TERM_PROGRAM=iTerm.app
04: TERM=screen-256color
05: SHELL=/bin/zsh
06: HOMEBREW_TEMP=/tmp/ariard/Homebrew/Temp
07: TMPDIR=/var/folders/zz/zyxvpxvq6csfxvn_n0002_2m000khn/T/
08: Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.UJksyURLXc/Render
09: TERM_PROGRAM_VERSION=3.0.10
10: TERM_SESSION_ID=w0t0p0:162D7F62-BEB1-405A-B3D5-E18A8A96E577
11: ZSH=/Users/ariard/.oh-my-zsh
12: USER=ariard
13: SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.zEo8Maujhn/Listeners
14: __CF_USER_TEXT_ENCODING=0x4A15:0x0:0x0
15: PAGER=less
16: TMUX=/private/tmp/tmux-18965/default,22653,2
17: HOMEBREW_CACHE=/tmp/ariard/Homebrew/Caches
18: LSCOLORS=Gxfxcxdxbxegedabagacad
19: PATH=/Users/ariard/.brew/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/munki://Users/ariard/local/bin
20: MAIL=ariard@student.42.fr
21: PWD=/Users/ariard/Projects/42sh/42ShellTester/tmp/sub_directory
22: LANG=en_US.UTF-8
23: ITERM_PROFILE=Default
24: XPC_FLAGS=0x0
25: TMUX_PANE=%9
26: XPC_SERVICE_NAME=0
27: SHLVL=4
28: HOME=/Users/ariard
29: COLORFGBG=7;0
30: ITERM_SESSION_ID=w0t0p0:162D7F62-BEB1-405A-B3D5-E18A8A96E577
31: LOGNAME=ariard
32: LESS=-R
33: LC_CTYPE=en_US.UTF-8
34: TMUX_PLUGIN_MANAGER_PATH=/Users/ariard/.tmux/plugins/
35: OLDPWD=/Users/ariard/Projects/42sh/42ShellTester/tmp
36: _=../../42sh
37: ?=0
38: ------------------------------
39: TOTAL ENVIRONMENT VARIABLES: 35
STDERR:
 SUCCESS expected_to be_empty
 (no output)
----------------------------------------------------------------
minishell/builtins/cd/errors/001-not-a-directory (WARNING)
Description:
 The purpose of this test is to check that using a file name as first argument with the builtin `cd` results in error and not changing current directory.
Before test:
 01: touch "./not_a_directory"
STDIN:
 01: cd not_a_directory
02: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
STDOUT:
 SUCCESS expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD`
 01: PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `[Nn]ot a directory`
 01: ../../42sh: cd: no such file or directory: not_a_directory
----------------------------------------------------------------
minishell/builtins/cd/errors/003-permission-denied (WARNING)
Description:
 The purpose of this test is to check that using a directory without any permission as first argument with the builtin `cd` results in error and not changing current directory.
Before test:
 01: if [ -d "./permission_denied" ]; then chmod 777 "./permission_denied"; fi
02: rm -rf "./permission_denied"
03: mkdir -m 0 "./permission_denied"
STDIN:
 01: cd permission_denied
02: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
STDOUT:
 SUCCESS expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD`
 01: PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `[Pp]ermission denied`
 01: ../../42sh: cd: no such file or directory: permission_denied
After test:
 01: if [ -d "./permission_denied" ]; then chmod 777 "./permission_denied"; fi
02: rm -rf "./permission_denied"
----------------------------------------------------------------
minishell/builtins/cd/errors/005-too-many-symbolic-links-encountered (WARNING)
Description:
 The purpose of this test is to check that using a symbolic link resulting in ELOOP error as first argument with the builtin `cd` results in error and not changing current directory.
Before test:
 01: rm -f "./symbolic_link1" "./symbolic_link2" "./symbolic_link3"
02: ln -s "./symbolic_link1" "./symbolic_link2"
03: ln -s "./symbolic_link2" "./symbolic_link3"
04: ln -s "./symbolic_link3" "./symbolic_link1"
STDIN:
 01: cd symbolic_link1
02: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
STDOUT:
 SUCCESS expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD`
 01: PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `[Tt]oo many.*symbolic links`
 01: ../../42sh: cd: no such file or directory: symbolic_link1
----------------------------------------------------------------
minishell/builtins/cd/options/002-oldpwd (FAILED)
Description:
 The purpose of this test is to check that using `-` as first argument with the builtin `cd` results in moving the previous current directory.
STDIN:
 01: cd /
02: cd -
03: /Users/ariard/Projects/42sh/42ShellTester/tmp/display_pwd
STDOUT:
 FAILURE expected_to match_regex `PWD:/Users/ariard/Projects/42sh/42ShellTester/tmp:PWD`
 01: /Users/ariard
02: PWD:/Users/ariard:PWD
STDERR:
 SUCCESS expected_to be_empty
 (no output)
----------------------------------------------------------------
minishell/builtins/env/errors/001-command-not-found (FAILED)
Description:
 The purpose of this test is to check that using the builtin `env` with an invalid binary as argument results in an error and failure exit status.
Before test:
 01: rm -f "./invalid_binary"
STDIN:
 01: env ./invalid_binary
STDOUT:
 (no output)
STDERR:
 SUCCESS expected_to_not be_empty
 WARNING might match_regex `[Cc]ommand not found`
 01: ../../42sh: env: ./invalid_binary: No such file or directory
MISC:
 FAILURE expected_to_not exit_with_status `0`
----------------------------------------------------------------
minishell/builtins/exit/errors/001-too-many-args (FAILED)
Description:
 The purpose of this test is to check that using a wrong number of arguments with the builtin `exit` does not result in the Shell termination but an error on standard error.
STDIN:
 01: exit 21 42
02: ./write_on_stdout TOKEN201703242314
STDOUT:
 FAILURE expected_to match_regex `TOKEN201703242314`
 (no output)
STDERR:
 FAILURE expected_to_not be_empty
 WARNING might match_regex `([Tt]oo many arguments|[Aa]rgument list too long)`
 (no output)
MISC:
 FAILURE expected_to exit_with_status `0`
Total tests: 54
Total failed tests: 6
Total pending tests: 0

View file

@ -1,133 +0,0 @@
#!/bin/sh
verbose=0
if [ "$1" = "-v" ]
then
verbose=1
fi
word=$(git status -s | sed 's/.* //')
red="\033[38;5;1m"
gre="\033[38;5;2m"
cya="\033[38;5;6m"
res="\033[0m"
elem_in_array ()
{
for cur in $2
do
if [ "$1" = "$cur" ]
then
echo "1"
return 1
fi
done
echo "0"
return 0
}
array_in_array ()
{
for cur in $1
do
match=$(elem_in_array "$cur" "$2")
if [ "$match" -ne 1 ]
then
echo "0"
return 0
fi
done
echo "1"
return 1
}
confirm ()
{
echo "$cya${1:-Are you sure? [y/N]}$res"
read -r -p " " response
case "$response" in
[yY][eE][sS]|[yY])
true
;;
*)
false
;;
esac
}
do_checkout ()
{
i_tmp=$(echo $i | sed 's/\//_/g')
cp $i "$HOME/Documents/.$i_tmp.back"
git checkout $i
if [ $verbose -eq 1 ]
then
echo "$gre D - O - N - E $res"
echo "$cya $i was checked out. A copy still exist in $HOME/Documents/.$i_tmp.back$res\n"
fi
}
if [ $verbose -eq 1 ]
then
for i in $word
do
if [ -e $i ]
then
if [ -f $i ]
then
diff=$(git diff -U0 --exit-code --color $i)
if [ "$?" -eq 1 ]
then
nb_lines=$(echo "$diff" | wc -l)
if [ "$nb_lines" -eq 7 ]
then
match=$(array_in_array "-9 +9 Updated: by ### ########.fr" "$diff")
if [ $match -eq 1 ]
then
echo "\n$cya CHANGES on $i :$res"
echo "$diff"
confirm
if [ $? -eq 0 ]
then
do_checkout
else
echo "$cya Nothing done for $i$res\n"
fi
else
echo "$gre$i is not concerned (diff on the good lines)$res"
fi
else
echo "$gre$i is not concerned (diff is too big)$res"
fi
else
echo "$gre$i is not concerned (diff is null)$res"
fi
else
echo "$red$i is not a regular file$res"
fi
else
echo "$red$i doesn't exist$res"
fi
done
else
for i in $word
do
if [ -e $i ]
then
if [ -f $i ]
then
diff=$(git diff -U0 --exit-code --color $i)
if [ "$?" -eq 1 ]
then
nb_lines=$(echo "$diff" | wc -l)
if [ "$nb_lines" -eq 7 ]
then
match=$(array_in_array "-9 +9 Updated: by ### ########.fr" "$diff")
if [ $match -eq 1 ]
then
do_checkout
fi
fi
fi
fi
fi
done
fi

View file

@ -1,17 +0,0 @@
MYPATH=$(pwd)
CUR_MAKEFILE=$MYPATH/Makefile
if [ -e $CUR_MAKEFILE ]
then
echo "regenerate Makefile"
sed "`grep -n 'SRC_BASE =' $CUR_MAKEFILE | sed 's/:.*//'`, \$d" $CUR_MAKEFILE > NEWMAKEFILE
grep 'SRC_BASE =' $CUR_MAKEFILE >> NEWMAKEFILE
expr "$(find ./src | grep "\.c$" | sed -e 's/src\///' -e 's/\.\///' -e 's/$/\\/')" : "\(.*\).$" >> NEWMAKEFILE
echo "" >> NEWMAKEFILE
grep 'SRCS =' $CUR_MAKEFILE >> NEWMAKEFILE
sed "1, `grep -n 'SRCS =' $CUR_MAKEFILE | sed 's/:.*//'`d" $CUR_MAKEFILE >> NEWMAKEFILE
mv $CUR_MAKEFILE ~/Documents/.OLDMakefile
mv NEWMAKEFILE $CUR_MAKEFILE
echo "Makefile done (copy still alive in ~/Documents/.OLDMakefile)"
else
echo "Makefile not found."
fi