agent/claude/code/scripts/test_deps.py

163 lines
6.1 KiB
Python
Raw Normal View History

import io
import os
import sys
import unittest
from unittest.mock import patch, mock_open
from deps import (
parse_dependencies,
find_circular_dependencies,
print_dependency_tree,
print_reverse_dependencies,
main
)
class TestDeps(unittest.TestCase):
def setUp(self):
self.yaml_content = """
repos:
core-tenant:
depends: [core-php]
core-admin:
depends: [core-php, core-tenant]
core-php:
depends: []
core-api:
depends: [core-php]
core-analytics:
depends: [core-php, core-api]
"""
self.graph = {
'core-tenant': ['core-php'],
'core-admin': ['core-php', 'core-tenant'],
'core-php': [],
'core-api': ['core-php'],
'core-analytics': ['core-php', 'core-api'],
}
self.circular_yaml_content = """
repos:
module-a:
depends: [module-b]
module-b:
depends: [module-c]
module-c:
depends: [module-a]
"""
self.circular_graph = {
'module-a': ['module-b'],
'module-b': ['module-c'],
'module-c': ['module-a'],
}
def test_parse_dependencies(self):
with patch("builtins.open", mock_open(read_data=self.yaml_content)):
graph = parse_dependencies("dummy_path.yaml")
self.assertEqual(graph, self.graph)
def test_find_circular_dependencies(self):
cycles = find_circular_dependencies(self.circular_graph)
self.assertEqual(len(cycles), 1)
self.assertIn('module-a', cycles[0])
self.assertIn('module-b', cycles[0])
self.assertIn('module-c', cycles[0])
def test_find_no_circular_dependencies(self):
cycles = find_circular_dependencies(self.graph)
self.assertEqual(len(cycles), 0)
@patch('sys.stdout', new_callable=io.StringIO)
def test_print_dependency_tree(self, mock_stdout):
print_dependency_tree(self.graph, 'core-admin')
expected_output = (
"core-admin\n"
"├── core-php\n"
"└── core-tenant\n"
" └── core-php\n"
)
self.assertEqual(mock_stdout.getvalue().strip(), expected_output.strip())
@patch('sys.stdout', new_callable=io.StringIO)
def test_print_dependency_tree_no_deps(self, mock_stdout):
print_dependency_tree(self.graph, 'core-php')
expected_output = "core-php\n"
self.assertEqual(mock_stdout.getvalue().strip(), expected_output.strip())
@patch('sys.stdout', new_callable=io.StringIO)
def test_print_reverse_dependencies(self, mock_stdout):
print_reverse_dependencies(self.graph, 'core-php')
expected_output = (
"├── core-admin\n"
"├── core-analytics\n"
"├── core-api\n"
"└── core-tenant"
)
self.assertEqual(mock_stdout.getvalue().strip(), expected_output.strip())
@patch('sys.stdout', new_callable=io.StringIO)
def test_print_reverse_dependencies_no_deps(self, mock_stdout):
print_reverse_dependencies(self.graph, 'core-admin')
expected_output = "(no modules depend on core-admin)"
self.assertEqual(mock_stdout.getvalue().strip(), expected_output.strip())
@patch('deps.find_repos_yaml', return_value='dummy_path.yaml')
@patch('sys.stdout', new_callable=io.StringIO)
def test_main_no_args(self, mock_stdout, mock_find_yaml):
with patch("builtins.open", mock_open(read_data=self.yaml_content)):
with patch.object(sys, 'argv', ['deps.py']):
main()
output = mock_stdout.getvalue()
self.assertIn("core-admin dependencies:", output)
self.assertIn("core-tenant dependencies:", output)
@patch('deps.find_repos_yaml', return_value='dummy_path.yaml')
@patch('sys.stdout', new_callable=io.StringIO)
def test_main_module_arg(self, mock_stdout, mock_find_yaml):
with patch("builtins.open", mock_open(read_data=self.yaml_content)):
with patch.object(sys, 'argv', ['deps.py', 'core-tenant']):
main()
expected_output = (
"core-tenant dependencies:\n"
"└── core-php\n"
)
self.assertEqual(mock_stdout.getvalue().strip(), expected_output.strip())
@patch('deps.find_repos_yaml', return_value='dummy_path.yaml')
@patch('sys.stdout', new_callable=io.StringIO)
def test_main_reverse_arg(self, mock_stdout, mock_find_yaml):
with patch("builtins.open", mock_open(read_data=self.yaml_content)):
with patch.object(sys, 'argv', ['deps.py', '--reverse', 'core-api']):
main()
expected_output = (
"Modules that depend on core-api:\n"
"└── core-analytics"
)
self.assertEqual(mock_stdout.getvalue().strip(), expected_output.strip())
@patch('deps.find_repos_yaml', return_value='dummy_path.yaml')
@patch('sys.stdout', new_callable=io.StringIO)
def test_main_circular_dep(self, mock_stdout, mock_find_yaml):
with patch("builtins.open", mock_open(read_data=self.circular_yaml_content)):
with patch.object(sys, 'argv', ['deps.py']):
with self.assertRaises(SystemExit) as cm:
main()
self.assertEqual(cm.exception.code, 1)
output = mock_stdout.getvalue()
self.assertIn("Error: Circular dependencies detected!", output)
self.assertIn("module-a -> module-b -> module-c -> module-a", output)
@patch('deps.find_repos_yaml', return_value='dummy_path.yaml')
@patch('sys.stdout', new_callable=io.StringIO)
def test_main_non_existent_module(self, mock_stdout, mock_find_yaml):
with patch("builtins.open", mock_open(read_data=self.yaml_content)):
with patch.object(sys, 'argv', ['deps.py', 'non-existent-module']):
with self.assertRaises(SystemExit) as cm:
main()
self.assertEqual(cm.exception.code, 1)
output = mock_stdout.getvalue()
self.assertIn("Error: Module 'non-existent-module' not found in repos.yaml.", output)
if __name__ == '__main__':
unittest.main()