예제 #1
0
def test_check_object_keys():
    s = setup_state('x = {"a": 2}', 'x = {"a": 2}')
    with pytest.raises(
        InstructorError,
        match=r"`check_keys\(\)` couldn't find key `b` in object `x` in the solution process\.",
    ):
        s.check_object("x").check_keys("b")
예제 #2
0
def test_check_object_is_instance():
    s = setup_state("x = 1", "x = 1")
    with pytest.raises(
        InstructorError,
        match=r"`is_instance\(\)` noticed that `x` is not a `str` in the solution process\.",
    ):
        s.check_object("x").is_instance(str)
예제 #3
0
def test_test_custom_equality_func(tol, passes):
    s = setup_state("a = [1.011]", "a = [1.01]")
    import numpy as np

    with helper.verify_sct(passes):
        s.check_object("a").has_equal_value(
            func=lambda x, y: np.allclose(x, y, atol=tol))
예제 #4
0
def test_check_call_lambda(stu, passes):
    s = setup_state(stu, "lambda a, b: a + b")
    with helper.verify_sct(passes):
        s.check_lambda_function().multi(
            check_call("f(1,2)").has_equal_value(),
            check_call("f(1,2)").has_equal_output(),
        )
예제 #5
0
def test_has_import():
    s = setup_state()
    with pytest.raises(
        InstructorError,
        match=r"`has_import\(\)` couldn't find an import of the package numpy in your solution code\.",
    ):
        s.has_import("numpy")
예제 #6
0
def test_check_object():
    s = setup_state()
    with pytest.raises(
        InstructorError,
        match=r"`check_object\(\)` couldn't find object `x` in the solution process\.",
    ):
        s.check_object("x")
예제 #7
0
def check_function_multiple_times():
    from pythonwhat.local import setup_state

    s = setup_state(sol_code="print('test')", stu_code="print('test')")
    helper.passes(s.check_function("print"))
    helper.passes(s.check_function("print").check_args(0))
    helper.passes(s.check_function("print").check_args("value"))
예제 #8
0
def test_assert_ast(element, no_error):
    s = setup_state()._state
    if no_error:
        assert_ast(s, element, {})
    else:
        with pytest.raises(InstructorError):
            assert_ast(s, element, {})
예제 #9
0
def test_args_kwargs_check_function_passing(argspec):
    code = "my_fun(1, 2, 3, 4, c = 5)"
    s = setup_state(pec="def my_fun(a, b, *args, **kwargs): pass",
                    stu_code=code,
                    sol_code=code)
    x = s.check_function("my_fun")
    helper.passes(x.check_args(argspec).has_equal_value())
예제 #10
0
def test_running_file_with_root_check(temp_py_file):
    content = cf.get_file_content(temp_py_file.name)
    chain = setup_state("", "", pec="")

    with tempfile.TemporaryDirectory() as d:
        with ChDir(d):
            chain.check_file(temp_py_file.name,
                             solution_code=content).run().check_object(
                                 "a").has_equal_value()

    with tempfile.TemporaryDirectory() as d:
        with ChDir(d):
            chain.check_file(temp_py_file.name,
                             solution_code=content).run().has_no_error()

    with tempfile.TemporaryDirectory() as d:
        with ChDir(d):
            chain.check_file(temp_py_file.name,
                             solution_code=content).run().has_printout(0)

    with pytest.raises(TF):
        with tempfile.TemporaryDirectory() as d:
            with ChDir(d):
                chain.check_file(
                    temp_py_file.name,
                    solution_code="print('Bye!')").run().has_printout(0)

    with tempfile.TemporaryDirectory() as d:
        with ChDir(d):
            chain.check_file(temp_py_file.name,
                             solution_code=content).run().has_output("Hi")
