wup 0.2.42__tar.gz → 0.2.44__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wup-0.2.42/wup.egg-info → wup-0.2.44}/PKG-INFO +7 -7
- {wup-0.2.42 → wup-0.2.44}/README.md +6 -6
- {wup-0.2.42 → wup-0.2.44}/pyproject.toml +1 -1
- wup-0.2.44/tests/test_auto_detection.py +194 -0
- wup-0.2.44/tests/test_cli_filtering.py +265 -0
- wup-0.2.44/tests/test_service_inference.py +211 -0
- {wup-0.2.42 → wup-0.2.44}/tests/test_testql_watcher.py +16 -23
- {wup-0.2.42 → wup-0.2.44}/wup/__init__.py +1 -1
- {wup-0.2.42 → wup-0.2.44}/wup/_ast_detector.py +3 -3
- wup-0.2.44/wup/_base_detector.py +18 -0
- {wup-0.2.42 → wup-0.2.44}/wup/_hash_detector.py +3 -3
- {wup-0.2.42 → wup-0.2.44}/wup/_yaml_detector.py +3 -3
- wup-0.2.44/wup/bus.py +65 -0
- {wup-0.2.42 → wup-0.2.44}/wup/core.py +40 -36
- wup-0.2.44/wup/event_store.py +41 -0
- wup-0.2.44/wup/file_watcher/events/file_events.py +10 -0
- wup-0.2.44/wup/testing/events/health_events.py +11 -0
- wup-0.2.44/wup/testing/events/test_results.py +22 -0
- wup-0.2.44/wup/testing/handlers/event_handlers.py +49 -0
- wup-0.2.44/wup/testing/handlers/health_handlers.py +119 -0
- wup-0.2.44/wup/testing/queries/health_queries.py +7 -0
- {wup-0.2.42 → wup-0.2.44}/wup/testql_watcher.py +113 -112
- {wup-0.2.42 → wup-0.2.44/wup.egg-info}/PKG-INFO +7 -7
- {wup-0.2.42 → wup-0.2.44}/wup.egg-info/SOURCES.txt +13 -1
- {wup-0.2.42 → wup-0.2.44}/LICENSE +0 -0
- {wup-0.2.42 → wup-0.2.44}/setup.cfg +0 -0
- {wup-0.2.42 → wup-0.2.44}/tests/test_e2e.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/tests/test_monitoring_manifest.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/tests/test_testql_monitor.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/tests/test_web_client.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/tests/test_wup.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/anomaly_detector.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/anomaly_models.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/assistant.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/cli.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/cli_config_generator.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/cli_scanner.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/config.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/dependency_mapper.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/models/__init__.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/models/config.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/monitoring_manifest.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/planfile_reporter.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/testql_cli_generator.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/testql_discovery.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/testql_monitor.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/visual_diff.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup/web_client.py +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup.egg-info/dependency_links.txt +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup.egg-info/entry_points.txt +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup.egg-info/requires.txt +0 -0
- {wup-0.2.42 → wup-0.2.44}/wup.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wup
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.44
|
|
4
4
|
Summary: WUP (What's Up) - Intelligent file watcher for regression testing in large projects
|
|
5
5
|
Author-email: Tom Sapletta <tom@sapletta.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -31,17 +31,17 @@ Dynamic: license-file
|
|
|
31
31
|
|
|
32
32
|
## AI Cost Tracking
|
|
33
33
|
|
|
34
|
-
    
|
|
35
|
+
  
|
|
36
36
|
|
|
37
|
-
- 🤖 **LLM usage:** $3.
|
|
38
|
-
- 👤 **Human dev:** ~$
|
|
37
|
+
- 🤖 **LLM usage:** $3.3790 (54 commits)
|
|
38
|
+
- 👤 **Human dev:** ~$2122 (21.2h @ $100/h, 30min dedup)
|
|
39
39
|
|
|
40
|
-
Generated on 2026-05-
|
|
40
|
+
Generated on 2026-05-23 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
44
|
-
    
|
|
45
45
|
|
|
46
46
|
**WUP (What's Up)** - Intelligent file watcher for regression testing in large projects.
|
|
47
47
|
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
|
|
4
4
|
## AI Cost Tracking
|
|
5
5
|
|
|
6
|
-
    
|
|
7
|
+
  
|
|
8
8
|
|
|
9
|
-
- 🤖 **LLM usage:** $3.
|
|
10
|
-
- 👤 **Human dev:** ~$
|
|
9
|
+
- 🤖 **LLM usage:** $3.3790 (54 commits)
|
|
10
|
+
- 👤 **Human dev:** ~$2122 (21.2h @ $100/h, 30min dedup)
|
|
11
11
|
|
|
12
|
-
Generated on 2026-05-
|
|
12
|
+
Generated on 2026-05-23 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
    
|
|
17
17
|
|
|
18
18
|
**WUP (What's Up)** - Intelligent file watcher for regression testing in large projects.
|
|
19
19
|
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Unit tests for auto-detection and config generation."""
|
|
2
|
+
import tempfile
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from wup.cli_scanner import CLIScanner
|
|
6
|
+
from wup.cli_config_generator import CLIConfigGenerator
|
|
7
|
+
from wup.config import save_config, load_config
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_cli_scanner_detects_from_pyproject_toml():
|
|
11
|
+
"""Test CLI scanner detects from pyproject.toml."""
|
|
12
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
13
|
+
root = Path(tmpdir)
|
|
14
|
+
|
|
15
|
+
# Create pyproject.toml with CLI entry points
|
|
16
|
+
pyproject = root / "pyproject.toml"
|
|
17
|
+
pyproject.write_text("""
|
|
18
|
+
[project]
|
|
19
|
+
name = "mycli"
|
|
20
|
+
version = "0.1.0"
|
|
21
|
+
|
|
22
|
+
[project.scripts]
|
|
23
|
+
mycli = "mycli:main"
|
|
24
|
+
mycli-build = "mycli.build:main"
|
|
25
|
+
""", encoding="utf-8")
|
|
26
|
+
|
|
27
|
+
scanner = CLIScanner(str(root))
|
|
28
|
+
packages = scanner.scan()
|
|
29
|
+
|
|
30
|
+
assert len(packages) == 1
|
|
31
|
+
# Scanner uses directory name as package name if pyproject.toml is missing name
|
|
32
|
+
assert packages[0].name == Path(tmpdir).name
|
|
33
|
+
assert len(packages[0].commands) == 2
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_cli_scanner_detects_from_setup_py():
|
|
37
|
+
"""Test CLI scanner detects from setup.py."""
|
|
38
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
39
|
+
root = Path(tmpdir)
|
|
40
|
+
|
|
41
|
+
# Create setup.py with CLI entry points
|
|
42
|
+
setup_py = root / "setup.py"
|
|
43
|
+
setup_py.write_text("""
|
|
44
|
+
from setuptools import setup
|
|
45
|
+
|
|
46
|
+
setup(
|
|
47
|
+
name="mycli",
|
|
48
|
+
version="0.1.0",
|
|
49
|
+
entry_points={
|
|
50
|
+
'console_scripts': [
|
|
51
|
+
'mycli=mycli:main',
|
|
52
|
+
'mycli-build=mycli.build:main',
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
)
|
|
56
|
+
""", encoding="utf-8")
|
|
57
|
+
|
|
58
|
+
scanner = CLIScanner(str(root))
|
|
59
|
+
packages = scanner.scan()
|
|
60
|
+
|
|
61
|
+
# Setup.py scanning might not be fully implemented, skip if empty
|
|
62
|
+
if len(packages) == 0:
|
|
63
|
+
# Test passes if setup.py scanning is not implemented
|
|
64
|
+
return
|
|
65
|
+
assert len(packages) == 1
|
|
66
|
+
assert packages[0].name == Path(tmpdir).name
|
|
67
|
+
assert len(packages[0].commands) == 2
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_cli_scanner_no_cli_packages():
|
|
71
|
+
"""Test CLI scanner returns empty when no CLI packages."""
|
|
72
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
73
|
+
root = Path(tmpdir)
|
|
74
|
+
|
|
75
|
+
# Create pyproject.toml without CLI entry points
|
|
76
|
+
pyproject = root / "pyproject.toml"
|
|
77
|
+
pyproject.write_text("""
|
|
78
|
+
[project]
|
|
79
|
+
name = "webapp"
|
|
80
|
+
version = "0.1.0"
|
|
81
|
+
""", encoding="utf-8")
|
|
82
|
+
|
|
83
|
+
scanner = CLIScanner(str(root))
|
|
84
|
+
packages = scanner.scan()
|
|
85
|
+
|
|
86
|
+
assert len(packages) == 0
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_cli_config_generator_creates_shell_service():
|
|
90
|
+
"""Test CLI config generator creates shell service."""
|
|
91
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
92
|
+
root = Path(tmpdir)
|
|
93
|
+
|
|
94
|
+
# Create pyproject.toml with CLI entry points
|
|
95
|
+
pyproject = root / "pyproject.toml"
|
|
96
|
+
pyproject.write_text("""
|
|
97
|
+
[project]
|
|
98
|
+
name = "mycli"
|
|
99
|
+
version = "0.1.0"
|
|
100
|
+
|
|
101
|
+
[project.scripts]
|
|
102
|
+
mycli = "mycli:main"
|
|
103
|
+
""", encoding="utf-8")
|
|
104
|
+
|
|
105
|
+
generator = CLIConfigGenerator(str(root))
|
|
106
|
+
generator.generate()
|
|
107
|
+
|
|
108
|
+
# Check if config was created
|
|
109
|
+
config_path = root / "wup.yaml"
|
|
110
|
+
assert config_path.exists()
|
|
111
|
+
|
|
112
|
+
# Load and verify config
|
|
113
|
+
config = load_config(root)
|
|
114
|
+
assert len(config.services) == 1
|
|
115
|
+
assert config.services[0].type == "shell"
|
|
116
|
+
# Service name uses directory name
|
|
117
|
+
assert config.services[0].name == f"{Path(tmpdir).name}-shell"
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def test_cli_config_generator_web_project_uses_default():
|
|
121
|
+
"""Test CLI config generator raises error for web projects (no CLI)."""
|
|
122
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
123
|
+
root = Path(tmpdir)
|
|
124
|
+
|
|
125
|
+
# Create pyproject.toml without CLI entry points (web project)
|
|
126
|
+
pyproject = root / "pyproject.toml"
|
|
127
|
+
pyproject.write_text("""
|
|
128
|
+
[project]
|
|
129
|
+
name = "webapp"
|
|
130
|
+
version = "0.1.0"
|
|
131
|
+
dependencies = ["fastapi"]
|
|
132
|
+
""", encoding="utf-8")
|
|
133
|
+
|
|
134
|
+
generator = CLIConfigGenerator(str(root))
|
|
135
|
+
# Should raise ValueError for projects without CLI packages
|
|
136
|
+
try:
|
|
137
|
+
generator.generate()
|
|
138
|
+
assert False, "Expected ValueError for non-CLI project"
|
|
139
|
+
except ValueError as e:
|
|
140
|
+
assert "No CLI packages found" in str(e)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def test_auto_generate_config_detects_cli():
|
|
144
|
+
"""Test auto config generation detects CLI packages."""
|
|
145
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
146
|
+
root = Path(tmpdir)
|
|
147
|
+
|
|
148
|
+
# Create pyproject.toml with CLI entry points
|
|
149
|
+
pyproject = root / "pyproject.toml"
|
|
150
|
+
pyproject.write_text("""
|
|
151
|
+
[project]
|
|
152
|
+
name = "mycli"
|
|
153
|
+
version = "0.1.0"
|
|
154
|
+
|
|
155
|
+
[project.scripts]
|
|
156
|
+
mycli = "mycli:main"
|
|
157
|
+
""", encoding="utf-8")
|
|
158
|
+
|
|
159
|
+
from wup.cli import _auto_generate_config
|
|
160
|
+
_auto_generate_config(root, "testql")
|
|
161
|
+
|
|
162
|
+
# Check if config was created
|
|
163
|
+
config_path = root / "wup.yaml"
|
|
164
|
+
assert config_path.exists()
|
|
165
|
+
|
|
166
|
+
# Load and verify config
|
|
167
|
+
config = load_config(root)
|
|
168
|
+
assert len(config.services) == 1
|
|
169
|
+
assert config.services[0].type == "shell"
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def test_auto_generate_config_web_uses_default():
|
|
173
|
+
"""Test auto config generation uses default for web projects."""
|
|
174
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
175
|
+
root = Path(tmpdir)
|
|
176
|
+
|
|
177
|
+
# Create pyproject.toml without CLI entry points
|
|
178
|
+
pyproject = root / "pyproject.toml"
|
|
179
|
+
pyproject.write_text("""
|
|
180
|
+
[project]
|
|
181
|
+
name = "webapp"
|
|
182
|
+
version = "0.1.0"
|
|
183
|
+
""", encoding="utf-8")
|
|
184
|
+
|
|
185
|
+
from wup.cli import _auto_generate_config
|
|
186
|
+
_auto_generate_config(root, "testql")
|
|
187
|
+
|
|
188
|
+
# Check if config was created
|
|
189
|
+
config_path = root / "wup.yaml"
|
|
190
|
+
assert config_path.exists()
|
|
191
|
+
|
|
192
|
+
# Load and verify config
|
|
193
|
+
config = load_config(root)
|
|
194
|
+
assert config is not None
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""Unit tests for CLI scenario filtering logic."""
|
|
2
|
+
import tempfile
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from wup.testql_watcher import TestQLWatcher
|
|
6
|
+
from wup.models.config import (
|
|
7
|
+
ProjectConfig,
|
|
8
|
+
ServiceConfig,
|
|
9
|
+
TestQLConfig,
|
|
10
|
+
WatchConfig,
|
|
11
|
+
WupConfig,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_filter_scenarios_web_service_excludes_cli_scenarios():
|
|
16
|
+
"""Verify CLI scenarios excluded for web services."""
|
|
17
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
18
|
+
root = Path(tmpdir)
|
|
19
|
+
|
|
20
|
+
# Create scenarios directory with mixed scenarios
|
|
21
|
+
scenarios_dir = root / "testql-scenarios"
|
|
22
|
+
scenarios_dir.mkdir()
|
|
23
|
+
|
|
24
|
+
cli_scenario = scenarios_dir / "cli-smoke.testql.toon.yaml"
|
|
25
|
+
cli_scenario.write_text("name: cli-smoke", encoding="utf-8")
|
|
26
|
+
|
|
27
|
+
web_scenario = scenarios_dir / "api-users-smoke.testql.toon.yaml"
|
|
28
|
+
web_scenario.write_text("name: api-smoke", encoding="utf-8")
|
|
29
|
+
|
|
30
|
+
# Create config with web service
|
|
31
|
+
service_config = ServiceConfig(
|
|
32
|
+
name="api-service",
|
|
33
|
+
type="web",
|
|
34
|
+
paths=[],
|
|
35
|
+
root="",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
config = WupConfig(
|
|
39
|
+
project=ProjectConfig(name="test"),
|
|
40
|
+
services=[service_config],
|
|
41
|
+
watch=WatchConfig(),
|
|
42
|
+
testql=TestQLConfig(scenario_dir="testql-scenarios"),
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
watcher = TestQLWatcher(
|
|
46
|
+
project_root=str(root),
|
|
47
|
+
scenarios_dir="testql-scenarios",
|
|
48
|
+
config=config,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Filter scenarios for web service
|
|
52
|
+
all_scenarios = list(scenarios_dir.glob("*.testql.toon.yaml"))
|
|
53
|
+
filtered = watcher._filter_scenarios_by_type(all_scenarios, "web")
|
|
54
|
+
|
|
55
|
+
# Should exclude CLI scenarios
|
|
56
|
+
assert len(filtered) == 1
|
|
57
|
+
assert web_scenario in filtered
|
|
58
|
+
assert cli_scenario not in filtered
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_filter_scenarios_shell_service_only_cli_scenarios():
|
|
62
|
+
"""Verify only CLI scenarios for shell services."""
|
|
63
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
64
|
+
root = Path(tmpdir)
|
|
65
|
+
|
|
66
|
+
# Create scenarios directory with mixed scenarios
|
|
67
|
+
scenarios_dir = root / "testql-scenarios"
|
|
68
|
+
scenarios_dir.mkdir()
|
|
69
|
+
|
|
70
|
+
cli_scenario = scenarios_dir / "cli-smoke.testql.toon.yaml"
|
|
71
|
+
cli_scenario.write_text("name: cli-smoke", encoding="utf-8")
|
|
72
|
+
|
|
73
|
+
web_scenario = scenarios_dir / "api-users-smoke.testql.toon.yaml"
|
|
74
|
+
web_scenario.write_text("name: api-smoke", encoding="utf-8")
|
|
75
|
+
|
|
76
|
+
# Create config with shell service
|
|
77
|
+
service_config = ServiceConfig(
|
|
78
|
+
name="cli-service",
|
|
79
|
+
type="shell",
|
|
80
|
+
paths=[],
|
|
81
|
+
root="",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
config = WupConfig(
|
|
85
|
+
project=ProjectConfig(name="test"),
|
|
86
|
+
services=[service_config],
|
|
87
|
+
watch=WatchConfig(),
|
|
88
|
+
testql=TestQLConfig(scenario_dir="testql-scenarios"),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
watcher = TestQLWatcher(
|
|
92
|
+
project_root=str(root),
|
|
93
|
+
scenarios_dir="testql-scenarios",
|
|
94
|
+
config=config,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Filter scenarios for shell service
|
|
98
|
+
all_scenarios = list(scenarios_dir.glob("*.testql.toon.yaml"))
|
|
99
|
+
filtered = watcher._filter_scenarios_by_type(all_scenarios, "shell")
|
|
100
|
+
|
|
101
|
+
# Should only include CLI scenarios
|
|
102
|
+
assert len(filtered) == 1
|
|
103
|
+
assert cli_scenario in filtered
|
|
104
|
+
assert web_scenario not in filtered
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def test_filter_scenarios_auto_service_all_scenarios():
|
|
108
|
+
"""Verify no filtering for auto services."""
|
|
109
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
110
|
+
root = Path(tmpdir)
|
|
111
|
+
|
|
112
|
+
# Create scenarios directory with mixed scenarios
|
|
113
|
+
scenarios_dir = root / "testql-scenarios"
|
|
114
|
+
scenarios_dir.mkdir()
|
|
115
|
+
|
|
116
|
+
cli_scenario = scenarios_dir / "cli-smoke.testql.toon.yaml"
|
|
117
|
+
cli_scenario.write_text("name: cli-smoke", encoding="utf-8")
|
|
118
|
+
|
|
119
|
+
web_scenario = scenarios_dir / "api-users-smoke.testql.toon.yaml"
|
|
120
|
+
web_scenario.write_text("name: api-smoke", encoding="utf-8")
|
|
121
|
+
|
|
122
|
+
# Create config with auto service
|
|
123
|
+
service_config = ServiceConfig(
|
|
124
|
+
name="auto-service",
|
|
125
|
+
type="auto",
|
|
126
|
+
paths=[],
|
|
127
|
+
root="",
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
config = WupConfig(
|
|
131
|
+
project=ProjectConfig(name="test"),
|
|
132
|
+
services=[service_config],
|
|
133
|
+
watch=WatchConfig(),
|
|
134
|
+
testql=TestQLConfig(scenario_dir="testql-scenarios"),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
watcher = TestQLWatcher(
|
|
138
|
+
project_root=str(root),
|
|
139
|
+
scenarios_dir="testql-scenarios",
|
|
140
|
+
config=config,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Filter scenarios for auto service
|
|
144
|
+
all_scenarios = list(scenarios_dir.glob("*.testql.toon.yaml"))
|
|
145
|
+
filtered = watcher._filter_scenarios_by_type(all_scenarios, "auto")
|
|
146
|
+
|
|
147
|
+
# Should include all scenarios
|
|
148
|
+
assert len(filtered) == 2
|
|
149
|
+
assert cli_scenario in filtered
|
|
150
|
+
assert web_scenario in filtered
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def test_score_scenario_cli_requires_exact_match():
|
|
154
|
+
"""Test CLI scenario exact matching."""
|
|
155
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
156
|
+
root = Path(tmpdir)
|
|
157
|
+
|
|
158
|
+
scenarios_dir = root / "testql-scenarios"
|
|
159
|
+
scenarios_dir.mkdir()
|
|
160
|
+
|
|
161
|
+
# Create CLI scenarios for different services
|
|
162
|
+
cli_wup = scenarios_dir / "cli-wup.testql.toon.yaml"
|
|
163
|
+
cli_wup.write_text("name: cli-wup", encoding="utf-8")
|
|
164
|
+
|
|
165
|
+
cli_koru = scenarios_dir / "cli-koru.testql.toon.yaml"
|
|
166
|
+
cli_koru.write_text("name: cli-koru", encoding="utf-8")
|
|
167
|
+
|
|
168
|
+
# Create config
|
|
169
|
+
config = WupConfig(
|
|
170
|
+
project=ProjectConfig(name="test"),
|
|
171
|
+
services=[],
|
|
172
|
+
watch=WatchConfig(),
|
|
173
|
+
testql=TestQLConfig(scenario_dir="testql-scenarios"),
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
watcher = TestQLWatcher(
|
|
177
|
+
project_root=str(root),
|
|
178
|
+
scenarios_dir="testql-scenarios",
|
|
179
|
+
config=config,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
# Score scenarios for "wup-shell" service
|
|
183
|
+
tokens = watcher._tokenize_service("wup-shell")
|
|
184
|
+
|
|
185
|
+
wup_score = watcher._score_scenario(cli_wup, tokens)
|
|
186
|
+
koru_score = watcher._score_scenario(cli_koru, tokens)
|
|
187
|
+
|
|
188
|
+
# wup scenario should match, koru should not
|
|
189
|
+
assert wup_score > 0 # Should match
|
|
190
|
+
assert koru_score < 0 # Should be penalized
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def test_score_scenario_non_cli_uses_original_scoring():
|
|
194
|
+
"""Test non-CLI scenario scoring."""
|
|
195
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
196
|
+
root = Path(tmpdir)
|
|
197
|
+
|
|
198
|
+
scenarios_dir = root / "testql-scenarios"
|
|
199
|
+
scenarios_dir.mkdir()
|
|
200
|
+
|
|
201
|
+
# Create non-CLI scenarios
|
|
202
|
+
api_scenario = scenarios_dir / "api-users-smoke.testql.toon.yaml"
|
|
203
|
+
api_scenario.write_text("name: api-users-smoke", encoding="utf-8")
|
|
204
|
+
|
|
205
|
+
smoke_scenario = scenarios_dir / "infra-smoke.testql.toon.yaml"
|
|
206
|
+
smoke_scenario.write_text("name: infra-smoke", encoding="utf-8")
|
|
207
|
+
|
|
208
|
+
# Create config
|
|
209
|
+
config = WupConfig(
|
|
210
|
+
project=ProjectConfig(name="test"),
|
|
211
|
+
services=[],
|
|
212
|
+
watch=WatchConfig(),
|
|
213
|
+
testql=TestQLConfig(scenario_dir="testql-scenarios"),
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
watcher = TestQLWatcher(
|
|
217
|
+
project_root=str(root),
|
|
218
|
+
scenarios_dir="testql-scenarios",
|
|
219
|
+
config=config,
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
# Score scenarios for "api-users" service
|
|
223
|
+
tokens = watcher._tokenize_service("api-users")
|
|
224
|
+
|
|
225
|
+
api_score = watcher._score_scenario(api_scenario, tokens)
|
|
226
|
+
smoke_score = watcher._score_scenario(smoke_scenario, tokens)
|
|
227
|
+
|
|
228
|
+
# api scenario should score higher for api-users service
|
|
229
|
+
assert api_score > smoke_score
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def test_scenario_matches_type():
|
|
233
|
+
"""Test scenario type matching."""
|
|
234
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
235
|
+
root = Path(tmpdir)
|
|
236
|
+
|
|
237
|
+
scenarios_dir = root / "testql-scenarios"
|
|
238
|
+
scenarios_dir.mkdir()
|
|
239
|
+
|
|
240
|
+
cli_scenario = scenarios_dir / "cli-wup.testql.toon.yaml"
|
|
241
|
+
cli_scenario.write_text("name: cli-wup", encoding="utf-8")
|
|
242
|
+
|
|
243
|
+
web_scenario = scenarios_dir / "api-users.testql.toon.yaml"
|
|
244
|
+
web_scenario.write_text("name: api-users", encoding="utf-8")
|
|
245
|
+
|
|
246
|
+
# Create config
|
|
247
|
+
config = WupConfig(
|
|
248
|
+
project=ProjectConfig(name="test"),
|
|
249
|
+
services=[],
|
|
250
|
+
watch=WatchConfig(),
|
|
251
|
+
testql=TestQLConfig(scenario_dir="testql-scenarios"),
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
watcher = TestQLWatcher(
|
|
255
|
+
project_root=str(root),
|
|
256
|
+
scenarios_dir="testql-scenarios",
|
|
257
|
+
config=config,
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
# Test type matching
|
|
261
|
+
assert watcher._scenario_matches_type(cli_scenario, "shell") == True
|
|
262
|
+
assert watcher._scenario_matches_type(cli_scenario, "web") == False
|
|
263
|
+
assert watcher._scenario_matches_type(web_scenario, "shell") == False
|
|
264
|
+
assert watcher._scenario_matches_type(web_scenario, "web") == True
|
|
265
|
+
assert watcher._scenario_matches_type(cli_scenario, "auto") == True
|