def test_marker_interfaces(self): # return {Type:None} # don't pass when a requirement is for a type but value is None class Marker(object): pass m = Mock() def setup(): m.setup() return {Marker: nothing} @requires(Marker) def use(): m.use() runner = Runner() runner.add(setup, returns=returns_mapping(), label='setup') runner['setup'].add(use) runner() compare([ call.setup(), call.use(), ], m.mock_calls)
def test_attr_multiple(self): class T2: bar = 'baz' class T: foo = T2() m = Mock() def job1(): m.job1() return T() def job2(obj): m.job2(obj) runner = Runner() runner.add(job1) runner.add(job2, requires(attr(T, 'foo', 'bar'))) runner() compare([ call.job1(), call.job2('baz'), ], m.mock_calls)
def test_modifier_changes_endpoint(self): m = Mock() runner = Runner(m.job1) compare(runner.end.obj, m.job1) verify(runner, (m.job1, set()), ) mod = runner.add(m.job2, label='foo') compare(runner.end.obj, m.job2) verify(runner, (m.job1, set()), (m.job2, {'foo'}), ) mod.add(m.job3) compare(runner.end.obj, m.job3) compare(runner.end.labels, {'foo'}) verify(runner, (m.job1, set()), (m.job2, set()), (m.job3, {'foo'}), ) runner.add(m.job4) compare(runner.end.obj, m.job4) compare(runner.end.labels, set()) verify(runner, (m.job1, set()), (m.job2, set()), (m.job3, {'foo'}), (m.job4, set()), )
def test_returns_list(self): m = Mock() class T1(object): pass class T2(object): pass t1 = T1() t2 = T2() def job1(): m.job1() return [t1, t2] @requires(obj1=T1, obj2=T2) def job2(obj1, obj2): m.job2(obj1, obj2) runner = Runner() runner.add(job1, returns=returns(T1, T2)) runner.add(job2) runner() compare([ call.job1(), call.job2(t1, t2), ], m.mock_calls)
def test_return_type_specified_imperative(self): m = Mock() class T1(object): pass class T2(object): pass t = T1() def job1(): m.job1() return t @requires(T2) def job2(obj): m.job2(obj) runner = Runner() runner.add(job1, returns=returns(T2)) runner.add(job2, requires(T2)) runner() compare([ call.job1(), call.job2(t), ], m.mock_calls)
def test_clone_between_empty(self): m = Mock() runner1 = Runner() runner1.add(m.f1, label='first') runner1.add(m.f2, label='second') runner2 = runner1.clone(start_label='first', end_label='second') verify(runner2)
def test_duplicate_label_runner_next_add(self): m = Mock() runner = Runner() runner.add(m.job1, label='label') with ShouldRaise(ValueError( "'label' already points to "+repr(m.job1)+" requires() " "returns_result_type() <-- label" )): runner.add(m.job2, label='label') verify(runner, (m.job1, {'label'}), )
def test_modifier_add_moves_label(self): def job1(): pass def job2(): pass runner = Runner() runner.add(job1, label='the label') runner['the label'].add(job2) verify(runner, (job1, set()), (job2, {'the label'}))
def test_runner_add_does_not_move_label(self): def job1(): pass def job2(): pass runner = Runner() runner.add(job1, label='the label') runner.add(job2) verify(runner, (job1, {'the label'}), (job2, set()))
def test_replace_keep_explicit_requirements(self): def foo(): return 'bar' def barbar(sheep): return sheep*2 runner = Runner() runner.add(foo, returns='flossy') runner.add(barbar, requires='flossy') compare(runner(), expected='barbar') runner.replace(barbar, lambda dog: None) compare(runner(), expected=None)
def test_replace_explicit_at_end(self): m = Mock() runner = Runner(m.job1, m.job2) runner.replace(m.job2, m.jobnew, returns='mock') runner.add(m.jobnew2) runner() compare([ call.job1(), call.jobnew(), call.jobnew2(), ], actual=m.mock_calls)
def test_replace_keep_explicit_requirements(self): def foo(): return 'bar' def barbar(sheep): return sheep * 2 runner = Runner() runner.add(foo, returns='flossy') runner.add(barbar, requires='flossy') compare(runner(), expected='barbar') runner.replace(barbar, lambda dog: None) compare(runner(), expected=None)
def test_duplicate_label_modifier(self): m = Mock() runner = Runner() runner.add(m.job1, label='label1') mod = runner['label1'] mod.add(m.job2, label='label2') with ShouldRaise(ValueError( "'label1' already points to "+repr(m.job1)+" requires() " "returns_result_type() <-- label1" )): mod.add(m.job3, label='label1') verify(runner, (m.job1, {'label1'}), (m.job2, {'label2'}), )
def test_runner_add_label(self): m = Mock() runner = Runner() runner.add(m.job1) runner.add_label('label') runner.add(m.job3) runner['label'].add(m.job2) verify(runner, (m.job1, set()), (m.job2, {'label'}), (m.job3, set())) cloned = runner.clone(added_using='label') verify( cloned, (m.job2, {'label'}), )
def test_item_multiple(self): class MyDict(dict): pass m = Mock() def job1(): m.job1() obj = MyDict() obj['the_thing'] = dict(other_thing=m.the_thing) return obj def job2(obj): m.job2(obj) runner = Runner() runner.add(job1) runner.add(job2, requires(item(MyDict, 'the_thing', 'other_thing'))) runner() compare([ call.job1(), call.job2(m.the_thing), ], m.mock_calls)
def test_nested(self): class T(object): foo = dict(baz='bar') m = Mock() def job1(): m.job1() return T() def job2(obj): m.job2(obj) runner = Runner() runner.add(job1) runner.add(job2, requires(item(attr(T, 'foo'), 'baz'))) runner() compare([ call.job1(), call.job2('bar'), ], m.mock_calls)
def test_clone_between(self): m = Mock() runner1 = Runner() runner1.add(m.f1, label='first') runner1.add(m.f2, label='second') runner1.add(m.f3, label='third') runner1.add(m.f4, label='fourth') runner2 = runner1.clone(start_label='first', end_label='fourth') verify(runner2, (m.f2, {'second'}), (m.f3, {'third'}), )
def test_missing_from_context_with_chain(self): class T(object): pass def job1(): pass def job2(): pass @requires(T) def job3(arg): pass # pragma: nocover def job4(): pass def job5(): pass runner = Runner() runner.add(job1, label='1') runner.add(job2) runner.add(job3) runner.add(job4, label='4') runner.add(job5, requires('foo', bar='baz'), returns('bob')) with ShouldRaise(ContextError) as s: runner() text = '\n'.join(( '', '', 'Already called:', repr(job1) + ' requires() returns_result_type() <-- 1', repr(job2) + ' requires() returns_result_type()', '', 'While calling: ' + repr(job3) + ' requires(T) returns_result_type()', 'with <Context: {}>:', '', 'No ' + repr(T) + ' in context', '', 'Still to call:', repr(job4) + ' requires() returns_result_type() <-- 4', repr(job5) + " requires('foo', bar='baz') returns('bob')", )) compare(text, repr(s.raised)) compare(text, str(s.raised))
def test_runner_add_label(self): m = Mock() runner = Runner() runner.add(m.job1) runner.add_label('label') runner.add(m.job3) runner['label'].add(m.job2) verify( runner, (m.job1, set()), (m.job2, {'label'}), (m.job3, set()) ) cloned = runner.clone(added_using='label') verify( cloned, (m.job2, {'label'}), )
def test_modifier_add_with_label(self): def job1(): pass def job2(): pass runner = Runner() mod = runner.add(job1) mod.add_label('1') runner['1'].add(job2, label='2') verify(runner, (job1, {'1'}), (job2, {'2'}))
def test_simple(self): m = Mock() def job(): m.job() runner = Runner() point = runner.add(job).callpoint compare(job, point.obj) compare(runner.start, point) compare(runner.end, point) runner() compare([call.job()], m.mock_calls) verify(runner, (job, set()))
def test_clone_end_label(self): m = Mock() runner1 = Runner() runner1.add(m.f1, label='first') runner1.add(m.f2, label='second') runner1.add(m.f3, label='third') runner2 = runner1.clone(end_label='third') verify(runner2, (m.f1, {'first'}), (m.f2, {'second'}), )
def test_clone_start_label_include(self): m = Mock() runner1 = Runner() runner1.add(m.f1, label='first') runner1.add(m.f2, label='second') runner1.add(m.f3, label='third') runner2 = runner1.clone(start_label='second', include_start=True) verify(runner2, (m.f2, {'second'}), (m.f3, {'third'}), )
def test_modifier_moves_only_explicit_label(self): def job1(): pass def job2(): pass runner = Runner() mod = runner.add(job1) mod.add_label('1') mod.add_label('2') verify(runner, (job1, {'1', '2'})) runner['2'].add(job2) verify(runner, (job1, {'1'}), (job2, {'2'}))
def test_simple(self): m = Mock() def job(): m.job() runner = Runner() point = runner.add(job).callpoint compare(job, point.obj) compare(runner.start, point) compare(runner.end, point) runner() compare([ call.job() ], m.mock_calls) verify(runner, (job, set()))
def test_missing_from_context_with_chain(self): class T(object): pass def job1(): pass def job2(): pass @requires(T) def job3(arg): pass # pragma: nocover def job4(): pass def job5(): pass runner = Runner() runner.add(job1, label='1') runner.add(job2) runner.add(job3) runner.add(job4, label='4') runner.add(job5, requires('foo', bar='baz'), returns('bob')) with ShouldRaise(ContextError) as s: runner() text = '\n'.join(( '', '', 'Already called:', repr(job1)+' requires() returns_result_type() <-- 1', repr(job2)+' requires() returns_result_type()', '', 'While calling: '+repr(job3)+' requires(T) returns_result_type()', 'with <Context: {}>:', '', 'No '+repr(T)+' in context', '', 'Still to call:', repr(job4)+' requires() returns_result_type() <-- 4', repr(job5)+" requires('foo', bar='baz') returns('bob')", )) compare(text, repr(s.raised)) compare(text, str(s.raised))
def test_imperative(self): m = Mock() class T1(object): pass class T2(object): pass t1 = T1() t2 = T2() def job1(): m.job1() return t1 def job2(obj): m.job2(obj) return t2 def job3(t2_): m.job3(t2_) # imperative config trumps declarative @requires(T1) def job4(t2_): m.job4(t2_) runner = Runner() runner.add(job1) runner.add(job2, requires(T1)) runner.add(job3, requires(t2_=T2)) runner.add(job4, requires(T2)) runner() compare([ call.job1(), call.job2(t1), call.job3(t2), call.job4(t2), ], m.mock_calls)
def test_clone_added_using(self): runner1 = Runner() m = Mock() runner1.add(m.f1) runner1.add(m.f2, label='the_label') runner1.add(m.f3) runner1['the_label'].add(m.f6) runner1['the_label'].add(m.f7) runner2 = runner1.clone(added_using='the_label') verify(runner2, (m.f6, set()), (m.f7, {'the_label'}), )
def test_add_with_label(self): def job1(): pass def job2(): pass runner = Runner() point1 = runner.add(job1, label='1').callpoint point2 = runner.add(job2, label='2').callpoint compare(point1.obj, job1) compare(point2.obj, job2) compare(runner['1'].callpoint, point1) compare(runner['2'].callpoint, point2) compare({'1'}, point1.labels) compare({'2'}, point2.labels) verify(runner, (job1, {'1'}), (job2, {'2'}))
def test_repr(self): class T1: pass class T2: pass m = Mock() runner = Runner() runner.add(m.job1, label='label1') runner.add(m.job2, requires('foo', T1), returns(T2), label='label2') runner.add(m.job3) compare('\n'.join(( '<Runner>', ' '+repr(m.job1)+' requires() returns_result_type() <-- label1', ' '+repr(m.job2)+" requires('foo', T1) returns(T2) <-- label2", ' '+repr(m.job3)+' requires() returns_result_type()', '</Runner>' )), repr(runner))
def test_clone(self): m = Mock() class T1(object): pass class T2(object): pass def f1(): m.f1() def n1(): m.n1() return T1(), T2() def l1(): m.l1() def t1(obj): m.t1() def t2(obj): m.t2() # original runner1 = Runner() runner1.add(f1, label='first') runner1.add(n1, returns=returns(T1, T2), label='normal') runner1.add(l1, label='last') runner1.add(t1, requires(T1)) runner1.add(t2, requires(T2)) # now clone and add bits def f2(): m.f2() def n2(): m.n2() def l2(): m.l2() def tn(obj): m.tn() runner2 = runner1.clone() runner2['first'].add(f2) runner2['normal'].add(n2) runner2['last'].add(l2) # make sure types stay in order runner2.add(tn, requires(T2)) # now run both, and make sure we only get what we should runner1() verify(runner1, (f1, {'first'}), (n1, {'normal'}), (l1, {'last'}), (t1, set()), (t2, set()), ) compare([ call.f1(), call.n1(), call.l1(), call.t1(), call.t2(), ], m.mock_calls) m.reset_mock() runner2() verify(runner2, (f1, set()), (f2, {'first'}), (n1, set()), (n2, {'normal'}), (l1, set()), (l2, {'last'}), (t1, set()), (t2, set()), (tn, set()), ) compare([ call.f1(), call.f2(), call.n1(), call.n2(), call.l1(), call.l2(), call.t1(), call.t2(), call.tn() ], m.mock_calls)