1import codecs 2import datetime 3import os 4import sys 5import unittest 6import tempfile 7import shutil 8import stat 9import warnings 10from unittest import skipIf, skipUnless, TestCase as unittest_TestCase 11 12py_ver = sys.version_info[:2] 13module = globals() 14 15from dbf import * 16import dbf 17 18try: 19 import pytz 20except ImportError: 21 pytz = None 22 23if py_ver < (3, 0): 24 MISC = ''.join([chr(i) for i in range(256)]) 25 PHOTO = ''.join(reversed([chr(i) for i in range(256)])) 26else: 27 unicode = str 28 xrange = range 29 module.update(dbf.LatinByte.__members__) 30 MISC = ''.join([chr(i) for i in range(256)]).encode('latin-1') 31 PHOTO = ''.join(reversed([chr(i) for i in range(256)])).encode('latin-1') 32 33try: 34 with warnings.catch_warnings(): 35 warnings.warn('test if warning is an exception', dbf.DbfWarning, stacklevel=1) 36 warnings_are_exceptions = False 37except dbf.DbfWarning: 38 warnings_are_exceptions = True 39 40print("\nTesting dbf version %d.%02d.%03d on %s with Python %s\n" % ( 41 dbf.version[:3] + (sys.platform, sys.version) )) 42 43 44class TestCase(unittest_TestCase): 45 46 def __init__(self, *args, **kwds): 47 regex = getattr(self, 'assertRaisesRegex', None) 48 if regex is None: 49 self.assertRaisesRegex = getattr(self, 'assertRaisesRegexp') 50 super(TestCase, self).__init__(*args, **kwds) 51 52 53# Walker in Leaves -- by Scot Noel -- http://www.scienceandfantasyfiction.com/sciencefiction/Walker-in-Leaves/walker-in-leaves.htm 54 55words = """ 56Soft rains, given time, have rounded the angles of great towers. Generation after generation, wind borne seeds have brought down cities amid the gentle tangle of their roots. All statues of stone have been worn away. 57Still one statue, not of stone, holds its lines against the passing years. 58Sunlight, fading autumn light, warms the sculpture as best it can, almost penetrating to its dreaming core. The figure is that of a woman, once the fair sex of a species now untroubled and long unseen. Man sleeps the sleep of extinction. This one statue remains. Behind the grace of its ivory brow and gentle, unseeing eyes, the statue dreams. 59A susurrus of voices, a flutter of images, and the dream tumbles down through the long morning. Suspended. Floating on the stream that brings from the heart of time the wandering self. Maya for that is the statue s name-- is buoyed by the sensation, rising within the cage of consciousness, but asleep. She has been this way for months: the unmoving figure of a woman caught in mid stride across the glade. The warmth of sunlight on her face makes her wonder if she will ever wake again. 60Even at the end, there was no proper word for what Maya has become. Robot. Cybernetic Organism. Android. These are as appropriate to her condition as calling the stars campfires of the night sky and equally precise. It is enough to know that her motive energies are no longer sun and sustenance, and though Maya was once a living woman, a scientist, now she inhabits a form of ageless attraction. It is a form whose energies are flagging. 61With great determination, Maya moves toward wakefulness. Flex a finger. Move a hand. Think of the lemurs, their tongues reaching out in stroke after stroke for the drip of the honeyed thorns. Though there is little time left to save her charges, Maya s only choice is the patience of the trees. On the day her energies return, it is autumn of the year following the morning her sleep began. Maya opens her eyes. The woman, the frozen machine --that which is both-- moves once more. 62Two lemur cubs tumbling near the edge of the glade take notice. One rushes forward to touch Maya s knee and laugh. Maya reaches out with an arthritic hand, cold in its sculpted smoothness, but the lemur darts away. Leaves swirl about its retreat, making a crisp sound. The cub displays a playfulness Maya s fevered mind cannot match. The second cub rolls between her moss covered feet, laughing. The lemurs are her charges, and she is failing them. Still, it is good to be awake. 63Sugar maples and sumacs shoulder brilliant robes. In the low sun, their orange and purple hues startle the heart. Of course, Maya has no beating organ, no heart. Her life energies are transmitted from deep underground. Nor are the cubs truly lemurs, nor the sugar maples the trees of old. The names have carried for ten million seasons, but the species have changed. Once the lemurs inhabited an island off the southeast coast of a place called Africa. Now they are here, much changed, in the great forests of the northern climes. 64The young lemurs seem hale, and it speaks well for their consanguine fellows. But their true fate lies in the story of DNA, of a few strands in the matriarchal line, of a sequence code-named "hope." No doubt a once clever acronym, today Maya s clouded mind holds nothing of the ancient codes. She knows only that a poet once spoke of hope as "the thing with feathers that perches in the soul." Emily Dickinson. A strange name, and so unlike the agnomen of the lemurs. What has become of Giver-of-Corn? 65Having no reason to alarm the cubs, Maya moves with her hands high, so that any movement will be down as leaves fall. Though anxious about Giver-of-Corn, she ambles on to finish the mission begun six months earlier. Ahead, the shadow of a mound rises up beneath a great oak. A door awaits. Somewhere below the forest, the engine that gives her life weakens. Held in sway to its faltering beat her mind and body froze, sending her into an abyss of dreams. She has been striding toward that door for half a year, unknowing if she would ever wake again. 66Vines lose their toughened grip as the door responds to Maya s approach. Regretfully, a tree root snaps, but the door shudders to a halt before its whine of power can cross the glade. Suddenly, an opening has been made into the earth, and Maya steps lightly on its downward slope. Without breathing, she catches a scent of mold and of deep, uncirculated water. A flutter like the sound of wings echoes from the hollow. Her vision adjusts as she descends. In spots, lights attempt to greet her, but it is a basement she enters, flickering and ancient, where the footfalls of millipedes wear tracks in grime older than the forest above. After a long descent, she steps into water. 67How long ago was it that the floor was dry? The exactitude of such time, vast time, escapes her. 68Once this place sustained great scholars, scientists. Now sightless fish skip through broken walls, retreating as Maya wades their private corridors, finding with each step that she remembers the labyrinthine path to the heart of power. A heart that flutters like dark wings. And with it, she flutters too. The closer she comes to the vault in which the great engine is housed, the less hopeful she becomes. 69The vault housing the engine rests beneath a silvered arch. Its mirrored surface denies age, even as a new generation of snails rise up out of the dark pool, mounting first the dais of pearled stone left by their ancestors, the discarded shells of millions, then higher to where the overhang drips, layered in egg sacs bright as coral. 70Maya has no need to set the vault door in motion, to break the dance of the snails. The state of things tells her all she needs to know. There shall be no repairs, no rescue; the engine will die, and she with it. Still, it is impossible not to check. At her touch, a breath of firefly lights coalesces within the patient dampness of the room. They confirm. The heart is simply too tired to go on. Its last reserves wield processes of great weight and care, banking the fires of its blood, dimming the furnace into safe resolve. Perhaps a month or two in cooling, then the last fire kindled by man shall die. 71For the figure standing knee deep in water the issues are more immediate. The powers that allow her to live will be the first to fade. It is amazing, even now, that she remains cognizant. 72For a moment, Maya stands transfixed by her own reflection. The silvered arch holds it as moonlight does a ghost. She is a sculpted thing with shoulders of white marble. Lips of stone. A child s face. No, the grace of a woman resides in the features, as though eternity can neither deny the sage nor touch the youth. Demeter. The Earth Mother. 73Maya smiles at the Greek metaphor. She has never before thought of herself as divine, nor monumental. When the energies of the base are withdrawn entirely, she will become immobile. Once a goddess, then a statue to be worn away by endless time, the crumbling remnant of something the self has ceased to be. Maya trembles at the thought. The last conscious reserve of man will soon fade forever from the halls of time. 74As if hewn of irresolute marble, Maya begins to shake; were she still human there would be sobs; there would be tears to moisten her grief and add to the dark waters at her feet. 75In time, Maya breaks the spell. She sets aside her grief to work cold fingers over the dim firefly controls, giving what priorities remain to her survival. In response, the great engine promises little, but does what it can. 76While life remains, Maya determines to learn what she can of the lemurs, of their progress, and the fate of the matriarchal line. There will be time enough for dreams. Dreams. The one that tumbled down through the long morning comes to her and she pauses to consider it. There was a big table. Indistinct voices gathered around it, but the energy of a family gathering filled the space. The warmth of the room curled about her, perfumed by the smell of cooking. An ancient memory, from a time before the shedding of the flesh. Outside, children laughed. A hand took hers in its own, bringing her to a table filled with colorful dishes and surrounded by relatives and friends. Thanksgiving? 77They re calling me home, Maya thinks. If indeed her ancestors could reach across time and into a form not of the flesh, perhaps that was the meaning of the dream. I am the last human consciousness, and I am being called home. 78With a flutter, Maya is outside, and the trees all but bare of leaves. Something has happened. Weeks have passed and she struggles to take in her situation. This time she has neither dreamed nor stood immobile, but she has been active without memory. 79Her arms cradle a lemur, sheltering the pubescent female against the wind. They sit atop a ridge that separates the valley from the forest to the west, and Walker-in-Leaves has been gone too long. That much Maya remembers. The female lemur sighs. It is a rumbling, mournful noise, and she buries her head tighter against Maya. This is Giver-of-Corn, and Walker is her love. 80With her free hand, Maya works at a stiff knitting of pine boughs, the blanket which covers their legs. She pulls it up to better shelter Giver-of-Corn. Beside them, on a shell of bark, a sliver of fish has gone bad from inattention. 81They wait through the long afternoon, but Walker does not return. When it is warmest and Giver sleeps, Maya rises in stages, gently separating herself from the lemur. She covers her charge well. Soon it will snow. 82There are few memories after reaching the vault, only flashes, and that she has been active in a semi-consciousness state frightens Maya. She stumbles away, shaking, but there is no comfort to seek. She does not know if her diminished abilities endanger the lemurs, and considers locking herself beneath the earth. But the sun is warm, and for the moment every thought is a cloudless sky. Memories descend from the past like a lost tribe wandering for home. 83To the east lie once powerful lands and remembered sepulchers. The life of the gods, the pulse of kings, it has all vanished and gone. Maya thinks back to the days of man. There was no disaster at the end. Just time. Civilization did not fail, it succumbed to endless seasons. Each vast stretch of years drawn on by the next saw the conquest of earth and stars, then went on, unheeding, until man dwindled and his monuments frayed. 84To the west rise groves of oaks and grassland plains, beyond them, mountains that shrugged off civilization more easily than the rest. 85Where is the voyager in those leaves? 86A flash of time and Maya finds herself deep in the forests to the west. A lemur call escapes her throat, and suddenly she realizes she is searching for Walker-in-Leaves. The season is the same. Though the air is crisp, the trees are not yet unburdened of their color. 87"Walker!" she calls out. "Your love is dying. She mourns your absence." 88At the crest of a rise, Maya finds another like herself, but one long devoid of life. This sculpted form startles her at first. It has been almost wholly absorbed into the trunk of a great tree. The knee and calf of one leg escape the surrounding wood, as does a shoulder, the curve of a breast, a mournful face. A single hand reaches out from the tree toward the valley below. 89In the distance, Maya sees the remnants of a fallen orbiter. Its power nacelle lies buried deep beneath the river that cushioned its fall. Earth and water, which once heaved at the impact, have worn down impenetrable metals and grown a forest over forgotten technologies. 90Had the watcher in the tree come to see the fall, or to stand vigil over the corpse? Maya knows only that she must go on before the hills and the trees conspire to bury her. She moves on, continuing to call for Walker-in-Leaves. 91In the night, a coyote finally answers Maya, its frenetic howls awakening responses from many cousins, hunting packs holding court up and down the valley. 92Giver-of-Corn holds the spark of her generation. It is not much. A gene here and there, a deep manipulation of the flesh. The consciousness that was man is not easy to engender. Far easier to make an eye than a mind to see. Along a path of endless complication, today Giver-of-Corn mourns the absence of her mate. That Giver may die of such stubborn love before passing on her genes forces Maya deeper into the forest, using the last of her strength to call endlessly into the night. 93Maya is dreaming. It s Thanksgiving, but the table is cold. The chairs are empty, and no one answers her call. As she walks from room to room, the lights dim and it begins to rain within the once familiar walls. 94When Maya opens her eyes, it is to see Giver-of-Corm sleeping beneath a blanket of pine boughs, the young lemur s bushy tail twitching to the rhythm of sorrowful dreams. Maya is awake once more, but unaware of how much time has passed, or why she decided to return. Her most frightening thought is that she may already have found Walker-in-Leaves, or what the coyotes left behind. 95Up from the valley, two older lemurs walk arm in arm, supporting one another along the rise. They bring with them a twig basket and a pouch made of hide. The former holds squash, its hollowed interior brimming with water, the latter a corn mash favored by the tribe. They are not without skills, these lemurs. Nor is language unknown to them. They have known Maya forever and treat her, not as a god, but as a force of nature. 96With a few brief howls, by clicks, chatters, and the sweeping gestures of their tails, the lemurs make clear their plea. Their words all but rhyme. Giver-of-Corn will not eat for them. Will she eat for Maya? 97Thus has the mission to found a new race come down to this: with her last strength, Maya shall spoon feed a grieving female. The thought strikes her as both funny and sad, while beyond her thoughts, the lemurs continue to chatter. 98Scouts have been sent, the elders assure Maya, brave sires skilled in tracking. They hope to find Walker before the winter snows. Their voices stir Giver, and she howls in petty anguish at her benefactors, then disappears beneath the blanket. The elders bow their heads and turn to go, oblivious of Maya s failures. 99Days pass upon the ridge in a thickness of clouds. Growing. Advancing. Dimmed by the mountainous billows above, the sun gives way to snow, and Maya watches Giver focus ever more intently on the line to the west. As the lemur s strength fails, her determination to await Walker s return seems to grow stronger still. 100Walker-in-Leaves holds a spark of his own. He alone ventures west after the harvest. He has done it before, always returning with a colored stone, a bit of metal, or a flower never before seen by the tribe. It is as if some mad vision compels him, for the journey s end brings a collection of smooth and colored booty to be arranged in a crescent beneath a small monolith Walker himself toiled to raise. Large stones and small, the lemur has broken two fingers of its left hand doing this. To Maya, it seems the ambition of butterflies and falling leaves, of no consequence beyond a motion in the sun. The only importance now is to keep the genes within Giver alive. 101Long ago, an ambition rose among the last generation of men, of what had once been men: to cultivate a new consciousness upon the Earth. Maya neither led nor knew the masters of the effort, but she was there when the first prosimians arrived, fresh from their land of orchids and baobabs. Men gathered lemurs and said to them "we shall make you men." Long years followed in the work of the genes, gentling the generations forward. Yet with each passing season, the cultivators grew fewer and their skills less true. So while the men died of age, or boredom, or despair, the lemurs prospered in their youth. 102To warm the starving lemur, Maya builds a fire. For this feat the tribe has little skill, nor do they know zero, nor that a lever can move the world. She holds Giver close and pulls the rough blanket of boughs about them both. 103All this time, Maya s thoughts remain clear, and the giving of comfort comforts her as well. 104The snow begins to cover the monument Walker-in-Leaves has built upon the ridge. As Maya stares on and on into the fire, watching it absorb the snow, watching the snow conquer the cold stones and the grasses already bowed under a cloak of white, she drifts into a flutter of reverie, a weakening of consciousness. The gate to the end is closing, and she shall never know never know. 105"I ll take it easy like, an stay around de house this winter," her father said. "There s carpenter work for me to do." 106Other voices joined in around a table upon which a vast meal had been set. Thanksgiving. At the call of their names, the children rushed in from outside, their laughter quick as sunlight, their jackets smelling of autumn and leaves. Her mother made them wash and bow their heads in prayer. Those already seated joined in. 107Grandmother passed the potatoes and called Maya her little kolache, rattling on in a series of endearments and concerns Maya s ear could not follow. Her mother passed on the sense of it and reminded Maya of the Czech for Thank you, Grandma. 108It s good to be home, she thinks at first, then: where is the walker in those leaves? 109A hand on which two fingers lay curled by the power of an old wound touches Maya. It shakes her, then gently moves her arms so that its owner can pull back the warm pine boughs hiding Giver-of Corn. Eyes first, then smile to tail, Giver opens herself to the returning wanderer. Walker-in-Leaves has returned, and the silence of their embrace brings the whole of the ridge alive in a glitter of sun-bright snow. Maya too comes awake, though this time neither word nor movement prevails entirely upon the fog of sleep. 110When the answering howls come to the ridge, those who follow help Maya to stand. She follows them back to the shelter of the valley, and though she stumbles, there is satisfaction in the hurried gait, in the growing pace of the many as they gather to celebrate the return of the one. Songs of rejoicing join the undisciplined and cacophonous barks of youth. Food is brought, from the deep stores, from the caves and their recesses. Someone heats fish over coals they have kept sheltered and going for months. The thought of this ingenuity heartens Maya. 111A delicacy of honeyed thorns is offered with great ceremony to Giver-of-Corn, and she tastes at last something beyond the bitterness of loss. 112Though Walker-in-Leaves hesitates to leave the side of his love, the others demand stories, persuading him to the center where he begins a cacophonous song of his own. 113Maya hopes to see what stones Walker has brought from the west this time, but though she tries to speak, the sounds are forgotten. The engine fades. The last flicker of man s fire is done, and with it the effort of her desires overcome her. She is gone. 114Around a table suited for the Queen of queens, a thousand and a thousand sit. Mother to daughter, side-by-side, generation after generation of lemurs share in the feast. Maya is there, hearing the excited voices and the stern warnings to prayer. To her left and her right, each daughter speaks freely. Then the rhythms change, rising along one side to the cadence of Shakespeare and falling along the other to howls the forest first knew. 115Unable to contain herself, Maya rises. She pushes on toward the head of a table she cannot see, beginning at last to run. What is the height her charges have reached? How far have they advanced? Lemur faces turn to laugh, their wide eyes joyous and amused. As the generations pass, she sees herself reflected in spectacles, hears the jangle of bracelets and burnished metal, watches matrons laugh behind scarves of silk. Then at last, someone with sculpted hands directs her outside, where the other children are at play in the leaves, now and forever. 116THE END""".split() 117 118# data 119numbers = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541] 120floats = [] 121last = 1 122for number in numbers: 123 floats.append(float(number ** 2 / last)) 124 last = number 125 126def permutate(Xs, N): 127 if N <= 0: 128 yield [] 129 return 130 for x in Xs: 131 for sub in permutate(Xs, N-1): 132 result = [x]+sub # don't allow duplicates 133 for item in result: 134 if result.count(item) > 1: 135 break 136 else: 137 yield result 138 139def combinate(Xs, N): 140 """Generate combinations of N items from list Xs""" 141 if N == 0: 142 yield [] 143 return 144 for i in xrange(len(Xs)-N+1): 145 for r in combinate(Xs[i+1:], N-1): 146 yield [Xs[i]] + r 147 148def index(sequence): 149 "returns integers 0 - len(sequence)" 150 for i in xrange(len(sequence)): 151 yield i 152 153# tests 154def active(rec): 155 if is_deleted(rec): 156 return DoNotIndex 157 return dbf.recno(rec) 158 159def inactive(rec): 160 if is_deleted(rec): 161 return recno(rec) 162 return DoNotIndex 163 164def unicodify(data): 165 if isinstance(data, list): 166 for i, item in enumerate(data): 167 data[i] = unicode(item) 168 return data 169 elif isinstance(data, dict): 170 new_data = {} 171 for k, v in data.items(): 172 new_data[unicode(k)] = v 173 return new_data 174 else: 175 raise TypeError('unknown type: %r' % (data, )) 176 177class TestChar(TestCase): 178 179 def test_exceptions(self): 180 "exceptions" 181 self.assertRaises(ValueError, Char, 7) 182 self.assertRaises(ValueError, Char, [u'nope']) 183 self.assertRaises(ValueError, Char, True) 184 self.assertRaises(ValueError, Char, False) 185 self.assertRaises(ValueError, Char, type) 186 self.assertRaises(ValueError, Char, str) 187 self.assertRaises(ValueError, Char, None) 188 189 def test_bools_and_none(self): 190 "booleans and None" 191 empty = Char() 192 self.assertFalse(bool(empty)) 193 one = Char(u' ') 194 self.assertFalse(bool(one)) 195 actual = Char(u'1') 196 self.assertTrue(bool(actual)) 197 198 def test_equality(self): 199 "equality" 200 a1 = Char(u'a') 201 a2 = u'a ' 202 self.assertEqual(a1, a2) 203 self.assertEqual(a2, a1) 204 a3 = u'a ' 205 a4 = Char(u'a ') 206 self.assertEqual(a3, a4) 207 self.assertEqual(a4, a3) 208 209 def test_inequality(self): 210 "inequality" 211 a1 = Char(u'ab ') 212 a2 = u'a b' 213 self.assertNotEqual(a1, a2) 214 self.assertNotEqual(a2, a1) 215 a3 = u'ab ' 216 a4 = Char(u'a b') 217 self.assertNotEqual(a3, a4) 218 self.assertNotEqual(a4, a3) 219 220 def test_less_than(self): 221 "less-than" 222 a1 = Char(u'a') 223 a2 = u'a ' 224 self.assertFalse(a1 < a2) 225 self.assertFalse(a2 < a1) 226 a3 = u'a ' 227 a4 = Char(u'a ') 228 self.assertFalse(a3 < a4) 229 self.assertFalse(a4 < a3) 230 a5 = u'abcd' 231 a6 = u'abce' 232 self.assertTrue(a5 < a6) 233 self.assertFalse(a6 < a5) 234 235 def test_less_than_equal(self): 236 "less-than or equal" 237 a1 = Char(u'a') 238 a2 = u'a ' 239 self.assertTrue(a1 <= a2) 240 self.assertTrue(a2 <= a1) 241 a3 = u'a ' 242 a4 = Char(u'a ') 243 self.assertTrue(a3 <= a4) 244 self.assertTrue(a4 <= a3) 245 a5 = u'abcd' 246 a6 = u'abce' 247 self.assertTrue(a5 <= a6) 248 self.assertFalse(a6 <= a5) 249 250 def test_greater_than(self): 251 "greater-than or equal" 252 a1 = Char(u'a') 253 a2 = u'a ' 254 self.assertTrue(a1 >= a2) 255 self.assertTrue(a2 >= a1) 256 a3 = u'a ' 257 a4 = Char(u'a ') 258 self.assertTrue(a3 >= a4) 259 self.assertTrue(a4 >= a3) 260 a5 = u'abcd' 261 a6 = u'abce' 262 self.assertFalse(a5 >= a6) 263 self.assertTrue(a6 >= a5) 264 265 def test_greater_than_equal(self): 266 "greater-than" 267 a1 = Char(u'a') 268 a2 = u'a ' 269 self.assertFalse(a1 > a2) 270 self.assertFalse(a2 > a1) 271 a3 = u'a ' 272 a4 = Char(u'a ') 273 self.assertFalse(a3 > a4) 274 self.assertFalse(a4 > a3) 275 a5 = u'abcd' 276 a6 = u'abce' 277 self.assertFalse(a5 > a6) 278 self.assertTrue(a6 > a5) 279 280 281class TestDateTime(TestCase): 282 "Testing Date" 283 284 def test_date_creation(self): 285 "Date creation" 286 self.assertEqual(Date(), NullDate) 287 self.assertEqual(Date.fromymd(' '), NullDate) 288 self.assertEqual(Date.fromymd('00000000'), NullDate) 289 self.assertEqual(Date.fromordinal(0), NullDate) 290 self.assertEqual(Date.today(), datetime.date.today()) 291 self.assertEqual(Date.max, datetime.date.max) 292 self.assertEqual(Date.min, datetime.date.min) 293 self.assertEqual(Date(2018, 5, 21), datetime.date(2018, 5, 21)) 294 self.assertEqual(Date.strptime('2018-01-01'), datetime.date(2018, 1, 1)) 295 self.assertRaises(ValueError, Date.fromymd, '00000') 296 self.assertRaises(ValueError, Date, 0, 0, 0) 297 298 def test_date_compare(self): 299 "Date comparisons" 300 nodate1 = Date() 301 nodate2 = Date() 302 date1 = Date.fromordinal(1000) 303 date2 = Date.fromordinal(2000) 304 date3 = Date.fromordinal(3000) 305 self.compareTimes(nodate1, nodate2, date1, date2, date3) 306 307 def test_datetime_creation(self): 308 "DateTime creation" 309 self.assertEqual(DateTime(), NullDateTime) 310 self.assertEqual(DateTime.fromordinal(0), NullDateTime) 311 self.assertTrue(DateTime.today()) 312 self.assertEqual(DateTime.max, datetime.datetime.max) 313 self.assertEqual(DateTime.min, datetime.datetime.min) 314 self.assertEqual(DateTime(2018, 5, 21, 19, 17, 16), datetime.datetime(2018, 5, 21, 19, 17 ,16)) 315 self.assertEqual(DateTime.strptime('2018-01-01 19:17:16'), datetime.datetime(2018, 1, 1, 19, 17, 16)) 316 317 def test_datetime_compare(self): 318 "DateTime comparisons" 319 nodatetime1 = DateTime() 320 nodatetime2 = DateTime() 321 datetime1 = DateTime.fromordinal(1000) 322 datetime2 = DateTime.fromordinal(20000) 323 datetime3 = DateTime.fromordinal(300000) 324 self.compareTimes(nodatetime1, nodatetime2, datetime1, datetime2, datetime3) 325 326 def test_datetime_replace(self): 327 "DateTime replacements" 328 datetime_target = DateTime(2001, 5, 31, 23, 59, 59, 999000) 329 datetime1 = datetime.datetime(2001, 5, 31, 23, 59, 59, 999230) 330 datetime2 = datetime.datetime(2001, 5, 31, 23, 59, 59, 999500) 331 datetime3 = datetime.datetime(2001, 5, 31, 23, 59, 59, 999728) 332 original_datetime = datetime.datetime 333 for dt in (datetime1, datetime2, datetime3): 334 class DateTimeNow(datetime.datetime): 335 @classmethod 336 def now(self): 337 datetime.datetime = original_datetime 338 return dt 339 datetime.datetime = DateTimeNow 340 result = DateTime.now() 341 self.assertEqual(result, datetime_target, 'in: %r out: %r desired: %r' % (dt, result, datetime_target)) 342 343 def test_time_creation(self): 344 "Time creation" 345 self.assertEqual(Time(), NullTime) 346 self.assertEqual(Time.max, datetime.time.max) 347 self.assertEqual(Time.min, datetime.time.min) 348 self.assertEqual(Time(19, 17, 16), datetime.time(19, 17 ,16)) 349 self.assertEqual(Time.strptime('19:17:16'), datetime.time(19, 17, 16)) 350 351 def test_time_compare(self): 352 "Time comparisons" 353 notime1 = Time() 354 notime2 = Time() 355 time1 = Time.fromfloat(7.75) 356 time2 = Time.fromfloat(9.5) 357 time3 = Time.fromfloat(16.25) 358 self.compareTimes(notime1, notime2, time1, time2, time3) 359 360 @unittest.skipIf(pytz is None, 'pytz not installed') 361 def test_datetime_tz(self): 362 "DateTime with Time Zones" 363 pst = pytz.timezone('America/Los_Angeles') 364 mst = pytz.timezone('America/Boise') 365 cst = pytz.timezone('America/Chicago') 366 est = pytz.timezone('America/New_York') 367 utc = pytz.timezone('UTC') 368 # 369 pdt = DateTime(2018, 5, 20, 5, 41, 33, tzinfo=pst) 370 mdt = DateTime(2018, 5, 20, 6, 41, 33, tzinfo=mst) 371 cdt = DateTime(2018, 5, 20, 7, 41, 33, tzinfo=cst) 372 edt = DateTime(2018, 5, 20, 8, 41, 33, tzinfo=est) 373 udt = DateTime(2018, 5, 20, 12, 41, 33, tzinfo=utc) 374 self.assertTrue(pdt == mdt == cdt == edt == udt) 375 # 376 dup1 = DateTime.combine(pdt.date(), mdt.timetz()) 377 dup2 = DateTime.combine(cdt.date(), Time(5, 41, 33, tzinfo=pst)) 378 self.assertTrue(dup1 == dup2 == udt) 379 # 380 udt2 = DateTime(2018, 5, 20, 13, 41, 33, tzinfo=utc) 381 mdt2 = mdt.replace(tzinfo=pst) 382 self.assertTrue(mdt2 == udt2) 383 # 384 with self.assertRaisesRegex(ValueError, 'not naive datetime'): 385 DateTime(pdt, tzinfo=mst) 386 with self.assertRaisesRegex(ValueError, 'not naive datetime'): 387 DateTime(datetime.datetime(2018, 5, 27, 15, 57, 11, tzinfo=pst), tzinfo=pst) 388 with self.assertRaisesRegex(ValueError, 'not naive time'): 389 Time(pdt.timetz(), tzinfo=mst) 390 with self.assertRaisesRegex(ValueError, 'not naive time'): 391 Time(datetime.time(15, 58, 59, tzinfo=mst), tzinfo=mst) 392 # 393 if py_ver < (3, 0): 394 from xmlrpclib import Marshaller, loads 395 else: 396 from xmlrpc.client import Marshaller, loads 397 self.assertEqual( 398 udt.utctimetuple(), 399 loads(Marshaller().dumps([pdt]), use_datetime=True)[0][0].utctimetuple(), 400 ) 401 # 402 self.assertEqual( 403 pdt, 404 DateTime.combine(Date(2018, 5, 20), Time(5, 41, 33), tzinfo=pst), 405 ) 406 407 def test_arithmetic(self): 408 "Date, DateTime, & Time Arithmetic" 409 one_day = datetime.timedelta(1) 410 a_day = Date(1970, 5, 20) 411 self.assertEqual(a_day + one_day, Date(1970, 5, 21)) 412 self.assertEqual(a_day - one_day, Date(1970, 5, 19)) 413 self.assertEqual(datetime.date(1970, 5, 21) - a_day, one_day) 414 a_time = Time(12) 415 one_second = datetime.timedelta(0, 1, 0) 416 self.assertEqual(a_time + one_second, Time(12, 0, 1)) 417 self.assertEqual(a_time - one_second, Time(11, 59, 59)) 418 self.assertEqual(datetime.time(12, 0, 1) - a_time, one_second) 419 an_appt = DateTime(2012, 4, 15, 12, 30, 00) 420 displacement = datetime.timedelta(1, 60*60*2+60*15) 421 self.assertEqual(an_appt + displacement, DateTime(2012, 4, 16, 14, 45, 0)) 422 self.assertEqual(an_appt - displacement, DateTime(2012, 4, 14, 10, 15, 0)) 423 self.assertEqual(datetime.datetime(2012, 4, 16, 14, 45, 0) - an_appt, displacement) 424 425 def test_none_compare(self): 426 "comparisons to None" 427 empty_date = Date() 428 empty_time = Time() 429 empty_datetime = DateTime() 430 self.assertEqual(empty_date, None) 431 self.assertEqual(empty_time, None) 432 self.assertEqual(empty_datetime, None) 433 434 def test_singletons(self): 435 "singletons" 436 empty_date = Date() 437 empty_time = Time() 438 empty_datetime = DateTime() 439 self.assertTrue(empty_date is NullDate) 440 self.assertTrue(empty_time is NullTime) 441 self.assertTrue(empty_datetime is NullDateTime) 442 443 def test_boolean_value(self): 444 "boolean evaluation" 445 empty_date = Date() 446 empty_time = Time() 447 empty_datetime = DateTime() 448 self.assertEqual(bool(empty_date), False) 449 self.assertEqual(bool(empty_time), False) 450 self.assertEqual(bool(empty_datetime), False) 451 actual_date = Date.today() 452 actual_time = Time.now() 453 actual_datetime = DateTime.now() 454 self.assertEqual(bool(actual_date), True) 455 self.assertEqual(bool(actual_time), True) 456 self.assertEqual(bool(actual_datetime), True) 457 458 def compareTimes(self, empty1, empty2, uno, dos, tres): 459 self.assertTrue(empty1 is empty2) 460 self.assertTrue(empty1 < uno, '%r is not less than %r' % (empty1, uno)) 461 self.assertFalse(empty1 > uno, '%r is less than %r' % (empty1, uno)) 462 self.assertTrue(uno > empty1, '%r is not greater than %r' % (empty1, uno)) 463 self.assertFalse(uno < empty1, '%r is greater than %r' % (empty1, uno)) 464 self.assertEqual(uno < dos, True) 465 self.assertEqual(uno <= dos, True) 466 self.assertEqual(dos <= dos, True) 467 self.assertEqual(dos <= tres, True) 468 self.assertEqual(dos < tres, True) 469 self.assertEqual(tres <= tres, True) 470 self.assertEqual(uno == uno, True) 471 self.assertEqual(dos == dos, True) 472 self.assertEqual(tres == tres, True) 473 self.assertEqual(uno != dos, True) 474 self.assertEqual(dos != tres, True) 475 self.assertEqual(tres != uno, True) 476 self.assertEqual(tres >= tres, True) 477 self.assertEqual(tres > dos, True) 478 self.assertEqual(dos >= dos, True) 479 self.assertEqual(dos >= uno, True) 480 self.assertEqual(dos > uno, True) 481 self.assertEqual(uno >= uno, True) 482 self.assertEqual(uno >= dos, False) 483 self.assertEqual(uno >= tres, False) 484 self.assertEqual(dos >= tres, False) 485 self.assertEqual(tres <= dos, False) 486 self.assertEqual(tres <= uno, False) 487 self.assertEqual(tres < tres, False) 488 self.assertEqual(tres < dos, False) 489 self.assertEqual(tres < uno, False) 490 self.assertEqual(dos < dos, False) 491 self.assertEqual(dos < uno, False) 492 self.assertEqual(uno < uno, False) 493 self.assertEqual(uno == dos, False) 494 self.assertEqual(uno == tres, False) 495 self.assertEqual(dos == uno, False) 496 self.assertEqual(dos == tres, False) 497 self.assertEqual(tres == uno, False) 498 self.assertEqual(tres == dos, False) 499 self.assertEqual(uno != uno, False) 500 self.assertEqual(dos != dos, False) 501 self.assertEqual(tres != tres, False) 502 503 504class TestNull(TestCase): 505 506 def test_all(self): 507 NULL = Null = dbf.Null() 508 self.assertTrue(NULL is dbf.Null()) 509 510 self.assertTrue(NULL + 1 is Null) 511 self.assertTrue(1 + NULL is Null) 512 NULL += 4 513 self.assertTrue(NULL is Null) 514 value = 5 515 value += NULL 516 self.assertTrue(value is Null) 517 518 self.assertTrue(NULL - 2 is Null) 519 self.assertTrue(2 - NULL is Null) 520 NULL -= 5 521 self.assertTrue(NULL is Null) 522 value = 6 523 value -= NULL 524 self.assertTrue(value is Null) 525 526 self.assertTrue(NULL / 0 is Null) 527 self.assertTrue(3 / NULL is Null) 528 NULL /= 6 529 self.assertTrue(NULL is Null) 530 value = 7 531 value /= NULL 532 self.assertTrue(value is Null) 533 534 self.assertTrue(NULL * -3 is Null) 535 self.assertTrue(4 * NULL is Null) 536 NULL *= 7 537 self.assertTrue(NULL is Null) 538 value = 8 539 value *= NULL 540 self.assertTrue(value is Null) 541 542 self.assertTrue(NULL % 1 is Null) 543 self.assertTrue(7 % NULL is Null) 544 NULL %= 1 545 self.assertTrue(NULL is Null) 546 value = 9 547 value %= NULL 548 self.assertTrue(value is Null) 549 550 self.assertTrue(NULL ** 2 is Null) 551 self.assertTrue(4 ** NULL is Null) 552 NULL **= 3 553 self.assertTrue(NULL is Null) 554 value = 9 555 value **= NULL 556 self.assertTrue(value is Null) 557 558 self.assertTrue(NULL & 1 is Null) 559 self.assertTrue(1 & NULL is Null) 560 NULL &= 1 561 self.assertTrue(NULL is Null) 562 value = 1 563 value &= NULL 564 self.assertTrue(value is Null) 565 566 self.assertTrue(NULL ^ 1 is Null) 567 self.assertTrue(1 ^ NULL is Null) 568 NULL ^= 1 569 self.assertTrue(NULL is Null) 570 value = 1 571 value ^= NULL 572 self.assertTrue(value is Null) 573 574 self.assertTrue(NULL | 1 is Null) 575 self.assertTrue(1 | NULL is Null) 576 NULL |= 1 577 self.assertTrue(NULL is Null) 578 value = 1 579 value |= NULL 580 self.assertTrue(value is Null) 581 582 self.assertTrue(str(divmod(NULL, 1)) == '(<null>, <null>)') 583 self.assertTrue(str(divmod(1, NULL)) == '(<null>, <null>)') 584 585 self.assertTrue(NULL << 1 is Null) 586 self.assertTrue(2 << NULL is Null) 587 NULL <<=3 588 self.assertTrue(NULL is Null) 589 value = 9 590 value <<= NULL 591 self.assertTrue(value is Null) 592 593 self.assertTrue(NULL >> 1 is Null) 594 self.assertTrue(2 >> NULL is Null) 595 NULL >>= 3 596 self.assertTrue(NULL is Null) 597 value = 9 598 value >>= NULL 599 self.assertTrue(value is Null) 600 601 self.assertTrue(-NULL is Null) 602 self.assertTrue(+NULL is Null) 603 self.assertTrue(abs(NULL) is Null) 604 self.assertTrue(~NULL is Null) 605 606 self.assertTrue(NULL.attr is Null) 607 self.assertTrue(NULL() is Null) 608 self.assertTrue(getattr(NULL, 'fake') is Null) 609 610 self.assertRaises(TypeError, hash, NULL) 611 612class TestLogical(TestCase): 613 "Testing Logical" 614 615 def test_unknown(self): 616 "Unknown" 617 for unk in '', '?', ' ', None, Null, Unknown, Other: 618 huh = Logical(unk) 619 self.assertEqual(huh == None, True, "huh is %r from %r, which is not None" % (huh, unk)) 620 self.assertEqual(huh != None, False, "huh is %r from %r, which is not None" % (huh, unk)) 621 self.assertEqual(huh != True, True, "huh is %r from %r, which is not None" % (huh, unk)) 622 self.assertEqual(huh == True, False, "huh is %r from %r, which is not None" % (huh, unk)) 623 self.assertEqual(huh != False, True, "huh is %r from %r, which is not None" % (huh, unk)) 624 self.assertEqual(huh == False, False, "huh is %r from %r, which is not None" % (huh, unk)) 625 self.assertRaises(ValueError, lambda : (0, 1, 2)[huh]) 626 627 def test_true(self): 628 "true" 629 for true in 'True', 'yes', 't', 'Y', 7, ['blah']: 630 huh = Logical(true) 631 self.assertEqual(huh == True, True) 632 self.assertEqual(huh != True, False) 633 self.assertEqual(huh == False, False, "%r is not True" % true) 634 self.assertEqual(huh != False, True) 635 self.assertEqual(huh == None, False) 636 self.assertEqual(huh != None, True) 637 self.assertEqual((0, 1, 2)[huh], 1) 638 639 def test_false(self): 640 "false" 641 for false in 'false', 'No', 'F', 'n', 0, []: 642 huh = Logical(false) 643 self.assertEqual(huh != False, False) 644 self.assertEqual(huh == False, True) 645 self.assertEqual(huh != True, True) 646 self.assertEqual(huh == True, False) 647 self.assertEqual(huh != None, True) 648 self.assertEqual(huh == None, False) 649 self.assertEqual((0, 1, 2)[huh], 0) 650 651 def test_singletons(self): 652 "singletons" 653 heh = Logical(True) 654 hah = Logical('Yes') 655 ick = Logical(False) 656 ack = Logical([]) 657 unk = Logical('?') 658 bla = Logical(None) 659 self.assertEqual(heh is hah, True) 660 self.assertEqual(ick is ack, True) 661 self.assertEqual(unk is bla, True) 662 663 def test_error(self): 664 "errors" 665 self.assertRaises(ValueError, Logical, 'wrong') 666 667 def test_and(self): 668 "and" 669 true = Logical(True) 670 false = Logical(False) 671 unknown = Logical(None) 672 self.assertEqual((true & true) is true, True) 673 self.assertEqual((true & false) is false, True) 674 self.assertEqual((false & true) is false, True) 675 self.assertEqual((false & false) is false, True) 676 self.assertEqual((true & unknown) is unknown, True) 677 self.assertEqual((false & unknown) is false, True) 678 self.assertEqual((unknown & true) is unknown, True) 679 self.assertEqual((unknown & false) is false, True) 680 self.assertEqual((unknown & unknown) is unknown, True) 681 self.assertEqual((true & True) is true, True) 682 self.assertEqual((true & False) is false, True) 683 self.assertEqual((false & True) is false, True) 684 self.assertEqual((false & False) is false, True) 685 self.assertEqual((true & None) is unknown, True) 686 self.assertEqual((false & None) is false, True) 687 self.assertEqual((unknown & True) is unknown, True) 688 self.assertEqual((unknown & False) is false, True) 689 self.assertEqual((unknown & None) is unknown, True) 690 self.assertEqual((True & true) is true, True) 691 self.assertEqual((True & false) is false, True) 692 self.assertEqual((False & true) is false, True) 693 self.assertEqual((False & false) is false, True) 694 self.assertEqual((True & unknown) is unknown, True) 695 self.assertEqual((False & unknown) is false, True) 696 self.assertEqual((None & true) is unknown, True) 697 self.assertEqual((None & false) is false, True) 698 self.assertEqual((None & unknown) is unknown, True) 699 self.assertEqual(type(true & 0), int) 700 self.assertEqual(true & 0, 0) 701 self.assertEqual(type(true & 3), int) 702 self.assertEqual(true & 3, 1) 703 self.assertEqual(type(false & 0), int) 704 self.assertEqual(false & 0, 0) 705 self.assertEqual(type(false & 2), int) 706 self.assertEqual(false & 2, 0) 707 self.assertEqual(type(unknown & 0), int) 708 self.assertEqual(unknown & 0, 0) 709 self.assertEqual(unknown & 2, unknown) 710 711 t = true 712 t &= true 713 self.assertEqual(t is true, True) 714 t = true 715 t &= false 716 self.assertEqual(t is false, True) 717 f = false 718 f &= true 719 self.assertEqual(f is false, True) 720 f = false 721 f &= false 722 self.assertEqual(f is false, True) 723 t = true 724 t &= unknown 725 self.assertEqual(t is unknown, True) 726 f = false 727 f &= unknown 728 self.assertEqual(f is false, True) 729 u = unknown 730 u &= true 731 self.assertEqual(u is unknown, True) 732 u = unknown 733 u &= false 734 self.assertEqual(u is false, True) 735 u = unknown 736 u &= unknown 737 self.assertEqual(u is unknown, True) 738 t = true 739 t &= True 740 self.assertEqual(t is true, True) 741 t = true 742 t &= False 743 self.assertEqual(t is false, True) 744 f = false 745 f &= True 746 self.assertEqual(f is false, True) 747 f = false 748 f &= False 749 self.assertEqual(f is false, True) 750 t = true 751 t &= None 752 self.assertEqual(t is unknown, True) 753 f = false 754 f &= None 755 self.assertEqual(f is false, True) 756 u = unknown 757 u &= True 758 self.assertEqual(u is unknown, True) 759 u = unknown 760 u &= False 761 self.assertEqual(u is false, True) 762 u = unknown 763 u &= None 764 self.assertEqual(u is unknown, True) 765 t = True 766 t &= true 767 self.assertEqual(t is true, True) 768 t = True 769 t &= false 770 self.assertEqual(t is false, True) 771 f = False 772 f &= true 773 self.assertEqual(f is false, True) 774 f = False 775 f &= false 776 self.assertEqual(f is false, True) 777 t = True 778 t &= unknown 779 self.assertEqual(t is unknown, True) 780 f = False 781 f &= unknown 782 self.assertEqual(f is false, True) 783 u = None 784 u &= true 785 self.assertEqual(u is unknown, True) 786 u = None 787 u &= false 788 self.assertEqual(u is false, True) 789 u = None 790 u &= unknown 791 self.assertEqual(u is unknown, True) 792 t = true 793 t &= 0 794 self.assertEqual(type(true & 0), int) 795 t = true 796 t &= 0 797 self.assertEqual(true & 0, 0) 798 t = true 799 t &= 3 800 self.assertEqual(type(true & 3), int) 801 t = true 802 t &= 3 803 self.assertEqual(true & 3, 1) 804 f = false 805 f &= 0 806 self.assertEqual(type(false & 0), int) 807 f = false 808 f &= 0 809 self.assertEqual(false & 0, 0) 810 f = false 811 f &= 2 812 self.assertEqual(type(false & 2), int) 813 f = false 814 f &= 2 815 self.assertEqual(false & 2, 0) 816 u = unknown 817 u &= 0 818 self.assertEqual(type(unknown & 0), int) 819 u = unknown 820 u &= 0 821 self.assertEqual(unknown & 0, 0) 822 u = unknown 823 u &= 2 824 self.assertEqual(unknown & 2, unknown) 825 826 def test_or(self): 827 "or" 828 true = Logical(True) 829 false = Logical(False) 830 unknown = Logical(None) 831 self.assertEqual((true | true) is true, True) 832 self.assertEqual((true | false) is true, True) 833 self.assertEqual((false | true) is true, True) 834 self.assertEqual((false | false) is false, True) 835 self.assertEqual((true | unknown) is true, True) 836 self.assertEqual((false | unknown) is unknown, True) 837 self.assertEqual((unknown | true) is true, True) 838 self.assertEqual((unknown | false) is unknown, True) 839 self.assertEqual((unknown | unknown) is unknown, True) 840 self.assertEqual((true | True) is true, True) 841 self.assertEqual((true | False) is true, True) 842 self.assertEqual((false | True) is true, True) 843 self.assertEqual((false | False) is false, True) 844 self.assertEqual((true | None) is true, True) 845 self.assertEqual((false | None) is unknown, True) 846 self.assertEqual((unknown | True) is true, True) 847 self.assertEqual((unknown | False) is unknown, True) 848 self.assertEqual((unknown | None) is unknown, True) 849 self.assertEqual((True | true) is true, True) 850 self.assertEqual((True | false) is true, True) 851 self.assertEqual((False | true) is true, True) 852 self.assertEqual((False | false) is false, True) 853 self.assertEqual((True | unknown) is true, True) 854 self.assertEqual((False | unknown) is unknown, True) 855 self.assertEqual((None | true) is true, True) 856 self.assertEqual((None | false) is unknown, True) 857 self.assertEqual((None | unknown) is unknown, True) 858 self.assertEqual(type(true | 0), int) 859 self.assertEqual(true | 0, 1) 860 self.assertEqual(type(true | 2), int) 861 self.assertEqual(true | 2, 3) 862 self.assertEqual(type(false | 0), int) 863 self.assertEqual(false | 0, 0) 864 self.assertEqual(type(false | 2), int) 865 self.assertEqual(false | 2, 2) 866 self.assertEqual(unknown | 0, unknown) 867 self.assertEqual(unknown | 2, unknown) 868 869 t = true 870 t |= true 871 self.assertEqual(t is true, True) 872 t = true 873 t |= false 874 self.assertEqual(t is true, True) 875 f = false 876 f |= true 877 self.assertEqual(f is true, True) 878 f = false 879 f |= false 880 self.assertEqual(f is false, True) 881 t = true 882 t |= unknown 883 self.assertEqual(t is true, True) 884 f = false 885 f |= unknown 886 self.assertEqual(f is unknown, True) 887 u = unknown 888 u |= true 889 self.assertEqual(u is true, True) 890 u = unknown 891 u |= false 892 self.assertEqual(u is unknown, True) 893 u = unknown 894 u |= unknown 895 self.assertEqual(u is unknown, True) 896 t = true 897 t |= True 898 self.assertEqual(t is true, True) 899 t = true 900 t |= False 901 self.assertEqual(t is true, True) 902 f = false 903 f |= True 904 self.assertEqual(f is true, True) 905 f = false 906 f |= False 907 self.assertEqual(f is false, True) 908 t = true 909 t |= None 910 self.assertEqual(t is true, True) 911 f = false 912 f |= None 913 self.assertEqual(f is unknown, True) 914 u = unknown 915 u |= True 916 self.assertEqual(u is true, True) 917 u = unknown 918 u |= False 919 self.assertEqual(u is unknown, True) 920 u = unknown 921 u |= None 922 self.assertEqual(u is unknown, True) 923 t = True 924 t |= true 925 self.assertEqual(t is true, True) 926 t = True 927 t |= false 928 self.assertEqual(t is true, True) 929 f = False 930 f |= true 931 self.assertEqual(f is true, True) 932 f = False 933 f |= false 934 self.assertEqual(f is false, True) 935 t = True 936 t |= unknown 937 self.assertEqual(t is true, True) 938 f = False 939 f |= unknown 940 self.assertEqual(f is unknown, True) 941 u = None 942 u |= true 943 self.assertEqual(u is true, True) 944 u = None 945 u |= false 946 self.assertEqual(u is unknown, True) 947 u = None 948 u |= unknown 949 self.assertEqual(u is unknown, True) 950 t = true 951 t |= 0 952 self.assertEqual(type(t), int) 953 t = true 954 t |= 0 955 self.assertEqual(t, 1) 956 t = true 957 t |= 2 958 self.assertEqual(type(t), int) 959 t = true 960 t |= 2 961 self.assertEqual(t, 3) 962 f = false 963 f |= 0 964 self.assertEqual(type(f), int) 965 f = false 966 f |= 0 967 self.assertEqual(f, 0) 968 f = false 969 f |= 2 970 self.assertEqual(type(f), int) 971 f = false 972 f |= 2 973 self.assertEqual(f, 2) 974 u = unknown 975 u |= 0 976 self.assertEqual(u, unknown) 977 978 def test_xor(self): 979 "xor" 980 true = Logical(True) 981 false = Logical(False) 982 unknown = Logical(None) 983 self.assertEqual((true ^ true) is false, True) 984 self.assertEqual((true ^ false) is true, True) 985 self.assertEqual((false ^ true) is true, True) 986 self.assertEqual((false ^ false) is false, True) 987 self.assertEqual((true ^ unknown) is unknown, True) 988 self.assertEqual((false ^ unknown) is unknown, True) 989 self.assertEqual((unknown ^ true) is unknown, True) 990 self.assertEqual((unknown ^ false) is unknown, True) 991 self.assertEqual((unknown ^ unknown) is unknown, True) 992 self.assertEqual((true ^ True) is false, True) 993 self.assertEqual((true ^ False) is true, True) 994 self.assertEqual((false ^ True) is true, True) 995 self.assertEqual((false ^ False) is false, True) 996 self.assertEqual((true ^ None) is unknown, True) 997 self.assertEqual((false ^ None) is unknown, True) 998 self.assertEqual((unknown ^ True) is unknown, True) 999 self.assertEqual((unknown ^ False) is unknown, True) 1000 self.assertEqual((unknown ^ None) is unknown, True) 1001 self.assertEqual((True ^ true) is false, True) 1002 self.assertEqual((True ^ false) is true, True) 1003 self.assertEqual((False ^ true) is true, True) 1004 self.assertEqual((False ^ false) is false, True) 1005 self.assertEqual((True ^ unknown) is unknown, True) 1006 self.assertEqual((False ^ unknown) is unknown, True) 1007 self.assertEqual((None ^ true) is unknown, True) 1008 self.assertEqual((None ^ false) is unknown, True) 1009 self.assertEqual((None ^ unknown) is unknown, True) 1010 self.assertEqual(type(true ^ 2), int) 1011 self.assertEqual(true ^ 2, 3) 1012 self.assertEqual(type(true ^ 0), int) 1013 self.assertEqual(true ^ 0, 1) 1014 self.assertEqual(type(false ^ 0), int) 1015 self.assertEqual(false ^ 0, 0) 1016 self.assertEqual(type(false ^ 2), int) 1017 self.assertEqual(false ^ 2, 2) 1018 self.assertEqual(unknown ^ 0, unknown) 1019 self.assertEqual(unknown ^ 2, unknown) 1020 1021 t = true 1022 t ^= true 1023 self.assertEqual(t is false, True) 1024 t = true 1025 t ^= false 1026 self.assertEqual(t is true, True) 1027 f = false 1028 f ^= true 1029 self.assertEqual(f is true, True) 1030 f = false 1031 f ^= false 1032 self.assertEqual(f is false, True) 1033 t = true 1034 t ^= unknown 1035 self.assertEqual(t is unknown, True) 1036 f = false 1037 f ^= unknown 1038 self.assertEqual(f is unknown, True) 1039 u = unknown 1040 u ^= true 1041 self.assertEqual(u is unknown, True) 1042 u = unknown 1043 u ^= false 1044 self.assertEqual(u is unknown, True) 1045 u = unknown 1046 u ^= unknown 1047 self.assertEqual(u is unknown, True) 1048 t = true 1049 t ^= True 1050 self.assertEqual(t is false, True) 1051 t = true 1052 t ^= False 1053 self.assertEqual(t is true, True) 1054 f = false 1055 f ^= True 1056 self.assertEqual(f is true, True) 1057 f = false 1058 f ^= False 1059 self.assertEqual(f is false, True) 1060 t = true 1061 t ^= None 1062 self.assertEqual(t is unknown, True) 1063 f = false 1064 f ^= None 1065 self.assertEqual(f is unknown, True) 1066 u = unknown 1067 u ^= True 1068 self.assertEqual(u is unknown, True) 1069 u = unknown 1070 u ^= False 1071 self.assertEqual(u is unknown, True) 1072 u = unknown 1073 u ^= None 1074 self.assertEqual(u is unknown, True) 1075 t = True 1076 t ^= true 1077 self.assertEqual(t is false, True) 1078 t = True 1079 t ^= false 1080 self.assertEqual(t is true, True) 1081 f = False 1082 f ^= true 1083 self.assertEqual(f is true, True) 1084 f = False 1085 f ^= false 1086 self.assertEqual(f is false, True) 1087 t = True 1088 t ^= unknown 1089 self.assertEqual(t is unknown, True) 1090 f = False 1091 f ^= unknown 1092 self.assertEqual(f is unknown, True) 1093 u = None 1094 u ^= true 1095 self.assertEqual(u is unknown, True) 1096 u = None 1097 u ^= false 1098 self.assertEqual(u is unknown, True) 1099 u = None 1100 u ^= unknown 1101 self.assertEqual(u is unknown, True) 1102 t = true 1103 t ^= 0 1104 self.assertEqual(type(true ^ 0), int) 1105 t = true 1106 t ^= 0 1107 self.assertEqual(true ^ 0, 1) 1108 t = true 1109 t ^= 2 1110 self.assertEqual(type(true ^ 2), int) 1111 t = true 1112 t ^= 2 1113 self.assertEqual(true ^ 2, 3) 1114 f = false 1115 f ^= 0 1116 self.assertEqual(type(false ^ 0), int) 1117 f = false 1118 f ^= 0 1119 self.assertEqual(false ^ 0, 0) 1120 f = false 1121 f ^= 2 1122 self.assertEqual(type(false ^ 2), int) 1123 f = false 1124 f ^= 2 1125 self.assertEqual(false ^ 2, 2) 1126 u = unknown 1127 u ^= 0 1128 self.assertEqual(unknown ^ 0, unknown) 1129 u = unknown 1130 u ^= 2 1131 self.assertEqual(unknown ^ 2, unknown) 1132 1133 def test_negation(self): 1134 "negation" 1135 true = Logical(True) 1136 false = Logical(False) 1137 none = Logical(None) 1138 self.assertEqual(-true, -1) 1139 self.assertEqual(-false, 0) 1140 self.assertEqual(-none, none) 1141 1142 def test_posation(self): 1143 "posation" 1144 true = Logical(True) 1145 false = Logical(False) 1146 none = Logical(None) 1147 self.assertEqual(+true, 1) 1148 self.assertEqual(+false, 0) 1149 self.assertEqual(+none, none) 1150 1151 def test_abs(self): 1152 "abs()" 1153 true = Logical(True) 1154 false = Logical(False) 1155 none = Logical(None) 1156 self.assertEqual(abs(true), 1) 1157 self.assertEqual(abs(false), 0) 1158 self.assertEqual(abs(none), none) 1159 1160 def test_invert(self): 1161 "~ operator" 1162 true = Logical(True) 1163 false = Logical(False) 1164 none = Logical(None) 1165 self.assertEqual(~true, -2) 1166 self.assertEqual(~false, -1) 1167 self.assertEqual(~none, none) 1168 1169 def test_complex(self): 1170 "complex" 1171 true = Logical(True) 1172 false = Logical(False) 1173 none = Logical(None) 1174 self.assertEqual(complex(true), complex(1)) 1175 self.assertEqual(complex(false), complex(0)) 1176 self.assertRaises(ValueError, complex, none) 1177 1178 def test_int(self): 1179 "int" 1180 true = Logical(True) 1181 false = Logical(False) 1182 none = Logical(None) 1183 self.assertEqual(int(true), 1) 1184 self.assertEqual(int(false), 0) 1185 self.assertRaises(ValueError, int, none) 1186 1187 if py_ver < (3, 0): 1188 def test_long(self): 1189 "long" 1190 true = Logical(True) 1191 false = Logical(False) 1192 none = Logical(None) 1193 self.assertEqual(long(true), long(1)) 1194 self.assertEqual(long(false), long(0)) 1195 self.assertRaises(ValueError, long, none) 1196 1197 def test_float(self): 1198 "float" 1199 true = Logical(True) 1200 false = Logical(False) 1201 none = Logical(None) 1202 self.assertEqual(float(true), 1.0) 1203 self.assertEqual(float(false), 0.0) 1204 self.assertRaises(ValueError, float, none) 1205 1206 def test_oct(self): 1207 "oct" 1208 true = Logical(True) 1209 false = Logical(False) 1210 none = Logical(None) 1211 self.assertEqual(oct(true), oct(1)) 1212 self.assertEqual(oct(false), oct(0)) 1213 self.assertRaises(ValueError, oct, none) 1214 1215 def test_hex(self): 1216 "hex" 1217 true = Logical(True) 1218 false = Logical(False) 1219 none = Logical(None) 1220 self.assertEqual(hex(true), hex(1)) 1221 self.assertEqual(hex(false), hex(0)) 1222 self.assertRaises(ValueError, hex, none) 1223 1224 def test_addition(self): 1225 "addition" 1226 true = Logical(True) 1227 false = Logical(False) 1228 unknown = Logical(None) 1229 self.assertEqual(true + true, 2) 1230 self.assertEqual(true + false, 1) 1231 self.assertEqual(false + true, 1) 1232 self.assertEqual(false + false, 0) 1233 self.assertEqual(true + unknown, unknown) 1234 self.assertEqual(false + unknown, unknown) 1235 self.assertEqual(unknown + true, unknown) 1236 self.assertEqual(unknown + false, unknown) 1237 self.assertEqual(unknown + unknown, unknown) 1238 self.assertEqual(true + True, 2) 1239 self.assertEqual(true + False, 1) 1240 self.assertEqual(false + True, 1) 1241 self.assertEqual(false + False, 0) 1242 self.assertEqual(true + None, unknown) 1243 self.assertEqual(false + None, unknown) 1244 self.assertEqual(unknown + True, unknown) 1245 self.assertEqual(unknown + False, unknown) 1246 self.assertEqual(unknown + None, unknown) 1247 self.assertEqual(True + true, 2) 1248 self.assertEqual(True + false, 1) 1249 self.assertEqual(False + true, 1) 1250 self.assertEqual(False + false, 0) 1251 self.assertEqual(True + unknown, unknown) 1252 self.assertEqual(False + unknown, unknown) 1253 self.assertEqual(None + true, unknown) 1254 self.assertEqual(None + false, unknown) 1255 self.assertEqual(None + unknown, unknown) 1256 1257 t = true 1258 t += true 1259 self.assertEqual(t, 2) 1260 t = true 1261 t += false 1262 self.assertEqual(t, 1) 1263 f = false 1264 f += true 1265 self.assertEqual(f, 1) 1266 f = false 1267 f += false 1268 self.assertEqual(f, 0) 1269 t = true 1270 t += unknown 1271 self.assertEqual(t, unknown) 1272 f = false 1273 f += unknown 1274 self.assertEqual(f, unknown) 1275 u = unknown 1276 u += true 1277 self.assertEqual(u, unknown) 1278 u = unknown 1279 u += false 1280 self.assertEqual(u, unknown) 1281 u = unknown 1282 u += unknown 1283 self.assertEqual(u, unknown) 1284 t = true 1285 t += True 1286 self.assertEqual(t, 2) 1287 t = true 1288 t += False 1289 self.assertEqual(t, 1) 1290 f = false 1291 f += True 1292 self.assertEqual(f, 1) 1293 f = false 1294 f += False 1295 self.assertEqual(f, 0) 1296 t = true 1297 t += None 1298 self.assertEqual(t, unknown) 1299 f = false 1300 f += None 1301 self.assertEqual(f, unknown) 1302 u = unknown 1303 u += True 1304 self.assertEqual(u, unknown) 1305 u = unknown 1306 u += False 1307 self.assertEqual(u, unknown) 1308 u = unknown 1309 u += None 1310 self.assertEqual(u, unknown) 1311 t = True 1312 t += true 1313 self.assertEqual(t, 2) 1314 t = True 1315 t += false 1316 self.assertEqual(t, 1) 1317 f = False 1318 f += true 1319 self.assertEqual(f, 1) 1320 f = False 1321 f += false 1322 self.assertEqual(f, 0) 1323 t = True 1324 t += unknown 1325 self.assertEqual(t, unknown) 1326 f = False 1327 f += unknown 1328 self.assertEqual(f, unknown) 1329 u = None 1330 u += true 1331 self.assertEqual(u, unknown) 1332 u = None 1333 u += false 1334 self.assertEqual(u, unknown) 1335 u = None 1336 u += unknown 1337 self.assertEqual(u, unknown) 1338 1339 def test_multiplication(self): 1340 "multiplication" 1341 true = Logical(True) 1342 false = Logical(False) 1343 unknown = Logical(None) 1344 self.assertEqual(true * true, 1) 1345 self.assertEqual(true * false, 0) 1346 self.assertEqual(false * true, 0) 1347 self.assertEqual(false * false, 0) 1348 self.assertEqual(true * unknown, unknown) 1349 self.assertEqual(false * unknown, 0) 1350 self.assertEqual(unknown * true, unknown) 1351 self.assertEqual(unknown * false, 0) 1352 self.assertEqual(unknown * unknown, unknown) 1353 self.assertEqual(true * True, 1) 1354 self.assertEqual(true * False, 0) 1355 self.assertEqual(false * True, 0) 1356 self.assertEqual(false * False, 0) 1357 self.assertEqual(true * None, unknown) 1358 self.assertEqual(false * None, 0) 1359 self.assertEqual(unknown * True, unknown) 1360 self.assertEqual(unknown * False, 0) 1361 self.assertEqual(unknown * None, unknown) 1362 self.assertEqual(True * true, 1) 1363 self.assertEqual(True * false, 0) 1364 self.assertEqual(False * true, 0) 1365 self.assertEqual(False * false, 0) 1366 self.assertEqual(True * unknown, unknown) 1367 self.assertEqual(False * unknown, 0) 1368 self.assertEqual(None * true, unknown) 1369 self.assertEqual(None * false, 0) 1370 self.assertEqual(None * unknown, unknown) 1371 1372 t = true 1373 t *= true 1374 self.assertEqual(t, 1) 1375 t = true 1376 t *= false 1377 self.assertEqual(t, 0) 1378 f = false 1379 f *= true 1380 self.assertEqual(f, 0) 1381 f = false 1382 f *= false 1383 self.assertEqual(f, 0) 1384 t = true 1385 t *= unknown 1386 self.assertEqual(t, unknown) 1387 f = false 1388 f *= unknown 1389 self.assertEqual(f, 0) 1390 u = unknown 1391 u *= true 1392 self.assertEqual(u, unknown) 1393 u = unknown 1394 u *= false 1395 self.assertEqual(u, 0) 1396 u = unknown 1397 u *= unknown 1398 self.assertEqual(u, unknown) 1399 t = true 1400 t *= True 1401 self.assertEqual(t, 1) 1402 t = true 1403 t *= False 1404 self.assertEqual(t, 0) 1405 f = false 1406 f *= True 1407 self.assertEqual(f, 0) 1408 f = false 1409 f *= False 1410 self.assertEqual(f, 0) 1411 t = true 1412 t *= None 1413 self.assertEqual(t, unknown) 1414 f = false 1415 f *= None 1416 self.assertEqual(f, 0) 1417 u = unknown 1418 u *= True 1419 self.assertEqual(u, unknown) 1420 u = unknown 1421 u *= False 1422 self.assertEqual(u, 0) 1423 u = unknown 1424 u *= None 1425 self.assertEqual(u, unknown) 1426 t = True 1427 t *= true 1428 self.assertEqual(t, 1) 1429 t = True 1430 t *= false 1431 self.assertEqual(t, 0) 1432 f = False 1433 f *= true 1434 self.assertEqual(f, 0) 1435 f = False 1436 f *= false 1437 self.assertEqual(f, 0) 1438 t = True 1439 t *= unknown 1440 self.assertEqual(t, unknown) 1441 f = False 1442 f *= unknown 1443 self.assertEqual(f, 0) 1444 u = None 1445 u *= true 1446 self.assertEqual(u, unknown) 1447 u = None 1448 u *= false 1449 self.assertEqual(u, 0) 1450 u = None 1451 u *= unknown 1452 self.assertEqual(u, unknown) 1453 1454 def test_subtraction(self): 1455 "subtraction" 1456 true = Logical(True) 1457 false = Logical(False) 1458 unknown = Logical(None) 1459 self.assertEqual(true - true, 0) 1460 self.assertEqual(true - false, 1) 1461 self.assertEqual(false - true, -1) 1462 self.assertEqual(false - false, 0) 1463 self.assertEqual(true - unknown, unknown) 1464 self.assertEqual(false - unknown, unknown) 1465 self.assertEqual(unknown - true, unknown) 1466 self.assertEqual(unknown - false, unknown) 1467 self.assertEqual(unknown - unknown, unknown) 1468 self.assertEqual(true - True, 0) 1469 self.assertEqual(true - False, 1) 1470 self.assertEqual(false - True, -1) 1471 self.assertEqual(false - False, 0) 1472 self.assertEqual(true - None, unknown) 1473 self.assertEqual(false - None, unknown) 1474 self.assertEqual(unknown - True, unknown) 1475 self.assertEqual(unknown - False, unknown) 1476 self.assertEqual(unknown - None, unknown) 1477 self.assertEqual(True - true, 0) 1478 self.assertEqual(True - false, 1) 1479 self.assertEqual(False - true, -1) 1480 self.assertEqual(False - false, 0) 1481 self.assertEqual(True - unknown, unknown) 1482 self.assertEqual(False - unknown, unknown) 1483 self.assertEqual(None - true, unknown) 1484 self.assertEqual(None - false, unknown) 1485 self.assertEqual(None - unknown, unknown) 1486 1487 t = true 1488 t -= true 1489 self.assertEqual(t, 0) 1490 t = true 1491 t -= false 1492 self.assertEqual(t, 1) 1493 f = false 1494 f -= true 1495 self.assertEqual(f, -1) 1496 f = false 1497 f -= false 1498 self.assertEqual(f, 0) 1499 t = true 1500 t -= unknown 1501 self.assertEqual(t, unknown) 1502 f = false 1503 f -= unknown 1504 self.assertEqual(f, unknown) 1505 u = unknown 1506 u -= true 1507 self.assertEqual(u, unknown) 1508 u = unknown 1509 u -= false 1510 self.assertEqual(u, unknown) 1511 u = unknown 1512 u -= unknown 1513 self.assertEqual(u, unknown) 1514 t = true 1515 t -= True 1516 self.assertEqual(t, 0) 1517 t = true 1518 t -= False 1519 self.assertEqual(t, 1) 1520 f = false 1521 f -= True 1522 self.assertEqual(f, -1) 1523 f = false 1524 f -= False 1525 self.assertEqual(f, 0) 1526 t = true 1527 t -= None 1528 self.assertEqual(t, unknown) 1529 f = false 1530 f -= None 1531 self.assertEqual(f, unknown) 1532 u = unknown 1533 u -= True 1534 self.assertEqual(u, unknown) 1535 u = unknown 1536 u -= False 1537 self.assertEqual(u, unknown) 1538 u = unknown 1539 u -= None 1540 self.assertEqual(u, unknown) 1541 t = True 1542 t -= true 1543 self.assertEqual(t, 0) 1544 t = True 1545 t -= false 1546 self.assertEqual(t, 1) 1547 f = False 1548 f -= true 1549 self.assertEqual(f, -1) 1550 f = False 1551 f -= false 1552 self.assertEqual(f, 0) 1553 t = True 1554 t -= unknown 1555 self.assertEqual(t, unknown) 1556 f = False 1557 f -= unknown 1558 self.assertEqual(f, unknown) 1559 u = None 1560 u -= true 1561 self.assertEqual(u, unknown) 1562 u = None 1563 u -= false 1564 self.assertEqual(u, unknown) 1565 u = None 1566 u -= unknown 1567 self.assertEqual(u, unknown) 1568 1569 def test_division(self): 1570 "division" 1571 true = Logical(True) 1572 false = Logical(False) 1573 unknown = Logical(None) 1574 self.assertEqual(true / true, 1) 1575 self.assertEqual(true / false, unknown) 1576 self.assertEqual(false / true, 0) 1577 self.assertEqual(false / false, unknown) 1578 self.assertEqual(true / unknown, unknown) 1579 self.assertEqual(false / unknown, unknown) 1580 self.assertEqual(unknown / true, unknown) 1581 self.assertEqual(unknown / false, unknown) 1582 self.assertEqual(unknown / unknown, unknown) 1583 self.assertEqual(true / True, 1) 1584 self.assertEqual(true / False, unknown) 1585 self.assertEqual(false / True, 0) 1586 self.assertEqual(false / False, unknown) 1587 self.assertEqual(true / None, unknown) 1588 self.assertEqual(false / None, unknown) 1589 self.assertEqual(unknown / True, unknown) 1590 self.assertEqual(unknown / False, unknown) 1591 self.assertEqual(unknown / None, unknown) 1592 self.assertEqual(True / true, 1) 1593 self.assertEqual(True / false, unknown) 1594 self.assertEqual(False / true, 0) 1595 self.assertEqual(False / false, unknown) 1596 self.assertEqual(True / unknown, unknown) 1597 self.assertEqual(False / unknown, unknown) 1598 self.assertEqual(None / true, unknown) 1599 self.assertEqual(None / false, unknown) 1600 self.assertEqual(None / unknown, unknown) 1601 1602 t = true 1603 t /= true 1604 self.assertEqual(t, 1) 1605 t = true 1606 t /= false 1607 self.assertEqual(t, unknown) 1608 f = false 1609 f /= true 1610 self.assertEqual(f, 0) 1611 f = false 1612 f /= false 1613 self.assertEqual(f, unknown) 1614 t = true 1615 t /= unknown 1616 self.assertEqual(t, unknown) 1617 f = false 1618 f /= unknown 1619 self.assertEqual(f, unknown) 1620 u = unknown 1621 u /= true 1622 self.assertEqual(u, unknown) 1623 u = unknown 1624 u /= false 1625 self.assertEqual(u, unknown) 1626 u = unknown 1627 u /= unknown 1628 self.assertEqual(u, unknown) 1629 t = true 1630 t /= True 1631 self.assertEqual(t, 1) 1632 t = true 1633 t /= False 1634 self.assertEqual(t, unknown) 1635 f = false 1636 f /= True 1637 self.assertEqual(f, 0) 1638 f = false 1639 f /= False 1640 self.assertEqual(f, unknown) 1641 t = true 1642 t /= None 1643 self.assertEqual(t, unknown) 1644 f = false 1645 f /= None 1646 self.assertEqual(f, unknown) 1647 u = unknown 1648 u /= True 1649 self.assertEqual(u, unknown) 1650 u = unknown 1651 u /= False 1652 self.assertEqual(u, unknown) 1653 u = unknown 1654 u /= None 1655 self.assertEqual(u, unknown) 1656 t = True 1657 t /= true 1658 self.assertEqual(t, 1) 1659 t = True 1660 t /= false 1661 self.assertEqual(t, unknown) 1662 f = False 1663 f /= true 1664 self.assertEqual(f, 0) 1665 f = False 1666 f /= false 1667 self.assertEqual(f, unknown) 1668 t = True 1669 t /= unknown 1670 self.assertEqual(t, unknown) 1671 f = False 1672 f /= unknown 1673 self.assertEqual(f, unknown) 1674 u = None 1675 u /= true 1676 self.assertEqual(u, unknown) 1677 u = None 1678 u /= false 1679 self.assertEqual(u, unknown) 1680 u = None 1681 u /= unknown 1682 self.assertEqual(u, unknown) 1683 1684 1685 self.assertEqual(true // true, 1) 1686 self.assertEqual(true // false, unknown) 1687 self.assertEqual(false // true, 0) 1688 self.assertEqual(false // false, unknown) 1689 self.assertEqual(true // unknown, unknown) 1690 self.assertEqual(false // unknown, unknown) 1691 self.assertEqual(unknown // true, unknown) 1692 self.assertEqual(unknown // false, unknown) 1693 self.assertEqual(unknown // unknown, unknown) 1694 self.assertEqual(true // True, 1) 1695 self.assertEqual(true // False, unknown) 1696 self.assertEqual(false // True, 0) 1697 self.assertEqual(false // False, unknown) 1698 self.assertEqual(true // None, unknown) 1699 self.assertEqual(false // None, unknown) 1700 self.assertEqual(unknown // True, unknown) 1701 self.assertEqual(unknown // False, unknown) 1702 self.assertEqual(unknown // None, unknown) 1703 self.assertEqual(True // true, 1) 1704 self.assertEqual(True // false, unknown) 1705 self.assertEqual(False // true, 0) 1706 self.assertEqual(False // false, unknown) 1707 self.assertEqual(True // unknown, unknown) 1708 self.assertEqual(False // unknown, unknown) 1709 self.assertEqual(None // true, unknown) 1710 self.assertEqual(None // false, unknown) 1711 self.assertEqual(None // unknown, unknown) 1712 1713 t = true 1714 t //= true 1715 self.assertEqual(t, 1) 1716 t = true 1717 t //= false 1718 self.assertEqual(t, unknown) 1719 f = false 1720 f //= true 1721 self.assertEqual(f, 0) 1722 f = false 1723 f //= false 1724 self.assertEqual(f, unknown) 1725 t = true 1726 t //= unknown 1727 self.assertEqual(t, unknown) 1728 f = false 1729 f //= unknown 1730 self.assertEqual(f, unknown) 1731 u = unknown 1732 u //= true 1733 self.assertEqual(u, unknown) 1734 u = unknown 1735 u //= false 1736 self.assertEqual(u, unknown) 1737 u = unknown 1738 u //= unknown 1739 self.assertEqual(u, unknown) 1740 t = true 1741 t //= True 1742 self.assertEqual(t, 1) 1743 t = true 1744 t //= False 1745 self.assertEqual(t, unknown) 1746 f = false 1747 f //= True 1748 self.assertEqual(f, 0) 1749 f = false 1750 f //= False 1751 self.assertEqual(f, unknown) 1752 t = true 1753 t //= None 1754 self.assertEqual(t, unknown) 1755 f = false 1756 f //= None 1757 self.assertEqual(f, unknown) 1758 u = unknown 1759 u //= True 1760 self.assertEqual(u, unknown) 1761 u = unknown 1762 u //= False 1763 self.assertEqual(u, unknown) 1764 u = unknown 1765 u //= None 1766 self.assertEqual(u, unknown) 1767 t = True 1768 t //= true 1769 self.assertEqual(t, 1) 1770 t = True 1771 t //= false 1772 self.assertEqual(t, unknown) 1773 f = False 1774 f //= true 1775 self.assertEqual(f, 0) 1776 f = False 1777 f //= false 1778 self.assertEqual(f, unknown) 1779 t = True 1780 t //= unknown 1781 self.assertEqual(t, unknown) 1782 f = False 1783 f //= unknown 1784 self.assertEqual(f, unknown) 1785 u = None 1786 u //= true 1787 self.assertEqual(u, unknown) 1788 u = None 1789 u //= false 1790 self.assertEqual(u, unknown) 1791 u = None 1792 u //= unknown 1793 self.assertEqual(u, unknown) 1794 1795 def test_shift(self): 1796 "<< and >>" 1797 true = Logical(True) 1798 false = Logical(False) 1799 unknown = Logical(None) 1800 1801 self.assertEqual(true >> true, 0) 1802 self.assertEqual(true >> false, 1) 1803 self.assertEqual(false >> true, 0) 1804 self.assertEqual(false >> false, 0) 1805 self.assertEqual(true >> unknown, unknown) 1806 self.assertEqual(false >> unknown, unknown) 1807 self.assertEqual(unknown >> true, unknown) 1808 self.assertEqual(unknown >> false, unknown) 1809 self.assertEqual(unknown >> unknown, unknown) 1810 self.assertEqual(true >> True, 0) 1811 self.assertEqual(true >> False, 1) 1812 self.assertEqual(false >> True, 0) 1813 self.assertEqual(false >> False, 0) 1814 self.assertEqual(true >> None, unknown) 1815 self.assertEqual(false >> None, unknown) 1816 self.assertEqual(unknown >> True, unknown) 1817 self.assertEqual(unknown >> False, unknown) 1818 self.assertEqual(unknown >> None, unknown) 1819 self.assertEqual(True >> true, 0) 1820 self.assertEqual(True >> false, 1) 1821 self.assertEqual(False >> true, 0) 1822 self.assertEqual(False >> false, 0) 1823 self.assertEqual(True >> unknown, unknown) 1824 self.assertEqual(False >> unknown, unknown) 1825 self.assertEqual(None >> true, unknown) 1826 self.assertEqual(None >> false, unknown) 1827 self.assertEqual(None >> unknown, unknown) 1828 1829 self.assertEqual(true << true, 2) 1830 self.assertEqual(true << false, 1) 1831 self.assertEqual(false << true, 0) 1832 self.assertEqual(false << false, 0) 1833 self.assertEqual(true << unknown, unknown) 1834 self.assertEqual(false << unknown, unknown) 1835 self.assertEqual(unknown << true, unknown) 1836 self.assertEqual(unknown << false, unknown) 1837 self.assertEqual(unknown << unknown, unknown) 1838 self.assertEqual(true << True, 2) 1839 self.assertEqual(true << False, 1) 1840 self.assertEqual(false << True, 0) 1841 self.assertEqual(false << False, 0) 1842 self.assertEqual(true << None, unknown) 1843 self.assertEqual(false << None, unknown) 1844 self.assertEqual(unknown << True, unknown) 1845 self.assertEqual(unknown << False, unknown) 1846 self.assertEqual(unknown << None, unknown) 1847 self.assertEqual(True << true, 2) 1848 self.assertEqual(True << false, 1) 1849 self.assertEqual(False << true, 0) 1850 self.assertEqual(False << false, 0) 1851 self.assertEqual(True << unknown, unknown) 1852 self.assertEqual(False << unknown, unknown) 1853 self.assertEqual(None << true, unknown) 1854 self.assertEqual(None << false, unknown) 1855 self.assertEqual(None << unknown, unknown) 1856 1857 t = true 1858 t >>= true 1859 self.assertEqual(t, 0) 1860 t = true 1861 t >>= false 1862 self.assertEqual(t, 1) 1863 f = false 1864 f >>= true 1865 self.assertEqual(f, 0) 1866 f = false 1867 f >>= false 1868 self.assertEqual(f, 0) 1869 t = true 1870 t >>= unknown 1871 self.assertEqual(t, unknown) 1872 f = false 1873 f >>= unknown 1874 self.assertEqual(f, unknown) 1875 u = unknown 1876 u >>= true 1877 self.assertEqual(u, unknown) 1878 u = unknown 1879 u >>= false 1880 self.assertEqual(u, unknown) 1881 u = unknown 1882 u >>= unknown 1883 self.assertEqual(u, unknown) 1884 t = true 1885 t >>= True 1886 self.assertEqual(t, 0) 1887 t = true 1888 t >>= False 1889 self.assertEqual(t, 1) 1890 f = false 1891 f >>= True 1892 self.assertEqual(f, 0) 1893 f = false 1894 f >>= False 1895 self.assertEqual(f, 0) 1896 t = true 1897 t >>= None 1898 self.assertEqual(t, unknown) 1899 f = false 1900 f >>= None 1901 self.assertEqual(f, unknown) 1902 u = unknown 1903 u >>= True 1904 self.assertEqual(u, unknown) 1905 u = unknown 1906 u >>= False 1907 self.assertEqual(u, unknown) 1908 u = unknown 1909 u >>= None 1910 self.assertEqual(u, unknown) 1911 t = True 1912 t >>= true 1913 self.assertEqual(t, 0) 1914 t = True 1915 t >>= false 1916 self.assertEqual(t, 1) 1917 f = False 1918 f >>= true 1919 self.assertEqual(f, 0) 1920 f = False 1921 f >>= false 1922 self.assertEqual(f, 0) 1923 t = True 1924 t >>= unknown 1925 self.assertEqual(t, unknown) 1926 f = False 1927 f >>= unknown 1928 self.assertEqual(f, unknown) 1929 u = None 1930 u >>= true 1931 self.assertEqual(u, unknown) 1932 u = None 1933 u >>= false 1934 self.assertEqual(u, unknown) 1935 u = None 1936 u >>= unknown 1937 self.assertEqual(u, unknown) 1938 1939 t = true 1940 t <<= true 1941 self.assertEqual(t, 2) 1942 t = true 1943 t <<= false 1944 self.assertEqual(t, 1) 1945 f = false 1946 f <<= true 1947 self.assertEqual(f, 0) 1948 f = false 1949 f <<= false 1950 self.assertEqual(f, 0) 1951 t = true 1952 t <<= unknown 1953 self.assertEqual(t, unknown) 1954 f = false 1955 f <<= unknown 1956 self.assertEqual(f, unknown) 1957 u = unknown 1958 u <<= true 1959 self.assertEqual(u, unknown) 1960 u = unknown 1961 u <<= false 1962 self.assertEqual(u, unknown) 1963 u = unknown 1964 u <<= unknown 1965 self.assertEqual(u, unknown) 1966 t = true 1967 t <<= True 1968 self.assertEqual(t, 2) 1969 t = true 1970 t <<= False 1971 self.assertEqual(t, 1) 1972 f = false 1973 f <<= True 1974 self.assertEqual(f, 0) 1975 f = false 1976 f <<= False 1977 self.assertEqual(f, 0) 1978 t = true 1979 t <<= None 1980 self.assertEqual(t, unknown) 1981 f = false 1982 f <<= None 1983 self.assertEqual(f, unknown) 1984 u = unknown 1985 u <<= True 1986 self.assertEqual(u, unknown) 1987 u = unknown 1988 u <<= False 1989 self.assertEqual(u, unknown) 1990 u = unknown 1991 u <<= None 1992 self.assertEqual(u, unknown) 1993 t = True 1994 t <<= true 1995 self.assertEqual(t, 2) 1996 t = True 1997 t <<= false 1998 self.assertEqual(t, 1) 1999 f = False 2000 f <<= true 2001 self.assertEqual(f, 0) 2002 f = False 2003 f <<= false 2004 self.assertEqual(f, 0) 2005 t = True 2006 t <<= unknown 2007 self.assertEqual(t, unknown) 2008 f = False 2009 f <<= unknown 2010 self.assertEqual(f, unknown) 2011 u = None 2012 u <<= true 2013 self.assertEqual(u, unknown) 2014 u = None 2015 u <<= false 2016 self.assertEqual(u, unknown) 2017 u = None 2018 u <<= unknown 2019 self.assertEqual(u, unknown) 2020 2021 def test_pow(self): 2022 "**" 2023 true = Logical(True) 2024 false = Logical(False) 2025 unknown = Logical(None) 2026 2027 self.assertEqual(true ** true, 1) 2028 self.assertEqual(true ** false, 1) 2029 self.assertEqual(false ** true, 0) 2030 self.assertEqual(false ** false, 1) 2031 self.assertEqual(true ** unknown, unknown) 2032 self.assertEqual(false ** unknown, unknown) 2033 self.assertEqual(unknown ** true, unknown) 2034 self.assertEqual(unknown ** false, 1) 2035 self.assertEqual(unknown ** unknown, unknown) 2036 self.assertEqual(true ** True, 1) 2037 self.assertEqual(true ** False, 1) 2038 self.assertEqual(false ** True, 0) 2039 self.assertEqual(false ** False, 1) 2040 self.assertEqual(true ** None, unknown) 2041 self.assertEqual(false ** None, unknown) 2042 self.assertEqual(unknown ** True, unknown) 2043 self.assertEqual(unknown ** False, 1) 2044 self.assertEqual(unknown ** None, unknown) 2045 self.assertEqual(True ** true, 1) 2046 self.assertEqual(True ** false, 1) 2047 self.assertEqual(False ** true, 0) 2048 self.assertEqual(False ** false, 1) 2049 self.assertEqual(True ** unknown, unknown) 2050 self.assertEqual(False ** unknown, unknown) 2051 self.assertEqual(None ** true, unknown) 2052 self.assertEqual(None ** false, 1) 2053 self.assertEqual(None ** unknown, unknown) 2054 2055 t = true 2056 t **= true 2057 self.assertEqual(t, 1) 2058 t = true 2059 t **= false 2060 self.assertEqual(t, 1) 2061 f = false 2062 f **= true 2063 self.assertEqual(f, 0) 2064 f = false 2065 f **= false 2066 self.assertEqual(f, 1) 2067 t = true 2068 t **= unknown 2069 self.assertEqual(t, unknown) 2070 f = false 2071 f **= unknown 2072 self.assertEqual(f, unknown) 2073 u = unknown 2074 u **= true 2075 self.assertEqual(u, unknown) 2076 u = unknown 2077 u **= false 2078 self.assertEqual(u, 1) 2079 u = unknown 2080 u **= unknown 2081 self.assertEqual(u, unknown) 2082 t = true 2083 t **= True 2084 self.assertEqual(t, 1) 2085 t = true 2086 t **= False 2087 self.assertEqual(t, 1) 2088 f = false 2089 f **= True 2090 self.assertEqual(f, 0) 2091 f = false 2092 f **= False 2093 self.assertEqual(f, 1) 2094 t = true 2095 t **= None 2096 self.assertEqual(t, unknown) 2097 f = false 2098 f **= None 2099 self.assertEqual(f, unknown) 2100 u = unknown 2101 u **= True 2102 self.assertEqual(u, unknown) 2103 u = unknown 2104 u **= False 2105 self.assertEqual(u, 1) 2106 u = unknown 2107 u **= None 2108 self.assertEqual(u, unknown) 2109 t = True 2110 t **= true 2111 self.assertEqual(t, 1) 2112 t = True 2113 t **= false 2114 self.assertEqual(t, 1) 2115 f = False 2116 f **= true 2117 self.assertEqual(f, 0) 2118 f = False 2119 f **= false 2120 self.assertEqual(f, 1) 2121 t = True 2122 t **= unknown 2123 self.assertEqual(t, unknown) 2124 f = False 2125 f **= unknown 2126 self.assertEqual(f, unknown) 2127 u = None 2128 u **= true 2129 self.assertEqual(u, unknown) 2130 u = None 2131 u **= false 2132 self.assertEqual(u, 1) 2133 u = None 2134 u **= unknown 2135 self.assertEqual(u, unknown) 2136 2137 def test_mod(self): 2138 "%" 2139 true = Logical(True) 2140 false = Logical(False) 2141 unknown = Logical(None) 2142 2143 self.assertEqual(true % true, 0) 2144 self.assertEqual(true % false, unknown) 2145 self.assertEqual(false % true, 0) 2146 self.assertEqual(false % false, unknown) 2147 self.assertEqual(true % unknown, unknown) 2148 self.assertEqual(false % unknown, unknown) 2149 self.assertEqual(unknown % true, unknown) 2150 self.assertEqual(unknown % false, unknown) 2151 self.assertEqual(unknown % unknown, unknown) 2152 self.assertEqual(true % True, 0) 2153 self.assertEqual(true % False, unknown) 2154 self.assertEqual(false % True, 0) 2155 self.assertEqual(false % False, unknown) 2156 self.assertEqual(true % None, unknown) 2157 self.assertEqual(false % None, unknown) 2158 self.assertEqual(unknown % True, unknown) 2159 self.assertEqual(unknown % False, unknown) 2160 self.assertEqual(unknown % None, unknown) 2161 self.assertEqual(True % true, 0) 2162 self.assertEqual(True % false, unknown) 2163 self.assertEqual(False % true, 0) 2164 self.assertEqual(False % false, unknown) 2165 self.assertEqual(True % unknown, unknown) 2166 self.assertEqual(False % unknown, unknown) 2167 self.assertEqual(None % true, unknown) 2168 self.assertEqual(None % false, unknown) 2169 self.assertEqual(None % unknown, unknown) 2170 2171 t = true 2172 t %= true 2173 self.assertEqual(t, 0) 2174 t = true 2175 t %= false 2176 self.assertEqual(t, unknown) 2177 f = false 2178 f %= true 2179 self.assertEqual(f, 0) 2180 f = false 2181 f %= false 2182 self.assertEqual(f, unknown) 2183 t = true 2184 t %= unknown 2185 self.assertEqual(t, unknown) 2186 f = false 2187 f %= unknown 2188 self.assertEqual(f, unknown) 2189 u = unknown 2190 u %= true 2191 self.assertEqual(u, unknown) 2192 u = unknown 2193 u %= false 2194 self.assertEqual(u, unknown) 2195 u = unknown 2196 u %= unknown 2197 self.assertEqual(u, unknown) 2198 t = true 2199 t %= True 2200 self.assertEqual(t, 0) 2201 t = true 2202 t %= False 2203 self.assertEqual(t, unknown) 2204 f = false 2205 f %= True 2206 self.assertEqual(f, 0) 2207 f = false 2208 f %= False 2209 self.assertEqual(f, unknown) 2210 t = true 2211 t %= None 2212 self.assertEqual(t, unknown) 2213 f = false 2214 f %= None 2215 self.assertEqual(f, unknown) 2216 u = unknown 2217 u %= True 2218 self.assertEqual(u, unknown) 2219 u = unknown 2220 u %= False 2221 self.assertEqual(u, unknown) 2222 u = unknown 2223 u %= None 2224 self.assertEqual(u, unknown) 2225 t = True 2226 t %= true 2227 self.assertEqual(t, 0) 2228 t = True 2229 t %= false 2230 self.assertEqual(t, unknown) 2231 f = False 2232 f %= true 2233 self.assertEqual(f, 0) 2234 f = False 2235 f %= false 2236 self.assertEqual(f, unknown) 2237 t = True 2238 t %= unknown 2239 self.assertEqual(t, unknown) 2240 f = False 2241 f %= unknown 2242 self.assertEqual(f, unknown) 2243 u = None 2244 u %= true 2245 self.assertEqual(u, unknown) 2246 u = None 2247 u %= false 2248 self.assertEqual(u, unknown) 2249 u = None 2250 u %= unknown 2251 self.assertEqual(u, unknown) 2252 2253 def test_divmod(self): 2254 "divmod()" 2255 true = Logical(True) 2256 false = Logical(False) 2257 unknown = Logical(None) 2258 2259 self.assertEqual(divmod(true, true), (1, 0)) 2260 self.assertEqual(divmod(true, false), (unknown, unknown)) 2261 self.assertEqual(divmod(false, true), (0, 0)) 2262 self.assertEqual(divmod(false, false), (unknown, unknown)) 2263 self.assertEqual(divmod(true, unknown), (unknown, unknown)) 2264 self.assertEqual(divmod(false, unknown), (unknown, unknown)) 2265 self.assertEqual(divmod(unknown, true), (unknown, unknown)) 2266 self.assertEqual(divmod(unknown, false), (unknown, unknown)) 2267 self.assertEqual(divmod(unknown, unknown), (unknown, unknown)) 2268 self.assertEqual(divmod(true, True), (1, 0)) 2269 self.assertEqual(divmod(true, False), (unknown, unknown)) 2270 self.assertEqual(divmod(false, True), (0, 0)) 2271 self.assertEqual(divmod(false, False), (unknown, unknown)) 2272 self.assertEqual(divmod(true, None), (unknown, unknown)) 2273 self.assertEqual(divmod(false, None), (unknown, unknown)) 2274 self.assertEqual(divmod(unknown, True), (unknown, unknown)) 2275 self.assertEqual(divmod(unknown, False), (unknown, unknown)) 2276 self.assertEqual(divmod(unknown, None), (unknown, unknown)) 2277 self.assertEqual(divmod(True, true), (1, 0)) 2278 self.assertEqual(divmod(True, false), (unknown, unknown)) 2279 self.assertEqual(divmod(False, true), (0, 0)) 2280 self.assertEqual(divmod(False, false), (unknown, unknown)) 2281 self.assertEqual(divmod(True, unknown), (unknown, unknown)) 2282 self.assertEqual(divmod(False, unknown), (unknown, unknown)) 2283 self.assertEqual(divmod(None, true), (unknown, unknown)) 2284 self.assertEqual(divmod(None, false), (unknown, unknown)) 2285 self.assertEqual(divmod(None, unknown), (unknown, unknown)) 2286 2287 2288class TestQuantum(TestCase): 2289 "Testing Quantum" 2290 2291 def test_exceptions(self): 2292 "errors" 2293 self.assertRaises(ValueError, Quantum, 'wrong') 2294 self.assertRaises(TypeError, lambda : (0, 1, 2)[On]) 2295 self.assertRaises(TypeError, lambda : (0, 1, 2)[Off]) 2296 self.assertRaises(TypeError, lambda : (0, 1, 2)[Other]) 2297 2298 def test_other(self): 2299 "Other" 2300 huh = unknown = Quantum('') 2301 self.assertEqual(huh is dbf.Other, True) 2302 self.assertEqual((huh != huh) is unknown, True) 2303 self.assertEqual((huh != True) is unknown, True) 2304 self.assertEqual((huh != False) is unknown, True) 2305 2306 huh = Quantum('?') 2307 self.assertEqual(huh is dbf.Other, True) 2308 self.assertEqual((huh != huh) is unknown, True) 2309 self.assertEqual((huh != True) is unknown, True) 2310 self.assertEqual((huh != False) is unknown, True) 2311 2312 huh = Quantum(' ') 2313 self.assertEqual(huh is dbf.Other, True) 2314 self.assertEqual((huh != huh) is unknown, True) 2315 self.assertEqual((huh != True) is unknown, True) 2316 self.assertEqual((huh != False) is unknown, True) 2317 2318 huh = Quantum(None) 2319 self.assertEqual(huh is dbf.Other, True) 2320 self.assertEqual((huh != huh) is unknown, True) 2321 self.assertEqual((huh != True) is unknown, True) 2322 self.assertEqual((huh != False) is unknown, True) 2323 2324 huh = Quantum(Null()) 2325 self.assertEqual(huh is dbf.Other, True) 2326 self.assertEqual((huh != huh) is unknown, True) 2327 self.assertEqual((huh != True) is unknown, True) 2328 self.assertEqual((huh != False) is unknown, True) 2329 2330 huh = Quantum(Other) 2331 self.assertEqual(huh is dbf.Other, True) 2332 self.assertEqual((huh != huh) is unknown, True) 2333 self.assertEqual((huh != True) is unknown, True) 2334 self.assertEqual((huh != False) is unknown, True) 2335 2336 huh = Quantum(Unknown) 2337 self.assertEqual(huh is dbf.Other, True) 2338 self.assertEqual((huh != huh) is unknown, True) 2339 self.assertEqual((huh != True) is unknown, True) 2340 self.assertEqual((huh != False) is unknown, True) 2341 2342 def test_true(self): 2343 "true" 2344 huh = Quantum('True') 2345 unknown = Quantum('?') 2346 self.assertEqual(huh, True) 2347 self.assertNotEqual(huh, False) 2348 self.assertEqual((huh != None) is unknown, True) 2349 2350 huh = Quantum('yes') 2351 unknown = Quantum('?') 2352 self.assertEqual(huh, True) 2353 self.assertNotEqual(huh, False) 2354 self.assertEqual((huh != None) is unknown, True) 2355 2356 huh = Quantum('t') 2357 unknown = Quantum('?') 2358 self.assertEqual(huh, True) 2359 self.assertNotEqual(huh, False) 2360 self.assertEqual((huh != None) is unknown, True) 2361 2362 huh = Quantum('Y') 2363 unknown = Quantum('?') 2364 self.assertEqual(huh, True) 2365 self.assertNotEqual(huh, False) 2366 self.assertEqual((huh != None) is unknown, True) 2367 2368 huh = Quantum(7) 2369 unknown = Quantum('?') 2370 self.assertEqual(huh, True) 2371 self.assertNotEqual(huh, False) 2372 self.assertEqual((huh != None) is unknown, True) 2373 2374 huh = Quantum(['blah']) 2375 unknown = Quantum('?') 2376 self.assertEqual(huh, True) 2377 self.assertNotEqual(huh, False) 2378 self.assertEqual((huh != None) is unknown, True) 2379 2380 def test_false(self): 2381 "false" 2382 huh = Quantum('false') 2383 unknown = Quantum('?') 2384 self.assertEqual(huh, False) 2385 self.assertNotEqual(huh, True) 2386 self.assertEqual((huh != None) is unknown, True) 2387 2388 huh = Quantum('No') 2389 unknown = Quantum('?') 2390 self.assertEqual(huh, False) 2391 self.assertNotEqual(huh, True) 2392 self.assertEqual((huh != None) is unknown, True) 2393 2394 huh = Quantum('F') 2395 unknown = Quantum('?') 2396 self.assertEqual(huh, False) 2397 self.assertNotEqual(huh, True) 2398 self.assertEqual((huh != None) is unknown, True) 2399 2400 huh = Quantum('n') 2401 unknown = Quantum('?') 2402 self.assertEqual(huh, False) 2403 self.assertNotEqual(huh, True) 2404 self.assertEqual((huh != None) is unknown, True) 2405 2406 huh = Quantum(0) 2407 unknown = Quantum('?') 2408 self.assertEqual(huh, False) 2409 self.assertNotEqual(huh, True) 2410 self.assertEqual((huh != None) is unknown, True) 2411 2412 huh = Quantum([]) 2413 unknown = Quantum('?') 2414 self.assertEqual(huh, False) 2415 self.assertNotEqual(huh, True) 2416 self.assertEqual((huh != None) is unknown, True) 2417 2418 def test_singletons(self): 2419 "singletons" 2420 heh = Quantum(True) 2421 hah = Quantum('Yes') 2422 ick = Quantum(False) 2423 ack = Quantum([]) 2424 unk = Quantum('?') 2425 bla = Quantum(None) 2426 self.assertEqual(heh is hah, True) 2427 self.assertEqual(ick is ack, True) 2428 self.assertEqual(unk is bla, True) 2429 2430 def test_or(self): 2431 "or" 2432 true = Quantum(True) 2433 false = Quantum(False) 2434 unknown = Quantum(None) 2435 self.assertEqual(true + true, true) 2436 self.assertEqual(true + false, true) 2437 self.assertEqual(false + true, true) 2438 self.assertEqual(false + false, false) 2439 self.assertEqual(true + unknown, true) 2440 self.assertEqual(false + unknown is unknown, True) 2441 self.assertEqual(unknown + unknown is unknown, True) 2442 self.assertEqual(true | true, true) 2443 self.assertEqual(true | false, true) 2444 self.assertEqual(false | true, true) 2445 self.assertEqual(false | false, false) 2446 self.assertEqual(true | unknown, true) 2447 self.assertEqual(false | unknown is unknown, True) 2448 self.assertEqual(unknown | unknown is unknown, True) 2449 self.assertEqual(true + True, true) 2450 self.assertEqual(true + False, true) 2451 self.assertEqual(false + True, true) 2452 self.assertEqual(false + False, false) 2453 self.assertEqual(true + None, true) 2454 self.assertEqual(false + None is unknown, True) 2455 self.assertEqual(unknown + None is unknown, True) 2456 self.assertEqual(true | True, true) 2457 self.assertEqual(true | False, true) 2458 self.assertEqual(false | True, true) 2459 self.assertEqual(false | False, false) 2460 self.assertEqual(true | None, true) 2461 self.assertEqual(false | None is unknown, True) 2462 self.assertEqual(unknown | None is unknown, True) 2463 self.assertEqual(True + true, true) 2464 self.assertEqual(True + false, true) 2465 self.assertEqual(False + true, true) 2466 self.assertEqual(False + false, false) 2467 self.assertEqual(True + unknown, true) 2468 self.assertEqual(False + unknown is unknown, True) 2469 self.assertEqual(None + unknown is unknown, True) 2470 self.assertEqual(True | true, true) 2471 self.assertEqual(True | false, true) 2472 self.assertEqual(False | true, true) 2473 self.assertEqual(False | false, false) 2474 self.assertEqual(True | unknown, true) 2475 self.assertEqual(False | unknown is unknown, True) 2476 self.assertEqual(None | unknown is unknown, True) 2477 2478 def test_and(self): 2479 "and" 2480 true = Quantum(True) 2481 false = Quantum(False) 2482 unknown = Quantum(None) 2483 self.assertEqual(true * true, true) 2484 self.assertEqual(true * false, false) 2485 self.assertEqual(false * true, false) 2486 self.assertEqual(false * false, false) 2487 self.assertEqual(true * unknown is unknown, True) 2488 self.assertEqual(false * unknown, false) 2489 self.assertEqual(unknown * unknown is unknown, True) 2490 self.assertEqual(true & true, true) 2491 self.assertEqual(true & false, false) 2492 self.assertEqual(false & true, false) 2493 self.assertEqual(false & false, false) 2494 self.assertEqual(true & unknown is unknown, True) 2495 self.assertEqual(false & unknown, false) 2496 self.assertEqual(unknown & unknown is unknown, True) 2497 self.assertEqual(true * True, true) 2498 self.assertEqual(true * False, false) 2499 self.assertEqual(false * True, false) 2500 self.assertEqual(false * False, false) 2501 self.assertEqual(true * None is unknown, True) 2502 self.assertEqual(false * None, false) 2503 self.assertEqual(unknown * None is unknown, True) 2504 self.assertEqual(true & True, true) 2505 self.assertEqual(true & False, false) 2506 self.assertEqual(false & True, false) 2507 self.assertEqual(false & False, false) 2508 self.assertEqual(true & None is unknown, True) 2509 self.assertEqual(false & None, false) 2510 self.assertEqual(unknown & None is unknown, True) 2511 self.assertEqual(True * true, true) 2512 self.assertEqual(True * false, false) 2513 self.assertEqual(False * true, false) 2514 self.assertEqual(False * false, false) 2515 self.assertEqual(True * unknown is unknown, True) 2516 self.assertEqual(False * unknown, false) 2517 self.assertEqual(None * unknown is unknown, True) 2518 self.assertEqual(True & true, true) 2519 self.assertEqual(True & false, false) 2520 self.assertEqual(False & true, false) 2521 self.assertEqual(False & false, false) 2522 self.assertEqual(True & unknown is unknown, True) 2523 self.assertEqual(False & unknown, false) 2524 self.assertEqual(None & unknown is unknown, True) 2525 2526 def test_xor(self): 2527 "xor" 2528 true = Quantum(True) 2529 false = Quantum(False) 2530 unknown = Quantum(None) 2531 self.assertEqual(true ^ true, false) 2532 self.assertEqual(true ^ false, true) 2533 self.assertEqual(false ^ true, true) 2534 self.assertEqual(false ^ false, false) 2535 self.assertEqual(true ^ unknown is unknown, True) 2536 self.assertEqual(false ^ unknown is unknown, True) 2537 self.assertEqual(unknown ^ unknown is unknown, True) 2538 self.assertEqual(true ^ True, false) 2539 self.assertEqual(true ^ False, true) 2540 self.assertEqual(false ^ True, true) 2541 self.assertEqual(false ^ False, false) 2542 self.assertEqual(true ^ None is unknown, True) 2543 self.assertEqual(false ^ None is unknown, True) 2544 self.assertEqual(unknown ^ None is unknown, True) 2545 self.assertEqual(True ^ true, false) 2546 self.assertEqual(True ^ false, true) 2547 self.assertEqual(False ^ true, true) 2548 self.assertEqual(False ^ false, false) 2549 self.assertEqual(True ^ unknown is unknown, True) 2550 self.assertEqual(False ^ unknown is unknown, True) 2551 self.assertEqual(None ^ unknown is unknown, True) 2552 2553 def test_implication_material(self): 2554 "implication, material" 2555 true = Quantum(True) 2556 false = Quantum(False) 2557 unknown = Quantum(None) 2558 self.assertEqual(true >> true, true) 2559 self.assertEqual(true >> false, false) 2560 self.assertEqual(false >> true, true) 2561 self.assertEqual(false >> false, true) 2562 self.assertEqual(true >> unknown is unknown, True) 2563 self.assertEqual(false >> unknown, true) 2564 self.assertEqual(unknown >> unknown is unknown, True) 2565 self.assertEqual(true >> True, true) 2566 self.assertEqual(true >> False, false) 2567 self.assertEqual(false >> True, true) 2568 self.assertEqual(false >> False, true) 2569 self.assertEqual(true >> None is unknown, True) 2570 self.assertEqual(false >> None, true) 2571 self.assertEqual(unknown >> None is unknown, True) 2572 self.assertEqual(True >> true, true) 2573 self.assertEqual(True >> false, false) 2574 self.assertEqual(False >> true, true) 2575 self.assertEqual(False >> false, true) 2576 self.assertEqual(True >> unknown is unknown, True) 2577 self.assertEqual(False >> unknown, true) 2578 self.assertEqual(None >> unknown is unknown, True) 2579 2580 def test_implication_relevant(self): 2581 "implication, relevant" 2582 true = Quantum(True) 2583 false = Quantum(False) 2584 unknown = Quantum(None) 2585 Quantum.set_implication('relevant') 2586 self.assertEqual(true >> true, true) 2587 self.assertEqual(true >> false, false) 2588 self.assertEqual(false >> true is unknown, True) 2589 self.assertEqual(false >> false is unknown, True) 2590 self.assertEqual(true >> unknown is unknown, True) 2591 self.assertEqual(false >> unknown is unknown, True) 2592 self.assertEqual(unknown >> unknown is unknown, True) 2593 self.assertEqual(true >> True, true) 2594 self.assertEqual(true >> False, false) 2595 self.assertEqual(false >> True is unknown, True) 2596 self.assertEqual(false >> False is unknown, True) 2597 self.assertEqual(true >> None is unknown, True) 2598 self.assertEqual(false >> None is unknown, True) 2599 self.assertEqual(unknown >> None is unknown, True) 2600 self.assertEqual(True >> true, true) 2601 self.assertEqual(True >> false, false) 2602 self.assertEqual(False >> true is unknown, True) 2603 self.assertEqual(False >> false is unknown, True) 2604 self.assertEqual(True >> unknown is unknown, True) 2605 self.assertEqual(False >> unknown is unknown, True) 2606 self.assertEqual(None >> unknown is unknown, True) 2607 2608 def test_nand(self): 2609 "negative and" 2610 true = Quantum(True) 2611 false = Quantum(False) 2612 unknown = Quantum(None) 2613 self.assertEqual(true.D(true), false) 2614 self.assertEqual(true.D(false), true) 2615 self.assertEqual(false.D(true), true) 2616 self.assertEqual(false.D(false), true) 2617 self.assertEqual(true.D(unknown) is unknown, True) 2618 self.assertEqual(false.D(unknown), true) 2619 self.assertEqual(unknown.D(unknown) is unknown, True) 2620 self.assertEqual(true.D(True), false) 2621 self.assertEqual(true.D(False), true) 2622 self.assertEqual(false.D(True), true) 2623 self.assertEqual(false.D(False), true) 2624 self.assertEqual(true.D(None) is unknown, True) 2625 self.assertEqual(false.D(None), true) 2626 self.assertEqual(unknown.D(None) is unknown, True) 2627 2628 def test_negation(self): 2629 "negation" 2630 true = Quantum(True) 2631 false = Quantum(False) 2632 none = Quantum(None) 2633 self.assertEqual(-true, false) 2634 self.assertEqual(-false, true) 2635 self.assertEqual(-none is none, True) 2636 2637 2638class TestExceptions(TestCase): 2639 2640 def test_bad_field_specs_on_creation(self): 2641 self.assertRaises(FieldSpecError, Table, 'blah', 'age N(3,2)', on_disk=False) 2642 self.assertRaises(FieldSpecError, Table, 'blah', 'name C(300)', on_disk=False) 2643 self.assertRaises(FieldSpecError, Table, 'blah', 'born L(9)', on_disk=False) 2644 self.assertRaises(FieldSpecError, Table, 'blah', 'married D(12)', on_disk=False) 2645 self.assertRaises(FieldSpecError, Table, 'blah', 'desc M(1)', on_disk=False) 2646 self.assertRaises(FieldSpecError, Table, 'blah', 'desc', on_disk=False) 2647 2648 def test_too_many_fields_on_creation(self): 2649 fields = [] 2650 for i in range(255): 2651 fields.append('a%03d C(10)' % i) 2652 Table(':test:', ';'.join(fields), on_disk=False) 2653 fields.append('a255 C(10)') 2654 self.assertRaises(DbfError, Table, ':test:', ';'.join(fields), on_disk=False) 2655 2656 def test_adding_too_many_fields(self): 2657 fields = [] 2658 for i in range(255): 2659 fields.append('a%03d C(10)' % i) 2660 table = Table(':test:', ';'.join(fields), on_disk=False) 2661 table.open(mode=READ_WRITE) 2662 self.assertRaises(DbfError, table.add_fields, 'a255 C(10)') 2663 2664 def test_adding_too_many_fields_with_null(self): 2665 fields = [] 2666 for i in range(254): 2667 fields.append(u'a%03d C(10) NULL' % i) 2668 table = Table(':test:', u';'.join(fields), dbf_type='vfp', on_disk=False) 2669 table.open(mode=READ_WRITE) 2670 self.assertRaises(DbfError, table.add_fields, u'a255 C(10)') 2671 fields = [] 2672 for i in range(254): 2673 fields.append(u'a%03d C(10) NULL' % i) 2674 table = Table(':test:', u';'.join(fields), dbf_type='vfp', on_disk=False) 2675 table.open(mode=READ_WRITE) 2676 self.assertRaises(DbfError, table.add_fields, u'a255 C(10)') 2677 2678 def test_too_many_records_in_table(self): 2679 "skipped -- test takes waaaaaaay too long" 2680 2681 def test_too_many_fields_to_change_to_null(self): 2682 fields = [] 2683 for i in range(255): 2684 fields.append('a%03d C(10)' % i) 2685 table = Table(':test:', ';'.join(fields), on_disk=False) 2686 table.open(mode=READ_WRITE) 2687 try: 2688 self.assertRaises(DbfError, table.allow_nulls, 'a001') 2689 finally: 2690 table.close() 2691 2692 def test_adding_existing_field_to_table(self): 2693 table = Table(':blah:', 'name C(50)', on_disk=False) 2694 self.assertRaises(DbfError, table.add_fields, 'name C(10)') 2695 2696 def test_deleting_non_existing_field_from_table(self): 2697 table = Table(':bleh:', 'name C(25)', on_disk=False) 2698 self.assertRaises(DbfError, table.delete_fields, 'age') 2699 2700 def test_modify_packed_record(self): 2701 table = Table(':ummm:', 'name C(3); age N(3,0)', on_disk=False) 2702 table.open(mode=READ_WRITE) 2703 for person in (('me', 25), ('you', 35), ('her', 29)): 2704 table.append(person) 2705 record = table[1] 2706 dbf.delete(record) 2707 table.pack() 2708 self.assertEqual(('you', 35), record) 2709 self.assertRaises(DbfError, dbf.write, record, **{'age':33}) 2710 2711 def test_read_only(self): 2712 table = Table(':ahhh:', 'name C(10)', on_disk=False) 2713 table.open(mode=dbf.READ_ONLY) 2714 self.assertRaises(DbfError, table.append, dict(name='uh uh!')) 2715 2716 def test_clipper(self): 2717 Table(os.path.join(tempdir, 'temptable'), 'name C(377); thesis C(20179)', dbf_type='clp') 2718 self.assertRaises(BadDataError, Table, os.path.join(tempdir, 'temptable')) 2719 2720 def test_data_overflow(self): 2721 table = Table(os.path.join(tempdir, 'temptable'), 'mine C(2); yours C(15)') 2722 table.open(mode=READ_WRITE) 2723 table.append(('me',)) 2724 try: 2725 table.append(('yours',)) 2726 except DataOverflowError: 2727 pass 2728 finally: 2729 table.close() 2730 2731 def test_change_null_field(self): 2732 "cannot making an existing field nullable" 2733 table = Table( 2734 os.path.join(tempdir, 'vfp_table'), 2735 'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' + 2736 ' weight F(18,3); age I; meeting T; misc G; photo P; price Y;' + 2737 ' dist B', 2738 dbf_type='vfp', 2739 default_data_types='enhanced', 2740 ) 2741 table.open(mode=READ_WRITE) 2742 namelist = [] 2743 paidlist = [] 2744 qtylist = [] 2745 orderlist = [] 2746 desclist = [] 2747 for i in range(10): 2748 name = words[i] 2749 paid = len(words[i]) % 3 == 0 2750 qty = floats[i] 2751 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 2752 desc = ' '.join(words[i:i+50]) 2753 namelist.append(name) 2754 paidlist.append(paid) 2755 qtylist.append(qty) 2756 orderlist.append(orderdate) 2757 desclist.append(desc) 2758 table.append({u'name':name, u'paid':paid, u'qty':qty, u'orderdate':orderdate, u'desc':desc}) 2759 # plus a blank record 2760 namelist.append('') 2761 paidlist.append(None) 2762 qtylist.append(None) 2763 orderlist.append(None) 2764 desclist.append('') 2765 table.append() 2766 for field in table.field_names: 2767 self.assertEqual(table.nullable_field(field), False) 2768 self.assertRaises(DbfError, table.allow_nulls, (u'name, qty')) 2769 table.close() 2770 2771 2772class TestWarnings(TestCase): 2773 2774 @skipIf(warnings_are_exceptions, '-W error specified') 2775 def test_field_name_warning(self): 2776 with warnings.catch_warnings(record=True) as w: 2777 huh = dbf.Table('cloud', 'p^type C(25)', on_disk=False).open(dbf.READ_WRITE) 2778 self.assertEqual(len(w), 1, str(w)) 2779 warning = w[-1] 2780 self.assertTrue(issubclass(warning.category, dbf.FieldNameWarning)) 2781 huh.resize_field('p^type', 30) 2782 self.assertEqual(len(w), 1, 'warning objects\n'+'\n'.join([str(warning) for warning in w])) 2783 huh.add_fields('c^word C(50)') 2784 self.assertEqual(len(w), 2, str(w)) 2785 warning = w[-1] 2786 self.assertTrue(issubclass(warning.category, dbf.FieldNameWarning)) 2787 2788 @skipUnless(warnings_are_exceptions, 'warnings are just warnings') 2789 def test_field_name_exceptions(self): 2790 with self.assertRaisesRegex(dbf.FieldNameWarning, "is invalid"): 2791 huh = dbf.Table('cloud', 'p^type C(25)', on_disk=False).open(dbf.READ_WRITE) 2792 with self.assertRaisesRegex(dbf.FieldNameWarning, "is invalid"): 2793 huh = dbf.Table('cloud', 'name C(25)', on_disk=False).open(dbf.READ_WRITE) 2794 try: 2795 huh.add_fields('c^word C(50)') 2796 finally: 2797 huh.close() 2798 2799 2800class TestIndexLocation(TestCase): 2801 2802 def test_false(self): 2803 self.assertFalse(IndexLocation(0, False)) 2804 self.assertFalse(IndexLocation(42, False)) 2805 2806 def test_true(self): 2807 self.assertTrue(IndexLocation(0, True)) 2808 self.assertTrue(IndexLocation(42, True)) 2809 2810 2811class TestDbfCreation(TestCase): 2812 "Testing table creation..." 2813 2814 def test_db3_memory_tables(self): 2815 "dbf tables in memory" 2816 fields = unicodify(['name C(25)', 'hiredate D', 'male L', 'wisdom M', 'qty N(3,0)', 'weight F(7,3)']) 2817 for i in range(1, len(fields)+1): 2818 for fieldlist in combinate(fields, i): 2819 table = Table(':memory:', fieldlist, dbf_type='db3', on_disk=False) 2820 actualFields = table.structure() 2821 self.assertEqual(fieldlist, actualFields) 2822 self.assertTrue(all([type(x) is unicode for x in table.field_names])) 2823 2824 def test_db3_disk_tables(self): 2825 "dbf table on disk" 2826 fields = unicodify(['name C(25)', 'hiredate D', 'male L', 'wisdom M', 'qty N(3,0)', 'weight F(7,3)']) 2827 for i in range(1, len(fields)+1): 2828 for fieldlist in combinate(fields, i): 2829 table = Table(os.path.join(tempdir, 'temptable'), ';'.join(fieldlist), dbf_type='db3') 2830 table = Table(os.path.join(tempdir, 'temptable'), dbf_type='db3') 2831 actualFields = table.structure() 2832 self.assertEqual(fieldlist, actualFields) 2833 table = open(table.filename, 'rb') 2834 try: 2835 last_byte = ord(table.read()[-1]) 2836 finally: 2837 table.close() 2838 self.assertEqual(last_byte, EOF) 2839 2840 def test_clp_memory_tables(self): 2841 "clp tables in memory" 2842 fields = unicodify(['name C(10977)', 'hiredate D', 'male L', 'wisdom M', 'qty N(3,0)', 'weight F(7,3)']) 2843 for i in range(1, len(fields)+1): 2844 for fieldlist in combinate(fields, i): 2845 table = Table(':memory:', fieldlist, dbf_type='clp', on_disk=False) 2846 actualFields = table.structure() 2847 self.assertEqual(fieldlist, actualFields) 2848 self.assertTrue(all([type(x) is unicode for x in table.field_names])) 2849 2850 def test_clp_disk_tables(self): 2851 "clp table on disk" 2852 table = Table(os.path.join(tempdir, 'temptable'), u'name C(377); thesis C(20179)', dbf_type='clp') 2853 self.assertEqual(table.record_length, 20557) 2854 fields = unicodify(['name C(10977)', 'hiredate D', 'male L', 'wisdom M', 'qty N(3,0)', 'weight F(7,3)']) 2855 for i in range(1, len(fields)+1): 2856 for fieldlist in combinate(fields, i): 2857 table = Table(os.path.join(tempdir, 'temptable'), u';'.join(fieldlist), dbf_type='clp') 2858 table = Table(os.path.join(tempdir, 'temptable'), dbf_type='clp') 2859 actualFields = table.structure() 2860 self.assertEqual(fieldlist, actualFields) 2861 table = open(table.filename, 'rb') 2862 try: 2863 last_byte = ord(table.read()[-1]) 2864 finally: 2865 table.close() 2866 self.assertEqual(last_byte, EOF) 2867 2868 def test_fp_memory_tables(self): 2869 "fp tables in memory" 2870 fields = unicodify(['name C(25)', 'hiredate D', 'male L', 'wisdom M', 'qty N(3,0)', 2871 'litres F(11,5)', 'blob G', 'graphic P', 'weight F(7,3)']) 2872 for i in range(1, len(fields)+1): 2873 for fieldlist in combinate(fields, i): 2874 table = Table(':memory:', u';'.join(fieldlist), dbf_type='fp', on_disk=False) 2875 actualFields = table.structure() 2876 self.assertEqual(fieldlist, actualFields) 2877 2878 def test_fp_disk_tables(self): 2879 "fp tables on disk" 2880 fields = unicodify(['name C(25)', 'hiredate D', 'male L', 'wisdom M', 'qty N(3,0)', 2881 'litres F(11,5)', 'blob G', 'graphic P', 'weight F(7,3)']) 2882 for i in range(1, len(fields)+1): 2883 for fieldlist in combinate(fields, i): 2884 table = Table(os.path.join(tempdir, 'tempfp'), u';'.join(fieldlist), dbf_type='fp') 2885 table = Table(os.path.join(tempdir, 'tempfp'), dbf_type='fp') 2886 actualFields = table.structure() 2887 self.assertEqual(fieldlist, actualFields) 2888 2889 def test_vfp_memory_tables(self): 2890 "vfp tables in memory" 2891 fields = unicodify(['name C(25)', 'hiredate D', 'male L', 'wisdom M', 'qty N(3,0)', 2892 'mass B', 'litres F(11,5)', 'int I', 'birth T', 'blob G', 'graphic P', 2893 'menu C(50) BINARY', 'graduated L NULL', 'fired D NULL', 'cipher C(50) NOCPTRANS NULL', 2894 'weight F(7,3)']) 2895 2896 for i in range(1, len(fields)+1): 2897 for fieldlist in combinate(fields, i): 2898 table = Table(':memory:', u';'.join(fieldlist), dbf_type='vfp', on_disk=False) 2899 actualFields = table.structure() 2900 fieldlist = [f.replace('NOCPTRANS','BINARY') for f in fieldlist] 2901 self.assertEqual(fieldlist, actualFields) 2902 2903 def test_vfp_disk_tables(self): 2904 "vfp tables on disk" 2905 fields = unicodify(['name C(25)', 'hiredate D', 'male L', 'wisdom M', 'qty N(3,0)', 2906 'mass B', 'litres F(11,5)', 'int I', 'birth T', 'blob G', 'graphic P', 2907 'menu C(50) binary', 'graduated L null', 'fired D NULL', 'cipher C(50) nocptrans NULL', 2908 'weight F(7,3)']) 2909 for i in range(1, len(fields)+1): 2910 for fieldlist in combinate(fields, i): 2911 table = Table(os.path.join(tempdir, 'tempvfp'), u';'.join(fieldlist), dbf_type='vfp') 2912 table = Table(os.path.join(tempdir, 'tempvfp'), dbf_type='vfp') 2913 actualFields = table.structure() 2914 fieldlist = [f.replace('nocptrans','BINARY') for f in fieldlist] 2915 self.assertEqual(fieldlist, actualFields) 2916 2917 def test_codepage(self): 2918 table = Table(os.path.join(tempdir, 'tempvfp'), u'name C(25); male L; fired D NULL', dbf_type='vfp') 2919 table.close() 2920 self.assertEqual(dbf.default_codepage, 'ascii') 2921 self.assertEqual(table.codepage, dbf.CodePage('ascii')) 2922 table.close() 2923 table.open(mode=READ_WRITE) 2924 table.close() 2925 table = Table(os.path.join(tempdir, 'tempvfp'), u'name C(25); male L; fired D NULL', dbf_type='vfp', codepage='cp850') 2926 table.close() 2927 self.assertEqual(table.codepage, dbf.CodePage('cp850')) 2928 2929 newtable = table.new('tempvfp2', codepage='cp437') 2930 self.assertEqual(newtable.codepage, dbf.CodePage('cp437')) 2931 newtable.open(mode=READ_WRITE) 2932 newtable.create_backup() 2933 newtable.close() 2934 bckup = Table(os.path.join(tempdir, newtable.backup)) 2935 self.assertEqual(bckup.codepage, newtable.codepage) 2936 2937 def test_db3_ignore_memos(self): 2938 table = Table(os.path.join(tempdir, 'tempdb3'), u'name C(25); wisdom M', dbf_type='db3').open(mode=READ_WRITE) 2939 table.append(('QC Tester', 'check it twice! check it thrice! check it . . . uh . . . again!')) 2940 table.close() 2941 table = Table(os.path.join(tempdir, 'tempdb3'), dbf_type='db3', ignore_memos=True) 2942 table.open(mode=READ_WRITE) 2943 try: 2944 self.assertEqual(table[0].wisdom, u'') 2945 finally: 2946 table.close() 2947 2948 def test_fp_ignore_memos(self): 2949 table = Table(os.path.join(tempdir, 'tempdb3'), u'name C(25); wisdom M', dbf_type='fp').open(mode=READ_WRITE) 2950 table.append(('QC Tester', 'check it twice! check it thrice! check it . . . uh . . . again!')) 2951 table.close() 2952 table = Table(os.path.join(tempdir, 'tempdb3'), dbf_type='fp', ignore_memos=True) 2953 table.open(mode=READ_WRITE) 2954 try: 2955 self.assertEqual(table[0].wisdom, u'') 2956 finally: 2957 table.close() 2958 2959 def test_vfp_ignore_memos(self): 2960 table = Table(os.path.join(tempdir, 'tempdb3'), u'name C(25); wisdom M', dbf_type='vfp').open(mode=READ_WRITE) 2961 table.append(('QC Tester', 'check it twice! check it thrice! check it . . . uh . . . again!')) 2962 table.close() 2963 table = Table(os.path.join(tempdir, 'tempdb3'), dbf_type='vfp', ignore_memos=True) 2964 table.open(mode=READ_WRITE) 2965 try: 2966 self.assertEqual(table[0].wisdom, u'') 2967 finally: 2968 table.close() 2969 2970 def test_clp_ignore_memos(self): 2971 table = Table(os.path.join(tempdir, 'tempdb3'), u'name C(25); wisdom M', dbf_type='clp').open(mode=READ_WRITE) 2972 table.append(('QC Tester', 'check it twice! check it thrice! check it . . . uh . . . again!')) 2973 table.close() 2974 table = Table(os.path.join(tempdir, 'tempdb3'), dbf_type='clp', ignore_memos=True) 2975 table.open(mode=READ_WRITE) 2976 try: 2977 self.assertEqual(table[0].wisdom, u'') 2978 finally: 2979 table.close() 2980 2981 2982class TestDbfRecords(TestCase): 2983 "Testing records" 2984 2985 def setUp(self): 2986 self.dbf_table = Table( 2987 os.path.join(tempdir, 'dbf_table'), 2988 u'name C(25); paid L; qty N(11,5); orderdate D; desc M', 2989 dbf_type='db3', 2990 ) 2991 self.vfp_table = Table( 2992 os.path.join(tempdir, 'vfp_table'), 2993 u'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' + 2994 u' weight F(18,3); age I; meeting T; misc G; photo P; price Y;' + 2995 u' dist B', 2996 dbf_type='vfp', 2997 default_data_types='enhanced', 2998 ) 2999 self.null_vfp_table = null_table = Table( 3000 os.path.join(tempdir, 'null_vfp_table'), 3001 'first C(25) null; last C(25); height N(3,1) null; age N(3,0); life_story M null; plans M', 3002 dbf_type='vfp', 3003 ) 3004 null_table.open(dbf.READ_WRITE) 3005 null_table.append() 3006 null_table.close() 3007 3008 def tearDown(self): 3009 self.dbf_table.close() 3010 self.vfp_table.close() 3011 self.null_vfp_table.close() 3012 3013 def test_slicing(self): 3014 table = self.dbf_table 3015 table.open(mode=READ_WRITE) 3016 table.append(('myself', True, 5.97, dbf.Date(2012, 5, 21), 'really cool')) 3017 self.assertEqual(table.first_record[u'name':u'qty'], table[0][:3]) 3018 3019 def test_dbf_adding_records(self): 3020 "dbf table: adding records" 3021 table = self.dbf_table 3022 table.open(mode=READ_WRITE) 3023 namelist = [] 3024 paidlist = [] 3025 qtylist = [] 3026 orderlist = [] 3027 desclist = [] 3028 for i in range(len(floats)): 3029 name = words[i] 3030 paid = len(words[i]) % 3 == 0 3031 qty = floats[i] 3032 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 3033 desc = ' '.join(words[i:i+50]) 3034 namelist.append(name) 3035 paidlist.append(paid) 3036 qtylist.append(qty) 3037 orderlist.append(orderdate) 3038 desclist.append(desc) 3039 table.append(unicodify({'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc})) 3040 record = table[-1] 3041 3042 t = open(table.filename, 'rb') 3043 last_byte = ord(t.read()[-1]) 3044 t.close() 3045 self.assertEqual(last_byte, EOF) 3046 self.assertEqual(record.name.strip(), name) 3047 self.assertEqual(record.paid, paid) 3048 self.assertEqual(record.qty, round(qty, 5)) 3049 self.assertEqual(record.orderdate, orderdate) 3050 self.assertEqual(record.desc.strip(), desc) 3051 # plus a blank record 3052 namelist.append('') 3053 paidlist.append(None) 3054 qtylist.append(None) 3055 orderlist.append(None) 3056 desclist.append('') 3057 blank_record = table.append() 3058 self.assertEqual(len(table), len(floats)+1) 3059 for field in table.field_names: 3060 self.assertEqual(1, table.field_names.count(field)) 3061 table.close() 3062 t = open(table.filename, 'rb') 3063 last_byte = ord(t.read()[-1]) 3064 t.close() 3065 self.assertEqual(last_byte, EOF) 3066 table = Table(table.filename, dbf_type='db3') 3067 table.open(mode=READ_WRITE) 3068 self.assertEqual(len(table), len(floats)+1) 3069 for field in table.field_names: 3070 self.assertEqual(1, table.field_names.count(field)) 3071 i = 0 3072 for record in table[:-1]: 3073 i += 1 3074 continue 3075 self.assertEqual(dbf.recno(record), i) 3076 self.assertEqual(table[i].name.strip(), namelist[i]) 3077 self.assertEqual(record.name.strip(), namelist[i]) 3078 self.assertEqual(table[i].paid, paidlist[i]) 3079 self.assertEqual(record.paid, paidlist[i]) 3080 self.assertEqual(abs(table[i].qty - qtylist[i]) < .00001, True) 3081 self.assertEqual(abs(record.qty - qtylist[i]) < .00001, True) 3082 self.assertEqual(table[i].orderdate, orderlist[i]) 3083 self.assertEqual(record.orderdate, orderlist[i]) 3084 self.assertEqual(table[i].desc.strip(), desclist[i]) 3085 self.assertEqual(record.desc.strip(), desclist[i]) 3086 i += 1 3087 record = table[-1] 3088 self.assertEqual(dbf.recno(record), i) 3089 self.assertEqual(table[i].name.strip(), namelist[i]) 3090 self.assertEqual(record.name.strip(), namelist[i]) 3091 self.assertEqual(table[i].paid, paidlist[i]) 3092 self.assertEqual(record.paid, paidlist[i]) 3093 self.assertEqual(table[i].qty, qtylist[i]) 3094 self.assertEqual(record.qty, qtylist[i]) 3095 self.assertEqual(table[i].orderdate, orderlist[i]) 3096 self.assertEqual(record.orderdate, orderlist[i]) 3097 self.assertEqual(table[i].desc, desclist[i]) 3098 self.assertEqual(record.desc, desclist[i]) 3099 i += 1 3100 self.assertEqual(i, len(table)) 3101 table.close() 3102 3103 def test_vfp_adding_records(self): 3104 "vfp table: adding records" 3105 table = self.vfp_table 3106 table.open(mode=READ_WRITE) 3107 namelist = [] 3108 paidlist = [] 3109 qtylist = [] 3110 orderlist = [] 3111 desclist = [] 3112 masslist = [] 3113 weightlist = [] 3114 agelist = [] 3115 meetlist = [] 3116 misclist = [] 3117 photolist = [] 3118 pricelist = [] 3119 distlist = [] 3120 for i in range(len(floats)): 3121 name = words[i] 3122 paid = len(words[i]) % 3 == 0 3123 qty = floats[i] 3124 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 3125 desc = ' '.join(words[i:i+50]) 3126 mass = floats[i] * floats[i] / 2.0 3127 weight = floats[i] * 3 3128 dist = floats[i] * 2 3129 age = numbers[i] 3130 meeting = datetime.datetime((numbers[i] + 2000), (numbers[i] % 12)+1, (numbers[i] % 28)+1, 3131 (numbers[i] % 24), numbers[i] % 60, (numbers[i] * 3) % 60) 3132 misc = (' '.join(words[i:i+50:3])).encode('ascii') 3133 photo = (' '.join(words[i:i+50:7])).encode('ascii') 3134 price = Decimal(round(floats[i] * 2.182737, 4)) 3135 namelist.append(name) 3136 paidlist.append(paid) 3137 qtylist.append(qty) 3138 orderlist.append(orderdate) 3139 desclist.append(desc) 3140 masslist.append(mass) 3141 distlist.append(dist) 3142 weightlist.append(weight) 3143 agelist.append(age) 3144 meetlist.append(meeting) 3145 misclist.append(misc) 3146 photolist.append(photo) 3147 pricelist.append(price) 3148 table.append(unicodify({'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc, 3149 'mass':mass, 'weight':weight, 'age':age, 'meeting':meeting, 'misc':misc, 'photo':photo, 3150 'dist': dist, 'price':price})) 3151 record = table[-1] 3152 self.assertEqual(record.name.strip(), name) 3153 self.assertEqual(record.paid, paid) 3154 self.assertEqual(round(record.qty, 5), round(qty, 5)) 3155 self.assertEqual(record.orderdate, orderdate) 3156 self.assertEqual(record.desc.strip(), desc) 3157 self.assertEqual(record.mass, mass) 3158 self.assertEqual(record.dist, dist) 3159 self.assertEqual(round(record.weight, 3), round(weight, 3)) 3160 self.assertEqual(record.age, age) 3161 self.assertEqual(record.meeting, meeting) 3162 self.assertEqual(record.misc, misc) 3163 self.assertEqual(record.photo, photo) 3164 self.assertEqual(round(record.price, 4), round(price, 4)) 3165 # plus a blank record 3166 namelist.append('') 3167 paidlist.append(Unknown) 3168 qtylist.append(None) 3169 orderlist.append(NullDate) 3170 desclist.append('') 3171 masslist.append(0.0) 3172 distlist.append(0.0) 3173 weightlist.append(None) 3174 agelist.append(0) 3175 meetlist.append(NullDateTime) 3176 misclist.append(''.encode('ascii')) 3177 photolist.append(''.encode('ascii')) 3178 pricelist.append(Decimal('0.0')) 3179 table.append() 3180 table.close() 3181 table = Table(table.filename, dbf_type='vfp') 3182 table.open(mode=READ_WRITE) 3183 self.assertEqual(len(table), len(floats)+1) 3184 i = 0 3185 for record in table[:-1]: 3186 self.assertEqual(dbf.recno(record), i) 3187 self.assertEqual(table[i].name.strip(), namelist[i]) 3188 self.assertEqual(record.name.strip(), namelist[i]) 3189 self.assertEqual(table[i].paid, paidlist[i]) 3190 self.assertEqual(record.paid, paidlist[i]) 3191 self.assertEqual(abs(table[i].qty - qtylist[i]) < .00001, True) 3192 self.assertEqual(abs(record.qty - qtylist[i]) < .00001, True) 3193 self.assertEqual(table[i].orderdate, orderlist[i]) 3194 self.assertEqual(record.orderdate, orderlist[i]) 3195 self.assertEqual(table[i].desc.strip(), desclist[i]) 3196 self.assertEqual(record.desc.strip(), desclist[i]) 3197 self.assertEqual(record.mass, masslist[i]) 3198 self.assertEqual(record.dist, distlist[i]) 3199 self.assertEqual(table[i].mass, masslist[i]) 3200 self.assertEqual(record.weight, round(weightlist[i], 3)) 3201 self.assertEqual(table[i].weight, round(weightlist[i], 3)) 3202 self.assertEqual(record.age, agelist[i]) 3203 self.assertEqual(table[i].age, agelist[i]) 3204 self.assertEqual(record.meeting, meetlist[i]) 3205 self.assertEqual(table[i].meeting, meetlist[i]) 3206 self.assertEqual(record.misc, misclist[i]) 3207 self.assertEqual(table[i].misc, misclist[i]) 3208 self.assertEqual(record.photo, photolist[i]) 3209 self.assertEqual(table[i].photo, photolist[i]) 3210 self.assertEqual(round(record.price, 4), round(pricelist[i], 4)) 3211 self.assertEqual(round(table[i].price, 4), round(pricelist[i], 4)) 3212 i += 1 3213 record = table[-1] 3214 self.assertEqual(dbf.recno(record), i) 3215 self.assertEqual(table[i].name.strip(), namelist[i]) 3216 self.assertEqual(record.name.strip(), namelist[i]) 3217 self.assertEqual(table[i].paid is None, True) 3218 self.assertEqual(record.paid is None, True) 3219 self.assertEqual(table[i].qty, None) 3220 self.assertEqual(record.qty, None) 3221 self.assertEqual(table[i].orderdate, orderlist[i]) 3222 self.assertEqual(record.orderdate, orderlist[i]) 3223 self.assertEqual(table[i].desc, desclist[i]) 3224 self.assertEqual(record.desc, desclist[i]) 3225 self.assertEqual(record.mass, masslist[i]) 3226 self.assertEqual(table[i].mass, masslist[i]) 3227 self.assertEqual(record.dist, distlist[i]) 3228 self.assertEqual(table[i].dist, distlist[i]) 3229 self.assertEqual(record.weight, weightlist[i]) 3230 self.assertEqual(table[i].weight, weightlist[i]) 3231 self.assertEqual(record.age, agelist[i]) 3232 self.assertEqual(table[i].age, agelist[i]) 3233 self.assertEqual(record.meeting, meetlist[i]) 3234 self.assertEqual(table[i].meeting, meetlist[i]) 3235 self.assertEqual(record.misc, misclist[i]) 3236 self.assertEqual(table[i].misc, misclist[i]) 3237 self.assertEqual(record.photo, photolist[i]) 3238 self.assertEqual(table[i].photo, photolist[i]) 3239 self.assertEqual(record.price, 0) 3240 self.assertEqual(table[i].price, 0) 3241 i += 1 3242 table.close() 3243 3244 def test_char_memo_return_type(self): 3245 "check character fields return type" 3246 table = Table(':memory:', 'text C(50); memo M', codepage='cp1252', dbf_type='vfp', on_disk=False) 3247 table.open(mode=READ_WRITE) 3248 table.append(('another one bites the dust', "and another one's gone, and another one's gone...")) 3249 table.append() 3250 for record in table: 3251 self.assertTrue(type(record.text) is unicode) 3252 self.assertTrue(type(record.memo) is unicode) 3253 3254 table = Table(':memory:', 'text C(50); memo M', codepage='cp1252', dbf_type='vfp', 3255 default_data_types=dict(C=Char, M=Char), on_disk=False) 3256 table.open(mode=READ_WRITE) 3257 table.append(('another one bites the dust', "and another one's gone, and another one's gone...")) 3258 table.append() 3259 for record in table: 3260 self.assertTrue(type(record.text) is Char) 3261 self.assertTrue(type(record.memo) is Char) 3262 3263 table = Table(':memory:', 'text C(50); memo M', codepage='cp1252', dbf_type='vfp', 3264 default_data_types=dict(C=(Char, NoneType), M=(Char, NoneType)), on_disk=False) 3265 table.open(mode=READ_WRITE) 3266 table.append(('another one bites the dust', "and another one's gone, and another one's gone...")) 3267 table.append() 3268 record = table[0] 3269 self.assertTrue(type(record.text) is Char) 3270 self.assertTrue(type(record.memo) is Char) 3271 record = table[1] 3272 self.assertTrue(type(record.text) is NoneType) 3273 self.assertTrue(type(record.memo) is NoneType) 3274 3275 def test_empty_is_none(self): 3276 "empty and None values" 3277 table = Table(':memory:', 'name C(20); born L; married D; appt T; wisdom M', dbf_type='vfp', on_disk=False) 3278 table.open(mode=READ_WRITE) 3279 table.append() 3280 record = table[-1] 3281 self.assertTrue(record.born is None) 3282 self.assertTrue(record.married is None) 3283 self.assertTrue(record.appt is None) 3284 self.assertEqual(record.wisdom, '') 3285 appt = DateTime.now() 3286 dbf.write( 3287 record, 3288 born = True, 3289 married = Date(1992, 6, 27), 3290 appt = appt, 3291 wisdom = 'Choose Python', 3292 ) 3293 self.assertTrue(record.born) 3294 self.assertEqual(record.married, Date(1992, 6, 27)) 3295 self.assertEqual(record.appt, appt) 3296 self.assertEqual(record.wisdom, 'Choose Python') 3297 dbf.write( 3298 record, 3299 born = Unknown, 3300 married = NullDate, 3301 appt = NullDateTime, 3302 wisdom = '', 3303 ) 3304 self.assertTrue(record.born is None) 3305 self.assertTrue(record.married is None) 3306 self.assertTrue(record.appt is None) 3307 self.assertEqual(record.wisdom, '') 3308 3309 def test_custom_data_type(self): 3310 "custom data types" 3311 table = Table( 3312 filename=':memory:', 3313 field_specs='name C(20); born L; married D; appt T; wisdom M', 3314 field_data_types=dict(name=Char, born=Logical, married=Date, appt=DateTime, wisdom=Char,), 3315 dbf_type='vfp', 3316 on_disk=False, 3317 ) 3318 table.open(mode=READ_WRITE) 3319 table.append() 3320 record = table[-1] 3321 self.assertTrue(type(record.name) is Char, "record.name is %r, not Char" % type(record.name)) 3322 self.assertTrue(type(record.born) is Logical, "record.born is %r, not Logical" % type(record.born)) 3323 self.assertTrue(type(record.married) is Date, "record.married is %r, not Date" % type(record.married)) 3324 self.assertTrue(type(record.appt) is DateTime, "record.appt is %r, not DateTime" % type(record.appt)) 3325 self.assertTrue(type(record.wisdom) is Char, "record.wisdom is %r, not Char" % type(record.wisdom)) 3326 self.assertEqual(record.name, ' ' * 20) 3327 self.assertTrue(record.born is Unknown, "record.born is %r, not Unknown" % record.born) 3328 self.assertTrue(record.married is NullDate, "record.married is %r, not NullDate" % record.married) 3329 self.assertEqual(record.married, None) 3330 self.assertTrue(record.appt is NullDateTime, "record.appt is %r, not NullDateTime" % record.appt) 3331 self.assertEqual(record.appt, None) 3332 appt = DateTime.now() 3333 dbf.write( 3334 record, 3335 name = 'Ethan ', 3336 born = True, 3337 married = Date(1992, 6, 27), 3338 appt = appt, 3339 wisdom = 'Choose Python', 3340 ) 3341 self.assertEqual(type(record.name), Char, "record.wisdom is %r, but should be Char" % record.wisdom) 3342 self.assertTrue(record.born is Truth) 3343 self.assertEqual(record.married, Date(1992, 6, 27)) 3344 self.assertEqual(record.appt, appt) 3345 self.assertEqual(type(record.wisdom), Char, "record.wisdom is %r, but should be Char" % record.wisdom) 3346 self.assertEqual(record.wisdom, 'Choose Python') 3347 dbf.write(record, born=Falsth) 3348 self.assertEqual(record.born, False) 3349 dbf.write(record, born=None, married=None, appt=None, wisdom=None) 3350 self.assertTrue(record.born is Unknown) 3351 self.assertTrue(record.married is NullDate) 3352 self.assertTrue(record.appt is NullDateTime) 3353 self.assertTrue(type(record.wisdom) is Char, "record.wisdom is %r, but should be Char" % type(record.wisdom)) 3354 3355 def test_datatypes_param(self): 3356 "field_types with normal data type but None on empty" 3357 table = Table( 3358 filename=':memory:', 3359 field_specs='name C(20); born L; married D; wisdom M', 3360 field_data_types=dict(name=(str, NoneType), born=(bool, bool)), 3361 dbf_type='db3', 3362 on_disk=False, 3363 ) 3364 table.open(mode=READ_WRITE) 3365 table.append() 3366 record = table[-1] 3367 self.assertTrue(type(record.name) is type(None), "record.name is %r, not None" % type(record.name)) 3368 self.assertTrue(type(record.born) is bool, "record.born is %r, not bool" % type(record.born)) 3369 self.assertTrue(record.name is None) 3370 self.assertTrue(record.born is False, "record.born is %r, not False" % record.born) 3371 dbf.write(record, name='Ethan ', born=True) 3372 self.assertEqual(type(record.name), str, "record.name is %r, but should be Char" % record.wisdom) 3373 self.assertTrue(record.born is True) 3374 dbf.write(record, born=False) 3375 self.assertEqual(record.born, False) 3376 dbf.write( 3377 record, 3378 name = None, 3379 born = None, 3380 ) 3381 self.assertTrue(record.name is None) 3382 self.assertTrue(record.born is False) 3383 3384 def test_null_type(self): 3385 "NullType" 3386 table = Table( 3387 filename=':memory:', 3388 field_specs='name C(20) NULL; born L NULL; married D NULL; appt T NULL; wisdom M NULL', 3389 default_data_types=dict( 3390 C=(Char, NoneType, NullType), 3391 L=(Logical, NoneType, NullType), 3392 D=(Date, NoneType, NullType), 3393 T=(DateTime, NoneType, NullType), 3394 M=(Char, NoneType, NullType), 3395 ), 3396 dbf_type='vfp', 3397 on_disk=False, 3398 ) 3399 table.open(mode=READ_WRITE) 3400 table.append() 3401 record = table[-1] 3402 self.assertIs(record.name, Null) 3403 self.assertIs(record.born, Null) 3404 self.assertIs(record.married, Null) 3405 self.assertIs(record.appt, Null) 3406 self.assertIs(record.wisdom, Null) 3407 appt = datetime.datetime(2012, 12, 15, 9, 37, 11) 3408 dbf.write( 3409 record, 3410 name = 'Ethan ', 3411 born = True, 3412 married = datetime.date(2001, 6, 27), 3413 appt = appt, 3414 wisdom = 'timing is everything', 3415 ) 3416 record = table[-1] 3417 self.assertEqual(record.name, u'Ethan') 3418 self.assertEqual(type(record.name), Char) 3419 self.assertTrue(record.born) 3420 self.assertTrue(record.born is Truth) 3421 self.assertEqual(record.married, datetime.date(2001, 6, 27)) 3422 self.assertEqual(type(record.married), Date) 3423 self.assertEqual(record.appt, datetime.datetime(2012, 12, 15, 9, 37, 11)) 3424 self.assertEqual(type(record.appt), DateTime) 3425 self.assertEqual(record.wisdom, u'timing is everything') 3426 self.assertEqual(type(record.wisdom), Char) 3427 dbf.write(record, name=Null, born=Null, married=Null, appt=Null, wisdom=Null) 3428 self.assertTrue(record.name is Null) 3429 self.assertTrue(record.born is Null) 3430 self.assertTrue(record.married is Null) 3431 self.assertTrue(record.appt is Null) 3432 self.assertTrue(record.wisdom is Null) 3433 dbf.write( 3434 record, 3435 name = None, 3436 born = None, 3437 married = None, 3438 appt = None, 3439 wisdom = None, 3440 ) 3441 record = table[-1] 3442 self.assertTrue(record.name is None) 3443 self.assertTrue(record.born is None) 3444 self.assertTrue(record.married is None) 3445 self.assertTrue(record.appt is None) 3446 self.assertTrue(record.wisdom is None) 3447 table = Table( 3448 filename=':memory:', 3449 field_specs='name C(20); born L; married D NULL; appt T; wisdom M; pets L; cars N(3,0) NULL; story M; died D NULL;', 3450 default_data_types=dict( 3451 C=(Char, NoneType, NullType), 3452 L=(Logical, NoneType, NullType), 3453 D=(Date, NoneType, NullType), 3454 T=(DateTime, NoneType, NullType), 3455 M=(Char, NoneType, NullType), 3456 N=(int, NoneType, NullType), 3457 ), 3458 dbf_type='vfp', 3459 on_disk=False, 3460 ) 3461 table.open(mode=READ_WRITE) 3462 table.append() 3463 record = table[-1] 3464 self.assertTrue(record.name is None) 3465 self.assertTrue(record.born is None) 3466 self.assertTrue(record.married is Null) 3467 self.assertTrue(record.appt is None) 3468 self.assertTrue(record.wisdom is None) 3469 self.assertTrue(record.pets is None) 3470 self.assertTrue(record.cars is Null) 3471 self.assertTrue(record.story is None) 3472 self.assertTrue(record.died is Null) 3473 dbf.write( 3474 record, 3475 name = 'Ethan ', 3476 born = True, 3477 married = datetime.date(2001, 6, 27), 3478 appt = appt, 3479 wisdom = 'timing is everything', 3480 pets = True, 3481 cars = 10, 3482 story = 'a poor farm boy who made good', 3483 died = datetime.date(2018, 5, 30), 3484 ) 3485 record = table[-1] 3486 self.assertEqual(record.name, 'Ethan') 3487 self.assertTrue(record.born) 3488 self.assertTrue(record.born is Truth) 3489 self.assertEqual(record.married, datetime.date(2001, 6, 27)) 3490 self.assertEqual(record.appt, datetime.datetime(2012, 12, 15, 9, 37, 11)) 3491 self.assertEqual(record.wisdom, 'timing is everything') 3492 self.assertTrue(record.pets) 3493 self.assertEqual(record.cars, 10) 3494 self.assertEqual(record.story, 'a poor farm boy who made good',) 3495 self.assertEqual(record.died, datetime.date(2018, 5, 30)) 3496 dbf.write(record, married=Null, died=Null) 3497 record = table[-1] 3498 self.assertTrue(record.married is Null) 3499 self.assertTrue(record.died is Null) 3500 3501 def test_nonascii_text_cptrans(self): 3502 "check non-ascii text to unicode" 3503 table = Table(':memory:', 'data C(50); memo M', codepage='cp437', dbf_type='vfp', on_disk=False) 3504 table.open(mode=READ_WRITE) 3505 decoder = codecs.getdecoder('cp437') 3506 if py_ver < (3, 0): 3507 high_ascii = decoder(''.join(chr(c) for c in range(128, 128+50)))[0] 3508 else: 3509 high_ascii = bytes(range(128, 128+50)).decode('cp437') 3510 table.append(dict(data=high_ascii, memo=high_ascii)) 3511 self.assertEqual(table[0].data, high_ascii) 3512 self.assertEqual(table[0].memo, high_ascii) 3513 table.close() 3514 3515 def test_nonascii_text_no_cptrans(self): 3516 "check non-ascii text to bytes" 3517 table = Table(':memory:', 'bindata C(50) BINARY; binmemo M BINARY', codepage='cp1252', dbf_type='vfp', on_disk=False) 3518 table.open(mode=READ_WRITE) 3519 if py_ver < (3, 0): 3520 high_ascii = ''.join(chr(c) for c in range(128, 128+50)) 3521 else: 3522 high_ascii = bytes(range(128, 128+50)) 3523 table.append(dict(bindata=high_ascii, binmemo=high_ascii)) 3524 bindata = table[0].bindata 3525 binmemo = table[0].binmemo 3526 self.assertTrue(isinstance(bindata, bytes)) 3527 self.assertTrue(isinstance(binmemo, bytes)) 3528 self.assertEqual(table[0].bindata, high_ascii) 3529 self.assertEqual(table[0].binmemo, high_ascii) 3530 table.close() 3531 3532 def test_add_null_field(self): 3533 "adding a NULL field to an existing table" 3534 table = Table( 3535 self.vfp_table.filename, 3536 'name C(50); age N(3,0)', 3537 dbf_type='vfp', 3538 ) 3539 table.open(mode=READ_WRITE) 3540 def _50(text): 3541 return text + ' ' * (50 - len(text)) 3542 data = ( (_50('Ethan'), 29), (_50('Joseph'), 33), (_50('Michael'), 54), ) 3543 for datum in data: 3544 table.append(datum) 3545 for datum, recordnum in zip(data, table): 3546 self.assertEqual(datum, tuple(recordnum)) 3547 table.add_fields('fired D NULL') 3548 for datum, recordnum in zip(data, table): 3549 self.assertEqual(datum, tuple(recordnum)[:2]) 3550 data += ((_50('Daniel'), 44, Null), ) 3551 table.append(('Daniel', 44, Null)) 3552 for datum, recordnum in zip(data, table): 3553 self.assertEqual(datum[:2], tuple(recordnum)[:2]) 3554 self.assertTrue(datum[2] is recordnum[2]) 3555 table.close() 3556 table = Table(table.filename) 3557 table.open(mode=READ_WRITE) 3558 for datum, recordnum in zip(data, table): 3559 self.assertEqual(datum[0:2], tuple(recordnum)[:2]) 3560 self.assertTrue(datum[2] is recordnum[2]) 3561 table.close() 3562 3563 def test_remove_null_field(self): 3564 "removing NULL fields from an existing table" 3565 table = Table( 3566 self.vfp_table.filename, 3567 'name C(50); age N(3,0); fired D NULL', 3568 dbf_type='vfp', 3569 ) 3570 table.open(mode=READ_WRITE) 3571 def _50(text): 3572 return text + ' ' * (50 - len(text)) 3573 data = ( (_50('Ethan'), 29, Null), (_50('Joseph'), 33, Null), (_50('Michael'), 54, Date(2010, 5, 3))) 3574 for datum in data: 3575 table.append(datum) 3576 for datum, recordnum in zip(data, table): 3577 self.assertEqual(datum[:2], tuple(recordnum)[:2]) 3578 self.assertTrue(datum[2] is recordnum[2] or datum[2] == recordnum[2]) 3579 table.delete_fields('fired') 3580 for datum, recordnum in zip(data, table): 3581 self.assertEqual(datum[:2], tuple(recordnum)) 3582 data += ((_50('Daniel'), 44), ) 3583 table.append(('Daniel', 44)) 3584 for datum, recordnum in zip(data, table): 3585 self.assertEqual(datum[:2], tuple(recordnum)) 3586 table.close() 3587 table = Table(table.filename) 3588 table.open(mode=READ_WRITE) 3589 for datum, recordnum in zip(data, table): 3590 self.assertEqual(datum[:2], tuple(recordnum)) 3591 table.close() 3592 3593 def test_add_field_to_null(self): 3594 "adding a normal field to a table with NULL fields" 3595 table = Table( 3596 self.vfp_table.filename, 3597 'name C(50); age N(3,0); fired D NULL', 3598 dbf_type='vfp', 3599 ) 3600 table.open(mode=READ_WRITE) 3601 def _50(text): 3602 return text + ' ' * (50 - len(text)) 3603 data = ( (_50('Ethan'), 29, Null), (_50('Joseph'), 33, Null), (_50('Michael'), 54, Date(2010, 7, 4)), ) 3604 for datum in data: 3605 table.append(datum) 3606 for datum, recordnum in zip(data, table): 3607 self.assertEqual(datum[:2], tuple(recordnum)[:2]) 3608 self.assertTrue(datum[2] is recordnum[2] or datum[2] == recordnum[2]) 3609 table.add_fields('tenure N(3,0)') 3610 for datum, recordnum in zip(data, table): 3611 self.assertEqual(datum[:2], tuple(recordnum)[:2]) 3612 self.assertTrue(datum[2] is recordnum[2] or datum[2] == recordnum[2]) 3613 data += ((_50('Daniel'), 44, Date(2005, 1, 31), 15 ), ) 3614 table.append(('Daniel', 44, Date(2005, 1, 31), 15)) 3615 for datum, recordnum in zip(data, table): 3616 self.assertEqual(datum[:2], tuple(recordnum)[:2]) 3617 self.assertTrue(datum[2] is recordnum[2] or datum[2] == recordnum[2]) 3618 self.assertEqual(datum[3], recordnum[3]) 3619 table.close() 3620 table = Table(table.filename) 3621 table.open(mode=READ_WRITE) 3622 for datum, recordnum in zip(data, table): 3623 self.assertEqual(datum[:2], tuple(recordnum)[:2]) 3624 self.assertTrue(datum[2] is recordnum[2] or datum[2] == recordnum[2]) 3625 self.assertEqual(datum[3], recordnum[3]) 3626 table.close() 3627 3628 def test_remove_field_from_null(self): 3629 "removing a normal field from a table with NULL fields" 3630 table = Table( 3631 self.vfp_table.filename, 3632 'name C(50); age N(3,0); fired D NULL', 3633 dbf_type='vfp', 3634 ) 3635 table.open(mode=READ_WRITE) 3636 def _50(text): 3637 return text + ' ' * (50 - len(text)) 3638 data = ( (_50('Ethan'), 29, Null), (_50('Joseph'), 33, Null), (_50('Michael'), 54, Date(2010, 7, 4)), ) 3639 for datum in data: 3640 table.append(datum) 3641 for datum, recordnum in zip(data, table): 3642 self.assertEqual(datum[:2], tuple(recordnum)[:2]) 3643 self.assertTrue(datum[2] is recordnum[2] or datum[2] == recordnum[2]) 3644 table.delete_fields('age') 3645 for datum, recordnum in zip(data, table): 3646 self.assertEqual(datum[0], recordnum[0]) 3647 self.assertTrue(datum[-1] is recordnum[1] or datum[-1] == recordnum[1]) 3648 data += ((_50('Daniel'), Date(2001, 11, 13)), ) 3649 table.append(('Daniel', Date(2001, 11, 13))) 3650 for datum, recordnum in zip(data, table): 3651 self.assertEqual(datum[0], recordnum[0]) 3652 self.assertTrue(datum[-1] is recordnum[1] or datum[-1] == recordnum[1]) 3653 table.close() 3654 table = Table(table.filename) 3655 table.open(mode=READ_WRITE) 3656 for datum, recordnum in zip(data, table): 3657 self.assertEqual(datum[0], recordnum[0]) 3658 self.assertTrue(datum[-1] is recordnum[-1] or datum[-1] == recordnum[-1], "name = %s; datum[-1] = %r; recordnum[-1] = %r" % (datum[0], datum[-1], recordnum[-1])) 3659 table.close() 3660 3661 def test_blank_record_template_uses_null(self): 3662 nullable = self.null_vfp_table 3663 with nullable: 3664 rec = nullable[-1] 3665 self.assertTrue(rec.first is Null, "rec.first is %r" % (rec.first, )) 3666 self.assertTrue(rec.last == ' '*25, "rec.last is %r" % (rec.last, )) 3667 self.assertTrue(rec.height is Null, "rec.height is %r" % (rec.height, )) 3668 self.assertTrue(rec.age is None, "rec.age is %r" % (rec.age, )) 3669 self.assertTrue(rec.life_story is Null, "rec.life_story is %r" % (rec.life_story, )) 3670 self.assertTrue(rec.plans == '', "rec.plans is %r" % (rec.plans, )) 3671 nullable.close() 3672 nullable = Table( 3673 self.null_vfp_table.filename, 3674 default_data_types='enhanced', 3675 ) 3676 with nullable: 3677 rec = nullable[-1] 3678 self.assertTrue(rec.first is Null, "rec.first is %r" % (rec.first, )) 3679 self.assertTrue(rec.last == '', "rec.last is %r" % (rec.last, )) 3680 self.assertTrue(rec.height is Null, "rec.height is %r" % (rec.height, )) 3681 self.assertTrue(rec.age is None, "rec.age is %r" % (rec.age, )) 3682 self.assertTrue(rec.life_story is Null, "rec.life_story is %r" % (rec.life_story, )) 3683 self.assertTrue(rec.plans == '', "rec.plans is %r" % (rec.plans, )) 3684 nullable.close() 3685 nullable = Table( 3686 self.null_vfp_table.filename, 3687 default_data_types=dict( 3688 C=(Char, NoneType, NullType), 3689 L=(Logical, NoneType, NullType), 3690 D=(Date, NoneType, NullType), 3691 T=(DateTime, NoneType, NullType), 3692 M=(Char, NoneType, NullType), 3693 ), 3694 ) 3695 with nullable: 3696 rec = nullable[-1] 3697 self.assertTrue(rec.first is Null, "rec.first is %r" % (rec.first, )) 3698 self.assertTrue(rec.last is None, "rec.last is %r" % (rec.last, )) 3699 self.assertTrue(rec.height is Null, "rec.height is %r" % (rec.height, )) 3700 self.assertTrue(rec.age is None, "rec.age is %r" % (rec.age, )) 3701 self.assertTrue(rec.life_story is Null, "rec.life_story is %r" % (rec.life_story, )) 3702 self.assertTrue(rec.plans is None, "rec.plans is %r" % (rec.plans, )) 3703 3704 def test_new_record_with_partial_fields_respects_null(self): 3705 nullable = self.null_vfp_table 3706 nullable.close() 3707 nullable = Table( 3708 self.null_vfp_table.filename, 3709 default_data_types=dict( 3710 C=(Char, NoneType, NullType), 3711 L=(Logical, NoneType, NullType), 3712 D=(Date, NoneType, NullType), 3713 T=(DateTime, NoneType, NullType), 3714 M=(Char, NoneType, NullType), 3715 ), 3716 ) 3717 with nullable: 3718 nullable.append({'first': 'ethan', 'last':'doe'}) 3719 rec = nullable[-1] 3720 self.assertTrue(rec.first == 'ethan', "rec.first is %r" % (rec.first, )) 3721 self.assertTrue(rec.last == 'doe', "rec.last is %r" % (rec.last, )) 3722 self.assertTrue(rec.height is Null, "rec.height is %r" % (rec.height, )) 3723 self.assertTrue(rec.age is None, "rec.age is %r" % (rec.age, )) 3724 self.assertTrue(rec.life_story is Null, "rec.life_story is %r" % (rec.life_story, )) 3725 self.assertTrue(rec.plans is None, "rec.plans is %r" % (rec.plans, )) 3726 nullable.close() 3727 3728 def test_flux_internal(self): 3729 "commit and rollback of flux record (implementation detail)" 3730 table = self.dbf_table 3731 table.open(mode=READ_WRITE) 3732 table.append(('dbf master', True, 77, Date(2012, 5, 20), "guru of some things dbf-y")) 3733 record = table[-1] 3734 old_data = dbf.scatter(record) 3735 record._start_flux() 3736 record.name = 'novice' 3737 record.paid = False 3738 record.qty = 69 3739 record.orderdate = Date(2011, 1, 1) 3740 record.desc = 'master of all he surveys' 3741 try: 3742 self.assertEqual( 3743 dbf.scatter(record), 3744 dict( 3745 name=unicode('novice '), 3746 paid=False, 3747 qty=69, 3748 orderdate=datetime.date(2011, 1, 1), 3749 desc='master of all he surveys', 3750 )) 3751 finally: 3752 record._rollback_flux() 3753 self.assertEqual(old_data, dbf.scatter(record)) 3754 record._start_flux() 3755 record.name = 'novice' 3756 record.paid = False 3757 record.qty = 69 3758 record.orderdate = Date(2011, 1, 1) 3759 record._commit_flux() 3760 self.assertEqual( 3761 dbf.scatter(record), 3762 dict( 3763 name=unicode('novice '), 3764 paid=False, 3765 qty=69, 3766 orderdate=datetime.date(2011, 1, 1), 3767 desc='guru of some things dbf-y', 3768 )) 3769 self.assertNotEqual(old_data, dbf.scatter(record)) 3770 3771 def test_field_capitalization(self): 3772 "ensure mixed- and upper-case field names work" 3773 table = dbf.Table('mixed', 'NAME C(30); Age N(5,2)', on_disk=False) 3774 self.assertEqual(['NAME', 'AGE'], field_names(table)) 3775 table.open(dbf.READ_WRITE) 3776 table.append({'Name':'Ethan', 'AGE': 99}) 3777 rec = table[0] 3778 self.assertEqual(rec.NaMe.strip(), 'Ethan') 3779 table.rename_field('NaMe', 'My_NAME') 3780 self.assertEqual(rec.My_NaMe.strip(), 'Ethan') 3781 self.assertEqual(['MY_NAME', 'AGE'], field_names(table)) 3782 table.append({'MY_Name':'Allen', 'AGE': 7}) 3783 rec = table[1] 3784 self.assertEqual(rec.my_NaMe.strip(), 'Allen') 3785 3786class TestDbfRecordTemplates(TestCase): 3787 "Testing records" 3788 3789 def setUp(self): 3790 self.dbf_table = Table( 3791 os.path.join(tempdir, 'dbf_table'), 3792 'name C(25); paid L; qty N(11,5); orderdate D; desc M', 3793 dbf_type='db3', 3794 ) 3795 self.vfp_table = Table( 3796 os.path.join(tempdir, 'vfp_table'), 3797 'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' + 3798 ' weight F(18,3); age I; meeting T; misc G; photo P; price Y', 3799 dbf_type='vfp', 3800 ) 3801 3802 def tearDown(self): 3803 self.dbf_table.close() 3804 self.vfp_table.close() 3805 3806 def test_dbf_storage(self): 3807 table = self.dbf_table 3808 table.open(mode=READ_WRITE) 3809 record = table.create_template() 3810 record.name = 'Stoneleaf' 3811 record.paid = True 3812 record.qty = 1 3813 record.orderdate = Date.today() 3814 record.desc = 'some Python dude' 3815 table.append(record) 3816 3817 def test_vfp_storage(self): 3818 table = self.vfp_table 3819 table.open(mode=READ_WRITE) 3820 record = table.create_template() 3821 record.name = 'Stoneleaf' 3822 record.paid = True 3823 record.qty = 1 3824 record.orderdate = Date.today() 3825 record.desc = 'some Python dude' 3826 record.mass = 251.9287 3827 record.weight = 971204.39 3828 record.age = 29 3829 record.meeting = DateTime.now() 3830 record.misc = MISC 3831 record.photo = PHOTO 3832 record.price = 19.99 3833 table.append(record) 3834 3835 3836class TestDbfFunctions(TestCase): 3837 3838 def setUp(self): 3839 "create a dbf and vfp table" 3840 self.empty_dbf_table = Table( 3841 os.path.join(tempdir, 'emptytemptable'), 3842 'name C(25); paid L; qty N(11,5); orderdate D; desc M', dbf_type='db3' 3843 ) 3844 self.dbf_table = table = Table( 3845 os.path.join(tempdir, 'temptable'), 3846 'name C(25); paid L; qty N(11,5); orderdate D; desc M', dbf_type='db3' 3847 ) 3848 table.open(mode=READ_WRITE) 3849 namelist = self.dbf_namelist = [] 3850 paidlist = self.dbf_paidlist = [] 3851 qtylist = self.dbf_qtylist = [] 3852 orderlist = self.dbf_orderlist = [] 3853 desclist = self.dbf_desclist = [] 3854 for i in range(len(floats)): 3855 name = '%-25s' % words[i] 3856 paid = len(words[i]) % 3 == 0 3857 qty = floats[i] 3858 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 3859 desc = ' '.join(words[i:i+50]) 3860 namelist.append(name) 3861 paidlist.append(paid) 3862 qtylist.append(qty) 3863 orderlist.append(orderdate) 3864 desclist.append(desc) 3865 table.append({'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc}) 3866 table.close() 3867 3868 self.empty_vfp_table = Table( 3869 os.path.join(tempdir, 'emptytempvfp'), 3870 'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' 3871 ' weight F(18,3); age I; meeting T; misc G; photo P; price Y;' 3872 ' dist B BINARY; atom I BINARY; wealth Y BINARY;' 3873 , 3874 dbf_type='vfp', 3875 ) 3876 self.odd_memo_vfp_table = Table( 3877 os.path.join(tempdir, 'emptytempvfp'), 3878 'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' 3879 ' weight F(18,3); age I; meeting T; misc G; photo P; price Y;' 3880 ' dist B BINARY; atom I BINARY; wealth Y BINARY;' 3881 , 3882 dbf_type='vfp', 3883 memo_size=48, 3884 ) 3885 self.vfp_table = table = Table( 3886 os.path.join(tempdir, 'tempvfp'), 3887 'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' 3888 ' weight F(18,3); age I; meeting T; misc G; photo P; price Y;' 3889 ' dist B BINARY; atom I BINARY; wealth Y BINARY;' 3890 , 3891 dbf_type='vfp', 3892 ) 3893 table.open(mode=READ_WRITE) 3894 namelist = self.vfp_namelist = [] 3895 paidlist = self.vfp_paidlist = [] 3896 qtylist = self.vfp_qtylist = [] 3897 orderlist = self.vfp_orderlist = [] 3898 desclist = self.vfp_desclist = [] 3899 masslist = self.vfp_masslist = [] 3900 weightlist = self.vfp_weightlist = [] 3901 agelist = self.vfp_agelist = [] 3902 meetlist = self.vfp_meetlist = [] 3903 misclist = self.vfp_misclist = [] 3904 photolist = self.vfp_photolist = [] 3905 pricelist = self.vfp_pricelist = [] 3906 for i in range(len(floats)): 3907 name = words[i] 3908 paid = len(words[i]) % 3 == 0 3909 qty = floats[i] 3910 price = Decimal(round(floats[i] * 2.182737, 4)) 3911 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 3912 desc = ' '.join(words[i:i+50]) 3913 mass = floats[i] * floats[i] / 2.0 3914 weight = round(floats[i] * 3, 3) 3915 age = numbers[i] 3916 meeting = datetime.datetime((numbers[i] + 2000), (numbers[i] % 12)+1, (numbers[i] % 28)+1, \ 3917 (numbers[i] % 24), numbers[i] % 60, (numbers[i] * 3) % 60) 3918 misc = ' '.join(words[i:i+50:3]).encode('latin1') 3919 photo = ' '.join(words[i:i+50:7]).encode('latin1') 3920 namelist.append('%-25s' % name) 3921 paidlist.append(paid) 3922 qtylist.append(qty) 3923 pricelist.append(price) 3924 orderlist.append(orderdate) 3925 desclist.append(desc) 3926 masslist.append(mass) 3927 weightlist.append(weight) 3928 agelist.append(age) 3929 meetlist.append(meeting) 3930 misclist.append(misc) 3931 photolist.append(photo) 3932 meeting = datetime.datetime((numbers[i] + 2000), (numbers[i] % 12)+1, (numbers[i] % 28)+1, 3933 (numbers[i] % 24), numbers[i] % 60, (numbers[i] * 3) % 60) 3934 table.append({'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc, 3935 'mass':mass, 'weight':weight, 'age':age, 'meeting':meeting, 'misc':misc, 'photo':photo, 3936 'price':price, 'dist':mass, 'atom':age, 'wealth':price}) 3937 table.close() 3938 3939 def tearDown(self): 3940 self.dbf_table.close() 3941 self.vfp_table.close() 3942 3943 def test_add_fields_to_dbf_table(self): 3944 "dbf table: adding and deleting fields" 3945 table = self.dbf_table 3946 table.open(mode=READ_WRITE) 3947 dbf._debug = True 3948 namelist = self.dbf_namelist 3949 paidlist = self.dbf_paidlist 3950 qtylist = self.dbf_qtylist 3951 orderlist = self.dbf_orderlist 3952 desclist = self.dbf_desclist 3953 table.delete_fields('name') 3954 table.close() 3955 table = Table(table.filename, dbf_type='db3') 3956 table.open(mode=READ_WRITE) 3957 for field in table.field_names: 3958 self.assertEqual(1, table.field_names.count(field)) 3959 i = 0 3960 for record in table: 3961 self.assertEqual(dbf.recno(record), i) 3962 self.assertEqual(table[i].paid, paidlist[i]) 3963 self.assertEqual(record.paid, paidlist[i]) 3964 self.assertEqual(abs(table[i].qty - qtylist[i]) < .00001, True) 3965 self.assertEqual(abs(record.qty - qtylist[i]) < .00001, True) 3966 self.assertEqual(table[i].orderdate, orderlist[i]) 3967 self.assertEqual(record.orderdate, orderlist[i]) 3968 self.assertEqual(table[i].desc, desclist[i]) 3969 self.assertEqual(record.desc, desclist[i]) 3970 i += 1 3971 first, middle, last = table[0], table[len(table)//2], table[-1] 3972 table.delete_fields('paid, orderdate') 3973 for field in table.field_names: 3974 self.assertEqual(1, table.field_names.count(field)) 3975 i = 0 3976 for record in table: 3977 self.assertEqual(dbf.recno(record), i) 3978 self.assertEqual(abs(table[i].qty - qtylist[i]) < .00001, True) 3979 self.assertEqual(abs(record.qty - qtylist[i]) < .00001, True) 3980 self.assertEqual(table[i].desc, desclist[i]) 3981 self.assertEqual(record.desc, desclist[i]) 3982 i += 1 3983 self.assertEqual(i, len(table)) 3984 self.assertTrue('paid' not in dbf.field_names(first)) 3985 self.assertTrue('orderdate' not in dbf.field_names(middle)) 3986 self.assertTrue('name' not in dbf.field_names(last)) 3987 table.add_fields('name C(25); paid L; orderdate D') 3988 for field in table.field_names: 3989 self.assertEqual(1, table.field_names.count(field)) 3990 self.assertEqual(i, len(table)) 3991 i = 0 3992 for i, record in enumerate(table): 3993 self.assertEqual(record.name, ' ' * 25) 3994 self.assertEqual(record.paid, None) 3995 self.assertEqual(record.orderdate, None) 3996 self.assertEqual(record.desc, desclist[i]) 3997 i += 1 3998 self.assertEqual(i, len(table)) 3999 i = 0 4000 for record in table: 4001 data = dict() 4002 data['name'] = namelist[dbf.recno(record)] 4003 data['paid'] = paidlist[dbf.recno(record)] 4004 data['orderdate'] = orderlist[dbf.recno(record)] 4005 dbf.gather(record, data) 4006 i += 1 4007 self.assertEqual(i, len(table)) 4008 i = 0 4009 for record in table: 4010 self.assertEqual(dbf.recno(record), i) 4011 self.assertEqual(table[i].name, namelist[i]) 4012 self.assertEqual(record.name, namelist[i]) 4013 self.assertEqual(table[i].paid, paidlist[i]) 4014 self.assertEqual(record.paid, paidlist[i]) 4015 self.assertEqual(abs(table[i].qty - qtylist[i]) < .00001, True) 4016 self.assertEqual(abs(record.qty - qtylist[i]) < .00001, True) 4017 self.assertEqual(table[i].orderdate, orderlist[i]) 4018 self.assertEqual(record.orderdate, orderlist[i]) 4019 self.assertEqual(table[i].desc, desclist[i]) 4020 self.assertEqual(record.desc, desclist[i]) 4021 i += 1 4022 table.close() 4023 4024 def test_add_fields_to_vfp_table(self): 4025 "vfp table: adding and deleting fields" 4026 table = self.vfp_table 4027 table.open(mode=READ_WRITE) 4028 namelist = self.vfp_namelist 4029 paidlist = self.vfp_paidlist 4030 qtylist = self.vfp_qtylist 4031 orderlist = self.vfp_orderlist 4032 desclist = self.vfp_desclist 4033 masslist = self.vfp_masslist 4034 weightlist = self.vfp_weightlist 4035 agelist = self.vfp_agelist 4036 meetlist = self.vfp_meetlist 4037 misclist = self.vfp_misclist 4038 photolist = self.vfp_photolist 4039 pricelist = self.vfp_pricelist 4040 self.assertEqual(len(table), len(floats)) 4041 i = 0 4042 for record in table: 4043 self.assertEqual(dbf.recno(record), i) 4044 self.assertEqual(table[i].name, namelist[i]) 4045 self.assertEqual(record.name, namelist[i]) 4046 self.assertEqual(table[i].paid, paidlist[i]) 4047 self.assertEqual(record.paid, paidlist[i]) 4048 self.assertTrue(abs(table[i].qty - qtylist[i]) < .00001) 4049 self.assertTrue(abs(record.qty - qtylist[i]) < .00001) 4050 self.assertEqual(table[i].orderdate, orderlist[i]) 4051 self.assertEqual(record.orderdate, orderlist[i]) 4052 self.assertEqual(table[i].desc, desclist[i]) 4053 self.assertEqual(record.desc, desclist[i]) 4054 self.assertEqual(record.mass, masslist[i]) 4055 self.assertEqual(table[i].mass, masslist[i]) 4056 self.assertEqual(record.dist, masslist[i]) 4057 self.assertEqual(table[i].dist, masslist[i]) 4058 self.assertEqual(record.weight, weightlist[i]) 4059 self.assertEqual(table[i].weight, weightlist[i]) 4060 self.assertEqual(record.age, agelist[i]) 4061 self.assertEqual(table[i].age, agelist[i]) 4062 self.assertEqual(record.atom, agelist[i]) 4063 self.assertEqual(table[i].atom, agelist[i]) 4064 self.assertEqual(record.meeting, meetlist[i]) 4065 self.assertEqual(table[i].meeting, meetlist[i]) 4066 self.assertEqual(record.misc, misclist[i]) 4067 self.assertEqual(table[i].misc, misclist[i]) 4068 self.assertEqual(record.photo, photolist[i]) 4069 self.assertEqual(table[i].photo, photolist[i]) 4070 self.assertEqual(round(record.price, 4), round(pricelist[i], 4)) 4071 self.assertEqual(round(table[i].price, 4), round(pricelist[i], 4)) 4072 self.assertTrue(round(record.wealth, 4), round(pricelist[i], 4)) 4073 self.assertTrue(round(table[i].wealth, 4), round(pricelist[i], 4)) 4074 i += 1 4075 table.delete_fields('desc') 4076 i = 0 4077 for record in table: 4078 self.assertEqual(dbf.recno(record), i) 4079 self.assertEqual(table[i].name, namelist[i]) 4080 self.assertEqual(record.name, namelist[i]) 4081 self.assertEqual(table[i].paid, paidlist[i]) 4082 self.assertEqual(record.paid, paidlist[i]) 4083 self.assertEqual(abs(table[i].qty - qtylist[i]) < .00001, True) 4084 self.assertEqual(abs(record.qty - qtylist[i]) < .00001, True) 4085 self.assertEqual(table[i].orderdate, orderlist[i]) 4086 self.assertEqual(record.orderdate, orderlist[i]) 4087 self.assertEqual(record.weight, weightlist[i]) 4088 self.assertEqual(table[i].weight, weightlist[i]) 4089 self.assertEqual(record.age, agelist[i]) 4090 self.assertEqual(table[i].age, agelist[i]) 4091 self.assertEqual(record.atom, agelist[i]) 4092 self.assertEqual(table[i].atom, agelist[i]) 4093 self.assertEqual(record.meeting, meetlist[i]) 4094 self.assertEqual(table[i].meeting, meetlist[i]) 4095 self.assertEqual(record.misc, misclist[i]) 4096 self.assertEqual(table[i].misc, misclist[i]) 4097 self.assertEqual(record.photo, photolist[i]) 4098 self.assertEqual(table[i].photo, photolist[i]) 4099 self.assertEqual(record.mass, masslist[i]) 4100 self.assertEqual(table[i].mass, masslist[i]) 4101 self.assertEqual(record.dist, masslist[i]) 4102 self.assertEqual(table[i].dist, masslist[i]) 4103 self.assertEqual(round(record.price, 4), round(pricelist[i], 4)) 4104 self.assertEqual(round(table[i].price, 4), round(pricelist[i], 4)) 4105 self.assertTrue(round(record.wealth, 4), round(pricelist[i], 4)) 4106 self.assertTrue(round(table[i].wealth, 4), round(pricelist[i], 4)) 4107 i += 1 4108 table.delete_fields('paid, mass') 4109 i = 0 4110 for record in table: 4111 self.assertEqual(dbf.recno(record), i) 4112 self.assertEqual(table[i].name, namelist[i]) 4113 self.assertEqual(record.name, namelist[i]) 4114 self.assertEqual(abs(table[i].qty - qtylist[i]) < .00001, True) 4115 self.assertEqual(abs(record.qty - qtylist[i]) < .00001, True) 4116 self.assertEqual(table[i].orderdate, orderlist[i]) 4117 self.assertEqual(record.orderdate, orderlist[i]) 4118 self.assertEqual(record.weight, weightlist[i]) 4119 self.assertEqual(table[i].weight, weightlist[i]) 4120 self.assertEqual(record.age, agelist[i]) 4121 self.assertEqual(table[i].age, agelist[i]) 4122 self.assertEqual(record.atom, agelist[i]) 4123 self.assertEqual(table[i].atom, agelist[i]) 4124 self.assertEqual(record.meeting, meetlist[i]) 4125 self.assertEqual(table[i].meeting, meetlist[i]) 4126 self.assertEqual(record.misc, misclist[i]) 4127 self.assertEqual(table[i].misc, misclist[i]) 4128 self.assertEqual(record.photo, photolist[i]) 4129 self.assertEqual(table[i].photo, photolist[i]) 4130 self.assertEqual(record.dist, masslist[i]) 4131 self.assertEqual(table[i].dist, masslist[i]) 4132 self.assertEqual(round(record.price, 4), round(pricelist[i], 4)) 4133 self.assertEqual(round(table[i].price, 4), round(pricelist[i], 4)) 4134 self.assertTrue(round(record.wealth, 4), round(pricelist[i], 4)) 4135 self.assertTrue(round(table[i].wealth, 4), round(pricelist[i], 4)) 4136 i += 1 4137 table.add_fields('desc M; paid L; mass B') 4138 i = 0 4139 for record in table: 4140 self.assertEqual(record.desc, unicode('')) 4141 self.assertEqual(record.paid is None, True) 4142 self.assertEqual(record.mass, 0.0) 4143 i += 1 4144 self.assertEqual(i, len(table)) 4145 i = 0 4146 for record in Process(table): 4147 record.desc = desclist[dbf.recno(record)] 4148 record.paid = paidlist[dbf.recno(record)] 4149 record.mass = masslist[dbf.recno(record)] 4150 i += 1 4151 self.assertEqual(i, len(table)) 4152 i = 0 4153 for record in table: 4154 self.assertEqual(dbf.recno(record), i) 4155 self.assertEqual(table[i].name, namelist[i]) 4156 self.assertEqual(record.name, namelist[i]) 4157 self.assertEqual(table[i].paid, paidlist[i]) 4158 self.assertEqual(record.paid, paidlist[i]) 4159 self.assertEqual(abs(table[i].qty - qtylist[i]) < .00001, True) 4160 self.assertEqual(abs(record.qty - qtylist[i]) < .00001, True) 4161 self.assertEqual(table[i].orderdate, orderlist[i]) 4162 self.assertEqual(record.orderdate, orderlist[i]) 4163 self.assertEqual(table[i].desc, desclist[i]) 4164 self.assertEqual(record.desc, desclist[i]) 4165 self.assertEqual(record.mass, masslist[i]) 4166 self.assertEqual(table[i].mass, masslist[i]) 4167 self.assertEqual(record.dist, masslist[i]) 4168 self.assertEqual(table[i].dist, masslist[i]) 4169 self.assertEqual(record.weight, weightlist[i]) 4170 self.assertEqual(table[i].weight, weightlist[i]) 4171 self.assertEqual(record.age, agelist[i]) 4172 self.assertEqual(table[i].age, agelist[i]) 4173 self.assertEqual(record.atom, agelist[i]) 4174 self.assertEqual(table[i].atom, agelist[i]) 4175 self.assertEqual(record.meeting, meetlist[i]) 4176 self.assertEqual(table[i].meeting, meetlist[i]) 4177 self.assertEqual(record.misc, misclist[i]) 4178 self.assertEqual(table[i].misc, misclist[i]) 4179 self.assertEqual(record.photo, photolist[i]) 4180 self.assertEqual(table[i].photo, photolist[i]) 4181 self.assertEqual(round(record.price, 4), round(pricelist[i], 4)) 4182 self.assertEqual(round(table[i].price, 4), round(pricelist[i], 4)) 4183 self.assertTrue(round(record.wealth, 4), round(pricelist[i], 4)) 4184 self.assertTrue(round(table[i].wealth, 4), round(pricelist[i], 4)) 4185 i += 1 4186 table.close() 4187 4188 def test_len_contains_iter(self): 4189 "basic function tests - len, contains & iterators" 4190 table = self.dbf_table.open() 4191 for field in table.field_names: 4192 self.assertEqual(1, table.field_names.count(field)) 4193 length = sum([1 for rec in table]) 4194 self.assertEqual(length, len(table)) 4195 i = 0 4196 for record in table: 4197 self.assertEqual(record, table[i]) 4198 self.assertTrue(record in table) 4199 self.assertTrue(tuple(record) in table) 4200 self.assertTrue(scatter(record) in table) 4201 self.assertTrue(create_template(record) in table) 4202 i += 1 4203 self.assertEqual(i, len(table)) 4204 table.close() 4205 4206 def test_undelete(self): 4207 "delete, undelete" 4208 table = Table(':memory:', 'name C(10)', dbf_type='db3', on_disk=False) 4209 table.open(mode=READ_WRITE) 4210 table.append() 4211 self.assertEqual(table.next_record, table[0]) 4212 table = Table(':memory:', 'name C(10)', dbf_type='db3', on_disk=False) 4213 table.open(mode=READ_WRITE) 4214 table.append(multiple=10) 4215 self.assertEqual(table.next_record, table[0]) 4216 table = self.dbf_table # Table(os.path.join(tempdir, 'temptable'), dbf_type='db3') 4217 table.open(mode=READ_WRITE) 4218 total = len(table) 4219 table.bottom() 4220 self.assertEqual(dbf.recno(table.current_record), total) 4221 table.top() 4222 self.assertEqual(dbf.recno(table.current_record), -1) 4223 table.goto(27) 4224 self.assertEqual(dbf.recno(table.current_record), 27) 4225 table.goto(total-1) 4226 self.assertEqual(dbf.recno(table.current_record), total-1) 4227 table.goto(0) 4228 self.assertEqual(dbf.recno(table.current_record), 0) 4229 self.assertRaises(IndexError, table.goto, total) 4230 self.assertRaises(IndexError, table.goto, -len(table)-1) 4231 table.top() 4232 self.assertRaises(dbf.Bof, table.skip, -1) 4233 table.bottom() 4234 self.assertRaises(Eof, table.skip) 4235 for record in table: 4236 dbf.delete(record) 4237 active_records = table.create_index(active) 4238 active_records.top() 4239 self.assertRaises(Eof, active_records.skip) 4240 dbf._debug = True 4241 active_records.bottom() 4242 self.assertRaises(Bof, active_records.skip, -1) 4243 for record in table: 4244 dbf.undelete(record) 4245 4246 # delete every third record 4247 i = 0 4248 for record in table: 4249 self.assertEqual(dbf.recno(record), i) 4250 if i % 3 == 0: 4251 dbf.delete(record) 4252 i += 1 4253 i = 0 4254 # and verify 4255 for record in table: 4256 self.assertEqual(dbf.is_deleted(record), i%3==0) 4257 self.assertEqual(dbf.is_deleted(table[i]), i%3==0) 4258 i += 1 4259 4260 # check that deletes were saved to disk.. 4261 table.close() 4262 table = Table(os.path.join(tempdir, 'temptable'), dbf_type='db3') 4263 table.open(mode=READ_WRITE) 4264 active_records = table.create_index(active) 4265 i = 0 4266 for record in table: 4267 self.assertEqual(dbf.is_deleted(record), i%3==0) 4268 self.assertEqual(dbf.is_deleted(table[i]), i%3==0) 4269 i += 1 4270 4271 # verify record numbers 4272 i = 0 4273 for record in table: 4274 self.assertEqual(dbf.recno(record), i) 4275 i += 1 4276 4277 # verify that deleted records are skipped 4278 i = 0 4279 for record in active_records: 4280 self.assertNotEqual(dbf.recno(record)%3, 0) 4281 active_records.goto(1) 4282 active_records.skip() 4283 self.assertEqual(dbf.recno(active_records.current_record), 4) 4284 active_records.skip(-1) 4285 self.assertEqual(dbf.recno(active_records.current_record), 2) 4286 4287 # verify that deleted records are skipped in slices 4288 list_of_records = active_records[3:6] 4289 self.assertEqual(len(list_of_records), 3) 4290 self.assertEqual(dbf.recno(list_of_records[0]), 5) 4291 self.assertEqual(dbf.recno(list_of_records[1]), 7) 4292 self.assertEqual(dbf.recno(list_of_records[2]), 8) 4293 4294 # verify behavior when all records are deleted 4295 for record in table: 4296 dbf.delete(record) 4297 active_records.bottom() 4298 self.assertRaises(Eof, active_records.skip) 4299 self.assertEqual(active_records.eof, True) 4300 active_records.top() 4301 self.assertRaises(Bof, active_records.skip, -1) 4302 self.assertEqual(active_records.bof, True) 4303 4304 # verify deleted records are seen with active record index 4305 deleted_records = table.create_index(inactive) 4306 i = 0 4307 for record in deleted_records: 4308 self.assertEqual(dbf.recno(record), i) 4309 i += 1 4310 4311 # verify undelete using table[index] 4312 for record in table: 4313 dbf.delete(record) 4314 self.assertTrue(dbf.is_deleted(record)) 4315 for i, record in enumerate(table): 4316 dbf.undelete(table[i]) 4317 self.assertEqual(dbf.is_deleted(record), False) 4318 self.assertEqual(dbf.is_deleted(table[i]), False) 4319 self.assertFalse(record in deleted_records) 4320 4321 # verify all records have been undeleted (recalled) 4322 self.assertEqual(len(active_records), len(table)) 4323 self.assertEqual(len(deleted_records), 0) 4324 table.close() 4325 4326 def test_finding_ordering_searching(self): 4327 "finding, ordering, searching" 4328 table = self.dbf_table 4329 table.open(mode=READ_WRITE) 4330 4331 # find (brute force) 4332 unordered = [] 4333 for record in table: 4334 unordered.append(record.name) 4335 for word in unordered: # returns records 4336 # records = table.query("select * where name == %r" % word) 4337 # self.assertEqual(len(records), unordered.count(word)) 4338 records = [rec for rec in table if rec.name == word] 4339 self.assertEqual(len(records), unordered.count(word)) 4340 4341 # ordering by one field 4342 ordered = unordered[:] 4343 ordered.sort() 4344 name_index = table.create_index(lambda rec: rec.name) 4345 self.assertEqual(list(name_index[::-1]), list(reversed(name_index))) 4346 i = 0 4347 for record in name_index: 4348 self.assertEqual(record.name, ordered[i]) 4349 i += 1 4350 4351 # search (BINARY) 4352 for word in unordered: 4353 records = name_index.search(match=word) 4354 self.assertEqual(len(records), unordered.count(word), "num records: %d\nnum words: %d\nfailure with %r" % (len(records), unordered.count(word), word)) 4355 records = table.query("select * where name == %r" % word) 4356 self.assertEqual(len(records), unordered.count(word)) 4357 records = dbf.pql(table, "select * where name == %r" % word) 4358 self.assertEqual(len(records), unordered.count(word)) 4359 4360 # ordering by two fields 4361 ordered = unordered[:] 4362 ordered.sort() 4363 nd_index = table.create_index(lambda rec: (rec.name, rec.desc)) 4364 self.assertEqual(list(nd_index[::-1]), list(reversed(nd_index))) 4365 i = 0 4366 for record in nd_index: 4367 self.assertEqual(record.name, ordered[i]) 4368 i += 1 4369 4370 # search (BINARY) 4371 for word in unordered: 4372 records = nd_index.search(match=(word, ), partial=True) 4373 ucount = sum([1 for wrd in unordered if wrd.startswith(word)]) 4374 self.assertEqual(len(records), ucount) 4375 4376 for record in table[::2]: 4377 dbf.write(record, qty=-record.qty) 4378 unordered = [] 4379 for record in table: 4380 unordered.append(record.qty) 4381 ordered = unordered[:] 4382 ordered.sort() 4383 qty_index = table.create_index(lambda rec: rec.qty) 4384 self.assertEqual(list(qty_index[::-1]), list(reversed(qty_index))) 4385 i = 0 4386 for record in qty_index: 4387 self.assertEqual(record.qty, ordered[i]) 4388 i += 1 4389 for number in unordered: 4390 records = qty_index.search(match=(number, )) 4391 self.assertEqual(len(records), unordered.count(number)) 4392 4393 table.close() 4394 4395 def test_scatter_gather_new(self): 4396 "scattering and gathering fields, and new()" 4397 table = self.dbf_table 4398 table.open(mode=READ_WRITE) 4399 table2 = table.new(os.path.join(tempdir, 'temptable2')) 4400 table2.open(mode=READ_WRITE) 4401 for record in table: 4402 table2.append() 4403 newrecord = table2[-1] 4404 testdict = dbf.scatter(record) 4405 for key in field_names(testdict): 4406 self.assertEqual(testdict[key], record[key]) 4407 dbf.gather(newrecord, dbf.scatter(record)) 4408 for field in dbf.field_names(record): 4409 self.assertEqual(newrecord[field], record[field]) 4410 table2.close() 4411 table2 = None 4412 table2 = Table(os.path.join(tempdir, 'temptable2'), dbf_type='db3') 4413 table2.open(mode=READ_WRITE) 4414 for i in range(len(table)): 4415 temp1 = dbf.scatter(table[i]) 4416 temp2 = dbf.scatter(table2[i]) 4417 for key in field_names(temp1): 4418 self.assertEqual(temp1[key], temp2[key]) 4419 for key in field_names(temp2): 4420 self.assertEqual(temp1[key], temp2[key]) 4421 table2.close() 4422 table3 = table.new(':memory:', on_disk=False) 4423 table3.open(mode=READ_WRITE) 4424 for record in table: 4425 table3.append(record) 4426 table4 = self.vfp_table 4427 table4.open(mode=READ_WRITE) 4428 table5 = table4.new(':memory:', on_disk=False) 4429 table5.open(mode=READ_WRITE) 4430 for record in table4: 4431 table5.append(record) 4432 table.close() 4433 table3.close() 4434 table4.close() 4435 table5.close() 4436 4437 def test_rename_contains_has_key(self): 4438 "renaming fields, __contains__, has_key" 4439 table = self.dbf_table 4440 table.open(mode=READ_WRITE) 4441 for field in table.field_names: 4442 oldfield = field 4443 table.rename_field(oldfield, 'newfield') 4444 self.assertEqual(oldfield in table.field_names, False) 4445 self.assertEqual('newfield' in table.field_names, True) 4446 table.close() 4447 table = Table(os.path.join(tempdir, 'temptable'), dbf_type='db3') 4448 table.open(mode=READ_WRITE) 4449 self.assertEqual(oldfield in table.field_names, False) 4450 self.assertEqual('newfield' in table.field_names, True) 4451 table.rename_field('newfield', oldfield) 4452 self.assertEqual(oldfield in table.field_names, True) 4453 self.assertEqual('newfield' in table.field_names, False) 4454 table.close() 4455 4456 def test_dbf_record_kamikaze(self): 4457 "kamikaze" 4458 table = self.dbf_table 4459 table.open(mode=READ_WRITE) 4460 table2 = table.new(os.path.join(tempdir, 'temptable2')) 4461 table2.open(mode=READ_WRITE) 4462 for record in table: 4463 table2.append(record) 4464 newrecord = table2[-1] 4465 for key in table.field_names: 4466 if key not in table.memo_types: 4467 self.assertEqual(newrecord[key], record[key]) 4468 for field in dbf.field_names(newrecord): 4469 if key not in table2.memo_types: 4470 self.assertEqual(newrecord[field], record[field]) 4471 table2.close() 4472 table2 = Table(os.path.join(tempdir, 'temptable2'), dbf_type='db3') 4473 table2.open(mode=READ_WRITE) 4474 for i in range(len(table)): 4475 dict1 = dbf.scatter(table[i], as_type=dict) 4476 dict2 = dbf.scatter(table2[i], as_type=dict) 4477 for key in dict1.keys(): 4478 if key not in table.memo_types: 4479 self.assertEqual(dict1[key], dict2[key]) 4480 for key in dict2.keys(): 4481 if key not in table2.memo_types: 4482 self.assertEqual(dict1[key], dict2[key]) 4483 for i in range(len(table)): 4484 template1 = dbf.scatter(table[i]) 4485 template2 = dbf.scatter(table2[i]) 4486 for key in dbf.field_names(template1): 4487 if key not in table.memo_types: 4488 self.assertEqual(template1[key], template2[key]) 4489 for key in dbf.field_names(template2): 4490 if key not in table2.memo_types: 4491 self.assertEqual(template1[key], template2[key]) 4492 table.close() 4493 table2.close() 4494 4495 def test_multiple_append(self): 4496 "multiple append" 4497 table = self.dbf_table 4498 table.open(mode=READ_WRITE) 4499 table2 = table.new(os.path.join(tempdir, 'temptable2')) 4500 table2.open(mode=READ_WRITE) 4501 record = table.next_record 4502 table2.append(dbf.scatter(record), multiple=100) 4503 for samerecord in table2: 4504 for field in dbf.field_names(record): 4505 self.assertEqual(record[field], samerecord[field]) 4506 table2.close() 4507 table2 = Table(os.path.join(tempdir, 'temptable2'), dbf_type='db3') 4508 table2.open(mode=READ_WRITE) 4509 for samerecord in table2: 4510 for field in dbf.field_names(record): 4511 self.assertEqual(record[field], samerecord[field]) 4512 table2.close() 4513 table3 = table.new(os.path.join(tempdir, 'temptable3')) 4514 table3.open(mode=READ_WRITE) 4515 record = table.next_record 4516 table3.append(record, multiple=100) 4517 for samerecord in table3: 4518 for field in dbf.field_names(record): 4519 self.assertEqual(record[field], samerecord[field]) 4520 table3.close() 4521 table3 = Table(os.path.join(tempdir, 'temptable3'), dbf_type='db3') 4522 table3.open(mode=READ_WRITE) 4523 for samerecord in table3: 4524 for field in dbf.field_names(record): 4525 self.assertEqual(record[field], samerecord[field]) 4526 table3.close() 4527 table.close() 4528 4529 def test_slices(self): 4530 "slices" 4531 table = self.dbf_table 4532 table.open(mode=READ_WRITE) 4533 slice1 = [table[0], table[1], table[2]] 4534 self.assertEqual(slice1, list(table[:3])) 4535 slice2 = [table[-3], table[-2], table[-1]] 4536 self.assertEqual(slice2, list(table[-3:])) 4537 slice3 = [record for record in table] 4538 self.assertEqual(slice3, list(table[:])) 4539 slice4 = [table[9]] 4540 self.assertEqual(slice4, list(table[9:10])) 4541 slice5 = [table[15], table[16], table[17], table[18]] 4542 self.assertEqual(slice5, list(table[15:19])) 4543 slice6 = [table[0], table[2], table[4], table[6], table[8]] 4544 self.assertEqual(slice6, list(table[:9:2])) 4545 slice7 = [table[-1], table[-2], table[-3]] 4546 self.assertEqual(slice7, list(table[-1:-4:-1])) 4547 table.close() 4548 4549 def test_record_reset(self): 4550 "reset record" 4551 table = self.dbf_table 4552 table.open(mode=READ_WRITE) 4553 for record in table: 4554 with record: 4555 self.assertTrue(record.qty) 4556 dbf.reset(record, keep_fields=['name']) 4557 self.assertFalse(record.qty) 4558 self.assertTrue(record.name) 4559 for record in table: 4560 dbf.reset(record) 4561 self.assertEqual(table[0].name, table[1].name) 4562 dbf.write(table[0], name='Python rocks!') 4563 self.assertNotEqual(table[0].name, table[1].name) 4564 table.close() 4565 4566 def test_adding_memos(self): 4567 "adding memos to existing records" 4568 table = Table(':memory:', 'name C(50); age N(3,0)', dbf_type='db3', on_disk=False) 4569 table.open(mode=READ_WRITE) 4570 table.append(('user', 0)) 4571 table.add_fields('motto M') 4572 dbf.write(table[0], motto='Are we there yet??') 4573 self.assertEqual(table[0].motto, 'Are we there yet??') 4574 table.close() 4575 table = Table(os.path.join(tempdir, 'temptable4'), 'name C(50); age N(3,0)', dbf_type='db3') 4576 table.open(mode=READ_WRITE) 4577 table.append(('user', 0)) 4578 table.close() 4579 table.open(mode=READ_WRITE) 4580 table.close() 4581 table = Table(os.path.join(tempdir, 'temptable4'), dbf_type='db3') 4582 table.open(mode=READ_WRITE) 4583 table.add_fields('motto M') 4584 dbf.write(table[0], motto='Are we there yet??') 4585 self.assertEqual(table[0].motto, 'Are we there yet??') 4586 table.close() 4587 table = Table(os.path.join(tempdir, 'temptable4'), dbf_type='db3') 4588 table.open(mode=READ_WRITE) 4589 self.assertEqual(table[0].motto, 'Are we there yet??') 4590 table.close() 4591 table = Table(os.path.join(tempdir, 'temptable4'), 'name C(50); age N(3,0)', dbf_type='vfp') 4592 table.open(mode=READ_WRITE) 4593 table.append(('user', 0)) 4594 table.close() 4595 table.open(mode=READ_WRITE) 4596 table.close() 4597 table = Table(os.path.join(tempdir, 'temptable4'), dbf_type='vfp') 4598 table.open(mode=READ_WRITE) 4599 table.add_fields('motto M') 4600 dbf.write(table[0], motto='Are we there yet??') 4601 self.assertEqual(table[0].motto, 'Are we there yet??') 4602 table.close() 4603 table = Table(os.path.join(tempdir, 'temptable4'), dbf_type='vfp') 4604 table.open(mode=READ_WRITE) 4605 self.assertEqual(table[0].motto, 'Are we there yet??') 4606 table.close() 4607 4608 def test_from_csv(self): 4609 "from_csv" 4610 table = self.dbf_table 4611 table.open(mode=READ_WRITE) 4612 dbf.export(table, table.filename, header=False) 4613 csvtable = dbf.from_csv(os.path.join(tempdir, 'temptable.csv')) 4614 csvtable.open(mode=READ_WRITE) 4615 for i in index(table): 4616 for j in index(table.field_names): 4617 self.assertEqual(str(table[i][j]), csvtable[i][j]) 4618 csvtable.close() 4619 csvtable = dbf.from_csv(os.path.join(tempdir, 'temptable.csv'), to_disk=True, filename=os.path.join(tempdir, 'temptable5')) 4620 csvtable.open(mode=READ_WRITE) 4621 for i in index(table): 4622 for j in index(table.field_names): 4623 self.assertEqual(str(table[i][j]).strip(), csvtable[i][j].strip()) 4624 csvtable.close() 4625 csvtable = dbf.from_csv(os.path.join(tempdir, 'temptable.csv'), field_names=['field1','field2']) 4626 csvtable.open(mode=READ_WRITE) 4627 for i in index(table): 4628 for j in index(table.field_names): 4629 self.assertEqual(str(table[i][j]), csvtable[i][j]) 4630 csvtable.close() 4631 csvtable = dbf.from_csv(os.path.join(tempdir, 'temptable.csv'), field_names=['field1','field2'], to_disk=True, filename=os.path.join(tempdir, 'temptable5')) 4632 csvtable.open(mode=READ_WRITE) 4633 for i in index(table): 4634 for j in index(table.field_names): 4635 self.assertEqual(str(table[i][j]).strip(), csvtable[i][j].strip()) 4636 csvtable.close() 4637 csvtable = dbf.from_csv(os.path.join(tempdir, 'temptable.csv'), extra_fields=['count N(5,0)','id C(10)']) 4638 csvtable.open(mode=READ_WRITE) 4639 for i in index(table): 4640 for j in index(table.field_names): 4641 self.assertEqual(str(table[i][j]), csvtable[i][j]) 4642 csvtable.close() 4643 csvtable = dbf.from_csv(os.path.join(tempdir, 'temptable.csv'), extra_fields=['count N(5,0)','id C(10)'], to_disk=True, filename=os.path.join(tempdir, 'temptable5')) 4644 csvtable.open(mode=READ_WRITE) 4645 for i in index(table): 4646 for j in index(table.field_names): 4647 self.assertEqual(str(table[i][j]).strip(), csvtable[i][j].strip()) 4648 csvtable.close() 4649 csvtable = dbf.from_csv(os.path.join(tempdir, 'temptable.csv'), field_names=['name','qty','paid','desc'], extra_fields='test1 C(15);test2 L'.split(';')) 4650 csvtable.open(mode=READ_WRITE) 4651 for i in index(table): 4652 for j in index(table.field_names): 4653 self.assertEqual(str(table[i][j]), csvtable[i][j]) 4654 csvtable.close() 4655 csvtable = dbf.from_csv(os.path.join(tempdir, 'temptable.csv'), field_names=['name','qty','paid','desc'], extra_fields='test1 C(15);test2 L'.split(';'), to_disk=True, filename=os.path.join(tempdir, 'temptable5')) 4656 csvtable.open(mode=READ_WRITE) 4657 for i in index(table): 4658 for j in index(table.field_names): 4659 self.assertEqual(str(table[i][j]).strip(), csvtable[i][j].strip()) 4660 csvtable.close() 4661 4662 def test_resize_empty(self): 4663 "resize" 4664 table = self.empty_dbf_table 4665 table.open(mode=READ_WRITE) 4666 table.resize_field('name', 40) 4667 table.close() 4668 4669 def test_resize(self): 4670 "resize" 4671 table = self.dbf_table 4672 table.open(mode=READ_WRITE) 4673 test_record = dbf.scatter(table[5]) 4674 test_record = dbf.scatter(table[5]) 4675 table.resize_field('name', 40) 4676 new_record = dbf.scatter(table[5]) 4677 self.assertEqual(test_record['orderdate'], new_record['orderdate']) 4678 table.close() 4679 4680 def test_memos_after_close(self): 4681 "memos available after close/open" 4682 table = dbf.Table('tempy', 'name C(20); desc M', dbf_type='db3', default_data_types=dict(C=Char)) 4683 table.open(mode=READ_WRITE) 4684 table.append(('Author','dashing, debonair, delightful')) 4685 table.close() 4686 table.open(mode=READ_WRITE) 4687 self.assertEqual(tuple(table[0]), ('Author','dashing, debonair, delightful')) 4688 table.close() 4689 table2 = dbf.Table('tempy', 'name C(20); desc M', dbf_type='db3') 4690 table2.open(mode=READ_WRITE) 4691 table2.append(('Benedict', 'brilliant, bombastic, bothered')) 4692 table2.close() 4693 table.open(mode=READ_WRITE) 4694 self.assertEqual(table[0].name, 'Benedict') 4695 self.assertEqual(table[0].desc, 'brilliant, bombastic, bothered') 4696 table.close() 4697 4698 def test_field_type(self): 4699 "table.type(field) == ('C', Char)" 4700 table = dbf.Table('tempy', 'name C(20); desc M', dbf_type='db3', default_data_types=dict(C=Char)) 4701 table.open(mode=READ_WRITE) 4702 field_info = table.field_info('name') 4703 self.assertEqual(field_info, (dbf.FieldType.CHAR, 20, 0, Char)) 4704 self.assertEqual(field_info.field_type, dbf.FieldType.CHAR) 4705 self.assertEqual(field_info.length, 20) 4706 self.assertEqual(field_info.decimal, 0) 4707 self.assertEqual(field_info.py_type, Char) 4708 table.close() 4709 4710 def test_memo_after_backup(self): 4711 "memo fields accessible after .backup()" 4712 table = self.dbf_table 4713 table.open(mode=READ_WRITE) 4714 table.create_backup() 4715 backup = dbf.Table(table.backup) 4716 backup.open(mode=READ_WRITE) 4717 desclist = self.dbf_desclist 4718 for i in range(len(desclist)): 4719 self.assertEqual(desclist[i], backup[i].desc) 4720 backup.close() 4721 table.close() 4722 4723 def test_memo_file_size_before_backup(self): 4724 table = self.odd_memo_vfp_table 4725 self.assertEqual(48, table._meta.memo_size) 4726 4727 def test_memo_file_size_after_backup(self): 4728 table = self.odd_memo_vfp_table 4729 table.open(mode=READ_ONLY) 4730 table.create_backup() 4731 table.close() 4732 backup = dbf.Table(table.backup) 4733 self.assertEqual(backup._meta.memo_size, table._meta.memo_size) 4734 4735 def test_write_loop(self): 4736 "Process loop commits changes" 4737 table = self.dbf_table 4738 table.open(mode=READ_WRITE) 4739 for record in Process(table): 4740 record.name = '!BRAND NEW NAME!' 4741 for record in table: 4742 self.assertEqual(record.name, '!BRAND NEW NAME! ') 4743 table.close() 4744 4745 def test_export(self): 4746 for table in self.dbf_table, self.vfp_table: 4747 table.open(mode=READ_WRITE) 4748 dbf.export(table, filename='test_export.csv') 4749 4750 def test_index_search(self): 4751 table = Table("unordered", "icao C(20)", default_data_types=dict(C=Char), on_disk=False).open(mode=READ_WRITE) 4752 icao = ("kilo charlie echo golf papa hotel delta tango india sierra juliet lima zulu mike " 4753 "bravo november alpha oscar quebec romeo uniform victor whiskey x-ray yankee foxtrot".split()) 4754 for alpha in icao: 4755 table.append((alpha,)) 4756 sorted = table.create_index(lambda rec: rec.icao) 4757 self.assertTrue(sorted.index_search('alpha')) 4758 self.assertTrue(sorted.index_search('bravo')) 4759 self.assertTrue(sorted.index_search('charlie')) 4760 self.assertTrue(sorted.index_search('delta')) 4761 self.assertTrue(sorted.index_search('echo')) 4762 self.assertTrue(sorted.index_search('foxtrot')) 4763 self.assertTrue(sorted.index_search('golf')) 4764 self.assertTrue(sorted.index_search('hotel')) 4765 self.assertTrue(sorted.index_search('india')) 4766 self.assertTrue(sorted.index_search('juliet')) 4767 self.assertTrue(sorted.index_search('kilo')) 4768 self.assertTrue(sorted.index_search('lima')) 4769 self.assertTrue(sorted.index_search('mike')) 4770 self.assertTrue(sorted.index_search('november')) 4771 self.assertTrue(sorted.index_search('oscar')) 4772 self.assertTrue(sorted.index_search('papa')) 4773 self.assertTrue(sorted.index_search('quebec')) 4774 self.assertTrue(sorted.index_search('romeo')) 4775 self.assertTrue(sorted.index_search('sierra')) 4776 self.assertTrue(sorted.index_search('tango')) 4777 self.assertTrue(sorted.index_search('uniform')) 4778 self.assertTrue(sorted.index_search('victor')) 4779 self.assertTrue(sorted.index_search('whiskey')) 4780 self.assertTrue(sorted.index_search('x-ray')) 4781 self.assertTrue(sorted.index_search('yankee')) 4782 self.assertTrue(sorted.index_search('zulu')) 4783 self.assertEqual(sorted.index_search('alpha'), 0) 4784 self.assertEqual(sorted.index_search('bravo'), 1) 4785 self.assertEqual(sorted.index_search('charlie'), 2) 4786 self.assertEqual(sorted.index_search('delta'), 3) 4787 self.assertEqual(sorted.index_search('echo'), 4) 4788 self.assertEqual(sorted.index_search('foxtrot'), 5) 4789 self.assertEqual(sorted.index_search('golf'), 6) 4790 self.assertEqual(sorted.index_search('hotel'), 7) 4791 self.assertEqual(sorted.index_search('india'), 8) 4792 self.assertEqual(sorted.index_search('juliet'), 9) 4793 self.assertEqual(sorted.index_search('kilo'), 10) 4794 self.assertEqual(sorted.index_search('lima'), 11) 4795 self.assertEqual(sorted.index_search('mike'), 12) 4796 self.assertEqual(sorted.index_search('november'), 13) 4797 self.assertEqual(sorted.index_search('oscar'), 14) 4798 self.assertEqual(sorted.index_search('papa'), 15) 4799 self.assertEqual(sorted.index_search('quebec'), 16) 4800 self.assertEqual(sorted.index_search('romeo'), 17) 4801 self.assertEqual(sorted.index_search('sierra'), 18) 4802 self.assertEqual(sorted.index_search('tango'), 19) 4803 self.assertEqual(sorted.index_search('uniform'), 20) 4804 self.assertEqual(sorted.index_search('victor'), 21) 4805 self.assertEqual(sorted.index_search('whiskey'), 22) 4806 self.assertEqual(sorted.index_search('x-ray'), 23) 4807 self.assertEqual(sorted.index_search('yankee'), 24) 4808 self.assertEqual(sorted.index_search('zulu'), 25) 4809 self.assertRaises(NotFoundError, sorted.index_search, 'john') 4810 self.assertRaises(NotFoundError, sorted.index_search, 'john', partial=True) 4811 self.assertEqual(sorted.index_search('able', nearest=True), 0) 4812 self.assertFalse(sorted.index_search('able', nearest=True)) 4813 self.assertEqual(sorted.index_search('alp', partial=True), 0) 4814 self.assertTrue(sorted.index_search('alp', partial=True)) 4815 self.assertEqual(sorted.index_search('john', nearest=True), 9) 4816 self.assertFalse(sorted.index_search('john', nearest=True)) 4817 self.assertEqual(sorted.index_search('jul', partial=True), 9) 4818 self.assertTrue(sorted.index_search('jul', partial=True)) 4819 4820 4821class TestDbfNavigation(TestCase): 4822 4823 def setUp(self): 4824 "create a dbf and vfp table" 4825 self.dbf_table = table = Table( 4826 os.path.join(tempdir, 'temptable'), 4827 'name C(25); paid L; qty N(11,5); orderdate D; desc M', dbf_type='db3' 4828 ) 4829 table.open(mode=READ_WRITE) 4830 namelist = self.dbf_namelist = [] 4831 paidlist = self.dbf_paidlist = [] 4832 qtylist = self.dbf_qtylist = [] 4833 orderlist = self.dbf_orderlist = [] 4834 desclist = self.dbf_desclist = [] 4835 for i in range(len(floats)): 4836 name = '%-25s' % words[i] 4837 paid = len(words[i]) % 3 == 0 4838 qty = floats[i] 4839 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 4840 desc = ' '.join(words[i:i+50]) 4841 namelist.append(name) 4842 paidlist.append(paid) 4843 qtylist.append(qty) 4844 orderlist.append(orderdate) 4845 desclist.append(desc) 4846 table.append({'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc}) 4847 table.close() 4848 4849 self.vfp_table = table = Table( 4850 os.path.join(tempdir, 'tempvfp'), 4851 'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' 4852 ' weight F(18,3); age I; meeting T; misc G; photo P', 4853 dbf_type='vfp', 4854 ) 4855 table.open(mode=READ_WRITE) 4856 namelist = self.vfp_namelist = [] 4857 paidlist = self.vfp_paidlist = [] 4858 qtylist = self.vfp_qtylist = [] 4859 orderlist = self.vfp_orderlist = [] 4860 desclist = self.vfp_desclist = [] 4861 masslist = self.vfp_masslist = [] 4862 weightlist = self.vfp_weightlist = [] 4863 agelist = self.vfp_agelist = [] 4864 meetlist = self.vfp_meetlist = [] 4865 misclist = self.vfp_misclist = [] 4866 photolist = self.vfp_photolist = [] 4867 for i in range(len(floats)): 4868 name = words[i] 4869 paid = len(words[i]) % 3 == 0 4870 qty = floats[i] 4871 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 4872 desc = ' '.join(words[i:i+50]) 4873 mass = floats[i] * floats[i] / 2.0 4874 weight = floats[i] * 3 4875 age = numbers[i] 4876 meeting = datetime.datetime((numbers[i] + 2000), (numbers[i] % 12)+1, (numbers[i] % 28)+1, \ 4877 (numbers[i] % 24), numbers[i] % 60, (numbers[i] * 3) % 60) 4878 misc = ' '.join(words[i:i+50:3]).encode('ascii') 4879 photo = ' '.join(words[i:i+50:7]).encode('ascii') 4880 namelist.append('%-25s' % name) 4881 paidlist.append(paid) 4882 qtylist.append(qty) 4883 orderlist.append(orderdate) 4884 desclist.append(desc) 4885 masslist.append(mass) 4886 weightlist.append(weight) 4887 agelist.append(age) 4888 meetlist.append(meeting) 4889 misclist.append(misc) 4890 photolist.append(photo) 4891 meeting = datetime.datetime((numbers[i] + 2000), (numbers[i] % 12)+1, (numbers[i] % 28)+1, 4892 (numbers[i] % 24), numbers[i] % 60, (numbers[i] * 3) % 60) 4893 table.append({'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc, 4894 'mass':mass, 'weight':weight, 'age':age, 'meeting':meeting, 'misc':misc, 'photo':photo}) 4895 table.close() 4896 4897 def tearDown(self): 4898 self.dbf_table.close() 4899 self.vfp_table.close() 4900 4901 def test_top(self): 4902 "top, current in Tables, Lists, and Indexes" 4903 table = self.dbf_table 4904 table.open(mode=READ_WRITE) 4905 list = List(table) 4906 index = Index(table, key=lambda rec: dbf.recno(rec)) 4907 total = len(table) 4908 mid = total // 2 4909 table.goto(mid) 4910 list.goto(mid) 4911 index.goto(mid) 4912 self.assertTrue(table.current != -1) 4913 self.assertTrue(list.current != -1) 4914 self.assertTrue(index.current != -1) 4915 table.top() 4916 list.top() 4917 index.top() 4918 self.assertEqual(table.current, -1) 4919 self.assertEqual(list.current, -1) 4920 self.assertEqual(index.current, -1) 4921 4922 def test_bottom(self): 4923 "bottom, current in Tables, Lists, and Indexes" 4924 table = self.dbf_table 4925 table.open(mode=READ_WRITE) 4926 list = List(table) 4927 index = Index(table, key=lambda rec: dbf.recno(rec)) 4928 total = len(table) 4929 mid = total // 2 4930 table.goto(mid) 4931 list.goto(mid) 4932 index.goto(mid) 4933 self.assertTrue(table.current != -1) 4934 self.assertTrue(list.current != -1) 4935 self.assertTrue(index.current != -1) 4936 table.bottom() 4937 list.bottom() 4938 index.bottom() 4939 self.assertEqual(table.current, total) 4940 self.assertEqual(list.current, total) 4941 self.assertEqual(index.current, total) 4942 4943 def test_goto(self): 4944 "goto, current in Tables, Lists, and Indexes" 4945 table = self.dbf_table 4946 table.open(mode=READ_WRITE) 4947 list = List(table) 4948 index = Index(table, key=lambda rec: dbf.recno(rec)) 4949 total = len(table) 4950 mid = total // 2 4951 table.goto(mid) 4952 list.goto(mid) 4953 index.goto(mid) 4954 self.assertEqual(table.current, mid) 4955 self.assertEqual(list.current, mid) 4956 self.assertEqual(index.current, mid) 4957 table.goto('top') 4958 list.goto('top') 4959 index.goto('top') 4960 self.assertEqual(table.current, -1) 4961 self.assertEqual(list.current, -1) 4962 self.assertEqual(index.current, -1) 4963 table.goto('bottom') 4964 list.goto('bottom') 4965 index.goto('bottom') 4966 self.assertEqual(table.current, total) 4967 self.assertEqual(list.current, total) 4968 self.assertEqual(index.current, total) 4969 dbf.delete(table[10]) 4970 self.assertTrue(dbf.is_deleted(list[10])) 4971 self.assertTrue(dbf.is_deleted(index[10])) 4972 table.goto(10) 4973 list.goto(10) 4974 index.goto(10) 4975 self.assertEqual(table.current, 10) 4976 self.assertEqual(list.current, 10) 4977 self.assertEqual(index.current, 10) 4978 table.close() 4979 4980 def test_skip(self): 4981 "skip, current in Tables, Lists, and Indexes" 4982 table = self.dbf_table 4983 table.open(mode=READ_WRITE) 4984 list = List(table) 4985 index = Index(table, key=lambda rec: dbf.recno(rec)) 4986 total = len(table) 4987 self.assertEqual(table.current, -1) 4988 self.assertEqual(list.current, -1) 4989 self.assertEqual(index.current, -1) 4990 table.skip(1) 4991 list.skip(1) 4992 index.skip(1) 4993 self.assertEqual(table.current, 0) 4994 self.assertEqual(list.current, 0) 4995 self.assertEqual(index.current, 0) 4996 table.skip(10) 4997 list.skip(10) 4998 index.skip(10) 4999 self.assertEqual(table.current, 10) 5000 self.assertEqual(list.current, 10) 5001 self.assertEqual(index.current, 10) 5002 table.close() 5003 5004 def test_first_record(self): 5005 "first_record in Tables, Lists, and Indexes" 5006 table = self.dbf_table 5007 table.open(mode=READ_WRITE) 5008 list = List(table) 5009 index = Index(table, key=lambda rec: dbf.recno(rec)) 5010 total = len(table) 5011 self.assertTrue(table[0] is list[0]) 5012 self.assertTrue(table[0] is index[0]) 5013 self.assertTrue(table.first_record is table[0]) 5014 self.assertTrue(list.first_record is table[0]) 5015 self.assertTrue(index.first_record is table[0]) 5016 table.close() 5017 5018 def test_prev_record(self): 5019 "prev_record in Tables, Lists, and Indexes" 5020 table = self.dbf_table 5021 table.open(mode=READ_WRITE) 5022 list = List(table) 5023 index = Index(table, key=lambda rec: dbf.recno(rec)) 5024 total = len(table) 5025 self.assertTrue(table[0] is list[0]) 5026 self.assertTrue(table[0] is index[0]) 5027 table.top() 5028 list.top() 5029 index.top() 5030 self.assertTrue(isinstance(table.prev_record, dbf.RecordVaporWare)) 5031 self.assertTrue(isinstance(list.prev_record, dbf.RecordVaporWare)) 5032 self.assertTrue(isinstance(index.prev_record, dbf.RecordVaporWare)) 5033 table.skip() 5034 list.skip() 5035 index.skip() 5036 self.assertTrue(isinstance(table.prev_record, dbf.RecordVaporWare)) 5037 self.assertTrue(isinstance(list.prev_record, dbf.RecordVaporWare)) 5038 self.assertTrue(isinstance(index.prev_record, dbf.RecordVaporWare)) 5039 table.skip() 5040 list.skip() 5041 index.skip() 5042 self.assertTrue(table.prev_record is table[0]) 5043 self.assertTrue(list.prev_record is table[0]) 5044 self.assertTrue(index.prev_record is table[0]) 5045 table.close() 5046 5047 def test_current_record(self): 5048 "current_record in Tables, Lists, and Indexes" 5049 table = self.dbf_table 5050 table.open(mode=READ_WRITE) 5051 list = List(table) 5052 index = Index(table, key=lambda rec: dbf.recno(rec)) 5053 total = len(table) 5054 mid = total // 2 5055 table.top() 5056 list.top() 5057 index.top() 5058 self.assertTrue(isinstance(table.current_record, dbf.RecordVaporWare)) 5059 self.assertTrue(isinstance(list.current_record, dbf.RecordVaporWare)) 5060 self.assertTrue(isinstance(index.current_record, dbf.RecordVaporWare)) 5061 table.bottom() 5062 list.bottom() 5063 index.bottom() 5064 self.assertTrue(isinstance(table.current_record, dbf.RecordVaporWare)) 5065 self.assertTrue(isinstance(list.current_record, dbf.RecordVaporWare)) 5066 self.assertTrue(isinstance(index.current_record, dbf.RecordVaporWare)) 5067 table.goto(mid) 5068 list.goto(mid) 5069 index.goto(mid) 5070 self.assertTrue(table.current_record is table[mid]) 5071 self.assertTrue(list.current_record is table[mid]) 5072 self.assertTrue(index.current_record is table[mid]) 5073 table.close() 5074 5075 def test_next_record(self): 5076 "prev_record in Tables, Lists, and Indexes" 5077 table = self.dbf_table 5078 table.open(mode=READ_WRITE) 5079 list = List(table) 5080 index = Index(table, key=lambda rec: dbf.recno(rec)) 5081 total = len(table) 5082 self.assertTrue(table[0] is list[0]) 5083 self.assertTrue(table[0] is index[0]) 5084 table.bottom() 5085 list.bottom() 5086 index.bottom() 5087 self.assertTrue(isinstance(table.next_record, dbf.RecordVaporWare)) 5088 self.assertTrue(isinstance(list.next_record, dbf.RecordVaporWare)) 5089 self.assertTrue(isinstance(index.next_record, dbf.RecordVaporWare)) 5090 table.skip(-1) 5091 list.skip(-1) 5092 index.skip(-1) 5093 self.assertTrue(isinstance(table.next_record, dbf.RecordVaporWare)) 5094 self.assertTrue(isinstance(list.next_record, dbf.RecordVaporWare)) 5095 self.assertTrue(isinstance(index.next_record, dbf.RecordVaporWare)) 5096 table.skip(-1) 5097 list.skip(-1) 5098 index.skip(-1) 5099 self.assertTrue(table.next_record is table[-1]) 5100 self.assertTrue(list.next_record is table[-1]) 5101 self.assertTrue(index.next_record is table[-1]) 5102 table.close() 5103 5104 def test_last_record(self): 5105 "last_record in Tables, Lists, and Indexes" 5106 table = self.dbf_table 5107 table.open(mode=READ_WRITE) 5108 list = List(table) 5109 index = Index(table, key=lambda rec: dbf.recno(rec)) 5110 total = len(table) 5111 self.assertTrue(table[-1] is list[-1]) 5112 self.assertTrue(table[-1] is index[-1]) 5113 self.assertTrue(table.last_record is table[-1]) 5114 self.assertTrue(list.last_record is table[-1]) 5115 self.assertTrue(index.last_record is table[-1]) 5116 table.close() 5117 5118 5119class TestDbfLists(TestCase): 5120 "DbfList tests" 5121 5122 def setUp(self): 5123 "create a dbf table" 5124 self.dbf_table = table = Table( 5125 os.path.join(tempdir, 'temptable'), 5126 'name C(25); paid L; qty N(11,5); orderdate D; desc M', dbf_type='db3' 5127 ) 5128 table.open(mode=READ_WRITE) 5129 records = [] 5130 for i in range(len(floats)): 5131 name = words[i] 5132 paid = len(words[i]) % 3 == 0 5133 qty = round(floats[i], 5) 5134 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 5135 desc = ' '.join(words[i:i+50]) 5136 data = {'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc} 5137 table.append(data) 5138 records.append(data) 5139 table.close() 5140 table.open(mode=READ_WRITE) 5141 for trec, drec in zip(table, records): 5142 self.assertEqual(trec.name.strip(), drec['name']) 5143 self.assertEqual(trec.paid, drec['paid']) 5144 self.assertEqual(trec.qty, drec['qty']) 5145 self.assertEqual(trec.orderdate, drec['orderdate']) 5146 self.assertEqual(trec.desc, drec['desc']) 5147 table.close() 5148 5149 def tearDown(self): 5150 self.dbf_table.close() 5151 5152 def test_exceptions(self): 5153 table = self.dbf_table 5154 table.open(mode=READ_WRITE) 5155 list = table[::5] 5156 record = table[5] 5157 dbf.delete(record) 5158 self.assertTrue(list[0] is table[0]) 5159 self.assertTrue(record in list) 5160 self.assertRaises(TypeError, list.__contains__, 'some string') 5161 self.assertRaises(TypeError, list.__getitem__, 'some string') 5162 self.assertRaises(TypeError, list.__delitem__, 'some string') 5163 self.assertRaises(TypeError, list.remove, 'some string') 5164 self.assertRaises(TypeError, list.index, 'some string') 5165 self.assertRaises(IndexError, list.__getitem__, 100) 5166 self.assertRaises(IndexError, list.pop, 1000) 5167 self.assertRaises(IndexError, list.goto, 1000) 5168 list.top() 5169 self.assertRaises(Bof, list.skip, -1) 5170 list.bottom() 5171 self.assertRaises(Eof, list.skip) 5172 table.pack() 5173 self.assertRaises(DbfError, list.__contains__, record) 5174 5175 list = List() 5176 self.assertRaises(IndexError, list.goto, 0) 5177 self.assertRaises(Bof, list.skip, -1) 5178 self.assertRaises(Eof, list.skip) 5179 self.assertRaises(ValueError, list.remove, table[0]) 5180 self.assertRaises(ValueError, list.index, table[1]) 5181 5182 def test_add_subtract(self): 5183 "addition and subtraction" 5184 table1 = self.dbf_table 5185 table1.open(mode=READ_WRITE) 5186 list1 = table1[::2] 5187 list2 = table1[::3] 5188 list3 = table1[:] - list1 - list2 5189 self.assertEqual(100, len(table1)) 5190 self.assertEqual(list1[0], list2[0]) 5191 self.assertEqual(list1[3], list2[2]) 5192 self.assertEqual(50, len(list1)) 5193 self.assertEqual(34, len(list2)) 5194 self.assertEqual(33, len(list3)) 5195 self.assertEqual(117, len(list1) + len(list2) + len(list3)) 5196 self.assertEqual(len(table1), len(list1 + list2 + list3)) 5197 self.assertEqual(67, len(list1 + list2)) 5198 self.assertEqual(33, len(list1 - list2)) 5199 self.assertEqual(17, len(list2 - list1)) 5200 table1.close() 5201 5202 def test_append_extend(self): 5203 "appending and extending" 5204 table1 = self.dbf_table 5205 table1.open(mode=READ_WRITE) 5206 list1 = table1[::2] 5207 list2 = table1[::3] 5208 list3 = table1[:] - list1 - list2 5209 list1.extend(list2) 5210 list2.append(table1[1]) 5211 self.assertEqual(67, len(list1)) 5212 self.assertEqual(35, len(list2)) 5213 list1.append(table1[1]) 5214 list2.extend(list3) 5215 self.assertEqual(68, len(list1)) 5216 self.assertEqual(67, len(list2)) 5217 table1.close() 5218 5219 def test_index(self): 5220 "indexing" 5221 table1 = self.dbf_table 5222 table1.open(mode=READ_WRITE) 5223 list1 = table1[::2] 5224 list2 = table1[::3] 5225 list3 = table1[:] - list1 - list2 5226 for i, rec in enumerate(list1): 5227 self.assertEqual(i, list1.index(rec)) 5228 for rec in list3: 5229 self.assertRaises(ValueError, list1.index, rec ) 5230 table1.close() 5231 5232 def test_sort(self): 5233 "sorting" 5234 table1 = self.dbf_table 5235 table1.open(mode=READ_WRITE) 5236 list1 = table1[::2] 5237 list2 = table1[::3] 5238 table1[:] - list1 - list2 5239 list4 = table1[:] 5240 index = table1.create_index(key = lambda rec: rec.name ) 5241 list4.sort(key=lambda rec: rec.name) 5242 for trec, lrec in zip(index, list4): 5243 self.assertEqual(dbf.recno(trec), dbf.recno(lrec)) 5244 table1.close() 5245 5246 def test_keys(self): 5247 "keys" 5248 table1 = self.dbf_table 5249 table1.open(mode=READ_WRITE) 5250 field = table1.field_names[0] 5251 list1 = List(table1, key=lambda rec: rec[field]) 5252 unique = set() 5253 for rec in table1: 5254 if rec[field] not in unique: 5255 unique.add(rec[field]) 5256 else: 5257 self.assertRaises(NotFoundError, list1.index, rec) 5258 self.assertFalse(rec in list1) 5259 self.assertTrue(rec[field] in unique) 5260 self.assertEqual(len(unique), len(list1)) 5261 table1.close() 5262 5263 def test_contains(self): 5264 table = self.dbf_table 5265 table.open(mode=READ_WRITE) 5266 list = List(table) 5267 i = 0 5268 for record in list: 5269 self.assertEqual(record, list[i]) 5270 self.assertTrue(record in list) 5271 self.assertTrue(tuple(record) in list) 5272 self.assertTrue(scatter(record) in list) 5273 self.assertTrue(create_template(record) in list) 5274 i += 1 5275 self.assertEqual(i, len(list)) 5276 table.close() 5277 5278 5279class TestFieldnameLists(TestCase): 5280 "FieldnameList tests" 5281 5282 def test_exceptions(self): 5283 self.assertRaises(TypeError, FieldnameList, [1]) 5284 self.assertRaises(TypeError, FieldnameList, ([u'1toy', int])) 5285 list1 = FieldnameList(unicodify(['lower', 'UPPER', 'MiXeD'])) 5286 self.assertRaises(TypeError, list1.__add__, [7]) 5287 self.assertRaises(TypeError, list1.__contains__, 7) 5288 self.assertRaises(TypeError, list1.__iadd__, [7]) 5289 self.assertRaises(TypeError, list1.__radd__, [7]) 5290 self.assertRaises(TypeError, list1.__setitem__, 0, 7) 5291 self.assertRaises(TypeError, list1.append, 7) 5292 self.assertRaises(TypeError, list1.count, 7) 5293 self.assertRaises(TypeError, list1.index, 7) 5294 self.assertRaises(TypeError, list1.insert, 7) 5295 self.assertRaises(TypeError, list1.remove, 7) 5296 5297 5298 def test_create(self): 5299 list1 = FieldnameList(['_this', 'that', 'somemore8']) 5300 list2 = list(list1) 5301 self.assertEqual(list2, unicodify(['_THIS', 'THAT', 'SOMEMORE8'])) 5302 self.assertEqual(list1, list2) 5303 5304 def test_add(self): 5305 "addition" 5306 list1 = FieldnameList(unicodify(['lower', 'UPPER', 'MiXeD'])) 5307 list2 = FieldnameList(['wah', u'a\xf1o']) 5308 list3 = FieldnameList(unicodify(['heh', 'hah'])) 5309 # 5310 list4 = list1 + list2 5311 self.assertEqual(list1, ['Lower', 'uppeR', 'Mixed']) 5312 self.assertEqual(list2, unicodify(['wah', u'A\xf1o'])) 5313 self.assertEqual(list4, unicodify(['loWer', 'UPpER', 'mixEd', 'wah', u'a\xf1O'])) 5314 self.assertTrue(isinstance(list4, FieldnameList)) 5315 # 5316 list4 += list3 5317 self.assertEqual(list3, unicodify(['heh', 'hah'])) 5318 self.assertEqual(list4, unicodify(['LOWER', 'upper', 'MIxeD', 'wah', u'A\xf1O', 'heh', 'hah'])) 5319 self.assertTrue(isinstance(list4, FieldnameList)) 5320 # 5321 unicode_list = unicodify(['uhhuh', 'UhUh', 'zero']) 5322 self.assertEqual(unicode_list, [u'uhhuh', u'UhUh', u'zero']) 5323 list5 = unicode_list + list1 5324 self.assertEqual(list1, unicodify(['LoWeR', 'uPpEr', 'MixED'])) 5325 self.assertEqual(list5, unicodify(['UhHuh', 'uHuH', 'zero', 'lowER', 'UPPer', 'miXeD'])) 5326 self.assertTrue(isinstance(list5, FieldnameList)) 5327 5328 def test_append_extend(self): 5329 "appending and extending" 5330 list1 = FieldnameList(unicodify(['lowER', 'UPPer', 'miXeD'])) 5331 list2 = FieldnameList(['wah', u'a\xd1o']) 5332 list3 = FieldnameList(unicodify(['heh', 'hah'])) 5333 # 5334 list1.append('ten') 5335 self.assertEqual(list1, ['LOWer', 'uppER', 'MIxEd', 'ten']) 5336 list2.extend(unicodify(['prime', 'Maybe'])) 5337 self.assertEqual(list2, unicodify(['wah', u'A\xd1o', 'PRIME', 'maybe'])) 5338 # 5339 list3.extend(list1) 5340 self.assertEqual(list1, unicodify(['lower', 'UPPER', 'miXEd', 'ten'])) 5341 self.assertEqual(list3, unicodify(['heh', 'hah', 'Lower', 'uPPER', 'MiXEd', 'ten'])) 5342 5343 def test_index(self): 5344 "indexing" 5345 list1 = FieldnameList(unicodify(['lOwEr', 'UpPeR', 'mIXed'])) 5346 list2 = FieldnameList(['wah', u'a\xd1O']) 5347 list3 = FieldnameList(unicodify(['heh', 'hah'])) 5348 # 5349 self.assertEqual(list1.index('lower'), 0) 5350 self.assertEqual(list2.index(u'A\xd1O'), 1) 5351 self.assertRaises(ValueError, list3.index, u'not there') 5352 self.assertRaises(ValueError, list3.index, 'not there') 5353 # 5354 slice1 = list1[:] 5355 slice2 = list2[:1] 5356 slice3 = list3[1:] 5357 self.assertTrue(isinstance(slice1, FieldnameList)) 5358 self.assertTrue(isinstance(slice2, FieldnameList)) 5359 self.assertTrue(isinstance(slice3, FieldnameList)) 5360 self.assertEqual(slice1, ['LOWER', 'UPPER', 'MIXED']) 5361 self.assertEqual(slice2, unicodify(['WAH'])) 5362 self.assertEqual(slice3, unicodify(['HAH'])) 5363 5364 def test_sort(self): 5365 "sorting" 5366 list1 = FieldnameList(unicodify(['LoweR', 'uPPEr', 'MiXED'])) 5367 list2 = FieldnameList(['wah', u'A\xd1O']) 5368 list3 = FieldnameList(unicodify(['heh', 'hah'])) 5369 list1.sort() 5370 list2.sort() 5371 list3.sort() 5372 # 5373 self.assertEqual(list1, ['LOWER', 'MIXED', 'UPPER']) 5374 self.assertEqual(list2, unicodify([u'A\xD1O', 'WAH'])) 5375 self.assertEqual(list3, unicodify(['HAH', 'HEH'])) 5376 self.assertFalse(list3 != list3) 5377 self.assertFalse(list2 < list2) 5378 self.assertFalse(list1 > list1) 5379 # 5380 list4 = list2[:] 5381 list5 = list2[:] + ['bar'] 5382 list6 = list2[:] + unicodify(['size']) 5383 list4.sort() 5384 list5.sort() 5385 list6.sort() 5386 # 5387 self.assertTrue(list2 < list1) 5388 self.assertTrue(list2 <= list1) 5389 self.assertFalse(list2 == list1) 5390 self.assertFalse(list2 >= list1) 5391 self.assertFalse(list2 > list1) 5392 self.assertTrue(list2 == list4) 5393 self.assertTrue(list4 > list5) 5394 self.assertTrue(list5 < list6) 5395 self.assertTrue(list5 <= list6) 5396 self.assertTrue(list5 != list6) 5397 self.assertFalse(list5 >= list6) 5398 self.assertFalse(list5 > list6) 5399 self.assertTrue(list6 > list5) 5400 self.assertTrue(list6 < list4) 5401 5402 def test_contains(self): 5403 list1 = FieldnameList(unicodify(['lower', 'UPPER', 'MiXeD'])) 5404 list2 = FieldnameList(['wah', u'a\xf1o']) 5405 list3 = FieldnameList(unicodify(['heh', 'hah'])) 5406 # 5407 self.assertTrue('Mixed' in list1) 5408 self.assertFalse(u'a\xf1o' in list1) 5409 self.assertTrue(u'A\xf1O' in list2) 5410 self.assertFalse('HEH' in list2) 5411 self.assertTrue(u'HEH' in list3) 5412 self.assertFalse(u'Mixed' in list3) 5413 5414 5415class TestReadWriteDefaultOpen(TestCase): 5416 "test __enter__/__exit__" 5417 5418 def setUp(self): 5419 "create a dbf table" 5420 self.dbf_table = table = Table( 5421 os.path.join(tempdir, 'temptable'), 5422 'name C(25); paid L; qty N(11,5); orderdate D; desc M', dbf_type='db3' 5423 ) 5424 table.open(READ_WRITE) 5425 table.append(('Rose Petals', True, 115, Date(2018, 2, 14), 'lightly scented, pink & red')) 5426 table.close() 5427 5428 def tearDown(self): 5429 os.chmod(self.dbf_table.filename, stat.S_IWRITE|stat.S_IREAD) 5430 os.chmod(self.dbf_table._meta.memoname, stat.S_IWRITE|stat.S_IREAD) 5431 self.dbf_table.close() 5432 5433 def test_context_manager(self): 5434 with self.dbf_table as t: 5435 t.append(dict(name='Stoneleaf', paid=True, qty=1)) 5436 5437 def test_delete_fields(self): 5438 dbf.delete_fields(self.dbf_table.filename, 'orderdate') 5439 5440 def test_add_fields(self): 5441 dbf.add_fields(self.dbf_table.filename, 'alias C(25)') 5442 5443 def test_processing(self): 5444 for rec in dbf.Process(self.dbf_table): 5445 rec.name = 'Carnations' 5446 5447 def test_read_only(self): 5448 table = self.dbf_table 5449 os.chmod(table.filename, stat.S_IREAD) 5450 os.chmod(table._meta.memoname, stat.S_IREAD) 5451 table.open(READ_ONLY) 5452 table.close() 5453 self.assertRaises((IOError, OSError), table.open, READ_WRITE) 5454 5455 5456class TestDBC(TestCase): 5457 "test DBC handling" 5458 5459 5460class TestVapor(TestCase): 5461 "test Vapor objects" 5462 5463 def test_falsey(self): 5464 self.assertFalse(dbf.Vapor) 5465 5466 5467class TestMisc(TestCase): 5468 "miscellaneous tests" 5469 5470 def setUp(self): 5471 self.table = Table( 5472 os.path.join(tempdir, 'dbf_table.'), 5473 'name C(25); paid L; qty N(11,5); orderdate D; desc M', 5474 dbf_type='db3', 5475 ) 5476 self.table_dbf = Table( 5477 os.path.join(tempdir, 'dbf_table.dbf'), 5478 'name C(25); paid L; qty N(11,5); orderdate D; desc M', 5479 dbf_type='db3', 5480 ) 5481 self.table_implicit = Table( 5482 os.path.join(tempdir, 'dbf_table'), 5483 'name C(25); paid L; qty N(11,5); orderdate D; desc M', 5484 dbf_type='db3', 5485 ) 5486 self.table_wierd = Table( 5487 os.path.join(tempdir, 'dbf_table.blah'), 5488 'name C(25); paid L; qty N(11,5); orderdate D; desc M', 5489 dbf_type='db3', 5490 ) 5491 self.table.close() 5492 self.table_dbf.close() 5493 self.table_implicit.close() 5494 self.table_wierd.close() 5495 5496 def test_table_type_with_dbf(self): 5497 dbf.table_type(self.table.filename) 5498 dbf.table_type(self.table_dbf.filename) 5499 dbf.table_type(self.table_implicit.filename) 5500 dbf.table_type(self.table_wierd.filename) 5501 dbf.Table(self.table.filename) 5502 dbf.Table(self.table_dbf.filename) 5503 dbf.Table(self.table_implicit.filename) 5504 dbf.Table(self.table_wierd.filename) 5505 5506 5507class TestWhatever(TestCase): 5508 "move tests here to run one at a time while debugging" 5509 5510 def setUp(self): 5511 "create a dbf and vfp table" 5512 self.dbf_table = table = Table( 5513 os.path.join(tempdir, 'temptable'), 5514 'name C(25); paid L; qty N(11,5); orderdate D; desc M', dbf_type='db3' 5515 ) 5516 table.open(mode=READ_WRITE) 5517 namelist = self.dbf_namelist = [] 5518 paidlist = self.dbf_paidlist = [] 5519 qtylist = self.dbf_qtylist = [] 5520 orderlist = self.dbf_orderlist = [] 5521 desclist = self.dbf_desclist = [] 5522 for i in range(len(floats)): 5523 name = '%-25s' % words[i] 5524 paid = len(words[i]) % 3 == 0 5525 qty = round(floats[i], 5) 5526 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 5527 desc = ' '.join(words[i:i+50]) 5528 namelist.append(name) 5529 paidlist.append(paid) 5530 qtylist.append(qty) 5531 orderlist.append(orderdate) 5532 desclist.append(desc) 5533 table.append({'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc}) 5534 table.close() 5535 5536 self.vfp_table = table = Table( 5537 os.path.join(tempdir, 'tempvfp'), 5538 'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' 5539 ' weight F(18,3); age I; meeting T; misc G; photo P', 5540 dbf_type='vfp', 5541 ) 5542 table.open(mode=READ_WRITE) 5543 namelist = self.vfp_namelist = [] 5544 paidlist = self.vfp_paidlist = [] 5545 qtylist = self.vfp_qtylist = [] 5546 orderlist = self.vfp_orderlist = [] 5547 desclist = self.vfp_desclist = [] 5548 masslist = self.vfp_masslist = [] 5549 weightlist = self.vfp_weightlist = [] 5550 agelist = self.vfp_agelist = [] 5551 meetlist = self.vfp_meetlist = [] 5552 misclist = self.vfp_misclist = [] 5553 photolist = self.vfp_photolist = [] 5554 for i in range(len(floats)): 5555 name = words[i] 5556 paid = len(words[i]) % 3 == 0 5557 qty = round(floats[i], 5) 5558 orderdate = datetime.date((numbers[i] + 1) * 2, (numbers[i] % 12) +1, (numbers[i] % 27) + 1) 5559 desc = ' '.join(words[i:i+50]) 5560 mass = floats[i] * floats[i] / 2.0 5561 weight = round(floats[i] * 3, 3) 5562 age = numbers[i] 5563 meeting = datetime.datetime((numbers[i] + 2000), (numbers[i] % 12)+1, (numbers[i] % 28)+1, \ 5564 (numbers[i] % 24), numbers[i] % 60, (numbers[i] * 3) % 60) 5565 misc = ' '.join(words[i:i+50:3]).encode('ascii') 5566 photo = ' '.join(words[i:i+50:7]).encode('ascii') 5567 namelist.append('%-25s' % name) 5568 paidlist.append(paid) 5569 qtylist.append(qty) 5570 orderlist.append(orderdate) 5571 desclist.append(desc) 5572 masslist.append(mass) 5573 weightlist.append(weight) 5574 agelist.append(age) 5575 meetlist.append(meeting) 5576 misclist.append(misc) 5577 photolist.append(photo) 5578 meeting = datetime.datetime((numbers[i] + 2000), (numbers[i] % 12)+1, (numbers[i] % 28)+1, 5579 (numbers[i] % 24), numbers[i] % 60, (numbers[i] * 3) % 60) 5580 table.append({'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc, 5581 'mass':mass, 'weight':weight, 'age':age, 'meeting':meeting, 'misc':misc, 'photo':photo}) 5582 table.close() 5583 5584 def tearDown(self): 5585 self.dbf_table.close() 5586 self.vfp_table.close() 5587 5588 5589# main 5590if __name__ == '__main__': 5591 tempdir = tempfile.mkdtemp() 5592 try: 5593 unittest.main() 5594 finally: 5595 shutil.rmtree(tempdir, True) 5596