예제 #11
0
def test_running_file(temp_py_file):
    content = cf.get_file_content(temp_py_file.name)
    chain = setup_state("", "", pec="")

    with tempfile.TemporaryDirectory() as d:
        with ChDir(d):
            chain.check_file(
                temp_py_file.name,
                solution_code=content).run().has_equal_value(expr_code="a")

    with tempfile.TemporaryDirectory() as d:
        with ChDir(d):
            chain.check_file(temp_py_file.name,
                             solution_code=content).run().check_object(
                                 "a").has_equal_value()

    with pytest.raises(TF):
        with tempfile.TemporaryDirectory() as d:
            with ChDir(d):
                chain.check_file(temp_py_file.name,
                                 solution_code=content.replace(
                                     "1",
                                     "2")).run().has_equal_value(expr_code="a")

    with tempfile.TemporaryDirectory() as d:
        with ChDir(d):
            chain.check_file(temp_py_file.name).run().has_equal_value(
                expr_code="a", override=1)

    with pytest.raises(TF):
        with tempfile.TemporaryDirectory() as d:
            with ChDir(d):
                chain.check_file(temp_py_file.name).run().has_equal_value(
                    expr_code="a", override=2)
예제 #12
0
def test_has_printout():
    s = setup_state()
    with pytest.raises(
        InstructorError,
        match=r"`has_printout\(1\)` couldn't find the second print call in your solution\.",
    ):
        s.has_printout(1)
예제 #13
0
def test_run_with_absolute_dir():
    code = 'from pathlib import Path; c = Path("c").read_text(encoding="utf-8")'

    file_dir = "a/b"
    solution_location = "solution"
    workspace_location = "workspace"

    with in_temp_dir():
        os.makedirs(file_dir)
        with ChDir(file_dir):
            abs_dir = os.path.abspath(".")
            abs_file_path = Path(abs_dir, "c")
            with open("c", "w") as f:
                f.write(code)

        write_file(solution_location, "c", code)

        os.makedirs(workspace_location)
        with ChDir(workspace_location):
            chain = setup_state("", "", pec="")

            child = chain.check_file(abs_file_path, solution_code=code)

            child.run(abs_dir).check_object("c")
            child.run().check_object("c")
예제 #14
0
def test_check_function_def_basic(stu, passes):
    s = setup_state(stu, "def test(x): print(x)")
    with helper.verify_sct(passes):
        s.check_function_def("test").multi(
            check_args(0).has_equal_part("name", msg="wrong"),
            check_body().set_context(1).check_function("print").check_args(
                0).has_equal_value(),
        )
예제 #15
0
def check_function_sig_false():
    code = "f(color = 'blue')"
    s = setup_state(pec="def f(*args, **kwargs): pass",
                    sol_code=code,
                    stu_code=code)
    helper.passes(
        s.check_function("f", 0,
                         signature=False).check_args("color").has_equal_ast())
def test_two_for_loops(stu, passes):
    s = setup_state(stu,
                    "for i in range(1):\n  pass\nfor j in range(4): print(j)")
    with helper.verify_sct(passes):
        s.check_for_loop(index=1).multi(
            check_iter().has_equal_value(),
            check_body().set_context(2).has_equal_output(),
        )
예제 #17
0
def test_context_vals_wrong_place_in_chain():
    code = "[(i,j) for i,j in enumerate(range(10))]"
    state = setup_state(code, code)
    with pytest.raises(
        InstructorError,
        match=r"`set_context\(\)` failed: context val names are missing, but you tried to set \['i', 'j'\]\.",
    ):
        state.check_list_comp(0).set_context(i=1, j=2).check_iter()
예제 #18
0
def test_check_call_not_on_check_function_def():
    code = "def x(a): pass"
    s = setup_state(code, code)
    with pytest.raises(
        InstructorError,
        match=r"`check_call\(\)` can only be called on `check_function_def\(\)` or `check_lambda_function\(\)`\.",
    ):
        s.check_object("x").check_call("f(1)")
예제 #19
0
def test_check_keys_not_on_check_object():
    code = "round(3)"
    s = setup_state(code, code)
    with pytest.raises(
        InstructorError,
        match=r"`is_instance\(\)` can only be called on `check_object\(\)` or `check_df\(\)`\.",
    ):
        s.check_function("round").check_args(0).check_keys("a")
예제 #20
0
def test_has_no_error_not_on_root():
    code = "for i in range(3): pass"
    s = setup_state(code, code)
    with pytest.raises(
        InstructorError,
        match=r"`has_no_error\(\)` should only be called focusing on a full script, following `Ex\(\)` or `run\(\)`\.",
    ):
        s.check_for_loop().check_body().has_no_error()
