~free.ekanayaka/storm/any-expr

129 by Gustavo Niemeyer
Added LGPL version 2.1 in the LICENSE file, and a standard
1
#
2
# Copyright (c) 2006, 2007 Canonical
3
#
4
# Written by Gustavo Niemeyer <gustavo@niemeyer.net>
5
#
6
# This file is part of Storm Object Relational Mapper.
7
#
8
# Storm is free software; you can redistribute it and/or modify
9
# it under the terms of the GNU Lesser General Public License as
10
# published by the Free Software Foundation; either version 2.1 of
11
# the License, or (at your option) any later version.
12
#
13
# Storm is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
# GNU Lesser General Public License for more details.
17
#
18
# You should have received a copy of the GNU Lesser General Public License
19
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
#
95.4.13 by James Henstridge
add TimeDeltaVariable
21
from datetime import datetime, date, time, timedelta
127 by Gustavo Niemeyer
Numeric variables (Bool, Int, and Float) will now raise a TypeError
22
from decimal import Decimal
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
23
import cPickle as pickle
290 by Thomas Hervé
Fix a leak in the C implementation of Variable.set: a port from the python
24
import gc
25
import weakref
289.3.1 by James Henstridge
Add a UUIDVariable type (will not function without Python >= 2.5).
26
try:
27
    import uuid
28
except ImportError:
29
    uuid = None
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
30
95.1.2 by Gustavo Niemeyer
- Renamed NotNoneError to NoneError.
31
from storm.exceptions import NoneError
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
32
from storm.variables import *
33
from storm.event import EventSystem
95.3.14 by Gustavo Niemeyer
Changed the meaning of plain strings for the expression compiler. Now
34
from storm.expr import Column, SQLToken
95.3.7 by Gustavo Niemeyer
- Minor changes in the way the SimpleProperty base works.
35
from storm.tz import tzutc, tzoffset
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
36
from storm import Undef
37
38
from tests.helper import TestHelper
39
40
95.1.8 by Gustavo Niemeyer
- Event system now has owner as a weak reference, to prevent the
41
class Marker(object):
42
    pass
43
44
marker = Marker()
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
45
46
47
class CustomVariable(Variable):
48
49
    def __init__(self, *args, **kwargs):
50
        self.gets = []
51
        self.sets = []
52
        Variable.__init__(self, *args, **kwargs)
53
142.3.1 by Christopher Armstrong
drop the underscores from the _parse_set and _parse_get methods,
54
    def parse_get(self, variable, to_db):
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
55
        self.gets.append((variable, to_db))
56
        return "g", variable
57
142.3.1 by Christopher Armstrong
drop the underscores from the _parse_set and _parse_get methods,
58
    def parse_set(self, variable, from_db):
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
59
        self.sets.append((variable, from_db))
60
        return "s", variable
61
62
63
class VariableTest(TestHelper):
64
65
    def test_constructor_value(self):
66
        variable = CustomVariable(marker)
67
        self.assertEquals(variable.sets, [(marker, False)])
68
69
    def test_constructor_value_from_db(self):
70
        variable = CustomVariable(marker, from_db=True)
71
        self.assertEquals(variable.sets, [(marker, True)])
72
73
    def test_constructor_value_factory(self):
74
        variable = CustomVariable(value_factory=lambda:marker)
75
        self.assertEquals(variable.sets, [(marker, False)])
76
77
    def test_constructor_value_factory_from_db(self):
78
        variable = CustomVariable(value_factory=lambda:marker, from_db=True)
79
        self.assertEquals(variable.sets, [(marker, True)])
80
81
    def test_constructor_column(self):
82
        variable = CustomVariable(column=marker)
83
        self.assertEquals(variable.column, marker)
84
85
    def test_constructor_event(self):
86
        variable = CustomVariable(event=marker)
87
        self.assertEquals(variable.event, marker)
88
89
    def test_get_default(self):
90
        variable = CustomVariable()
91
        self.assertEquals(variable.get(default=marker), marker)
92
93
    def test_set(self):
94
        variable = CustomVariable()
95
        variable.set(marker)
96
        self.assertEquals(variable.sets, [(marker, False)])
97
        variable.set(marker, from_db=True)
98
        self.assertEquals(variable.sets, [(marker, False), (marker, True)])
99
290 by Thomas Hervé
Fix a leak in the C implementation of Variable.set: a port from the python
100
    def test_set_leak(self):
101
        """When a variable is checkpointed, the value must not leak."""
102
        variable = Variable()
103
        m = Marker()
104
        m_ref = weakref.ref(m)
105
        variable.set(m)
106
        variable.checkpoint()
107
        variable.set(LazyValue())
108
        del m
109
        gc.collect()
110
        self.assertIdentical(m_ref(), None)
111
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
112
    def test_get(self):
113
        variable = CustomVariable()
114
        variable.set(marker)
115
        self.assertEquals(variable.get(), ("g", ("s", marker)))
116
        self.assertEquals(variable.gets, [(("s", marker), False)])
117
118
        variable = CustomVariable()
119
        variable.set(marker)
120
        self.assertEquals(variable.get(to_db=True), ("g", ("s", marker)))
121
        self.assertEquals(variable.gets, [(("s", marker), True)])
122
123
    def test_is_defined(self):
124
        variable = CustomVariable()
125
        self.assertFalse(variable.is_defined())
126
        variable.set(marker)
127
        self.assertTrue(variable.is_defined())
128
129
    def test_set_get_none(self):
130
        variable = CustomVariable()
131
        variable.set(None)
132
        self.assertEquals(variable.get(marker), None)
133
        self.assertEquals(variable.sets, [])
134
        self.assertEquals(variable.gets, [])
135
95.1.2 by Gustavo Niemeyer
- Renamed NotNoneError to NoneError.
136
    def test_set_none_with_allow_none(self):
