Skip to content

Commit

Permalink
Format code
Browse files Browse the repository at this point in the history
  • Loading branch information
hermansje committed Mar 25, 2019
1 parent f7c85ac commit 417f953
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 107 deletions.
98 changes: 61 additions & 37 deletions tests/test_check_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,91 +11,115 @@
# TODO: selectors require a _priority attribute and _get_field_names
# this is a holdover from the sql ast modules
ast.Expr._priority = 0
DUMMY_NODES = {'Expr': ast.Expr}
DUMMY_NODES = {"Expr": ast.Expr}


class ParseHey:
ParseError = SyntaxError

def parse(self, code, *args, **kwargs): return ast.parse(code)
def parse(self, code, *args, **kwargs):
return ast.parse(code)


def assert_equal_ast(a, b):
assert ast.dump(a) == ast.dump(b)


@pytest.fixture(scope="function")
def tf():
with NamedTemporaryFile() as tmp:
tmp.file.write(b'1 + 1')
tmp.file.write(b"1 + 1")
tmp.file.flush()
yield tmp


@pytest.fixture(scope="function")
def state():
return State(
student_code = "",
solution_code = "",
reporter = Reporter(),
student_code="",
solution_code="",
reporter=Reporter(),
# args below should be ignored
pre_exercise_code = "NA",
student_result = "", solution_result = "",
student_conn = None, solution_conn = None,
ast_dispatcher = Dispatcher(ast.AST, DUMMY_NODES, ParseHey())
)
pre_exercise_code="NA",
student_result="",
solution_result="",
student_conn=None,
solution_conn=None,
ast_dispatcher=Dispatcher(ast.AST, DUMMY_NODES, ParseHey()),
)


def test_initial_state():
State(student_code = {'script.py': '1'}, solution_code = {'script.py': '1'},
reporter = Reporter(), pre_exercise_code = "",
student_result = "", solution_result = "",
student_conn = None, solution_conn = None,
ast_dispatcher = Dispatcher(ast.AST, DUMMY_NODES, ParseHey()))
State(
student_code={"script.py": "1"},
solution_code={"script.py": "1"},
reporter=Reporter(),
pre_exercise_code="",
student_result="",
solution_result="",
student_conn=None,
solution_conn=None,
ast_dispatcher=Dispatcher(ast.AST, DUMMY_NODES, ParseHey()),
)


def test_check_file_use_fs(state, tf):
state.solution_code = { tf.name: '3 + 3' }
child = cf.check_file(state, tf.name, use_solution = True)
assert child.student_code == '1 + 1'
state.solution_code = {tf.name: "3 + 3"}
child = cf.check_file(state, tf.name, use_solution=True)
assert child.student_code == "1 + 1"
assert_equal_ast(child.student_ast, ast.parse(child.student_code))
assert child.solution_code == '3 + 3'
assert child.solution_code == "3 + 3"
assert_equal_ast(child.solution_ast, ast.parse(child.solution_code))
assert check_node(child, 'Expr', 0)
assert check_node(child, "Expr", 0)


def test_check_file_use_fs_no_parse(state, tf):
state.solution_code = { tf.name: '3 + 3' }
child = cf.check_file(state, tf.name, parse = False)
assert child.student_code == '1 + 1'
state.solution_code = {tf.name: "3 + 3"}
child = cf.check_file(state, tf.name, parse=False)
assert child.student_code == "1 + 1"
assert child.student_ast is None
assert child.solution_ast is None
with pytest.raises(TypeError):
assert check_node(child, 'Expr', 0)
assert check_node(child, "Expr", 0)


def test_check_no_sol(state, tf):
child = cf.check_file(state, tf.name, use_fs = True)
child = cf.check_file(state, tf.name, use_fs=True)
assert child.solution_code is None


def test_check_dir(state):
with TemporaryDirectory() as td:
cf.has_dir(state, td)


