コード例 #1
0
def test_dynamic_registration_named(state, dummy_checks):
    diagnose_calls = 0

    # this makes diagnose a LazyChain wrapper
    @state_dec_gen(dummy_checks)
    def diagnose(end_state):
        assert end_state.state_history[0] is state
        nonlocal diagnose_calls
        diagnose_calls += 1

    TestEx = ExGen(dummy_checks, state)
    TestF = LazyChainStart(dummy_checks)

    TestEx.register_chainable_function(diagnose, "test123")

    TestEx().test123()
    TestEx() >> TestF().test123()
    TestEx() >> diagnose()
    assert diagnose_calls == 3

    with pytest.raises(AttributeError):
        # The function is registered with a given name (test123)
        TestEx().diagnose()

    with pytest.raises(NameError):
        TestEx() >> test123()
コード例 #2
0
def test_multiple_dynamic_registrations(state, dummy_checks):
    diagnose_calls = 0

    state_dec = state_dec_gen(dummy_checks)

    @state_dec
    def diagnose1(end_state):
        assert end_state.state_history[0] is state
        nonlocal diagnose_calls
        diagnose_calls += 1

    @state_dec
    def diagnose2(end_state):
        assert end_state.state_history[0] is state
        nonlocal diagnose_calls
        diagnose_calls += 1

    TestEx = ExGen(dummy_checks, state)
    TestF = LazyChainStart(dummy_checks)

    TestEx.register_chainable_function(diagnose1)
    TestEx.register_chainable_function(diagnose2)

    TestEx().diagnose1().diagnose2()
    TestEx() >> TestF().diagnose1().diagnose2()
    TestEx() >> diagnose1().diagnose2()
    TestEx() >> diagnose1() >> diagnose2()
    assert diagnose_calls == 8

    TestEx().diagnose1().noop().diagnose2().noop()
    TestEx() >> TestF().diagnose1().noop().diagnose2().noop()
    TestEx() >> diagnose1().noop() >> diagnose2().noop()
    assert diagnose_calls == 14

    TestEx().child_state().diagnose1().diagnose2()
コード例 #3
0
def test_dynamic_registration(state, dummy_checks):
    diagnose_calls = 0

    @state_dec_gen(dummy_checks)
    def diagnose(end_state):
        assert end_state.state_history[0] is state
        nonlocal diagnose_calls
        diagnose_calls += 1

    TestEx = ExGen(dummy_checks, state)
    TestF = LazyChainStart(dummy_checks)

    TestEx.register_chainable_function(diagnose)

    TestEx().diagnose()
    TestEx() >> TestF().diagnose()
    TestEx() >> diagnose()
    assert diagnose_calls == 3

    TestEx().diagnose().noop()
    TestEx() >> TestF().diagnose().noop()
    TestEx() >> diagnose().noop()
    assert diagnose_calls == 6

    TestEx().child_state().diagnose()
コード例 #4
0
def test_create_embed_context(state, dummy_checks):
    # Given
    Ex = ExGen(dummy_checks, state)
    assert Ex()._state == state

    def derive_custom_state_args(parent_state):
        assert parent_state == state
        return {"student_code": "override"}

    # When
    embed_context = create_embed_context(
        "proto",
        Ex(),
        derive_custom_state_args=derive_custom_state_args,
    )

    # Then
    assert isinstance(embed_context["get_bash_history"](), LazyChain)
    assert isinstance(embed_context["F"]().get_bash_history(), LazyChain)

    embed_state = embed_context["Ex"].root_state
    assert isinstance(embed_state, State)
    assert embed_state.student_code == "override"
    assert embed_state.reporter.runner == state.reporter
    assert embed_state.creator == {"type": "embed", "args": {"state": state}}
