1 |
# Copyright (c) 2002 by Intevation GmbH |
2 |
# Authors: |
3 |
# Bernhard Herzog <[email protected]> |
4 |
# |
5 |
# This program is free software under the GPL (>=v2) |
6 |
# Read the file COPYING coming with Thuban for details. |
7 |
|
8 |
""" |
9 |
Test the TitledObject and Modifiable |
10 |
""" |
11 |
|
12 |
__version__ = "$Revision$" |
13 |
# $Source$ |
14 |
# $Id$ |
15 |
|
16 |
import unittest |
17 |
|
18 |
import support |
19 |
support.initthuban() |
20 |
|
21 |
from Thuban.Model.base import TitledObject, Modifiable |
22 |
from Thuban.Model.messages import TITLE_CHANGED, CHANGED |
23 |
from Thuban.Lib.connector import Publisher |
24 |
|
25 |
SOMETHING_ELSE = "SOMETHING_ELSE" |
26 |
|
27 |
class SomeTitledObject(TitledObject, Publisher): |
28 |
|
29 |
"""TitledObject for test purposes. |
30 |
|
31 |
TitledObject is not used directly. It's a mixin to be used together |
32 |
with Publisher. |
33 |
""" |
34 |
|
35 |
class SomeModifiable(Modifiable): |
36 |
|
37 |
"""Modifiable for test purposes. |
38 |
|
39 |
Modifiable is intended to be used as a base class for classes that |
40 |
need to inform other classes when they change and that have to keep |
41 |
track of whether they have changed. Thus we use a derived class for |
42 |
testing that provides some methods that simulate modificatios. |
43 |
""" |
44 |
|
45 |
def do_something(self): |
46 |
"""Call self.changed without parameters""" |
47 |
self.changed() |
48 |
|
49 |
def do_something_else(self): |
50 |
"""Call self.changed with a message parameter""" |
51 |
self.changed(SOMETHING_ELSE) |
52 |
|
53 |
|
54 |
class SubscriberTest(unittest.TestCase, support.SubscriberMixin): |
55 |
|
56 |
"""Base class for test cases that use SubscriberMixin. |
57 |
|
58 |
Just provide the default implementations of setUp and tearDown. |
59 |
""" |
60 |
|
61 |
def setUp(self): |
62 |
"""Clear the list of received messages""" |
63 |
self.clear_messages() |
64 |
|
65 |
def tearDown(self): |
66 |
"""Clear the list of received messages""" |
67 |
self.clear_messages() |
68 |
|
69 |
|
70 |
class TestTitledObject(SubscriberTest): |
71 |
|
72 |
"""Test cases for TitledObject""" |
73 |
|
74 |
def test_titled_object(self): |
75 |
"""Test TitledObject""" |
76 |
titled = SomeTitledObject("Some Title") |
77 |
titled.Subscribe(TITLE_CHANGED, |
78 |
self.subscribe_with_params, TITLE_CHANGED) |
79 |
|
80 |
self.assertEquals(titled.Title(), "Some Title") |
81 |
|
82 |
titled.SetTitle("New Title") |
83 |
self.assertEquals(titled.Title(), "New Title") |
84 |
|
85 |
self.check_messages([(titled, TITLE_CHANGED)]) |
86 |
|
87 |
|
88 |
class TestModifiable(SubscriberTest): |
89 |
|
90 |
"""Test cases for Modifiable""" |
91 |
|
92 |
def setUp(self): |
93 |
"""Extend the inherited method to create a Modifiable instance. |
94 |
|
95 |
Bind the Modifiable instance (actually an instance of |
96 |
SomeModifiable) to self.modifiable and subscribe to its CHANGED |
97 |
and SOMETHING_ELSE channels. |
98 |
""" |
99 |
SubscriberTest.setUp(self) |
100 |
self.modifiable = SomeModifiable() |
101 |
self.modifiable.Subscribe(CHANGED, self.subscribe_with_params, CHANGED) |
102 |
self.modifiable.Subscribe(SOMETHING_ELSE, |
103 |
self.subscribe_with_params, SOMETHING_ELSE) |
104 |
|
105 |
def tearDown(self): |
106 |
"""Extend the inherited method to explicitly destroy self.modifiable. |
107 |
""" |
108 |
self.modifiable.Destroy() |
109 |
SubscriberTest.tearDown(self) |
110 |
|
111 |
def test_initial_state(self): |
112 |
"""Test Modifiable initial state""" |
113 |
# initially a modifiable is unmodified |
114 |
self.failIf(self.modifiable.WasModified()) |
115 |
# this test should not have resulted in any messages |
116 |
self.check_messages([]) |
117 |
|
118 |
def test_silent_change(self): |
119 |
"""Test Modifiable method which doesn't issue messages""" |
120 |
self.modifiable.do_something() |
121 |
# Now it should be modified and we should not have received any |
122 |
# message |
123 |
self.assert_(self.modifiable.WasModified()) |
124 |
self.check_messages([]) |
125 |
|
126 |
def test_unset_modified(self): |
127 |
"""Test Modifiable.UnsetModified. |
128 |
|
129 |
Test whether the UnsetModified does in fact clear the modified |
130 |
flag and whether it issues a CHANGED message if it changes the |
131 |
modified flag from true to false. |
132 |
""" |
133 |
# We start with an unmodified object, so when we call |
134 |
# UnsetModified now it shouldn't result in any message. |
135 |
self.modifiable.UnsetModified() |
136 |
self.check_messages([]) |
137 |
self.failIf(self.modifiable.WasModified()) |
138 |
|
139 |
# Call a method that modifies the object silently. |
140 |
self.modifiable.do_something() |
141 |
self.check_messages([]) |
142 |
self.assert_(self.modifiable.WasModified()) |
143 |
|
144 |
# when we now call UnsetModified it should result in a CHANGED |
145 |
# message |
146 |
self.modifiable.UnsetModified() |
147 |
self.check_messages([(CHANGED,)]) |
148 |
self.failIf(self.modifiable.WasModified()) |
149 |
|
150 |
def test_issuing_change(self): |
151 |
"""Test Modifiable method that issues messages""" |
152 |
self.modifiable.do_something_else() |
153 |
# Now it should be modified and we should have received a |
154 |
# CHANGED message |
155 |
self.check_messages([(SOMETHING_ELSE,)]) |
156 |
self.assert_(self.modifiable.WasModified()) |
157 |
|
158 |
|
159 |
|
160 |
if __name__ == "__main__": |
161 |
unittest.main() |