예제 #1
0
class TestBase(unittest2.TestCase):

    container = fixture(Container, True)
    subclass_arguments = fixture(MyArguments, True)
    subclass_str_arg = fixture(MyArguments, Mock(prop=45))

    def test_applies_is_false_if_compatible_type_is_none(self):
        eq_(self.container.COMPATIBLE_TYPE, None)
        eq_(self.container.applies, False)

    def applies_is_true_if_input_type_is_compatible_type(self):
        self.container.COMPATIBLE_TYPE = int
        ok_(type(self.container.input) is not int)

        self.assertFalse(self.container.applies)
        self.container.input = 9
        self.assertTrue(self.container.applies)

    def test_argument_variables_defaults_to_nothing(self):
        eq_(self.container.arguments, {})

    def test_variables_only_returns_argument_objects(self):
        eq_(
            MyArguments.arguments,
            dict(variable1=MyArguments.variable1,
                 opposite_variable1=MyArguments.opposite_variable1,
                 str_variable=MyArguments.str_variable))

    def test_arguments_work(self):
        ok_(self.subclass_arguments.variable1)

    def test_can_use_string_as_argument(self):
        eq_(self.subclass_str_arg.str_variable, 45)

    def test_str_is_argument_container_plus_argument_name(self):
        eq_(str(MyArguments.variable1), 'MyArguments.variable1')

    def test_owner_is_class_its_in(self):
        eq_(MyArguments.variable1.owner, MyArguments)

    def test_name_is_name_inside_class(self):
        eq_(MyArguments.variable1.name, 'variable1')
        eq_(MyArguments.opposite_variable1.name, 'opposite_variable1')
예제 #2
0
class Dummy(object):

    outside = 'value from outside'

    @fixture
    def number(self):
        return 42

    @fixture
    def obj(self):
        return object()

    inline = fixture(int, 5)
    inline_func = fixture(lambda self: self.outside)
    inline_func_with_args = fixture(lambda *a, **k: (a, k), 1, 2, a=3)
    inline_from_method = fixture(Outer.meth)

    inline_from_method_with_arg_1 = fixture(Outer.reflective_meth, 1)
    inline_from_method_with_arg_2 = fixture(Outer.reflective_meth, 2)
