mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-04-30 14:52:36 +00:00
183 lines
6.7 KiB
Python
183 lines
6.7 KiB
Python
"""Unit tests for GlobTool."""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from crewai_tools import GlobTool
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_dir(tmp_path: Path) -> Path:
|
|
"""Create a temp directory with sample files for testing."""
|
|
# src/main.py
|
|
src = tmp_path / "src"
|
|
src.mkdir()
|
|
(src / "main.py").write_text("print('hello')")
|
|
(src / "utils.py").write_text("def helper(): pass")
|
|
|
|
# src/components/button.tsx
|
|
components = src / "components"
|
|
components.mkdir()
|
|
(components / "button.tsx").write_text("export const Button = () => {}")
|
|
(components / "input.tsx").write_text("export const Input = () => {}")
|
|
|
|
# tests/test_main.py
|
|
tests = tmp_path / "tests"
|
|
tests.mkdir()
|
|
(tests / "test_main.py").write_text("def test_hello(): pass")
|
|
(tests / "test_utils.py").write_text("def test_helper(): pass")
|
|
|
|
# config files
|
|
(tmp_path / "config.yaml").write_text("key: value")
|
|
(tmp_path / "settings.json").write_text("{}")
|
|
|
|
# hidden file
|
|
(tmp_path / ".hidden").write_text("secret")
|
|
|
|
# empty directory
|
|
(tmp_path / "empty_dir").mkdir()
|
|
|
|
return tmp_path
|
|
|
|
|
|
class TestGlobTool:
|
|
"""Tests for GlobTool."""
|
|
|
|
def setup_method(self) -> None:
|
|
"""Set up test fixtures."""
|
|
self.tool = GlobTool()
|
|
|
|
def test_tool_metadata(self) -> None:
|
|
"""Test tool has correct name and description."""
|
|
assert self.tool.name == "glob"
|
|
assert "pattern" in self.tool.description.lower()
|
|
|
|
def test_args_schema(self) -> None:
|
|
"""Test that args_schema has correct fields."""
|
|
schema = self.tool.args_schema
|
|
fields = schema.model_fields
|
|
|
|
assert "pattern" in fields
|
|
assert fields["pattern"].is_required()
|
|
|
|
assert "path" in fields
|
|
assert not fields["path"].is_required()
|
|
|
|
assert "output_mode" in fields
|
|
assert not fields["output_mode"].is_required()
|
|
|
|
assert "include_hidden" in fields
|
|
assert not fields["include_hidden"].is_required()
|
|
|
|
def test_find_python_files(self, sample_dir: Path) -> None:
|
|
"""Test finding Python files with *.py pattern."""
|
|
result = self.tool._run(pattern="*.py", path=str(sample_dir))
|
|
assert "main.py" in result
|
|
assert "utils.py" in result
|
|
assert "test_main.py" in result
|
|
assert "test_utils.py" in result
|
|
|
|
def test_find_specific_extension(self, sample_dir: Path) -> None:
|
|
"""Test finding files with specific extension."""
|
|
result = self.tool._run(pattern="*.tsx", path=str(sample_dir))
|
|
assert "button.tsx" in result
|
|
assert "input.tsx" in result
|
|
assert "main.py" not in result
|
|
|
|
def test_find_test_files(self, sample_dir: Path) -> None:
|
|
"""Test finding test files with test_*.py pattern."""
|
|
result = self.tool._run(pattern="test_*.py", path=str(sample_dir))
|
|
assert "test_main.py" in result
|
|
assert "test_utils.py" in result
|
|
# Verify non-test files are not included (check for exact filename, not substring)
|
|
lines = result.split("\n")
|
|
file_lines = [l for l in lines if l.endswith(".py")]
|
|
assert not any(l.endswith("/main.py") or l == "main.py" for l in file_lines)
|
|
assert not any(l.endswith("/utils.py") or l == "utils.py" for l in file_lines)
|
|
|
|
def test_recursive_pattern(self, sample_dir: Path) -> None:
|
|
"""Test explicit recursive pattern **/*.py."""
|
|
result = self.tool._run(pattern="**/*.py", path=str(sample_dir))
|
|
assert "main.py" in result
|
|
assert "test_main.py" in result
|
|
|
|
def test_hidden_files_excluded_by_default(self, sample_dir: Path) -> None:
|
|
"""Test hidden files are excluded by default."""
|
|
result = self.tool._run(pattern="*", path=str(sample_dir))
|
|
assert ".hidden" not in result
|
|
|
|
def test_hidden_files_included(self, sample_dir: Path) -> None:
|
|
"""Test hidden files included when include_hidden=True."""
|
|
result = self.tool._run(
|
|
pattern=".*", path=str(sample_dir), include_hidden=True
|
|
)
|
|
assert ".hidden" in result
|
|
|
|
def test_output_mode_paths(self, sample_dir: Path) -> None:
|
|
"""Test paths output mode shows file paths."""
|
|
result = self.tool._run(
|
|
pattern="*.py", path=str(sample_dir), output_mode="paths"
|
|
)
|
|
# Should contain full paths
|
|
assert str(sample_dir) in result or "main.py" in result
|
|
|
|
def test_output_mode_detailed(self, sample_dir: Path) -> None:
|
|
"""Test detailed output mode shows sizes."""
|
|
result = self.tool._run(
|
|
pattern="*.py", path=str(sample_dir), output_mode="detailed"
|
|
)
|
|
# Should contain size indicators
|
|
assert "B" in result # Bytes indicator
|
|
|
|
def test_output_mode_tree(self, sample_dir: Path) -> None:
|
|
"""Test tree output mode shows directory structure."""
|
|
result = self.tool._run(
|
|
pattern="*.py", path=str(sample_dir), output_mode="tree"
|
|
)
|
|
assert str(sample_dir) in result
|
|
|
|
def test_dirs_only(self, sample_dir: Path) -> None:
|
|
"""Test dirs_only=True only returns directories."""
|
|
result = self.tool._run(
|
|
pattern="*",
|
|
path=str(sample_dir),
|
|
dirs_only=True,
|
|
files_only=False,
|
|
)
|
|
assert "src" in result or "tests" in result or "empty_dir" in result
|
|
# Should not contain file extensions
|
|
assert ".py" not in result
|
|
assert ".yaml" not in result
|
|
|
|
def test_path_not_found(self) -> None:
|
|
"""Test error message when path doesn't exist."""
|
|
result = self.tool._run(pattern="*.py", path="/nonexistent/path")
|
|
assert "Error" in result
|
|
assert "does not exist" in result
|
|
|
|
def test_path_is_file(self, sample_dir: Path) -> None:
|
|
"""Test error message when path is a file, not directory."""
|
|
file_path = sample_dir / "config.yaml"
|
|
result = self.tool._run(pattern="*.py", path=str(file_path))
|
|
assert "Error" in result
|
|
assert "not a directory" in result
|
|
|
|
def test_no_matches(self, sample_dir: Path) -> None:
|
|
"""Test message when no files match pattern."""
|
|
result = self.tool._run(pattern="*.xyz", path=str(sample_dir))
|
|
assert "No files found" in result
|
|
|
|
def test_found_count_in_output(self, sample_dir: Path) -> None:
|
|
"""Test that result includes count of found files."""
|
|
result = self.tool._run(pattern="*.py", path=str(sample_dir))
|
|
assert "Found" in result
|
|
assert "file(s)" in result
|
|
|
|
def test_run_with_kwargs(self, sample_dir: Path) -> None:
|
|
"""Test _run ignores extra kwargs."""
|
|
result = self.tool._run(
|
|
pattern="*.py", path=str(sample_dir), extra_arg="ignored"
|
|
)
|
|
assert "main.py" in result
|