mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-03-30 05:23:37 +08:00
181 lines
5.2 KiB
Python
181 lines
5.2 KiB
Python
import pytest
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
mock_nodes = MagicMock()
|
|
mock_nodes.MAX_RESOLUTION = 16384
|
|
mock_server = MagicMock()
|
|
|
|
with patch.dict("sys.modules", {"nodes": mock_nodes, "server": mock_server}):
|
|
from comfy_extras.nodes_number_convert import NumberConvertNode
|
|
|
|
|
|
class TestNumberConvertExecute:
|
|
@staticmethod
|
|
def _exec(value) -> object:
|
|
return NumberConvertNode.execute(value)
|
|
|
|
# --- INT input ---
|
|
|
|
def test_int_input(self):
|
|
result = self._exec(42)
|
|
assert result[0] == 42.0
|
|
assert result[1] == 42
|
|
|
|
def test_int_zero(self):
|
|
result = self._exec(0)
|
|
assert result[0] == 0.0
|
|
assert result[1] == 0
|
|
|
|
def test_int_negative(self):
|
|
result = self._exec(-7)
|
|
assert result[0] == -7.0
|
|
assert result[1] == -7
|
|
|
|
# --- FLOAT input ---
|
|
|
|
def test_float_input(self):
|
|
result = self._exec(3.14)
|
|
assert result[0] == 3.14
|
|
assert result[1] == 3
|
|
|
|
def test_float_truncation_toward_zero(self):
|
|
result = self._exec(-2.9)
|
|
assert result[0] == -2.9
|
|
assert result[1] == -2 # int() truncates toward zero, not floor
|
|
|
|
def test_float_output_type(self):
|
|
result = self._exec(5)
|
|
assert isinstance(result[0], float)
|
|
|
|
def test_int_output_type(self):
|
|
result = self._exec(5.7)
|
|
assert isinstance(result[1], int)
|
|
|
|
# --- BOOL input ---
|
|
|
|
def test_bool_true(self):
|
|
result = self._exec(True)
|
|
assert result[0] == 1.0
|
|
assert result[1] == 1
|
|
|
|
def test_bool_false(self):
|
|
result = self._exec(False)
|
|
assert result[0] == 0.0
|
|
assert result[1] == 0
|
|
|
|
# --- STRING input ---
|
|
|
|
def test_string_integer(self):
|
|
result = self._exec("42")
|
|
assert result[0] == 42.0
|
|
assert result[1] == 42
|
|
|
|
def test_string_float(self):
|
|
result = self._exec("3.14")
|
|
assert result[0] == 3.14
|
|
assert result[1] == 3
|
|
|
|
def test_string_negative(self):
|
|
result = self._exec("-5.5")
|
|
assert result[0] == -5.5
|
|
assert result[1] == -5
|
|
|
|
def test_string_with_whitespace(self):
|
|
result = self._exec(" 7.0 ")
|
|
assert result[0] == 7.0
|
|
assert result[1] == 7
|
|
|
|
def test_string_scientific_notation(self):
|
|
result = self._exec("1e3")
|
|
assert result[0] == 1000.0
|
|
assert result[1] == 1000
|
|
|
|
# --- Large number precision (string input) ---
|
|
|
|
def test_string_large_int_above_2_53(self):
|
|
"""Text-to-int must not lose precision for integers beyond 2^53."""
|
|
big = 2**53 + 1 # 9007199254740993
|
|
result = self._exec(str(big))
|
|
assert result[1] == big
|
|
|
|
def test_string_large_negative_int_above_2_53(self):
|
|
big = -(2**53 + 1)
|
|
result = self._exec(str(big))
|
|
assert result[1] == big
|
|
|
|
def test_string_very_large_int(self):
|
|
big = 2**63 + 42
|
|
result = self._exec(str(big))
|
|
assert result[1] == big
|
|
|
|
def test_string_large_int_float_output_is_float(self):
|
|
"""FLOAT output is still a float (may lose precision, but must be float type)."""
|
|
result = self._exec(str(2**53 + 1))
|
|
assert isinstance(result[0], float)
|
|
|
|
# --- Large number precision (int input) ---
|
|
|
|
def test_int_large_above_2_53(self):
|
|
"""Native int input must preserve its value in the INT output."""
|
|
big = 2**53 + 1
|
|
result = self._exec(big)
|
|
assert result[1] == big
|
|
|
|
def test_int_large_negative_above_2_53(self):
|
|
big = -(2**53 + 1)
|
|
result = self._exec(big)
|
|
assert result[1] == big
|
|
|
|
def test_int_very_large(self):
|
|
big = 2**100
|
|
result = self._exec(big)
|
|
assert result[1] == big
|
|
|
|
# --- String decimal / scientific notation fallback ---
|
|
|
|
def test_string_decimal_still_truncates(self):
|
|
"""Strings with decimal points fall back to int(float(...)) truncation."""
|
|
result = self._exec("3.7")
|
|
assert result[1] == 3
|
|
|
|
def test_string_negative_decimal_truncates(self):
|
|
result = self._exec("-2.9")
|
|
assert result[1] == -2
|
|
|
|
def test_string_scientific_large(self):
|
|
result = self._exec("1e18")
|
|
assert result[0] == 1e18
|
|
assert result[1] == 10**18
|
|
|
|
# --- STRING error paths ---
|
|
|
|
def test_empty_string_raises(self):
|
|
with pytest.raises(ValueError, match="Cannot convert empty string"):
|
|
self._exec("")
|
|
|
|
def test_whitespace_only_string_raises(self):
|
|
with pytest.raises(ValueError, match="Cannot convert empty string"):
|
|
self._exec(" ")
|
|
|
|
def test_non_numeric_string_raises(self):
|
|
with pytest.raises(ValueError, match="Cannot convert string to number"):
|
|
self._exec("abc")
|
|
|
|
def test_string_inf_raises(self):
|
|
with pytest.raises(ValueError, match="non-finite"):
|
|
self._exec("inf")
|
|
|
|
def test_string_nan_raises(self):
|
|
with pytest.raises(ValueError, match="non-finite"):
|
|
self._exec("nan")
|
|
|
|
def test_string_negative_inf_raises(self):
|
|
with pytest.raises(ValueError, match="non-finite"):
|
|
self._exec("-inf")
|
|
|
|
# --- Unsupported type ---
|
|
|
|
def test_unsupported_type_raises(self):
|
|
with pytest.raises(TypeError, match="Unsupported input type"):
|
|
self._exec([1, 2, 3])
|