예제 #21
0
def test_has_printout_not_on_root():
    code = "for i in range(3): print(i)"
    s = setup_state(code, code)
    with pytest.raises(
        InstructorError,
        match=r"`has_printout\(\)` should only be called focusing on a full script, following `Ex\(\)` or `run\(\)`\. If you want to check printouts done in e.g. a for loop, you have to use a `check_function\('print'\)` chain instead.",
    ):
        s.check_for_loop().check_body().has_printout(0)
예제 #22
0
def test_set_context():
    code = "x = { m:len(m) for m in ['a', 'b', 'c'] }"
    s = setup_state(code, code)
    with pytest.raises(
        InstructorError,
        match=r"In `set_context\(\)`, specify arguments either by position, either by name\.",
    ):
        s.check_dict_comp().check_key().set_context("a", m="a").has_equal_value()
예제 #23
0
def test_file_parsing(temp_py_file):
    expected_content = cf.get_file_content(temp_py_file.name)
    chain = setup_state("", "", pec="")

    file_chain = chain.check_file(temp_py_file.name,
                                  solution_code=expected_content)
    file_chain.check_if_else().check_test().has_equal_value()
    file_chain.check_if_else().check_test().has_equal_value(expr_code="False")
예제 #24
0
def test_manual_converter_2():
    s = setup_state(
        stu_code="my_array = np.array([[0,0], [0,0], [0,0]])",
        sol_code="my_array = np.array([[1,2], [3,4], [5,6]])",
        pec="import numpy as np",
    )
    set_converter(key="numpy.ndarray", fundef=lambda x: x.shape)
    s.check_object("my_array").has_equal_value()
예제 #25
0
def test_test_function_v2_no_sig():
    s = setup_state("np.arange(10)", "np.arange(10)", pec="import numpy as np")
    # test_function_v2 sets signature=False if no params
    s.test_function_v2("numpy.arange")
    # check_function fails unless explicity setting signature=Fa
    s.check_function("numpy.arange", signature=False)
    with pytest.raises(InstructorError):
        s.check_function("numpy.arange")
예제 #26
0
def test_running_code_isolation_run(sol_code, stu_code):
    # test that setup_state is isolated
    chain = setup_state(sol_code, stu_code, pec="")
    chain._state.solution_code = sol_code
    chain._state.student_code = stu_code

    with verify_sct(False):
        # test that run is isolated
        chain.run().has_equal_value(name="bar", override="bar")
def test_check_class_def_pass(stu, passes):
    sol = "class A(str):\n  def __init__(self): pass"
    s = setup_state(stu, sol)
    with helper.verify_sct(passes):
        s.check_class_def("A").multi(
            check_bases(0).has_equal_ast(),
            check_body().check_function_def(
                "__init__").check_body().has_equal_ast(),
        )
예제 #28
0
def test_urlopen_in_process(sol_code, stu_code):
    with in_temp_dir():
        chain = setup_state("", "", pec="")

        chain._state.solution_code = sol_code
        chain._state.student_code = stu_code

        with verify_sct(True):
            chain.run()
예제 #29
0
def test_args_kwargs_check_function_failing_not_specified(argspec, msg):
    s = setup_state(
        pec="def my_fun(a, b, *args, **kwargs): pass",
        sol_code="my_fun(1, 2, 3, 4, c = 5)",
        stu_code="my_fun(1, 2)",
    )
    x = s.check_function("my_fun")
    with pytest.raises(TF, match=msg):
        x.check_args(argspec)
예제 #30
0
def test_args_kwargs_check_function_failing_not_correct(argspec, msg):
    s = setup_state(
        pec="def my_fun(a, b, *args, **kwargs): pass",
        sol_code="my_fun(1, 2, 3, 4, c = 5)",
        stu_code="my_fun(1, 2, 4, 5, c = 6)",
    )
    x = s.check_function("my_fun")
    with pytest.raises(TF, match=msg):
        x.check_args(argspec).has_equal_value()