1import unittest, Mk4py, sys
2from test import test_support
3from mktestsupport import *
4
5class Dummy:
6    def __init__(self, **kws):
7        self.__dict__.update(kws)
8
9try:
10    # new-style class declaration; fails on Python 2.1 and earlier
11    new_dummy = """class NewDummy(object):
12    def __init__(self, **kws):
13        self.__dict__.update(kws)"""
14    eval(compile(new_dummy, '', 'single'))
15except:
16    NewDummy = None
17
18class SequenceCounter:
19    def __init__(self, initial_value):
20        self.beginning = self.count = initial_value
21
22    def begin(self):
23        self.beginning = self.count
24
25    # ideally, this wants to be a generator...
26    # but then we'd have a more complex interface, and lose compatibility with
27    # older Python versions
28    def __call__(self):
29        self.count += 1
30        return self.count - 1
31
32##class StorageTestCase(unittest.TestCase):
33    #storge(), storage(file), storage(fnm, rw=[0,1,2])
34    #getas
35    #view
36    #rollback
37    #commit
38    #aside
39    #description
40    #contents
41    #autocommit
42    #load
43    #save
44##    def testX(self):
45##        pass
46
47#class WrapTestCase(unittest.TestCase):
48    #wrap(seq, props, usetuples=0) -> RO view
49    #pass
50
51class ViewerTestCase(unittest.TestCase):
52    def setUpViews(self):
53        self.s = s = Mk4py.storage()
54        self.v0 = s.getas('v0[s:S,i:I]')
55        self.v1 = s.getas('v1[s:S,f:D]')
56        self.v2 = s.getas('v2[i:I,b:M]')
57        for vals in [('a',1),('b',2),('c',3)]:
58            self.v0.append(vals)
59        for vals in [('c',1.0),('b',2.0),('a',3.0)]:
60            self.v1.append(vals)
61        for vals in [(2,'\2'),(3,'\3'),(4,'\4')]:
62            self.v2.append(vals)
63        t = self.v1.rename('s', 't')
64        self.p0 = t.product(self.v0)
65        self.g0 = self.p0.groupby(self.p0.t, self.p0.f, 'details')
66        self.f0 = self.g0.flatten(self.g0.details)
67        self.f1 = self.f0[3:]
68        self.m0 = self.f1.copy()
69        def f(row):
70            row.i = row.i + 1
71        self.m0.map(f)
72
73    def setUp(self):
74        self.setUpViews()
75        self.v0 = self.v0.unique()
76        # unique sorts, so v1 needs to be put back in reverse order
77        self.v1 = self.v1.unique().sortrev([self.v1.s],[self.v1.s])
78        self.v2 = self.v2.unique()
79        self.p0 = self.p0.unique()
80
81    def testStructure(self):
82        proplist = self.v0.structure()
83        self.assertEqual(type(proplist), type([]))
84        self.assertEqual(len(proplist), 2)
85        propdict = self.v0.properties()
86        self.assertEqual(type(propdict), type({}))
87        self.assertEqual(len(propdict), 2)
88        for prop in proplist:
89            prop2 = propdict[prop.name]
90            self.assertEqual(prop2.name, prop.name)
91            self.assertEqual(prop2.type, prop.type)
92            self.assertEqual(prop2.id, prop.id)
93
94    def testSimple(self):
95        self.assertEqual(len(self.v0),3)
96        self.assertEqual(self.v0[0].s, 'a')
97        self.assertEqual(self.v0[0].i, 1)
98        v1 = self.v0[1:]
99        self.assertEqual(len(v1), 2)
100        self.assertEqual(v1[0].s, 'b')
101        self.assertEqual(v1[0].i, 2)
102
103    def testFind(self):
104        self.assertEqual(self.v0.find(s='c'), 2)
105        self.assertEqual(self.v0.find(i=2), 1)
106        self.assertEqual(self.v0.find(s='z'), -1)
107
108    def testSearch(self):
109        #search - v0 is ordered on  s
110        self.assertEqual(self.v0.search(s='c'), 2)
111        self.assertEqual(self.v0.search(s='b'), 1)
112        self.assertEqual(self.v0.search(s='a'), 0)
113        self.assertEqual(self.v0.search(s=' '), 0)
114        self.assertEqual(self.v0.search(s='z'), 3)
115
116    def testLocate(self):
117        #locate - v0 is ordered on  s
118        self.assertEqual(self.v0.locate(s='c'), (2,1))
119        self.assertEqual(self.v0.locate(s='b'), (1,1))
120        self.assertEqual(self.v0.locate(s='a'), (0,1))
121        self.assertEqual(self.v0.locate(s=' '), (0,0))
122        self.assertEqual(self.v0.locate(s='z'), (3,0))
123
124        #itemsize
125        #self.assertEqual(v0.itemsize(v0.i), -2)
126        #self.assertEqual(v0.itemsize(v0.s, 0), 2)
127
128    def testCopy(self):
129        #copy
130        w0 = self.v0.copy()
131        self.assertEqual(len(w0), len(self.v0))
132        self.assertEqual(w0.structure(), self.v0.structure())
133        self.assertEqual(type(w0), Mk4py.ViewType)
134
135    def testConcat(self):
136        #v1 + v2
137        w0 = self.v0.copy()
138        x0 = w0 + self.v0
139        x1 = self.v0 + w0
140        self.assertEqual(len(x0), len(x1))
141        self.assertEqual(len(x0), 2*len(self.v0))
142        self.assertEqual(x0.structure(), self.v0.structure())
143        self.assertEqual(x1.structure(), self.v0.structure())
144
145    def testRepeat(self):
146        #v1 * 2
147        x1 = self.v0 * 2
148        self.assertEqual(len(x1), 2*len(self.v0))
149        self.assertEqual(x1.structure(), self.v0.structure())
150
151    def testRename(self):
152        #rename
153        self.assertEqual(self.v0.s, Mk4py.property('S','s'))
154        x2 = self.v0.rename('s', 'stringprop')
155        self.assertEqual(x2.stringprop, Mk4py.property('S','stringprop'))
156        self.assertNotEqual(x2.structure(), self.v0.structure())
157        self.assertEqual(len(x2.structure()), 2)
158        self.assertEqual(x2.i, self.v0.i)
159
160    def testSelect(self):
161        #select
162        t0 = self.v0.select(s='b')
163        self.assertEqual(len(t0), 1)
164        self.assertEqual(t0[0].s, 'b')
165        t0 = self.v0.select({'s':'a'},{'s':'b'})
166        self.assertEqual(len(t0), 2)
167        self.assertEqual(t0[1].s, 'b')
168        t0 = self.v0.select({'s':'a','i':2},{'s':'b','i':4})
169        self.assertEqual(len(t0), 1)
170        self.assertEqual(t0[0].s, 'b')
171
172    def testSort(self):
173        #sort
174        t0 = self.v0.sort()  # already in order
175        self.assertEqual(len(t0), len(self.v0))
176        for i in range(1, len(t0)):
177            self.assertEqual( cmp(t0[i-1].s,t0[i].s), -1)
178        t0 = self.v1.sort(self.v1.s)  # reverses native order
179        self.assertEqual(len(t0), len(self.v1))
180        for i in range(1, len(t0)):
181            self.assertEqual( cmp(t0[i-1].s,t0[i].s), -1)
182
183    def testSortrev(self):
184        #sortrev
185        t0 = self.v0.sortrev([self.v0.s],[self.v0.s])  # reverses order
186        self.assertEqual(len(t0), len(self.v0))
187        for i in range(1, len(t0)):
188            self.assertEqual( cmp(t0[i-1].s,t0[i].s), 1)
189        t0 = self.v1.sortrev([self.v1.s],[self.v1.s])  # native order
190        self.assertEqual(len(t0), len(self.v1))
191        for i in range(1, len(t0)):
192            self.assertEqual( cmp(t0[i-1].s,t0[i].s), 1)
193
194    def testProject(self):
195        #project
196        t0 = self.v0.project(self.v0.s)
197        s = t0.structure()
198        self.assertEqual(len(s), 1)
199        self.assertEqual(s[0], self.v0.s)
200
201    def testProduct(self):
202        #product
203        self.assertEqual(len(self.p0), 9)
204        self.assertEqual(len(self.p0.select(s='a')), 3)
205        self.assertEqual(len(self.p0.select(t='a')), 3)
206
207    def testCounts(self):
208        #counts
209        t1 = self.p0.counts(self.p0.t, self.p0.f, 'details')
210        self.assertEqual(len(t1), 3)
211        self.assertEqual(len(t1.select(t='a')), 1)
212        for i in range(len(t1)):
213            self.assertEqual(t1[i].details, len(self.v0))
214
215    def testGroupby(self):
216        #groupby
217        self.assertEqual(len(self.g0), 3)
218        self.assertEqual(len(self.g0.select(t='a')), 1)
219        for i in range(len(self.g0)):
220            self.assertEqual(len(self.g0[i].details), len(self.v0))
221            self.assertEqual(len(self.g0[i].details.select(s='a')), 1)
222
223    def testFlatten(self):
224        #flatten
225        self.assertEqual(len(self.f0), 9)
226        self.assertEqual(len(self.f0.select(s='a')), 3)
227        self.assertEqual(len(self.f0.select(t='a')), 3)
228
229    def testUnion(self):
230        #union
231        u0 = self.p0.union(self.f0)   # these 2 are the same
232        self.assertEqual(len(u0), 9)
233        self.assertEqual(len(u0.select(s='a')), 3)
234        self.assertEqual(len(u0.select(t='a')), 3)
235        u1 = self.p0.union(self.f1)   # strict subset
236        self.assertEqual(len(u1), 9)
237        u2 = self.p0.union(self.m0)
238        self.assertEqual(len(u2), len(self.p0)+len(self.m0))
239
240    def testIntersect(self):
241        #intersect
242        i0 = self.p0.intersect(self.f0)   # these 2 are the same
243        self.assertEqual(len(i0), 9)
244        self.assertEqual(len(i0.select(s='a')), 3)
245        self.assertEqual(len(i0.select(t='a')), 3)
246        i1 = self.p0.intersect(self.f1)   # strict subset
247        self.assertEqual(len(i1), len(self.f1))
248        i2 = self.p0.intersect(self.m0)
249        self.assertEqual(len(i2), 0)
250
251    def testDifferent(self):
252        #different
253        d0 = self.p0.different(self.f0)   # these 2 are the same
254        self.assertEqual(len(d0),0)
255        d1 = self.p0.different(self.f1)   # strict subset
256        self.assertEqual(len(d1), len(self.p0)-len(self.f1))
257        d2 = self.f1.different(self.p0)
258        self.assertEqual(len(d2), len(self.p0)-len(self.f1))
259        d3 = self.p0.different(self.m0)
260        self.assertEqual(len(d3), len(self.p0)+len(self.m0))
261
262    def testMinus(self):
263        #minus
264        m0 = self.p0.minus(self.f0)   # these 2 are the same
265        self.assertEqual(len(m0),0)
266        m1 = self.p0.minus(self.f1)   # strict subset
267        self.assertEqual(len(m1), len(self.p0)-len(self.f1))
268        m2 = self.f1.minus(self.p0)
269        self.assertEqual(len(m2), 0)
270        m3 = self.p0.minus(self.m0)
271        self.assertEqual(len(m3), len(self.p0))
272
273    def testJoin(self):
274        #join
275        j1 = self.v0.join(self.v1, self.v0.s)
276        self.assertEqual(len(j1),3)
277        self.assertEqual(j1[0].s, 'a')
278        self.assertEqual(j1[0].i, 1)
279        self.assertEqual(j1[0].f, 3.0)
280        j2 = self.v0.join(self.v2, self.v0.i)
281        self.assertEqual(len(j2),2)
282        self.assertEqual(j2[0].s, 'b')
283        self.assertEqual(j2[0].i, 2)
284        self.assertEqual(j2[0].b, '\2')
285        # outerjoin
286        j3 = self.v0.join(self.v2, self.v0.i, 1)
287        self.assertEqual(len(j3),3)
288        self.assertEqual(j3[0].s, 'a')
289        self.assertEqual(j3[0].i, 1)
290        self.assertEqual(j3[0].b, '')
291
292    def testIndices(self):
293        #indices
294        subset = self.p0.select(s='a')
295        iv = self.p0.indices(subset)
296        self.assertEqual(len(iv), len(subset))
297        self.assertEqual(len(iv.structure()), 1)
298        for i in range(len(iv)):
299            self.assertEqual(self.p0[iv[i].index].s, 'a')
300
301    def testRemapwith(self):
302        #remapwith
303        subset = self.p0.select(s='a')
304        iv = self.p0.indices(subset)
305        r0 = self.p0.remapwith(iv)
306        self.assertEqual(len(r0), len(iv))
307        for row in r0:
308            self.assertEqual(row.s, 'a')
309
310    def testPair(self):
311        #pair
312        p0 = self.v1.pair(self.v2)
313        self.assertEqual(len(p0), len(self.v1))
314        self.assertEqual(p0[0].s, 'c')
315        self.assertEqual(p0[0].f, 1.0)
316        self.assertEqual(p0[0].i, 2)
317        self.assertEqual(p0[0].b, '\2')
318        p1 = self.v1.pair(self.v2 * 2)
319        self.assertEqual(len(p1), len(self.v1))
320
321    def testUnique(self):
322        #unique
323        t = self.v0 * 2
324        u = t.unique()
325        self.assertEqual(len(u), len(self.v0))
326        self.assertEqual(len(u.minus(self.v0)), 0)
327
328    def testFilter(self):
329        #filter
330        t = self.v0.filter(lambda row: row.s < 'b' or row.s > 'b')
331        self.assertEqual(len(t), 2)
332        for row in t:
333            self.assertNotEqual(self.v0[row.index], 'b')
334
335    def testReduce(self):
336        #reduce
337        self.assertEqual(self.v0.reduce(lambda row, last: last+row.i), 6)
338
339class ViewTestCase(ViewerTestCase):
340    def setUp(self):
341        self.setUpViews()
342
343    def testAddProperty(self):
344        x0 = self.v0.copy()
345        x0.addproperty(Mk4py.property('I','shoesize'))
346        self.assertEqual(len(x0.structure()), 3)
347        self.assertEqual(x0.shoesize, x0.structure()[-1])
348
349    def testSetsize(self):
350        #setsize
351        x = self.v0.copy()
352        self.assertEqual(x.setsize(6), 6)
353        self.assertRaises(TypeError, x.setsize, 1, 2)
354        self.assertRaises(TypeError, x.setsize, 'a')
355        self.assertEqual(len(x), 6)
356        for row in x[3:]:
357            self.assertEqual(row.s, '')
358            self.assertEqual(row.i, 0)
359        self.assertEqual(x.setsize(0), 0)
360        self.assertEqual(len(x), 0)
361
362    def testInsert(self):
363        #insert
364        x = self.v0.copy()
365
366        # Most of insert()'s attribute handling is tested by append(),
367        # so just test the features unique to insert() here.
368        def insert(index, i):
369            a = [r.i for r in x]
370            x.insert(index, i=i)
371            if index < 0:
372                index += len(a) # default behavior in Python 2.3 and later
373            a.insert(index, i)
374            self.assertEqual(a, [r.i for r in x])
375
376        insert(0, 7)
377        insert(1, 4)
378        insert(2, 8)
379        insert(-1, 6)
380        insert(-2, 9)
381        insert(500, 48)
382        insert(MAXINT, 300)
383        insert(MININT, 21)
384        self.assertRaises(TypeError, x.insert, 'hi', i=2)
385        self.assertRaises(TypeError, x.insert, None, i=2)
386        self.assertRaises(TypeError, x.insert)
387        self.assertRaises(int_long_error, x.insert, MAXINT + 1, i=2)
388        self.assertRaises(int_long_error, x.insert, MININT - 1, i=2)
389
390    def testAppend(self):
391        #append
392        x = self.v0.copy()
393        c = SequenceCounter(3)
394
395        self.assertEqual(x.append(['hi', 2]), c())
396        self.assertRaises(TypeError, x.append, 1, 2)
397        self.assertRaises(IndexError, x.append, [1, 2, 3]) # could also be TypeError
398        self.assertRaises(IndexError, x.append, 'abc')
399        self.assertRaises(IndexError, x.append, ['hi', 2, 3])
400        self.assertEqual(x.append(s='hi',i=2), c())
401        self.assertEqual(x.append(i=2,s='hi'), c())
402        self.assertRaises(TypeError, x.append, [1, 's'])
403        self.assertRaises(TypeError, x.append, ['s', 't'])
404        self.assertRaises(TypeError, x.append, 'hi')
405        self.assertEqual(x.append(('hi', 2)), c())
406        self.assertEqual(x.append(Dummy(s='hi', i=2)), c())
407        self.assertEqual(x.append(Dummy(s='hi', i=2, j=4)), c())
408        self.assertRaises(TypeError, x.append, Dummy(s=1))
409        self.assertRaises(TypeError, x.append, Dummy(s=Dummy()))
410        if NewDummy:
411            self.assertEqual(x.append(NewDummy(s='hi', i=2)), c())
412            self.assertEqual(x.append(NewDummy(s='hi', i=2, j=4)), c())
413            self.assertRaises(TypeError, x.append, NewDummy(s=1))
414            self.assertRaises(TypeError, x.append, NewDummy(s=NewDummy()))
415        for row in x[c.beginning:]:
416            self.assertEqual(row.s, 'hi')
417            self.assertEqual(row.i, 2)
418
419        c.begin()
420        self.assertEqual(x.append(s='hi'), c())
421        self.assertEqual(x.append(s='hi',j=2), c())
422        self.assertEqual(x.append(['hi']), c())
423        self.assertRaises(TypeError, x.append, [1])
424        self.assertRaises(TypeError, x.append, 1)
425        self.assertEqual(x.append(Dummy(s='hi')), c())
426        self.assertEqual(x.append(Dummy(s='hi', j=2)), c())
427        if NewDummy:
428            self.assertEqual(x.append(NewDummy(s='hi')), c())
429            self.assertEqual(x.append(NewDummy(s='hi', j=2)), c())
430        for row in x[c.beginning:]:
431            self.assertEqual(row.s, 'hi')
432            self.assertEqual(row.i, 0)
433
434        c.begin()
435        self.assertEqual(x.append(), c())
436        self.assertEqual(x.append(()), c())
437        self.assertEqual(x.append(Dummy()), c())
438        self.assertEqual(x.append(Dummy(k=Dummy())), c())
439        if NewDummy:
440            self.assertEqual(x.append(NewDummy()), c())
441            self.assertEqual(x.append(NewDummy(k=NewDummy())), c())
442        for row in x[c.beginning:]:
443            self.assertEqual(row.s, '')
444            self.assertEqual(row.i, 0)
445
446        # XXX test 'L', 'D', 'M'/'B' types
447        # XXX test other view types (necessary?)
448
449        #delete
450        #remove
451        #map
452        #v[n] = x
453        #v[m:n] = x
454        #hash
455        #blocked
456        #ordered
457        #indexed
458
459        #access
460        #modify
461
462
463class RORowRefTestCase(unittest.TestCase):
464    def setUp(self):
465        self.setUpView()
466        self.v = self.v.unique()
467    def setUpView(self):
468        self.s = s = Mk4py.storage()
469        self.v = v = s.getas('test[i:I,l:L,f:F,d:D,s:S,v[s:S],b:B,m:M]')
470        v.append()
471    def testProperties(self):
472        plist = self.v.structure()
473        pdict = self.v.properties()
474        for prop in plist:
475            self.assertEqual(prop, pdict[prop.name])
476            self.assertEqual(prop, getattr(self.v, prop.name))
477    def testType(self):
478        self.assertEqual(type(self.v[0]), Mk4py.RORowRefType)
479    def testGetAttr(self):
480        r = self.v[0]
481        attrs = r.__attrs__
482        self.assertEqual(len(attrs), 8)
483        self.assertEqual(attrs[0].name, 'i')
484        self.assertEqual(attrs[0].type, 'I')
485        self.assertEqual(attrs[0].id, Mk4py.property('I','i').id)
486        self.assertEqual(attrs[7].name, 'm')
487        self.assertEqual(attrs[7].type, 'B')
488        self.assertEqual(attrs[7].id, Mk4py.property('M','m').id)
489        #self.assertEqual(r.__view__, v)    what's r.__view__ good for??
490        self.assertEqual(r.__index__, 0)
491        self.assertEqual(r.i, 0)
492        self.assertEqual(r.l, 0)
493        self.assertEqual(r.f, 0.0)
494        self.assertEqual(r.d, 0.0)
495        self.assertEqual(r.s, '')
496        self.assertEqual(len(r.v, ), 0)
497        self.assertEqual(type(r.v), Mk4py.ViewType)
498        self.assertEqual(r.b, '')
499        self.assertEqual(r.m, '')
500    def testSetAttr(self):
501        v = self.v.unique()
502        r = v[0]
503        self.assertRaises(TypeError, setattr, (r, 'i', 1))
504
505class RowRefTestCase(RORowRefTestCase):
506    def setUp(self):
507        self.setUpView()
508    def testType(self):
509        self.assertEqual(type(self.v[0]), Mk4py.RowRefType)
510    def testSetAttr(self):
511        r = self.v[0]
512
513        #setattr I - int, castable to int
514        r.i = 3
515        self.assertEqual(r.i, 3)
516        self.assertEqual(type(r.i), int)
517        try:
518            r.i = True
519        except NameError:
520            pass
521        else:
522            self.assertEqual(r.i, 1)
523            self.assertEqual(type(r.i), int)
524        r.i = 8.0
525        self.assertEqual(r.i, 8)
526        self.assertEqual(type(r.i), int)
527        r.i = 8.9
528        self.assertEqual(r.i, 8)
529        self.assertEqual(type(r.i), int)
530        self.assertRaises(TypeError, setattr, (r, 'i', '1'))
531
532        #        L - int, long, castable to long
533        r.l = 3L
534        self.assertEqual(r.l, 3)
535        self.assertEqual(type(r.l), long)
536        try:
537            r.l = True
538        except NameError:
539            pass
540        else:
541            self.assertEqual(r.l, 1)
542            self.assertEqual(type(r.l), long)
543        r.l = 8.0
544        self.assertEqual(r.l, 8)
545        self.assertEqual(type(r.l), long)
546        r.l = 8.9
547        self.assertEqual(r.l, 8)
548        self.assertEqual(type(r.l), long)
549        try:
550            bignum = sys.maxint + 1
551        except OverflowError:
552            pass
553        else:
554            r.l = bignum
555            self.assertEqual(r.l, bignum)
556        self.assertRaises(TypeError, setattr, (r, 'l', '1'))
557
558        #        F - float, castable to double
559        r.f = 1.0
560        self.assertEqual(r.f, 1.0)
561        r.f = 1
562        self.assertEqual(r.f, 1.0)
563        self.assertEqual(type(r.f), float)
564        self.assertRaises(TypeError, setattr, (r, 'f', '1.0'))
565
566        #        D - float, castable to double
567        r.d = 1.0
568        self.assertEqual(r.d, 1.0)
569        r.d = 1
570        self.assertEqual(r.d, 1.0)
571        self.assertEqual(type(r.d), float)
572        self.assertRaises(TypeError, setattr, (r, 'd', '1.0'))
573
574        #        S - string
575        s = 'a string'
576        r.s = s
577        self.assertEqual(r.s, s)
578        r.s = s*50
579        self.assertEqual(r.s, s*50)
580        self.assertRaises(TypeError, setattr, (r, 's', 1.0))
581
582        #        V - view, sequence
583        r.v = []
584        self.assertEqual(len(r.v), 0)
585        r.v = [('a',),('b',)]
586        self.assertEqual(len(r.v), 2)
587        self.assertEqual(r.v[0].s, 'a')
588        self.assertEqual(r.v[1].s, 'b')
589        #special case where subview has only one property
590        r.v = ['a','b']
591        self.assertEqual(len(r.v), 2)
592        self.assertEqual(r.v[0].s, 'a')
593        self.assertEqual(r.v[1].s, 'b')
594        r.v = [{'s':'a'},{'s':'b'}]
595        self.assertEqual(len(r.v), 2)
596        self.assertEqual(r.v[0].s, 'a')
597        self.assertEqual(r.v[1].s, 'b')
598        r.v = [Dummy(s='a'),Dummy(s='b')]
599        self.assertEqual(len(r.v), 2)
600        self.assertEqual(r.v[0].s, 'a')
601        self.assertEqual(r.v[1].s, 'b')
602
603        #        B,M - string
604        s = '\0a\0binary\1string'
605        r.b = s
606        self.assertEqual(r.b, s)
607        r.b = s*50
608        self.assertEqual(r.b, s*50)
609        self.assertRaises(TypeError, setattr, (r, 'b', 1.0))
610        r.m = s
611        self.assertEqual(r.m, s)
612        r.m = s*50
613        self.assertEqual(r.m, s*50)
614        self.assertRaises(TypeError, setattr, (r, 'm', 1.0))
615
616def test_main():
617    l = [ unittest.makeSuite(RORowRefTestCase),
618          unittest.makeSuite(RowRefTestCase),
619          unittest.makeSuite(ViewerTestCase),
620          unittest.makeSuite(ViewTestCase), ]
621    suite = unittest.TestSuite(l)
622    test_support.run_suite(suite)
623
624if __name__ == '__main__':
625    test_main()
626