Ejemplo n.º 1
0
    def validate_form(self, route, fields, field_tag="input"):
        """Make sure HTML form at `route` has input fields given by `fields`"""
        if not isinstance(fields, list):
            fields = [fields]

        content = self.get(route).content()
        required = {field: False for field in fields}
        for tag in content.find_all(field_tag):
            try:
                name = tag.attrs["name"]
                if required[name]:
                    raise Error("found more than one field called \"{}\"".format(name))
            except KeyError:
                pass
            else:
                check50.log("found required \"{}\" field".format(name))
                required[name] = True

        try:
            missing = next(name for name, found in required.items() if not found)
        except StopIteration:
            pass
        else:
            raise check50.Failure(f"expected to find {field_tag} field with name \"{missing}\", but none found")

        if content.find("button", type="submit") is None:
            raise check50.Failure("expected button to submit form, but none was found")

        return self
Ejemplo n.º 2
0
def nbconvert(notebook, dest=None):
    notebook = pathlib.Path(notebook)
    if dest == None:
        dest = notebook.with_suffix('')
    else:
        dest = pathlib.Path(dest).with_suffix('')

    check50.log(f"converting {notebook} to {dest.with_suffix('.py')}")

    # convert notebook
    with open(os.devnull, "w") as devnull:
        if subprocess.call([
                sys.executable, '-m', 'nbconvert', '--to', 'script', notebook,
                "--output", dest
        ],
                           stdout=devnull,
                           stderr=devnull) != 0:
            raise NotebookError("Could not convert notebook.")

    dest = dest.with_suffix(".py")

    # remove all magic lines
    with open(dest, "r") as f:
        lines = f.readlines()
    with open(dest, "w") as f:
        f.write("".join([l for l in lines if "get_ipython" not in l]))
Ejemplo n.º 3
0
def check_bmps(expected_filename, actual_filename):

    # Open files.
    with open(expected_filename, "rb") as expected_file, \
            open(actual_filename, "rb") as actual_file:

        # Read in the headers.
        expected_header = BitmapHeader.from_file(expected_file)
        actual_header = BitmapHeader.from_file(actual_file)

        expected_bytes = expected_file.read()
        actual_bytes = actual_file.read()

    check50.log(f"checking {actual_filename} header...")
    for (field, expected_field), (_,
                                  actual_field) in zip(expected_header,
                                                       actual_header):
        if expected_field != actual_field:
            raise check50.Failure(
                f"expected {hex(expected_field)}, not {hex(actual_field)} in header field {field}"
            )

    check50.log(f"checking {actual_filename} pixel data...")
    for i, (expected_byte, actual_byte) in enumerate(
            zip_longest(expected_bytes, actual_bytes), 1):
        if actual_byte is None:
            raise check50.Failure("image has fewer bytes than expected.")
        elif expected_byte is None:
            raise check50.Failure("image has more bytes than expected.")
        elif expected_byte != actual_byte:
            raise check50.Failure(
                f"expected {hex(expected_byte)}, not {hex(actual_byte)} in byte {i} of pixel data"
            )
Ejemplo n.º 4
0
def lock_pairs2():
    """lock_pairs skips final pair if it creates cycle"""
    output = check50.run("./tideman_test 6 14").stdout()
    print(output)
    check50.log(output)
    check50.run("./tideman_test 6 14").stdout(
        "false true false false false false false false false false true false false false false false false false false false false false false true false false true true false false false false false false false false "
    ).exit(0)
Ejemplo n.º 5
0
def test_functions_exist():
    """Checks that there are functions in the program """
    output = check50.run("cat credit.py").stdout()
    result = re.findall(
        r'(\ndef \w*:|\ndef \w*\(\):|\ndef \w*\([A-Z ,a-z0-9]*\):)', output)
    defCount = len(result)
    for i in result:
        check50.log("Found " + i.strip())
    if defCount < 2:
        raise check50.Failure("You need at least two functions defined")
