1
2import testing
3from testing import failed,FailedTest
4from testing import divert_nexus_log,restore_nexus_log,FakeLog
5from testing import value_eq,object_eq,object_neq
6
7
8def test_logging():
9    from generic import log,message,warn,error
10    from generic import generic_settings,NexusError
11
12    # send messages to object rather than stdout
13    divert_nexus_log()
14
15    logfile = generic_settings.devlog
16
17    # test log
18    #   simple message
19    s = 'simple message'
20    logfile.reset()
21    log(s)
22    assert(logfile.s==s+'\n')
23
24    #   list of items
25    items = ['a','b','c',1,2,3]
26    logfile.reset()
27    log(*items)
28    assert(logfile.s=='a b c 1 2 3 \n')
29
30    #   message with indentation
31    s = 'a message\nwith indentation'
32    logfile.reset()
33    log(s,indent='  ')
34    assert(logfile.s=='  a message\n  with indentation\n')
35
36    logfile.reset()
37    log(s,indent='msg: ')
38    assert(logfile.s=='msg: a message\nmsg: with indentation\n')
39
40    #   writing to separate log files
41    logfile2 = FakeLog()
42    s1 = 'message to log 1'
43    s2 = 'message to log 2'
44    logfile.reset()
45    logfile2.reset()
46    log(s1)
47    assert(logfile.s==s1+'\n')
48    assert(logfile2.s=='')
49
50    logfile.reset()
51    logfile2.reset()
52    log(s2,logfile=logfile2)
53    assert(logfile.s=='')
54    assert(logfile2.s==s2+'\n')
55
56
57    # test warn
58    logfile.reset()
59    s = 'this is a warning'
60    warn(s)
61    so = '''
62  warning:
63    this is a warning
64'''
65    assert(logfile.s==so)
66    logfile.reset()
67    s = 'this is a warning'
68    warn(s,header='Special')
69    so = '''
70  Special warning:
71    this is a warning
72'''
73    assert(logfile.s==so)
74
75    # test error
76    #   in testing environment, should raise an error
77    try:
78        error('testing environment')
79        raise FailedTest
80    except NexusError:
81        None
82    except FailedTest:
83        failed()
84    except Exception as e:
85        failed(str(e))
86    #end try
87    #   in standard/user environment, should print message
88    generic_settings.raise_error = False
89    logfile.reset()
90    error('this is an error',header='User',exit=False)
91    so = '''
92  User error:
93    this is an error
94'''
95    assert(logfile.s==so)
96    generic_settings.raise_error = True
97    #   in testing environment, should raise an error
98    try:
99        error('testing environment')
100        raise FailedTest
101    except NexusError:
102        None
103    except FailedTest:
104        failed()
105    except Exception as e:
106        failed(str(e))
107    #end try
108
109    restore_nexus_log()
110
111#end def test_logging
112
113
114
115def test_intrinsics():
116    # test object_interface functions
117    import os
118    from generic import obj,object_interface
119    from generic import generic_settings,NexusError
120    from numpy import array,bool_
121
122    tpath = testing.setup_unit_test_output_directory('generic','test_intrinsics')
123
124    # test object set/get
125    # make a simple object
126    o = obj()
127    o.a = 1
128    o.b = 'b'
129    o['c'] = (1,1,1)
130    o[3,4,5] = (5,6,7)
131
132    # test member values
133    assert(o.a==1)
134    assert(o.b=='b')
135    assert(o.c==(1,1,1))
136    assert(o[3,4,5]==(5,6,7))
137
138    # test member presence and length
139    assert('a' in o)
140    assert(2 not in o)
141    assert(len(o)==4)
142    del o.a
143    assert('a' not in o)
144    assert(len(o)==3)
145    try:
146        del o.d
147        raise FailedTest
148    except AttributeError:
149        None
150    except FailedTest:
151        failed()
152    except Exception as e:
153        failed(str(e))
154    #end try
155
156    # test add/access failures
157    try: # add unhashable type
158        o[{1:2,3:4}] = 5
159        raise FailedTest
160    except TypeError:
161        None
162    except FailedTest:
163        failed()
164    except Exception as e:
165        failed(str(e))
166    #end try
167    try: # access missing member
168        v = o.d
169        raise FailedTest
170    except AttributeError:
171        None
172    except FailedTest:
173        failed()
174    except Exception as e:
175        failed(str(e))
176    #end try
177    try: # access missing member
178        v = o['d']
179        raise FailedTest
180    except KeyError:
181        None
182    except FailedTest:
183        failed()
184    except Exception as e:
185        failed(str(e))
186    #end try
187
188    # test iterability
189    # test list-like iterability
190    l = list()
191    for v in o:
192        l.append(v)
193    #end for
194    l = set(l)
195    l2 = {'b', (1, 1, 1), (5, 6, 7)}
196    assert(l2==l)
197
198    # test dict-like iterability
199    d = dict()
200    for k,v in o.items():
201        d[k] = v
202    #end for
203    o2 = obj()
204    o2.__dict__ = d
205    assert(object_eq(o,o2))
206    assert(set(o.keys())==set(d.keys()))
207    assert(set(o.values())==set(d.values()))
208    assert(set(o.items())==set(d.items()))
209
210    # test repr
211    ro = '''
212  b                     str
213  c                     tuple
214  (3, 4, 5)             tuple
215'''
216    assert(repr(o)==ro[1:])
217    o2 = obj(
218        a = obj(a1=1,a2=2,a3=3),
219        b = obj(b1='b1',b2='b2'),
220        c = obj(c1=5,c2=('a',3,4)),
221        d = array([3,4,5],dtype=int),
222        )
223    ro2 = '''
224  a                     obj
225  b                     obj
226  c                     obj
227  d                     ndarray
228'''
229    assert(repr(o2)==ro2[1:])
230
231    # test str
232    so = '''
233  b               = b
234  c               = (1, 1, 1)
235  (3, 4, 5)       = (5, 6, 7)
236'''
237    assert(str(o)==so[1:])
238    so2 = '''
239  d               = [3 4 5]
240  a
241    a1              = 1
242    a2              = 2
243    a3              = 3
244  end a
245  b
246    b1              = b1
247    b2              = b2
248  end b
249  c
250    c1              = 5
251    c2              = ('a', 3, 4)
252  end c
253'''
254    assert(str(o2)==so2[1:])
255    o3 = o2
256
257    # test tree
258    #   not committed to output, only check execution
259    assert(isinstance(o2.tree(),str))
260    assert(isinstance(o2.tree(depth=1),str))
261    assert(isinstance(o2.tree(types=True),str))
262    assert(isinstance(o2.tree(all=True),str))
263    assert(isinstance(o2.tree(nindent=2),str))
264
265    # test deepcopy
266    o2 = o.copy()
267    assert(id(o)!=id(o2))
268    assert(object_eq(o,o2))
269    o2.a=1
270    assert(object_neq(o,o2))
271
272    # test eq
273    assert(o==o2)
274    o4 = o3.copy()
275    v = o3==o4
276    assert(isinstance(v,bool_))
277    assert(bool(v))
278    assert(object_eq(o3,o4))
279
280    # test clear
281    o2.clear()
282    assert(len(o2)==0)
283    assert('a' not in o2)
284
285    # test save/load
286    save_file = os.path.join(tpath,'o.p')
287    o.save(save_file)
288    o2 = obj()
289    o2.load(save_file)
290    assert(object_eq(o,o2))
291
292    # test class-level set/get methods
293    class objint(object_interface):
294        a = 1
295        b = 'b'
296        c = (1,1,1)
297    #end class objint
298
299    # test class_has
300    assert(objint.class_has('c'))
301
302    # test class_get
303    assert(objint.class_get('c')==(1,1,1))
304    try:
305        val = objint.class_get('d')
306        raise FailedTest
307    except AttributeError:
308        None
309    except FailedTest:
310        failed()
311    except Exception as e:
312        failed(str(e))
313    #end try
314
315    # test class_keys
316    ck = objint.class_keys()
317    for v in 'abc':
318        assert(v in ck)
319    #end for
320
321    # test class_set_single
322    objint.class_set_single('d',1.34)
323    assert(objint.class_has('d'))
324
325    # test class_set
326    objint.class_set(
327        e = 45,
328        f = 'a phrase',
329        g = {4:6,'a':2}
330        )
331    for v in 'efg':
332        assert(objint.class_has(v))
333    #end for
334
335    # test class_set_optional
336    objint.class_set_optional(h=2)
337    assert(objint.class_has('h'))
338    assert(objint.class_get('h')==2)
339    objint.class_set_optional(a=6)
340    assert(objint.class_get('a')==1)
341
342
343    # test logging functions
344
345    # test open log, write, close log
346    o = obj()
347    o.open_log('log.out')
348    s = 'log output'
349    o.write(s)
350    o.close_log()
351    f = open('log.out','r')
352    so = f.read()
353    f.close()
354    os.remove('log.out')
355    assert(so==s)
356
357    # send messages to object rather than stdout
358    divert_nexus_log()
359    logfile = object_interface._logfile
360
361    #   simple message
362    class DerivedObj(obj):
363        None
364    #end class DerivedObj
365    o = DerivedObj()
366    s = 'simple message'
367    logfile.reset()
368    o.log(s)
369    assert(logfile.s==s+'\n')
370
371    #   list of items
372    items = ['a','b','c',1,2,3]
373    logfile.reset()
374    o.log(*items)
375    assert(logfile.s=='a b c 1 2 3 \n')
376
377    #   message with indentation
378    s = 'a message\nwith indentation'
379    logfile.reset()
380    o.log(s,indent='  ')
381    assert(logfile.s=='  a message\n  with indentation\n')
382
383    logfile.reset()
384    o.log(s,indent='msg: ')
385    assert(logfile.s=='msg: a message\nmsg: with indentation\n')
386
387    #   writing to separate log files
388    logfile2 = FakeLog()
389    s1 = 'message to log 1'
390    s2 = 'message to log 2'
391    logfile.reset()
392    logfile2.reset()
393    o.log(s1)
394    assert(logfile.s==s1+'\n')
395    assert(logfile2.s=='')
396
397    logfile.reset()
398    logfile2.reset()
399    o.log(s2,logfile=logfile2)
400    assert(logfile.s=='')
401    assert(logfile2.s==s2+'\n')
402
403
404    # test warn
405    logfile.reset()
406    s = 'this is a warning'
407    o.warn(s)
408    so = '''
409  DerivedObj warning:
410    this is a warning
411'''
412    assert(logfile.s==so)
413    logfile.reset()
414    s = 'this is a warning'
415    o.warn(s,header='Special')
416    so = '''
417  Special warning:
418    this is a warning
419'''
420    assert(logfile.s==so)
421
422    # test error
423    #   in testing environment, should raise an error
424    try:
425        o.error('testing environment')
426        raise FailedTest
427    except NexusError:
428        None
429    except FailedTest:
430        failed()
431    except Exception as e:
432        failed(str(e))
433    #end try
434    #   in standard/user environment, should print message
435    generic_settings.raise_error = False
436    logfile.reset()
437    o.error('this is an error',exit=False)
438    so = '''
439  DerivedObj error:
440    this is an error
441'''
442    assert(logfile.s==so)
443    logfile.reset()
444    o.error('this is an error',header='User',exit=False)
445    so = '''
446  User error:
447    this is an error
448'''
449    assert(logfile.s==so)
450    generic_settings.raise_error = True
451    #   in testing environment, should raise an error
452    try:
453        o.error('testing environment')
454        raise FailedTest
455    except NexusError:
456        None
457    except FailedTest:
458        failed()
459    except Exception as e:
460        failed(str(e))
461    #end try
462
463    # restore logging function
464    restore_nexus_log()
465
466#end def test_intrinsics
467
468
469
470def test_extensions():
471    # test obj functions
472    from generic import obj,NexusError
473
474    # make a simple object
475    o = obj(
476        a = 1,
477        b = 'b',
478        c = (1,1,1),
479        )
480    o[3,4,5] = (5,6,7)
481
482    # test member values
483    assert(o.a==1)
484    assert(o.b=='b')
485    assert(o.c==(1,1,1))
486    assert(o[3,4,5]==(5,6,7))
487
488    # test member presence and length
489    assert('a' in o)
490    assert(2 not in o)
491    assert(len(o)==4)
492
493    # test list interface
494    vals = [3,'t',6.4,(4,3,2)]
495    l = list()
496    lo = obj()
497    for v in vals:
498        l.append(v)
499        lo.append(v)
500    #end for
501    assert(len(l)==len(lo))
502    for i in range(len(l)):
503        assert(l[i]==lo[i])
504    #end for
505
506
507    # test representations
508    # test list representation
509    l2 = lo.list()
510    assert(isinstance(l2,list))
511    assert(l==l2)
512    l2 = lo.list_optional(1,3)
513    assert(l2==['t',(4,3,2)])
514    l2 = o.list_optional('b',(3,4,5))
515    assert(l2==['b',(5,6,7)])
516
517    # test tuple representation
518    t = lo.tuple()
519    assert(isinstance(t,tuple))
520    assert(t==tuple(l))
521    d = dict(
522        a = 1,
523        b = 'b',
524        c = (1,1,1),
525        )
526    d[3,4,5] = (5,6,7)
527
528    # test dict representation
529    do = o.dict()
530    assert(isinstance(do,dict))
531    assert(do==d)
532    d2 = d.copy()
533    d2['d'] = d
534    o2 = o.copy()
535    o2.d = o
536    d2o = o2.to_dict()
537    assert(d2o==d2)
538
539    # test obj representation
540    o2 = o.obj()
541    assert(isinstance(o2,obj))
542    assert(id(o2)!=id(o))
543    assert(object_eq(o2,o))
544    o2 = o.copy().to_obj()
545    assert(object_eq(o2,o))
546
547    # test list extensions
548    # test first
549    assert(lo.first()==lo[0])
550
551    # test last
552    assert(lo.last()==lo[3])
553
554    # test select_random
555    v = lo.select_random()
556    assert(v in lo.list())
557
558
559    # test dict extensions
560    # test random_key
561    k = o.random_key()
562    assert(k in o)
563    o2 = obj()
564    assert(o2.random_key() is None)
565
566    # test set
567    o2 = o.copy()
568    o2.set(
569        b = 'b2',
570        d = ('a','b','c'),
571        )
572    assert(o2.b=='b2')
573    assert(o2.d==tuple('abc'))
574    o1 = obj(a=1,b=2)
575    o2 = obj(c=3,d=4)
576    o3 = obj(e=5,f=6)
577    o4 = obj()
578    o4.set(o1,o2,o3)
579    for on in (o1,o2,o3):
580        for k,v in on.items():
581            assert(o4[k]==v)
582        #end for
583    #end for
584
585    # test set optional
586    o2 = o.copy()
587    o2.set_optional(
588        b = 'b2',
589        d = ('a','b','c'),
590        )
591    assert(o2.b=='b')
592    assert(o2.d==tuple('abc'))
593    o1 = obj(a=1,b=2)
594    o2 = obj(c=3,d=4)
595    o3 = obj(e=5,f=6)
596    o4 = obj()
597    o4.set_optional(o1,o2,o3)
598    for on in (o1,o2,o3):
599        for k,v in on.items():
600            assert(o4[k]==v)
601        #end for
602    #end for
603
604    # test get
605    assert(o.get('c')==(1,1,1))
606    assert('d' not in o)
607    assert(o.get('d') is None)
608
609    # test get optional (identical to get)
610    assert(o.get_optional('c')==(1,1,1))
611    assert(o.get_optional('d') is None)
612
613    # test get required
614    assert(o.get_required('c')==(1,1,1))
615    try:
616        val = o.get_required('d')
617        raise FailedTest
618    except NexusError:
619        None
620    except FailedTest:
621        failed()
622    except Exception as e:
623        failed(str(e))
624    #end try
625
626    # test delete
627    o2 = o.copy()
628    assert(o2.delete('c')==(1,1,1))
629    assert('c' not in o2)
630    keys = 'a','b','c',(3,4,5)
631    vals = [1,'b',(1,1,1),(5,6,7)]
632    o2 = o.copy()
633    assert(o2.delete(*keys)==vals)
634    assert(len(o2)==0)
635    for k in keys:
636        assert(k not in o2)
637    #end for
638    o2 = o.copy()
639    assert(o2.delete(keys)==vals)
640    assert(len(o2)==0)
641    for k in keys:
642        assert(k not in o2)
643    #end for
644    o2 = o.copy()
645    try:
646        o2.delete('a','d')
647        raise FailedTest
648    except KeyError:
649        None
650    except FailedTest:
651        failed()
652    except Exception as e:
653        failed(str(e))
654    #end try
655
656    # test delete optional
657    o2 = o.copy()
658    o2.delete_optional('c')
659    assert('c' not in o2)
660    assert('d' not in o2)
661    o2.delete_optional('d')
662    assert('d' not in o2)
663
664    # test delete required
665    o2 = o.copy()
666    o2.delete_required('c')
667    assert('c' not in o2)
668    try:
669        o2.delete_required('d')
670        raise FailedTest
671    except NexusError:
672        None
673    except FailedTest:
674        failed()
675    except Exception as e:
676        failed(str(e))
677    #end try
678
679    # test add
680    o2 = obj()
681    o2.add('a',1)
682    try: # add unhashable type
683        o2.add([3,4,5],6)
684        raise FailedTest
685    except TypeError:
686        None
687    #end if
688
689    # test add optional
690    o2 = obj(a=1)
691    o2.add_optional('a',2)
692    o2.add_optional('b',3)
693    assert(o2.a==1)
694    assert(o2.b==3)
695
696
697    # test transfer/copy/move functions
698    dref = dict(
699        a = 1,
700        b = 'b',
701        c = (1,1,1),
702        d = dict(
703            e = 5.4,
704            f = [3.3,4.5],
705            ),
706        )
707    dref[3,4,5] = (5,6,7)
708
709    # test transfer from
710    o = obj()
711    o.transfer_from(dref)
712    assert(o.to_dict()==dref)
713    assert(id(o.d)==id(dref['d']))
714
715    o = obj()
716    o.transfer_from(dref,copy=True)
717    assert(o.to_dict()==dref)
718    assert(id(o.d)!=id(dref['d']))
719
720    osmall = obj(b='b',c=(1,1,1))
721    osmall[3,4,5] = (5,6,7)
722    o = obj()
723    oref = obj(dref)
724    assert(oref.to_dict()==dref)
725    o.transfer_from(oref,keys=['b','c',(3,4,5)])
726    assert(object_eq(o,osmall))
727
728    o = obj(a=6,b=7)
729    o.transfer_from(oref,overwrite=False)
730    assert(object_neq(o,oref))
731    o.transfer_from(oref,overwrite=True)
732    assert(object_eq(o,oref))
733    assert(o.to_dict()==dref)
734
735    o = obj()
736    try:
737        o.transfer_from(oref,keys=['a','x'])
738        raise FailedTest
739    except KeyError:
740        None
741    except FailedTest:
742        failed()
743    except Exception as e:
744        failed(str(e))
745    #end try
746
747    # test transfer to
748    o = obj()
749    oref.transfer_to(o)
750    assert(object_eq(o,oref))
751    assert(id(o.d)==id(oref.d))
752
753    o = obj()
754    oref.transfer_to(o,copy=True)
755    assert(object_eq(o,oref))
756    assert(id(o.d)!=id(oref.d))
757
758    o = obj()
759    oref.transfer_to(o,keys=['b','c',(3,4,5)])
760    assert(object_eq(o,osmall))
761
762    o = obj(a=6,b=7)
763    oref.transfer_to(o,overwrite=False)
764    assert(object_neq(o,oref))
765    oref.transfer_to(o,overwrite=True)
766    assert(object_eq(o,oref))
767
768    o = obj()
769    try:
770        oref.transfer_to(o,keys=['a','x'])
771        raise FailedTest
772    except KeyError:
773        None
774    except FailedTest:
775        failed()
776    except Exception as e:
777        failed(str(e))
778    #end try
779
780    # test move from
781    d2 = dref.copy()
782    o = obj()
783    o.move_from(d2)
784    assert(len(d2)==0)
785    assert(object_eq(o,oref))
786
787    o2 = oref.copy()
788    o = obj()
789    o.move_from(o2)
790    assert(len(o2)==0)
791    assert(object_eq(o,oref))
792
793    osmall2 = oref.copy()
794    del osmall2.b
795    del osmall2.c
796    del osmall2[3,4,5]
797    o2 = oref.copy()
798    o = obj()
799    o.move_from(o2,keys=['b','c',(3,4,5)])
800    assert(object_eq(o,osmall))
801    assert(object_eq(o2,osmall2))
802
803    o2 = oref.copy()
804    o = obj()
805    o.move_from_optional(o2,keys=['b','c',(3,4,5),'alpha','beta'])
806    assert(object_eq(o,osmall))
807    assert(object_eq(o2,osmall2))
808
809    o2 = oref.copy()
810    o = obj()
811    try:
812        o.move_from(o2,keys=['a','x'])
813        raise FailedTest
814    except KeyError:
815        None
816    except FailedTest:
817        failed()
818    except Exception as e:
819        failed(str(e))
820    #end try
821
822    # test move to
823    o2 = oref.copy()
824    d = dict()
825    o2.move_to(d)
826    assert(len(o2)==0)
827    assert(d==dref)
828
829    o2 = oref.copy()
830    o = obj()
831    o2.move_to(o)
832    assert(len(o2)==0)
833    assert(object_eq(o,oref))
834
835    o2 = oref.copy()
836    o = obj()
837    o2.move_to(o,keys=['b','c',(3,4,5)])
838    assert(object_eq(o,osmall))
839    assert(object_eq(o2,osmall2))
840
841    o2 = oref.copy()
842    o = obj()
843    o2.move_to_optional(o,keys=['b','c',(3,4,5),'alpha','beta'])
844    assert(object_eq(o,osmall))
845    assert(object_eq(o2,osmall2))
846
847    o2 = oref.copy()
848    o = obj()
849    try:
850        o2.move_to(o,keys=['a','x'])
851        raise FailedTest
852    except KeyError:
853        None
854    except FailedTest:
855        failed()
856    except Exception as e:
857        failed(str(e))
858    #end try
859
860    # test copy from
861    o = obj()
862    o.copy_from(dref)
863    assert(o.to_dict()==dref)
864    assert(id(o.d)!=id(dref['d']))
865
866    o = obj()
867    o.copy_from(dref,deep=False)
868    assert(o.to_dict()==dref)
869    assert(id(o.d)==id(dref['d']))
870
871    osmall = obj(b='b',c=(1,1,1))
872    osmall[3,4,5] = (5,6,7)
873    o = obj()
874    oref = obj(dref)
875    assert(oref.to_dict()==dref)
876    o.copy_from(oref,keys=['b','c',(3,4,5)])
877    assert(object_eq(o,osmall))
878
879    o = obj()
880    try:
881        o.copy_from(oref,keys=['a','x'])
882        raise FailedTest
883    except KeyError:
884        None
885    except FailedTest:
886        failed()
887    except Exception as e:
888        failed(str(e))
889    #end try
890
891    # test copy to
892    o = obj()
893    oref.copy_to(o)
894    assert(object_eq(o,oref))
895    assert(id(o.d)!=id(oref.d))
896
897    o = obj()
898    oref.copy_to(o,deep=False)
899    assert(object_eq(o,oref))
900    assert(id(o.d)==id(oref.d))
901
902    o = obj()
903    oref.copy_to(o,keys=['b','c',(3,4,5)])
904    assert(object_eq(o,osmall))
905
906    o = obj()
907    try:
908        oref.copy_to(o,keys=['a','x'])
909        raise FailedTest
910    except KeyError:
911        None
912    except FailedTest:
913        failed()
914    except Exception as e:
915        failed(str(e))
916    #end try
917
918    # test extract
919    o = oref.copy()
920    o2 = o.extract()
921    assert(len(o)==0)
922    assert(object_eq(o2,oref))
923
924    o = oref.copy()
925    o2 = o.extract(['b','c',(3,4,5)])
926    assert(object_eq(o2,osmall))
927    assert(object_eq(o,osmall2))
928
929    o = oref.copy()
930    o2 = o.extract_optional(['b','c',(3,4,5),'alpha','beta'])
931    assert(object_eq(o2,osmall))
932    assert(object_eq(o,osmall2))
933
934
935    # test check_required
936    oref.check_required(['a','d',(3,4,5)])
937    try:
938        oref.check_required(['alpha','beta'])
939        raise FailedTest
940    except NexusError:
941        None
942    except FailedTest:
943        failed()
944    except Exception as e:
945        failed(str(e))
946    #end try
947
948    # test check_types
949    types = dict(
950        a = int,
951        b = str,
952        c = tuple,
953        d = dict,
954        )
955    types[3,4,5] = tuple
956    oref.check_types(types)
957
958    types['b'] = int
959    try:
960        oref.check_types(types)
961        raise FailedTest
962    except:
963        None
964    #end try
965
966    types['b'] = str
967    types['alpha'] = float
968    types['beta'] = list
969    oref.check_types_optional(types)
970
971    # test shallow_copy
972    class DerivedObj(obj):
973        None
974    #end class DerivedObj
975    do = DerivedObj(
976        a = 1,
977        b = 'b',
978        c = (1,1,1),
979        )
980    do[3,4,5] = (5,6,7)
981    do2 = do.shallow_copy()
982    assert(isinstance(do2,DerivedObj))
983    assert(object_eq(do2,do))
984    assert(id(do2.c)==id(do.c))
985
986    # test inverse
987    oi = do.inverse()
988    assert(set(oi.keys())==set(do.values()))
989    assert(set(oi.values())==set(do.keys()))
990
991    assert(oi[1]=='a')
992    assert(oi.b=='b')
993    assert(oi[1,1,1]=='c')
994    assert(oi[5,6,7]==(3,4,5))
995
996    # test path operations
997    # test path exists
998    o2 = obj()
999    o2.this = obj()
1000    o2.this.new = obj()
1001    o2.this.new.variable = 'here'
1002    path1 = ['this','new','variable']
1003    path2 = 'this/new/variable'
1004    assert(o2.path_exists(path1))
1005    assert(o2.path_exists(path2))
1006
1007    # test set path
1008    o3 = obj()
1009    o3.set_path(path1,'here')
1010    assert(o3.path_exists(path1))
1011    assert(o3.path_exists(path2))
1012    assert(object_eq(o2,o3))
1013    o4 = obj()
1014    o4.set_path(path2,'here')
1015    assert(o4.path_exists(path1))
1016    assert(o4.path_exists(path2))
1017    assert(object_eq(o3,o4))
1018
1019    # test get path
1020    assert(o2.get_path(path1)=='here')
1021    assert(o2.get_path(path2)=='here')
1022
1023    # test serial
1024    o = obj(
1025        a = obj(
1026            a0 = 0,
1027            a1 = obj(
1028                a10 = 1,
1029                ),
1030            ),
1031        b = obj(
1032            b0 = 0,
1033            b1 = obj(
1034                b10 = 1,
1035                ),
1036            b2 = obj(
1037                b20 = obj(
1038                    b200 = 2,
1039                    ),
1040                b21 = obj(
1041                    b210 = obj(
1042                        b2100 = 3,
1043                        ),
1044                    ),
1045                ),
1046            ),
1047        c = obj(
1048            c0 = 0,
1049            c1 = obj(
1050                c10 = 1,
1051                ),
1052            c2 = obj(
1053                c20 = obj(
1054                    c200 = 2,
1055                    ),
1056                c21 = obj(
1057                    c210 = obj(
1058                        c2100 = 3,
1059                        ),
1060                    ),
1061                ),
1062            c3 = obj(
1063                c30 = obj(
1064                    c300 = obj(
1065                        c3000 = obj(
1066                            c30000 = 4,
1067                            ),
1068                        ),
1069                    c301 = obj(
1070                        c3010 = obj(
1071                            c30100 = obj(
1072                                c301000 = 5,
1073                                ),
1074                            ),
1075                        ),
1076                    ),
1077                c31 = obj(
1078                    c310 = obj(
1079                        c3100 = obj(
1080                            c31000 = obj(
1081                                c310000 = obj(
1082                                    c3100000 = 6,
1083                                    ),
1084                                ),
1085                            ),
1086                        ),
1087                    c311 = obj(
1088                        c3110 = obj(
1089                            c31100 = obj(
1090                                c311000 = obj(
1091                                    c3110000 = obj(
1092                                        c3110000 = 7,
1093                                        )
1094                                    ),
1095                                ),
1096                            ),
1097                        ),
1098                    ),
1099                ),
1100            ),
1101        )
1102
1103    oref = obj({
1104        'a/a0':0,
1105        'a/a1/a10':1,
1106        'b/b0':0,
1107        'b/b1/b10':1,
1108        'b/b2/b20/b200':2,
1109        'b/b2/b21/b210/b2100':3,
1110        'c/c0':0,
1111        'c/c1/c10':1,
1112        'c/c2/c20/c200':2,
1113        'c/c2/c21/c210/c2100':3,
1114        'c/c3/c30/c300/c3000/c30000':4,
1115        'c/c3/c30/c301/c3010/c30100/c301000':5,
1116        'c/c3/c31/c310/c3100/c31000/c310000/c3100000':6,
1117        'c/c3/c31/c311/c3110/c31100/c311000/c3110000/c3110000':7,
1118        })
1119
1120    for k,v in oref.items():
1121        assert(o.get_path(k)==v)
1122    #end for
1123    o2 = o.serial()
1124    assert(object_eq(o2,oref))
1125
1126#end def test_extensions
1127
1128