コード例 #5
0
def test_sct_reflection(dummy_checks):
    def diagnose(_):
        raise RuntimeError("This is not run")

    sct_dict = {"diagnose": diagnose, **dummy_checks}
    Ex = ExGen(sct_dict, None, strict=False)
    F = LazyChainStart(sct_dict)

    chain_part_1 = Ex().noop().child_state()
    assert str(chain_part_1) == "child_state()"

    chain_part_2 = F().diagnose().fail()
    assert str(chain_part_2) == "diagnose().fail()"

    chain_part_3 = F().noop()
    assert str(chain_part_3) == "noop()"

    chain_part_2_and_3 = chain_part_2 >> chain_part_3
    assert str(chain_part_2_and_3) == "diagnose().fail().noop()"

    chain = chain_part_1 >> chain_part_2_and_3
    assert str(chain) == str(chain_part_2_and_3)
    assert str(chain_part_1) == "child_state().diagnose().fail().noop()"

    assert str(Ex) == "Ex().noop().child_state().diagnose().fail().noop()"
コード例 #6
0
def test_dynamic_registration_raising(state, dummy_checks):
    @state_dec_gen(dummy_checks)
    def diagnose(_):
        raise InstructorError.from_message("problem")

    TestEx = ExGen(dummy_checks, state)
    TestEx.register_chainable_function(diagnose)

    with pytest.raises(InstructorError) as e:
        TestEx().diagnose()

    # If calls with a state argument in state_dec would be decorated with link_to_state,
    # there would be a double link_to_state call when an sct decorated with state_dec
    # is registered for chaining
    assert len(re.findall("Debug", str(e.value))) == 1
    assert len(e.value.state_history) == 2
コード例 #7
0
def test_state_linking_root_creator_noop(state, dummy_checks):
    def diagnose(end_state):
        assert end_state.creator is None

    sct_dict = {"diagnose": diagnose, **dummy_checks}
    TestEx = ExGen(sct_dict, state)
    TestF = LazyChainStart(sct_dict)
    TestEx().noop() >> TestF().diagnose()
コード例 #8
0
def test_delayed_debug(state, dummy_checks):
    Ex = ExGen(state, {"_debug": _debug, **dummy_checks})
    try:
        Ex()._debug("breakpoint name", on_error=True).noop().child_state().fail()
        assert False
    except TF as e:
        assert "history" in str(e)
        assert "child_state" in str(e)
        assert "test" in str(e)
コード例 #9
0
def test_state_linking_root_creator_child_state(state, dummy_checks):
    def diagnose(end_state):
        assert end_state != state
        assert end_state.parent_state is state
        assert len(end_state.state_history) == 2
        assert state == end_state.state_history[0]
        assert end_state == end_state.state_history[1]

    TestEx = ExGen(state, dummy_checks)
    TestEx().child_state() >> F(attr_scts={"diagnose": diagnose}).diagnose()
コード例 #10
0
def test_get_embed_chain_constructors(state, dummy_checks):
    # Given
    Ex = ExGen(dummy_checks, state)
    assert Ex()._state == state

    # When
    EmbedEx, EmbedF = get_embed_chain_constructors("proto", Ex())

    # Then
    assert isinstance(EmbedEx(), EagerChain)
    assert isinstance(EmbedF(), LazyChain)
コード例 #11
0
def test_state_linking_root_creator_child_state(state, dummy_checks):
    def diagnose(end_state):
        assert end_state != state
        assert end_state.parent_state is state
        assert len(end_state.state_history) == 2
        assert state == end_state.state_history[0]
        assert end_state == end_state.state_history[1]

    sct_dict = {"diagnose": diagnose, **dummy_checks}
    TestEx = ExGen(sct_dict, state)
    TestF = LazyChainStart(sct_dict)
    TestEx().child_state() >> TestF().diagnose()
コード例 #12
0
def test_debug(state, dummy_checks):
    state.do_test(Success("msg"))
    sct_dict = {"_debug": _debug, **dummy_checks}
    Ex = ExGen(sct_dict, state)
    try:
        Ex().noop().child_state() >> LazyChain(
            chainable_functions=sct_dict)._debug("breakpoint name")
        assert False
    except InstructorError as e:
        assert "breakpoint name" in str(e)
        assert "history" in str(e)
        assert "child_state" in str(e)
        assert "test" in str(e)