137
        variable = CustomVariable(allow_none=False)
138
        self.assertRaises(NoneError, variable.set, None)
139
140
    def test_set_none_with_allow_none_and_column(self):
141
        column = Column("column_name")
142
        variable = CustomVariable(allow_none=False, column=column)
143
        try:
144
            variable.set(None)
145
        except NoneError, e:
146
            pass
147
        self.assertTrue("column_name" in str(e))
148
149
    def test_set_none_with_allow_none_and_column_with_table(self):
95.3.14 by Gustavo Niemeyer
Changed the meaning of plain strings for the expression compiler. Now
150
        column = Column("column_name", SQLToken("table_name"))
95.1.2 by Gustavo Niemeyer
- Renamed NotNoneError to NoneError.
151
        variable = CustomVariable(allow_none=False, column=column)
152
        try:
153
            variable.set(None)
154
        except NoneError, e:
155
            pass
95.1.3 by Gustavo Niemeyer
NoneError message had column_name and table_name inverted.
156
        self.assertTrue("table_name.column_name" in str(e))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
157
221.1.1 by Gustavo Niemeyer
A validator function may now be passed to any property, and it will be
158
    def test_set_with_validator(self):
159
        args = []
160
        def validator(obj, attr, value):
161
            args.append((obj, attr, value))
162
            return value
163
        variable = CustomVariable(validator=validator)
164
        variable.set(3)
165
        self.assertEquals(args, [(None, None, 3)])
166
167
    def test_set_with_validator_and_validator_arguments(self):
168
        args = []
169
        def validator(obj, attr, value):
170
            args.append((obj, attr, value))
171
            return value
172
        variable = CustomVariable(validator=validator,
173
                                  validator_object_factory=lambda: 1,
174
                                  validator_attribute=2)
175
        variable.set(3)
176
        self.assertEquals(args, [(1, 2, 3)])
177
178
    def test_set_with_validator_raising_error(self):
179
        args = []
180
        def validator(obj, attr, value):
181
            args.append((obj, attr, value))
182
            raise ZeroDivisionError()
183
        variable = CustomVariable(validator=validator)
184
        self.assertRaises(ZeroDivisionError, variable.set, marker)
185
        self.assertEquals(args, [(None, None, marker)])
186
        self.assertEquals(variable.get(), None)
187
188
    def test_set_with_validator_changing_value(self):
189
        args = []
190
        def validator(obj, attr, value):
191
            args.append((obj, attr, value))
192
            return 42
193
        variable = CustomVariable(validator=validator)
194
        variable.set(marker)
195
        self.assertEquals(args, [(None, None, marker)])
196
        self.assertEquals(variable.get(), ('g', ('s', 42)))
197
198
    def test_set_from_db_wont_call_validator(self):
199
        args = []
200
        def validator(obj, attr, value):
201
            args.append((obj, attr, value))
202
            return 42
203
        variable = CustomVariable(validator=validator)
204
        variable.set(marker, from_db=True)
205
        self.assertEquals(args, [])
206
        self.assertEquals(variable.get(), ('g', ('s', marker)))
207
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
208
    def test_event_changed(self):
209
        event = EventSystem(marker)
210
211
        changed_values = []
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
212
        def changed(owner, variable, old_value, new_value, fromdb):
213
            changed_values.append((owner, variable,
214
                                   old_value, new_value, fromdb))
268.1.3 by Thomas Hervé
Whitespace
215
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
216
        event.hook("changed", changed)
217
218
        variable = CustomVariable(event=event)
219
        variable.set("value1")
220
        variable.set("value2")
221
        variable.set("value3", from_db=True)
222
        variable.set(None, from_db=True)
223
        variable.set("value4")
224
        variable.delete()
225
        variable.delete()
226
227
        self.assertEquals(changed_values[0],
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
228
          (marker, variable, Undef, "value1", False))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
229
        self.assertEquals(changed_values[1],
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
230
          (marker, variable, ("g", ("s", "value1")), "value2", False))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
231
        self.assertEquals(changed_values[2],
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
232
          (marker, variable, ("g", ("s", "value2")), ("g", ("s", "value3")),
233
           True))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
234
        self.assertEquals(changed_values[3],
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
235
          (marker, variable, ("g", ("s", "value3")), None, True))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
236
        self.assertEquals(changed_values[4],
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
237
          (marker, variable, None, "value4", False))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
238
        self.assertEquals(changed_values[5],
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
239
          (marker, variable, ("g", ("s", "value4")), Undef, False))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
240
        self.assertEquals(len(changed_values), 6)
241
242
    def test_get_state(self):
243
        variable = CustomVariable(marker)
85 by Gustavo Niemeyer
- Greatly improved the autoreload feature support.
244
        self.assertEquals(variable.get_state(), (Undef, ("s", marker)))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
245
246
    def test_set_state(self):
85 by Gustavo Niemeyer
- Greatly improved the autoreload feature support.
247
        lazy_value = object()
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
248
        variable = CustomVariable()
85 by Gustavo Niemeyer
- Greatly improved the autoreload feature support.
249
        variable.set_state((lazy_value, marker))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
250
        self.assertEquals(variable.get(), ("g", marker))
85 by Gustavo Niemeyer
- Greatly improved the autoreload feature support.
251
        self.assertEquals(variable.get_lazy(), lazy_value)
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
252
253
    def test_checkpoint_and_has_changed(self):
254
        variable = CustomVariable()
85 by Gustavo Niemeyer
- Greatly improved the autoreload feature support.
255
        self.assertTrue(variable.has_changed())
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
256
        variable.set(marker)
257
        self.assertTrue(variable.has_changed())
