245 lines
6.8 KiB
Python
245 lines
6.8 KiB
Python
"""
|
|
Tests for String Joiner Node
|
|
|
|
Run with: python test_string_joiner.py
|
|
"""
|
|
|
|
import inspect
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Add parent directory to path to import node modules
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from string_joiner import StringJoiner
|
|
|
|
|
|
def test_basic_join():
|
|
"""Test basic string joining"""
|
|
node = StringJoiner()
|
|
|
|
# Basic join
|
|
result, count = node.join_list(["a", "b", "c"], ",")
|
|
assert result == "a,b,c", f"Expected 'a,b,c', got '{result}'"
|
|
assert count == 3, f"Expected count 3, got {count}"
|
|
|
|
print("✓ test_basic_join passed")
|
|
|
|
|
|
def test_with_string_splitter():
|
|
"""Test round-trip with String Splitter"""
|
|
from string_splitter import StringSplitter
|
|
|
|
splitter = StringSplitter()
|
|
joiner = StringJoiner()
|
|
|
|
# Split then join - should get back original
|
|
original = "10,25,42,100"
|
|
split_list, _ = splitter.split_string(original, ",")
|
|
rejoined, _ = joiner.join_list(split_list, ",")
|
|
|
|
assert rejoined == original, f"Expected '{original}', got '{rejoined}'"
|
|
|
|
print("✓ test_with_string_splitter passed")
|
|
|
|
|
|
def test_integer_list():
|
|
"""Test joining list of integers"""
|
|
node = StringJoiner()
|
|
|
|
# Integer list (from String Splitter with INT output)
|
|
int_list = [10, 25, 42, 100]
|
|
result, count = node.join_list(int_list, ",")
|
|
|
|
assert result == "10,25,42,100", f"Expected '10,25,42,100', got '{result}'"
|
|
assert count == 4
|
|
|
|
print("✓ test_integer_list passed")
|
|
|
|
|
|
def test_float_list():
|
|
"""Test joining list of floats"""
|
|
node = StringJoiner()
|
|
|
|
float_list = [1.5, 2.0, 3.14]
|
|
result, _ = node.join_list(float_list, ",")
|
|
|
|
assert result == "1.5,2.0,3.14", f"Expected '1.5,2.0,3.14', got '{result}'"
|
|
|
|
print("✓ test_float_list passed")
|
|
|
|
|
|
def test_different_delimiters():
|
|
"""Test various delimiters"""
|
|
node = StringJoiner()
|
|
|
|
test_list = ["a", "b", "c"]
|
|
|
|
# Pipe delimiter
|
|
result, _ = node.join_list(test_list, "|")
|
|
assert result == "a|b|c", f"Pipe delimiter failed: {result}"
|
|
|
|
# Newline
|
|
result, _ = node.join_list(test_list, "\n")
|
|
assert result == "a\nb\nc", f"Newline delimiter failed: {result}"
|
|
|
|
# Space
|
|
result, _ = node.join_list(test_list, " ")
|
|
assert result == "a b c", f"Space delimiter failed: {result}"
|
|
|
|
# Multi-character
|
|
result, _ = node.join_list(test_list, " :: ")
|
|
assert result == "a :: b :: c", f"Multi-char delimiter failed: {result}"
|
|
|
|
print("✓ test_different_delimiters passed")
|
|
|
|
|
|
def test_edge_cases():
|
|
"""Test edge cases"""
|
|
node = StringJoiner()
|
|
|
|
# Empty list
|
|
result, count = node.join_list([], ",")
|
|
assert result == "", f"Empty list should give empty string"
|
|
assert count == 0
|
|
|
|
# Single item
|
|
result, count = node.join_list(["only"], ",")
|
|
assert result == "only", f"Single item failed: {result}"
|
|
assert count == 1
|
|
|
|
# Empty strings in list
|
|
result, _ = node.join_list(["a", "", "c"], ",")
|
|
assert result == "a,,c", f"Empty string handling failed: {result}"
|
|
|
|
print("✓ test_edge_cases passed")
|
|
|
|
|
|
def test_mixed_types():
|
|
"""Test list with mixed types"""
|
|
node = StringJoiner()
|
|
|
|
mixed_list = ["text", 42, 3.14, True, None]
|
|
result, count = node.join_list(mixed_list, " | ")
|
|
|
|
assert result == "text | 42 | 3.14 | True | None", f"Mixed types failed: {result}"
|
|
assert count == 5
|
|
|
|
print("✓ test_mixed_types passed")
|
|
|
|
|
|
def test_return_types():
|
|
"""Validate return types"""
|
|
node = StringJoiner()
|
|
|
|
result = node.join_list(["a", "b"], ",")
|
|
|
|
assert isinstance(result, tuple), f"Should return tuple"
|
|
assert len(result) == 2, f"Should return 2 items"
|
|
assert isinstance(result[0], str), f"First item should be string"
|
|
assert isinstance(result[1], int), f"Second item should be int"
|
|
|
|
print("✓ test_return_types passed")
|
|
|
|
|
|
def test_input_types_structure():
|
|
"""Validate INPUT_TYPES matches function signature"""
|
|
input_types = StringJoiner.INPUT_TYPES()
|
|
|
|
all_inputs = set()
|
|
if "required" in input_types:
|
|
all_inputs.update(input_types["required"].keys())
|
|
if "optional" in input_types:
|
|
all_inputs.update(input_types["optional"].keys())
|
|
|
|
function = getattr(StringJoiner(), StringJoiner.FUNCTION)
|
|
sig = inspect.signature(function)
|
|
function_params = set(sig.parameters.keys()) - {'self'}
|
|
|
|
missing = function_params - all_inputs
|
|
extra = all_inputs - function_params
|
|
|
|
assert not missing, f"Function has params not in INPUT_TYPES: {missing}"
|
|
assert not extra, f"INPUT_TYPES has entries not in function: {extra}"
|
|
|
|
print("✓ test_input_types_structure passed")
|
|
|
|
|
|
def test_full_workflow():
|
|
"""Test complete workflow: split → process → join"""
|
|
from string_splitter import StringSplitter
|
|
from list_index_selector import ListIndexSelector
|
|
|
|
splitter = StringSplitter()
|
|
selector = ListIndexSelector()
|
|
joiner = StringJoiner()
|
|
|
|
# Start with frame numbers
|
|
original = "10,25,42,100"
|
|
|
|
# Split to list
|
|
frame_list, _ = splitter.split_string(original, ",", output_type="INT")
|
|
|
|
# Process - select one frame
|
|
selected_frame, _ = selector.select_from_list(frame_list, 2, True)
|
|
assert selected_frame == 42, "Should select frame 42"
|
|
|
|
# Join back for display/logging
|
|
display_string, _ = joiner.join_list(frame_list, ", ")
|
|
assert display_string == "10, 25, 42, 100", f"Display string wrong: {display_string}"
|
|
|
|
print("✓ test_full_workflow passed")
|
|
|
|
def test_escape_sequences():
|
|
node = StringJoiner()
|
|
|
|
# Newline
|
|
result, _ = node.join_list(["a", "b", "c"], "\\n")
|
|
assert result == "a\nb\nc", "Should convert \\n to newline"
|
|
|
|
# Tab
|
|
result, _ = node.join_list(["a", "b"], "\\t")
|
|
assert result == "a\tb", "Should convert \\t to tab"
|
|
|
|
print("✓ test_escape_sequences passed")
|
|
|
|
def run_all_tests():
|
|
"""Run all test functions"""
|
|
print("Running tests for StringJoiner...\n")
|
|
|
|
try:
|
|
test_basic_join()
|
|
test_with_string_splitter()
|
|
test_integer_list()
|
|
test_float_list()
|
|
test_different_delimiters()
|
|
test_edge_cases()
|
|
test_mixed_types()
|
|
test_return_types()
|
|
test_input_types_structure()
|
|
test_full_workflow()
|
|
test_escape_sequences()
|
|
|
|
print("\n" + "="*50)
|
|
print("✅ ALL TESTS PASSED!")
|
|
print("="*50)
|
|
return True
|
|
|
|
except AssertionError as e:
|
|
print("\n" + "="*50)
|
|
print(f"❌ TEST FAILED: {e}")
|
|
print("="*50)
|
|
return False
|
|
except Exception as e:
|
|
print("\n" + "="*50)
|
|
print(f"❌ UNEXPECTED ERROR: {e}")
|
|
print("="*50)
|
|
import traceback
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
success = run_all_tests()
|
|
exit(0 if success else 1) |