예제 #3
0
class TestIntegration(Exam, unittest2.TestCase):

    class Callback(object):

        def __init__(self):
            self.register_calls = []
            self.unregister_calls = []
            self.update_calls = []

        def switch_added(self, switch):
            self.register_calls.append(switch)

        def switch_removed(self, switch):
            self.unregister_calls.append(switch)

        def switch_updated(self, switch):
            self.update_calls.append((switch, switch.changes))

    class inputs(object):

        def __init__(self, manager, *inputs):
            self.manager = manager
            self.manager.input(*inputs)

        def __enter__(self):
            return self

        def active(self, *args, **kwargs):
            return self.manager.active(*args, **kwargs)

        def __exit__(self, type, value, traceback):
            self.manager.flush()

    callback = fixture(Callback)

    @fixture
    def manager(self):
        return Manager(storage=dict())

    @before
    def build_objects(self):
        self.setup_inputs()
        self.setup_conditions()
        self.setup_switches()

    @after
    def reset_objects(self):
        signals.switch_registered.reset()
        signals.switch_unregistered.reset()
        signals.switch_updated.reset()

    def setup_inputs(self):
        self.jeff = User(deterministicstring('jeff'), 21)
        self.frank = User(deterministicstring('frank'), 10, location="Seattle")
        self.larry = User(deterministicstring('bill'), 70, location="Yakima", married=True)
        self.timmy = User(deterministicstring('timmy'), 12)
        self.steve = User(deterministicstring('timmy'), 19)

    def setup_conditions(self):
        self.age_65_and_up = Condition(UserArguments, 'age', MoreThanOrEqualTo(lower_limit=65))
        self.age_under_18 = Condition(UserArguments, 'age', LessThan(upper_limit=18))
        self.age_not_under_18 = Condition(UserArguments, 'age', LessThan(upper_limit=18), negative=True)
        self.age_21_plus = Condition(UserArguments, 'age', MoreThanOrEqualTo(lower_limit=21))
        self.age_between_13_and_18 = Condition(UserArguments, 'age', Between(lower_limit=13, upper_limit=18))

        self.in_sf = Condition(UserArguments, 'location', Equals(value='San Francisco'))
        self.has_location = Condition(UserArguments, 'location', Truthy())

        self.ten_percent = Condition(UserArguments, 'name', Percent(percentage=10))
        self.upper_50_percent = Condition(UserArguments, 'name', PercentRange(lower_limit=50, upper_limit=100))
        self.answer_to_life = Condition(IntegerArguments, 'value', Equals(value=42))

    def setup_switches(self):
        self.add_switch('can drink', condition=self.age_21_plus)
        self.add_switch('can drink in europe', condition=self.age_21_plus, state=Switch.states.GLOBAL)
        self.add_switch('can drink:answer to life', condition=self.answer_to_life)
        self.add_switch('can drink:wine', condition=self.in_sf, concent=True)
        self.add_switch('retired', condition=self.age_65_and_up)
        self.add_switch('can vote', condition=self.age_not_under_18)
        self.add_switch('teenager', condition=self.age_between_13_and_18)
        self.add_switch('SF resident', condition=self.in_sf)
        self.add_switch('teen or in SF', self.age_between_13_and_18, self.in_sf)
        self.add_switch('teen and in SF', self.age_between_13_and_18,
                        self.has_location, compounded=True)
        self.add_switch('10 percent', self.ten_percent)
        self.add_switch('Upper 50 percent', self.upper_50_percent)

    def add_switch(self, name, condition=None, *conditions, **kwargs):
        switch = Switch(name, compounded=kwargs.get('compounded', False))
        switch.state = kwargs.get('state', Switch.states.SELECTIVE)
        conditions = list(conditions)

        if condition:
            conditions.append(condition)

        [switch.conditions.append(c) for c in conditions]
        kwargs.get('manager', self.manager).register(switch)
        return switch

    def test_basic_switches_work_with_conditions(self):
        with self.inputs(self.manager, self.larry) as context:
            ok_(context.active('can drink') is True)
            ok_(context.active('can drink in europe') is True)
            ok_(context.active('can vote') is True)
            ok_(context.active('SF resident') is False)
            ok_(context.active('retired') is True)
            ok_(context.active('10 percent') is False)
            ok_(context.active('Upper 50 percent') is True)

        with self.inputs(self.manager, self.jeff) as context:
            ok_(context.active('can drink') is True)
            ok_(context.active('can drink in europe') is True)
            ok_(context.active('can vote') is True)
            ok_(context.active('SF resident') is True)
            ok_(context.active('teenager') is False)
            ok_(context.active('teen or in SF') is True)
            ok_(context.active('teen and in SF') is False)
            ok_(context.active('10 percent') is False)
            ok_(context.active('Upper 50 percent') is True)

        with self.inputs(self.manager, self.frank) as context:
            ok_(context.active('can drink') is False)
            ok_(context.active('can drink in europe') is True)
            ok_(context.active('can vote') is False)
            ok_(context.active('teenager') is False)
            ok_(context.active('10 percent') is False)
            ok_(context.active('Upper 50 percent') is True)

    def test_can_use_extra_inputs_to_active(self):
        with self.inputs(self.manager, self.frank) as context:
            ok_(context.active('can drink') is False)
            ok_(context.active('can drink', self.larry) is True)

        with self.inputs(self.manager, self.larry) as context:
            ok_(context.active('can drink') is True)
            ok_(context.active('can drink', self.frank, exclusive=True) is False)

    def test_switches_with_multiple_inputs(self):

        with self.inputs(self.manager, self.larry, self.jeff) as context:
            ok_(context.active('can drink') is True)
            ok_(context.active('can drink in europe') is True)
            ok_(context.active('SF resident') is True)
            ok_(context.active('teenager') is False)
            ok_(context.active('10 percent') is False)
            ok_(context.active('Upper 50 percent') is True)

        with self.inputs(self.manager, self.frank, self.jeff) as context:
            ok_(context.active('can drink') is True)
            ok_(context.active('can drink in europe') is True)
            ok_(context.active('SF resident') is True)
            ok_(context.active('teenager') is False)
            ok_(context.active('10 percent') is False)
            ok_(context.active('Upper 50 percent') is True)

    def test_switches_can_concent_top_parent_switch(self):
        with self.inputs(self.manager, self.jeff) as context:
            ok_(context.active('can drink') is True)
            ok_(context.active('can drink in europe') is True)
            ok_(context.active('SF resident') is True)
            ok_(context.active('can drink:wine') is True)
        with self.inputs(self.manager, self.timmy) as context:
            ok_(context.active('can drink') is False)
            ok_(context.active('can drink in europe') is True)
            ok_(context.active('SF resident') is True)
            ok_(context.active('can drink:wine') is False)

    def test_changing_parent_is_reflected_in_child_switch(self):
        with self.inputs(self.manager, self.jeff) as context:
            assert self.manager['can drink'].children
            ok_(context.active('can drink:wine') is True)

            parent = self.manager['can drink']
            parent.state = Switch.states.DISABLED
            parent.save()

            assert self.manager['can drink'].children
            ok_(context.active('can drink:wine') is False)

    def test_switches_can_be_deregistered_and_then_autocreated(self):
        with self.inputs(self.manager, self.jeff) as context:
            ok_(context.active('can drink') is True)

            context.manager.unregister('can drink')

            with assert_raises(ValueError):
                context.manager.active('can drink')

            context.manager.autocreate = True
            ok_(context.active('can drink') is False)

    def test_can_register_signals_and_get_notified(self):
        signals.switch_registered.connect(self.callback.switch_added)
        signals.switch_unregistered.connect(self.callback.switch_removed)
        signals.switch_updated.connect(self.callback.switch_updated)

        eq_(self.callback.register_calls, [])
        eq_(self.callback.unregister_calls, [])
        eq_(self.callback.update_calls, [])

        switch = Switch('foo')

        self.manager.register(switch)
        eq_(self.callback.register_calls, [switch])

        self.manager.unregister(switch.name)
        eq_(self.callback.unregister_calls, [switch])

        self.manager.register(switch)
        eq_(self.callback.register_calls, [switch, switch])

        switch.state = Switch.states.GLOBAL
        self.manager.update(switch)

        change = self.callback.update_calls[0]
        eq_(change[0], switch)
        changes = change[1]
        eq_(changes['state'], dict(current=Switch.states.GLOBAL, previous=Switch.states.DISABLED))

    def test_namespaes_keep_switches_isloated(self):
        germany = self.manager.namespaced('germany')
        usa = self.manager.namespaced('usa')

        self.add_switch('booze', condition=self.age_21_plus, manager=usa)
        self.add_switch('booze', condition=self.age_not_under_18, manager=germany)

        eq_(len(germany.switches), 1)
        eq_(len(usa.switches), 1)

        eq_(usa.switches[0].conditions, [self.age_21_plus])
        eq_(germany.switches[0].conditions, [self.age_not_under_18])

        with self.inputs(usa, self.jeff) as context:
            ok_(context.active('booze') is True)

        with self.inputs(usa, self.jeff, self.timmy) as context:
            ok_(context.active('booze') is True)  # Jeff is 21, so he counts
            ok_(context.active('booze', self.timmy, exclusive=True) is False)  # Timmy is 10

        with self.inputs(usa, self.timmy) as context:
            ok_(context.active('booze') is False)

        with self.inputs(usa, self.timmy, self.steve) as context:
            ok_(context.active('booze') is False)

        with self.inputs(germany, self.timmy) as context:
            ok_(context.active('booze') is False)  # 10 is still too young

        with self.inputs(germany, self.steve) as context:
            ok_(context.active('booze') is True)  # 19 is old enough!

        with self.inputs(germany, self.timmy, self.steve) as context:
            ok_(context.active('booze') is True)  # Cause steve is 19

        with self.inputs(germany, self.jeff, self.timmy) as context:
            ok_(context.active('booze') is True)  # Cause jeff is 21

        with self.inputs(germany, self.jeff) as context:
            ok_(context.active('booze', self.timmy, exclusive=True) is False)  # exclusive timmy is 10

    def test_namespace_switches_not_shared_with_parent(self):
        base = self.manager
        daughter = self.manager.namespaced('daughter')
        son = self.manager.namespaced('son')

        ok_(base.switches is not daughter.switches)
        ok_(base.switches is not son.switches)
        ok_(daughter.switches is not son.switches)

        daughter_switch = self.add_switch('daughter only', manager=daughter)
        son_switch = self.add_switch('son only', manager=son)

        eq_(daughter.switches, [daughter_switch])
        eq_(son.switches, [son_switch])

        ok_(daughter_switch not in base.switches)
        ok_(son_switch not in base.switches)

    def test_retrieved_switches_can_be_updated(self):
        switch = Switch('foo')
        self.manager.register(switch)

        self.assertEquals(self.manager.switch('foo').name, 'foo')

        switch.state = Switch.states.GLOBAL
        switch.save()

        self.assertEquals(
            self.manager.switch('foo').state,
            Switch.states.GLOBAL
        )

    def test_concent_with_different_arguments(self):
        # Test that a parent switch with a different argument type from the
        # child works.
        with self.inputs(self.manager, self.jeff, 42) as context:
            ok_(context.active('can drink:answer to life') is True)
        with self.inputs(self.manager, self.timmy, 42) as context:
            ok_(context.active('can drink:answer to life') is False)

        with self.inputs(self.manager, self.jeff, 77) as context:
            ok_(context.active('can drink:answer to life') is False)
        with self.inputs(self.manager, self.timmy, 77) as context:
            ok_(context.active('can drink:answer to life') is False)