95.3.71 by Gustavo Niemeyer
As discussed with James Henstrigde, committing and rolling back
258
        variable.checkpoint()
259
        self.assertFalse(variable.has_changed())
260
        variable.set(marker)
261
        self.assertFalse(variable.has_changed())
262
        variable.set((marker, marker))
263
        self.assertTrue(variable.has_changed())
264
        variable.checkpoint()
265
        self.assertFalse(variable.has_changed())
266
        variable.set((marker, marker))
267
        self.assertFalse(variable.has_changed())
268
        variable.set(marker)
269
        self.assertTrue(variable.has_changed())
270
        variable.set((marker, marker))
271
        self.assertFalse(variable.has_changed())
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
272
273
    def test_copy(self):
274
        variable = CustomVariable()
275
        variable.set(marker)
276
        variable_copy = variable.copy()
269.1.4 by Thomas Hervé
Fix other tests relying on variables with same value being equal.
277
        variable_copy.gets = []
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
278
        self.assertTrue(variable is not variable_copy)
269.1.4 by Thomas Hervé
Fix other tests relying on variables with same value being equal.
279
        self.assertVariablesEqual([variable], [variable_copy])
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
280
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
281
    def test_lazy_value_setting(self):
282
        variable = CustomVariable()
81.1.18 by Gustavo Niemeyer
- LazyValues don't need a constructor.
283
        variable.set(LazyValue())
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
284
        self.assertEquals(variable.sets, [])
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
285
        self.assertTrue(variable.has_changed())
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
286
287
    def test_lazy_value_getting(self):
288
        variable = CustomVariable()
81.1.18 by Gustavo Niemeyer
- LazyValues don't need a constructor.
289
        variable.set(LazyValue())
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
290
        self.assertEquals(variable.get(marker), marker)
291
        variable.set(1)
81.1.18 by Gustavo Niemeyer
- LazyValues don't need a constructor.
292
        variable.set(LazyValue())
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
293
        self.assertEquals(variable.get(marker), marker)
81.1.19 by Gustavo Niemeyer
Implemented Variable.get_lazy().
294
        self.assertFalse(variable.is_defined())
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
295
296
    def test_lazy_value_resolving(self):
297
        event = EventSystem(marker)
298
299
        resolve_values = []
300
        def resolve(owner, variable, value):
301
            resolve_values.append((owner, variable, value))
302
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
303
304
81.1.18 by Gustavo Niemeyer
- LazyValues don't need a constructor.
305
        lazy_value = LazyValue()
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
306
        variable = CustomVariable(lazy_value, event=event)
307
308
        event.hook("resolve-lazy-value", resolve)
309
310
        variable.get()
311
312
        self.assertEquals(resolve_values,
313
                          [(marker, variable, lazy_value)])
314
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
315
    def test_lazy_value_changed_event(self):
316
        event = EventSystem(marker)
317
318
        changed_values = []
319
        def changed(owner, variable, old_value, new_value, fromdb):
320
            changed_values.append((owner, variable,
321
                                   old_value, new_value, fromdb))
268.1.3 by Thomas Hervé
Whitespace
322
81.1.20 by Gustavo Niemeyer
- Implemented support for expressions as lazy values in the store!
323
        event.hook("changed", changed)
324
325
        variable = CustomVariable(event=event)
326
327
        lazy_value = LazyValue()
328
329
        variable.set(lazy_value)
330
331
        self.assertEquals(changed_values,
332
                          [(marker, variable, Undef, lazy_value, False)])
333
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
334
    def test_lazy_value_setting_on_resolving(self):
335
        event = EventSystem(marker)
336
337
        def resolve(owner, variable, value):
338
            variable.set(marker)
339
340
        event.hook("resolve-lazy-value", resolve)
341
81.1.18 by Gustavo Niemeyer
- LazyValues don't need a constructor.
342
        lazy_value = LazyValue()
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
343
        variable = CustomVariable(lazy_value, event=event)
344
345
        self.assertEquals(variable.get(), ("g", ("s", marker)))
346
347
    def test_lazy_value_reset_after_changed(self):
348
        event = EventSystem(marker)
349
350
        resolve_called = []
351
        def resolve(owner, variable, value):
352
            resolve_called.append(True)
353
354
        event.hook("resolve-lazy-value", resolve)
355
356
        variable = CustomVariable(event=event)
357
81.1.18 by Gustavo Niemeyer
- LazyValues don't need a constructor.
358
        variable.set(LazyValue())
81.1.17 by Gustavo Niemeyer
Implemented lazy value support in variables.
359
        variable.set(1)
360
        self.assertEquals(variable.get(), ("g", ("s", 1)))
361
        self.assertEquals(resolve_called, [])
362
81.1.19 by Gustavo Niemeyer
Implemented Variable.get_lazy().
363
    def test_get_lazy_value(self):
364
        lazy_value = LazyValue()
365
        variable = CustomVariable()
366
        self.assertEquals(variable.get_lazy(), None)
367
        self.assertEquals(variable.get_lazy(marker), marker)
368
        variable.set(lazy_value)
369
        self.assertEquals(variable.get_lazy(marker), lazy_value)
370
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
371
372
class BoolVariableTest(TestHelper):
373
374
    def test_set_get(self):
375
        variable = BoolVariable()
376
        variable.set(1)
377
        self.assertTrue(variable.get() is True)
378
        variable.set(0)
379
        self.assertTrue(variable.get() is False)
127 by Gustavo Niemeyer
Numeric variables (Bool, Int, and Float) will now raise a TypeError
380
        variable.set(1.1)
381
        self.assertTrue(variable.get() is True)
382
        variable.set(0.0)
383
        self.assertTrue(variable.get() is False)
384
        variable.set(Decimal(1))
385
        self.assertTrue(variable.get() is True)
386
        variable.set(Decimal(0))
