Files
2026-08-28 01:01:12 +02:00

140 lines
4.5 KiB
Python

import json
from types import SimpleNamespace
import pytest
import torch
from h3_guidemaster.core import compiler as compiler_module
from h3_guidemaster.core.compat import assert_native_h3_support
class FakeNested:
def __init__(self, tensors):
self.is_nested = True
self.tensors = tuple(tensors)
def unbind(self):
return self.tensors
def h3_latent():
return {
"samples": FakeNested((
torch.zeros((1, 24, 7, 48, 84)),
torch.zeros((1, 32, 2, 37)),
)),
"keep_me": 123,
}
def setter(conditioning, values):
out = []
for embedding, metadata in conditioning:
merged = dict(metadata)
merged.update(values)
out.append([embedding, merged])
return out
def test_compiler_preserves_existing_keyframes_and_latent_metadata(monkeypatch):
monkeypatch.setattr(
compiler_module,
"compile_keyframes",
lambda *args, **kwargs: [{"resolved_frame_index": 10, "latent": "new"}],
)
positive = [["embed", {"minimax_keyframes": [{"resolved_frame_index": 0, "latent": "old"}]}]]
latent = h3_latent()
out_positive, out_latent = compiler_module.compile_guidemaster(
positive,
latent,
json.dumps({"version": 1, "fps": 24}),
conditioning_setter=setter,
)
assert [k["resolved_frame_index"] for k in out_positive[0][1]["minimax_keyframes"]] == [0, 10]
assert out_latent["samples"] is latent["samples"]
assert out_latent["keep_me"] == 123
def test_compiler_leaves_the_latent_untouched(monkeypatch):
monkeypatch.setattr(compiler_module, "compile_keyframes", lambda *a, **k: [])
latent = h3_latent()
latent["noise_mask"] = "existing"
out_positive, out_latent = compiler_module.compile_guidemaster(
[["embed", {}]], latent, "", conditioning_setter=setter
)
assert out_latent["noise_mask"] == "existing"
assert out_latent is not latent
assert "minimax_keyframes" not in out_positive[0][1]
def test_compiler_rejects_empty_conditioning():
with pytest.raises(ValueError, match="conditioning"):
compiler_module.compile_guidemaster([], h3_latent(), "", conditioning_setter=setter)
def test_compiler_rejects_malformed_conditioning_entry(monkeypatch):
monkeypatch.setattr(
compiler_module, "compile_keyframes", lambda *a, **k: [{"resolved_frame_index": 0}]
)
with pytest.raises(ValueError, match="standard CONDITIONING"):
compiler_module.compile_guidemaster(
[torch.zeros((1, 4))], h3_latent(), "", conditioning_setter=setter
)
def test_compat_accepts_required_native_h3_features():
assert_native_h3_support(
h3_nodes=SimpleNamespace(MiniMaxH3AddGuide=object()),
h3_model=SimpleNamespace(FRAME_PER_TOKEN=(1, 4, 4, 4, 4), FRAME_RESCALE=5 / 3),
)
def test_compat_names_missing_upstream_prs():
common = dict(
h3_model=SimpleNamespace(FRAME_PER_TOKEN=(1, 4, 4, 4, 4), FRAME_RESCALE=5 / 3),
)
with pytest.raises(RuntimeError, match="#15439"):
assert_native_h3_support(h3_nodes=SimpleNamespace(), **common)
def test_compiler_does_not_emit_guide_intent_metadata(monkeypatch):
monkeypatch.setattr(
compiler_module,
"compile_keyframes",
lambda *args, **kwargs: [{"resolved_frame_index": 10, "latent": "guide-latent"}],
)
timeline = json.dumps({
"version": 1, "fps": 24,
"reference": {"selected_frame": 10},
"guides": [{
"id": "g1", "enabled": True, "frame": 10, "image_slot": 0,
"intent": "legacy text that must be ignored",
}],
})
out_positive, _ = compiler_module.compile_guidemaster(
[["embed", {}]], h3_latent(), timeline,
guide_images={"guide_image_0": object()}, conditioning_setter=setter
)
metadata = out_positive[0][1]
assert "majoor_guide_intents" not in metadata
assert set(metadata["minimax_keyframes"][-1]) == {"resolved_frame_index", "latent"}
def test_compiler_passes_first_and_last_frames_to_keyframe_compiler(monkeypatch):
captured = {}
def fake_compile(*args, **kwargs):
captured.update(kwargs)
return []
monkeypatch.setattr(compiler_module, "compile_keyframes", fake_compile)
first = object()
last = object()
compiler_module.compile_guidemaster(
[["embed", {}]], h3_latent(), json.dumps({"version": 2, "fps": 24}),
first_frame=first, last_frame=last, conditioning_setter=setter,
)
assert captured["first_frame"] is first
assert captured["last_frame"] is last