コード例 #13
0
def test_debug(state, dummy_checks):
    state.do_test(Success("msg"))
    Ex = ExGen(state, dummy_checks)
    try:
        Ex().noop().child_state() >> F(attr_scts={"_debug": _debug})._debug(
            "breakpoint name"
        )
        assert False
    except TF as e:
        assert "breakpoint name" in str(e)
        assert "history" in str(e)
        assert "child_state" in str(e)
        assert "test" in str(e)
コード例 #14
0
ファイル: sct_context.py プロジェクト: alexyarosh/protowhat
def create_sct_context(sct_dict,
                       root_state: State = None) -> Dict[str, Callable]:
    """
    Create the globals that will be available when running the SCT.

    Args:
        sct_dict: a dictionary of the functions to make available
        root_state: a State instance with the exercise information available to the SCT

    Returns:
        dict: the globals available to the SCT code
    """
    state_dec = state_dec_gen(sct_dict)
    sct_ctx = {k: state_dec(v) for k, v in sct_dict.items()}

    ctx = {
        **sct_ctx,
        "state_dec": state_dec,  # needed by ext packages
        "Ex": ExGen(sct_dict, root_state),
        "F": LazyChainStart(sct_dict),
    }

    return ctx
コード例 #15
0
def test_final_debug(state, dummy_checks):
    Ex = ExGen({"_debug": _debug, **dummy_checks}, state)
    Ex()._debug("breakpoint name", on_error=True).noop().child_state()
    assert state.reporter.fail
コード例 #16
0
ファイル: sct_syntax.py プロジェクト: datacamp/pythonwhat
def get_chains():
    return {
        "Ex": ExGen(sct_dict, State.root_state),
        "F": LazyChainStart(sct_dict),
    }
コード例 #17
0
from protowhat.failure import TestFail as TF
from protowhat.selectors import Dispatcher
from protowhat.State import State
from protowhat.Reporter import Reporter

from protowhat.sct_syntax import LazyChain, ExGen
from protowhat.checks import check_files as cf
from protowhat.checks.check_funcs import check_node, has_code

# TODO: selectors require a _priority attribute
#  this is a holdover from the sql ast modules
ast.Expr._priority = 0
DUMMY_NODES = {"Expr": ast.Expr}

Ex = ExGen({}, None)


class ParseHey:
    ParseError = SyntaxError

    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
def temp_file_sum():
コード例 #18
0
from protowhat.State import State
from protowhat.sct_syntax import ExGen, F, state_dec_gen
import pytest

state_dec = state_dec_gen(State, {})
Ex = ExGen(State, {})


@pytest.fixture
def addx():
    return lambda state, x: state + x


@pytest.fixture
def f():
    return F._from_func(lambda state, b: state + b, b='b')


@pytest.fixture
def f2():
    return F._from_func(lambda state, c: state + c, c='c')


def test_f_from_func(f):
    assert f('a') == 'ab'


def test_f_sct_copy_kw(addx):
    assert F()._sct_copy(addx)(x='x')('state') == 'statex'

コード例 #19
0
def test_state_linking_root_creator_noop(state, dummy_checks):
    def diagnose(end_state):
        assert end_state.creator is None

    TestEx = ExGen(state, dummy_checks)
    TestEx().noop() >> F(attr_scts={"diagnose": diagnose}).diagnose()
コード例 #20
0
import pytest

from protowhat.failure import InstructorError
from protowhat.sct_syntax import (
    ChainedCall,
    ChainExtender,
    EagerChain,
    ExGen,
    LazyChain,
    LazyChainStart,
    state_dec_gen,
)
from tests.helper import state, dummy_checks

sct_dict = {}
Ex = ExGen(sct_dict, None)
state_dec = state_dec_gen(sct_dict)

state = pytest.fixture(state)
dummy_checks = pytest.fixture(dummy_checks)


@pytest.fixture
def addx():
    return lambda state, x: state + x


@pytest.fixture
def f():
    return LazyChain(ChainedCall(lambda state, b: state + b, kwargs={"b":
                                                                     "b"}))