@pytest.fixture(scope="function")
def code_state():
return State(
student_code = {'script1.py': '1 + 1', 'script2.py': '2 + 2'},
solution_code = {'script1.py': '3 + 3', 'script2.py': '4 + 4'},
reporter = Reporter(),
student_code={"script1.py": "1 + 1", "script2.py": "2 + 2"},
solution_code={"script1.py": "3 + 3", "script2.py": "4 + 4"},
reporter=Reporter(),
# args below should be ignored
pre_exercise_code = "NA",
student_result = "", solution_result = "",
student_conn = None, solution_conn = None,
ast_dispatcher = Dispatcher(ast.AST, DUMMY_NODES, ParseHey())
)
pre_exercise_code="NA",
student_result="",
solution_result="",
student_conn=None,
solution_conn=None,
ast_dispatcher=Dispatcher(ast.AST, DUMMY_NODES, ParseHey()),
)


def test_check_file(code_state):
child = cf.check_file(code_state, 'script1.py', use_fs=False, use_solution=True)
child = cf.check_file(code_state, "script1.py", use_fs=False, use_solution=True)
assert child.student_code == "1 + 1"
assert_equal_ast(child.student_ast, ast.parse(child.student_code))
assert_equal_ast(child.solution_ast, ast.parse(child.solution_code))


def test_check_file_no_parse(code_state):
child = cf.check_file(code_state, 'script1.py', use_fs=False, parse = False, use_solution=True)
child = cf.check_file(
code_state, "script1.py", use_fs=False, parse=False, use_solution=True
)
assert child.student_code == "1 + 1"
assert child.student_ast is None
assert child.solution_ast is None

72 changes: 42 additions & 30 deletions tests/test_check_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,87 @@
from protowhat.Test import TestFail as TF
from functools import partial


@pytest.fixture(scope="function")
def state():
return State(
student_code = "",
solution_code = "",
reporter = Reporter(),
student_code="",
solution_code="",
reporter=Reporter(),
# args below should be ignored
pre_exercise_code = "NA",
student_result = {'a': [1]}, solution_result = {'b': [2]},
student_conn = None, solution_conn = None)
pre_exercise_code="NA",
student_result={"a": [1]},
solution_result={"b": [2]},
student_conn=None,
solution_conn=None,
)


def fails(state, msg=""):
def fails(state, msg=""):
cl.fail(state, msg)


def passes(state):
return state

@pytest.mark.parametrize('arg1', ( passes, [passes, passes] ))
@pytest.mark.parametrize('arg2', ( passes, [passes, passes] ))

@pytest.mark.parametrize("arg1", (passes, [passes, passes]))
@pytest.mark.parametrize("arg2", (passes, [passes, passes]))
def test_test_multi_pass_one(state, arg1, arg2):
cl.multi(state, arg1, arg2)

@pytest.mark.parametrize('arg1', ( fails, [passes, fails] ))

@pytest.mark.parametrize("arg1", (fails, [passes, fails]))
def test_test_multi_fail_arg1(state, arg1):
with pytest.raises(TF): cl.multi(state, arg1)
with pytest.raises(TF):
cl.multi(state, arg1)


@pytest.mark.parametrize('arg2', ( fails, [passes, fails] ))
@pytest.mark.parametrize("arg2", (fails, [passes, fails]))
def test_test_multi_fail_arg2(state, arg2):
with pytest.raises(TF): cl.multi(state, passes, arg2)
with pytest.raises(TF):
cl.multi(state, passes, arg2)


def test_check_or_pass(state):
cl.check_or(state, passes, fails)


def test_check_or_fail(state):
f1, f2 = partial(fails, msg="f1"), partial(fails, msg="f2")
with pytest.raises(TF, match='f1'):
with pytest.raises(TF, match="f1"):
cl.check_or(state, f1, f2)

@pytest.mark.parametrize('arg1', [
fails,
[fails, fails]
])

@pytest.mark.parametrize("arg1", [fails, [fails, fails]])
def test_check_not_pass(state, arg1):
cl.check_not(state, arg1, msg='fail')
cl.check_not(state, arg1, msg="fail")

@pytest.mark.parametrize('arg1', [
passes,
[passes, fails],
[fails, passes]
])

