|
| 1 | +from codegen.sdk.codebase.factory.get_session import get_codebase_session |
| 2 | +from codegen.sdk.core.dataclasses.usage import UsageType |
| 3 | +from codegen.sdk.enums import ProgrammingLanguage |
| 4 | + |
| 5 | + |
| 6 | +def test_dependencies_with_depth(tmpdir): |
| 7 | + """Test that dependencies property and get_dependencies_to_depth respect depth parameter.""" |
| 8 | + py_code = """ |
| 9 | +class A: |
| 10 | + def method_a(self): |
| 11 | + pass |
| 12 | +
|
| 13 | +class B(A): |
| 14 | + def method_b(self): |
| 15 | + self.method_a() |
| 16 | +
|
| 17 | +class C(B): |
| 18 | + def method_c(self): |
| 19 | + self.method_b() |
| 20 | +
|
| 21 | +def use_c(): |
| 22 | + return C() |
| 23 | +""" |
| 24 | + with get_codebase_session(tmpdir=tmpdir, programming_language=ProgrammingLanguage.PYTHON, files={"test.py": py_code}) as G: |
| 25 | + use_c_func = G.get_function("use_c") |
| 26 | + c_class = G.get_class("C") |
| 27 | + b_class = G.get_class("B") |
| 28 | + a_class = G.get_class("A") |
| 29 | + |
| 30 | + # Test direct dependencies (depth=1) |
| 31 | + direct_deps = c_class.get_dependencies_to_depth(depth=1) |
| 32 | + assert len(direct_deps) == 1 |
| 33 | + assert direct_deps[0] == b_class |
| 34 | + |
| 35 | + # Test two levels of dependencies (depth=2) |
| 36 | + two_level_deps = c_class.get_dependencies_to_depth(depth=2) |
| 37 | + assert len(two_level_deps) == 2 |
| 38 | + assert b_class in two_level_deps |
| 39 | + assert a_class in two_level_deps |
| 40 | + |
| 41 | + # Test unlimited depth (depth=None) |
| 42 | + all_deps = c_class.get_dependencies_to_depth() |
| 43 | + assert len(all_deps) == 2 |
| 44 | + assert b_class in all_deps |
| 45 | + assert a_class in all_deps |
| 46 | + |
| 47 | + # Test that default dependencies property returns all dependencies |
| 48 | + default_deps = c_class.dependencies |
| 49 | + assert set(default_deps) == set(all_deps) |
| 50 | + |
| 51 | + |
| 52 | +def test_dependencies_with_imports(tmpdir): |
| 53 | + """Test that dependencies property and get_dependencies_to_depth handle imports correctly.""" |
| 54 | + py_code = """ |
| 55 | +from typing import Optional |
| 56 | +
|
| 57 | +class MyClass: |
| 58 | + def __init__(self, value: Optional[str] = None): |
| 59 | + self.value = value |
| 60 | +""" |
| 61 | + with get_codebase_session(tmpdir=tmpdir, programming_language=ProgrammingLanguage.PYTHON, files={"test.py": py_code}) as G: |
| 62 | + my_class = G.get_class("MyClass") |
| 63 | + |
| 64 | + # Test that imports are included in dependencies |
| 65 | + deps = my_class.get_dependencies_to_depth(depth=1) |
| 66 | + assert len(deps) == 2 # Optional and str |
| 67 | + assert any(dep.name == "Optional" for dep in deps) |
| 68 | + assert any(dep.name == "str" for dep in deps) |
| 69 | + |
| 70 | + # Test that default dependencies property includes imports |
| 71 | + all_deps = my_class.dependencies |
| 72 | + assert len(all_deps) == 2 |
| 73 | + assert any(dep.name == "Optional" for dep in all_deps) |
| 74 | + assert any(dep.name == "str" for dep in all_deps) |
| 75 | + |
| 76 | + |
| 77 | +def test_backward_compatibility(tmpdir): |
| 78 | + """Test that get_dependencies method still works for backward compatibility.""" |
| 79 | + py_code = """ |
| 80 | +from typing import Optional |
| 81 | +
|
| 82 | +class MyClass: |
| 83 | + def __init__(self, value: Optional[str] = None): |
| 84 | + self.value = value |
| 85 | +""" |
| 86 | + with get_codebase_session(tmpdir=tmpdir, programming_language=ProgrammingLanguage.PYTHON, files={"test.py": py_code}) as G: |
| 87 | + my_class = G.get_class("MyClass") |
| 88 | + |
| 89 | + # Test that get_dependencies with DIRECT usage type works |
| 90 | + direct_deps = my_class.get_dependencies(UsageType.DIRECT) |
| 91 | + assert len(direct_deps) == 2 |
| 92 | + assert any(dep.name == "Optional" for dep in direct_deps) |
| 93 | + assert any(dep.name == "str" for dep in direct_deps) |
| 94 | + |
| 95 | + # Test that get_dependencies with CHAINED usage type works |
| 96 | + chained_deps = my_class.get_dependencies(UsageType.CHAINED) |
| 97 | + assert len(chained_deps) == 0 # No chained dependencies in this example |
| 98 | + |
| 99 | + # Test that get_dependencies with combined usage types works |
| 100 | + all_deps = my_class.get_dependencies(UsageType.DIRECT | UsageType.CHAINED) |
| 101 | + assert len(all_deps) == 2 |
| 102 | + assert any(dep.name == "Optional" for dep in all_deps) |
| 103 | + assert any(dep.name == "str" for dep in all_deps) |
| 104 | + |
| 105 | + |
| 106 | +def test_zero_depth(tmpdir): |
| 107 | + """Test that depth=0 returns empty list.""" |
| 108 | + py_code = """ |
| 109 | +class A: |
| 110 | + pass |
| 111 | +
|
| 112 | +class B(A): |
| 113 | + pass |
| 114 | +""" |
| 115 | + with get_codebase_session(tmpdir=tmpdir, programming_language=ProgrammingLanguage.PYTHON, files={"test.py": py_code}) as G: |
| 116 | + b_class = G.get_class("B") |
| 117 | + |
| 118 | + # Test that depth=0 returns empty list |
| 119 | + deps = b_class.get_dependencies_to_depth(depth=0) |
| 120 | + assert len(deps) == 0 |
| 121 | + |
| 122 | + |
| 123 | +def test_cyclic_dependencies(tmpdir): |
| 124 | + """Test that dependencies property and get_dependencies_to_depth handle cyclic dependencies.""" |
| 125 | + py_code = """ |
| 126 | +class A: |
| 127 | + def method_a(self): |
| 128 | + return B() |
| 129 | +
|
| 130 | +class B: |
| 131 | + def method_b(self): |
| 132 | + return A() |
| 133 | +""" |
| 134 | + with get_codebase_session(tmpdir=tmpdir, programming_language=ProgrammingLanguage.PYTHON, files={"test.py": py_code}) as G: |
| 135 | + a_class = G.get_class("A") |
| 136 | + b_class = G.get_class("B") |
| 137 | + |
| 138 | + # Test direct dependencies |
| 139 | + a_direct_deps = a_class.get_dependencies_to_depth(depth=1) |
| 140 | + assert len(a_direct_deps) == 1 |
| 141 | + assert a_direct_deps[0] == b_class |
| 142 | + |
| 143 | + # Test that cyclic dependencies are handled properly |
| 144 | + a_all_deps = a_class.get_dependencies_to_depth() |
| 145 | + assert len(a_all_deps) == 1 |
| 146 | + assert b_class in a_all_deps |
| 147 | + |
| 148 | + # Test B's dependencies |
| 149 | + b_direct_deps = b_class.get_dependencies_to_depth(depth=1) |
| 150 | + assert len(b_direct_deps) == 1 |
| 151 | + assert b_direct_deps[0] == a_class |
0 commit comments