feat(player): alteration engine — knob vector to RenderPlan (design §4/§5)
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import pytest
|
||||
|
||||
from hef.selection import Coordinate
|
||||
from player.alteration import (
|
||||
AnalyticalOverlay,
|
||||
ColorGrade,
|
||||
RenderPlan,
|
||||
Restyle,
|
||||
plan_alteration,
|
||||
)
|
||||
|
||||
|
||||
def _coord(left=0, right=0, dark=0, light=0):
|
||||
return Coordinate(left=left, right=right, dark=dark, light=light)
|
||||
|
||||
|
||||
def test_all_zero_knobs_is_the_unaltered_base():
|
||||
plan = plan_alteration(_coord())
|
||||
assert plan.is_identity
|
||||
assert plan.overlay.intensity == 0.0
|
||||
assert plan.restyle.blend == 0.0
|
||||
assert plan.grade.tone == 0.0
|
||||
assert plan.grade.is_identity
|
||||
|
||||
|
||||
def test_left_drives_the_analytical_overlay_only():
|
||||
plan = plan_alteration(_coord(left=4))
|
||||
assert plan.overlay.intensity == 1.0
|
||||
assert plan.restyle.blend == 0.0 # Left does not touch the substrate
|
||||
assert plan.grade.tone == 0.0
|
||||
|
||||
|
||||
def test_right_drives_the_restyle_substrate_only():
|
||||
plan = plan_alteration(_coord(right=2))
|
||||
assert plan.restyle.blend == 0.5
|
||||
assert plan.overlay.intensity == 0.0 # Right does not add overlay
|
||||
|
||||
|
||||
def test_left_and_right_stack_not_cancel():
|
||||
# design §4.2: whole-brain corner = dreamlike substrate WITH labels on top
|
||||
plan = plan_alteration(_coord(left=4, right=4))
|
||||
assert plan.overlay.intensity == 1.0
|
||||
assert plan.restyle.blend == 1.0
|
||||
|
||||
|
||||
def test_light_pole_grades_warm_positive_tone():
|
||||
plan = plan_alteration(_coord(light=4))
|
||||
assert plan.grade.tone == 1.0
|
||||
assert not plan.grade.is_identity
|
||||
|
||||
|
||||
def test_dark_pole_grades_cool_negative_tone():
|
||||
plan = plan_alteration(_coord(dark=4))
|
||||
assert plan.grade.tone == -1.0
|
||||
|
||||
|
||||
def test_equal_dark_and_light_is_identity_grade():
|
||||
# design §5: the mood center is the raw, ungraded footage
|
||||
assert plan_alteration(_coord(dark=3, light=3)).grade.is_identity
|
||||
assert plan_alteration(_coord(dark=2, light=2)).grade.is_identity
|
||||
|
||||
|
||||
def test_dark_minus_light_sets_intermediate_tone():
|
||||
assert plan_alteration(_coord(dark=4, light=2)).grade.tone == pytest.approx(-0.5)
|
||||
assert plan_alteration(_coord(dark=1, light=3)).grade.tone == pytest.approx(0.5)
|
||||
|
||||
|
||||
def test_whole_brain_dark_corner_stacks_grade_substrate_and_overlay():
|
||||
# design §4.2 "Dark + analytical": cold measurement over a melancholy scene
|
||||
plan = plan_alteration(_coord(left=4, right=2, dark=4, light=0))
|
||||
assert plan.overlay.intensity == 1.0
|
||||
assert plan.restyle.blend == 0.5
|
||||
assert plan.grade.tone == -1.0
|
||||
assert not plan.is_identity
|
||||
|
||||
|
||||
def test_render_plan_is_frozen():
|
||||
plan = plan_alteration(_coord())
|
||||
with pytest.raises(Exception):
|
||||
plan.grade.tone = 0.5 # type: ignore[misc]
|
||||
Reference in New Issue
Block a user