387
        self.assertTrue(variable.get() is False)
388
        self.assertRaises(TypeError, variable.set, "string")
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
389
390
391
class IntVariableTest(TestHelper):
392
393
    def test_set_get(self):
394
        variable = IntVariable()
127 by Gustavo Niemeyer
Numeric variables (Bool, Int, and Float) will now raise a TypeError
395
        variable.set(1)
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
396
        self.assertEquals(variable.get(), 1)
397
        variable.set(1.1)
398
        self.assertEquals(variable.get(), 1)
127 by Gustavo Niemeyer
Numeric variables (Bool, Int, and Float) will now raise a TypeError
399
        variable.set(Decimal(2))
400
        self.assertEquals(variable.get(), 2)
401
        self.assertRaises(TypeError, variable.set, "1")
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
402
403
404
class FloatVariableTest(TestHelper):
405
406
    def test_set_get(self):
407
        variable = FloatVariable()
408
        variable.set(1.1)
409
        self.assertEquals(variable.get(), 1.1)
127 by Gustavo Niemeyer
Numeric variables (Bool, Int, and Float) will now raise a TypeError
410
        variable.set(1)
411
        self.assertEquals(variable.get(), 1)
412
        self.assertEquals(type(variable.get()), float)
413
        variable.set(Decimal("1.1"))
414
        self.assertEquals(variable.get(), 1.1)
415
        self.assertRaises(TypeError, variable.set, "1")
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
416
417
144.2.1 by jdahlin at com
Add NumericVariable and Numeric property mapping to python's Decimal type
418
class DecimalVariableTest(TestHelper):
419
420
    def test_set_get(self):
144.2.3 by Gustavo Niemeyer
- Renamed NumericVariable to DecimalVariable, and the property to Decimal,
421
        variable = DecimalVariable()
144.2.1 by jdahlin at com
Add NumericVariable and Numeric property mapping to python's Decimal type
422
        variable.set(Decimal("1.1"))
423
        self.assertEquals(variable.get(), Decimal("1.1"))
424
        variable.set(1)
425
        self.assertEquals(variable.get(), 1)
426
        self.assertEquals(type(variable.get()), Decimal)
427
        variable.set(Decimal("1.1"))
428
        self.assertEquals(variable.get(), Decimal("1.1"))
429
        self.assertRaises(TypeError, variable.set, "1")
430
        self.assertRaises(TypeError, variable.set, 1.1)
431
144.2.4 by Gustavo Niemeyer
- Added tests in the store and in the database to ensure that
432
    def test_get_set_from_database(self):
433
        """Strings used to/from the database."""
144.2.3 by Gustavo Niemeyer
- Renamed NumericVariable to DecimalVariable, and the property to Decimal,
434
        variable = DecimalVariable()
435
        variable.set("1.1", from_db=True)
436
        self.assertEquals(variable.get(), Decimal("1.1"))
144.2.4 by Gustavo Niemeyer
- Added tests in the store and in the database to ensure that
437
        self.assertEquals(variable.get(to_db=True), "1.1")
144.2.3 by Gustavo Niemeyer
- Renamed NumericVariable to DecimalVariable, and the property to Decimal,
438
144.2.1 by jdahlin at com
Add NumericVariable and Numeric property mapping to python's Decimal type
439
147 by Gustavo Niemeyer
- The Chars type is now RawStr. Chars will stay as an alias for
440
class RawStrVariableTest(TestHelper):
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
441
442
    def test_set_get(self):
147 by Gustavo Niemeyer
- The Chars type is now RawStr. Chars will stay as an alias for
443
        variable = RawStrVariable()
125 by Gustavo Niemeyer
- Now Unicode and Bin will blow up if the values set are not
444
        variable.set("str")
445
        self.assertEquals(variable.get(), "str")
446
        variable.set(buffer("buffer"))
447
        self.assertEquals(variable.get(), "buffer")
448
        self.assertRaises(TypeError, variable.set, u"unicode")
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
449
450
451
class UnicodeVariableTest(TestHelper):
452
453
    def test_set_get(self):
454
        variable = UnicodeVariable()
125 by Gustavo Niemeyer
- Now Unicode and Bin will blow up if the values set are not
455
        variable.set(u"unicode")
456
        self.assertEquals(variable.get(), u"unicode")
457
        self.assertRaises(TypeError, variable.set, "str")
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
458
459
460
class DateTimeVariableTest(TestHelper):
461
462
    def test_get_set(self):
463
        epoch = datetime.utcfromtimestamp(0)
464
        variable = DateTimeVariable()
465
        variable.set(0)
466
        self.assertEquals(variable.get(), epoch)
467
        variable.set(0.0)
468
        self.assertEquals(variable.get(), epoch)
469
        variable.set(0L)
470
        self.assertEquals(variable.get(), epoch)
471
        variable.set(epoch)
472
        self.assertEquals(variable.get(), epoch)
473
        self.assertRaises(TypeError, variable.set, marker)
474
475
    def test_get_set_from_database(self):
476
        datetime_str = "1977-05-04 12:34:56.78"
477
        datetime_uni = unicode(datetime_str)
478
        datetime_obj = datetime(1977, 5, 4, 12, 34, 56, 780000)
479
480
        variable = DateTimeVariable()
481
482
        variable.set(datetime_str, from_db=True)
483
        self.assertEquals(variable.get(), datetime_obj)
484
        variable.set(datetime_uni, from_db=True)
485
        self.assertEquals(variable.get(), datetime_obj)
486
        variable.set(datetime_obj, from_db=True)
487
        self.assertEquals(variable.get(), datetime_obj)
488
489
        datetime_str = "1977-05-04 12:34:56"
490
        datetime_uni = unicode(datetime_str)
