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)
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, {})
def check_function_multiple_times(): from pythoncheck.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'))
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')
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)
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")
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")
def test_is_instance_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\(\)`\."): s.check_function('round').check_args(0).is_instance(int)
def test_disable_highlighting(): s = setup_state(stu_code="round(1.234, 2)", sol_code="round(2.345, 2)") assert s._state.highlighting_disabled is None assert s.disable_highlighting()._state.highlighting_disabled assert s.disable_highlighting().check_function( 'round')._state.highlighting_disabled assert s.check_function( 'round').disable_highlighting()._state.highlighting_disabled
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)
def test_basic_check_function_failing(): pec = 'def my_fun(a=1): pass' sol = 'my_fun(1)' s = setup_state(stu_code = '', sol_code=sol, pec=pec) with pytest.raises(TF): s.check_function('my_fun') s = setup_state(stu_code = 'my_fun()', sol_code=sol, pec=pec) helper.passes(s.check_function('my_fun')) with pytest.raises(TF): s.check_function('my_fun').check_args('a') s = setup_state(stu_code = 'my_fun(a = 10)', sol_code=sol, pec=pec) helper.passes(s.check_function('my_fun')) helper.passes(s.check_function('my_fun').check_args('a')) with pytest.raises(TF): s.check_function('my_fun').check_args('a').has_equal_value()
def test_basic_check_function_passing(arg, stu): pec = 'def my_fun(a, b): pass' sol = 'my_fun(1, 2)' s = setup_state(stu_code=stu, sol_code=sol, pec=pec) helper.passes(s.check_function('my_fun')) helper.passes(s.check_function('my_fun').check_args(arg)) helper.passes(s.check_function('my_fun').check_args(arg).has_equal_value())
def test_method_2(): code = "df[df.b == 'x'].a.sum()" s = setup_state(sol_code = code, stu_code = code, pec = "import pandas as pd; df = pd.DataFrame({'a': [1, 2, 3], 'b': ['x', 'x', 'y']})") helper.passes(s.check_function('df.a.sum', signature = False)) from pythoncheck.signatures import sig_from_obj import pandas as pd helper.passes(s.check_function('df.a.sum', signature = sig_from_obj(pd.Series.sum)))
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()
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 from the root state, `Ex\(\)`\." ): s.check_for_loop().check_body().has_printout(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)")
def test_method_1(): code = "df.groupby('b').sum()" s = setup_state(sol_code = code, stu_code = code, pec = "import pandas as pd; df = pd.DataFrame({'a': [1, 2, 3], 'b': ['x', 'x', 'y']})") helper.passes(s.check_function('df.groupby').check_args(0).has_equal_value()) helper.passes(s.check_function('df.groupby.sum', signature = False)) from pythoncheck.signatures import sig_from_obj import pandas as pd helper.passes(s.check_function('df.groupby.sum', signature = sig_from_obj(pd.Series.sum)))
def test_has_equal_ast_on_check_function_v2(): code = 'round(1)' s = setup_state(code, code) with helper.set_v2_only_env('1'): with pytest.raises( InstructorError, match= r"`has_equal_ast\(\)` should not be called on `check_function\(\)`\." ): s.check_function('round').has_equal_ast()
def test_has_equal_ast_on_check_object_v2(): code = 'x = 1' s = setup_state(code, code) with helper.set_v2_only_env('1'): with pytest.raises( InstructorError, match= r"`has_equal_ast\(\)` should not be called on `check_object\(\)`\." ): s.check_object('x').has_equal_ast()
def test_check_object_not_on_root_v2(): code = 'for i in range(3): x = 1' s = setup_state(code, code) with helper.set_v2_only_env('1'): with pytest.raises( InstructorError, match= r"`check_object\(\)` should only be called from the root state, `Ex\(\)`\." ): s.check_for_loop().check_body().check_object('x')
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()
def test_bind_args(): from pythoncheck.local import setup_state from inspect import signature from pythoncheck.check_function import bind_args pec = "def my_fun(a, b, *args, **kwargs): pass" s = setup_state(pec = pec, stu_code = "my_fun(1, 2, 3, 4, c = 5)") args = s._state.student_function_calls['my_fun'][0]['args'] sig = signature(s._state.student_process.shell.user_ns['my_fun']) binded_args = bind_args(sig, args) assert binded_args['a']['node'].n == 1 assert binded_args['b']['node'].n == 2 assert binded_args['args'][0]['node'].n == 3 assert binded_args['args'][1]['node'].n == 4 assert binded_args['kwargs']['c']['node'].n == 5
def test_has_printout_multiple(stu): sol = 'print("randomness")\nprint(1, 2, 3)' s = setup_state(stu_code=stu, sol_code=sol) helper.passes(s.has_printout(1))
def test_basic_has_printout_failing_custom(): sol = 'print(1, 2, 3)' stu = 'print(1, 2)' s = setup_state(stu_code=stu, sol_code=sol) with pytest.raises(TF, match='wrong'): s.has_printout(0, not_printed_msg='wrong')
def test_basic_has_printout(stu, correct): sol = 'print(1, 2, 3)' s = setup_state(stu_code=stu, sol_code=sol) with helper.verify_sct(correct): s.has_printout(0)
def test_has_expr_override_pass(): stu = 'x = [1, 2, 3]' sol = 'x = [1, 2, 5]' s = setup_state(stu_code=stu, sol_code=sol) helper.passes(s.check_object('x').has_equal_value(expr_code = 'x[2]', override=3))
def test_chaining(stu, correct): s = setup_state(stu_code = stu, sol_code = 'import numpy.random as rand') with helper.verify_sct(correct): s.has_import('numpy.random')
def test_same_as(stu, same_as, correct): s = setup_state(stu_code = stu, sol_code = 'import pandas as pd') with helper.verify_sct(correct): s.has_import('pandas', same_as = same_as)
def test_basic(stu, correct): s = setup_state(stu_code = stu, sol_code = 'import pandas as pd') with helper.verify_sct(correct): s.has_import('pandas')
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())