Completed
Push — master ( 887f61...192352 )
by Aaron
06:16
created

TestElementBitField   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 114
rs 10
wmc 16

5 Methods

Rating   Name   Duplication   Size   Complexity  
B test_out_of_range_values_pack() 0 25 4
A test_invalid_enum() 0 13 3
A test_unpack() 0 23 3
B test_valid_pack() 0 26 3
A test_not_valid() 0 20 3
1
#!/usr/bin/env python3
2
3
"""Tests for the elementenum class"""
4
5
import unittest
6
7
import enum
8
from starstruct.bitfield import BitField
9
from starstruct.elementbitfield import ElementBitField
10
11
12
class SimpleEnum(enum.Enum):
13
    """Simple enum class for testing message pack/unpack"""
14
    one = 1
15
    two = 2
16
    four = 4
17
18
19
class SimpleEnumWithZero(enum.Enum):
20
    """Simple enum class for testing message pack/unpack"""
21
    zero = 0
22
    one = 1
23
    two = 2
24
25
26
# pylint: disable=blacklisted-name
27
class StrEnum(enum.Enum):
28
    """string based enum class for testing message pack/unpack"""
29
    foo = 'foo'
30
    bar = 'bar'
31
32
33
# pylint: disable=line-too-long,invalid-name,no-self-use
34
class TestElementBitField(unittest.TestCase):
35
    """ElementBitField module tests"""
36
37
    def test_invalid_enum(self):
38
        """Test field formats that are valid ElementBitField elements."""
39
        # pylint: disable=unused-variable
40
41
        with self.assertRaises(TypeError) as cm:
42
            test_bitfield = BitField(StrEnum)  # noqa: F841
43
        msg = 'Enum {} members must have integer values'.format(repr(StrEnum))
44
        self.assertEqual(str(cm.exception), msg)
45
46
        with self.assertRaises(TypeError) as cm:
47
            test_bitfield = BitField(SimpleEnumWithZero)  # noqa: F841
48
        msg = 'Cannot construct BitField from {} with a value for 0: {}'
49
        self.assertEqual(str(cm.exception), msg.format(repr(SimpleEnumWithZero), SimpleEnumWithZero.zero))
50
51
    def test_not_valid(self):
52
        """Test field formats that are not valid ElementEnum elements."""
53
54
        test_bitfield = BitField(SimpleEnum)
55
56
        test_fields = [
57
            ('a', 'b', SimpleEnum),      # enum field
58
            ('a', 'b', StrEnum),       # enum field
59
            ('a', '4x', test_bitfield),  # 4 pad bytes
60
            ('b', 'z', test_bitfield),   # invalid
61
            ('c', '1', test_bitfield),   # invalid
62
            ('e', '9s', test_bitfield),  # invalid (no strings allowed)
63
            ('d', '/', test_bitfield),   # invalid
64
            ('f', 'H'),               # unsigned short (no class)
65
        ]
66
67
        for field in test_fields:
68
            with self.subTest(field):  # pylint: disable=no-member
69
                out = ElementBitField.valid(field)
70
                self.assertFalse(out)
71
72
    def test_valid_pack(self):
73
        """Test packing valid enum values."""
74
75
        test_bitfield = BitField(SimpleEnum)
76
77
        field = ('a', 'b', test_bitfield)  # signed byte: -128, 127
78
        out = ElementBitField.valid(field)
79
        self.assertTrue(out)
80
81
        elem = ElementBitField(field)
82
        test_values = [
83
            ({'a': 2}, b'\x02'),
84
            ({'a': []}, b'\x00'),
85
            ({'a': None}, b'\x00'),
86
            ({'a': 0}, b'\x00'),  # 0 is treated the same as None or an empty list
87
            ({'a': [SimpleEnum.one]}, b'\x01'),
88
            ({'a': ['one']}, b'\x01'),
89
            ({'a': [SimpleEnum.two]}, b'\x02'),
90
            ({'a': [SimpleEnum.one, SimpleEnum.two]}, b'\x03'),
91
            ({'a': [1, SimpleEnum.two]}, b'\x03'),
92
            ({'a': [1, SimpleEnum.two, 'four']}, b'\x07'),
93
        ]
94
        for (in_val, out_val) in test_values:
95
            with self.subTest((out_val, in_val)):  # pylint: disable=no-member
96
                ret = elem.pack(in_val)
97
                self.assertEqual(ret, out_val)
98
99
    def test_out_of_range_values_pack(self):
100
        """Test packing invalid enum values."""
101
102
        test_bitfield = BitField(SimpleEnum)
103
104
        field = ('a', 'b', test_bitfield)  # signed byte: -128, 127
105
        out = ElementBitField.valid(field)
106
        self.assertTrue(out)
107
108
        elem = ElementBitField(field)
109
        test_values = [
110
            ({'a': -1}, -1),
111
            ({'a': 3}, 3),
112
            ({'a': [0, SimpleEnum.one]}, 0),
113
            ({'a': [SimpleEnum.one, -1]}, -1),
114
            ({'a': [SimpleEnum.two, 3]}, 3),
115
            ({'a': ['TWO']}, 'TWO'),
116
        ]
117
118
        msg = '{} is not a valid {}'
119
        for (in_val, bad_val) in test_values:
120
            with self.subTest((in_val, bad_val)):  # pylint: disable=no-member
121
                with self.assertRaises(ValueError) as cm:
122
                    elem.pack(in_val)
123
                self.assertEqual(str(cm.exception), msg.format(bad_val, 'SimpleEnum'))
124
125
    def test_unpack(self):
126
        """Test unpacking valid enum values."""
127
128
        test_bitfield = BitField(SimpleEnum)
129
130
        field = ('a', 'b', test_bitfield)  # signed byte: -128, 127
131
        out = ElementBitField.valid(field)
132
        self.assertTrue(out)
133
        elem = ElementBitField(field)
134
        test_values = [
135
            (b'\x00', frozenset([])),
136
            (b'\xF8', frozenset([])),
137
            (b'\x01', frozenset([SimpleEnum.one])),
138
            (b'\x02', frozenset([SimpleEnum.two])),
139
            (b'\x03', frozenset([SimpleEnum.one, SimpleEnum.two])),
140
            (b'\xFF', frozenset([SimpleEnum.one, SimpleEnum.two, SimpleEnum.four])),
141
            (b'\xAA', frozenset([SimpleEnum.two])),
142
        ]
143
        for (in_val, out_val) in test_values:
144
            with self.subTest((in_val, out_val)):  # pylint: disable=no-member
145
                (ret, unused) = elem.unpack({}, in_val)
146
                self.assertEqual(unused, b'')
147
                self.assertEqual(ret, out_val)
148