Skip to main content
Glama

Jinni: Bring Your Project Into Context

by smat-dev
test_mcp_exclusions.py10.1 kB
# tests/test_mcp_exclusions.py """Integration tests for MCP server exclusion features.""" import pytest import json import tempfile from pathlib import Path from tests.conftest import run_mcp_tool_call def create_project_structure(root: Path, structure: dict): """Create a nested directory/file structure from a dict.""" for name, content in structure.items(): path = root / name if isinstance(content, dict): # It's a directory path.mkdir(exist_ok=True) create_project_structure(path, content) else: # It's a file path.parent.mkdir(exist_ok=True, parents=True) path.write_text(content, encoding='utf-8') class TestMCPExclusions: """Test MCP server exclusion functionality.""" @pytest.fixture def test_project(self): """Create a test project structure.""" with tempfile.TemporaryDirectory() as tmpdir: root = Path(tmpdir) structure = { "src": { "app.py": "# Application", "utils.py": "# Utils", "legacy": { "old.py": "# Old code" }, "tests": { "test_app.py": "# App tests" } }, "tests": { "test_integration.py": "# Integration" }, "vendor": { "lib.py": "# Library" }, "docs": { "readme.md": "# Docs" }, "build": { "output.js": "// Built" }, "app.test.js": "// JS test", "util.spec.py": "# Python spec", "temp.log": "Log file" } create_project_structure(root, structure) yield root async def test_exclusions_global(self, test_project): """Test global exclusions via MCP.""" result = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=[], rules=[], list_only=True, exclusions={ "global": ["tests", "vendor"] } ) lines = result.strip().split('\n') # Should exclude globally assert not any("tests/" in line for line in lines) assert not any("test_" in line for line in lines) assert not any("vendor/" in line for line in lines) assert not any(".test." in line for line in lines) # Should include others assert any("src/app.py" in line for line in lines) assert any("docs/readme.md" in line for line in lines) async def test_exclusions_scoped(self, test_project): """Test scoped exclusions via MCP.""" result = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=[], rules=[], list_only=True, exclusions={ "scoped": { "src": ["legacy", "tests"] } } ) lines = result.strip().split('\n') # Should exclude only within src assert not any("src/legacy/" in line for line in lines) assert not any("src/tests/" in line for line in lines) # Should include other src files assert any("src/app.py" in line for line in lines) assert any("src/utils.py" in line for line in lines) # Should include tests outside src assert any("tests/test_integration.py" in line for line in lines) async def test_exclusions_patterns(self, test_project): """Test file pattern exclusions via MCP.""" result = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=[], rules=[], list_only=True, exclusions={ "patterns": ["*.test.*", "*.spec.*", "*.log"] } ) lines = result.strip().split('\n') # Should exclude matching patterns assert not any("app.test.js" in line for line in lines) assert not any("util.spec.py" in line for line in lines) assert not any("temp.log" in line for line in lines) # Should include others assert any("src/app.py" in line for line in lines) async def test_exclusions_combined(self, test_project): """Test combining all exclusion types via MCP.""" result = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=[], rules=[], list_only=True, exclusions={ "global": ["vendor", "build"], "scoped": { "src": ["legacy"] }, "patterns": ["*.log"] } ) lines = result.strip().split('\n') # Check all exclusions work assert not any("vendor/" in line for line in lines) assert not any("build/" in line for line in lines) assert not any("src/legacy/" in line for line in lines) assert not any(".log" in line for line in lines) # Check inclusions assert any("src/app.py" in line for line in lines) assert any("tests/test_integration.py" in line for line in lines) async def test_exclusions_with_specific_targets(self, test_project): """Test exclusions work with specific targets.""" result = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=["src"], rules=[], list_only=True, exclusions={ "global": ["tests"] } ) lines = result.strip().split('\n') # Should only process src, excluding tests within it assert any("src/app.py" in line for line in lines) assert not any("src/tests/" in line for line in lines) # Should not include anything outside src assert not any("vendor/" in line for line in lines) assert not any("docs/" in line for line in lines) async def test_exclusions_with_rules(self, test_project): """Test exclusions work together with rules.""" result = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=[], rules=["*.py", "!**/legacy/**"], # Include only .py, exclude legacy list_only=True, exclusions={ "global": ["vendor"] } ) lines = result.strip().split('\n') # Should apply both rules and exclusions assert any("src/app.py" in line for line in lines) assert any("src/utils.py" in line for line in lines) # Excluded by rules assert not any(".js" in line for line in lines) assert not any(".md" in line for line in lines) assert not any("legacy/" in line for line in lines) # Excluded by exclusions assert not any("vendor/" in line for line in lines) async def test_exclusions_empty(self, test_project): """Test empty exclusions object has no effect.""" result_with_empty = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=[], rules=[], list_only=True, exclusions={} ) result_without = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=[], rules=[], list_only=True ) # Results should be identical assert result_with_empty == result_without async def test_exclusions_with_summarize(self, test_project): """Test exclusions work with summarize_context tool.""" result = await run_mcp_tool_call( "summarize_context", project_root=str(test_project), targets=[], rules=[], list_only=True, exclusions={ "global": ["tests", "vendor"] } ) lines = result.strip().split('\n') # Exclusions should work same as read_context assert not any("tests/" in line for line in lines) assert not any("vendor/" in line for line in lines) assert any("src/app.py" in line for line in lines) async def test_exclusions_debug_mode(self, test_project): """Test debug mode shows exclusion information.""" result = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=[], rules=[], list_only=True, debug_explain=True, exclusions={ "global": ["tests"] } ) # Should contain debug information assert "DEBUG LOG" in result assert "exclusion patterns" in result.lower() async def test_exclusions_invalid_structure(self, test_project): """Test handling of invalid exclusion structures.""" # Test with non-list values result = await run_mcp_tool_call( "read_context", project_root=str(test_project), targets=[], rules=[], list_only=True, exclusions={ "global": "tests", # Should be a list "patterns": ["*.log"] } ) # Should still work, ignoring invalid parts lines = result.strip().split('\n') assert not any(".log" in line for line in lines)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/smat-dev/jinni'

If you have feedback or need assistance with the MCP directory API, please join our Discord server