Source code for ship.utils.dbfread.test_field_parser

import datetime
from decimal import Decimal
from pytest import raises
from .field_parser import FieldParser

[docs]class MockHeader(object): dbversion = 0x02
[docs]class MockDBF(object): def __init__(self): self.header = MockHeader() self.encoding = 'ascii'
[docs]class MockField(object): def __init__(self, type='', **kwargs): self.type = type self.__dict__.update(kwargs)
[docs]class MockMemoFile(dict): def __getitem__(self, index): if index == 0: return None else: return dict.__getitem__(self, index)
[docs]def make_field_parser(field_type, dbversion=0x02, memofile=None): dbf = MockDBF() dbf.header.dbversion = dbversion parser = FieldParser(dbf, memofile) field = MockField(field_type) def parse(data): return parser.parse(field, data) return parse
[docs]def test_0(): parse = make_field_parser('0') assert parse(b'\0') == b'\x00' assert parse(b'\xaa\xff') == b'\xaa\xff'
[docs]def test_C(): parse = make_field_parser('C') assert type(parse(b'test')) == type(u'')
[docs]def test_D(): parse = make_field_parser('D') assert parse(b'00000000') is None assert parse(b' ') is None epoch = datetime.date(1970, 1, 1) assert parse(b'19700101') == epoch with raises(ValueError): parse(b'NotIntgr')
[docs]def test_F(): parse = make_field_parser('F') assert parse(b'') is None assert parse(b' ') is None assert parse(b'0') == 0 assert parse(b'1') == 1 assert parse(b'-1') == -1 assert parse(b'3.14') == 3.14 with raises(ValueError): parse(b'jsdf')
# This also tests parse2B() (+)
[docs]def test_I(): parse = make_field_parser('I') # Little endian unsigned integer. assert parse(b'\x00\x00\x00\x00') == 0 assert parse(b'\x01\x00\x00\x00') == 1 assert parse(b'\xff\xff\xff\xff') == -1
[docs]def test_L(): parse = make_field_parser('L') for char in b'TtYy': assert parse(char) is True for char in b'FfNn': assert parse(char) is False for char in b'? ': assert parse(char) is None # Some invalid values. for char in b'!0': with raises(ValueError): parse(char)
# This also tests B, G and P.
[docs]def test_M(): parse = make_field_parser('M', memofile=MockMemoFile({1: b'test'})) assert parse(b'\x01\x00\x00\x00') == u'test' assert parse(b'1') == u'test' assert parse(b'') is None with raises(ValueError): parse(b'NotInteger')
[docs]def test_B(): # In VisualFox the B field is a double precision floating point number. parse = make_field_parser('B', dbversion=0x30) assert isinstance(parse(b'01abcdef'), float) assert parse(b'\0' * 8) == 0.0 # Data must be exactly 8 bytes. with raises(Exception): parse(b'') # In other db versions it is a memo index. parse = make_field_parser('B', dbversion=0x02, memofile=MockMemoFile({1: b'test'})) parse(b'1') == b'test' parse(b'') is None
[docs]def test_N(): parse = make_field_parser('N') assert parse(b'') is None assert parse(b' ') is None assert parse(b'1') == 1 assert parse(b'-99') == -99 assert parse(b'3.14') == 3.14 with raises(ValueError): parse(b'okasd')
[docs]def test_O(): """Test double field.""" parse = make_field_parser('O') assert parse(b'\x00' * 8) == 0.0 assert parse(b'\x00\x00\x00\x00\x00\x00\xf0?') == 1.0 assert parse(b'\x00\x00\x00\x00\x00\x00Y\xc0') == -100
# This also tests parse40() (@)
[docs]def test_T(): parse = make_field_parser('T') assert parse(b'') is None assert parse(b' ') is None
# Todo: add more tests.
[docs]def test_Y(): parse = make_field_parser('Y') assert parse(b'\1\0\0\0\0\0\0\0') == Decimal('0.0001') assert parse(b'\xff\xff\xff\xff\xff\xff\xff\xff') == Decimal('-0.0001')
[docs]def test_hex_field(): class PlusFieldParser(FieldParser): encoding = 'latin1' def parse3F(self, field, data): """Parser for '?' field.""" return None parser = PlusFieldParser(MockDBF()) field = MockField('?') parser.parse(field, b'test')