491
        datetime_obj = datetime(1977, 5, 4, 12, 34, 56)
492
493
        variable.set(datetime_str, from_db=True)
494
        self.assertEquals(variable.get(), datetime_obj)
495
        variable.set(datetime_uni, from_db=True)
496
        self.assertEquals(variable.get(), datetime_obj)
497
        variable.set(datetime_obj, from_db=True)
498
        self.assertEquals(variable.get(), datetime_obj)
499
500
        self.assertRaises(TypeError, variable.set, 0, from_db=True)
501
        self.assertRaises(TypeError, variable.set, marker, from_db=True)
502
        self.assertRaises(ValueError, variable.set, "foobar", from_db=True)
503
        self.assertRaises(ValueError, variable.set, "foo bar", from_db=True)
504
95.3.7 by Gustavo Niemeyer
- Minor changes in the way the SimpleProperty base works.
505
    def test_get_set_with_tzinfo(self):
506
        datetime_str = "1977-05-04 12:34:56.78"
507
        datetime_obj = datetime(1977, 5, 4, 12, 34, 56, 780000, tzinfo=tzutc())
508
509
        variable = DateTimeVariable(tzinfo=tzutc())
510
511
        # Naive timezone, from_db=True.
512
        variable.set(datetime_str, from_db=True)
513
        self.assertEquals(variable.get(), datetime_obj)
514
        variable.set(datetime_obj, from_db=True)
515
        self.assertEquals(variable.get(), datetime_obj)
516
517
        # Naive timezone, from_db=False (doesn't work).
518
        datetime_obj = datetime(1977, 5, 4, 12, 34, 56, 780000)
519
        self.assertRaises(ValueError, variable.set, datetime_obj)
520
521
        # Different timezone, from_db=False.
522
        datetime_obj = datetime(1977, 5, 4, 12, 34, 56, 780000,
523
                                tzinfo=tzoffset("1h", 3600))
524
        variable.set(datetime_obj, from_db=False)
525
        converted_obj = variable.get()
526
        self.assertEquals(converted_obj, datetime_obj)
527
        self.assertEquals(type(converted_obj.tzinfo), tzutc)
528
529
        # Different timezone, from_db=True.
530
        datetime_obj = datetime(1977, 5, 4, 12, 34, 56, 780000,
531
                                tzinfo=tzoffset("1h", 3600))
532
        variable.set(datetime_obj, from_db=True)
533
        converted_obj = variable.get()
534
        self.assertEquals(converted_obj, datetime_obj)
535
        self.assertEquals(type(converted_obj.tzinfo), tzutc)
536
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
537
538
class DateVariableTest(TestHelper):
539
540
    def test_get_set(self):
541
        epoch = datetime.utcfromtimestamp(0)
542
        epoch_date = epoch.date()
543
544
        variable = DateVariable()
545
546
        variable.set(epoch)
547
        self.assertEquals(variable.get(), epoch_date)
548
        variable.set(epoch_date)
549
        self.assertEquals(variable.get(), epoch_date)
550
551
        self.assertRaises(TypeError, variable.set, marker)
552
553
    def test_get_set_from_database(self):
554
        date_str = "1977-05-04"
555
        date_uni = unicode(date_str)
556
        date_obj = date(1977, 5, 4)
557
558
        variable = DateVariable()
559
560
        variable.set(date_str, from_db=True)
561
        self.assertEquals(variable.get(), date_obj)
562
        variable.set(date_uni, from_db=True)
563
        self.assertEquals(variable.get(), date_obj)
564
        variable.set(date_obj, from_db=True)
565
        self.assertEquals(variable.get(), date_obj)
566
567
        self.assertRaises(TypeError, variable.set, 0, from_db=True)
568
        self.assertRaises(TypeError, variable.set, marker, from_db=True)
569
        self.assertRaises(ValueError, variable.set, "foobar", from_db=True)
570
95.3.13 by Gustavo Niemeyer
Added some tests for DateVariable being set from a string including
571
    def test_set_with_datetime(self):
572
        datetime_str = "1977-05-04 12:34:56.78"
573
        date_obj = date(1977, 5, 4)
574
        variable = DateVariable()
575
        variable.set(datetime_str, from_db=True)
576
        self.assertEquals(variable.get(), date_obj)
577
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
578
579
class TimeVariableTest(TestHelper):
580
581
    def test_get_set(self):
582
        epoch = datetime.utcfromtimestamp(0)
583
        epoch_time = epoch.time()
584
585
        variable = TimeVariable()
586
587
        variable.set(epoch)
588
        self.assertEquals(variable.get(), epoch_time)
589
        variable.set(epoch_time)
590
        self.assertEquals(variable.get(), epoch_time)
591
592
        self.assertRaises(TypeError, variable.set, marker)
593
594
    def test_get_set_from_database(self):
595
        time_str = "12:34:56.78"
596
        time_uni = unicode(time_str)
597
        time_obj = time(12, 34, 56, 780000)
598
599
        variable = TimeVariable()
600
601
        variable.set(time_str, from_db=True)
602
        self.assertEquals(variable.get(), time_obj)
603
        variable.set(time_uni, from_db=True)
604
        self.assertEquals(variable.get(), time_obj)
605
        variable.set(time_obj, from_db=True)
606
        self.assertEquals(variable.get(), time_obj)
607
608
        time_str = "12:34:56"
609
        time_uni = unicode(time_str)
610
        time_obj = time(12, 34, 56)
611
612
        variable.set(time_str, from_db=True)
613
        self.assertEquals(variable.get(), time_obj)
614
        variable.set(time_uni, from_db=True)
615
        self.assertEquals(variable.get(), time_obj)
616
        variable.set(time_obj, from_db=True)
617
        self.assertEquals(variable.get(), time_obj)
