test(helpers): add comprehensive teists for dependency collection

- Test closure variable detection (helpers, constants, imports)
- Test nested dependency resolution and ordering
- Test class definitions and decorator removal
- Test import style preservation
- Test caching mechanism
This commit is contained in:
synacktra.work@gmail.com
2025-12-17 01:12:38 +05:30
parent e7be69d5cd
commit efcb370a55

View File

@@ -0,0 +1,478 @@
from computer.helpers import generate_source_code
class TestSimpleCases:
"""Test simple dependency cases"""
def test_simple_function_no_dependencies(self):
"""Test simple function with no dependencies"""
def simple_func():
return 42
code = generate_source_code(simple_func)
assert "def simple_func():" in code
assert "return 42" in code
def test_function_with_parameters(self):
"""Test function with parameters"""
def add(a, b):
return a + b
code = generate_source_code(add)
assert "def add(a, b):" in code
assert "return a + b" in code
def test_function_with_docstring(self):
"""Test function with docstring"""
def documented():
"""This is a docstring"""
return True
code = generate_source_code(documented)
assert "def documented():" in code
assert "This is a docstring" in code
class TestImports:
"""Test import handling"""
def test_stdlib_import_inside_function(self):
"""Test function with stdlib import inside"""
def with_stdlib():
import math
return math.sqrt(16)
code = generate_source_code(with_stdlib)
assert "import math" in code
assert "def with_stdlib():" in code
assert "math.sqrt(16)" in code
def test_multiple_stdlib_imports(self):
"""Test function with multiple stdlib imports"""
def with_multiple():
import json
import math
return json.dumps({"value": math.pi})
code = generate_source_code(with_multiple)
assert "import json" in code
assert "import math" in code
def test_from_import_stdlib(self):
"""Test from X import Y style"""
def with_from_import():
from math import pi, sqrt
return sqrt(16) + pi
code = generate_source_code(with_from_import)
assert "from math import" in code
assert "sqrt, pi" in code or ("sqrt" in code and "pi" in code)
def test_third_party_global_import(self):
"""Test globally imported third-party module"""
from requests import get
def with_requests():
return get
code = generate_source_code(with_requests)
assert "from requests import get" in code
assert "def with_requests():" in code
class TestHelperFunctions:
"""Test helper function dependencies"""
def test_single_helper_function(self):
"""Test function with one helper"""
def helper(x):
return x * 2
def main():
return helper(21)
code = generate_source_code(main)
assert "def helper(x):" in code
assert "return x * 2" in code
assert "def main():" in code
assert "return helper(21)" in code
def test_nested_helper_functions(self):
"""Test function with nested helpers"""
def helper_a(x):
return x + 1
def helper_b(x):
return helper_a(x) * 2
def main():
return helper_b(10)
code = generate_source_code(main)
assert "def helper_a(x):" in code
assert "def helper_b(x):" in code
assert "def main():" in code
def test_helper_dependency_ordering(self):
"""Test that helpers are ordered correctly (dependencies first)"""
def level_3(x):
return x + 1
def level_2(x):
return level_3(x) * 2
def level_1(x):
return level_2(x) + 5
code = generate_source_code(level_1)
# Check ordering
pos_3 = code.find("def level_3")
pos_2 = code.find("def level_2")
pos_1 = code.find("def level_1")
assert pos_3 < pos_2 < pos_1, "Functions not in correct dependency order"
def test_helper_with_import(self):
"""Test helper function that uses imports"""
import math
def helper(x):
return math.sqrt(x)
def main():
return helper(16)
code = generate_source_code(main)
assert "import math" in code
assert "def helper(x):" in code
assert "def main():" in code
class TestGlobalConstants:
"""Test global constant handling"""
def test_simple_constant(self):
"""Test function using simple constant"""
MY_CONSTANT = 42
def with_constant():
return MY_CONSTANT * 2
code = generate_source_code(with_constant)
assert "MY_CONSTANT = 42" in code
assert "def with_constant():" in code
def test_string_constant(self):
"""Test function using string constant"""
API_URL = "https://api.example.com"
def with_string():
return API_URL
code = generate_source_code(with_string)
assert "API_URL" in code
assert "https://api.example.com" in code
def test_multiple_constants(self):
"""Test function using multiple constants"""
BASE_URL = "https://example.com"
TIMEOUT = 30
def with_multiple():
return f"{BASE_URL}?timeout={TIMEOUT}"
code = generate_source_code(with_multiple)
assert "BASE_URL" in code
assert "TIMEOUT" in code
class TestClassDefinitions:
"""Test class definition handling"""
def test_simple_class(self):
"""Test function using simple class"""
class Calculator:
def __init__(self, value):
self.value = value
def add(self, x):
return self.value + x
def with_class():
calc = Calculator(10)
return calc.add(5)
code = generate_source_code(with_class)
assert "class Calculator:" in code
assert "__init__" in code
assert "def add" in code
assert "def with_class():" in code
def test_class_with_methods(self):
"""Test class with multiple methods"""
class Math:
def add(self, a, b):
return a + b
def multiply(self, a, b):
return a * b
def use_math():
m = Math()
return m.add(2, 3) + m.multiply(4, 5)
code = generate_source_code(use_math)
assert "class Math:" in code
assert "def add" in code
assert "def multiply" in code
class TestDecoratorRemoval:
"""Test decorator removal"""
def test_simple_decorator_removed(self):
"""Test that decorators are removed"""
def my_decorator(f):
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wrapper
@my_decorator
def decorated():
return 42
code = generate_source_code(decorated)
assert "@my_decorator" not in code
assert "def decorated():" in code
assert "return 42" in code
def test_multiple_decorators_removed(self):
"""Test that multiple decorators are removed"""
def decorator1(f):
return f
def decorator2(f):
return f
@decorator1
@decorator2
def multi_decorated():
return True
code = generate_source_code(multi_decorated)
assert "@decorator1" not in code
assert "@decorator2" not in code
assert "def multi_decorated():" in code
class TestComplexScenarios:
"""Test complex real-world scenarios"""
def test_api_client_pattern(self):
"""Test typical API client pattern"""
import json
BASE_URL = "https://api.example.com"
def make_request(endpoint):
return f"{BASE_URL}/{endpoint}"
def parse_response(response):
return json.loads(response)
def get_user(user_id):
url = make_request(f"users/{user_id}")
response = f'{{"id": {user_id}}}'
return parse_response(response)
code = generate_source_code(get_user)
assert "import json" in code
assert "BASE_URL" in code
assert "def make_request" in code
assert "def parse_response" in code
assert "def get_user" in code
def test_data_processing_pipeline(self):
"""Test data processing pipeline"""
def validate_data(data):
return [x for x in data if x > 0]
def transform_data(data):
return [x * 2 for x in data]
def process_pipeline(raw_data):
valid = validate_data(raw_data)
return transform_data(valid)
code = generate_source_code(process_pipeline)
assert "def validate_data" in code
assert "def transform_data" in code
assert "def process_pipeline" in code
# Check ordering
validate_pos = code.find("def validate_data")
transform_pos = code.find("def transform_data")
pipeline_pos = code.find("def process_pipeline")
assert validate_pos < pipeline_pos
assert transform_pos < pipeline_pos
class TestEdgeCases:
"""Test edge cases"""
def test_function_with_default_args(self):
"""Test function with default arguments"""
def with_defaults(a, b=10, c=20):
return a + b + c
code = generate_source_code(with_defaults)
assert "def with_defaults(a, b=10, c=20):" in code
def test_function_with_kwargs(self):
"""Test function with *args and **kwargs"""
def with_varargs(*args, **kwargs):
return sum(args)
code = generate_source_code(with_varargs)
assert "def with_varargs(*args, **kwargs):" in code
def test_async_function(self):
"""Test async function"""
async def async_func():
return 42
code = generate_source_code(async_func)
assert "async def async_func():" in code
assert "return 42" in code
def test_lambda_works_in_files(self):
"""Test that lambda functions work when defined in files"""
lambda_func = lambda x: x * 2
# Lambda functions defined in files CAN have their source extracted
code = generate_source_code(lambda_func)
# Should include the lambda
assert "lambda" in code.lower() or "lambda_func" in code
class TestCaching:
"""Test caching mechanism"""
def test_cache_returns_same_result(self):
"""Test that cache returns identical results"""
def cached_func():
return 42
code1 = generate_source_code(cached_func)
code2 = generate_source_code(cached_func)
assert code1 == code2
def test_different_functions_different_cache(self):
"""Test that different functions have different cache entries"""
def func1():
return 1
def func2():
return 2
code1 = generate_source_code(func1)
code2 = generate_source_code(func2)
assert code1 != code2
assert "return 1" in code1
assert "return 2" in code2
class TestBuiltinHandling:
"""Test that builtins are handled correctly"""
def test_builtin_not_included(self):
"""Test that builtin functions are not included as dependencies"""
def uses_builtins():
data = list(range(10))
return len(data)
code = generate_source_code(uses_builtins)
# Should not include definitions for list, range, len
assert "def list" not in code
assert "def range" not in code
assert "def len" not in code
assert "def uses_builtins():" in code
class TestImportStylePreservation:
"""Test that import styles are preserved"""
def test_from_import_preserved(self):
"""Test from X import Y is preserved"""
from math import sqrt
def use_sqrt():
return sqrt(16)
code = generate_source_code(use_sqrt)
assert "from math import sqrt" in code
def test_import_as_preserved(self):
"""Test import X as Y is preserved"""
import json as j
def use_json():
return j.dumps({"key": "value"})
code = generate_source_code(use_json)
# The import style should be preserved
assert "import json" in code