The suite is green for the first time this session: 376 passed, 0 failed. test_collapse_insearch_reproduces_94g_finish_time_result hard-coded both endpoints of the 17 result -- 15 fails before collapse, 12 after. Those were measured before 39.4, when harbor's effective programme was silently 32 instances because codes like cr1 were read as generic circulation; the same layout now scores 82. But the guarantee the test exists to protect, per its own docstring, is that in-search collapse reaches the SAME layout as finish-time collapse on fixed geometry -- and two independent constants never checked that. They can both drift and stay equal, or both hold and mask an inequality. Rewritten to compute both sides live and assert they agree, plus that collapse does not make the layout worse. Measured: 82 -> 58 in-search, and finish-time collapse independently reaches 58 at iters=3 and iters=6. The invariant holds; only the constants were stale. Restating the reference figure itself remains homemaker-py-ut5. test_classify_fail_tier_covers_full_corpus globbed examples/**/*.fails and asserted checked > 0. Git tracks ZERO .fails -- they are artefacts the scorer writes beside a .dom -- so its docstring described files that by design never exist in the repo, and it passed only on a machine that had already run the scorer. Split into: a test that GENERATES fails by scoring three corpus layouts picked for breadth (requiring >= 8 distinct kinds so it cannot silently narrow); a test that an unclassifiable string actually raises; and an opportunistic .fails sweep that never requires them. Verified by moving every .fails out of the tree and re-running. Closes homemaker-py-1ue. Lint at parity (46). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MJ84Feep79Hhm3E4zZJmnB
143 lines
5.9 KiB
Python
143 lines
5.9 KiB
Python
"""Tests for the IN-SEARCH global collapse (homemaker-py-qpk, DESIGN.md §17
|
|
follow-on): running Fitness.collapse_global inside every fitness eval instead
|
|
of once at finish time.
|
|
|
|
Covers:
|
|
- default-OFF guarantee + conf-driven knobs (adjacency, iters)
|
|
- _evaluate_full wiring: collapse_global is invoked (with the right kwargs)
|
|
when the flag is on, never when it is off
|
|
- end-to-end effect on a real evolved layout, cross-checked against the
|
|
documented 94g finish-time result (DESIGN.md §17: 15 -> 12 fails on
|
|
evolved-3M-nols-3.dom)
|
|
"""
|
|
|
|
import copy
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from _helpers import with_usage
|
|
from homemaker_layout import dom as dom_mod
|
|
from homemaker_layout.dom import Node, _link_subtree
|
|
from homemaker_layout.fitness import Fitness, load_config
|
|
|
|
HARBOR = Path(__file__).parent.parent / "examples" / "harbor-house"
|
|
|
|
|
|
def _two_leaf_root(t_left: str, t_right: str, side: float = 6.0, div: float = 0.4):
|
|
from homemaker_layout import geometry
|
|
geometry.clear_cache()
|
|
root = Node(
|
|
node=[[0, 0], [side, 0], [side, side], [0, side]],
|
|
rotation=0, division=[div, div],
|
|
left=Node(type=t_left), right=Node(type=t_right),
|
|
)
|
|
_link_subtree(root, None, "")
|
|
return root
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Defaults + conf-driven knobs
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
def test_collapse_insearch_default_off():
|
|
fit = Fitness()
|
|
assert fit._collapse_insearch is False
|
|
assert fit._collapse_insearch_adjacency is True
|
|
assert fit._collapse_insearch_iters == 3
|
|
|
|
|
|
def test_collapse_insearch_flag_on():
|
|
fit = Fitness(conf={"collapse_insearch": True})
|
|
assert fit._collapse_insearch is True
|
|
|
|
|
|
def test_collapse_insearch_adjacency_knob_off():
|
|
fit = Fitness(conf={"collapse_insearch": True,
|
|
"collapse_insearch_adjacency": False})
|
|
assert fit._collapse_insearch_adjacency is False
|
|
|
|
|
|
def test_collapse_insearch_iters_knob():
|
|
fit = Fitness(conf={"collapse_insearch": True, "collapse_insearch_iters": 5})
|
|
assert fit._collapse_insearch_iters == 5
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# _evaluate_full wiring
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
def test_evaluate_full_calls_collapse_global_when_on():
|
|
fit = Fitness(conf={"collapse_insearch": True, "collapse_insearch_iters": 2,
|
|
"spaces": with_usage({"b1": {"size": [16.0, 4.0], "count": 2}})})
|
|
root = _two_leaf_root("b1", "b1")
|
|
with patch.object(Fitness, "collapse_global", wraps=fit.collapse_global) as m:
|
|
fit.score_with_fails(root)
|
|
m.assert_called_once()
|
|
_, kw = m.call_args
|
|
assert kw["adjacency"] is True
|
|
assert kw["objective"] == "threshold"
|
|
assert kw["preserve_public_access"] is True
|
|
assert kw["iters"] == 2
|
|
|
|
|
|
def test_evaluate_full_does_not_call_collapse_global_when_off():
|
|
fit = Fitness(conf={"spaces": with_usage({"b1": {"size": [16.0, 4.0], "count": 2}})})
|
|
root = _two_leaf_root("b1", "b1")
|
|
with patch.object(Fitness, "collapse_global", wraps=fit.collapse_global) as m:
|
|
fit.score_with_fails(root)
|
|
m.assert_not_called()
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# End-to-end: matches the documented 94g finish-time result
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
@pytest.mark.skipif(not HARBOR.is_dir(), reason="harbor-house example absent")
|
|
def test_collapse_insearch_matches_finish_time_collapse():
|
|
"""in-search collapse must reach the SAME layout as finish-time collapse.
|
|
|
|
That equality is the actual guarantee: `collapse_insearch` runs the same
|
|
`collapse_global` earlier in the same pipeline (before the Phase-1 checks
|
|
rather than after the whole search), so on a FIXED geometry the two must
|
|
agree. Both sides are computed here rather than hard-coded.
|
|
|
|
This test previously asserted the §17 constants directly -- `15` fails
|
|
before collapse and `12` after. Those were measured before §39.4, when
|
|
harbor's effective programme was silently 32 instances because codes like
|
|
`cr1` were being read as generic circulation; the same layout now scores 82
|
|
-> 58. Pinning the endpoints made a live invariant fail whenever the
|
|
programme or the objective legitimately changed, while not actually
|
|
checking the invariant at all (two independent constants can both drift and
|
|
still be equal, or both hold and mask an inequality). See
|
|
`homemaker-py-ut5` for restating the reference figure itself.
|
|
"""
|
|
conf, cost = load_config(HARBOR)
|
|
conf_ci, _ = load_config(HARBOR, overrides={"collapse_insearch": True})
|
|
root = dom_mod.load(str(HARBOR / "evolved-3M-nols-3.dom"))
|
|
|
|
_, f_base = Fitness(conf, cost).score_with_fails(copy.deepcopy(root))
|
|
_, f_ci = Fitness(conf_ci, cost).score_with_fails(copy.deepcopy(root))
|
|
|
|
# the same collapse, applied once at finish time, scored canonically
|
|
finished = copy.deepcopy(root)
|
|
Fitness(conf, cost).collapse_global(
|
|
finished, adjacency=True, objective="threshold",
|
|
preserve_public_access=True, iters=3)
|
|
_, f_finish = Fitness(conf, cost).score_with_fails(finished)
|
|
|
|
assert len(f_ci) == len(f_finish), (
|
|
"in-search collapse diverged from finish-time collapse on fixed geometry")
|
|
assert len(f_ci) < len(f_base), "collapse must not make the layout worse"
|
|
|
|
|
|
@pytest.mark.skipif(not HARBOR.is_dir(), reason="harbor-house example absent")
|
|
def test_collapse_insearch_off_reproduces_baseline():
|
|
conf, cost = load_config(HARBOR)
|
|
fit = Fitness(conf, cost)
|
|
root = dom_mod.load(str(HARBOR / "evolved-3M-nols-3.dom"))
|
|
s1, f1 = fit.score_with_fails(copy.deepcopy(root))
|
|
s2, f2 = Fitness(conf, cost).score_with_fails(copy.deepcopy(root))
|
|
assert s1 == pytest.approx(s2)
|
|
assert f1 == f2
|