618
619
        self.assertRaises(TypeError, variable.set, 0, from_db=True)
620
        self.assertRaises(TypeError, variable.set, marker, from_db=True)
621
        self.assertRaises(ValueError, variable.set, "foobar", from_db=True)
622
95.3.13 by Gustavo Niemeyer
Added some tests for DateVariable being set from a string including
623
    def test_set_with_datetime(self):
624
        datetime_str = "1977-05-04 12:34:56.78"
625
        time_obj = time(12, 34, 56, 780000)
626
        variable = TimeVariable()
627
        variable.set(datetime_str, from_db=True)
628
        self.assertEquals(variable.get(), time_obj)
629
110 by Gustavo Niemeyer
Fixing date conversion issue regarding floating point precision.
630
    def test_microsecond_error(self):
631
        time_str = "15:14:18.598678"
632
        time_obj = time(15, 14, 18, 598678)
633
        variable = TimeVariable()
634
        variable.set(time_str, from_db=True)
635
        self.assertEquals(variable.get(), time_obj)
636
637
    def test_microsecond_error_less_digits(self):
638
        time_str = "15:14:18.5986"
639
        time_obj = time(15, 14, 18, 598600)
640
        variable = TimeVariable()
641
        variable.set(time_str, from_db=True)
642
        self.assertEquals(variable.get(), time_obj)
643
644
    def test_microsecond_error_more_digits(self):
645
        time_str = "15:14:18.5986789"
646
        time_obj = time(15, 14, 18, 598678)
647
        variable = TimeVariable()
648
        variable.set(time_str, from_db=True)
649
        self.assertEquals(variable.get(), time_obj)
650
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
651
95.4.13 by James Henstridge
add TimeDeltaVariable
652
class TimeDeltaVariableTest(TestHelper):
653
654
    def test_get_set(self):
655
        delta = timedelta(days=42)
656
657
        variable = TimeDeltaVariable()
658
659
        variable.set(delta)
660
        self.assertEquals(variable.get(), delta)
661
662
        self.assertRaises(TypeError, variable.set, marker)
268.1.3 by Thomas Hervé
Whitespace
663
95.4.13 by James Henstridge
add TimeDeltaVariable
664
    def test_get_set_from_database(self):
665
        delta_str = "42 days 12:34:56.78"
666
        delta_uni = unicode(delta_str)
667
        delta_obj = timedelta(days=42, hours=12, minutes=34,
668
                              seconds=56, microseconds=780000)
669
670
        variable = TimeDeltaVariable()
671
672
        variable.set(delta_str, from_db=True)
673
        self.assertEquals(variable.get(), delta_obj)
674
        variable.set(delta_uni, from_db=True)
675
        self.assertEquals(variable.get(), delta_obj)
676
        variable.set(delta_obj, from_db=True)
677
        self.assertEquals(variable.get(), delta_obj)
678
95.4.17 by James Henstridge
get rid of TimeDeltaVariable._parse_get(). Make _parse_interval()
679
        delta_str = "1 day, 12:34:56"
95.4.13 by James Henstridge
add TimeDeltaVariable
680
        delta_uni = unicode(delta_str)
681
        delta_obj = timedelta(days=1, hours=12, minutes=34, seconds=56)
682
683
        variable.set(delta_str, from_db=True)
684
        self.assertEquals(variable.get(), delta_obj)
685
        variable.set(delta_uni, from_db=True)
686
        self.assertEquals(variable.get(), delta_obj)
687
        variable.set(delta_obj, from_db=True)
688
        self.assertEquals(variable.get(), delta_obj)
689
690
        self.assertRaises(TypeError, variable.set, 0, from_db=True)
691
        self.assertRaises(TypeError, variable.set, marker, from_db=True)
692
        self.assertRaises(ValueError, variable.set, "foobar", from_db=True)
693
694
        # Intervals of months or years can not be converted to a
695
        # Python timedelta, so a ValueError exception is raised:
696
        self.assertRaises(ValueError, variable.set, "42 months", from_db=True)
697
        self.assertRaises(ValueError, variable.set, "42 years", from_db=True)
698
699
193.2.1 by Gustavo Niemeyer
- Rewrote interval parser for TimeDeltaVariable(). Many more formats
700
class ParseIntervalTest(TestHelper):
701
702
    def check(self, interval, td):
193.2.2 by Gustavo Niemeyer
Test _parse_interval() through TimeDeltaVariable instead of
703
        self.assertEquals(TimeDeltaVariable(interval, from_db=True).get(), td)
193.2.1 by Gustavo Niemeyer
- Rewrote interval parser for TimeDeltaVariable(). Many more formats
704
705
    def test_zero(self):
706
        self.check("0:00:00", timedelta(0))
707
708
    def test_one_microsecond(self):
709
        self.check("0:00:00.000001", timedelta(0, 0, 1))
710
711
    def test_twelve_centiseconds(self):
712
        self.check("0:00:00.120000", timedelta(0, 0, 120000))
713
714
    def test_one_second(self):
715
        self.check("0:00:01", timedelta(0, 1))
716
717
    def test_twelve_seconds(self):
718
        self.check("0:00:12", timedelta(0, 12))
719
720
    def test_one_minute(self):
721
        self.check("0:01:00", timedelta(0, 60))
722
723
    def test_twelve_minutes(self):
724
        self.check("0:12:00", timedelta(0, 12*60))
725
726
    def test_one_hour(self):
727
        self.check("1:00:00", timedelta(0, 60*60))
728
729
    def test_twelve_hours(self):
730
        self.check("12:00:00", timedelta(0, 12*60*60))
731
732
    def test_one_day(self):
733
        self.check("1 day, 0:00:00", timedelta(1))
734
735
    def test_twelve_days(self):
736
        self.check("12 days, 0:00:00", timedelta(12))