Ejemplo n.º 6
0
def check_distance(a, b, expected):
    helpers = check50.py.import_("helpers.py")
    check50.log(f"checking edit distance for inputs {repr(a)} and {repr(b)}...")
    with open(os.devnull, "w") as f:
        try:
            actual = helpers.distances(a, b)[len(a)][len(b)][0]
        except Exception as e:
            raise check50.Failure(str(e))

    if actual != expected:
        raise check50.Failure(f"expected edit distance of {expected}, not {actual}")
Ejemplo n.º 7
0
def sorts():
    """correctly identifies each sort"""

    check50.log("checking that sorts are classified correctly...")

    expected = [
        "sort1 uses:\s*bubble", "sort2 uses:\s*merge",
        "sort3 uses:\s*selection"
    ]
    actual = open("answers.txt", "r").read().lower()

    for e in expected:
        if not search(e, actual):
            raise check50.Failure("Incorrect assignment of sorts.")
Ejemplo n.º 8
0
def check_strings(method, expected, *args):
    a, b = args[0], args[1]
    helpers = check50.py.import_("helpers.py")
    check50.log(f"running '{method}' on inputs {repr(a)} and {repr(b)}...")
    try:
        with open(os.devnull, "w") as f:
            actual = getattr(helpers, method)(*args)
    except Exception as e:
        raise check50.Failure(str(e))

    if len(actual) != len(expected):
        raise check50.Failure(f"expected {len(expected)} matches, not {len(actual)}")
    actual = set(actual)
    if actual != expected:
        raise check50.Mismatch(str(expected), str(actual))
Ejemplo n.º 9
0
def benchmark():
    """passes benchmarking"""

    time = Time()

    for text in os.listdir("texts"):
        out = check50.run(
            "./speller dictionaries/large texts/{} 1".format(text)).stdout(
                timeout=20)
        try:
            load, check, size, unload = map(float, out.split())
        except ValueError:
            check50.log(out)
            raise check50.Failure(
                "program has unexpected output or runtime error",
                help=
                "If your hash function is causing an integer overflow error, "
                "try removing -fsanitize=integer from CFLAGS in your Makefile!"
            )
        time.load += load
        time.check += check
        time.size += size
        time.unload += unload

    time.total = sum(attr.astuple(time))

    # Memory data.
    memory = Memory()
    check50.run(
        "valgrind --tool=massif --heap=yes --stacks=yes --massif-out-file=massif.out ./speller dictionaries/large texts/holmes.txt 1"
    ).stdout(timeout=20)

    re_heap = re.compile("mem_heap_B=(\d+)")
    re_stack = re.compile("mem_stacks_B=(\d+)")
    with open("massif.out") as f:
        for line in f:
            heap_match = re_heap.match(line)
            stack_match = re_stack.match(line)
            if heap_match:
                memory.heap = max(memory.heap, int(heap_match.groups()[0]))
            elif stack_match:
                memory.stack = max(memory.stack, int(stack_match.groups()[0]))

    check50.data(time=attr.asdict(time), memory=attr.asdict(memory))
Ejemplo n.º 10
0
def synonyms():
    """Checking if command synonyms are handled correctly"""
    check = check50.run(RUN_SMALL)
    check.stdin("W").stdout(room_2_description, regex=False)
    check.stdin("E").stdout(room_1_name, regex=False)

    # check with nonsensical synonyms
    check50.log('changing Synonyms.dat to contain nonsensical synonyms...')
    os.rename(r'data/Synonyms.dat', r'data/Synonyms2.dat')
    os.rename(r'data/NonsensicalSynonyms.dat', r'data/Synonyms.dat')
    check = check50.run(RUN_SMALL)

    try:
        check.stdin("G").stdout(room_2_description, regex=False)
        check.stdin("F").stdout(room_1_name, regex=False)
    except check50.Failure as error:
        raise check50.Failure(f"{error}\n"
                              f"    Your program didn't handle a different Synonyms.dat correctly. Did you hardcode the synonyms?")

    os.rename(r'data/Synonyms.dat', r'data/NonsensicalSynonyms.dat')
    os.rename(r'data/Synonyms2.dat', r'data/Synonyms.dat')
Ejemplo n.º 11
0
def run_and_interpret_checkstyle(rationale=None,
                                 log_msg=None,
                                 log_individual_warnings=False,
                                 **kwargs):
    """
    Execute the checkstyle CLI runner, interpret and log all resulting warnings
    and raise check50 Failure if there were warnings.

    Ideally, this would be replaced by a special check50.Failure subclass
    that encapsulates all warnings and is rendered nicely into html by check50.
    The problem is that check50 hard-codes its html template.

    :param rationale: the message given to the Failure raised in case there are
                      warnings. The substring "{report}" will be replaced by an
                      itemised list of warnings from checkstyle.
    :param log_msg: the message passed on to check50.log in case there are
                    warnings. Again, "{report}" will be substituted.
    :param log_individual_warnings: if true, each warning will be logged on its
                                    own.

    All other parameters are as for :func:`run_checkstyle`.
    """
    report = run_checkstyle(**kwargs)
    if report:
        # all warnings as one string
        report_itemised = "\n".join(["- " + str(w) for w in report])

        if log_msg:
            check50.log(log_msg.format(report=report_itemised))
        if log_individual_warnings:
            for w in report:
                check50.log("- " + str(w))
        if rationale:
            rationale = rationale.format(report=report_itemised)
        else:
            rationale = "issues found"
        raise Failure(rationale=rationale)
Ejemplo n.º 12
0
def run(path,
        argv=tuple(),
        stdin=tuple(),
        set_attributes=(("__name__", "__main__"), )):
    """
	Lets you run a python module while configuring argv, stdin, and attributes prior to running.
	path: the path of the file to run
	argv: list of argv arguments
	set_attributes: a list of tuples [(attribute, value), ...] that are set prior to running
	"""

    path = pathlib.Path(path)
    src = source(path)
    tree = ast.parse(src)

    for node in tree.body[:]:
        if not isinstance(node, ast.FunctionDef):
            tree.body.remove(node)

    code = compile(tree)

    mod = None
    output = ""

    if not argv:
        argv = sys.argv

    with capture_stdout() as stdout_stream, capture_stdin(
    ) as stdin_stream, set_argv(*argv):
        # fill stdin with args
        if stdin:
            for arg in stdin:
                stdin_stream.write(str(arg) + "\n")
            stdin_stream.seek(0)

        moduleName = path.stem

        check50.log(f"importing {moduleName}")
        mod = imp.new_module(moduleName)

        # overwrite attributes
        for attr, value in set_attributes:
            setattr(mod, attr, value)

        try:
            # execute code in mod
            exec(code, mod.__dict__)
        except EOFError:
            raise check50.Failure("You read too much input from stdin")
        except BaseException as e:
            raise PythonException(e)

        # add resulting module to sys
        sys.modules[moduleName] = mod
        #except tuple(ignoreExceptions) as e:
        #	pass

        # wrap every function in mod with Function
        # for name, func in [(name, f) for name, f in mod.__dict__.items() if callable(f)]:
        # 	if func.__module__ == moduleName:
        #		setattr(mod, name, function.Function(func))

    return Result(stdout=stdout_stream.getvalue(),
                  stdin=stdin_stream.read(),
                  module=mod)
Ejemplo n.º 13
0
 def write(self, text):
     check50.log("writing {} to stdin".format(text.replace('\n', '\\n')))
     super().write(text)
Ejemplo n.º 14
0
def check():
    check50.log("AHHHHHHHHHHHHHHHHHHH")
    raise check50.Failure("AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH")
Ejemplo n.º 15
0
def log(lines):
    if isinstance(lines, list):
        for line in lines:
            check50.log(line)
    else:
        check50.log(lines)
Ejemplo n.º 16
0
def print_winner2():
    """print_winner prints winner of election when some pairs are tied"""
    check50.log(check50.run("./tideman_test 4 13").stdout())
    check50.run("./tideman_test 4 13").stdout("Charlie\n").exit(0)