aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCharles Cabergs <me@cacharle.xyz>2021-02-05 12:27:32 +0100
committerCharles Cabergs <me@cacharle.xyz>2021-02-05 12:27:32 +0100
commit904a033ae738e1c351f8fef71e2ec2418fc4db3d (patch)
tree3de4980582c109c4f0d19111a2b88eafec9b9b36 /src
parenta3e983f78dc4cbcf6f75f78fa2b3c57e09cd1b2b (diff)
downloadminishell_test-904a033ae738e1c351f8fef71e2ec2418fc4db3d.tar.gz
minishell_test-904a033ae738e1c351f8fef71e2ec2418fc4db3d.tar.bz2
minishell_test-904a033ae738e1c351f8fef71e2ec2418fc4db3d.zip
Renaming src -> minishell_test for package name, Renaming main.py -> __main__.py for package execution with python -m
Diffstat (limited to 'src')
-rw-r--r--src/args.py87
-rw-r--r--src/config.py120
-rw-r--r--src/hooks.py123
-rwxr-xr-xsrc/main.py93
-rw-r--r--src/sandbox.py48
-rw-r--r--src/suite/__init__.py2
-rw-r--r--src/suite/decorator.py47
-rw-r--r--src/suite/suite.py179
-rw-r--r--src/suites/__init__.py17
-rw-r--r--src/suites/builtin.py403
-rw-r--r--src/suites/cmd.py331
-rw-r--r--src/suites/flow.py290
-rw-r--r--src/suites/misc.py100
-rw-r--r--src/suites/path.py137
-rw-r--r--src/suites/preprocess.py463
-rw-r--r--src/test/__init__.py13
-rw-r--r--src/test/captured.py56
-rw-r--r--src/test/result.py246
-rw-r--r--src/test/test.py155
19 files changed, 0 insertions, 2910 deletions
diff --git a/src/args.py b/src/args.py
deleted file mode 100644
index b7fcca6..0000000
--- a/src/args.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# ############################################################################ #
-# #
-# ::: :::::::: #
-# args.py :+: :+: :+: #
-# +:+ +:+ +:+ #
-# By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# Created: 2020/07/15 18:24:32 by charles #+# #+# #
-# Updated: 2021/01/11 22:20:16 by charles ### ########.fr #
-# #
-# ############################################################################ #
-
-import argparse
-import textwrap
-
-
-def parse_args():
- """Parse command line arguments"""
-
- parser = argparse.ArgumentParser(
- description=textwrap.dedent(r"""
- ___ ____ _ _ _ _ _ _
- | \/ (_) (_) | | | | | | | | |
- | . . |_ _ __ _ ___| |__ ___| | | | |_ ___ ___| |_
- | |\/| | | '_ \| / __| '_ \ / _ \ | | | __/ _ \/ __| __|
- | | | | | | | | \__ \ | | | __/ | | | || __/\__ \ |_
- \_| |_/_|_| |_|_|___/_| |_|\___|_|_| \__\___||___/\__|
- """),
- formatter_class=argparse.RawTextHelpFormatter,
- epilog=textwrap.dedent("""\
- Signal handling is not tested
- There is a commented glob suite in src/suites/preprocess.py.
- Good luck handling `*'.*'`.
- """)
- )
- parser.add_argument(
- "-k", "--check-leaks", action="store_true",
- help="Run valgrind on tests (disable usual comparison with bash)"
- )
- parser.add_argument(
- "-r", "--range", nargs=2, type=int, metavar=("BEGIN", "END"),
- help="Range of test index to run (imply --show-index)"
- )
- parser.add_argument(
- "--show-range", action="store_true",
- help="Show test index (useful with --range)"
- )
- parser.add_argument(
- "-x", "--exit-first", action="store_true",
- help="Exit on first fail"
- )
- parser.add_argument(
- "-v", "--verbose", action="count",
- help="Increase verbosity level (e.g -vv == 2)"
- )
- parser.add_argument(
- "-b", "--bonus", action="store_true",
- help="Enable bonus tests"
- )
- parser.add_argument(
- "-n", "--no-bonus", action="store_true",
- help="Disable bonus tests"
- )
- parser.add_argument(
- "-l", "--list", action="store_true",
- help="Print available test suites"
- )
- parser.add_argument(
- "-m", "--make", action="store_true",
- help="Make minishell and exit"
- )
- parser.add_argument(
- "-g", "--pager", action="store_true",
- help="After running the test, display the result in a pager of your choice"
- )
- parser.add_argument(
- "suites", nargs='*', metavar="suite",
- help=textwrap.dedent("""\
- Test suites/group to run.
- It tries to be smart and autocomplete the suite name
- (e.g ./run int -> ./run preprocess/interpolation)
- """)
- )
- tmp = parser.parse_args()
- if tmp.verbose is None:
- tmp.verbose = 1
- return tmp
diff --git a/src/config.py b/src/config.py
deleted file mode 100644
index 493652c..0000000
--- a/src/config.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# ############################################################################ #
-# #
-# ::: :::::::: #
-# config.py :+: :+: :+: #
-# +:+ +:+ +:+ #
-# By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# Created: 2020/07/15 18:24:19 by charles #+# #+# #
-# Updated: 2021/01/31 04:41:29 by charles ### ########.fr #
-# #
-# ############################################################################ #
-
-################################################################################
-# Minishell configuration file #
-################################################################################
-
-import os
-import shutil
-import distutils.spawn
-from typing import List
-
-# run the bonus tests
-# can be changed with `export MINISHELL_TEST_BONUS=yes` in your shell rc file.
-BONUS = False
-
-# minishell dir path
-MINISHELL_DIR = "../minishell"
-
-# minishell executable
-MINISHELL_EXEC = "minishell"
-
-# make minishell before executing the test if set to True
-MINISHELL_MAKE = True
-
-# path to reference shell (shell which will be compared minishell)
-# has to support the -c option (sh, bash and zsh support it)
-REFERENCE_PATH = "/bin/bash"
-# can be changed with `export MINISHELL_TEST_ARGS=--poxix,--otherarg`
-REFERENCE_ARGS: List[str] = [] # ["--posix"]
-
-# pager to use with --pager option
-# can be changed with `export MINISHELL_TEST_PAGER=yourpager`
-PAGER = "less"
-
-# log file path
-LOG_PATH = "result.log"
-
-# path to the sandbox directory
-# WARNING: will be rm -rf so be careful
-SANDBOX_PATH = "sandbox"
-
-# where the availables commands are stored
-EXECUTABLES_PATH = "./bin"
-
-# commands available in test"
-AVAILABLE_COMMANDS = ["rmdir", "env", "cat", "touch", "ls", "grep", "sh", "head"]
-
-# $PATH environment variable passed to the shell
-PATH_VARIABLE = os.path.abspath(EXECUTABLES_PATH)
-
-# test timeout
-TIMEOUT = 0.5
-
-# check leaks test timeout
-CHECK_LEAKS_TIMEOUT = 10
-
-LOREM = """
-Mollitia asperiores assumenda excepturi et ipsa. Nihil corporis facere aut a rem consequatur.
-Quas molestiae corporis et quibusdam maiores. Molestiae sed unde aut at sed.
-Deserunt quidem quidem aspernatur pariatur vel illum voluptatum. Culpa unde dolor aspernatur sit.
-Mollitia tenetur sed eaque autem placeat a aut in. Ipsam ea consequuntur omnis.
-Non et qui vel corrupti similique eum aut voluptatibus. Iste consequatur voluptatum et omnis debitis.
-Sit quia neque nihil consequatur sint. Velit libero ut aut et et rerum.
-Placeat cumque incidunt non repellat sunt perspiciatis ullam.
-Repellendus repudiandae nostrum quia quis corrupti.
-Rerum veniam earum cumque pariatur accusantium voluptatum omnis.
-Alias ut et et adipisci. Tempore omnis numquam ullam et animi et eveniet.
-Dolor itaque distinctio in. Magnam rerum quia est laboriosam repellat perspiciatis eos.
-Consequuntur quae corrupti atque. Numquam enim ut ut.
-Perspiciatis ut maxime et libero quo voluptas consequatur illum. Pariatur porro dolor cumque molestiae harum.
-"""
-LOREM = ' '.join(LOREM.split('\n'))
-
-###############################################################################
-# You probably shouldn't edit after #
-###############################################################################
-
-MINISHELL_PATH = os.path.abspath(
- os.path.join(MINISHELL_DIR, MINISHELL_EXEC)
-)
-
-VALGRIND_CMD: List[str] = [
- distutils.spawn.find_executable("valgrind") or "couldn't find valgrind",
- # "valgrind",
- "--trace-children=no",
- "--leak-check=yes",
- "--child-silent-after-fork=yes",
- "--show-leak-kinds=definite",
- MINISHELL_PATH,
-]
-
-# 0, 1, 2
-VERBOSE_LEVEL = 1
-
-MINISHELL_ERROR_BEGIN = os.path.basename(MINISHELL_PATH) + ": "
-REFERENCE_ERROR_BEGIN = REFERENCE_PATH + ": line 0: "
-
-TERM_COLS = shutil.get_terminal_size().columns
-if TERM_COLS < 40:
- raise RuntimeError("You're terminal isn't wide enough")
-
-PLATFORM = os.uname().sysname
-
-EXIT_FIRST = False
-
-CHECK_LEAKS = False
-
-SHOW_RANGE = False
-
-RANGE = None
diff --git a/src/hooks.py b/src/hooks.py
deleted file mode 100644
index e37f2aa..0000000
--- a/src/hooks.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# ############################################################################ #
-# #
-# ::: :::::::: #
-# hooks.py :+: :+: :+: #
-# +:+ +:+ +:+ #
-# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# Created: 2020/09/11 16:10:20 by charles #+# #+# #
-# Updated: 2020/11/25 21:36:18 by charles ### ########.fr #
-# #
-# ############################################################################ #
-
-import re
-import sys
-import os
-
-import config
-
-
-def sort_lines(output):
- """Sort lines of output"""
- return '\n'.join(sorted(output.split('\n')))
-
-
-def error_line0(output):
- """Replace "/bin/bash: -c: line 0:" by "minishell:" and delete the second line"""
- error_message = os.environ.get("MINISHELL_TEST_DONT_CHECK_ERROR_MESSAGE")
- if error_message is not None and error_message == "yes":
- return "DISCARDED BY TEST"
-
- lines = output.split('\n')
- if len(lines) != 3:
- return output
- prefix = "{}: -c: line 0: ".format(config.REFERENCE_PATH)
- if lines[0].find(prefix) != 0:
- return output
- return lines[0].replace(prefix, "minishell: ") + "\n"
-
-
-def discard(output):
- """Discard the output"""
- return "DISCARDED BY TEST"
-
-
-def export_singleton(output):
- """Remove variable that are not set to anything in a call to export without arguments"""
- prefix = "export " if ("--posix" in config.REFERENCE_ARGS) else "declare -x "
- return sort_lines(
- '\n'.join([line for line in output.split('\n')
- if re.match("^{}[a-zA-Z]+$".format(prefix), line) is None])
- )
-
-
-def replace_double_slash(output):
- """Replace occurence of double slash by one"""
- return output.replace("//", "/")
-
-
-def replace_double_semi_colon(output):
- """Replace occurence of double semi-colon by one"""
- return output.replace(";;", ";")
-
-
-def platform_status(darwin_status, linux_status, windows_status=None):
- def hook(status):
- if config.PLATFORM == "Darwin":
- return status
- elif config.PLATFORM == "Linux":
- return (darwin_status if status == linux_status else status)
- else:
- raise RuntimeError("This platform exit codes are not supported yet,"
- "feel free to contact me to add it.")
- sys.exit(2)
- return status
- return hook
-
-
-def is_directory(output):
- if config.PLATFORM == "Linux":
- return output.replace("Is a directory", "is a directory")
- else:
- return output
-
-
-# def no_cd_too_many_arguments(output):
-# for i, line in output.split("\n"):
-# if line.find("too many arguments")
-
-
-def shlvl_0_to_1(output):
- if config.PLATFORM == "Linux":
- return output.replace("SHLVL=0", "SHLVL=1")
- else:
- return output
-
-
-def delete_escape(output):
- if config.PLATFORM == "Linux":
- return output.replace("\\", "")
- else:
- return output
-
-
-def error_eof_to_expected_token(output):
- return output.replace(
- "-c: line 1: syntax error: unexpected end of file",
- "syntax error expected token"
- )
-
-
-def linux_discard(output):
- if config.PLATFORM == "Linux":
- return "DISCARDED BY MINISHELL TEST"
- else:
- return output
-
-
-def should_not_be(not_expected):
- def hook(output):
- if output == not_expected:
- return "OUTPUT SHOULD NOT BE " + output
- return "DISCARDED BY TEST"
- return hook
diff --git a/src/main.py b/src/main.py
deleted file mode 100755
index fe48b5e..0000000
--- a/src/main.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python3
-
-# ############################################################################ #
-# #
-# ::: :::::::: #
-# main.py :+: :+: :+: #
-# +:+ +:+ +:+ #
-# By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# Created: 2020/07/15 15:11:52 by charles #+# #+# #
-# Updated: 2020/07/15 15:11:52 by charles ### ########.fr #
-# #
-# ############################################################################ #
-
-import os
-import sys
-import shutil
-import distutils.spawn
-import subprocess
-
-import config
-import sandbox
-from args import parse_args
-from suite import Suite
-from suites import * # noqa: F403,F401
-
-
-def main():
- args = parse_args()
- if args.list:
- Suite.list()
- sys.exit(0)
-
- if config.MINISHELL_MAKE or args.make:
- try:
- print("{:=^{width}}".format("MAKE", width=config.TERM_COLS))
- subprocess.run(["make", "--no-print-directory", "-C", config.MINISHELL_DIR],
- check=True,
- env={"MINISHELL_TEST_FLAGS": "-DMINISHELL_TEST", **os.environ})
- print("=" * config.TERM_COLS)
- except subprocess.CalledProcessError:
- sys.exit(1)
- if args.make:
- sys.exit(0)
- if os.path.exists(config.EXECUTABLES_PATH):
- shutil.rmtree(config.EXECUTABLES_PATH)
- os.mkdir(config.EXECUTABLES_PATH)
- for cmd in config.AVAILABLE_COMMANDS:
- cmd_path = distutils.spawn.find_executable(cmd)
- if cmd_path is None:
- raise RuntimeError
- shutil.copy(cmd_path,
- os.path.join(config.EXECUTABLES_PATH, cmd))
-
- reference_args = os.environ.get("MINISHELL_TEST_ARGS")
- if reference_args is not None:
- config.REFERENCE_ARGS.extend(reference_args.split(','))
-
- pager = os.environ.get("MINISHELL_TEST_PAGER")
- if pager is not None:
- config.PAGER = pager
-
- config.VERBOSE_LEVEL = args.verbose
- if args.bonus or os.environ.get("MINISHELL_TEST_BONUS") == "yes":
- config.BONUS = True
- if args.no_bonus:
- config.BONUS = False
- config.EXIT_FIRST = args.exit_first
- config.CHECK_LEAKS = args.check_leaks
- config.RANGE = args.range
- config.SHOW_RANGE = args.show_range
- if config.RANGE is not None or config.CHECK_LEAKS:
- config.SHOW_RANGE = True
-
- Suite.setup(args.suites)
- try:
- Suite.run_all()
- except KeyboardInterrupt:
- sandbox.remove()
-
- Suite.summarize()
- Suite.save_log()
- print("See", config.LOG_PATH, "for more information")
- if config.CHECK_LEAKS:
- print("HELP: Valgrind is really slow the -x and --range options could be useful"
- " (./run -h for more details)")
-
- if args.pager:
- subprocess.run([config.PAGER, config.LOG_PATH])
-
-
-if __name__ == "__main__":
- main()
diff --git a/src/sandbox.py b/src/sandbox.py
deleted file mode 100644
index bd49d1e..0000000
--- a/src/sandbox.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# ############################################################################ #
-# #
-# ::: :::::::: #
-# sandbox.py :+: :+: :+: #
-# +:+ +:+ +:+ #
-# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# Created: 2020/09/11 13:48:07 by charles #+# #+# #
-# Updated: 2021/01/31 03:59:30 by charles ### ########.fr #
-# #
-# ############################################################################ #
-
-import os
-import glob
-import shutil
-import subprocess
-from contextlib import contextmanager
-
-import config
-
-
-def create():
- """Create a new sandbox directory"""
- try:
- os.mkdir(config.SANDBOX_PATH)
- except OSError:
- pass
-
-
-def remove():
- """Remove the sandbox directory
- Brute force rm -rf if clean removal doesn't work due to permissions.
- """
- try:
- shutil.rmtree(config.SANDBOX_PATH)
- except PermissionError:
- subprocess.run(["chmod", "777", *glob.glob(config.SANDBOX_PATH + "/*")], check=True)
- subprocess.run(["rm", "-rf", config.SANDBOX_PATH], check=True)
- except FileNotFoundError:
- pass
-
-
-@contextmanager
-def context():
- """Sandbox context manager"""
- create()
- yield
- remove()
diff --git a/src/suite/__init__.py b/src/suite/__init__.py
deleted file mode 100644
index 6f7f321..0000000
--- a/src/suite/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from suite.suite import Suite # noqa: F401
-from suite.decorator import suite # noqa: F401
diff --git a/src/suite/decorator.py b/src/suite/decorator.py
deleted file mode 100644
index fdc7fb6..0000000
--- a/src/suite/decorator.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# ############################################################################ #
-# #
-# ::: :::::::: #
-# decorator.py :+: :+: :+: #
-# +:+ +:+ +:+ #
-# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# Created: 2020/09/11 12:28:00 by charles #+# #+# #
-# Updated: 2021/02/04 16:18:11 by charles ### ########.fr #
-# #
-# ############################################################################ #
-
-import inspect
-from typing import List
-
-from suite import Suite
-from test import Test
-
-
-def suite(groups: List[str] = [], bonus: bool = False): # type: ignore
- """Decorator generator for suites arguments"""
-
- def suite_wrapper(origin):
- """Decorator for a suite function (fmt: suite_[name]) """
-
- mod = inspect.getmodule(origin)
- if mod is None:
- raise NotImplementedError
- mod_name = mod.__name__[len("suites."):]
- name = "{}/{}".format(mod_name, origin.__name__[len("suite_"):])
- description = origin.__doc__
- if description is None:
- print("You should had a doc string to the {} suite".format(name))
- description = "no description"
- description = description.split("\n")[0].strip()
- s = Suite(name, groups + [mod_name], bonus, description)
-
- def test_generator():
- def test(*args, **kwargs):
- s.add(Test(*args, **kwargs))
- origin(test)
-
- s.generator_func = test_generator
- Suite.available.append(s)
- return test_generator
-
- return suite_wrapper
diff --git a/src/suite/suite.py b/src/suite/suite.py
deleted file mode 100644
index 836cac0..0000000
--- a/src/suite/suite.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# ############################################################################ #
-# #
-# ::: :::::::: #
-# suite.py :+: :+: :+: #
-# +:+ +:+ +:+ #
-# By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# Created: 2020/07/15 18:24:29 by charles #+# #+# #
-# Updated: 2021/02/04 16:13:08 by charles ### ########.fr #
-# #
-# ############################################################################ #
-
-import sys
-from typing import List, Tuple, Optional, Callable
-
-import config
-from test import Test
-
-
-class Suite:
- available: List['Suite'] = []
-
- @classmethod
- def run_all(cls):
- """Run all available suites"""
- for s in cls.available:
- if not s.run() and config.EXIT_FIRST:
- break
-
- @classmethod
- def setup(cls, asked_names: List[str]) -> None:
- """ Remove not asked suite from available suites
- Tries to autocomplete the asked names
- """
- if not config.BONUS:
- cls.available = [s for s in cls.available if not s.bonus]
- if len(asked_names) == 0:
- asked_names = [s.name for s in cls.available]
-
- suite_names = [s.name for s in cls.available]
- names = []
- for i, name in enumerate(asked_names):
- if name in suite_names:
- names.append(name)
- continue
- matches = [n for n in suite_names
- if n.find("/") != -1
- and n[n.find("/") + 1:].startswith(name)
- or n.startswith(name)]
- if len(matches) == 1:
- names.append(matches[0])
- elif len(matches) != 0 and all(n.startswith(name) for n in matches):
- names.extend(matches)
- elif len(matches) > 2:
- print(("Ambiguous name `{}` match the following suites\n\t{}\n"
- "Try to run with -l to see the available suites")
- .format(name, ', '.join(matches)))
- sys.exit(1)
- elif len(matches) == 0:
- print(("Name `{}` doesn't match any suite/group name\n\t"
- "Try to run with -l to see the available suites")
- .format(name))
- sys.exit(1)
-
- cls.available = list(set(
- [s for s in cls.available if s.name in names]
- + [s for s in cls.available if any(g for g in s.groups if g in names)]
- ))
- cls.available.sort(key=lambda s: s.name)
- for s in cls.available:
- if s.generator_func is not None:
- s.generator_func()
-
- @classmethod
- def available_names(cls) -> List[str]:
- """List of available suites names"""
- return [s.name for s in cls.available]
-
- @classmethod
- def list(cls):
- print("Groups:")
- print("\n".join({" - " + ', '.join(s.groups) for s in Suite.available}))
- print("The available suites are:")
- max_name_width = max(len(s.name) for s in Suite.available) + 5
- lines = [
- " - {:.<{max_name_width}} {}".format(
- s.name + " ",
- s.description,
- max_name_width=max_name_width
- )
- for s in Suite.available
- ]
- print("\n".join(lines))
-
- def __init__(
- self,
- name: str,
- groups: List[str],
- bonus: bool = False,
- description: str = "no description",
- ):
- """Suite class
- name: suite id
- groups: list of suite groups
- bonus: is this suite bonus
- """
- self.name = name
- self.groups = groups
- self.description = description
- self.bonus = bonus
- self.generator_func: Optional[Callable] = None
- self.tests: List[Test] = []
-
- def add(self, test):
- """Append a test to the suite"""
- self.tests.append(test)
-
- BLUE_CHARS = "\033[34m"
- CLOSE_CHARS = "\033[0m"
-
- def run(self) -> bool:
- """Run all test in the suite"""
- if config.VERBOSE_LEVEL == 0:
- print(self.name + ": ", end="")
- else:
- print("{}{:#^{width}}{}".format(
- self.BLUE_CHARS,
- " " + self.name + " ",
- self.CLOSE_CHARS,
- width=config.TERM_COLS
- ))
- for i, t in enumerate(self.tests):
- if config.RANGE is not None:
- if not (config.RANGE[0] <= i <= config.RANGE[1]):
- continue
- t.run(i)
- if config.EXIT_FIRST and t.result is not None and t.result.failed:
- return False
- if config.VERBOSE_LEVEL == 0:
- print()
- return True
-
- def total(self) -> Tuple[int, int]:
- """Returns the total of passed and failed tests"""
- passed_total = 0
- for t in self.tests:
- if t.result is None:
- return (-1, -1)
- if t.result.passed:
- passed_total += 1
- return passed_total, len(self.tests) - passed_total
-
- @classmethod
- def summarize(cls):
- """Print a summary of all runned suites"""
- pass_sum = 0
- fail_sum = 0
- print("\nSummary:")
- for s in cls.available:
- (pass_total, fail_total) = s.total()
- if pass_total == -1:
- continue
- pass_sum += pass_total
- fail_sum += fail_total
- print("{:.<{width}} \033[32m{:4} [PASS]\033[0m \033[31m{:4} [FAIL]\033[0m"
- .format(s.name + " ", pass_total, fail_total, width=config.TERM_COLS - 24))
- print("{:.<{width}} \033[32m{:4} [PASS]\033[0m \033[31m{:4} [FAIL]\033[0m"
- .format("TOTAL ", pass_sum, fail_sum, width=config.TERM_COLS - 24))
-
- @classmethod
- def save_log(cls):
- """Save the result of all suites to a file"""
- with open(config.LOG_PATH, "w") as log_file:
- for s in cls.available:
- for t in s.tests:
- if t.result is not None and t.result.failed:
- t.result.colored = False
- t.result.set_colors()
- log_file.write(t.result.full_diff() + '\n')
diff --git a/src/suites/__init__.py b/src/suites/__init__.py
deleted file mode 100644
index b6b3b68..0000000
--- a/src/suites/__init__.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# ############################################################################ #
-# #
-# ::: :::::::: #
-# __init__.py :+: :+: :+: #
-# +:+ +:+ +:+ #
-# By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# Created: 2020/07/15 18:24:48 by charles #+# #+# #
-# Updated: 2020/09/11 13:25:26 by charles ### ########.fr #
-# #
-# ############################################################################ #
-
-import os
-import glob
-
-modules = glob.glob(os.path.join(os.path.dirname(__file__), "*.py"))
-__all__ = [os.path.basename(f)[:-3] for f in modules if os.path.isfile(f) and not f.endswith("__init__.py")]
diff --git a/src/suites/builtin.py b/src/suites/builtin.py
deleted file mode 100644
index 9ab2af8..0000000
--- a/src/suites/builtin.py
+++ /dev/null
@@ -1,403 +0,0 @@
-# **************************************************************************** #
-# #
-# ::: :::::::: #
-# builtin.py :+: :+: :+: #
-# +:+ +:+ +:+ #
-# By: juligonz <juligonz@student.42.fr> +#+ +:+ +#+ #
-# +#+#+#+#+#+ +#+ #
-# Created: 2020/07/15 18:24:43 by charles #+# #+# #
-# Updated: 2020/11/28 06:17:19 by charles ### ########.fr #
-# Updated: 2020/09/11 18:01:27 by juligonz ### ########.fr #
-# #
-# **************************************************************************** #
-
-import os
-
-import config
-import hooks
-from suite import suite
-from hooks import linux_discard
-
-
-@suite()
-def suite_echo(test):
- """ echo builtin tests """
- test("echo")
- test("echo bonjour")
- test("echo lalalala lalalalal alalalalal alalalala")
- test("echo lalalala lalalalal alalalalal alalalala")
- test("echo " + config.LOREM)
- test("echo -n")
- test("echo -n bonjour")
- test("echo -n lalalala lalalalal alalalalal alalalala")
- test("echo -n lalalala lalalalal alalalalal alalalala")
- test("echo -n " + config.LOREM)
- test("echo bonjour -n")
- test("echo -n bonjour -n")
- test(" echo bonjour je")
- test(" echo -n bonjour je")
- test("echo a '' b '' c '' d")
- test('echo a "" b "" c "" d')
- test("echo -n a '' b '' c '' d")
- test('echo -n a "" b "" c "" d')
- test("echo '' '' ''")
- test("Echo bonjour")
- test("eCho bonjour")
- test("ecHo bonjour")
- test("echO bonjour")
- test("EchO bonjour")
- test("eCHo bonjour")
- test("EcHo bonjour")
- test("eChO bonjour")
- test("Echo bonjour", exports={"PATH": "/bin:/usr/bin"})
- test("eCho bonjour", exports={"PATH": "/bin:/usr/bin"})
- test("ecHo bonjour", exports={"PATH": "/bin:/usr/bin"})
- test("echO bonjour", exports={"PATH": "/bin:/usr/bin"})
- test("EchO bonjour", exports={"PATH": "/bin:/usr/bin"})
- test("eCHo bonjour", exports={"PATH": "/bin:/usr/bin"})
- test("EcHo bonjour", exports={"PATH": "/bin:/usr/bin"})
- test("eChO bonjour", exports={"PATH": "/bin:/usr/bin"})
- test("eChO -e 'bonjo\\nur'", exports={"PATH": "/bin:/usr/bin"})
- test("echo -n -n -n -n bonjour")
- test("echo -nnnnnnnnnnnnnnnnnnnnn bonjour")
- test("echo -nnnnnnnnnnnnnnnnnnnnn -n -n -n bonjour -n -n")
-
-
-@suite()
-def suite_e