Files
Artificial-Sweetener-Simple…/tests/test_regional_visual_benchmark_workflow.py
T

163 lines
5.5 KiB
Python

# SimpleSyrup - workflow-focused ComfyUI extensions for image generation
# Copyright (C) 2026 Artificial Sweetener and contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Verify P10.3 public workflow construction."""
import pytest
from tools.attention_coupling_benchmark.manifest import load_manifest
from tools.regional_visual_benchmark.matrix import (
RegionalStrategy,
SpatialProfile,
source_positions,
visual_positions,
)
from tools.regional_visual_benchmark.workflow import (
VisualBenchmarkWorkflowBuilder,
)
def test_source_workflow_uses_only_global_prompt_at_1024() -> None:
"""Keep shared refinement sources strategy-neutral and independently saved."""
manifest = load_manifest()
source = source_positions(manifest)[0]
built = VisualBenchmarkWorkflowBuilder().build_source(
manifest, source, run_id="run-1"
)
classes = [str(node["class_type"]) for node in built.prompt.values()]
assert classes.count("CLIPTextEncode") == 2
assert "SimpleSyrup.EncodePromptBatch" not in classes
assert "KSampler" in classes
latent = next(
node
for node in built.prompt.values()
if node["class_type"] == "EmptyCosmosLatentVideo"
)
assert latent["inputs"] == {
"width": 1024,
"height": 1024,
"length": 1,
"batch_size": 1,
}
positive = next(
node
for node in built.prompt.values()
if node["class_type"] == "CLIPTextEncode"
and "worst quality" not in str(node["inputs"])
)
positive_inputs = positive["inputs"]
assert isinstance(positive_inputs, dict)
case = next(value for value in manifest.cases if value.case_id == source.case_id)
assert positive_inputs["text"] == ", ".join(
(case.global_prompt, *case.regional_prompts)
)
def test_visual_workflows_route_all_strategy_profile_pairs() -> None:
"""Bind every pair to its exact public sampler and corrected settings."""
manifest = load_manifest()
case = manifest.cases[0]
selected = {
(position.strategy, position.spatial_profile): position
for position in visual_positions(manifest)
if position.case_id == case.case_id
and position.seed == manifest.sampling.seeds[0]
}
builder = VisualBenchmarkWorkflowBuilder()
for (strategy, profile), position in selected.items():
built = builder.build_visual(
manifest,
position,
run_id="run-1",
mask_names=("left.png", "right.png"),
source_name="source.png" if position.is_refinement else None,
)
sampler = next(
node
for node in built.prompt.values()
if str(node["class_type"]).startswith("SimpleSyrup.KSampler")
)
class_type = str(sampler["class_type"])
assert ("AttentionCoupling" in class_type) == (
strategy is RegionalStrategy.ATTENTION_COUPLING
)
assert ("Tiled" in class_type or "TiledRegion" in class_type) == (
profile
in {
SpatialProfile.TILED_MULTIDIFFUSION,
SpatialProfile.TILED_MIXTURE_OF_DIFFUSERS,
}
)
assert ("Contextual" in class_type) == profile.value.startswith("contextual_")
inputs = sampler["inputs"]
assert isinstance(inputs, dict)
assert inputs["steps"] == 30
assert inputs["cfg"] == 4.0
assert inputs["denoise"] == (0.3 if position.is_refinement else 1.0)
def test_refinement_workflow_loads_and_scales_exact_shared_source() -> None:
"""Use a named 1024 source only through the approved 1536 refinement path."""
manifest = load_manifest()
position = next(
position for position in visual_positions(manifest) if position.is_refinement
)
built = VisualBenchmarkWorkflowBuilder().build_visual(
manifest,
position,
run_id="run-1",
mask_names=("left.png", "right.png"),
source_name="source.png",
)
load = next(
node for node in built.prompt.values() if node["class_type"] == "LoadImage"
)
scale = next(
node for node in built.prompt.values() if node["class_type"] == "ImageScale"
)
assert load["inputs"] == {"image": "source.png"}
assert scale["inputs"] == {
"image": next(
[node_id, 0]
for node_id, node in built.prompt.items()
if node["class_type"] == "LoadImage"
),
"upscale_method": "lanczos",
"width": 1536,
"height": 1536,
"crop": "disabled",
}
def test_source_presence_must_match_spatial_profile() -> None:
"""Reject accidental from-noise spatial graphs and source-fed full graphs."""
manifest = load_manifest()
positions = visual_positions(manifest)
full = next(position for position in positions if not position.is_refinement)
refinement = next(position for position in positions if position.is_refinement)
builder = VisualBenchmarkWorkflowBuilder()
with pytest.raises(ValueError, match="source publication"):
builder.build_visual(
manifest,
full,
run_id="run-1",
mask_names=("left.png", "right.png"),
source_name="source.png",
)
with pytest.raises(ValueError, match="source publication"):
builder.build_visual(
manifest,
refinement,
run_id="run-1",
mask_names=("left.png", "right.png"),
source_name=None,
)