aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 41cdc4bdc222c389a755ea33b5b332b18c94421f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# minishell test [![Build Status](https://api.travis-ci.com/cacharle/minishell_test.svg?branch=master)](https://travis-ci.com/cacharle/minishell_test) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/minishell-test)](https://pypi.org/project/minishell-test/) [![Documentation](https://readthedocs.org/projects/minishell-test/badge/?version=latest)](https://minishell-test.readthedocs.io)

Test for the minishell project of school 42.

![preview](https://i.imgur.com/98xh2xY.gif)

## Installation

### pip

```
$ pip3 install minishell-test
```

### Manual

```
$ git clone https://github.com/cacharle/minishell_test
$ cd minishell_test
$ pip3 install -e .
```

## Usage

```
$ minishell_test             # In your project directory
$ python3 -m minishell_test  # If you don't have ~/.brew/bin or ~/.local/bin in your PATH

$ minishell_test --help
usage: minishell_test [-h] [-p PATH] [-l] [-t COMMAND] [-k] [-r BEGIN END]
                      [--show-range] [-x] [-v] [-b] [-n] [-m] [-g]
                      [suite [suite ...]]

Test for the minishell project of school 42.

positional arguments:
  suite                 Test suites/group to run.
                        It tries to be smart and autocomplete the suite name
                        (e.g ./run int -> ./run preprocess/interpolation)

optional arguments:
  -h, --help            show this help message and exit
  -p PATH, --path PATH  Path to minishell directory
  -l, --list            Print available test suites
  -t COMMAND, --try-cmd COMMAND
                        Run a custom command like this test would
                        (the only environment variable passed to your executable are TERM and PATH)
  -k, --check-leaks     Run valgrind on tests (disable usual comparison with bash)
  -r BEGIN END, --range BEGIN END
                        Range of test index to run (imply --show-index)
  --show-range          Show test index (useful with --range)
  -x, --exit-first      Exit on first fail
  -v, --verbose         Increase verbosity level (e.g -vv == 2)
  -b, --bonus           Enable bonus tests
  -n, --no-bonus        Disable bonus tests
  -m, --make            Make minishell and exit
  -g, --pager           After running the test, display the result in a pager of your choice

Made by cacharle - https://cacharle.xyz
```

## Test compatibility

Your executable **must** support the `-c` option which allow to pass command as string.

```command
$ bash -c 'echo bonjour je suis'
bonjour je suis
$ ./minishell -c 'echo bonjour je suis'
bonjour je suis

$ bash -c 'ls'
README.md test.sh
$ ./minishell -c 'ls'
README.md test.sh
```

With this setup `argv[2]` is what you would usually get in `line` from `get_next_line`.
This allows you to set the prompt to whatever you want.

### Environement variables

My test only gives the `PATH` and `TERM` environment variables to your minishell.
**Please check that your project still work with those settings before messaging me on Slack or creating an issue**.
You can test this quickly with the `-t` option (e.g `minishell_test -t 'echo bonjour`).

## Bonus

* Force the bonus tests with `$ minishell_test -b`
* Change the `BONUS` variable in [config.py](minishell_test/config.py) to True
* Set the environment variable `MINISHELL_TEST_BONUS` to `yes`
  (e.g `echo 'export MINISHELL_TEST_BONUS=yes' >> ~/.zshrc`)

## Memory leaks

`$ minishell_test -k`, checkout the `--show-range`, `--range` and `-x` options to help
to select the tests to run since valgrind is really slow.

## Don't check error messages

If you don't want to copy bash syntax error message,
you can set the environment variable `MINISHELL_TEST_DONT_CHECK_ERROR_MESSAGE` to `yes`.
It will still test your exit status code but will discard any output on error tests.

## Linux

The tester will try to convert to output/status code of bash on Linux to the one on Mac.

---

## Add new tests

You can find the suites in the [minishell\_test/suites](minishell_test/suites) directory.

### Add individual test

In your suite function you can use the `test` function. With the following arguments:

1. Command to be tested (output and status will be compared to bash)
2. A command to setup the sandbox directory where the tested command will be run
3. List of files to watch (the content of each file will be compared)

```python
test("echo bonjour je suis")                                  # simple command
test("cat < somefile", setup="echo file content > somefile")  # setup
test("ls > somefile", setup="", files=["somefile"])           # watch a file
test("echo $A", exports={"A": "a"})                           # export variables
                                                              # in the environment
test("echo bonjour", hook=lambda s: s.replace("o", "a"))      # pass the shell output
                                                              # through a hook function

test("cat < somefile > otherfile",
     setup="echo file content > somefile",
     files=["otherfile"])
```

### Add Suite

A test suite is a group of related tests.

```python
@suite()  # @suite(bonus=True) if it's a bonus suite
def suite_yoursuitename(test):
    """ a description of the suite """
    test(...)
    test(...)
    test(...)
```

---

## Wildcard (or glob)

There is a commented glob suite in [minishell\_test/suites/preprocess.py](minishell_test/suites/preprocess.py).
Good luck handling `*'.*'`.