Files
ausboss-ComfyUI-AusBoss/tests/test_resolution.py
ausboss b160e8bcbc Latent Size: give Qwen Image 2.1 the size set on the node
Wired straight into a Qwen Image 2.1 sampler, the node's latent made a
picture twice as wide and tall as the size shown (1024 x 768 came out
2048 x 1536). The latent now carries how far it is downsampled, as
ComfyUI's own empty-latent nodes do, so ComfyUI fits it to a model that
packs pixels differently. Other models are unchanged.
2026-10-03 12:26:47 -05:00

80 lines
3.5 KiB
Python

"""Latent Size 🆎 backend: clamping and the latent output."""
import sys
import unittest
from unittest.mock import patch
from types import SimpleNamespace
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from nodes.node_resolution import (
DIM_MAX,
DIM_MIN,
LATENT_FAMILIES,
clamp_dimension,
latent_downscale,
latent_shape,
)
from nodes import node_resolution
ResolutionNode = getattr(node_resolution, "AusBossResolution", getattr(node_resolution, "AusBossLabResolution", None))
class TestClampDimension(unittest.TestCase):
def test_passthrough_and_clamp(self):
self.assertEqual(clamp_dimension(1344), 1344)
self.assertEqual(clamp_dimension(5), DIM_MIN)
self.assertEqual(clamp_dimension(999999), DIM_MAX)
def test_junk_falls_back(self):
self.assertEqual(clamp_dimension("wide"), 1024)
self.assertEqual(clamp_dimension(None), 1024)
self.assertEqual(clamp_dimension(float("inf")), 1024)
class TestLatentShape(unittest.TestCase):
def test_families_match_the_core_empty_latent_nodes(self):
# EmptySD3LatentImage: [b, 16, h//8, w//8]; EmptyLatentImage: [b, 4, h//8, w//8];
# EmptyFlux2LatentImage: [b, 128, h//16, w//16].
self.assertEqual(latent_shape(1024, 768, "16ch", 1), (1, 16, 96, 128))
self.assertEqual(latent_shape(1024, 768, "4ch", 2), (2, 4, 96, 128))
self.assertEqual(latent_shape(1024, 768, "128ch", 1), (1, 128, 48, 64))
def test_unknown_family_and_bad_batch_fall_back(self):
self.assertEqual(latent_shape(512, 512, "nope", "x"), (1, 16, 64, 64))
self.assertEqual(latent_shape(512, 512, "16ch", 999), (64, 16, 64, 64))
def test_combo_options_are_the_family_labels(self):
options = ResolutionNode.INPUT_TYPES()["optional"]["latent"][0]
self.assertEqual(options, list(LATENT_FAMILIES))
class TestResolve(unittest.TestCase):
def test_typed_values_survive_exactly_and_the_latent_follows(self):
# Snap governs gestures; the backend never re-snaps 1920x1080.
fake_torch = SimpleNamespace(zeros=lambda shape, **kwargs: SimpleNamespace(shape=tuple(shape)))
with patch("nodes.node_resolution.torch", fake_torch), patch("nodes.node_resolution.model_management", None):
width, height, latent = ResolutionNode().resolve(1920, 1080)
self.assertEqual((width, height), (1920, 1080))
samples = latent["samples"]
shape = tuple(samples.shape) if samples is not None else latent["shape"]
self.assertEqual(shape, (1, 16, 135, 240))
def test_the_latent_says_how_far_it_is_downsampled(self):
# Core's empty-latent nodes carry this, and the sampler uses it to resize an
# empty latent for a model with another ratio (Qwen Image 2.1 is 16x).
fake_torch = SimpleNamespace(zeros=lambda shape, **kwargs: SimpleNamespace(shape=tuple(shape)))
with patch("nodes.node_resolution.torch", fake_torch), patch("nodes.node_resolution.model_management", None):
ratios = [ResolutionNode().resolve(1024, 1024, family)[2]["downscale_ratio_spacial"] for family in LATENT_FAMILIES]
self.assertEqual(ratios, [8, 8, 16])
self.assertEqual(latent_downscale("nope"), 8)
def test_outputs_are_width_height_latent(self):
self.assertEqual(ResolutionNode.RETURN_NAMES, ("width", "height", "latent"))
self.assertEqual(ResolutionNode.RETURN_TYPES, ("INT", "INT", "LATENT"))
if __name__ == "__main__":
unittest.main()