feat: add initial uipath explainator implementation
Scaffold project with pyproject.toml and environment configuration Implement core modules including CLI, Gemini integration, and scanner
This commit is contained in:
113
tests/test_pipeline.py
Normal file
113
tests/test_pipeline.py
Normal file
@@ -0,0 +1,113 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT / "src"))
|
||||
|
||||
from uipath_explainator.pipeline import ProjectPipeline
|
||||
from uipath_explainator.scanner import crawl_dependencies, extract_dependencies, strip_comment_out_blocks
|
||||
|
||||
|
||||
MAIN_XAML = """<?xml version="1.0" encoding="utf-8"?>
|
||||
<Activity xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:ui="http://schemas.uipath.com/workflow/activities">
|
||||
<Sequence>
|
||||
<ui:InvokeWorkflowFile WorkflowFileName="Flows/Active.xaml" />
|
||||
<ui:CommentOut>
|
||||
<Sequence>
|
||||
<ui:InvokeWorkflowFile WorkflowFileName="Flows/Old.xaml" />
|
||||
</Sequence>
|
||||
</ui:CommentOut>
|
||||
</Sequence>
|
||||
</Activity>
|
||||
"""
|
||||
|
||||
ACTIVE_XAML = """<?xml version="1.0" encoding="utf-8"?>
|
||||
<Activity xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:ui="http://schemas.uipath.com/workflow/activities"
|
||||
xmlns:sap2010="http://schemas.microsoft.com/netfx/2010/xaml/activities/presentation">
|
||||
<Sequence>
|
||||
<ui:InvokeVBA>
|
||||
<ui:InvokeVBA.CodeFilePath>
|
||||
<InArgument x:TypeArguments="x:String">["Scripts/Keep.bas"]</InArgument>
|
||||
</ui:InvokeVBA.CodeFilePath>
|
||||
</ui:InvokeVBA>
|
||||
</Sequence>
|
||||
</Activity>
|
||||
"""
|
||||
|
||||
OLD_XAML = """<?xml version="1.0" encoding="utf-8"?>
|
||||
<Activity xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
|
||||
xmlns:ui="http://schemas.uipath.com/workflow/activities">
|
||||
<Sequence>
|
||||
<ui:InvokeVBA CodeFilePath="Scripts/Drop.bas" />
|
||||
</Sequence>
|
||||
</Activity>
|
||||
"""
|
||||
|
||||
|
||||
class StubAnalyzer:
|
||||
def analyze(self, relative_path: Path, content: str) -> str:
|
||||
return f"# {relative_path.as_posix()}\n\n{len(content)}"
|
||||
|
||||
|
||||
class PipelineTests(unittest.TestCase):
|
||||
def test_strip_comment_out_blocks_removes_nested_blocks(self) -> None:
|
||||
source = "<root><ui:CommentOut><x/><ui:CommentOut><y/></ui:CommentOut></ui:CommentOut><z/></root>"
|
||||
cleaned = strip_comment_out_blocks(source)
|
||||
self.assertEqual(cleaned, "<root><z/></root>")
|
||||
|
||||
def test_extract_dependencies_reads_property_element_paths(self) -> None:
|
||||
with TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
flows = root / "Flows"
|
||||
flows.mkdir()
|
||||
(root / "Main.xaml").write_text(ACTIVE_XAML, encoding="utf-8")
|
||||
(root / "Scripts").mkdir()
|
||||
(root / "Scripts" / "Keep.bas").write_text("Sub Keep()", encoding="utf-8")
|
||||
|
||||
dependencies, warnings = extract_dependencies(root, root / "Main.xaml")
|
||||
|
||||
self.assertEqual(len(warnings), 0)
|
||||
self.assertEqual(len(dependencies), 1)
|
||||
self.assertEqual(dependencies[0].target, root / "Scripts" / "Keep.bas")
|
||||
|
||||
def test_pipeline_prunes_files_only_reachable_before_comment_cleanup(self) -> None:
|
||||
with TemporaryDirectory() as tmp:
|
||||
tmp_path = Path(tmp)
|
||||
project_root = tmp_path / "project"
|
||||
output_root = tmp_path / "workspace"
|
||||
(project_root / "Flows").mkdir(parents=True)
|
||||
(project_root / "Flows" / "Active.xaml").write_text(ACTIVE_XAML, encoding="utf-8")
|
||||
(project_root / "Flows" / "Old.xaml").write_text(OLD_XAML, encoding="utf-8")
|
||||
(project_root / "Scripts").mkdir()
|
||||
(project_root / "Scripts" / "Keep.bas").write_text("Sub Keep()\nEnd Sub", encoding="utf-8")
|
||||
(project_root / "Scripts" / "Drop.bas").write_text("Sub Drop()\nEnd Sub", encoding="utf-8")
|
||||
(project_root / "main.xaml").write_text(MAIN_XAML, encoding="utf-8")
|
||||
|
||||
initial_scan = crawl_dependencies(project_root, project_root / "main.xaml")
|
||||
initial_files = {path.relative_to(project_root).as_posix() for path in initial_scan.files}
|
||||
self.assertIn("Flows/Old.xaml", initial_files)
|
||||
self.assertIn("Scripts/Drop.bas", initial_files)
|
||||
|
||||
report = ProjectPipeline(project_root, output_root, "main.xaml", force=True).run(StubAnalyzer())
|
||||
|
||||
final_files = {path.as_posix() for path in report.final_files}
|
||||
self.assertIn("main.xaml", final_files)
|
||||
self.assertIn("Flows/Active.xaml", final_files)
|
||||
self.assertIn("Scripts/Keep.bas", final_files)
|
||||
self.assertNotIn("Flows/Old.xaml", final_files)
|
||||
self.assertNotIn("Scripts/Drop.bas", final_files)
|
||||
self.assertFalse((output_root / "Flows" / "Old.xaml").exists())
|
||||
self.assertFalse((output_root / "Scripts" / "Drop.bas").exists())
|
||||
self.assertTrue((output_root / "Flows" / "Active.xaml.analysis.md").exists())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user