aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Cabergs <me@cacharle.xyz>2021-01-31 04:13:22 +0100
committerCharles Cabergs <me@cacharle.xyz>2021-01-31 04:13:22 +0100
commit361e1fe39e88788ef4173083482d520753225a3e (patch)
tree9df150f1bbdc8848d44effb6fe4da5643c013d05
parentaa962c545496fc645d3f78370d7190ae1f3db11e (diff)
downloadminishell_test-361e1fe39e88788ef4173083482d520753225a3e.tar.gz
minishell_test-361e1fe39e88788ef4173083482d520753225a3e.tar.bz2
minishell_test-361e1fe39e88788ef4173083482d520753225a3e.zip
Refactoring Result into BaseResult, Result and LeakResult
-rw-r--r--src/sandbox.py4
-rw-r--r--src/test/result.py228
-rw-r--r--src/test/test.py6
3 files changed, 128 insertions, 110 deletions
diff --git a/src/sandbox.py b/src/sandbox.py
index 8194556..bd49d1e 100644
--- a/src/sandbox.py
+++ b/src/sandbox.py
@@ -6,7 +6,7 @@
# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/09/11 13:48:07 by charles #+# #+# #
-# Updated: 2020/09/12 17:06:28 by charles ### ########.fr #
+# Updated: 2021/01/31 03:59:30 by charles ### ########.fr #
# #
# ############################################################################ #
@@ -36,6 +36,8 @@ def remove():
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
diff --git a/src/test/result.py b/src/test/result.py
index 4d060fa..e4512ac 100644
--- a/src/test/result.py
+++ b/src/test/result.py
@@ -6,7 +6,7 @@
# By: charles <me@cacharle.xyz> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/09/11 12:17:34 by charles #+# #+# #
-# Updated: 2021/01/31 03:35:53 by charles ### ########.fr #
+# Updated: 2021/01/31 04:10:31 by charles ### ########.fr #
# #
# ############################################################################ #
@@ -18,73 +18,21 @@ import config
from test.captured import Captured
-# TODO split into BaseResult, Result and LeakResult
-class Result:
+class BaseResult:
RED_CHARS = "\033[31m"
GREEN_CHARS = "\033[32m"
BLUE_CHARS = "\033[34m"
BOLD_CHARS = "\033[1m"
CLOSE_CHARS = "\033[0m"
- def __init__(
- self,
- cmd: str,
- file_names: List[str],
- expected: Captured,
- actual: Captured,
- leak_output: str = None
- ):
- """Result class
- cmd: runned command
- file_names: names of watched files
- expected: expected capture
- actual: actual capture
- leak_output: output of valgrind in check leak mode
- """
- self.cmd = cmd
- self.file_names = file_names
- self.expected = expected
- self.actual = actual
+ def __init__(self):
self.colored = True
- self.leak_output = leak_output
self.set_colors()
- @staticmethod
- def leak(cmd: str, captured: Captured):
- return Result(cmd, [], None, captured, captured.output)
-
- def _search_leak_kind(self, kind: str) -> Match:
- match = re.search(
- r"==\d+==\s+" + kind + r" lost: (?P<bytes>[0-9,]+) bytes in [0-9,]+ blocks",
- self.leak_output
- )
- if match is None:
- raise RuntimeError(
- "valgrind output parsing failed for `{}`:\n{}"
- .format(self.cmd, self.leak_output)
- )
- return match
-
- @property
- def lost_bytes(self):
- if self.leak_output.find("All heap blocks were freed -- no leaks are possible") != -1:
- definite_bytes = 0
- indirect_bytes = 0
- else:
- definite_match = self._search_leak_kind("definitely")
- indirect_match = self._search_leak_kind("indirectly")
- definite_bytes = int(definite_match.group("bytes").replace(",", ""))
- indirect_bytes = int(indirect_match.group("bytes").replace(",", ""))
- return definite_bytes + indirect_bytes
-
@property
def passed(self):
"""Check if the result passed"""
- if self.leak_output is not None:
- if self.actual.is_timeout:
- return False
- return self.lost_bytes == 0
- return self.actual == self.expected
+ raise NotImplementedError
@property
def failed(self):
@@ -96,7 +44,7 @@ class Result:
if config.VERBOSE_LEVEL == 0:
return self.green('.') if self.passed else self.red('!')
elif config.VERBOSE_LEVEL == 1:
- printed = self.escaped_cmd[:]
+ printed = self._escaped_cmd[:]
if config.SHOW_RANGE:
printed = "{:2}: ".format(self.index) + printed
if len(printed) > config.TERM_COLS - 7:
@@ -119,8 +67,79 @@ class Result:
else:
print()
+ def indicator(self, title: str, prefix: str) -> str:
+ return self.bold(self.blue(prefix + " " + title))
+
+ def full_diff(self) -> str:
+ raise NotImplementedError
+
+ @property
+ def _escaped_cmd(self):
+ """Escape common control characters"""
+ return (self.cmd
+ .replace("\t", "\\t")
+ .replace("\n", "\\n")
+ .replace("\v", "\\v")
+ .replace("\r", "\\r")
+ .replace("\f", "\\f"))
+
+ @property
+ def _header_with(self):
+ return self.indicator("WITH {}".format(self._escaped_cmd), "|>") + '\n'
+
+ def set_colors(self):
+ """Set colors strings on or off based on self.colored"""
+ if self.colored:
+ self.color_red = self.RED_CHARS
+ self.color_green = self.GREEN_CHARS
+ self.color_blue = self.BLUE_CHARS
+ self.color_bold = self.BOLD_CHARS
+ self.color_close = self.CLOSE_CHARS
+ else:
+ self.color_red = ""
+ self.color_green = ""
+ self.color_blue = ""
+ self.color_bold = ""
+ self.color_close = ""
+
+ def green(self, s):
+ return self.color_green + s + self.color_close
+
+ def red(self, s):
+ return self.color_red + s + self.color_close
+
+ def blue(self, s):
+ return self.color_blue + s + self.color_close
+
+ def bold(self, s):
+ return self.color_bold + s + self.color_close
+
+
+class Result(BaseResult):
+ def __init__(
+ self,
+ cmd: str,
+ file_names: List[str],
+ expected: Captured,
+ actual: Captured,
+ ):
+ """Result class
+ cmd: runned command
+ file_names: names of watched files
+ expected: expected capture
+ actual: actual capture
+ """
+ self.cmd = cmd
+ self.file_names = file_names
+ self.expected = expected
+ self.actual = actual
+ super().__init__()
+
+ @property
+ def passed(self):
+ return self.actual == self.expected
+
def header(self, title: str) -> str:
- """Create a one line header with a title"""
return self.bold("|---------------------------------------{:-<40}".format(title))
@property
@@ -131,8 +150,14 @@ class Result:
def actual_header(self) -> str:
return self.red(self.header("ACTUAL"))
- def indicator(self, title: str, prefix: str) -> str:
- return self.bold(self.blue(prefix + " " + title))
+ def cat_e(self, s: str) -> str:
+ """Pass a string through a cat -e like output"""
+ s = s.replace("\n", "$\n")
+ if len(s) < 2:
+ return s
+ if s[-1] != '\n':
+ s += '\n'
+ return s
def file_diff(self, file_name: str, expected: str, actual: str) -> str:
"""Difference between 2 files"""
@@ -173,55 +198,46 @@ class Result:
def full_diff(self) -> str:
"""Concat all difference reports"""
- rest = ""
- if self.leak_output is not None:
- rest = self.leak_output
- else:
- rest = (self.output_diff() + self.files_diff() + "=" * 80 + '\n')
- return (self.indicator("WITH {}".format(self.escaped_cmd), "|>") + '\n' + rest)
-
- def cat_e(self, s: str) -> str:
- """Pass a string through a cat -e like output"""
- s = s.replace("\n", "$\n")
- if len(s) < 2:
- return s
- if s[-1] != '\n':
- s += '\n'
- return s
+ return self._header_with + self.output_diff() + self.files_diff() + "=" * 80 + '\n'
- @property
- def escaped_cmd(self):
- """Escape common control characters"""
- return (self.cmd
- .replace("\t", "\\t")
- .replace("\n", "\\n")
- .replace("\v", "\\v")
- .replace("\r", "\\r")
- .replace("\f", "\\f"))
- def set_colors(self):
- """Set colors strings on or off based on self.colored"""
- if self.colored:
- self.color_red = self.RED_CHARS
- self.color_green = self.GREEN_CHARS
- self.color_blue = self.BLUE_CHARS
- self.color_bold = self.BOLD_CHARS
- self.color_close = self.CLOSE_CHARS
- else:
- self.color_red = ""
- self.color_green = ""
- self.color_blue = ""
- self.color_bold = ""
- self.color_close = ""
+class LeakResult(BaseResult):
+ def __init__(self, cmd: str, captured: Captured):
+ self.cmd = cmd
+ self.captured = captured
+ super().__init__()
- def green(self, s):
- return self.color_green + s + self.color_close
+ def _search_leak_kind(self, kind: str) -> Match:
+ match = re.search(
+ r"==\d+==\s+" + kind + r" lost: (?P<bytes>[0-9,]+) bytes in [0-9,]+ blocks",
+ self.captured.output
+ )
+ if match is None:
+ raise RuntimeError(
+ "valgrind output parsing failed for `{}`:\n{}"
+ .format(self.cmd, self.captured.output)
+ )
+ return match
- def red(self, s):
- return self.color_red + s + self.color_close
+ @property
+ def _lost_bytes(self):
+ if self.captured.output.find("All heap blocks were freed -- no leaks are possible") != -1:
+ definite_bytes = 0
+ indirect_bytes = 0
+ else:
+ definite_match = self._search_leak_kind("definitely")
+ indirect_match = self._search_leak_kind("indirectly")
+ definite_bytes = int(definite_match.group("bytes").replace(",", ""))
+ indirect_bytes = int(indirect_match.group("bytes").replace(",", ""))
+ return definite_bytes + indirect_bytes
- def blue(self, s):
- return self.color_blue + s + self.color_close
+ @property
+ def passed(self):
+ """Check if the result passed"""
+ if self.captured.is_timeout:
+ return False
+ return self._lost_bytes == 0
- def bold(self, s):
- return self.color_bold + s + self.color_close
+ def full_diff(self) -> str:
+ """Concat all difference reports"""
+ return self._header_with + self.captured.output
diff --git a/src/test/test.py b/src/test/test.py
index 517e610..6f3aad5 100644
--- a/src/test/test.py
+++ b/src/test/test.py
@@ -6,7 +6,7 @@
# By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/06/16 21:48:50 by charles #+# #+# #
-# Updated: 2021/01/31 03:30:15 by charles ### ########.fr #
+# Updated: 2021/01/31 03:55:43 by charles ### ########.fr #
# #
# ############################################################################ #
@@ -17,7 +17,7 @@ from typing import Optional, List, Dict
import config
from test.captured import Captured
-from test.result import Result
+from test.result import Result, LeakResult
import sandbox
@@ -64,7 +64,7 @@ class Test:
captured = self._run_sandboxed([*config.VALGRIND_CMD, "-c"])
if config.VERBOSE_LEVEL == 2:
print(captured.output)
- self.result = Result.leak(self.full_cmd, captured)
+ self.result = LeakResult(self.full_cmd, captured)
self.result.put(index)
return