1from nose.tools import raises
2from tg._compat import im_self
3from tg.configuration.milestones import _ConfigMilestoneTracker, config_ready
4from tg.configuration.utils import GlobalConfigurable, TGConfigError
5
6
7class Action:
8    called = 0
9    def __call__(self):
10        self.called += 1
11
12
13class TestMilestones(object):
14    def setup(self):
15        self.milestone = _ConfigMilestoneTracker('test_milestone')
16
17    def test_multiple_registration(self):
18        a = Action()
19        self.milestone.register(a)
20        self.milestone.register(a)
21        self.milestone.register(a)
22
23        self.milestone.reach()
24        assert a.called == 1
25
26    def test_register_after_reach(self):
27        a = Action()
28
29        self.milestone.reach()
30        self.milestone.register(a)
31        assert a.called == 1
32
33    def test_call_all(self):
34        a = Action()
35        a2 = Action()
36        a3 = Action()
37
38        self.milestone.register(a)
39        self.milestone.register(a2)
40        self.milestone.register(a3)
41
42        self.milestone.reach()
43        assert a.called == a2.called == a3.called == 1
44
45    def test_register_func_unique(self):
46        called = []
47        def f():
48            called.append(True)
49
50        self.milestone.register(f)
51        self.milestone.register(f)
52
53        self.milestone.reach()
54        assert len(called) == 1
55
56
57class TemporaryGlobalConfigurable(GlobalConfigurable):
58    pass
59
60class TestGlobalConfigurable(object):
61    def setup(self):
62        config_ready._reset()
63
64    def teardown(self):
65        for action in config_ready._keep_on_reset[:]:
66            default_object = im_self(action)
67            if default_object and isinstance(default_object, TemporaryGlobalConfigurable):
68                config_ready._keep_on_reset.remove(action)
69
70        config_ready._reset()
71
72    @raises(NotImplementedError)
73    def test_requires_configure_implementation(self):
74        class NoConfig(TemporaryGlobalConfigurable):
75            CONFIG_NAMESPACE = 'fake.'
76
77        default_object = NoConfig.create_global()
78        config_ready.reach()
79
80    @raises(TGConfigError)
81    def test_requires_namespace(self):
82        class NoNameSpace(TemporaryGlobalConfigurable):
83            def configure(self, **options):
84                return options
85
86        default_object = NoNameSpace.create_global()
87        config_ready.reach()
88
89    def test_gets_configured_on_config_ready(self):
90        class Configurable(TemporaryGlobalConfigurable):
91            CONFIG_NAMESPACE = 'fake.'
92            _CONFIGURED = []
93
94            def configure(self, **options):
95                self._CONFIGURED.append(True)
96
97        default_object = Configurable.create_global()
98        config_ready.reach()
99
100        assert len(Configurable._CONFIGURED) == 1
101
102    def test_keeps_on_milestone_reset(self):
103        class Configurable(TemporaryGlobalConfigurable):
104            CONFIG_NAMESPACE = 'fake.'
105            _CONFIGURED = []
106
107            def configure(self, **options):
108                self._CONFIGURED.append(True)
109
110        default_object = Configurable.create_global()
111        config_ready.reach()
112
113        config_ready._reset()
114        config_ready.reach()
115
116        assert len(Configurable._CONFIGURED) == 2