"""Unit tests for the INT8 / SERIAL8 codec — no server required. The byte vectors below were captured off the wire from both Informix 12.10.FC12W1DE and 15.0.1.0.3DE, which emit byte-identical encodings. INT8 is sign-magnitude across two 32-bit halves, stored high-half-last: bytes 0-1 sign word: 0 = NULL, 1 = positive, 0xFFFF = negative bytes 2-5 LOW 32 bits, big-endian unsigned bytes 6-9 HIGH 32 bits, big-endian unsigned The trap: +n and -n have *identical* magnitude bytes. Anything that treats this as a two's-complement integer is wrong for every negative value while looking correct for every positive one. """ from __future__ import annotations import pytest from informix_db._types import IfxType from informix_db.converters import FIXED_WIDTHS, _decode_int8 # (hex bytes, expected value) — captured from the wire. WIRE_VECTORS = [ ("0001be991a140000001c", 123456789012), ("ffffbe991a140000001c", -123456789012), ("00010000002a00000000", 42), ("ffff0000002a00000000", -42), ("00010000000000000000", 0), ("00000000000000000000", None), # sign word 0 -> NULL ("0001ffffffffffffffff", 2**64 - 1), # both halves saturated ("00010000000100000000", 1), ("00010000000000000001", 1 << 32), # high half only ] @pytest.mark.parametrize(("hexbytes", "expected"), WIRE_VECTORS) def test_decode_int8_wire_vectors(hexbytes: str, expected: int | None) -> None: assert _decode_int8(bytes.fromhex(hexbytes)) == expected def test_positive_and_negative_share_magnitude_bytes() -> None: """The whole reason a naive 8-byte read gets negatives wrong.""" pos = bytes.fromhex("0001be991a140000001c") neg = bytes.fromhex("ffffbe991a140000001c") assert pos[2:] == neg[2:], "magnitude bytes should be identical" assert _decode_int8(pos) == -_decode_int8(neg) def test_null_sign_word_beats_nonzero_magnitude() -> None: """Sign word 0 means NULL regardless of what the magnitude bytes hold.""" assert _decode_int8(bytes.fromhex("0000be991a140000001c")) is None def test_short_payload_raises() -> None: with pytest.raises(ValueError, match="too short"): _decode_int8(bytes.fromhex("0001be991a14")) # 6 bytes, need 10 def test_int8_registered_as_ten_bytes() -> None: """A width of 8 here would desync every row containing an INT8.""" assert FIXED_WIDTHS[IfxType.INT8] == 10 assert FIXED_WIDTHS[IfxType.SERIAL8] == 10 def test_int8_width_differs_from_bigint() -> None: """INT8 (17) and BIGINT (52) are different types with different widths — conflating them is the easy mistake.""" assert FIXED_WIDTHS[IfxType.INT8] != FIXED_WIDTHS[IfxType.BIGINT] assert FIXED_WIDTHS[IfxType.BIGINT] == 8