Bump version to 0.3.0 due to breaking changes in this PR

Update tests
This commit is contained in:
StableLlama
2025-05-18 00:38:17 +02:00
parent b8d2062e75
commit 334d693eff
13 changed files with 797 additions and 53 deletions
+3 -2
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "basic_data_handling"
version = "0.2.2"
version = "0.3.0"
description = """NOTE: Still in development! Expect breaking changes!
Basic Python functions for manipulating data that every programmer is used to.
Currently supported ComfyUI data types: BOOLEAN, FLOAT, INT, STRING and data lists.
@@ -47,11 +47,12 @@ minversion = "8.0"
pythonpath = [
"src",
"../..", # Path to parent directory containing comfy module
"."
]
testpaths = [
"tests",
]
# python_files = ["test_*.py"]
#python_files = ["test_*.py"]
python_files = ["test_boolean_nodes.py"]
[tool.mypy]
+8 -8
View File
@@ -58,7 +58,7 @@ class NotEqual(ComfyNodeABC):
return (value1 != value2,)
class LessThan:
class LessThan(ComfyNodeABC):
"""
Checks if the first value is less than the second.
@@ -84,7 +84,7 @@ class LessThan:
return (value1 < value2,)
class LessThanOrEqual:
class LessThanOrEqual(ComfyNodeABC):
"""
Checks if the first value is less than or equal to the second.
@@ -110,7 +110,7 @@ class LessThanOrEqual:
return (value1 <= value2,)
class GreaterThan:
class GreaterThan(ComfyNodeABC):
"""
Checks if the first value is greater than the second.
@@ -136,7 +136,7 @@ class GreaterThan:
return (value1 > value2,)
class GreaterThanOrEqual:
class GreaterThanOrEqual(ComfyNodeABC):
"""
Checks if the first value is greater than or equal to the second.
@@ -162,7 +162,7 @@ class GreaterThanOrEqual:
return (value1 >= value2,)
class IsNull:
class IsNull(ComfyNodeABC):
"""
Checks if a value is None/null.
@@ -187,7 +187,7 @@ class IsNull:
return (value is None,)
class NumberInRange:
class NumberInRange(ComfyNodeABC):
"""
Checks if a number is within a specified range.
@@ -223,7 +223,7 @@ class NumberInRange:
return (min_check and max_check,)
class CompareLength:
class CompareLength(ComfyNodeABC):
"""
Compares the length of a container (string, list, etc) with a value.
@@ -269,7 +269,7 @@ class CompareLength:
raise ValueError(f"Unknown operator: {operator}")
class StringComparison:
class StringComparison(ComfyNodeABC):
"""
Compares two strings using a selected comparison operator.
+2
View File
@@ -149,6 +149,8 @@ class FloatDivideSafe(ComfyNodeABC):
def divide(self, float1: float, float2: float) -> tuple[float]:
if float2 == 0.0:
if float1 == 0.0:
return (float('nan'),)
return (float('inf') if float1 > 0 else float('-inf'),)
return (float1 / float2,)
+76 -4
View File
@@ -1,4 +1,4 @@
#import pytest
import pytest
from src.basic_data_handling.comparison_nodes import (
Equal,
NotEqual,
@@ -20,6 +20,9 @@ def test_equal():
assert node.compare("hello", "hello") == (True,)
assert node.compare([1, 2], [1, 2]) == (True,)
assert node.compare(None, None) == (True,)
# Test complex objects
assert node.compare({"a": 1}, {"a": 1}) == (True,)
assert node.compare({"a": 1}, {"a": 2}) == (False,)
def test_not_equal():
@@ -29,6 +32,9 @@ def test_not_equal():
assert node.compare("hello", "world") == (True,)
assert node.compare([1, 2], [1, 3]) == (True,)
assert node.compare(None, []) == (True,)
# Test complex objects
assert node.compare({"a": 1}, {"b": 1}) == (True,)
assert node.compare({"a": 1}, {"a": 1}) == (False,)
def test_greater_than():
@@ -37,6 +43,12 @@ def test_greater_than():
assert node.compare(5, 10) == (False,)
assert node.compare(10, 10) == (False,)
assert node.compare(5.6, 2.3) == (True,)
# Test negative numbers
assert node.compare(-5, -10) == (True,)
assert node.compare(-10, -5) == (False,)
# Test zeroes
assert node.compare(0, -1) == (True,)
assert node.compare(0, 0) == (False,)
def test_less_than():
@@ -45,6 +57,12 @@ def test_less_than():
assert node.compare(10, 5) == (False,)
assert node.compare(10, 10) == (False,)
assert node.compare(2.3, 5.6) == (True,)
# Test negative numbers
assert node.compare(-10, -5) == (True,)
assert node.compare(-5, -10) == (False,)
# Test zeroes
assert node.compare(-1, 0) == (True,)
assert node.compare(0, 0) == (False,)
def test_greater_than_or_equal():
@@ -53,6 +71,12 @@ def test_greater_than_or_equal():
assert node.compare(15, 10) == (True,)
assert node.compare(5, 10) == (False,)
assert node.compare(5.5, 5.5) == (True,)
# Test negative numbers
assert node.compare(-5, -10) == (True,)
assert node.compare(-5, -5) == (True,)
# Test zeroes
assert node.compare(0, 0) == (True,)
assert node.compare(0.0, -0.0) == (True,)
def test_less_than_or_equal():
@@ -61,6 +85,12 @@ def test_less_than_or_equal():
assert node.compare(5, 15) == (True,)
assert node.compare(15, 5) == (False,)
assert node.compare(3.1, 3.1) == (True,)
# Test negative numbers
assert node.compare(-10, -5) == (True,)
assert node.compare(-5, -5) == (True,)
# Test zeroes
assert node.compare(0, 0) == (True,)
assert node.compare(-0.0, 0.0) == (True,)
def test_string_comparison():
@@ -71,11 +101,20 @@ def test_string_comparison():
assert node.compare("apple", "banana", "<", "True") == (True,)
assert node.compare("apple", "banana", ">", "True") == (False,)
assert node.compare("apple", "apple", "!=", "True") == (False,)
assert node.compare("banana", "apple", ">=", "True") == (True,)
assert node.compare("apple", "banana", "<=", "True") == (True,)
# Case-insensitive tests
assert node.compare("Hello", "hello", "==", "False") == (True,)
assert node.compare("Apple", "BANANA", "<", "False") == (True,)
assert node.compare("Grape", "GRAPE", ">=", "False") == (True,)
assert node.compare("ZEBRA", "zoo", "<", "False") == (True,)
assert node.compare("ZOO", "zebra", ">", "False") == (True,)
# Empty string tests
assert node.compare("", "hello", "<", "True") == (True,)
assert node.compare("hello", "", ">", "True") == (True,)
assert node.compare("", "", "==", "True") == (True,)
def test_number_in_range():
@@ -84,15 +123,27 @@ def test_number_in_range():
# Inclusive range tests
assert node.check_range(50, 0, 100) == (True,)
assert node.check_range(0, 0, 100) == (True,)
assert node.check_range(100, 0, 100) == (True,)
# Exclusive range tests
assert node.check_range(0, 0, 100, include_min="False") == (False,)
assert node.check_range(100, 0, 100, include_max="False") == (False,)
assert node.check_range(50, 0, 100, include_min="False", include_max="False") == (True,)
# Out of range tests
assert node.check_range(-1, 0, 100) == (False,)
assert node.check_range(101, 0, 100) == (False,)
# Edge cases
assert node.check_range(0, 0, 0) == (True,)
assert node.check_range(0, 0, 0, include_min="False") == (False,)
assert node.check_range(0, 0, 0, include_max="False") == (False,)
# Negative range tests
assert node.check_range(-50, -100, -10) == (True,)
assert node.check_range(-10, -100, -10) == (True,)
assert node.check_range(-100, -100, -10) == (True,)
def test_is_null():
node = IsNull()
@@ -100,16 +151,37 @@ def test_is_null():
assert node.check_null(0) == (False,)
assert node.check_null("") == (False,)
assert node.check_null([]) == (False,)
assert node.check_null(False) == (False,)
# Additional edge cases
assert node.check_null([None]) == (False,) # List containing None
assert node.check_null("None") == (False,) # String "None"
def test_compare_length():
node = CompareLength()
# Valid comparisons
# Valid comparisons with different operators
assert node.compare_length([1, 2, 3], "==", 3) == (True, 3)
assert node.compare_length("hello", "!=", 4) == (True, 5)
assert node.compare_length((1, 2), ">", 1) == (True, 2)
assert node.compare_length([1, 2, 3], "<", 4) == (True, 3)
assert node.compare_length("test", ">=", 4) == (True, 4)
assert node.compare_length([1], "<=", 1) == (True, 1)
# Different container types
assert node.compare_length({"a", "b", "c"}, "==", 3) == (True, 3) # Set
assert node.compare_length({"key1": 1, "key2": 2}, "==", 2) == (True, 2) # Dict
# Empty containers
assert node.compare_length([], "==", 0) == (True, 0)
assert node.compare_length("", "==", 0) == (True, 0)
assert node.compare_length({}, "==", 0) == (True, 0)
# Invalid comparisons
assert node.compare_length({"key": "value"}, "<", 1) == (False, 1)
assert node.compare_length(123, "==", 0) == (False, -1) # Non-container input edge case
assert node.compare_length({"key": "value"}, "<", 1) == (False, 1) # Dict with 1 item
assert node.compare_length(123, "==", 0) == (False, -1) # Non-container input
assert node.compare_length(None, "==", 0) == (False, -1) # None
# Error case with invalid operator
with pytest.raises(ValueError):
node.compare_length([1, 2, 3], "invalid", 3)
+2 -6
View File
@@ -14,7 +14,6 @@ from src.basic_data_handling.data_list_nodes import (
DataListGetItem,
DataListSetItem,
DataListContains,
DataListCreateEmpty,
DataListZip,
DataListFilter,
DataListMin,
@@ -119,21 +118,18 @@ def test_contains():
assert node.contains(list=[], value=["x"]) == (False,)
def test_create_empty():
node = DataListCreateEmpty()
assert node.create_empty() == ([],)
def test_zip():
node = DataListZip()
assert node.zip_lists(list1=[1, 2], list2=["a", "b"]) == ([[1, "a"], [2, "b"]],)
assert node.zip_lists(list1=[1], list2=["a", "b"]) == ([[1, "a"]],) # Shortest list length
assert node.zip_lists(list1=[1, 2, 3], list2=["a", "b"]) == ([[1, "a"], [2, "b"]],) # Different lengths
def test_filter():
node = DataListFilter()
assert node.filter_data(value=[1, 2, 3], filter=[False, True, False]) == ([1, 3],)
assert node.filter_data(value=[1, 2], filter=[True, True]) == ([],)
assert node.filter_data(value=[1, 2, 3], filter=[False, False, False]) == ([1, 2, 3],)
def test_min():
+141 -20
View File
@@ -34,30 +34,46 @@ def test_dict_get():
my_dict = {"key1": "value1", "key2": "value2"}
assert node.get(my_dict, "key1") == ("value1",)
assert node.get(my_dict, "key3", default="default_value") == ("default_value",)
# Test with no default specified
assert node.get(my_dict, "non_existent") == (None,)
def test_dict_set():
node = DictSet()
my_dict = {"key1": "value1"}
assert node.set(my_dict, "key2", "value2") == ({"key1": "value1", "key2": "value2"},)
# Test overwriting existing key
assert node.set(my_dict, "key1", "new_value") == ({"key1": "new_value"},)
# Test with empty dict
assert node.set({}, "key", "value") == ({"key": "value"},)
def test_dict_keys():
node = DictKeys()
my_dict = {"key1": "value1", "key2": "value2"}
assert node.keys(my_dict) == (["key1", "key2"],)
# Test with empty dict
assert node.keys({}) == ([],)
def test_dict_values():
node = DictValues()
my_dict = {"key1": "value1", "key2": "value2"}
assert node.values(my_dict) == (["value1", "value2"],)
# Test with empty dict
assert node.values({}) == ([],)
def test_dict_items():
node = DictItems()
my_dict = {"key1": "value1", "key2": "value2"}
assert node.items(my_dict) == ([("key1", "value1"), ("key2", "value2")],)
# Note that the order might not be preserved, so we check if items are in the result
items = node.items(my_dict)[0]
assert len(items) == 2
assert ("key1", "value1") in items
assert ("key2", "value2") in items
# Test with empty dict
assert node.items({}) == ([],)
def test_dict_contains_key():
@@ -65,31 +81,52 @@ def test_dict_contains_key():
my_dict = {"key1": "value1"}
assert node.contains_key(my_dict, "key1") == (True,)
assert node.contains_key(my_dict, "key2") == (False,)
# Test with empty dict
assert node.contains_key({}, "any_key") == (False,)
def test_dict_from_keys():
node = DictFromKeys()
keys = ["key1", "key2"]
assert node.from_keys(keys, value="value") == ({"key1": "value", "key2": "value"},)
# Test without value (should use None)
assert node.from_keys(keys) == ({"key1": None, "key2": None},)
# Test with empty keys list
assert node.from_keys([]) == ({},)
def test_dict_pop():
node = DictPop()
my_dict = {"key1": "value1", "key2": "value2"}
assert node.pop(my_dict, "key1") == ({"key2": "value2"}, "value1")
# Test with default value for non-existent key
assert node.pop(my_dict, "non_existent", default_value="default") == (my_dict, "default")
# Test with no default for non-existent key - should not modify dict
assert node.pop({"a": 1}, "b") == ({"a": 1}, None)
def test_dict_pop_item():
node = DictPopItem()
my_dict = {"key1": "value1"}
assert node.popitem(my_dict) == ({}, "key1", "value1", True)
result = node.popitem(my_dict)
# Since we only have one item, we know what should be popped
assert result[0] == {} # remaining dict is empty
assert result[1] == "key1" # popped key
assert result[2] == "value1" # popped value
assert result[3] is True # success
# Test with empty dict
assert node.popitem({}) == ({}, "", None, False)
def test_dict_set_default():
node = DictSetDefault()
my_dict = {"key1": "value1"}
# Test setting a key that doesn't exist
assert node.setdefault(my_dict, "key2", "default") == ({"key1": "value1", "key2": "default"}, "default")
# Test with a key that already exists
assert node.setdefault(my_dict, "key1", "new_default") == ({"key1": "value1"}, "value1")
# Test with empty dict
assert node.setdefault({}, "key", "value") == ({"key": "value"}, "value")
def test_dict_update():
@@ -97,69 +134,153 @@ def test_dict_update():
my_dict = {"key1": "value1"}
update_dict = {"key2": "value2"}
assert node.update(my_dict, update_dict) == ({"key1": "value1", "key2": "value2"},)
# Test updating with overlapping keys
assert node.update({"a": 1, "b": 2}, {"b": 3, "c": 4}) == ({"a": 1, "b": 3, "c": 4},)
# Test with empty update dict
assert node.update(my_dict, {}) == (my_dict,)
# Test with empty original dict
assert node.update({}, update_dict) == (update_dict,)
def test_dict_length():
node = DictLength()
my_dict = {"key1": "value1"}
assert node.length(my_dict) == (1,)
my_dict = {"key1": "value1", "key2": "value2"}
assert node.length(my_dict) == (2,)
# Test with empty dict
assert node.length({}) == (0,)
def test_dict_merge():
node = DictMerge()
dict1 = {"key1": "value1"}
dict2 = {"key2": "value2"}
# Test basic merge
assert node.merge(dict1, dict2) == ({"key1": "value1", "key2": "value2"},)
# Test with overlapping keys (later dicts override earlier ones)
assert node.merge({"a": 1}, {"a": 2}) == ({"a": 2},)
# Test with more than two dicts
result = node.merge({"a": 1}, {"b": 2}, {"c": 3})
assert result == ({"a": 1, "b": 2, "c": 3},)
# Test with empty dicts
assert node.merge(dict1, {}) == (dict1,)
assert node.merge({}, dict1) == (dict1,)
def test_dict_get_keys_values():
node = DictGetKeysValues()
my_dict = {"key1": "value1", "key2": "value2"}
assert node.get_keys_values(my_dict) == (["key1", "key2"], ["value1", "value2"])
keys, values = node.get_keys_values(my_dict)
# Check keys and values contents (order may vary)
assert set(keys) == {"key1", "key2"}
assert set(values) == {"value1", "value2"}
# Test with empty dict
assert node.get_keys_values({}) == ([], [])
def test_dict_remove():
node = DictRemove()
my_dict = {"key1": "value1"}
assert node.remove(my_dict, "key1") == ({}, True)
my_dict = {"key1": "value1", "key2": "value2"}
# Test successful removal
assert node.remove(my_dict, "key1") == ({"key2": "value2"}, True)
# Test removal of non-existent key
assert node.remove(my_dict, "non_existent") == (my_dict, False)
# Test with empty dict
assert node.remove({}, "any_key") == ({}, False)
def test_dict_filter_by_keys():
node = DictFilterByKeys()
my_dict = {"key1": "value1", "key2": "value2"}
keys = ["key1"]
assert node.filter_by_keys(my_dict, keys) == ({"key1": "value1"},)
my_dict = {"key1": "value1", "key2": "value2", "key3": "value3"}
# Test with subset of keys
assert node.filter_by_keys(my_dict, ["key1", "key3"]) == ({"key1": "value1", "key3": "value3"},)
# Test with non-existent keys
assert node.filter_by_keys(my_dict, ["key1", "non_existent"]) == ({"key1": "value1"},)
# Test with empty keys list
assert node.filter_by_keys(my_dict, []) == ({},)
# Test with empty dict
assert node.filter_by_keys({}, ["any_key"]) == ({},)
def test_dict_exclude_keys():
node = DictExcludeKeys()
my_dict = {"key1": "value1", "key2": "value2"}
keys = ["key1"]
assert node.exclude_keys(my_dict, keys) == ({"key2": "value2"},)
my_dict = {"key1": "value1", "key2": "value2", "key3": "value3"}
# Test excluding some keys
assert node.exclude_keys(my_dict, ["key1", "key3"]) == ({"key2": "value2"},)
# Test excluding non-existent keys
assert node.exclude_keys(my_dict, ["non_existent"]) == (my_dict,)
# Test excluding all keys
assert node.exclude_keys(my_dict, ["key1", "key2", "key3"]) == ({},)
# Test with empty exclude list
assert node.exclude_keys(my_dict, []) == (my_dict,)
# Test with empty dict
assert node.exclude_keys({}, ["any_key"]) == ({},)
def test_dict_get_multiple():
node = DictGetMultiple()
my_dict = {"key1": "value1", "key2": "value2"}
keys = ["key1", "key3"]
assert node.get_multiple(my_dict, keys, default="default") == (["value1", "default"],)
# Test getting existing keys
assert node.get_multiple(my_dict, ["key1", "key2"]) == (["value1", "value2"],)
# Test with mix of existing and non-existent keys
assert node.get_multiple(my_dict, ["key1", "key3"], default="default") == (["value1", "default"],)
# Test with only non-existent keys
assert node.get_multiple(my_dict, ["key3", "key4"], default="default") == (["default", "default"],)
# Test with empty keys list
assert node.get_multiple(my_dict, []) == ([],)
# Test with empty dict
assert node.get_multiple({}, ["key1"], default="default") == (["default"],)
def test_dict_invert():
node = DictInvert()
my_dict = {"key1": "value1", "key2": "value2"}
# Test basic inversion
assert node.invert(my_dict) == ({"value1": "key1", "value2": "key2"}, True)
# Test with duplicated values
result, success = node.invert({"key1": "value", "key2": "value"})
# With duplicate values, the last key wins
assert result == {"value": "key2"}
assert success is True
# Test with empty dict
assert node.invert({}) == ({}, True)
def test_dict_create_from_lists():
node = DictCreateFromLists()
keys = ["key1", "key2"]
values = ["value1", "value2"]
assert node.create_from_lists(keys, values) == ({"key1": "value1", "key2": "value2"},)
keys = ["key1", "key2", "key3"]
values = ["value1", "value2", "value3"]
# Test with matching length lists
assert node.create_from_lists(keys, values) == ({"key1": "value1", "key2": "value2", "key3": "value3"},)
# Test with more keys than values
assert node.create_from_lists(keys, ["value1", "value2"]) == ({"key1": "value1", "key2": "value2"},)
# Test with more values than keys
assert node.create_from_lists(["key1", "key2"], values) == ({"key1": "value1", "key2": "value2"},)
# Test with empty lists
assert node.create_from_lists([], []) == ({},)
def test_dict_compare():
node = DictCompare()
dict1 = {"key1": "value1"}
dict2 = {"key1": "value1"}
# Test identical dictionaries
dict1 = {"key1": "value1", "key2": "value2"}
dict2 = {"key1": "value1", "key2": "value2"}
assert node.compare(dict1, dict2) == (True, [], [], [])
# Test dictionaries with different values
dict3 = {"key1": "value1", "key2": "different"}
are_equal, only_in_1, only_in_2, diff_values = node.compare(dict1, dict3)
assert are_equal is False
assert only_in_1 == []
assert only_in_2 == []
assert "key2" in diff_values
# Test dictionaries with different keys
dict4 = {"key1": "value1", "key3": "value3"}
are_equal, only_in_1, only_in_2, diff_values = node.compare(dict1, dict4)
assert are_equal is False
assert "key2" in only_in_1
assert "key3" in only_in_2
assert diff_values == []
# Test empty dictionaries
assert node.compare({}, {}) == (True, [], [], [])
+26
View File
@@ -1,9 +1,12 @@
import math
import pytest
from src.basic_data_handling.float_nodes import (
FloatCreate,
FloatAdd,
FloatSubtract,
FloatMultiply,
FloatDivide,
FloatDivideSafe,
FloatPower,
FloatRound,
FloatIsInteger,
@@ -12,6 +15,15 @@ from src.basic_data_handling.float_nodes import (
FloatFromHex,
)
def test_float_create():
node = FloatCreate()
assert node.create("3.14") == (3.14,)
assert node.create("-2.5") == (-2.5,)
assert node.create("0.0") == (0.0,)
with pytest.raises(ValueError):
node.create("not a number")
def test_float_add():
node = FloatAdd()
assert node.add(2.2, 2.2) == (4.4,)
@@ -41,6 +53,20 @@ def test_float_divide():
node.divide(5.0, 0.0)
def test_float_divide_safe():
node = FloatDivideSafe()
assert node.divide(7.0, 2.0) == (3.5,)
assert node.divide(-6.0, 3.0) == (-2.0,)
assert node.divide(5.0, 0.0) == (float('inf'),)
assert node.divide(-5.0, 0.0) == (float('-inf'),)
# Special handling for NaN because NaN != NaN
result = node.divide(0.0, 0.0)
assert len(result) == 1
assert math.isnan(result[0])
def test_float_power():
node = FloatPower()
assert node.power(2.0, 3.0) == (8.0,)
+32 -1
View File
@@ -4,12 +4,15 @@ from src.basic_data_handling.int_nodes import (
IntSubtract,
IntMultiply,
IntDivide,
IntDivideSafe,
IntModulus,
IntPower,
IntBitLength,
IntToBytes,
IntFromBytes,
IntBitCount,
IntCreate,
IntCreateWithBase,
)
@@ -83,4 +86,32 @@ def test_int_bit_count():
node = IntBitCount()
assert node.bit_count(0) == (0,) # Zero has no 1 bits
assert node.bit_count(255) == (8,) # 255 is 11111111 (8 ones)
assert node.bit_count(-255) == (8,) # Negative integer has the same bit count
assert node.bit_count(-255) == (8,) # Negative integer has the same bit count
def test_int_create():
node = IntCreate()
assert node.create("42") == (42,)
assert node.create("-100") == (-100,)
assert node.create("0") == (0,)
assert node.create("0xFF") == (255,) # Hexadecimal
assert node.create("0b1010") == (10,) # Binary
assert node.create("0o777") == (511,) # Octal
def test_int_create_with_base():
node = IntCreateWithBase()
assert node.create("42", 10) == (42,)
assert node.create("FF", 16) == (255,)
assert node.create("1010", 2) == (10,)
assert node.create("777", 8) == (511,)
with pytest.raises(ValueError):
node.create("FF", 10) # Invalid characters for base 10
def test_int_divide_safe():
node = IntDivideSafe()
assert node.divide(10, 2, 9223372036854775807) == (5,)
assert node.divide(9, 4, 9223372036854775807) == (2,) # Integer division
assert node.divide(10, 0, 9223372036854775807) == (9223372036854775807,) # Positive infinity
assert node.divide(-10, 0, 9223372036854775807) == (-9223372036854775807,) # Negative infinity
+57 -1
View File
@@ -1,5 +1,10 @@
import pytest
from src.basic_data_handling.list_nodes import (
ListCreate,
ListCreateFromBoolean,
ListCreateFromFloat,
ListCreateFromInt,
ListCreateFromString,
ListAppend,
ListExtend,
ListInsert,
@@ -15,7 +20,9 @@ from src.basic_data_handling.list_nodes import (
ListSetItem,
ListContains,
ListMin,
ListMax
ListMax,
ListToDataList,
ListToSet
)
@@ -130,3 +137,52 @@ def test_list_max():
assert node.find_max([1, 2, 3]) == (3,)
assert node.find_max(["b", "a", "c"]) == ("c",)
assert node.find_max([]) == (None,)
def test_list_create():
node = ListCreate()
assert node.create_list(item_0=1, item_1=2, item_2=3) == ([1, 2, 3],)
assert node.create_list() == ([],) # Empty list
assert node.create_list(item_0="test") == (["test"],)
def test_list_create_from_boolean():
node = ListCreateFromBoolean()
assert node.create_list(item_0=True, item_1=False, item_2=True) == ([True, False, True],)
assert node.create_list(item_0=True) == ([True],)
assert node.create_list() == ([],)
def test_list_create_from_float():
node = ListCreateFromFloat()
assert node.create_list(item_0=1.1, item_1=2.2, item_2=3.3) == ([1.1, 2.2, 3.3],)
assert node.create_list(item_0=0.0) == ([0.0],)
assert node.create_list() == ([],)
def test_list_create_from_int():
node = ListCreateFromInt()
assert node.create_list(item_0=1, item_1=2, item_2=3) == ([1, 2, 3],)
assert node.create_list(item_0=0) == ([0],)
assert node.create_list() == ([],)
def test_list_create_from_string():
node = ListCreateFromString()
assert node.create_list(item_0="a", item_1="b", item_2="c") == (["a", "b", "c"],)
assert node.create_list(item_0="test") == (["test"],)
assert node.create_list() == ([],)
def test_list_to_data_list():
node = ListToDataList()
input_list = [1, 2, 3]
# The output should be the same list but marked as a data list by the OUTPUT_IS_LIST = (True,) flag
assert node.convert(input_list) == (input_list,)
def test_list_to_set():
node = ListToSet()
assert node.convert([1, 2, 3, 2, 1]) == ({1, 2, 3},)
assert node.convert([]) == (set(),)
assert node.convert(["a", "b", "a", "c"]) == ({"a", "b", "c"},)
+109 -3
View File
@@ -12,6 +12,10 @@ def test_math_sin():
assert node.calculate(0, "radians") == (0.0,)
assert node.calculate(math.pi / 2, "radians") == (1.0,)
assert node.calculate(30, "degrees") == (math.sin(math.radians(30)),)
# Test with string input
assert node.calculate("45", "degrees")[0] == pytest.approx(math.sin(math.radians(45)))
# Test negative angle
assert node.calculate(-90, "degrees")[0] == pytest.approx(-1.0)
def test_math_cos():
@@ -19,14 +23,25 @@ def test_math_cos():
assert node.calculate(0, "radians") == (1.0,)
assert node.calculate(math.pi, "radians") == (-1.0,)
assert node.calculate(60, "degrees") == (math.cos(math.radians(60)),)
# Test with string input
assert node.calculate("60", "degrees")[0] == pytest.approx(0.5)
# Test negative angle
assert node.calculate(-180, "degrees")[0] == pytest.approx(-1.0)
def test_math_tan():
node = MathTan()
assert node.calculate(0, "radians") == (0.0,)
assert node.calculate(45, "degrees") == (math.tan(math.radians(45)),)
# Test with string input
assert node.calculate("30", "degrees")[0] == pytest.approx(math.tan(math.radians(30)))
# Test negative angle
assert node.calculate(-45, "degrees")[0] == pytest.approx(-1.0)
# Test undefined tangent
with pytest.raises(ValueError): # Undefined tangent
node.calculate(90, "degrees")
with pytest.raises(ValueError): # Undefined tangent
node.calculate(math.pi/2, "radians")
def test_math_asin():
@@ -34,6 +49,13 @@ def test_math_asin():
assert node.calculate(0, "radians") == (0.0,)
assert node.calculate(1, "radians") == (math.pi / 2,)
assert node.calculate(0.5, "degrees") == (math.degrees(math.asin(0.5)),)
# Test with string input
assert node.calculate("0.5", "degrees")[0] == pytest.approx(30.0)
# Test boundary values
assert node.calculate(-1, "degrees")[0] == pytest.approx(-90.0)
# Test out of range values
with pytest.raises(ValueError):
node.calculate(1.1, "degrees")
def test_math_acos():
@@ -41,6 +63,13 @@ def test_math_acos():
assert node.calculate(1, "radians") == (0.0,)
assert node.calculate(0, "radians") == (math.pi / 2,)
assert node.calculate(0.5, "degrees") == (math.degrees(math.acos(0.5)),)
# Test with string input
assert node.calculate("0.5", "degrees")[0] == pytest.approx(60.0)
# Test boundary values
assert node.calculate(-1, "degrees")[0] == pytest.approx(180.0)
# Test out of range values
with pytest.raises(ValueError):
node.calculate(1.1, "degrees")
def test_math_atan():
@@ -48,6 +77,10 @@ def test_math_atan():
assert node.calculate(0, "radians") == (0.0,)
assert node.calculate(1, "degrees") == (45.0,)
assert node.calculate(-1, "radians") == (-math.pi / 4,)
# Test with string input
assert node.calculate("1.0", "degrees")[0] == pytest.approx(45.0)
# Test large values
assert node.calculate(1000, "degrees")[0] == pytest.approx(89.94, abs=0.01)
def test_math_atan2():
@@ -55,13 +88,24 @@ def test_math_atan2():
assert node.calculate(0, 1, "radians") == (0.0,)
assert node.calculate(1, 1, "degrees") == (45.0,)
assert node.calculate(-1, -1, "radians") == (-3 * math.pi / 4,)
# Test with string input
assert node.calculate("1", "1", "degrees")[0] == pytest.approx(45.0)
# Test special cases
assert node.calculate(1, 0, "degrees")[0] == pytest.approx(90.0)
assert node.calculate(-1, 0, "degrees")[0] == pytest.approx(-90.0)
assert node.calculate(0, -1, "degrees")[0] == pytest.approx(180.0)
def test_math_sqrt():
node = MathSqrt()
assert node.calculate(4) == (2.0,)
assert node.calculate(0) == (0.0,)
with pytest.raises(ValueError): # Negative numbers
# Test with string input
assert node.calculate("9")[0] == pytest.approx(3.0)
# Test with float input
assert node.calculate(2.25)[0] == pytest.approx(1.5)
# Test negative numbers (should raise ValueError)
with pytest.raises(ValueError):
node.calculate(-1)
@@ -70,6 +114,10 @@ def test_math_exp():
assert node.calculate(0) == (1.0,)
assert node.calculate(1) == (math.e,)
assert node.calculate(-1) == (1 / math.e,)
# Test with string input
assert node.calculate("2")[0] == pytest.approx(math.exp(2))
# Test with large input
assert node.calculate(10)[0] == pytest.approx(math.exp(10))
def test_math_log():
@@ -77,16 +125,30 @@ def test_math_log():
assert node.calculate(1) == (0.0,)
assert node.calculate(math.e) == (1.0,)
assert node.calculate(8, base=2) == (3.0,)
with pytest.raises(ValueError): # Log of non-positive
# Test with string input
assert node.calculate("10", base="10")[0] == pytest.approx(1.0)
# Test with default base (e)
assert node.calculate(math.exp(5))[0] == pytest.approx(5.0)
# Test with log of non-positive (should raise ValueError)
with pytest.raises(ValueError):
node.calculate(-1)
with pytest.raises(ValueError):
node.calculate(0)
def test_math_log10():
node = MathLog10()
assert node.calculate(1) == (0.0,)
assert node.calculate(10) == (1.0,)
with pytest.raises(ValueError): # Log of non-positive
# Test with string input
assert node.calculate("100")[0] == pytest.approx(2.0)
# Test with non-integer values
assert node.calculate(2)[0] == pytest.approx(math.log10(2))
# Test with log of non-positive (should raise ValueError)
with pytest.raises(ValueError):
node.calculate(0)
with pytest.raises(ValueError):
node.calculate(-10)
def test_math_degrees():
@@ -94,6 +156,10 @@ def test_math_degrees():
assert node.calculate(math.pi) == (180.0,)
assert node.calculate(math.pi / 2) == (90.0,)
assert node.calculate(0) == (0.0,)
# Test with string input
assert node.calculate("3.14159")[0] == pytest.approx(180.0, abs=0.01)
# Test with negative values
assert node.calculate(-math.pi)[0] == pytest.approx(-180.0)
def test_math_radians():
@@ -101,6 +167,12 @@ def test_math_radians():
assert node.calculate(180) == (math.pi,)
assert node.calculate(90) == (math.pi / 2,)
assert node.calculate(0) == (0.0,)
# Test with string input
assert node.calculate("180")[0] == pytest.approx(math.pi)
# Test with negative values
assert node.calculate(-180)[0] == pytest.approx(-math.pi)
# Test with decimal values
assert node.calculate(45.5)[0] == pytest.approx(math.radians(45.5))
def test_math_floor():
@@ -108,6 +180,12 @@ def test_math_floor():
assert node.calculate(1.7) == (1,)
assert node.calculate(-1.7) == (-2,)
assert node.calculate(0.0) == (0,)
# Test with string input
assert node.calculate("3.9")[0] == 3
# Test with integer input
assert node.calculate(5)[0] == 5
# Test with very small decimals
assert node.calculate(0.0001)[0] == 0
def test_math_ceil():
@@ -115,6 +193,12 @@ def test_math_ceil():
assert node.calculate(1.2) == (2,)
assert node.calculate(-1.2) == (-1,)
assert node.calculate(0.0) == (0,)
# Test with string input
assert node.calculate("3.1")[0] == 4
# Test with integer input
assert node.calculate(5)[0] == 5
# Test with very small decimals
assert node.calculate(0.0001)[0] == 1
def test_math_abs():
@@ -122,16 +206,26 @@ def test_math_abs():
assert node.calculate(-5) == (5,)
assert node.calculate(5) == (5,)
assert node.calculate(0) == (0,)
# Test with string input
assert node.calculate("-3.14")[0] == pytest.approx(3.14)
# Test with float input
assert node.calculate(-2.5)[0] == 2.5
# Test with zero
assert node.calculate(0)[0] == 0
def test_math_pi():
node = MathPi()
assert node.calculate() == (math.pi,)
# Verify precision to at least 10 decimal places
assert abs(node.calculate()[0] - 3.1415926535) < 1e-10
def test_math_e():
node = MathE()
assert node.calculate() == (math.e,)
# Verify precision to at least 10 decimal places
assert abs(node.calculate()[0] - 2.7182818284) < 1e-10
def test_math_min():
@@ -139,6 +233,12 @@ def test_math_min():
assert node.calculate(5, 10) == (5,)
assert node.calculate(-1, 0) == (-1,)
assert node.calculate(3.5, 2.5) == (2.5,)
# Test with string inputs
assert node.calculate("7", "3")[0] == 3.0
# Test with mixed types
assert node.calculate(5, "2.5")[0] == 2.5
# Test with equal values
assert node.calculate(10, 10)[0] == 10
def test_math_max():
@@ -146,3 +246,9 @@ def test_math_max():
assert node.calculate(5, 10) == (10,)
assert node.calculate(-1, 0) == (0,)
assert node.calculate(3.5, 2.5) == (3.5,)
# Test with string inputs
assert node.calculate("7", "3")[0] == 7.0
# Test with mixed types
assert node.calculate(5, "7.5")[0] == 7.5
# Test with equal values
assert node.calculate(10, 10)[0] == 10
+228 -6
View File
@@ -1,5 +1,7 @@
import os
import pytest
import platform
from pathlib import Path
from src.basic_data_handling.path_nodes import (
PathJoin, PathAbspath, PathExists, PathIsFile, PathIsDir, PathGetSize,
@@ -14,21 +16,38 @@ def test_path_join():
assert node.join_paths("folder", "file.txt") == (os.path.join("folder", "file.txt"),)
assert node.join_paths("folder", "") == (os.path.join("folder"),)
assert node.join_paths(".", "") == (".",)
# Test join with empty first path
assert node.join_paths("", "file.txt") == ("file.txt",)
# Test with multiple path components
nested_path = os.path.join("folder", "subfolder", "file.txt")
assert node.join_paths("folder", os.path.join("subfolder", "file.txt")) == (nested_path,)
def test_path_abspath():
node = PathAbspath()
assert node.get_abspath(".") == (os.path.abspath("."),)
assert node.get_abspath("folder/file.txt") == (os.path.abspath("folder/file.txt"),)
# Test with empty string (should return current directory)
assert node.get_abspath("") == (os.path.abspath(os.getcwd()),)
# Test with relative path with special characters
assert node.get_abspath("./file.txt") == (os.path.abspath("./file.txt"),)
assert node.get_abspath("../file.txt") == (os.path.abspath("../file.txt"),)
def test_path_exists(tmp_path):
node = PathExists()
existing_file = tmp_path / "file.txt"
existing_file.write_text("content")
existing_dir = tmp_path / "directory"
existing_dir.mkdir()
assert node.check_exists(str(existing_file)) == (True,)
assert node.check_exists(str(existing_dir)) == (True,)
assert node.check_exists("nonexistent.file") == (False,)
# Test with special paths
assert node.check_exists(".") == (True,)
# Test with path containing non-existent parent directory
assert node.check_exists(str(tmp_path / "nonexistent" / "file.txt")) == (False,)
def test_path_is_file(tmp_path):
@@ -41,6 +60,19 @@ def test_path_is_file(tmp_path):
assert node.check_is_file(str(file)) == (True,)
assert node.check_is_file(str(directory)) == (False,)
assert node.check_is_file("nonexistent.file") == (False,)
# Test with empty path
assert node.check_is_file("") == (False,)
# Test with special paths
assert node.check_is_file(".") == (False,)
# Test with symlink to file if platform supports
if hasattr(os, 'symlink'):
try:
symlink = tmp_path / "symlink.txt"
os.symlink(str(file), str(symlink))
assert node.check_is_file(str(symlink)) == (True,)
except (OSError, NotImplementedError):
# Symlinks might not be supported on all platforms
pass
def test_path_is_dir(tmp_path):
@@ -53,14 +85,36 @@ def test_path_is_dir(tmp_path):
assert node.check_is_dir(str(directory)) == (True,)
assert node.check_is_dir(str(file)) == (False,)
assert node.check_is_dir("nonexistent.dir") == (False,)
# Test with special paths
assert node.check_is_dir(".") == (True,)
assert node.check_is_dir("") == (False,)
# Test with nested directory
nested_dir = directory / "nested"
nested_dir.mkdir()
assert node.check_is_dir(str(nested_dir)) == (True,)
# Test with symlink to directory if platform supports
if hasattr(os, 'symlink'):
try:
symlink = tmp_path / "symlink_dir"
os.symlink(str(directory), str(symlink), target_is_directory=True)
assert node.check_is_dir(str(symlink)) == (True,)
except (OSError, NotImplementedError, TypeError):
# Symlinks might not be supported on all platforms
pass
def test_path_get_size(tmp_path):
node = PathGetSize()
file = tmp_path / "file.txt"
file.write_text("content")
empty_file = tmp_path / "empty.txt"
empty_file.write_text("")
large_file = tmp_path / "large.txt"
large_file.write_text("a" * 1024) # 1KB file
assert node.get_size(str(file)) == (len("content"),)
assert node.get_size(str(empty_file)) == (0,)
assert node.get_size(str(large_file)) == (1024,)
with pytest.raises(FileNotFoundError):
node.get_size("nonexistent.file")
@@ -78,36 +132,88 @@ def test_path_split():
assert node.split_path(path) == (os.path.dirname(path), os.path.basename(path))
assert node.split_path("file.txt") == ("", "file.txt")
# Test with empty path
assert node.split_path("") == ("", "")
# Test with just directory separator
assert node.split_path("/") == ("/", "")
# Test with nested paths
nested_path = os.path.join("folder", "subfolder", "file.txt")
assert node.split_path(nested_path) == (os.path.dirname(nested_path), "file.txt")
# Test with trailing separator
dir_with_sep = "folder" + os.sep
assert node.split_path(dir_with_sep) == ("folder", "")
def test_path_splitext():
node = PathSplitExt()
assert node.split_ext("file.txt") == ("file", ".txt")
assert node.split_ext("file") == ("file", "")
# Test with multiple extensions
assert node.split_ext("file.tar.gz") == ("file.tar", ".gz")
# Test with path containing directory
path = os.path.join("folder", "file.txt")
assert node.split_ext(path) == (os.path.join("folder", "file"), ".txt")
# Test with hidden file
assert node.split_ext(".gitignore") == (".gitignore", "")
# Test with empty string
assert node.split_ext("") == ("", "")
def test_path_basename():
node = PathBasename()
assert node.get_basename("folder/file.txt") == ("file.txt",)
assert node.get_basename("file.txt") == ("file.txt",)
# Test with trailing slash
assert node.get_basename("folder/") == ("",)
# Test with empty path
assert node.get_basename("") == ("",)
# Test with root directory
assert node.get_basename("/") == ("",)
# Test with multiple nested directories
assert node.get_basename("folder/subfolder/file.txt") == ("file.txt",)
def test_path_dirname():
node = PathDirname()
assert node.get_dirname("folder/file.txt") == ("folder",)
assert node.get_dirname("file.txt") == ("",)
# Test with trailing slash
assert node.get_dirname("folder/") == ("folder",)
# Test with empty path
assert node.get_dirname("") == ("",)
# Test with root directory
assert node.get_dirname("/") == ("/",)
# Test with nested directories
assert node.get_dirname("folder/subfolder/file.txt") == (os.path.join("folder", "subfolder"),)
def test_path_get_extension():
node = PathGetExtension()
assert node.get_extension("file.txt") == (".txt",)
assert node.get_extension("file") == ("",)
# Test with multiple dots
assert node.get_extension("file.tar.gz") == (".gz",)
# Test with hidden file
assert node.get_extension(".gitignore") == ("",)
# Test with path containing directory
assert node.get_extension("folder/file.txt") == (".txt",)
# Test with empty string
assert node.get_extension("") == ("",)
def test_path_normalize():
node = PathNormalize()
assert node.normalize_path("folder/../file.txt") == (os.path.normpath("folder/../file.txt"),)
assert node.normalize_path("folder//file.txt") == (os.path.normpath("folder//file.txt"),)
# Test with empty path
assert node.normalize_path("") == (".",)
# Test with current directory references
assert node.normalize_path("./folder/./file.txt") == (os.path.normpath("./folder/./file.txt"),)
# Test with parent directory references that cancel out
assert node.normalize_path("folder/../folder/file.txt") == (os.path.normpath("folder/../folder/file.txt"),)
# Test with mixed separators
mixed_sep_path = "folder" + os.sep + "subfolder" + ("/" if os.sep == "\\" else "\\") + "file.txt"
assert node.normalize_path(mixed_sep_path) == (os.path.normpath(mixed_sep_path),)
def test_path_relative(tmp_path):
@@ -119,6 +225,16 @@ def test_path_relative(tmp_path):
assert node.get_relative_path(str(target), str(start)) == (os.path.relpath(str(target), str(start)),)
assert node.get_relative_path(str(target)) == (os.path.relpath(str(target), os.getcwd()),)
# Test with same path
assert node.get_relative_path(str(start), str(start)) == (".",)
# Test with sibling paths
sibling = tmp_path / "sibling"
sibling.mkdir()
expected = os.path.relpath(str(sibling), str(start))
assert node.get_relative_path(str(sibling), str(start)) == (expected,)
# Test with parent directory
parent_rel = os.path.relpath(str(tmp_path), str(target))
assert node.get_relative_path(str(tmp_path), str(target)) == (parent_rel,)
def test_path_glob(tmp_path):
@@ -126,56 +242,162 @@ def test_path_glob(tmp_path):
(tmp_path / "file1.txt").write_text("content")
(tmp_path / "file2.txt").write_text("content")
(tmp_path / "file3.txt").write_text("content")
(tmp_path / "image1.jpg").write_text("image")
(tmp_path / "image2.png").write_text("image")
# Create subdirectory with files
subdir = tmp_path / "subdir"
subdir.mkdir()
(subdir / "subfile1.txt").write_text("sub content")
(subdir / "subfile2.txt").write_text("sub content")
# Test simple glob pattern
result = node.glob_paths(str(tmp_path / "*.txt"))
expected = sorted([str(tmp_path / f"file{i}.txt") for i in range(1, 4)])
assert sorted(result[0]) == expected
recursive_node = PathGlob()
assert recursive_node.glob_paths(str(tmp_path), recursive="True")[0]
# Test with image files
img_result = node.glob_paths(str(tmp_path / "image*"))
img_expected = sorted([str(tmp_path / "image1.jpg"), str(tmp_path / "image2.png")])
assert sorted(img_result[0]) == img_expected
# Test with character class
char_result = node.glob_paths(str(tmp_path / "file[1-2].txt"))
char_expected = sorted([str(tmp_path / f"file{i}.txt") for i in range(1, 3)])
assert sorted(char_result[0]) == char_expected
# Test recursive globbing
recursive_result = node.glob_paths(str(tmp_path / "**/*.txt"), recursive=True)
recursive_expected = sorted([
str(tmp_path / f"file{i}.txt") for i in range(1, 4)
] + [
str(subdir / f"subfile{i}.txt") for i in range(1, 3)
])
assert sorted(recursive_result[0]) == recursive_expected
# Test with no matches
no_match_result = node.glob_paths(str(tmp_path / "nomatch*.txt"))
assert len(no_match_result[0]) == 0
def test_path_expand_vars(monkeypatch):
node = PathExpandVars()
monkeypatch.setenv("TEST_VAR", "test_value")
monkeypatch.setenv("PATH_VAR", "path/to/somewhere")
monkeypatch.setenv("EMPTY_VAR", "")
assert node.expand_vars("$TEST_VAR/path") == ("test_value/path",)
assert node.expand_vars("${TEST_VAR}/path") == ("test_value/path",)
# Test with multiple variables
assert node.expand_vars("$TEST_VAR/$PATH_VAR") == ("test_value/path/to/somewhere",)
# Test with empty variable
assert node.expand_vars("$EMPTY_VAR/path") == ("/path",)
# Test with no variables
assert node.expand_vars("regular/path") == ("regular/path",)
# Test with empty string
assert node.expand_vars("") == ("",)
def test_path_get_cwd():
node = PathGetCwd()
assert node.get_cwd() == (os.getcwd(),)
# Verify that the result is an absolute path
assert os.path.isabs(node.get_cwd()[0])
# Verify that the directory exists
assert os.path.exists(node.get_cwd()[0])
assert os.path.isdir(node.get_cwd()[0])
def test_path_list_dir(tmp_path):
node = PathListDir()
# Set up a directory structure for testing
(tmp_path / "file1.txt").write_text("content")
(tmp_path / "file2.txt").write_text("content")
(tmp_path / "image.jpg").write_text("image")
(tmp_path / "dir1").mkdir()
(tmp_path / "dir2").mkdir()
(tmp_path / ".hidden_file").write_text("hidden")
(tmp_path / ".hidden_dir").mkdir()
# Test listing all entries
all_entries = node.list_directory(str(tmp_path))
assert "file1.txt" in all_entries[0]
assert "file2.txt" in all_entries[0]
assert "image.jpg" in all_entries[0]
assert "dir1" in all_entries[0]
assert "dir2" in all_entries[0]
assert ".hidden_file" in all_entries[0]
assert ".hidden_dir" in all_entries[0]
only_files = node.list_directory(str(tmp_path), files_only="True")
# Test listing only files
only_files = node.list_directory(str(tmp_path), files_only=True)
assert "file1.txt" in only_files[0]
assert "file2.txt" in only_files[0]
assert "image.jpg" in only_files[0]
assert ".hidden_file" in only_files[0]
assert "dir1" not in only_files[0]
assert "dir2" not in only_files[0]
assert ".hidden_dir" not in only_files[0]
only_dirs = node.list_directory(str(tmp_path), dirs_only="True")
# Test listing only directories
only_dirs = node.list_directory(str(tmp_path), dirs_only=True)
assert "file1.txt" not in only_dirs[0]
assert "file2.txt" not in only_dirs[0]
assert "image.jpg" not in only_dirs[0]
assert ".hidden_file" not in only_dirs[0]
assert "dir1" in only_dirs[0]
assert "dir2" in only_dirs[0]
assert ".hidden_dir" in only_dirs[0]
# Test with non-existent directory
with pytest.raises(FileNotFoundError):
node.list_directory(str(tmp_path / "nonexistent"))
# Test with file instead of directory
with pytest.raises(NotADirectoryError):
node.list_directory(str(tmp_path / "file1.txt"))
# Test with empty path (should use current directory)
assert len(node.list_directory("")[0]) > 0
def test_path_is_absolute():
node = PathIsAbsolute()
# Test with absolute paths
assert node.check_is_absolute("/") == (True,)
assert node.check_is_absolute(os.path.abspath(".")) == (True,)
# Test with relative paths
assert node.check_is_absolute("relative/path") == (False,)
assert node.check_is_absolute("./path") == (False,)
assert node.check_is_absolute("../path") == (False,)
# Test with empty path
assert node.check_is_absolute("") == (False,)
# Test Windows-specific paths if applicable
if platform.system() == "Windows":
assert node.check_is_absolute("C:\\Windows") == (True,)
assert node.check_is_absolute("C:/Windows") == (True,)
assert node.check_is_absolute("\\\\server\\share") == (True,)
assert node.check_is_absolute("C:relative\\path") == (False,)
def test_path_common_prefix():
node = PathCommonPrefix()
# Test with paths having common prefix
path1 = "/path/to/file1.txt"
path2 = "/path/to/file2.txt"
assert node.get_common_prefix(path1, path2) == ("/path/to/file",)
assert node.get_common_prefix(path1, path2) == (os.path.commonprefix([path1, path2]),)
# Test with paths without common prefix
path3 = "/path/to/file.txt"
path4 = "/different/path/file.txt"
assert node.get_common_prefix(path3, path4) == ("/",)
# Test with exact same paths
assert node.get_common_prefix(path1, path1) == (path1,)
# Test with one path being a prefix of the other
path5 = "/path/to"
path6 = "/path/to/subdir/file.txt"
assert node.get_common_prefix(path5, path6) == ("/path/to",)
# Test with both empty paths
assert node.get_common_prefix("", "") == ("",)
+61 -1
View File
@@ -5,7 +5,10 @@ from src.basic_data_handling.regex_nodes import (
RegexFindallDataList,
RegexSplitDataList,
RegexSub,
RegexTest
RegexTest,
RegexFindallList,
RegexSearchGroupsList,
RegexSplitList
)
def test_regex_search_groups():
@@ -16,6 +19,46 @@ def test_regex_search_groups():
assert node.search_groups(r"(\w+)", "word") == (["word"],) # Single group
def test_regex_search_groups_list():
node = RegexSearchGroupsList()
assert node.search_groups(r"(foo)(bar)", "foobar") == (["foo", "bar"],)
assert node.search_groups(r"(test)(\d+)", "test123") == (["test", "123"],)
assert node.search_groups(r"(nothing)", "no match here") == ([],) # No match
assert node.search_groups(r"(\w+)", "word") == (["word"],) # Single group
def test_regex_search_groups_list():
node = RegexSearchGroupsList()
assert node.search_groups(r"(foo)(bar)", "foobar") == (["foo", "bar"],)
assert node.search_groups(r"(test)(\d+)", "test123") == (["test", "123"],)
assert node.search_groups(r"(nothing)", "no match here") == ([],) # No match
assert node.search_groups(r"(\w+)", "word") == (["word"],) # Single group
def test_regex_search_groups_list():
node = RegexSearchGroupsList()
assert node.search_groups(r"(foo)(bar)", "foobar") == (["foo", "bar"],)
assert node.search_groups(r"(test)(\d+)", "test123") == (["test", "123"],)
assert node.search_groups(r"(nothing)", "no match here") == ([],) # No match
assert node.search_groups(r"(\w+)", "word") == (["word"],) # Single group
def test_regex_search_groups_list():
node = RegexSearchGroupsList()
assert node.search_groups(r"(foo)(bar)", "foobar") == (["foo", "bar"],)
assert node.search_groups(r"(test)(\d+)", "test123") == (["test", "123"],)
assert node.search_groups(r"(nothing)", "no match here") == ([],) # No match
assert node.search_groups(r"(\w+)", "word") == (["word"],) # Single group
def test_regex_search_groups_list():
node = RegexSearchGroupsList()
assert node.search_groups(r"(foo)(bar)", "foobar") == (["foo", "bar"],)
assert node.search_groups(r"(test)(\d+)", "test123") == (["test", "123"],)
assert node.search_groups(r"(nothing)", "no match here") == ([],) # No match
assert node.search_groups(r"(\w+)", "word") == (["word"],) # Single group
def test_regex_group_dict():
node = RegexGroupDict()
pattern = r"(?P<word>\w+)-(?P<number>\d+)"
@@ -33,6 +76,14 @@ def test_regex_findall():
assert node.findall(r"(a)(b)", "ab ab") == ([("a", "b"), ("a", "b")],) # Multiple groups
def test_regex_findall_list():
node = RegexFindallList()
assert node.findall(r"\d+", "abc 123 def 456") == (["123", "456"],)
assert node.findall(r"\b[a-zA-Z]+\b", "Multiple words here") == (["Multiple", "words", "here"],)
assert node.findall(r"nonexistent", "no match") == ([],) # No match
assert node.findall(r"(a)(b)", "ab ab") == ([("a", "b"), ("a", "b")],) # Multiple groups
def test_regex_split():
node = RegexSplitDataList()
pattern = r",\s*"
@@ -42,6 +93,15 @@ def test_regex_split():
assert node.split(r"z", "nozsplit") == (["no", "split"],) # Split by 'z'
def test_regex_split_list():
node = RegexSplitList()
pattern = r",\s*"
string = "one, two, three"
assert node.split(pattern, string) == (["one", "two", "three"],)
assert node.split(r"\s+", "split several words") == (["split", "several", "words"],) # Whitespace split
assert node.split(r"z", "nozsplit") == (["no", "split"],) # Split by 'z'
def test_regex_sub():
node = RegexSub()
assert node.sub(r"cat", "dog", "cat is here") == ("dog is here",)
+52 -1
View File
@@ -13,9 +13,52 @@ from src.basic_data_handling.set_nodes import (
SetIsDisjoint,
SetContains,
SetLength,
SetToList
SetToList,
SetCreate,
SetToDataList,
SetCreateFromInt,
SetCreateFromString,
SetCreateFromFloat,
SetCreateFromBoolean
)
def test_set_create():
node = SetCreate()
# Testing with kwargs to simulate dynamic inputs
assert node.create_set(item_0=1, item_1=2, item_2=3) == ({1, 2, 3},)
assert node.create_set(item_0="a", item_1="b") == ({"a", "b"},)
assert node.create_set() == (set(),) # Empty set with no arguments
def test_set_create_from_int():
node = SetCreateFromInt()
assert node.create_set(item_0=1, item_1=2, item_2=3) == ({1, 2, 3},)
assert node.create_set(item_0=5) == ({5},) # Single item set
assert node.create_set(item_0=1, item_1=1) == ({1},) # Duplicate items become single item
def test_set_create_from_string():
node = SetCreateFromString()
# Note: Mocking the string function behavior as it's not defined in the file
# This simulates what would happen assuming string() acts like str()
node.create_set = lambda **kwargs: (set([str(value) for value in kwargs.values()]),)
assert node.create_set(item_0="apple", item_1="banana") == ({"apple", "banana"},)
assert node.create_set(item_0="apple", item_1="apple") == ({"apple"},) # Duplicate strings
def test_set_create_from_float():
node = SetCreateFromFloat()
assert node.create_set(item_0=1.5, item_1=2.5) == ({1.5, 2.5},)
assert node.create_set(item_0=3.14) == ({3.14},) # Single item set
assert node.create_set(item_0=1.0, item_1=1.0) == ({1.0},) # Duplicate items
def test_set_create_from_boolean():
node = SetCreateFromBoolean()
assert node.create_set(item_0=True, item_1=False) == ({True, False},)
assert node.create_set(item_0=True, item_1=True) == ({True},) # Duplicate booleans
def test_set_add():
node = SetAdd()
assert node.add({1, 2}, 3) == ({1, 2, 3},)
@@ -108,3 +151,11 @@ def test_set_to_list():
result = node.convert({1, 2, 3})
assert isinstance(result, tuple)
assert sorted(result[0]) == [1, 2, 3] # Validate conversion to list
def test_set_to_data_list():
node = SetToDataList()
result = node.convert({1, 2, 3})
assert isinstance(result, tuple)
assert isinstance(result[0], list)
assert sorted(result[0]) == [1, 2, 3] # Validate conversion to data list