737
738
    def test_twelve_twelve_twelve_twelve_twelve(self):
739
        self.check("12 days, 12:12:12.120000",
740
                   timedelta(12, 12*60*60 + 12*60 + 12, 120000))
741
742
    def test_minus_twelve_centiseconds(self):
743
        self.check("-1 day, 23:59:59.880000", timedelta(0, 0, -120000))
744
745
    def test_minus_twelve_days(self):
746
        self.check("-12 days, 0:00:00", timedelta(-12))
747
748
    def test_minus_twelve_hours(self):
749
        self.check("-12:00:00", timedelta(hours=-12))
750
751
    def test_one_day_and_a_half(self):
752
        self.check("1.5 days", timedelta(days=1, hours=12))
753
754
    def test_seconds_without_unit(self):
755
        self.check("1h123", timedelta(hours=1, seconds=123))
756
757
    def test_d_h_m_s_ms(self):
758
        self.check("1d1h1m1s1ms", timedelta(days=1, hours=1, minutes=1,
759
                                            seconds=1, microseconds=1000))
760
761
    def test_days_without_unit(self):
762
        self.check("-12 1:02 3s", timedelta(days=-12, hours=1, minutes=2,
763
                                            seconds=3))
764
765
    def test_unsupported_unit(self):
766
        try:
767
            self.check("1 month", None)
768
        except ValueError, e:
769
            self.assertEquals(str(e), "Unsupported interval unit 'month' "
770
                                      "in interval '1 month'")
771
        else:
772
            self.fail("ValueError not raised")
773
774
    def test_missing_value(self):
775
        try:
776
            self.check("day", None)
777
        except ValueError, e:
778
            self.assertEquals(str(e), "Expected an interval value rather than "
779
                                      "'day' in interval 'day'")
780
        else:
781
            self.fail("ValueError not raised")
782
783
289.3.1 by James Henstridge
Add a UUIDVariable type (will not function without Python >= 2.5).
784
class UUIDVariableTest(TestHelper):
785
786
    def is_supported(self):
787
        return uuid is not None
788
789
    def test_get_set(self):
790
        value = uuid.UUID("{0609f76b-878f-4546-baf5-c1b135e8de72}")
791
792
        variable = UUIDVariable()
793
794
        variable.set(value)
795
        self.assertEquals(variable.get(), value)
796
        self.assertEquals(
797
            variable.get(to_db=True), "0609f76b-878f-4546-baf5-c1b135e8de72")
798
799
        self.assertRaises(TypeError, variable.set, marker)
800
        self.assertRaises(TypeError, variable.set,
801
                          "0609f76b-878f-4546-baf5-c1b135e8de72")
802
        self.assertRaises(TypeError, variable.set,
803
                          u"0609f76b-878f-4546-baf5-c1b135e8de72")
804
805
    def test_get_set_from_database(self):
806
        value = uuid.UUID("{0609f76b-878f-4546-baf5-c1b135e8de72}")
807
808
        variable = UUIDVariable()
809
810
        # Strings and UUID objects are accepted from the database.
811
        variable.set(value, from_db=True)
812
        self.assertEquals(variable.get(), value)
813
        variable.set("0609f76b-878f-4546-baf5-c1b135e8de72", from_db=True)
814
        self.assertEquals(variable.get(), value)
815
        variable.set(u"0609f76b-878f-4546-baf5-c1b135e8de72", from_db=True)
816
        self.assertEquals(variable.get(), value)
817
289.3.2 by James Henstridge
Add a UUID property built using UUIDVariable.
818
        # Some other representations for UUID values.
819
        variable.set("{0609f76b-878f-4546-baf5-c1b135e8de72}", from_db=True)
820
        self.assertEquals(variable.get(), value)
821
        variable.set("0609f76b878f4546baf5c1b135e8de72", from_db=True)
822
        self.assertEquals(variable.get(), value)
823
289.3.1 by James Henstridge
Add a UUIDVariable type (will not function without Python >= 2.5).
824
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
825
class PickleVariableTest(TestHelper):
826
827
    def test_get_set(self):
828
        d = {"a": 1}
829
        d_dump = pickle.dumps(d, -1)
830
831
        variable = PickleVariable()
832
833
        variable.set(d)
834
        self.assertEquals(variable.get(), d)
835
        self.assertEquals(variable.get(to_db=True), d_dump)
836
837
        variable.set(d_dump, from_db=True)
838
        self.assertEquals(variable.get(), d)
839
        self.assertEquals(variable.get(to_db=True), d_dump)
840
85 by Gustavo Niemeyer
- Greatly improved the autoreload feature support.
841
        self.assertEquals(variable.get_state(), (Undef, d_dump))
268.1.3 by Thomas Hervé
Whitespace
842
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
843
        variable.set(marker)
85 by Gustavo Niemeyer
- Greatly improved the autoreload feature support.
844
        variable.set_state((Undef, d_dump))
58 by Gustavo Niemeyer
- Major refactoring of the typing system. Kinds are gone. Now Variables
845
        self.assertEquals(variable.get(), d)
846
847
        variable.get()["b"] = 2
848
        self.assertEquals(variable.get(), {"a": 1, "b": 2})
849
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
850
    def test_pickle_events(self):
851
        event = EventSystem(marker)
852
853
        variable = PickleVariable(event=event, value_factory=list)
854
855
        changes = []
856
        def changed(owner, variable, old_value, new_value, fromdb):
857
            changes.append((variable, old_value, new_value, fromdb))
858
268.1.1 by Thomas Hervé
Remove the default iteration for alive object, and use 2 new events to narrow
859
        event.emit("start-tracking-changes", event)
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
860
        event.hook("changed", changed)
861
862
        variable.checkpoint()
