mirror of
https://github.com/feder-cr/invisible_playwright.git
synced 2026-07-22 11:51:11 +02:00
tests: drop font-sampling tests
Follows the invisible_core removal of the dead per-profile font-sampling: delete the derive_font_prefs/derive_font_whitelist tests, the 'fonts' pin tests, and the profile font_whitelist assertions. Suite green (444 passed).
This commit is contained in:
parent
47a1044733
commit
a1b75d93e9
3 changed files with 4 additions and 191 deletions
|
|
@ -51,22 +51,11 @@ def test_pin_key_without_dot_raises():
|
|||
generate_profile(seed=42, pin={"madeup": 1})
|
||||
|
||||
|
||||
def test_pin_top_level_fonts_accepted():
|
||||
p = generate_profile(seed=42, pin={"fonts": ["Arial", "Verdana", "Tahoma"]})
|
||||
assert "Arial" in p.fonts
|
||||
assert "Verdana" in p.fonts
|
||||
|
||||
|
||||
def test_pin_top_level_dark_theme_accepted():
|
||||
p = generate_profile(seed=42, pin={"dark_theme": True})
|
||||
assert p.dark_theme is True
|
||||
|
||||
|
||||
def test_pin_fonts_wrong_type_raises():
|
||||
with pytest.raises(TypeError, match="list/tuple"):
|
||||
generate_profile(seed=42, pin={"fonts": "Arial,Verdana"})
|
||||
|
||||
|
||||
def test_pin_overrides_seed_value():
|
||||
"""The same seed produces different output once a pin is applied."""
|
||||
natural = generate_profile(seed=42)
|
||||
|
|
|
|||
|
|
@ -21,12 +21,6 @@ from invisible_playwright._fpforge.profile import (
|
|||
# _validate_pin_key
|
||||
# ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_validate_pin_key_top_level_fonts():
|
||||
"""VK1 — `fonts` is a known top-level key."""
|
||||
_validate_pin_key("fonts")
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_validate_pin_key_top_level_dark_theme():
|
||||
"""VK2 — `dark_theme` is a known top-level key."""
|
||||
|
|
@ -98,7 +92,6 @@ def _raw_baseline():
|
|||
"screen_h": 1080,
|
||||
"webgl_vendor": "Google Inc. (Intel)",
|
||||
"webgl_renderer": "ANGLE (Intel)",
|
||||
"font_whitelist": "arial,calibri",
|
||||
"dark_theme": 0,
|
||||
}
|
||||
|
||||
|
|
@ -110,34 +103,6 @@ def test_apply_pins_to_raw_screen_width():
|
|||
assert out["screen_w"] == 2560
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_apply_pins_to_raw_fonts_list():
|
||||
"""AP2 — list pin joined into comma-separated whitelist."""
|
||||
out = _apply_pins_to_raw(_raw_baseline(), {"fonts": ["Arial", "Verdana"]})
|
||||
assert out["font_whitelist"] == "Arial,Verdana"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_apply_pins_to_raw_fonts_tuple():
|
||||
"""AP3 — tuple pin is also accepted."""
|
||||
out = _apply_pins_to_raw(_raw_baseline(), {"fonts": ("Arial",)})
|
||||
assert out["font_whitelist"] == "Arial"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_apply_pins_to_raw_fonts_string_raises():
|
||||
"""AP4 — bare string is not a list/tuple, must raise."""
|
||||
with pytest.raises(TypeError, match="list/tuple"):
|
||||
_apply_pins_to_raw(_raw_baseline(), {"fonts": "Arial"})
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_apply_pins_to_raw_fonts_int_raises():
|
||||
"""AP5 — int is also rejected."""
|
||||
with pytest.raises(TypeError):
|
||||
_apply_pins_to_raw(_raw_baseline(), {"fonts": 42})
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_apply_pins_to_raw_multiple_pins():
|
||||
"""AP6 — multiple pins all land in raw."""
|
||||
|
|
@ -158,7 +123,7 @@ def test_apply_pins_to_raw_returns_copy_not_mutation():
|
|||
|
||||
@pytest.mark.unit
|
||||
def test_apply_pins_to_raw_unknown_key_silent():
|
||||
"""AP8 — key not in `_PIN_TO_RAW` (and not 'fonts') is ignored.
|
||||
"""AP8 — key not in `_PIN_TO_RAW` is ignored.
|
||||
|
||||
Validation happens upstream in `generate_profile`; the inner helper
|
||||
guards defensively but does not raise.
|
||||
|
|
@ -260,15 +225,6 @@ def test_generate_profile_is_frozen():
|
|||
p.seed = 99 # type: ignore[misc]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_generate_profile_fonts_is_list_of_strings():
|
||||
"""GP11 — fonts is a non-empty list of stripped strings."""
|
||||
p = generate_profile(seed=42)
|
||||
assert isinstance(p.fonts, list)
|
||||
assert len(p.fonts) > 0
|
||||
assert all(isinstance(f, str) and f.strip() == f for f in p.fonts)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_generate_profile_to_prefs_dict_flat_and_matches_raw():
|
||||
"""GP12 — to_prefs_dict() returns a flat dict containing core sampler keys."""
|
||||
|
|
@ -319,13 +275,6 @@ def test_generate_profile_pin_dark_theme_false():
|
|||
assert p.dark_theme is False
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_generate_profile_pin_fonts_list_visible_on_profile():
|
||||
"""fonts pin: list → joined raw string → split back to list on Profile."""
|
||||
p = generate_profile(seed=42, pin={"fonts": ["Arial", "Verdana"]})
|
||||
assert p.fonts == ["Arial", "Verdana"]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_generate_profile_pin_gpu_renderer_propagates():
|
||||
p = generate_profile(seed=42, pin={"gpu.renderer": "FORCED_RENDERER"})
|
||||
|
|
@ -335,14 +284,13 @@ def test_generate_profile_pin_gpu_renderer_propagates():
|
|||
|
||||
@pytest.mark.unit
|
||||
def test_generate_profile_pin_to_raw_keymap_complete():
|
||||
"""Every dotted pin key (besides 'fonts') has a `_PIN_TO_RAW` mapping.
|
||||
"""Every dotted pin key has a `_PIN_TO_RAW` mapping.
|
||||
|
||||
Guards against silently-ignored pins if someone adds a key to `_PIN_GROUPS`
|
||||
but forgets the raw-key mapping.
|
||||
"""
|
||||
dotted = {f"{group}.{field}" for group, fields in _PIN_GROUPS.items()
|
||||
for field in fields}
|
||||
# 'dark_theme' is top-level and present in _PIN_TO_RAW; 'fonts' is handled
|
||||
# specially and intentionally absent.
|
||||
# 'dark_theme' is top-level and present in _PIN_TO_RAW.
|
||||
missing = dotted - set(_PIN_TO_RAW.keys())
|
||||
assert missing == set(), f"pin keys without raw mapping: {sorted(missing)}"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
"""Unit tests for invisible_playwright._fpforge._sampler.
|
||||
|
||||
Covers classify_gpu (decision-table over GPU strings), _screen_tier,
|
||||
derive_font_prefs / derive_font_whitelist, and the public Forge / sample
|
||||
entry points.
|
||||
and the public Forge / sample entry points.
|
||||
"""
|
||||
import random
|
||||
|
||||
import pytest
|
||||
|
||||
from invisible_playwright._fpforge import _sampler
|
||||
|
|
@ -14,8 +11,6 @@ from invisible_playwright._fpforge._sampler import (
|
|||
_LOCKED,
|
||||
_screen_tier,
|
||||
classify_gpu,
|
||||
derive_font_prefs,
|
||||
derive_font_whitelist,
|
||||
sample,
|
||||
)
|
||||
|
||||
|
|
@ -213,116 +208,6 @@ def test_screen_tier_4200x2000_is_ultrawide_via_width_branch():
|
|||
assert _screen_tier({"screen": {"w": 4200, "h": 2000}}) == "ultrawide"
|
||||
|
||||
|
||||
# ── derive_font_prefs / derive_font_whitelist ───────────────────────────
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_derive_font_prefs_returns_whitelist_key():
|
||||
"""FP1 [HAPPY]: result is a single-key dict with the font family list.
|
||||
|
||||
The per-family ``metrics`` string was removed on 2026-06-20: fonts now
|
||||
render from the bundled real Windows files (genuine widths) and per-session
|
||||
metric uniqueness comes from the HarfBuzz jitter, not fabricated factors."""
|
||||
out = derive_font_prefs("integrated_modern", random.Random(42))
|
||||
assert set(out.keys()) == {"whitelist"}
|
||||
assert isinstance(out["whitelist"], str)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_derive_font_prefs_core_fonts_always_present():
|
||||
"""FP2 [ECP]: every core font name appears in whitelist regardless of class."""
|
||||
out = derive_font_prefs("integrated_old", random.Random(0))
|
||||
names = set(out["whitelist"].split(","))
|
||||
for entry in _sampler._FONT_CORE:
|
||||
assert entry["name"] in names
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_derive_font_prefs_deterministic_per_seed():
|
||||
"""FP3 [ECP]: same gpu_class + same rng seed → identical result."""
|
||||
a = derive_font_prefs("workstation", random.Random(7))
|
||||
b = derive_font_prefs("workstation", random.Random(7))
|
||||
assert a == b
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_derive_font_prefs_unknown_class_falls_back_to_integrated_modern():
|
||||
"""FP4 [ECP]: gpu_class missing from CPT → uses integrated_modern row."""
|
||||
fallback = derive_font_prefs("nonexistent", random.Random(123))
|
||||
expected = derive_font_prefs("integrated_modern", random.Random(123))
|
||||
assert fallback == expected
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_derive_font_prefs_whitelist_alphabetically_sorted():
|
||||
"""FP6 [ECP]: whitelist names are sorted (ordering invariant for stable dedup)."""
|
||||
out = derive_font_prefs("high_end", random.Random(5))
|
||||
names = out["whitelist"].split(",")
|
||||
assert names == sorted(names)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_derive_font_whitelist_legacy_shim_matches_dict_form():
|
||||
"""FW1 [HAPPY]: legacy shim returns same string as dict['whitelist']."""
|
||||
rng_a = random.Random(11)
|
||||
rng_b = random.Random(11)
|
||||
assert derive_font_whitelist("low_end", rng_a) == \
|
||||
derive_font_prefs("low_end", rng_b)["whitelist"]
|
||||
|
||||
|
||||
# Standard fonts that ship with every Windows 10/11 install. They MUST be in the
|
||||
# core (always-present) set, never in the optional/per-profile set: a real Windows
|
||||
# machine never lacks them, so a session that drops one advertises a font set that
|
||||
# doesn't match any real Windows profile (image-dedup font probes then report a
|
||||
# short/degenerate name list → server-side OS-font-set checks fail). Calibri in
|
||||
# particular sat in `optional` (a bug); these caused the detected set to come up
|
||||
# short on some seeds. Regression guard for the 2026-06-18 optional→core move.
|
||||
# NB: the exact Win11 family is "franklin gothic medium" (there is no bare
|
||||
# "franklin gothic" family); the 2026-06-20 bundle reconciliation uses real names.
|
||||
_STANDARD_WINDOWS_FONTS = [
|
||||
"calibri", "franklin gothic medium", "gadugi", "javanese text", "myanmar text",
|
||||
]
|
||||
_ALL_GPU_CLASSES = [
|
||||
"integrated_old", "integrated_modern", "mid_range", "high_end",
|
||||
"low_end", "workstation",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.parametrize("gpu_class", _ALL_GPU_CLASSES)
|
||||
def test_standard_windows_fonts_always_present_every_class_and_seed(gpu_class):
|
||||
"""FP7 [regression]: the standard-Windows fonts appear in the whitelist for
|
||||
every gpu_class across many seeds (i.e. they are core, not profile-optional).
|
||||
Guards against a standard font silently becoming optional."""
|
||||
for seed in range(40):
|
||||
out = derive_font_prefs(gpu_class, random.Random(seed))
|
||||
wl = set(out["whitelist"].split(","))
|
||||
for font in _STANDARD_WINDOWS_FONTS:
|
||||
assert font in wl, f"{font!r} missing from whitelist (class={gpu_class}, seed={seed})"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_standard_windows_fonts_are_in_core_pool():
|
||||
"""FP8 [regression]: the standard-Windows fonts live in the CORE pool (not
|
||||
optional) — the structural source of the always-present guarantee above."""
|
||||
core_names = {e["name"] for e in _sampler._FONT_CORE}
|
||||
optional_names = {e["name"] for e in _sampler._FONT_OPTIONAL}
|
||||
for font in _STANDARD_WINDOWS_FONTS:
|
||||
assert font in core_names, f"{font!r} must be in core pool"
|
||||
assert font not in optional_names, f"{font!r} must NOT be in optional pool"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.parametrize("gpu_class", _ALL_GPU_CLASSES)
|
||||
def test_derive_font_prefs_no_duplicate_families(gpu_class):
|
||||
"""FP9 [regression]: no family appears twice in the whitelist, even when a
|
||||
profile's optional list also names a core font. Guards the dedup in
|
||||
derive_font_prefs (a duplicate family would emit a malformed list)."""
|
||||
for seed in range(30):
|
||||
out = derive_font_prefs(gpu_class, random.Random(seed))
|
||||
wl = out["whitelist"].split(",")
|
||||
assert len(wl) == len(set(wl)), f"duplicate in whitelist (class={gpu_class}, seed={seed})"
|
||||
|
||||
|
||||
# ── Forge / sample ──────────────────────────────────────────────────────
|
||||
|
||||
# Keys the Forge.sample bundle must always contain. Builds on _LOCKED +
|
||||
|
|
@ -338,7 +223,6 @@ _EXPECTED_KEYS = {
|
|||
"av1_enabled", "webm_encoder_enabled",
|
||||
"mediasource_webm", "mediasource_mp4", "webspeech_synth",
|
||||
"storage_quota_mb", "dark_theme",
|
||||
"font_whitelist",
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -425,14 +309,6 @@ def test_forge_sample_avail_h_defaults_to_h_minus_40_when_missing(monkeypatch):
|
|||
assert out["screen_avail_h"] == 1080 - 40
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_forge_sample_includes_font_keys():
|
||||
"""FS9 [ECP]: font_whitelist present and non-empty (the joined family list)."""
|
||||
out = sample(42)
|
||||
assert out["font_whitelist"]
|
||||
assert "," in out["font_whitelist"] # at least the core fonts joined
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_forge_seed_coercion_to_int():
|
||||
"""FS extra: Forge(seed) coerces seed to int (e.g. float 42.7 → 42)."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue