##// END OF EJS Templates
BUG/TEST: Fix typo in test name.
Scott Sanderson -
Show More
@@ -1,1422 +1,1422 b''
1 1 # encoding: utf-8
2 2 """Tests for IPython.utils.traitlets."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6 #
7 7 # Adapted from enthought.traits, Copyright (c) Enthought, Inc.,
8 8 # also under the terms of the Modified BSD License.
9 9
10 10 import pickle
11 11 import re
12 12 import sys
13 13 from unittest import TestCase
14 14
15 15 import nose.tools as nt
16 16 from nose import SkipTest
17 17
18 18 from IPython.utils.traitlets import (
19 19 HasTraits, MetaHasTraits, TraitType, Any, CBytes, Dict,
20 20 Int, Long, Integer, Float, Complex, Bytes, Unicode, TraitError,
21 21 Undefined, Type, This, Instance, TCPAddress, List, Tuple,
22 22 ObjectName, DottedObjectName, CRegExp, link, directional_link,
23 23 EventfulList, EventfulDict, ForwardDeclaredType, ForwardDeclaredInstance,
24 24 )
25 25 from IPython.utils import py3compat
26 26 from IPython.testing.decorators import skipif
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Helper classes for testing
30 30 #-----------------------------------------------------------------------------
31 31
32 32
33 33 class HasTraitsStub(HasTraits):
34 34
35 35 def _notify_trait(self, name, old, new):
36 36 self._notify_name = name
37 37 self._notify_old = old
38 38 self._notify_new = new
39 39
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Test classes
43 43 #-----------------------------------------------------------------------------
44 44
45 45
46 46 class TestTraitType(TestCase):
47 47
48 48 def test_get_undefined(self):
49 49 class A(HasTraits):
50 50 a = TraitType
51 51 a = A()
52 52 self.assertEqual(a.a, Undefined)
53 53
54 54 def test_set(self):
55 55 class A(HasTraitsStub):
56 56 a = TraitType
57 57
58 58 a = A()
59 59 a.a = 10
60 60 self.assertEqual(a.a, 10)
61 61 self.assertEqual(a._notify_name, 'a')
62 62 self.assertEqual(a._notify_old, Undefined)
63 63 self.assertEqual(a._notify_new, 10)
64 64
65 65 def test_validate(self):
66 66 class MyTT(TraitType):
67 67 def validate(self, inst, value):
68 68 return -1
69 69 class A(HasTraitsStub):
70 70 tt = MyTT
71 71
72 72 a = A()
73 73 a.tt = 10
74 74 self.assertEqual(a.tt, -1)
75 75
76 76 def test_default_validate(self):
77 77 class MyIntTT(TraitType):
78 78 def validate(self, obj, value):
79 79 if isinstance(value, int):
80 80 return value
81 81 self.error(obj, value)
82 82 class A(HasTraits):
83 83 tt = MyIntTT(10)
84 84 a = A()
85 85 self.assertEqual(a.tt, 10)
86 86
87 87 # Defaults are validated when the HasTraits is instantiated
88 88 class B(HasTraits):
89 89 tt = MyIntTT('bad default')
90 90 self.assertRaises(TraitError, B)
91 91
92 92 def test_is_valid_for(self):
93 93 class MyTT(TraitType):
94 94 def is_valid_for(self, value):
95 95 return True
96 96 class A(HasTraits):
97 97 tt = MyTT
98 98
99 99 a = A()
100 100 a.tt = 10
101 101 self.assertEqual(a.tt, 10)
102 102
103 103 def test_value_for(self):
104 104 class MyTT(TraitType):
105 105 def value_for(self, value):
106 106 return 20
107 107 class A(HasTraits):
108 108 tt = MyTT
109 109
110 110 a = A()
111 111 a.tt = 10
112 112 self.assertEqual(a.tt, 20)
113 113
114 114 def test_info(self):
115 115 class A(HasTraits):
116 116 tt = TraitType
117 117 a = A()
118 118 self.assertEqual(A.tt.info(), 'any value')
119 119
120 120 def test_error(self):
121 121 class A(HasTraits):
122 122 tt = TraitType
123 123 a = A()
124 124 self.assertRaises(TraitError, A.tt.error, a, 10)
125 125
126 126 def test_dynamic_initializer(self):
127 127 class A(HasTraits):
128 128 x = Int(10)
129 129 def _x_default(self):
130 130 return 11
131 131 class B(A):
132 132 x = Int(20)
133 133 class C(A):
134 134 def _x_default(self):
135 135 return 21
136 136
137 137 a = A()
138 138 self.assertEqual(a._trait_values, {})
139 139 self.assertEqual(list(a._trait_dyn_inits.keys()), ['x'])
140 140 self.assertEqual(a.x, 11)
141 141 self.assertEqual(a._trait_values, {'x': 11})
142 142 b = B()
143 143 self.assertEqual(b._trait_values, {'x': 20})
144 144 self.assertEqual(list(a._trait_dyn_inits.keys()), ['x'])
145 145 self.assertEqual(b.x, 20)
146 146 c = C()
147 147 self.assertEqual(c._trait_values, {})
148 148 self.assertEqual(list(a._trait_dyn_inits.keys()), ['x'])
149 149 self.assertEqual(c.x, 21)
150 150 self.assertEqual(c._trait_values, {'x': 21})
151 151 # Ensure that the base class remains unmolested when the _default
152 152 # initializer gets overridden in a subclass.
153 153 a = A()
154 154 c = C()
155 155 self.assertEqual(a._trait_values, {})
156 156 self.assertEqual(list(a._trait_dyn_inits.keys()), ['x'])
157 157 self.assertEqual(a.x, 11)
158 158 self.assertEqual(a._trait_values, {'x': 11})
159 159
160 160
161 161
162 162 class TestHasTraitsMeta(TestCase):
163 163
164 164 def test_metaclass(self):
165 165 self.assertEqual(type(HasTraits), MetaHasTraits)
166 166
167 167 class A(HasTraits):
168 168 a = Int
169 169
170 170 a = A()
171 171 self.assertEqual(type(a.__class__), MetaHasTraits)
172 172 self.assertEqual(a.a,0)
173 173 a.a = 10
174 174 self.assertEqual(a.a,10)
175 175
176 176 class B(HasTraits):
177 177 b = Int()
178 178
179 179 b = B()
180 180 self.assertEqual(b.b,0)
181 181 b.b = 10
182 182 self.assertEqual(b.b,10)
183 183
184 184 class C(HasTraits):
185 185 c = Int(30)
186 186
187 187 c = C()
188 188 self.assertEqual(c.c,30)
189 189 c.c = 10
190 190 self.assertEqual(c.c,10)
191 191
192 192 def test_this_class(self):
193 193 class A(HasTraits):
194 194 t = This()
195 195 tt = This()
196 196 class B(A):
197 197 tt = This()
198 198 ttt = This()
199 199 self.assertEqual(A.t.this_class, A)
200 200 self.assertEqual(B.t.this_class, A)
201 201 self.assertEqual(B.tt.this_class, B)
202 202 self.assertEqual(B.ttt.this_class, B)
203 203
204 204 class TestHasTraitsNotify(TestCase):
205 205
206 206 def setUp(self):
207 207 self._notify1 = []
208 208 self._notify2 = []
209 209
210 210 def notify1(self, name, old, new):
211 211 self._notify1.append((name, old, new))
212 212
213 213 def notify2(self, name, old, new):
214 214 self._notify2.append((name, old, new))
215 215
216 216 def test_notify_all(self):
217 217
218 218 class A(HasTraits):
219 219 a = Int
220 220 b = Float
221 221
222 222 a = A()
223 223 a.on_trait_change(self.notify1)
224 224 a.a = 0
225 225 self.assertEqual(len(self._notify1),0)
226 226 a.b = 0.0
227 227 self.assertEqual(len(self._notify1),0)
228 228 a.a = 10
229 229 self.assertTrue(('a',0,10) in self._notify1)
230 230 a.b = 10.0
231 231 self.assertTrue(('b',0.0,10.0) in self._notify1)
232 232 self.assertRaises(TraitError,setattr,a,'a','bad string')
233 233 self.assertRaises(TraitError,setattr,a,'b','bad string')
234 234 self._notify1 = []
235 235 a.on_trait_change(self.notify1,remove=True)
236 236 a.a = 20
237 237 a.b = 20.0
238 238 self.assertEqual(len(self._notify1),0)
239 239
240 240 def test_notify_one(self):
241 241
242 242 class A(HasTraits):
243 243 a = Int
244 244 b = Float
245 245
246 246 a = A()
247 247 a.on_trait_change(self.notify1, 'a')
248 248 a.a = 0
249 249 self.assertEqual(len(self._notify1),0)
250 250 a.a = 10
251 251 self.assertTrue(('a',0,10) in self._notify1)
252 252 self.assertRaises(TraitError,setattr,a,'a','bad string')
253 253
254 254 def test_subclass(self):
255 255
256 256 class A(HasTraits):
257 257 a = Int
258 258
259 259 class B(A):
260 260 b = Float
261 261
262 262 b = B()
263 263 self.assertEqual(b.a,0)
264 264 self.assertEqual(b.b,0.0)
265 265 b.a = 100
266 266 b.b = 100.0
267 267 self.assertEqual(b.a,100)
268 268 self.assertEqual(b.b,100.0)
269 269
270 270 def test_notify_subclass(self):
271 271
272 272 class A(HasTraits):
273 273 a = Int
274 274
275 275 class B(A):
276 276 b = Float
277 277
278 278 b = B()
279 279 b.on_trait_change(self.notify1, 'a')
280 280 b.on_trait_change(self.notify2, 'b')
281 281 b.a = 0
282 282 b.b = 0.0
283 283 self.assertEqual(len(self._notify1),0)
284 284 self.assertEqual(len(self._notify2),0)
285 285 b.a = 10
286 286 b.b = 10.0
287 287 self.assertTrue(('a',0,10) in self._notify1)
288 288 self.assertTrue(('b',0.0,10.0) in self._notify2)
289 289
290 290 def test_static_notify(self):
291 291
292 292 class A(HasTraits):
293 293 a = Int
294 294 _notify1 = []
295 295 def _a_changed(self, name, old, new):
296 296 self._notify1.append((name, old, new))
297 297
298 298 a = A()
299 299 a.a = 0
300 300 # This is broken!!!
301 301 self.assertEqual(len(a._notify1),0)
302 302 a.a = 10
303 303 self.assertTrue(('a',0,10) in a._notify1)
304 304
305 305 class B(A):
306 306 b = Float
307 307 _notify2 = []
308 308 def _b_changed(self, name, old, new):
309 309 self._notify2.append((name, old, new))
310 310
311 311 b = B()
312 312 b.a = 10
313 313 b.b = 10.0
314 314 self.assertTrue(('a',0,10) in b._notify1)
315 315 self.assertTrue(('b',0.0,10.0) in b._notify2)
316 316
317 317 def test_notify_args(self):
318 318
319 319 def callback0():
320 320 self.cb = ()
321 321 def callback1(name):
322 322 self.cb = (name,)
323 323 def callback2(name, new):
324 324 self.cb = (name, new)
325 325 def callback3(name, old, new):
326 326 self.cb = (name, old, new)
327 327
328 328 class A(HasTraits):
329 329 a = Int
330 330
331 331 a = A()
332 332 a.on_trait_change(callback0, 'a')
333 333 a.a = 10
334 334 self.assertEqual(self.cb,())
335 335 a.on_trait_change(callback0, 'a', remove=True)
336 336
337 337 a.on_trait_change(callback1, 'a')
338 338 a.a = 100
339 339 self.assertEqual(self.cb,('a',))
340 340 a.on_trait_change(callback1, 'a', remove=True)
341 341
342 342 a.on_trait_change(callback2, 'a')
343 343 a.a = 1000
344 344 self.assertEqual(self.cb,('a',1000))
345 345 a.on_trait_change(callback2, 'a', remove=True)
346 346
347 347 a.on_trait_change(callback3, 'a')
348 348 a.a = 10000
349 349 self.assertEqual(self.cb,('a',1000,10000))
350 350 a.on_trait_change(callback3, 'a', remove=True)
351 351
352 352 self.assertEqual(len(a._trait_notifiers['a']),0)
353 353
354 354 def test_notify_only_once(self):
355 355
356 356 class A(HasTraits):
357 357 listen_to = ['a']
358 358
359 359 a = Int(0)
360 360 b = 0
361 361
362 362 def __init__(self, **kwargs):
363 363 super(A, self).__init__(**kwargs)
364 364 self.on_trait_change(self.listener1, ['a'])
365 365
366 366 def listener1(self, name, old, new):
367 367 self.b += 1
368 368
369 369 class B(A):
370 370
371 371 c = 0
372 372 d = 0
373 373
374 374 def __init__(self, **kwargs):
375 375 super(B, self).__init__(**kwargs)
376 376 self.on_trait_change(self.listener2)
377 377
378 378 def listener2(self, name, old, new):
379 379 self.c += 1
380 380
381 381 def _a_changed(self, name, old, new):
382 382 self.d += 1
383 383
384 384 b = B()
385 385 b.a += 1
386 386 self.assertEqual(b.b, b.c)
387 387 self.assertEqual(b.b, b.d)
388 388 b.a += 1
389 389 self.assertEqual(b.b, b.c)
390 390 self.assertEqual(b.b, b.d)
391 391
392 392
393 393 class TestHasTraits(TestCase):
394 394
395 395 def test_trait_names(self):
396 396 class A(HasTraits):
397 397 i = Int
398 398 f = Float
399 399 a = A()
400 400 self.assertEqual(sorted(a.trait_names()),['f','i'])
401 401 self.assertEqual(sorted(A.class_trait_names()),['f','i'])
402 402
403 403 def test_trait_metadata(self):
404 404 class A(HasTraits):
405 405 i = Int(config_key='MY_VALUE')
406 406 a = A()
407 407 self.assertEqual(a.trait_metadata('i','config_key'), 'MY_VALUE')
408 408
409 409 def test_trait_metadata_default(self):
410 410 class A(HasTraits):
411 411 i = Int()
412 412 a = A()
413 413 self.assertEqual(a.trait_metadata('i', 'config_key'), None)
414 414 self.assertEqual(a.trait_metadata('i', 'config_key', 'default'), 'default')
415 415
416 416 def test_traits(self):
417 417 class A(HasTraits):
418 418 i = Int
419 419 f = Float
420 420 a = A()
421 421 self.assertEqual(a.traits(), dict(i=A.i, f=A.f))
422 422 self.assertEqual(A.class_traits(), dict(i=A.i, f=A.f))
423 423
424 424 def test_traits_metadata(self):
425 425 class A(HasTraits):
426 426 i = Int(config_key='VALUE1', other_thing='VALUE2')
427 427 f = Float(config_key='VALUE3', other_thing='VALUE2')
428 428 j = Int(0)
429 429 a = A()
430 430 self.assertEqual(a.traits(), dict(i=A.i, f=A.f, j=A.j))
431 431 traits = a.traits(config_key='VALUE1', other_thing='VALUE2')
432 432 self.assertEqual(traits, dict(i=A.i))
433 433
434 434 # This passes, but it shouldn't because I am replicating a bug in
435 435 # traits.
436 436 traits = a.traits(config_key=lambda v: True)
437 437 self.assertEqual(traits, dict(i=A.i, f=A.f, j=A.j))
438 438
439 439 def test_init(self):
440 440 class A(HasTraits):
441 441 i = Int()
442 442 x = Float()
443 443 a = A(i=1, x=10.0)
444 444 self.assertEqual(a.i, 1)
445 445 self.assertEqual(a.x, 10.0)
446 446
447 447 def test_positional_args(self):
448 448 class A(HasTraits):
449 449 i = Int(0)
450 450 def __init__(self, i):
451 451 super(A, self).__init__()
452 452 self.i = i
453 453
454 454 a = A(5)
455 455 self.assertEqual(a.i, 5)
456 456 # should raise TypeError if no positional arg given
457 457 self.assertRaises(TypeError, A)
458 458
459 459 #-----------------------------------------------------------------------------
460 460 # Tests for specific trait types
461 461 #-----------------------------------------------------------------------------
462 462
463 463
464 464 class TestType(TestCase):
465 465
466 466 def test_default(self):
467 467
468 468 class B(object): pass
469 469 class A(HasTraits):
470 470 klass = Type
471 471
472 472 a = A()
473 473 self.assertEqual(a.klass, None)
474 474
475 475 a.klass = B
476 476 self.assertEqual(a.klass, B)
477 477 self.assertRaises(TraitError, setattr, a, 'klass', 10)
478 478
479 479 def test_value(self):
480 480
481 481 class B(object): pass
482 482 class C(object): pass
483 483 class A(HasTraits):
484 484 klass = Type(B)
485 485
486 486 a = A()
487 487 self.assertEqual(a.klass, B)
488 488 self.assertRaises(TraitError, setattr, a, 'klass', C)
489 489 self.assertRaises(TraitError, setattr, a, 'klass', object)
490 490 a.klass = B
491 491
492 492 def test_allow_none(self):
493 493
494 494 class B(object): pass
495 495 class C(B): pass
496 496 class A(HasTraits):
497 497 klass = Type(B, allow_none=False)
498 498
499 499 a = A()
500 500 self.assertEqual(a.klass, B)
501 501 self.assertRaises(TraitError, setattr, a, 'klass', None)
502 502 a.klass = C
503 503 self.assertEqual(a.klass, C)
504 504
505 505 def test_validate_klass(self):
506 506
507 507 class A(HasTraits):
508 508 klass = Type('no strings allowed')
509 509
510 510 self.assertRaises(ImportError, A)
511 511
512 512 class A(HasTraits):
513 513 klass = Type('rub.adub.Duck')
514 514
515 515 self.assertRaises(ImportError, A)
516 516
517 517 def test_validate_default(self):
518 518
519 519 class B(object): pass
520 520 class A(HasTraits):
521 521 klass = Type('bad default', B)
522 522
523 523 self.assertRaises(ImportError, A)
524 524
525 525 class C(HasTraits):
526 526 klass = Type(None, B, allow_none=False)
527 527
528 528 self.assertRaises(TraitError, C)
529 529
530 530 def test_str_klass(self):
531 531
532 532 class A(HasTraits):
533 533 klass = Type('IPython.utils.ipstruct.Struct')
534 534
535 535 from IPython.utils.ipstruct import Struct
536 536 a = A()
537 537 a.klass = Struct
538 538 self.assertEqual(a.klass, Struct)
539 539
540 540 self.assertRaises(TraitError, setattr, a, 'klass', 10)
541 541
542 542 def test_set_str_klass(self):
543 543
544 544 class A(HasTraits):
545 545 klass = Type()
546 546
547 547 a = A(klass='IPython.utils.ipstruct.Struct')
548 548 from IPython.utils.ipstruct import Struct
549 549 self.assertEqual(a.klass, Struct)
550 550
551 551 class TestInstance(TestCase):
552 552
553 553 def test_basic(self):
554 554 class Foo(object): pass
555 555 class Bar(Foo): pass
556 556 class Bah(object): pass
557 557
558 558 class A(HasTraits):
559 559 inst = Instance(Foo)
560 560
561 561 a = A()
562 562 self.assertTrue(a.inst is None)
563 563 a.inst = Foo()
564 564 self.assertTrue(isinstance(a.inst, Foo))
565 565 a.inst = Bar()
566 566 self.assertTrue(isinstance(a.inst, Foo))
567 567 self.assertRaises(TraitError, setattr, a, 'inst', Foo)
568 568 self.assertRaises(TraitError, setattr, a, 'inst', Bar)
569 569 self.assertRaises(TraitError, setattr, a, 'inst', Bah())
570 570
571 571 def test_default_klass(self):
572 572 class Foo(object): pass
573 573 class Bar(Foo): pass
574 574 class Bah(object): pass
575 575
576 576 class FooInstance(Instance):
577 577 klass = Foo
578 578
579 579 class A(HasTraits):
580 580 inst = FooInstance()
581 581
582 582 a = A()
583 583 self.assertTrue(a.inst is None)
584 584 a.inst = Foo()
585 585 self.assertTrue(isinstance(a.inst, Foo))
586 586 a.inst = Bar()
587 587 self.assertTrue(isinstance(a.inst, Foo))
588 588 self.assertRaises(TraitError, setattr, a, 'inst', Foo)
589 589 self.assertRaises(TraitError, setattr, a, 'inst', Bar)
590 590 self.assertRaises(TraitError, setattr, a, 'inst', Bah())
591 591
592 592 def test_unique_default_value(self):
593 593 class Foo(object): pass
594 594 class A(HasTraits):
595 595 inst = Instance(Foo,(),{})
596 596
597 597 a = A()
598 598 b = A()
599 599 self.assertTrue(a.inst is not b.inst)
600 600
601 601 def test_args_kw(self):
602 602 class Foo(object):
603 603 def __init__(self, c): self.c = c
604 604 class Bar(object): pass
605 605 class Bah(object):
606 606 def __init__(self, c, d):
607 607 self.c = c; self.d = d
608 608
609 609 class A(HasTraits):
610 610 inst = Instance(Foo, (10,))
611 611 a = A()
612 612 self.assertEqual(a.inst.c, 10)
613 613
614 614 class B(HasTraits):
615 615 inst = Instance(Bah, args=(10,), kw=dict(d=20))
616 616 b = B()
617 617 self.assertEqual(b.inst.c, 10)
618 618 self.assertEqual(b.inst.d, 20)
619 619
620 620 class C(HasTraits):
621 621 inst = Instance(Foo)
622 622 c = C()
623 623 self.assertTrue(c.inst is None)
624 624
625 625 def test_bad_default(self):
626 626 class Foo(object): pass
627 627
628 628 class A(HasTraits):
629 629 inst = Instance(Foo, allow_none=False)
630 630
631 631 self.assertRaises(TraitError, A)
632 632
633 633 def test_instance(self):
634 634 class Foo(object): pass
635 635
636 636 def inner():
637 637 class A(HasTraits):
638 638 inst = Instance(Foo())
639 639
640 640 self.assertRaises(TraitError, inner)
641 641
642 642
643 643 class TestThis(TestCase):
644 644
645 645 def test_this_class(self):
646 646 class Foo(HasTraits):
647 647 this = This
648 648
649 649 f = Foo()
650 650 self.assertEqual(f.this, None)
651 651 g = Foo()
652 652 f.this = g
653 653 self.assertEqual(f.this, g)
654 654 self.assertRaises(TraitError, setattr, f, 'this', 10)
655 655
656 656 def test_this_inst(self):
657 657 class Foo(HasTraits):
658 658 this = This()
659 659
660 660 f = Foo()
661 661 f.this = Foo()
662 662 self.assertTrue(isinstance(f.this, Foo))
663 663
664 664 def test_subclass(self):
665 665 class Foo(HasTraits):
666 666 t = This()
667 667 class Bar(Foo):
668 668 pass
669 669 f = Foo()
670 670 b = Bar()
671 671 f.t = b
672 672 b.t = f
673 673 self.assertEqual(f.t, b)
674 674 self.assertEqual(b.t, f)
675 675
676 676 def test_subclass_override(self):
677 677 class Foo(HasTraits):
678 678 t = This()
679 679 class Bar(Foo):
680 680 t = This()
681 681 f = Foo()
682 682 b = Bar()
683 683 f.t = b
684 684 self.assertEqual(f.t, b)
685 685 self.assertRaises(TraitError, setattr, b, 't', f)
686 686
687 687 def test_this_in_container(self):
688 688
689 689 class Tree(HasTraits):
690 690 value = Unicode()
691 691 leaves = List(This())
692 692
693 693 tree = Tree(
694 694 value='foo',
695 695 leaves=[Tree('bar'), Tree('buzz')]
696 696 )
697 697
698 698 with self.assertRaises(TraitError):
699 699 tree.leaves = [1, 2]
700 700
701 701 class TraitTestBase(TestCase):
702 702 """A best testing class for basic trait types."""
703 703
704 704 def assign(self, value):
705 705 self.obj.value = value
706 706
707 707 def coerce(self, value):
708 708 return value
709 709
710 710 def test_good_values(self):
711 711 if hasattr(self, '_good_values'):
712 712 for value in self._good_values:
713 713 self.assign(value)
714 714 self.assertEqual(self.obj.value, self.coerce(value))
715 715
716 716 def test_bad_values(self):
717 717 if hasattr(self, '_bad_values'):
718 718 for value in self._bad_values:
719 719 try:
720 720 self.assertRaises(TraitError, self.assign, value)
721 721 except AssertionError:
722 722 assert False, value
723 723
724 724 def test_default_value(self):
725 725 if hasattr(self, '_default_value'):
726 726 self.assertEqual(self._default_value, self.obj.value)
727 727
728 728 def test_allow_none(self):
729 729 if (hasattr(self, '_bad_values') and hasattr(self, '_good_values') and
730 730 None in self._bad_values):
731 731 trait=self.obj.traits()['value']
732 732 try:
733 733 trait.allow_none = True
734 734 self._bad_values.remove(None)
735 735 #skip coerce. Allow None casts None to None.
736 736 self.assign(None)
737 737 self.assertEqual(self.obj.value,None)
738 738 self.test_good_values()
739 739 self.test_bad_values()
740 740 finally:
741 741 #tear down
742 742 trait.allow_none = False
743 743 self._bad_values.append(None)
744 744
745 745 def tearDown(self):
746 746 # restore default value after tests, if set
747 747 if hasattr(self, '_default_value'):
748 748 self.obj.value = self._default_value
749 749
750 750
751 751 class AnyTrait(HasTraits):
752 752
753 753 value = Any
754 754
755 755 class AnyTraitTest(TraitTestBase):
756 756
757 757 obj = AnyTrait()
758 758
759 759 _default_value = None
760 760 _good_values = [10.0, 'ten', u'ten', [10], {'ten': 10},(10,), None, 1j]
761 761 _bad_values = []
762 762
763 763
764 764 class IntTrait(HasTraits):
765 765
766 766 value = Int(99)
767 767
768 768 class TestInt(TraitTestBase):
769 769
770 770 obj = IntTrait()
771 771 _default_value = 99
772 772 _good_values = [10, -10]
773 773 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None, 1j,
774 774 10.1, -10.1, '10L', '-10L', '10.1', '-10.1', u'10L',
775 775 u'-10L', u'10.1', u'-10.1', '10', '-10', u'10', u'-10']
776 776 if not py3compat.PY3:
777 777 _bad_values.extend([long(10), long(-10), 10*sys.maxint, -10*sys.maxint])
778 778
779 779
780 780 class LongTrait(HasTraits):
781 781
782 782 value = Long(99 if py3compat.PY3 else long(99))
783 783
784 784 class TestLong(TraitTestBase):
785 785
786 786 obj = LongTrait()
787 787
788 788 _default_value = 99 if py3compat.PY3 else long(99)
789 789 _good_values = [10, -10]
790 790 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,),
791 791 None, 1j, 10.1, -10.1, '10', '-10', '10L', '-10L', '10.1',
792 792 '-10.1', u'10', u'-10', u'10L', u'-10L', u'10.1',
793 793 u'-10.1']
794 794 if not py3compat.PY3:
795 795 # maxint undefined on py3, because int == long
796 796 _good_values.extend([long(10), long(-10), 10*sys.maxint, -10*sys.maxint])
797 797 _bad_values.extend([[long(10)], (long(10),)])
798 798
799 799 @skipif(py3compat.PY3, "not relevant on py3")
800 800 def test_cast_small(self):
801 801 """Long casts ints to long"""
802 802 self.obj.value = 10
803 803 self.assertEqual(type(self.obj.value), long)
804 804
805 805
806 806 class IntegerTrait(HasTraits):
807 807 value = Integer(1)
808 808
809 809 class TestInteger(TestLong):
810 810 obj = IntegerTrait()
811 811 _default_value = 1
812 812
813 813 def coerce(self, n):
814 814 return int(n)
815 815
816 816 @skipif(py3compat.PY3, "not relevant on py3")
817 817 def test_cast_small(self):
818 818 """Integer casts small longs to int"""
819 819 if py3compat.PY3:
820 820 raise SkipTest("not relevant on py3")
821 821
822 822 self.obj.value = long(100)
823 823 self.assertEqual(type(self.obj.value), int)
824 824
825 825
826 826 class FloatTrait(HasTraits):
827 827
828 828 value = Float(99.0)
829 829
830 830 class TestFloat(TraitTestBase):
831 831
832 832 obj = FloatTrait()
833 833
834 834 _default_value = 99.0
835 835 _good_values = [10, -10, 10.1, -10.1]
836 836 _bad_values = ['ten', u'ten', [10], {'ten': 10},(10,), None,
837 837 1j, '10', '-10', '10L', '-10L', '10.1', '-10.1', u'10',
838 838 u'-10', u'10L', u'-10L', u'10.1', u'-10.1']
839 839 if not py3compat.PY3:
840 840 _bad_values.extend([long(10), long(-10)])
841 841
842 842
843 843 class ComplexTrait(HasTraits):
844 844
845 845 value = Complex(99.0-99.0j)
846 846
847 847 class TestComplex(TraitTestBase):
848 848
849 849 obj = ComplexTrait()
850 850
851 851 _default_value = 99.0-99.0j
852 852 _good_values = [10, -10, 10.1, -10.1, 10j, 10+10j, 10-10j,
853 853 10.1j, 10.1+10.1j, 10.1-10.1j]
854 854 _bad_values = [u'10L', u'-10L', 'ten', [10], {'ten': 10},(10,), None]
855 855 if not py3compat.PY3:
856 856 _bad_values.extend([long(10), long(-10)])
857 857
858 858
859 859 class BytesTrait(HasTraits):
860 860
861 861 value = Bytes(b'string')
862 862
863 863 class TestBytes(TraitTestBase):
864 864
865 865 obj = BytesTrait()
866 866
867 867 _default_value = b'string'
868 868 _good_values = [b'10', b'-10', b'10L',
869 869 b'-10L', b'10.1', b'-10.1', b'string']
870 870 _bad_values = [10, -10, 10.1, -10.1, 1j, [10],
871 871 ['ten'],{'ten': 10},(10,), None, u'string']
872 872 if not py3compat.PY3:
873 873 _bad_values.extend([long(10), long(-10)])
874 874
875 875
876 876 class UnicodeTrait(HasTraits):
877 877
878 878 value = Unicode(u'unicode')
879 879
880 880 class TestUnicode(TraitTestBase):
881 881
882 882 obj = UnicodeTrait()
883 883
884 884 _default_value = u'unicode'
885 885 _good_values = ['10', '-10', '10L', '-10L', '10.1',
886 886 '-10.1', '', u'', 'string', u'string', u"€"]
887 887 _bad_values = [10, -10, 10.1, -10.1, 1j,
888 888 [10], ['ten'], [u'ten'], {'ten': 10},(10,), None]
889 889 if not py3compat.PY3:
890 890 _bad_values.extend([long(10), long(-10)])
891 891
892 892
893 893 class ObjectNameTrait(HasTraits):
894 894 value = ObjectName("abc")
895 895
896 896 class TestObjectName(TraitTestBase):
897 897 obj = ObjectNameTrait()
898 898
899 899 _default_value = "abc"
900 900 _good_values = ["a", "gh", "g9", "g_", "_G", u"a345_"]
901 901 _bad_values = [1, "", u"€", "9g", "!", "#abc", "aj@", "a.b", "a()", "a[0]",
902 902 None, object(), object]
903 903 if sys.version_info[0] < 3:
904 904 _bad_values.append(u"ΓΎ")
905 905 else:
906 906 _good_values.append(u"ΓΎ") # ΓΎ=1 is valid in Python 3 (PEP 3131).
907 907
908 908
909 909 class DottedObjectNameTrait(HasTraits):
910 910 value = DottedObjectName("a.b")
911 911
912 912 class TestDottedObjectName(TraitTestBase):
913 913 obj = DottedObjectNameTrait()
914 914
915 915 _default_value = "a.b"
916 916 _good_values = ["A", "y.t", "y765.__repr__", "os.path.join", u"os.path.join"]
917 917 _bad_values = [1, u"abc.€", "_.@", ".", ".abc", "abc.", ".abc.", None]
918 918 if sys.version_info[0] < 3:
919 919 _bad_values.append(u"t.ΓΎ")
920 920 else:
921 921 _good_values.append(u"t.ΓΎ")
922 922
923 923
924 924 class TCPAddressTrait(HasTraits):
925 925
926 926 value = TCPAddress()
927 927
928 928 class TestTCPAddress(TraitTestBase):
929 929
930 930 obj = TCPAddressTrait()
931 931
932 932 _default_value = ('127.0.0.1',0)
933 933 _good_values = [('localhost',0),('192.168.0.1',1000),('www.google.com',80)]
934 934 _bad_values = [(0,0),('localhost',10.0),('localhost',-1), None]
935 935
936 936 class ListTrait(HasTraits):
937 937
938 938 value = List(Int)
939 939
940 940 class TestList(TraitTestBase):
941 941
942 942 obj = ListTrait()
943 943
944 944 _default_value = []
945 945 _good_values = [[], [1], list(range(10)), (1,2)]
946 946 _bad_values = [10, [1,'a'], 'a']
947 947
948 948 def coerce(self, value):
949 949 if value is not None:
950 950 value = list(value)
951 951 return value
952 952
953 953 class Foo(object):
954 954 pass
955 955
956 956 class InstanceListTrait(HasTraits):
957 957
958 958 value = List(Instance(__name__+'.Foo'))
959 959
960 960 class TestInstanceList(TraitTestBase):
961 961
962 962 obj = InstanceListTrait()
963 963
964 964 def test_klass(self):
965 965 """Test that the instance klass is properly assigned."""
966 966 self.assertIs(self.obj.traits()['value']._trait.klass, Foo)
967 967
968 968 _default_value = []
969 969 _good_values = [[Foo(), Foo(), None], None]
970 970 _bad_values = [['1', 2,], '1', [Foo]]
971 971
972 972 class LenListTrait(HasTraits):
973 973
974 974 value = List(Int, [0], minlen=1, maxlen=2)
975 975
976 976 class TestLenList(TraitTestBase):
977 977
978 978 obj = LenListTrait()
979 979
980 980 _default_value = [0]
981 981 _good_values = [[1], [1,2], (1,2)]
982 982 _bad_values = [10, [1,'a'], 'a', [], list(range(3))]
983 983
984 984 def coerce(self, value):
985 985 if value is not None:
986 986 value = list(value)
987 987 return value
988 988
989 989 class TupleTrait(HasTraits):
990 990
991 991 value = Tuple(Int(allow_none=True))
992 992
993 993 class TestTupleTrait(TraitTestBase):
994 994
995 995 obj = TupleTrait()
996 996
997 997 _default_value = None
998 998 _good_values = [(1,), None, (0,), [1], (None,)]
999 999 _bad_values = [10, (1,2), ('a'), ()]
1000 1000
1001 1001 def coerce(self, value):
1002 1002 if value is not None:
1003 1003 value = tuple(value)
1004 1004 return value
1005 1005
1006 1006 def test_invalid_args(self):
1007 1007 self.assertRaises(TypeError, Tuple, 5)
1008 1008 self.assertRaises(TypeError, Tuple, default_value='hello')
1009 1009 t = Tuple(Int, CBytes, default_value=(1,5))
1010 1010
1011 1011 class LooseTupleTrait(HasTraits):
1012 1012
1013 1013 value = Tuple((1,2,3))
1014 1014
1015 1015 class TestLooseTupleTrait(TraitTestBase):
1016 1016
1017 1017 obj = LooseTupleTrait()
1018 1018
1019 1019 _default_value = (1,2,3)
1020 1020 _good_values = [(1,), None, [1], (0,), tuple(range(5)), tuple('hello'), ('a',5), ()]
1021 1021 _bad_values = [10, 'hello', {}]
1022 1022
1023 1023 def coerce(self, value):
1024 1024 if value is not None:
1025 1025 value = tuple(value)
1026 1026 return value
1027 1027
1028 1028 def test_invalid_args(self):
1029 1029 self.assertRaises(TypeError, Tuple, 5)
1030 1030 self.assertRaises(TypeError, Tuple, default_value='hello')
1031 1031 t = Tuple(Int, CBytes, default_value=(1,5))
1032 1032
1033 1033
1034 1034 class MultiTupleTrait(HasTraits):
1035 1035
1036 1036 value = Tuple(Int, Bytes, default_value=[99,b'bottles'])
1037 1037
1038 1038 class TestMultiTuple(TraitTestBase):
1039 1039
1040 1040 obj = MultiTupleTrait()
1041 1041
1042 1042 _default_value = (99,b'bottles')
1043 1043 _good_values = [(1,b'a'), (2,b'b')]
1044 1044 _bad_values = ((),10, b'a', (1,b'a',3), (b'a',1), (1, u'a'))
1045 1045
1046 1046 class CRegExpTrait(HasTraits):
1047 1047
1048 1048 value = CRegExp(r'')
1049 1049
1050 1050 class TestCRegExp(TraitTestBase):
1051 1051
1052 1052 def coerce(self, value):
1053 1053 return re.compile(value)
1054 1054
1055 1055 obj = CRegExpTrait()
1056 1056
1057 1057 _default_value = re.compile(r'')
1058 1058 _good_values = [r'\d+', re.compile(r'\d+')]
1059 1059 _bad_values = ['(', None, ()]
1060 1060
1061 1061 class DictTrait(HasTraits):
1062 1062 value = Dict()
1063 1063
1064 1064 def test_dict_assignment():
1065 1065 d = dict()
1066 1066 c = DictTrait()
1067 1067 c.value = d
1068 1068 d['a'] = 5
1069 1069 nt.assert_equal(d, c.value)
1070 1070 nt.assert_true(c.value is d)
1071 1071
1072 1072 class TestLink(TestCase):
1073 1073 def test_connect_same(self):
1074 1074 """Verify two traitlets of the same type can be linked together using link."""
1075 1075
1076 1076 # Create two simple classes with Int traitlets.
1077 1077 class A(HasTraits):
1078 1078 value = Int()
1079 1079 a = A(value=9)
1080 1080 b = A(value=8)
1081 1081
1082 1082 # Conenct the two classes.
1083 1083 c = link((a, 'value'), (b, 'value'))
1084 1084
1085 1085 # Make sure the values are the same at the point of linking.
1086 1086 self.assertEqual(a.value, b.value)
1087 1087
1088 1088 # Change one of the values to make sure they stay in sync.
1089 1089 a.value = 5
1090 1090 self.assertEqual(a.value, b.value)
1091 1091 b.value = 6
1092 1092 self.assertEqual(a.value, b.value)
1093 1093
1094 1094 def test_link_different(self):
1095 1095 """Verify two traitlets of different types can be linked together using link."""
1096 1096
1097 1097 # Create two simple classes with Int traitlets.
1098 1098 class A(HasTraits):
1099 1099 value = Int()
1100 1100 class B(HasTraits):
1101 1101 count = Int()
1102 1102 a = A(value=9)
1103 1103 b = B(count=8)
1104 1104
1105 1105 # Conenct the two classes.
1106 1106 c = link((a, 'value'), (b, 'count'))
1107 1107
1108 1108 # Make sure the values are the same at the point of linking.
1109 1109 self.assertEqual(a.value, b.count)
1110 1110
1111 1111 # Change one of the values to make sure they stay in sync.
1112 1112 a.value = 5
1113 1113 self.assertEqual(a.value, b.count)
1114 1114 b.count = 4
1115 1115 self.assertEqual(a.value, b.count)
1116 1116
1117 1117 def test_unlink(self):
1118 1118 """Verify two linked traitlets can be unlinked."""
1119 1119
1120 1120 # Create two simple classes with Int traitlets.
1121 1121 class A(HasTraits):
1122 1122 value = Int()
1123 1123 a = A(value=9)
1124 1124 b = A(value=8)
1125 1125
1126 1126 # Connect the two classes.
1127 1127 c = link((a, 'value'), (b, 'value'))
1128 1128 a.value = 4
1129 1129 c.unlink()
1130 1130
1131 1131 # Change one of the values to make sure they don't stay in sync.
1132 1132 a.value = 5
1133 1133 self.assertNotEqual(a.value, b.value)
1134 1134
1135 1135 def test_callbacks(self):
1136 1136 """Verify two linked traitlets have their callbacks called once."""
1137 1137
1138 1138 # Create two simple classes with Int traitlets.
1139 1139 class A(HasTraits):
1140 1140 value = Int()
1141 1141 class B(HasTraits):
1142 1142 count = Int()
1143 1143 a = A(value=9)
1144 1144 b = B(count=8)
1145 1145
1146 1146 # Register callbacks that count.
1147 1147 callback_count = []
1148 1148 def a_callback(name, old, new):
1149 1149 callback_count.append('a')
1150 1150 a.on_trait_change(a_callback, 'value')
1151 1151 def b_callback(name, old, new):
1152 1152 callback_count.append('b')
1153 1153 b.on_trait_change(b_callback, 'count')
1154 1154
1155 1155 # Connect the two classes.
1156 1156 c = link((a, 'value'), (b, 'count'))
1157 1157
1158 1158 # Make sure b's count was set to a's value once.
1159 1159 self.assertEqual(''.join(callback_count), 'b')
1160 1160 del callback_count[:]
1161 1161
1162 1162 # Make sure a's value was set to b's count once.
1163 1163 b.count = 5
1164 1164 self.assertEqual(''.join(callback_count), 'ba')
1165 1165 del callback_count[:]
1166 1166
1167 1167 # Make sure b's count was set to a's value once.
1168 1168 a.value = 4
1169 1169 self.assertEqual(''.join(callback_count), 'ab')
1170 1170 del callback_count[:]
1171 1171
1172 1172 class TestDirectionalLink(TestCase):
1173 1173 def test_connect_same(self):
1174 1174 """Verify two traitlets of the same type can be linked together using directional_link."""
1175 1175
1176 1176 # Create two simple classes with Int traitlets.
1177 1177 class A(HasTraits):
1178 1178 value = Int()
1179 1179 a = A(value=9)
1180 1180 b = A(value=8)
1181 1181
1182 1182 # Conenct the two classes.
1183 1183 c = directional_link((a, 'value'), (b, 'value'))
1184 1184
1185 1185 # Make sure the values are the same at the point of linking.
1186 1186 self.assertEqual(a.value, b.value)
1187 1187
1188 1188 # Change one the value of the source and check that it synchronizes the target.
1189 1189 a.value = 5
1190 1190 self.assertEqual(b.value, 5)
1191 1191 # Change one the value of the target and check that it has no impact on the source
1192 1192 b.value = 6
1193 1193 self.assertEqual(a.value, 5)
1194 1194
1195 1195 def test_link_different(self):
1196 1196 """Verify two traitlets of different types can be linked together using link."""
1197 1197
1198 1198 # Create two simple classes with Int traitlets.
1199 1199 class A(HasTraits):
1200 1200 value = Int()
1201 1201 class B(HasTraits):
1202 1202 count = Int()
1203 1203 a = A(value=9)
1204 1204 b = B(count=8)
1205 1205
1206 1206 # Conenct the two classes.
1207 1207 c = directional_link((a, 'value'), (b, 'count'))
1208 1208
1209 1209 # Make sure the values are the same at the point of linking.
1210 1210 self.assertEqual(a.value, b.count)
1211 1211
1212 1212 # Change one the value of the source and check that it synchronizes the target.
1213 1213 a.value = 5
1214 1214 self.assertEqual(b.count, 5)
1215 1215 # Change one the value of the target and check that it has no impact on the source
1216 1216 b.value = 6
1217 1217 self.assertEqual(a.value, 5)
1218 1218
1219 1219 def test_unlink(self):
1220 1220 """Verify two linked traitlets can be unlinked."""
1221 1221
1222 1222 # Create two simple classes with Int traitlets.
1223 1223 class A(HasTraits):
1224 1224 value = Int()
1225 1225 a = A(value=9)
1226 1226 b = A(value=8)
1227 1227
1228 1228 # Connect the two classes.
1229 1229 c = directional_link((a, 'value'), (b, 'value'))
1230 1230 a.value = 4
1231 1231 c.unlink()
1232 1232
1233 1233 # Change one of the values to make sure they don't stay in sync.
1234 1234 a.value = 5
1235 1235 self.assertNotEqual(a.value, b.value)
1236 1236
1237 1237 class Pickleable(HasTraits):
1238 1238 i = Int()
1239 1239 j = Int()
1240 1240
1241 1241 def _i_default(self):
1242 1242 return 1
1243 1243
1244 1244 def _i_changed(self, name, old, new):
1245 1245 self.j = new
1246 1246
1247 1247 def test_pickle_hastraits():
1248 1248 c = Pickleable()
1249 1249 for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1250 1250 p = pickle.dumps(c, protocol)
1251 1251 c2 = pickle.loads(p)
1252 1252 nt.assert_equal(c2.i, c.i)
1253 1253 nt.assert_equal(c2.j, c.j)
1254 1254
1255 1255 c.i = 5
1256 1256 for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
1257 1257 p = pickle.dumps(c, protocol)
1258 1258 c2 = pickle.loads(p)
1259 1259 nt.assert_equal(c2.i, c.i)
1260 1260 nt.assert_equal(c2.j, c.j)
1261 1261
1262 1262 class TestEventful(TestCase):
1263 1263
1264 1264 def test_list(self):
1265 1265 """Does the EventfulList work?"""
1266 1266 event_cache = []
1267 1267
1268 1268 class A(HasTraits):
1269 1269 x = EventfulList([c for c in 'abc'])
1270 1270 a = A()
1271 1271 a.x.on_events(lambda i, x: event_cache.append('insert'), \
1272 1272 lambda i, x: event_cache.append('set'), \
1273 1273 lambda i: event_cache.append('del'), \
1274 1274 lambda: event_cache.append('reverse'), \
1275 1275 lambda *p, **k: event_cache.append('sort'))
1276 1276
1277 1277 a.x.remove('c')
1278 1278 # ab
1279 1279 a.x.insert(0, 'z')
1280 1280 # zab
1281 1281 del a.x[1]
1282 1282 # zb
1283 1283 a.x.reverse()
1284 1284 # bz
1285 1285 a.x[1] = 'o'
1286 1286 # bo
1287 1287 a.x.append('a')
1288 1288 # boa
1289 1289 a.x.sort()
1290 1290 # abo
1291 1291
1292 1292 # Were the correct events captured?
1293 1293 self.assertEqual(event_cache, ['del', 'insert', 'del', 'reverse', 'set', 'set', 'sort'])
1294 1294
1295 1295 # Is the output correct?
1296 1296 self.assertEqual(a.x, [c for c in 'abo'])
1297 1297
1298 1298 def test_dict(self):
1299 1299 """Does the EventfulDict work?"""
1300 1300 event_cache = []
1301 1301
1302 1302 class A(HasTraits):
1303 1303 x = EventfulDict({c: c for c in 'abc'})
1304 1304 a = A()
1305 1305 a.x.on_events(lambda k, v: event_cache.append('add'), \
1306 1306 lambda k, v: event_cache.append('set'), \
1307 1307 lambda k: event_cache.append('del'))
1308 1308
1309 1309 del a.x['c']
1310 1310 # ab
1311 1311 a.x['z'] = 1
1312 1312 # abz
1313 1313 a.x['z'] = 'z'
1314 1314 # abz
1315 1315 a.x.pop('a')
1316 1316 # bz
1317 1317
1318 1318 # Were the correct events captured?
1319 1319 self.assertEqual(event_cache, ['del', 'add', 'set', 'del'])
1320 1320
1321 1321 # Is the output correct?
1322 1322 self.assertEqual(a.x, {c: c for c in 'bz'})
1323 1323
1324 1324 ###
1325 1325 # Traits for Forward Declaration Tests
1326 1326 ###
1327 1327 class ForwardDeclaredInstanceTrait(HasTraits):
1328 1328
1329 1329 value = ForwardDeclaredInstance('ForwardDeclaredBar')
1330 1330
1331 1331 class ForwardDeclaredTypeTrait(HasTraits):
1332 1332
1333 1333 value = ForwardDeclaredType('ForwardDeclaredBar')
1334 1334
1335 1335 class ForwardDeclaredInstanceListTrait(HasTraits):
1336 1336
1337 1337 value = List(ForwardDeclaredInstance('ForwardDeclaredBar'))
1338 1338
1339 1339 class ForwardDeclaredTypeListTrait(HasTraits):
1340 1340
1341 1341 value = List(ForwardDeclaredType('ForwardDeclaredBar'))
1342 1342 ###
1343 1343 # End Traits for Forward Declaration Tests
1344 1344 ###
1345 1345
1346 1346 ###
1347 1347 # Classes for Forward Declaration Tests
1348 1348 ###
1349 1349 class ForwardDeclaredBar(object):
1350 1350 pass
1351 1351
1352 1352 class ForwardDeclaredBarSub(ForwardDeclaredBar):
1353 1353 pass
1354 1354 ###
1355 1355 # End Classes for Forward Declaration Tests
1356 1356 ###
1357 1357
1358 1358 ###
1359 1359 # Forward Declaration Tests
1360 1360 ###
1361 1361 class TestForwardDeclaredInstanceTrait(TraitTestBase):
1362 1362
1363 1363 obj = ForwardDeclaredInstanceTrait()
1364 1364 _default_value = None
1365 1365 _good_values = [None, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
1366 1366 _bad_values = ['foo', 3, ForwardDeclaredBar, ForwardDeclaredBarSub]
1367 1367
1368 class TestForwardDeclaredInstanceTrait(TraitTestBase):
1368 class TestForwardDeclaredTypeTrait(TraitTestBase):
1369 1369
1370 1370 obj = ForwardDeclaredTypeTrait()
1371 1371 _default_value = None
1372 1372 _good_values = [None, ForwardDeclaredBar, ForwardDeclaredBarSub]
1373 1373 _bad_values = ['foo', 3, ForwardDeclaredBar(), ForwardDeclaredBarSub()]
1374 1374
1375 1375 class TestForwardDeclaredInstanceList(TraitTestBase):
1376 1376
1377 1377 obj = ForwardDeclaredInstanceListTrait()
1378 1378
1379 1379 def test_klass(self):
1380 1380 """Test that the instance klass is properly assigned."""
1381 1381 self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
1382 1382
1383 1383 _default_value = []
1384 1384 _good_values = [
1385 1385 [ForwardDeclaredBar(), ForwardDeclaredBarSub(), None],
1386 1386 [None],
1387 1387 [],
1388 1388 None,
1389 1389 ]
1390 1390 _bad_values = [
1391 1391 ForwardDeclaredBar(),
1392 1392 [ForwardDeclaredBar(), 3],
1393 1393 '1',
1394 1394 # Note that this is the type, not an instance.
1395 1395 [ForwardDeclaredBar]
1396 1396 ]
1397 1397
1398 1398 class TestForwardDeclaredTypeList(TraitTestBase):
1399 1399
1400 1400 obj = ForwardDeclaredTypeListTrait()
1401 1401
1402 1402 def test_klass(self):
1403 1403 """Test that the instance klass is properly assigned."""
1404 1404 self.assertIs(self.obj.traits()['value']._trait.klass, ForwardDeclaredBar)
1405 1405
1406 1406 _default_value = []
1407 1407 _good_values = [
1408 1408 [ForwardDeclaredBar, ForwardDeclaredBarSub, None],
1409 1409 [],
1410 1410 [None],
1411 1411 None,
1412 1412 ]
1413 1413 _bad_values = [
1414 1414 ForwardDeclaredBar,
1415 1415 [ForwardDeclaredBar, 3],
1416 1416 '1',
1417 1417 # Note that this is an instance, not the type.
1418 1418 [ForwardDeclaredBar()]
1419 1419 ]
1420 1420 ###
1421 1421 # End Forward Declaration Tests
1422 1422 ###
General Comments 0
You need to be logged in to leave comments. Login now