@pytest.mark.parametrize("arg1", [passes, [passes, fails], [fails, passes]])
def test_check_not_fail(state, arg1):
with pytest.raises(TF, match='boom'):
cl.check_not(state, arg1, msg='boom')
with pytest.raises(TF, match="boom"):
cl.check_not(state, arg1, msg="boom")


def test_check_correct_pass(state):
cl.check_correct(state, passes, fails)


def test_check_correct_fail_force_diagnose(state):
state.force_diagnose = True
with pytest.raises(TF, match='f2'):
with pytest.raises(TF, match="f2"):
cl.check_correct(state, passes, partial(fails, msg="f2"))


def test_check_correct_fail_msg(state):
f1, f2 = partial(fails, msg="f1"), partial(fails, msg="f2")
with pytest.raises(TF, match='f2'):
with pytest.raises(TF, match="f2"):
cl.check_correct(state, f1, f2)


@pytest.mark.debug
def test_check_correct_fail_multi_msg(state):
f1, f2, f3 = [partial(fails, msg="f%s"%ii) for ii in range(1, 4)]
with pytest.raises(TF, match='f2'):
f1, f2, f3 = [partial(fails, msg="f%s" % ii) for ii in range(1, 4)]
with pytest.raises(TF, match="f2"):
cl.check_correct(state, [f1, f3], [f2, f3])
45 changes: 28 additions & 17 deletions tests/test_check_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,61 @@
from protowhat.Test import TestFail as TF
import pytest

sct_ctx = {'has_chosen': has_chosen, 'success_msg': success_msg}
sct_ctx = {"has_chosen": has_chosen, "success_msg": success_msg}


def prepare_state(student_code):
return State(
student_code = student_code,
reporter = Reporter(),
student_code=student_code,
reporter=Reporter(),
# args below should be ignored
solution_code = "NA", pre_exercise_code = "NA",
solution_ast = "NA", student_ast = "NA",
student_result = [], solution_result = [],
student_conn = None, solution_conn = None
solution_code="NA",
pre_exercise_code="NA",
solution_ast="NA",
student_ast="NA",
student_result=[],
solution_result=[],
student_conn=None,
solution_conn=None,
)


def test_has_chosen_alone_pass():
state = prepare_state("selected_option = 1")
has_chosen(state, 1, ['good', 'bad'])
has_chosen(state, 1, ["good", "bad"])


def test_has_chosen_alone_fail():
state = prepare_state("selected_option = 2")
with pytest.raises(TF):
has_chosen(state, 1, ['good', 'bad'])
has_chosen(state, 1, ["good", "bad"])


def test_has_chosen_chain_pass():
state = prepare_state("selected_option = 1")
Chain(state, sct_ctx).has_chosen(1, ['good', 'bad'])
assert state.reporter.build_final_payload()['message'] == 'good'
Chain(state, sct_ctx).has_chosen(1, ["good", "bad"])
assert state.reporter.build_final_payload()["message"] == "good"


def test_has_chosen_chain_fail():
state = prepare_state("selected_option = 2")
with pytest.raises(TF, match = 'bad'):
Chain(state, sct_ctx).has_chosen(1, ['good', 'bad'])
with pytest.raises(TF, match="bad"):
Chain(state, sct_ctx).has_chosen(1, ["good", "bad"])


def test_success_msg_pass():
state = prepare_state("")
success_msg(state, "NEW SUCCESS MSG")

sct_payload = state.reporter.build_final_payload()
assert sct_payload['correct'] == True
assert sct_payload['message'] == "NEW SUCCESS MSG"
assert sct_payload["correct"] == True
assert sct_payload["message"] == "NEW SUCCESS MSG"


def test_success_msg_pass_ex():
state = prepare_state("")
Chain(state, sct_ctx).success_msg("NEW SUCCESS MSG")

sct_payload = state.reporter.build_final_payload()
assert sct_payload['correct'] == True
assert sct_payload['message'] == "NEW SUCCESS MSG"
assert sct_payload["correct"] == True
assert sct_payload["message"] == "NEW SUCCESS MSG"
Loading

0 comments on commit 417f953

Please sign in to comment.