def test_should_return_byte_value_when_calling_raw_property( self, size, format_): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) assert struct.pack(f'!{format_}', field.value) == field.raw()
def test_should_return_field_part_value_when_giving_correct_name( self, size, format_): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) assert 4 == field.get_field_part_value('version')
def test_should_raise_error_when_tuple_is_empty(self): field = BitsField( parts=[FieldPart('version', 4, 4), FieldPart('IHL', 5, 4)], format='B') with pytest.raises(ValueError) as exc_info: field.value = () assert 'value must not be an empty tuple' == str(exc_info.value)
def test_should_raise_error_when_all_items_in_tuple_are_not_integers(self): field = BitsField( parts=[FieldPart('version', 4, 4), FieldPart('IHL', 5, 4)], format='B') with pytest.raises(ValueError) as exc_info: field.value = (2, 3.4) assert 'all items in tuple must be integers' == str(exc_info.value)
def test_should_set_field_part_value_when_giving_correct_name_and_value( self, size, format_): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) field.set_field_part_value('version', 6) assert (6, 5) == field.value_as_tuple
def test_should_call_randint_function_with_correct_values( self, mocker, size, format_, right_value): randint_mock = mocker.patch('random.randint', return_value=2) field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) assert 2 == field.random_value() randint_mock.assert_called_once_with(0, right_value)
def test_should_return_empty_byte_when_not_enough_data_to_compute( self, size, format_): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) remaining_bytes = field.compute_value(b'bbb') assert remaining_bytes == b'' assert field.value_was_computed is False
def test_should_raise_error_when_value_is_not_integer_or_tuple( self, value): field = BitsField( parts=[FieldPart('version', 4, 4), FieldPart('IHL', 5, 4)], format='B') with pytest.raises(TypeError) as exc_info: field.value = value assert 'value must be an integer or a tuple of integers' == str( exc_info.value)
def test_should_raise_error_when_tuple_length_is_different_field_parts_length( self): field = BitsField( parts=[FieldPart('version', 4, 4), FieldPart('IHL', 5, 4)], format='B') with pytest.raises(ValueError) as exc_info: field.value = (2, 3, 4) assert 'tuple length is different from field parts length' == str( exc_info.value)
def test_should_raise_error_when_int_value_is_not_in_valid_boundaries( self, size, format_, value_1, value_2): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) for value in [value_1, value_2]: with pytest.raises(ValueError) as exc_info: field.value = value assert f'integer value must be between 0 and {value_2 - 1}' == str( exc_info.value)
def test_should_raise_error_when_items_dont_have_a_correct_value( self, size, format_, value_1, value_2): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) for value in [value_1, value_2]: with pytest.raises(ValueError) as exc_info: field.value = (value, 4) message = f'item version must be between 0 and {2 ** size - 1} according to the field part size' assert message == str(exc_info.value)
def test_should_raise_error_if_name_is_not_present_in_field_parts_when_setting_value( self, size, format_): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) name = 'hello' with pytest.raises(KeyError) as exc_info: field.set_field_part_value(name, 6) assert f"'no field part was found with name {name}'" == str( exc_info.value)
def test_should_return_a_copy_of_the_object_when_calling_clone_method( self): field = BitsField( parts=[FieldPart('version', 4, 4), FieldPart('IHL', 5, 4)], format='B') cloned_field = field.clone() assert cloned_field == field assert cloned_field is not field # check the parts attribute of cloned field is not a shallow copy for i, part in enumerate(cloned_field.parts): assert part is not field.parts[i]
def test_should_not_raise_error_when_setting_a_correct_tuple_value( self, size, format_): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) value = (5, 6) try: field.value = value except ValueError: pytest.fail(f'unexpected error when setting value with {value}') assert value == field.value_as_tuple
def test_should_compute_internal_field_part_value_when_calling_compute_value_method( self, size, format_): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) assert field.value_was_computed is False value = (8, 11) data = struct.pack(f'!{format_}5s', self.get_int_from_tuple(size, value), b'hello') remaining_data = field.compute_value(data) assert remaining_data == b'hello' assert field.value_as_tuple == (8, 11) assert field.value_was_computed is True
def test_should_return_correct_value_when_calling_value_as_tuple_property( self): field = BitsField( parts=[FieldPart('version', 4, 4), FieldPart('IHL', 5, 4)], format='B') assert (4, 5) == field.value_as_tuple
def test_should_return_field_part_given_its_name(self, size, format_): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) field_part = field['IHL'] assert field_part.name == 'IHL'
def test_should_correctly_instantiate_bits_field(self): field_parts = [FieldPart('version', 4, 4), FieldPart('IHL', 5, 4)] field = BitsField(parts=field_parts, format='B') assert field_parts == field.parts assert 1 == field.size assert '!B' == field.struct_format assert self.get_int_from_tuple(4, (4, 5)) == field.default assert not field.hex
def test_should_correctly_represent_bits_field(self, value_1, value_2, hexadecimal): field_parts = [FieldPart('version', 4, 4), FieldPart('IHL', 5, 4)] field = BitsField(parts=field_parts, format='B', hex=hexadecimal) assert ( f'BitsField(FieldPart(name=version, default={value_1}, value={value_1}),' f' FieldPart(name=IHL, default={value_2}, value={value_2}))' ) == repr(field)
def test_should_raise_error_when_trying_to_access_field_part_giving_a_wrong_name( self, size, format_): field = BitsField( parts=[FieldPart('version', 4, size), FieldPart('IHL', 5, size)], format=format_) with pytest.raises(KeyError) as exc_info: assert field['foo'] assert f"'no field part was found with name foo'" == str( exc_info.value)
def test_should_raise_error_when_parts_size_is_not_correct( self, size_1, size_2): with pytest.raises(ValueError) as exc_info: BitsField( parts=[ FieldPart('version', 4, size_1), FieldPart('IHL', 5, size_2) ], format='B' # 1 byte (8 bits) ) size = size_1 + size_2 assert (f'the sum in bits of the different FieldPart ({size})' f' is different from the field size (8)') == str( exc_info.value)
def test_should_raise_error_when_parts_is_not_correct(self, parts, error): with pytest.raises(error) as exc_info: BitsField(parts, 'B') if error is ValueError: assert 'parts must not be an empty list' == str(exc_info.value)
def test_should_raise_error_when_format_is_not_correct(self, value): with pytest.raises(ValueError): BitsField([FieldPart('part', 2, 3)], value)
def test_should_return_correct_value_when_calling_value_property(self): field = BitsField( parts=[FieldPart('version', 4, 4), FieldPart('IHL', 5, 4)], format='B') assert int('01000101', base=2) == field.value