test_filter.py
1 #!/usr/bin/env python3 2 """ 3 Unit tests for Shadow Runner filter logic. 4 """ 5 6 import os 7 import sys 8 9 # Add parent directory to path for imports 10 sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) 11 12 import pytest 13 from filter import should_use_shadow, get_speed, get_estimated_duration, REPO_SPEED 14 15 16 class TestRepoClassification: 17 def test_all_repos_classified(self): 18 """Verify all repos appear in exactly one speed category.""" 19 fast = set(REPO_SPEED["fast"]) 20 medium = set(REPO_SPEED["medium"]) 21 slow = set(REPO_SPEED["slow"]) 22 23 # No overlaps 24 assert fast.isdisjoint(medium), "Fast and medium overlap" 25 assert fast.isdisjoint(slow), "Fast and slow overlap" 26 assert medium.isdisjoint(slow), "Medium and slow overlap" 27 28 def test_get_speed_fast(self): 29 assert get_speed("acdc-core") == "fast" 30 assert get_speed("sdk") == "fast" 31 assert get_speed("acdc-wallet") == "fast" 32 33 def test_get_speed_medium(self): 34 assert get_speed("adnet") == "medium" 35 assert get_speed("adl") == "medium" 36 assert get_speed("wallet-core") == "medium" 37 38 def test_get_speed_slow(self): 39 assert get_speed("alphavm") == "slow" 40 assert get_speed("deltavm") == "slow" 41 assert get_speed("alphaos") == "slow" 42 assert get_speed("deltaos") == "slow" 43 44 def test_get_speed_unknown(self): 45 assert get_speed("nonexistent-repo") == "unknown" 46 47 48 class TestShouldUseShadow: 49 # Fast repos - never use shadow 50 def test_fast_repo_returns_false(self): 51 result, reason = should_use_shadow("acdc-core", {}) 52 assert result is False 53 assert "fast" in reason.lower() 54 55 def test_fast_repo_ignores_context(self): 56 result, _ = should_use_shadow("sdk", {"full_suite": True}) 57 assert result is False 58 59 # Slow repos - always use shadow (unless interactive) 60 def test_slow_repo_returns_true(self): 61 result, reason = should_use_shadow("alphavm", {}) 62 assert result is True 63 assert "60-90min" in reason 64 65 def test_slow_repo_with_interactive_returns_false(self): 66 result, reason = should_use_shadow("deltavm", {"interactive": True}) 67 assert result is False 68 assert "interactive" in reason.lower() 69 70 def test_slow_repo_with_single_test_returns_false(self): 71 result, reason = should_use_shadow("alphaos", {"single_test": True}) 72 assert result is False 73 assert "single test" in reason.lower() 74 75 # Medium repos - depends on context 76 def test_medium_repo_full_suite_returns_true(self): 77 result, reason = should_use_shadow("adnet", {"full_suite": True}) 78 assert result is True 79 assert "30-45min" in reason 80 81 def test_medium_repo_default_returns_true(self): 82 # Default is full_suite=True 83 result, _ = should_use_shadow("adl", {}) 84 assert result is True 85 86 def test_medium_repo_partial_returns_false(self): 87 result, reason = should_use_shadow("adnet", {"full_suite": False}) 88 assert result is False 89 assert "partial" in reason.lower() 90 91 def test_medium_repo_interactive_returns_false(self): 92 result, reason = should_use_shadow("wallet-core", {"interactive": True}) 93 assert result is False 94 95 # Unknown repos 96 def test_unknown_repo_returns_false(self): 97 result, reason = should_use_shadow("mystery-repo", {}) 98 assert result is False 99 assert "unknown" in reason.lower() 100 101 # Small changes 102 def test_small_change_with_unit_tests_returns_false(self): 103 result, reason = should_use_shadow("alphavm", { 104 "files_changed": 1, 105 "unit_tests_only": True 106 }) 107 assert result is False 108 assert "small change" in reason.lower() 109 110 111 class TestEstimatedDuration: 112 def test_fast_duration(self): 113 assert get_estimated_duration("acdc-core") == "<10 minutes" 114 115 def test_medium_duration(self): 116 assert get_estimated_duration("adnet") == "30-45 minutes" 117 118 def test_slow_duration(self): 119 assert get_estimated_duration("alphavm") == "60-90 minutes" 120 121 def test_unknown_duration(self): 122 assert get_estimated_duration("unknown") == "unknown" 123 124 125 if __name__ == "__main__": 126 pytest.main([__file__, "-v"])