From a0f278b13a1347663fd9626322b30e7b87615a0d Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Mon, 1 Mar 2021 14:39:47 +0100 Subject: Added custom test configuration --- .travis.yml | 1 + docs/README.rst | 2 +- docs/bonus.rst | 5 +- docs/conf.py | 2 +- docs/config.rst | 16 +++--- docs/custom_test.rst | 128 +++++++++++++++++++++++++++++++++++--------- docs/gettingstarted.rst | 42 --------------- docs/gettingstarted.rst.inc | 46 ++++++++++++++++ docs/index.rst | 3 +- docs/options.rst | 5 +- tox.ini | 16 +++--- 11 files changed, 176 insertions(+), 90 deletions(-) delete mode 100644 docs/gettingstarted.rst create mode 100644 docs/gettingstarted.rst.inc diff --git a/.travis.yml b/.travis.yml index 5c2486f..bcf9b9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,3 +33,4 @@ script: - python -m pytest -vvv - python -m minishell_test -p /tmp/minishell - python -m minishell_test -p /tmp/minishell -k pwd + - python -m sphinx-build docs docs/_build diff --git a/docs/README.rst b/docs/README.rst index 8c95bc7..6609610 100644 --- a/docs/README.rst +++ b/docs/README.rst @@ -16,7 +16,7 @@ minishell_test .. image:: https://i.imgur.com/98xh2xY.gif :alt: preview -.. include:: gettingstarted.rst +.. include:: gettingstarted.rst.inc Documentation ------------- diff --git a/docs/bonus.rst b/docs/bonus.rst index f3d9a88..d0e94f7 100644 --- a/docs/bonus.rst +++ b/docs/bonus.rst @@ -1,8 +1,11 @@ -.. program:: minishell_test +.. _bonus: Bonus ===== +.. program:: minishell_test + + See :ref:`how to enable the bonus tests in the configuration ` and the :option:`suite` option. diff --git a/docs/conf.py b/docs/conf.py index 692a56c..d60ba56 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -43,7 +43,7 @@ templates_path = ['_templates'] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'README.rst'] # -- Options for HTML output ------------------------------------------------- diff --git a/docs/config.rst b/docs/config.rst index c7995e3..adc4c07 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -27,8 +27,7 @@ Global settings are defined under the ``[minishell_test]`` section. :type: true|false - Enable the bonus tests (:ref:`bonus`). - + Enable the bonus tests, see :ref:`bonus`. .. _config-make: .. conf:: make @@ -44,7 +43,7 @@ Global settings are defined under the ``[minishell_test]`` section. | Argument given to the ``make`` command. | The default value (``MINISHELL_TEST_FLAGS=-DMINISHELL_TEST``) allows you to do conditional compilation - to support both the ``-c`` option and the :ref:`subject` + to support both the ``-c`` option and the subject (which doesn't say anything about options, so we assume the minishell executable didn't take any). | In your ``Makefile`` add ``$(MINISHELL_TEST_FLAGS)`` in your object compilation command. @@ -69,6 +68,7 @@ Global settings are defined under the ``[minishell_test]`` section. #endif .. _config-check-error-messages: + .. conf:: check_error_messages :type: true|false @@ -110,12 +110,13 @@ Shell settings are defined under the ``[shell]`` section. ``{shell_available_commands_dir}`` will be replaced by the directory where the available commands are stored. -Reference -+++++++++ +.. _config-reference-shell: + +Reference Shell ++++++++++++++++ Reference shell settings are defined under the ``[shell:reference]`` section. -.. _config-shell-reference-path: .. conf:: path :type: path @@ -137,6 +138,8 @@ Timeout Timeout settings are defined under the ``[timeout]`` section. +.. _config-timeout-test: + .. conf:: test :type: float (seconds) @@ -144,6 +147,7 @@ Timeout settings are defined under the ``[timeout]`` section. Time before a timeout occurs on a regular test. .. _config-timeout-leaks: + .. conf:: leaks :type: float (seconds) diff --git a/docs/custom_test.rst b/docs/custom_test.rst index fc5cf22..32d3ec3 100644 --- a/docs/custom_test.rst +++ b/docs/custom_test.rst @@ -3,41 +3,119 @@ Add Custom Tests ================ +You can add custom test in a file named ``minishell_test.py`` at the root of your project. + +Suite +----- + +A test suite is a group of related tests. + +.. code:: python + + @suite() + def suite_yoursuitename(test): + """ a description of the suite """ + test(...) + test(...) + +.. warning:: + your suite function name **must** be prefixed by ``suite_``. + +Bonus ++++++ + +.. code:: python + + @suite(bonus=True) + def suite_yoursuitename(test): + Test ---- -In your suite function you can use the ``test`` function. With the -following arguments: +In your suite function you can use the ``test`` function (passed in the suite function argument). -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) +The first argument of ``test`` is passed to the shell (via ``-c``, see :ref:`compatibility`). .. code:: 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("echo bonjour je suis") + test("cat -e < /etc/shells") + test("sed 's/sh/foo/g' /etc/shells > notshells") - test("cat < somefile > otherfile", - setup="echo file content > somefile", - files=["otherfile"]) +Setup Command ++++++++++++++ -Suite ------ +| ``setup`` is a command to run before the test. +| Contrary to the tested command there is no restriction for the ``setup`` command. +| The only requirement for the test setup to be successful is for this command to return a non zero status code. + +.. code:: python + + test("cat < somefile", setup="echo file content > somefile") + test("ls -la", setup="touch a b c d e") -A test suite is a group of related tests. + +Compare Files ++++++++++++++ + +| The ``files`` argument is a list of files to compare against the :ref:`config-reference-shell`.. +| Checks if the file exists and the file's content. .. code:: python - @suite() # @suite(bonus=True) if it's a bonus suite - def suite_yoursuitename(test): - """ a description of the suite """ - test(...) - test(...) - test(...) + test("echo bonjour > somefile", files=["somefile"]) + test("echo bonjour > a > b > c", files=["a", "b", "c"]) + test("echo bonjour > foo ; echo aurevoir >> foo", files=["foo"]) + +Export Variables +++++++++++++++++ + +Add environment variable passed to your executable with the ``exports`` dictionnary. + +.. note:: + Those variables will be passed **in addition** of the default exports (i.e ``PATH`` and ``TERM``). + +.. code:: python + + test("echo $FOO", exports={"FOO": "foo"}) + test("echo $FOO$BAR", exports={"FOO": "foo", "BAR": "bar"}) + test("echo $SHLVL", exports={"SHLVL": "100"}) + +Timeout ++++++++ + +``timeout`` overwrites the :ref:`default timeout value` of the configuration. + +.. code:: python + + test("echo /*/*/*", timeout=60) + +Hook +++++ + +Output +^^^^^^ + +``hook`` is a function (or list of functions) applied on the output of test after it is done running. + +.. code:: python + + def replace_foo_by_bar_hook(output): + return output.replace("foo", "bar") + + test("echo @@foo foo foo@@", hook=replace_foo_by_bar_hook) + # initial output: @@foo foo foo@@ + # after passedf through hook: @@bar bar bar@@ + +Status Code +^^^^^^^^^^^ + +``hook_status`` is similar to ``hook`` only it take a status code has it's first argument and return the new status. + +.. code:: python + + def reverse_error(status): + return 0 if status != 0 else 1 + + test("cat doesnotexists", hook=reverse_error) + # status code will be 0 after status hook diff --git a/docs/gettingstarted.rst b/docs/gettingstarted.rst deleted file mode 100644 index 15c1efc..0000000 --- a/docs/gettingstarted.rst +++ /dev/null @@ -1,42 +0,0 @@ -Getting Started ---------------- - -Installation -++++++++++++ - -.. code-block:: - - $ pip3 install minishell-test - $ pip3 install --user minishell-test # if you don't have root access - -Compatibility -+++++++++++++ - -Your executable **must** support the ``-c`` option which allow to pass command as an argument. - -.. code-block:: - - $ bash -c 'echo bonjour je suis | cat -e' - bonjour he suis$ - $ ./minishell -c 'echo bonjour je suis | cat -e' - bonjour je suis$ - - -.. note:: - With this setup ``argv[2]`` is what you would usually get in ``line`` from ``get_next_line``. - -Usage -+++++ - -Run all the predefined tests: - -.. code-block:: - - $ cd - $ minishell_test - -.. warning:: - If you get ``command not found``, do either of those things: - - * Add ``~/.local/bin`` to your ``PATH`` environment variable. - * Run ``$ python3 -m minishell_test`` instead of ``$ minishell_test`` diff --git a/docs/gettingstarted.rst.inc b/docs/gettingstarted.rst.inc new file mode 100644 index 0000000..f1dce9c --- /dev/null +++ b/docs/gettingstarted.rst.inc @@ -0,0 +1,46 @@ +Getting Started +--------------- + +Installation +++++++++++++ + +.. code-block:: + + $ pip3 install minishell-test + $ pip3 install --user minishell-test # if you don't have root access + +.. _compatibility: + +Compatibility ++++++++++++++ + +Your executable **must** support the ``-c`` option which allow to pass command as an argument. + +.. code-block:: + + $ bash -c 'echo bonjour je suis | cat -e' + bonjour he suis$ + $ ./minishell -c 'echo bonjour je suis | cat -e' + bonjour je suis$ + + +.. note:: + With this setup ``argv[2]`` is what you would usually get in ``line`` from ``get_next_line``. + +Usage ++++++ + +Run all the predefined tests: + +.. code-block:: + + $ cd + $ minishell_test + +.. warning:: + If you get ``command not found``, do either of those things: + + * Add ``~/.local/bin`` to your ``PATH`` environment variable. + * Run ``$ python3 -m minishell_test`` instead of ``$ minishell_test`` + +.. vim:ft=rst diff --git a/docs/index.rst b/docs/index.rst index 07ad2af..c37c212 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,6 @@ Documentation of minishell_test .. toctree:: :maxdepth: 2 - gettingstarted config options bonus @@ -15,4 +14,4 @@ Documentation of minishell_test .. include:: disclaimer.rst -.. include:: gettingstarted.rst +.. include:: gettingstarted.rst.inc diff --git a/docs/options.rst b/docs/options.rst index dd524d9..c342090 100644 --- a/docs/options.rst +++ b/docs/options.rst @@ -47,7 +47,8 @@ Command line Options Print available test suites .. command-output:: minishell_test --list - :ellipsis: 15 + +.. :ellipsis: 15 .. option:: -t , --try @@ -64,7 +65,7 @@ Memory Leaks .. option:: -k, --check-leaks | Runs `valgrind `_ on tests to check for memory leaks. - | (disable the usual comparison with the :ref:`reference shell `) + | (disable the usual comparison with the :ref:`config-reference-shell`) .. warning:: | Running ``valgrind`` on each tests may take a while especially if your ``minishell`` isn't correctly optimized, diff --git a/tox.ini b/tox.ini index 39d4ce6..74bb804 100644 --- a/tox.ini +++ b/tox.ini @@ -5,27 +5,23 @@ distshare = {homedir}/.cache/tox/distshare [testenv] passenv = * - deps = flake8 mypy pytest - allowlist_externals = git rm valgrind - commands_pre = git clone --recurse-submodules git://git.cacharle.xyz/minishell /tmp/minishell pip install -e . - commands = - flake8 minishell_test - mypy minishell_test - pytest - python -m minishell_test -p /tmp/minishell - python -m minishell_test -p /tmp/minishell -k pwd - + python -m flake8 minishell_test + python -m mypy minishell_test + python -m pytest + python -m minishell_test --list + python -m minishell_test --path /tmp/minishell + python -m minishell_test --path /tmp/minishell --check-leaks pwd commands_post = rm -rf /tmp/minishell -- cgit