863
864
        event.emit("flush")
865
866
        self.assertEquals(changes, [])
867
868
        lst = variable.get()
869
870
        self.assertEquals(lst, [])
871
        self.assertEquals(changes, [])
872
873
        lst.append("a")
874
875
        self.assertEquals(changes, [])
876
877
        event.emit("flush")
878
879
        self.assertEquals(changes, [(variable, None, ["a"], False)])
880
881
        del changes[:]
882
883
        event.emit("object-deleted")
884
        self.assertEquals(changes, [(variable, None, ["a"], False)])
885
886
887
class ListVariableTest(TestHelper):
888
889
    def test_get_set(self):
282.3.1 by James Henstridge
Modify the ListVariable test to use EnumVariables for its items, since
890
        # Enumeration variables are used as items so that database
282.3.2 by James Henstridge
Clean up test a little.
891
        # side and python side values can be distinguished.
282.3.1 by James Henstridge
Modify the ListVariable test to use EnumVariables for its items, since
892
        get_map = {1: "a", 2: "b", 3: "c"}
893
        set_map = {"a": 1, "b": 2, "c": 3}
894
        item_factory = VariableFactory(
895
            EnumVariable, get_map=get_map, set_map=set_map)
896
897
        l = ["a", "b"]
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
898
        l_dump = pickle.dumps(l, -1)
282.3.1 by James Henstridge
Modify the ListVariable test to use EnumVariables for its items, since
899
        l_vars = [item_factory(value=x) for x in l]
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
900
282.3.1 by James Henstridge
Modify the ListVariable test to use EnumVariables for its items, since
901
        variable = ListVariable(item_factory)
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
902
903
        variable.set(l)
904
        self.assertEquals(variable.get(), l)
282.3.1 by James Henstridge
Modify the ListVariable test to use EnumVariables for its items, since
905
        self.assertVariablesEqual(variable.get(to_db=True), l_vars)
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
906
282.3.1 by James Henstridge
Modify the ListVariable test to use EnumVariables for its items, since
907
        variable.set([1, 2], from_db=True)
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
908
        self.assertEquals(variable.get(), l)
282.3.1 by James Henstridge
Modify the ListVariable test to use EnumVariables for its items, since
909
        self.assertVariablesEqual(variable.get(to_db=True), l_vars)
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
910
911
        self.assertEquals(variable.get_state(), (Undef, l_dump))
912
913
        variable.set([])
914
        variable.set_state((Undef, l_dump))
915
        self.assertEquals(variable.get(), l)
916
282.3.1 by James Henstridge
Modify the ListVariable test to use EnumVariables for its items, since
917
        variable.get().append("c")
918
        self.assertEquals(variable.get(), ["a", "b", "c"])
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
919
920
    def test_list_events(self):
921
        event = EventSystem(marker)
922
147 by Gustavo Niemeyer
- The Chars type is now RawStr. Chars will stay as an alias for
923
        variable = ListVariable(RawStrVariable, event=event,
126 by Gustavo Niemeyer
Let's go with Binary(Variable) rather than Bin(Variable).
924
                                value_factory=list)
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
925
926
        changes = []
927
        def changed(owner, variable, old_value, new_value, fromdb):
928
            changes.append((variable, old_value, new_value, fromdb))
929
268.1.1 by Thomas Hervé
Remove the default iteration for alive object, and use 2 new events to narrow
930
        event.emit("start-tracking-changes", event)
95.1.11 by Gustavo Niemeyer
- Some additional tests for List variables.
931
        event.hook("changed", changed)
932
933
        variable.checkpoint()
934
935
        event.emit("flush")
936
937
        self.assertEquals(changes, [])
938
939
        lst = variable.get()
940
941
        self.assertEquals(lst, [])
942
        self.assertEquals(changes, [])
943
944
        lst.append("a")
945
946
        self.assertEquals(changes, [])
947
948
        event.emit("flush")
949
950
        self.assertEquals(changes, [(variable, None, ["a"], False)])
951
952
        del changes[:]
953
954
        event.emit("object-deleted")
955
        self.assertEquals(changes, [(variable, None, ["a"], False)])
956
95.3.15 by Gustavo Niemeyer
Implemented Enum, after much hassling from Kiko. This is infrastructure
957
958
class EnumVariableTest(TestHelper):
959
960
    def test_set_get(self):
108.1.1 by Gustavo Niemeyer
- Now Enum maps are cached, rather than being recomputed on each
961
        variable = EnumVariable({1: "foo", 2: "bar"}, {"foo": 1, "bar": 2})
95.3.15 by Gustavo Niemeyer
Implemented Enum, after much hassling from Kiko. This is infrastructure
962
        variable.set("foo")
963
        self.assertEquals(variable.get(), "foo")
964
        self.assertEquals(variable.get(to_db=True), 1)
965
        variable.set(2, from_db=True)
966
        self.assertEquals(variable.get(), "bar")
967
        self.assertEquals(variable.get(to_db=True), 2)
968
        self.assertRaises(ValueError, variable.set, "foobar")
108.1.1 by Gustavo Niemeyer
- Now Enum maps are cached, rather than being recomputed on each
969
        self.assertRaises(ValueError, variable.set, 2)
970
971
    def test_in_map(self):
972
        variable = EnumVariable({1: "foo", 2: "bar"}, {"one": 1, "two": 2})
973
        variable.set("one")
974
        self.assertEquals(variable.get(), "foo")
975
        self.assertEquals(variable.get(to_db=True), 1)
976
        variable.set(2, from_db=True)
977
        self.assertEquals(variable.get(), "bar")
978
        self.assertEquals(variable.get(to_db=True), 2)
979
        self.assertRaises(ValueError, variable.set, "foo")
980
        self.assertRaises(ValueError, variable.set, 2)