diff --git a/check50/_api.py b/check50/_api.py index bb7f2e0..be757c7 100644 --- a/check50/_api.py +++ b/check50/_api.py @@ -161,10 +161,16 @@ def __init__(self, command, env={}): full_env = os.environ.copy() full_env.update(env) + # load in env into bash manually via export commands + bash_command = "" + for key in full_env: + bash_command += "export {}={} && ".format(shlex.quote(key), shlex.quote(full_env[key])) + bash_command += command + # Workaround for OSX pexpect bug http://pexpect.readthedocs.io/en/stable/commonissues.html#truncated-output-just-before-child-exits # Workaround from https://github.com/pexpect/pexpect/issues/373 - command = "bash -c {}".format(shlex.quote(command)) - self.process = pexpect.spawn(command, encoding="utf-8", echo=False, env=full_env) + command = "bash -c {}".format(shlex.quote(bash_command)) + self.process = pexpect.spawn(command, encoding="utf-8", echo=False) def stdin(self, line, str_line=None, prompt=True, timeout=3): """ diff --git a/check50/_simple.py b/check50/_simple.py index 9339b05..ca4a188 100644 --- a/check50/_simple.py +++ b/check50/_simple.py @@ -59,7 +59,7 @@ def _compile_check(name, check): if check_name[0].isdigit(): check_name = f"_{check_name}" - if not re.match("\w+", check_name): + if not re.match(r"\w+", check_name): raise CompileError( _("{} is not a valid name for a check; check names should consist only of alphanumeric characters, underscores, and spaces").format(name)) diff --git a/check50/c.py b/check50/c.py index d38078f..021d177 100644 --- a/check50/c.py +++ b/check50/c.py @@ -55,7 +55,8 @@ def compile(*files, exe_name=None, cc=CC, max_log_lines=50, **cflags): out_flag = f" -o {exe_name} " if exe_name is not None else " " - process = run(f"{cc} {files}{out_flag}{flags}") + proc_str = f"{cc} {files}{out_flag}{flags}" + process = run(proc_str) # Strip out ANSI codes stdout = re.sub(r"\x1B\[[0-?]*[ -/]*[@-~]", "", process.stdout()) diff --git a/check50/regex.py b/check50/regex.py index 215c65a..2b20786 100644 --- a/check50/regex.py +++ b/check50/regex.py @@ -7,16 +7,16 @@ def decimal(number): In case of a positive number:: - (?\n'\ - 'int main() {\n'\ - ' printf("hello, world!\\n");\n'\ - '}' - f.write(src) - check50.c.compile("hello.c") - self.assertTrue(os.path.isfile("hello")) + +class TestRun(Base): + def test_stdout_hello_world(self): + check50.c.compile("hello.c") check50.run("./hello").stdout("hello, world!", regex=False) + def test_stdin_cash(self): + check50.c.compile("cash.c", lcs50=True) + check50.run("./cash").stdin("42", prompt=True).stdout("5").exit() + class TestValgrind(Base): def setUp(self): super().setUp() + + # valgrind installation check moved to here from Base() + if not VALGRIND_INSTALLED: + raise unittest.SkipTest("valgrind not installed") if not (sys.platform == "linux" or sys.platform == "linux2"): raise unittest.SkipTest("skipping valgrind checks under anything other than Linux due to false positives") def test_no_leak(self): check50.internal.check_running = True - with open("foo.c", "w") as f: - src = 'int main() {}' - f.write(src) check50.c.compile("foo.c") with check50.internal.register: @@ -66,13 +80,6 @@ def test_no_leak(self): def test_leak(self): check50.internal.check_running = True - with open("leak.c", "w") as f: - src = '#include \n'\ - 'void leak() {malloc(sizeof(int));}\n'\ - 'int main() {\n'\ - ' leak();\n'\ - '}' - f.write(src) check50.c.compile("leak.c") with self.assertRaises(check50.Failure): diff --git a/tests/test_files/blank.c b/tests/test_files/blank.c new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_files/cash.c b/tests/test_files/cash.c new file mode 100644 index 0000000..f8ed03f --- /dev/null +++ b/tests/test_files/cash.c @@ -0,0 +1,21 @@ +#include +#include + +int main(void) { + int cents; + do { + cents = get_int("Cents? "); + } + while (cents < 0); + + const int n_denominations = 4; + int denominations[n_denominations] = {1, 5, 10, 25}; + + int coins = 0; + for (int i = n_denominations - 1; i >= 0; i--) { + coins += cents / denominations[i]; + cents %= denominations[i]; + } + + printf("%i\n", coins); +} diff --git a/tests/test_files/foo.c b/tests/test_files/foo.c new file mode 100644 index 0000000..237c8ce --- /dev/null +++ b/tests/test_files/foo.c @@ -0,0 +1 @@ +int main() {} diff --git a/tests/test_files/hello.c b/tests/test_files/hello.c new file mode 100644 index 0000000..a262b3f --- /dev/null +++ b/tests/test_files/hello.c @@ -0,0 +1,5 @@ +#include + +int main() { + printf("hello, world!\n"); +} diff --git a/tests/test_files/leak.c b/tests/test_files/leak.c new file mode 100644 index 0000000..e0e29f3 --- /dev/null +++ b/tests/test_files/leak.c @@ -0,0 +1,9 @@ +#include + +void leak() { + malloc(sizeof(int)); +} + +int main() { + leak(); +}