예제 #4
0
class MockTest(TestCase):

    mock = fixture(Mock)

    @before
    def assert_mock_clean(self):
        self.mock.assert_not_called()

    def test_assert_called_asserts_mock_was_called(self):
        self.assertRaises(AssertionError, self.mock.assert_called)

        self.mock()
        self.mock.assert_called()

        self.mock.reset_mock()
        self.assertRaises(AssertionError, self.mock.assert_called)

    def test_assert_not_called_asserts_mock_was_not_called(self):
        self.mock()
        self.assertRaises(AssertionError, self.mock.assert_not_called)

        self.mock.reset_mock()
        self.mock.assert_not_called()

    def test_assert_not_called_with_asserts_not_called_with_args(self):
        self.mock(1, 2, three=4)
        self.mock.assert_called_with(1, 2, three=4)

        self.mock.assert_not_called_with(1, 2, four=5)
        self.mock.assert_not_called_with(1, three=5)
        self.mock.assert_not_called_with()

        with self.assertRaises(AssertionError):
            self.mock.assert_not_called_with(1, 2, three=4)

        self.mock('foo')
        self.mock.assert_not_called_with(1, 2, three=4)  # not the latest call

    def test_assert_not_called_once_with_asserts_one_call_with_args(self):
        self.mock.assert_not_called_once_with(1, 2, three=4)  # 0 times

        self.mock(1, 2, three=4)

        with self.assertRaises(AssertionError):
            self.mock.assert_not_called_once_with(1, 2, three=4)  # 1 time

        self.mock(1, 2, three=4)
        self.mock.assert_not_called_once_with(1, 2, three=4)  # 2 times

    def test_assert_not_any_call_asserts_never_called_with_args(self):
        self.mock.assert_not_any_call(1, 2, three=4)

        self.mock(1, 2, three=4)

        with self.assertRaises(AssertionError):
            self.mock.assert_not_any_call(1, 2, three=4)

        self.mock('foo')

        with self.assertRaises(AssertionError):
            # Even though it's not the latest, it was previously called with
            # these args
            self.mock.assert_not_any_call(1, 2, three=4)