Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 111 additions & 1 deletion src/tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
from __future__ import annotations

import io
import struct
from pathlib import Path
from typing import TYPE_CHECKING

import pytest

from mss.tools import to_png
from mss.tools import parse_edid, to_png

if TYPE_CHECKING:
from collections.abc import Callable
Expand Down Expand Up @@ -57,3 +58,112 @@ def test_output_raw_bytes() -> None:
raw = to_png(data, (WIDTH, HEIGHT))
assert isinstance(raw, bytes)
assert_is_valid_png(raw=raw)


# ---------------------------------------------------------------------------
# Helpers and tests for parse_edid
# ---------------------------------------------------------------------------


def _make_edid(
*,
manufacturer: str = "TST",
product_code: int = 0x1234,
serial_number: int = 0,
manufacture_week: int = 0,
manufacture_year: int = 30,
descriptors: list[tuple[int, int, str]] | None = None,
bad_checksum: bool = False,
) -> bytes:
"""Build a minimal 128-byte EDID block."""
data = bytearray(128)
data[0:8] = b"\x00\xff\xff\xff\xff\xff\xff\x00"
packed = ((ord(manufacturer[0]) - ord("@")) << 10) | ((ord(manufacturer[1]) - ord("@")) << 5) | (ord(manufacturer[2]) - ord("@"))
data[8] = (packed >> 8) & 0xFF
data[9] = packed & 0xFF
struct.pack_into("<H", data, 10, product_code)
struct.pack_into("<I", data, 12, serial_number)
data[16] = manufacture_week
data[17] = manufacture_year
data[18] = 1 # EDID version
data[19] = 4 # EDID revision
_text_len = 13 # descriptor text field is 13 bytes (slice(5, 18))
if descriptors:
for offset, tag, text in descriptors:
# bytes at relative offsets 0,1,2,4 must be 0 (already 0 from init)
data[offset + 3] = tag
encoded = text.encode("ascii")
if len(encoded) < _text_len:
encoded = encoded + b"\n" + b" " * (_text_len - len(encoded) - 1)
data[offset + 5 : offset + 18] = encoded[:_text_len]
checksum = (-sum(data[:127])) % 256
data[127] = (checksum + 1) % 256 if bad_checksum else checksum
return bytes(data)


def test_parse_edid_too_short() -> None:
assert parse_edid(b"") == {}
assert parse_edid(b"\x00" * 64) == {}
assert parse_edid(b"\x00" * 127) == {}


def test_parse_edid_invalid_checksum() -> None:
assert parse_edid(_make_edid(bad_checksum=True)) == {}


def test_parse_edid_invalid_header() -> None:
data = bytearray(_make_edid())
data[0] = 0x01 # corrupt the header magic
data[127] = (-sum(data[:127])) % 256 # recompute checksum
assert parse_edid(bytes(data)) == {}


def test_parse_edid_basic() -> None:
result = parse_edid(_make_edid(manufacturer="TST", product_code=0x1234))
assert result["id_legacy"] == "TST1234"


def test_parse_edid_manufacture_year_only() -> None:
result = parse_edid(_make_edid(manufacture_week=0, manufacture_year=30))
assert result["manufacture_year"] == 2020
assert "manufacture_week" not in result
assert "model_year" not in result


def test_parse_edid_manufacture_week_and_year() -> None:
result = parse_edid(_make_edid(manufacture_week=10, manufacture_year=30))
assert result["manufacture_year"] == 2020
assert result["manufacture_week"] == 10
assert "model_year" not in result


def test_parse_edid_model_year() -> None:
result = parse_edid(_make_edid(manufacture_week=0xFF, manufacture_year=31))
assert result["model_year"] == 2021
assert "manufacture_year" not in result
assert "manufacture_week" not in result


def test_parse_edid_serial_number_integer() -> None:
result = parse_edid(_make_edid(serial_number=12345))
assert result["serial_number"] == 12345


def test_parse_edid_serial_number_not_set() -> None:
result = parse_edid(_make_edid(serial_number=0))
assert "serial_number" not in result


def test_parse_edid_descriptor_serial_number() -> None:
result = parse_edid(_make_edid(descriptors=[(0x48, 0xFF, "SN123456")]))
assert result["serial_number"] == "SN123456"


def test_parse_edid_descriptor_display_name() -> None:
result = parse_edid(_make_edid(descriptors=[(0x5A, 0xFC, "Test Monitor")]))
assert result["display_name"] == "Test Monitor"


def test_parse_edid_descriptor_string_serial_overrides_integer() -> None:
result = parse_edid(_make_edid(serial_number=99, descriptors=[(0x48, 0xFF, "STRSERIAL")]))
assert result["serial_number"] == "STRSERIAL"
Loading