yamlgraph 0.3.9__py3-none-any.whl
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.
- examples/__init__.py +1 -0
- examples/codegen/__init__.py +5 -0
- examples/codegen/models/__init__.py +13 -0
- examples/codegen/models/schemas.py +76 -0
- examples/codegen/tests/__init__.py +1 -0
- examples/codegen/tests/test_ai_helpers.py +235 -0
- examples/codegen/tests/test_ast_analysis.py +174 -0
- examples/codegen/tests/test_code_analysis.py +134 -0
- examples/codegen/tests/test_code_context.py +301 -0
- examples/codegen/tests/test_code_nav.py +89 -0
- examples/codegen/tests/test_dependency_tools.py +119 -0
- examples/codegen/tests/test_example_tools.py +185 -0
- examples/codegen/tests/test_git_tools.py +112 -0
- examples/codegen/tests/test_impl_agent_schemas.py +193 -0
- examples/codegen/tests/test_impl_agent_v4_graph.py +94 -0
- examples/codegen/tests/test_jedi_analysis.py +226 -0
- examples/codegen/tests/test_meta_tools.py +250 -0
- examples/codegen/tests/test_plan_discovery_prompt.py +98 -0
- examples/codegen/tests/test_syntax_tools.py +85 -0
- examples/codegen/tests/test_synthesize_prompt.py +94 -0
- examples/codegen/tests/test_template_tools.py +244 -0
- examples/codegen/tools/__init__.py +80 -0
- examples/codegen/tools/ai_helpers.py +420 -0
- examples/codegen/tools/ast_analysis.py +92 -0
- examples/codegen/tools/code_context.py +180 -0
- examples/codegen/tools/code_nav.py +52 -0
- examples/codegen/tools/dependency_tools.py +120 -0
- examples/codegen/tools/example_tools.py +188 -0
- examples/codegen/tools/git_tools.py +151 -0
- examples/codegen/tools/impl_executor.py +614 -0
- examples/codegen/tools/jedi_analysis.py +311 -0
- examples/codegen/tools/meta_tools.py +202 -0
- examples/codegen/tools/syntax_tools.py +26 -0
- examples/codegen/tools/template_tools.py +356 -0
- examples/fastapi_interview.py +167 -0
- examples/npc/api/__init__.py +1 -0
- examples/npc/api/app.py +100 -0
- examples/npc/api/routes/__init__.py +5 -0
- examples/npc/api/routes/encounter.py +182 -0
- examples/npc/api/session.py +330 -0
- examples/npc/demo.py +387 -0
- examples/npc/nodes/__init__.py +5 -0
- examples/npc/nodes/image_node.py +92 -0
- examples/npc/run_encounter.py +230 -0
- examples/shared/__init__.py +0 -0
- examples/shared/replicate_tool.py +238 -0
- examples/storyboard/__init__.py +1 -0
- examples/storyboard/generate_videos.py +335 -0
- examples/storyboard/nodes/__init__.py +12 -0
- examples/storyboard/nodes/animated_character_node.py +248 -0
- examples/storyboard/nodes/animated_image_node.py +138 -0
- examples/storyboard/nodes/character_node.py +162 -0
- examples/storyboard/nodes/image_node.py +118 -0
- examples/storyboard/nodes/replicate_tool.py +49 -0
- examples/storyboard/retry_images.py +118 -0
- scripts/demo_async_executor.py +212 -0
- scripts/demo_interview_e2e.py +200 -0
- scripts/demo_streaming.py +140 -0
- scripts/run_interview_demo.py +94 -0
- scripts/test_interrupt_fix.py +26 -0
- tests/__init__.py +1 -0
- tests/conftest.py +178 -0
- tests/integration/__init__.py +1 -0
- tests/integration/test_animated_storyboard.py +63 -0
- tests/integration/test_cli_commands.py +242 -0
- tests/integration/test_colocated_prompts.py +139 -0
- tests/integration/test_map_demo.py +50 -0
- tests/integration/test_memory_demo.py +283 -0
- tests/integration/test_npc_api/__init__.py +1 -0
- tests/integration/test_npc_api/test_routes.py +357 -0
- tests/integration/test_npc_api/test_session.py +216 -0
- tests/integration/test_pipeline_flow.py +105 -0
- tests/integration/test_providers.py +163 -0
- tests/integration/test_resume.py +75 -0
- tests/integration/test_subgraph_integration.py +295 -0
- tests/integration/test_subgraph_interrupt.py +106 -0
- tests/unit/__init__.py +1 -0
- tests/unit/test_agent_nodes.py +355 -0
- tests/unit/test_async_executor.py +346 -0
- tests/unit/test_checkpointer.py +212 -0
- tests/unit/test_checkpointer_factory.py +212 -0
- tests/unit/test_cli.py +121 -0
- tests/unit/test_cli_package.py +81 -0
- tests/unit/test_compile_graph_map.py +132 -0
- tests/unit/test_conditions_routing.py +253 -0
- tests/unit/test_config.py +93 -0
- tests/unit/test_conversation_memory.py +276 -0
- tests/unit/test_database.py +145 -0
- tests/unit/test_deprecation.py +104 -0
- tests/unit/test_executor.py +172 -0
- tests/unit/test_executor_async.py +179 -0
- tests/unit/test_export.py +149 -0
- tests/unit/test_expressions.py +178 -0
- tests/unit/test_feature_brainstorm.py +194 -0
- tests/unit/test_format_prompt.py +145 -0
- tests/unit/test_generic_report.py +200 -0
- tests/unit/test_graph_commands.py +327 -0
- tests/unit/test_graph_linter.py +627 -0
- tests/unit/test_graph_loader.py +357 -0
- tests/unit/test_graph_schema.py +193 -0
- tests/unit/test_inline_schema.py +151 -0
- tests/unit/test_interrupt_node.py +182 -0
- tests/unit/test_issues.py +164 -0
- tests/unit/test_jinja2_prompts.py +85 -0
- tests/unit/test_json_extract.py +134 -0
- tests/unit/test_langsmith.py +600 -0
- tests/unit/test_langsmith_tools.py +204 -0
- tests/unit/test_llm_factory.py +109 -0
- tests/unit/test_llm_factory_async.py +118 -0
- tests/unit/test_loops.py +403 -0
- tests/unit/test_map_node.py +144 -0
- tests/unit/test_no_backward_compat.py +56 -0
- tests/unit/test_node_factory.py +348 -0
- tests/unit/test_passthrough_node.py +126 -0
- tests/unit/test_prompts.py +324 -0
- tests/unit/test_python_nodes.py +198 -0
- tests/unit/test_reliability.py +298 -0
- tests/unit/test_result_export.py +234 -0
- tests/unit/test_router.py +296 -0
- tests/unit/test_sanitize.py +99 -0
- tests/unit/test_schema_loader.py +295 -0
- tests/unit/test_shell_tools.py +229 -0
- tests/unit/test_state_builder.py +331 -0
- tests/unit/test_state_builder_map.py +104 -0
- tests/unit/test_state_config.py +197 -0
- tests/unit/test_streaming.py +307 -0
- tests/unit/test_subgraph.py +596 -0
- tests/unit/test_template.py +190 -0
- tests/unit/test_tool_call_integration.py +164 -0
- tests/unit/test_tool_call_node.py +178 -0
- tests/unit/test_tool_nodes.py +129 -0
- tests/unit/test_websearch.py +234 -0
- yamlgraph/__init__.py +35 -0
- yamlgraph/builder.py +110 -0
- yamlgraph/cli/__init__.py +159 -0
- yamlgraph/cli/__main__.py +6 -0
- yamlgraph/cli/commands.py +231 -0
- yamlgraph/cli/deprecation.py +92 -0
- yamlgraph/cli/graph_commands.py +541 -0
- yamlgraph/cli/validators.py +37 -0
- yamlgraph/config.py +67 -0
- yamlgraph/constants.py +70 -0
- yamlgraph/error_handlers.py +227 -0
- yamlgraph/executor.py +290 -0
- yamlgraph/executor_async.py +288 -0
- yamlgraph/graph_loader.py +451 -0
- yamlgraph/map_compiler.py +150 -0
- yamlgraph/models/__init__.py +36 -0
- yamlgraph/models/graph_schema.py +181 -0
- yamlgraph/models/schemas.py +124 -0
- yamlgraph/models/state_builder.py +236 -0
- yamlgraph/node_factory.py +768 -0
- yamlgraph/routing.py +87 -0
- yamlgraph/schema_loader.py +240 -0
- yamlgraph/storage/__init__.py +20 -0
- yamlgraph/storage/checkpointer.py +72 -0
- yamlgraph/storage/checkpointer_factory.py +123 -0
- yamlgraph/storage/database.py +320 -0
- yamlgraph/storage/export.py +269 -0
- yamlgraph/tools/__init__.py +1 -0
- yamlgraph/tools/agent.py +320 -0
- yamlgraph/tools/graph_linter.py +388 -0
- yamlgraph/tools/langsmith_tools.py +125 -0
- yamlgraph/tools/nodes.py +126 -0
- yamlgraph/tools/python_tool.py +179 -0
- yamlgraph/tools/shell.py +205 -0
- yamlgraph/tools/websearch.py +242 -0
- yamlgraph/utils/__init__.py +48 -0
- yamlgraph/utils/conditions.py +157 -0
- yamlgraph/utils/expressions.py +245 -0
- yamlgraph/utils/json_extract.py +104 -0
- yamlgraph/utils/langsmith.py +416 -0
- yamlgraph/utils/llm_factory.py +118 -0
- yamlgraph/utils/llm_factory_async.py +105 -0
- yamlgraph/utils/logging.py +104 -0
- yamlgraph/utils/prompts.py +171 -0
- yamlgraph/utils/sanitize.py +98 -0
- yamlgraph/utils/template.py +102 -0
- yamlgraph/utils/validators.py +181 -0
- yamlgraph-0.3.9.dist-info/METADATA +1105 -0
- yamlgraph-0.3.9.dist-info/RECORD +185 -0
- yamlgraph-0.3.9.dist-info/WHEEL +5 -0
- yamlgraph-0.3.9.dist-info/entry_points.txt +2 -0
- yamlgraph-0.3.9.dist-info/licenses/LICENSE +33 -0
- yamlgraph-0.3.9.dist-info/top_level.txt +4 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
"""Tests for universal graph runner (Phase 7.2).
|
|
2
|
+
|
|
3
|
+
TDD tests for `yamlgraph graph run <path>` command.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from unittest.mock import MagicMock, patch
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
# =============================================================================
|
|
13
|
+
# graph subcommand tests
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TestGraphSubcommand:
|
|
18
|
+
"""Tests for graph subcommand group."""
|
|
19
|
+
|
|
20
|
+
def test_graph_subparser_exists(self):
|
|
21
|
+
"""graph subparser should be configured."""
|
|
22
|
+
from yamlgraph.cli import create_parser
|
|
23
|
+
|
|
24
|
+
parser = create_parser()
|
|
25
|
+
# Parse with graph command
|
|
26
|
+
args = parser.parse_args(["graph", "list"])
|
|
27
|
+
assert args.command == "graph"
|
|
28
|
+
|
|
29
|
+
def test_graph_run_subcommand_exists(self):
|
|
30
|
+
"""graph run subcommand should exist."""
|
|
31
|
+
from yamlgraph.cli import create_parser
|
|
32
|
+
|
|
33
|
+
parser = create_parser()
|
|
34
|
+
args = parser.parse_args(
|
|
35
|
+
["graph", "run", "graphs/yamlgraph.yaml", "--var", "topic=AI"]
|
|
36
|
+
)
|
|
37
|
+
assert args.graph_command == "run"
|
|
38
|
+
assert args.graph_path == "graphs/yamlgraph.yaml"
|
|
39
|
+
|
|
40
|
+
def test_graph_list_subcommand_exists(self):
|
|
41
|
+
"""graph list subcommand should exist."""
|
|
42
|
+
from yamlgraph.cli import create_parser
|
|
43
|
+
|
|
44
|
+
parser = create_parser()
|
|
45
|
+
args = parser.parse_args(["graph", "list"])
|
|
46
|
+
assert args.graph_command == "list"
|
|
47
|
+
|
|
48
|
+
def test_graph_info_subcommand_exists(self):
|
|
49
|
+
"""graph info subcommand should exist."""
|
|
50
|
+
from yamlgraph.cli import create_parser
|
|
51
|
+
|
|
52
|
+
parser = create_parser()
|
|
53
|
+
args = parser.parse_args(["graph", "info", "graphs/yamlgraph.yaml"])
|
|
54
|
+
assert args.graph_command == "info"
|
|
55
|
+
assert args.graph_path == "graphs/yamlgraph.yaml"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# =============================================================================
|
|
59
|
+
# graph run argument parsing tests
|
|
60
|
+
# =============================================================================
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class TestGraphRunArgs:
|
|
64
|
+
"""Tests for graph run argument parsing."""
|
|
65
|
+
|
|
66
|
+
def test_var_single_value(self):
|
|
67
|
+
"""--var key=value should parse correctly."""
|
|
68
|
+
from yamlgraph.cli import create_parser
|
|
69
|
+
|
|
70
|
+
parser = create_parser()
|
|
71
|
+
args = parser.parse_args(
|
|
72
|
+
["graph", "run", "graphs/test.yaml", "--var", "topic=AI"]
|
|
73
|
+
)
|
|
74
|
+
assert args.var == ["topic=AI"]
|
|
75
|
+
|
|
76
|
+
def test_var_multiple_values(self):
|
|
77
|
+
"""Multiple --var flags should accumulate."""
|
|
78
|
+
from yamlgraph.cli import create_parser
|
|
79
|
+
|
|
80
|
+
parser = create_parser()
|
|
81
|
+
args = parser.parse_args(
|
|
82
|
+
[
|
|
83
|
+
"graph",
|
|
84
|
+
"run",
|
|
85
|
+
"graphs/test.yaml",
|
|
86
|
+
"--var",
|
|
87
|
+
"topic=AI",
|
|
88
|
+
"--var",
|
|
89
|
+
"style=casual",
|
|
90
|
+
]
|
|
91
|
+
)
|
|
92
|
+
assert args.var == ["topic=AI", "style=casual"]
|
|
93
|
+
|
|
94
|
+
def test_thread_argument(self):
|
|
95
|
+
"""--thread should set thread ID."""
|
|
96
|
+
from yamlgraph.cli import create_parser
|
|
97
|
+
|
|
98
|
+
parser = create_parser()
|
|
99
|
+
args = parser.parse_args(
|
|
100
|
+
["graph", "run", "graphs/test.yaml", "--thread", "abc123"]
|
|
101
|
+
)
|
|
102
|
+
assert args.thread == "abc123"
|
|
103
|
+
|
|
104
|
+
def test_export_flag(self):
|
|
105
|
+
"""--export flag should enable export."""
|
|
106
|
+
from yamlgraph.cli import create_parser
|
|
107
|
+
|
|
108
|
+
parser = create_parser()
|
|
109
|
+
args = parser.parse_args(["graph", "run", "graphs/test.yaml", "--export"])
|
|
110
|
+
assert args.export is True
|
|
111
|
+
|
|
112
|
+
def test_graph_path_required(self):
|
|
113
|
+
"""graph run requires a path argument."""
|
|
114
|
+
from yamlgraph.cli import create_parser
|
|
115
|
+
|
|
116
|
+
parser = create_parser()
|
|
117
|
+
with pytest.raises(SystemExit):
|
|
118
|
+
parser.parse_args(["graph", "run"])
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# =============================================================================
|
|
122
|
+
# parse_vars helper tests
|
|
123
|
+
# =============================================================================
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class TestParseVars:
|
|
127
|
+
"""Tests for --var parsing helper."""
|
|
128
|
+
|
|
129
|
+
def test_parse_single_var(self):
|
|
130
|
+
"""Single var should parse to dict."""
|
|
131
|
+
from yamlgraph.cli.graph_commands import parse_vars
|
|
132
|
+
|
|
133
|
+
result = parse_vars(["topic=AI"])
|
|
134
|
+
assert result == {"topic": "AI"}
|
|
135
|
+
|
|
136
|
+
def test_parse_multiple_vars(self):
|
|
137
|
+
"""Multiple vars should parse to dict."""
|
|
138
|
+
from yamlgraph.cli.graph_commands import parse_vars
|
|
139
|
+
|
|
140
|
+
result = parse_vars(["topic=AI", "style=casual", "count=5"])
|
|
141
|
+
assert result == {"topic": "AI", "style": "casual", "count": "5"}
|
|
142
|
+
|
|
143
|
+
def test_parse_empty_list(self):
|
|
144
|
+
"""Empty list returns empty dict."""
|
|
145
|
+
from yamlgraph.cli.graph_commands import parse_vars
|
|
146
|
+
|
|
147
|
+
result = parse_vars([])
|
|
148
|
+
assert result == {}
|
|
149
|
+
|
|
150
|
+
def test_parse_none_returns_empty(self):
|
|
151
|
+
"""None returns empty dict."""
|
|
152
|
+
from yamlgraph.cli.graph_commands import parse_vars
|
|
153
|
+
|
|
154
|
+
result = parse_vars(None)
|
|
155
|
+
assert result == {}
|
|
156
|
+
|
|
157
|
+
def test_parse_value_with_equals(self):
|
|
158
|
+
"""Value containing = should preserve it."""
|
|
159
|
+
from yamlgraph.cli.graph_commands import parse_vars
|
|
160
|
+
|
|
161
|
+
result = parse_vars(["equation=a=b+c"])
|
|
162
|
+
assert result == {"equation": "a=b+c"}
|
|
163
|
+
|
|
164
|
+
def test_parse_invalid_format_raises(self):
|
|
165
|
+
"""Invalid format (no =) should raise ValueError."""
|
|
166
|
+
from yamlgraph.cli.graph_commands import parse_vars
|
|
167
|
+
|
|
168
|
+
with pytest.raises(ValueError, match="Invalid"):
|
|
169
|
+
parse_vars(["invalid"])
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# =============================================================================
|
|
173
|
+
# cmd_graph_run tests
|
|
174
|
+
# =============================================================================
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class TestCmdGraphRun:
|
|
178
|
+
"""Tests for cmd_graph_run function."""
|
|
179
|
+
|
|
180
|
+
def test_cmd_graph_run_exists(self):
|
|
181
|
+
"""cmd_graph_run function should exist."""
|
|
182
|
+
from yamlgraph.cli.graph_commands import cmd_graph_run
|
|
183
|
+
|
|
184
|
+
assert callable(cmd_graph_run)
|
|
185
|
+
|
|
186
|
+
def test_graph_not_found_error(self):
|
|
187
|
+
"""Should error if graph file doesn't exist."""
|
|
188
|
+
from yamlgraph.cli.graph_commands import cmd_graph_run
|
|
189
|
+
|
|
190
|
+
args = argparse.Namespace(
|
|
191
|
+
graph_path="nonexistent.yaml",
|
|
192
|
+
var=[],
|
|
193
|
+
thread=None,
|
|
194
|
+
export=False,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
with pytest.raises(SystemExit):
|
|
198
|
+
cmd_graph_run(args)
|
|
199
|
+
|
|
200
|
+
@patch("yamlgraph.graph_loader.load_and_compile")
|
|
201
|
+
def test_invokes_graph_with_vars(self, mock_load):
|
|
202
|
+
"""Should invoke graph with parsed vars as initial state."""
|
|
203
|
+
from yamlgraph.cli.graph_commands import cmd_graph_run
|
|
204
|
+
|
|
205
|
+
mock_graph = MagicMock()
|
|
206
|
+
mock_app = MagicMock()
|
|
207
|
+
mock_app.invoke.return_value = {"result": "success"}
|
|
208
|
+
mock_graph.compile.return_value = mock_app
|
|
209
|
+
mock_load.return_value = mock_graph
|
|
210
|
+
|
|
211
|
+
args = argparse.Namespace(
|
|
212
|
+
graph_path="graphs/yamlgraph.yaml",
|
|
213
|
+
var=["topic=AI", "style=casual"],
|
|
214
|
+
thread=None,
|
|
215
|
+
export=False,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# Mock Path.exists
|
|
219
|
+
with patch.object(Path, "exists", return_value=True):
|
|
220
|
+
cmd_graph_run(args)
|
|
221
|
+
|
|
222
|
+
mock_app.invoke.assert_called_once()
|
|
223
|
+
call_args = mock_app.invoke.call_args[0][0]
|
|
224
|
+
assert call_args["topic"] == "AI"
|
|
225
|
+
assert call_args["style"] == "casual"
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
# =============================================================================
|
|
229
|
+
# cmd_graph_list tests
|
|
230
|
+
# =============================================================================
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class TestCmdGraphList:
|
|
234
|
+
"""Tests for cmd_graph_list function."""
|
|
235
|
+
|
|
236
|
+
def test_cmd_graph_list_exists(self):
|
|
237
|
+
"""cmd_graph_list function should exist."""
|
|
238
|
+
from yamlgraph.cli.graph_commands import cmd_graph_list
|
|
239
|
+
|
|
240
|
+
assert callable(cmd_graph_list)
|
|
241
|
+
|
|
242
|
+
@patch("yamlgraph.cli.graph_commands.Path")
|
|
243
|
+
def test_lists_yaml_files(self, mock_path):
|
|
244
|
+
"""Should list all .yaml files in graphs/."""
|
|
245
|
+
from yamlgraph.cli.graph_commands import cmd_graph_list
|
|
246
|
+
|
|
247
|
+
mock_graphs_dir = MagicMock()
|
|
248
|
+
mock_path.return_value = mock_graphs_dir
|
|
249
|
+
mock_graphs_dir.exists.return_value = True
|
|
250
|
+
mock_graphs_dir.glob.return_value = [
|
|
251
|
+
Path("graphs/yamlgraph.yaml"),
|
|
252
|
+
Path("graphs/router-demo.yaml"),
|
|
253
|
+
]
|
|
254
|
+
|
|
255
|
+
args = argparse.Namespace()
|
|
256
|
+
|
|
257
|
+
with patch("builtins.print") as mock_print:
|
|
258
|
+
cmd_graph_list(args)
|
|
259
|
+
# Check it printed something about the graphs
|
|
260
|
+
calls = [str(c) for c in mock_print.call_args_list]
|
|
261
|
+
assert any("yamlgraph" in c for c in calls)
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
# =============================================================================
|
|
265
|
+
# cmd_graph_info tests
|
|
266
|
+
# =============================================================================
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class TestCmdGraphInfo:
|
|
270
|
+
"""Tests for cmd_graph_info function."""
|
|
271
|
+
|
|
272
|
+
def test_cmd_graph_info_exists(self):
|
|
273
|
+
"""cmd_graph_info function should exist."""
|
|
274
|
+
from yamlgraph.cli.graph_commands import cmd_graph_info
|
|
275
|
+
|
|
276
|
+
assert callable(cmd_graph_info)
|
|
277
|
+
|
|
278
|
+
def test_info_file_not_found(self):
|
|
279
|
+
"""Should error if graph file doesn't exist."""
|
|
280
|
+
from yamlgraph.cli.graph_commands import cmd_graph_info
|
|
281
|
+
|
|
282
|
+
args = argparse.Namespace(graph_path="nonexistent.yaml")
|
|
283
|
+
|
|
284
|
+
with pytest.raises(SystemExit):
|
|
285
|
+
cmd_graph_info(args)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
# =============================================================================
|
|
289
|
+
# cmd_graph_validate tests
|
|
290
|
+
# =============================================================================
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class TestCmdGraphValidate:
|
|
294
|
+
"""Tests for cmd_graph_validate function."""
|
|
295
|
+
|
|
296
|
+
def test_cmd_graph_validate_exists(self):
|
|
297
|
+
"""cmd_graph_validate function should exist."""
|
|
298
|
+
from yamlgraph.cli.graph_commands import cmd_graph_validate
|
|
299
|
+
|
|
300
|
+
assert callable(cmd_graph_validate)
|
|
301
|
+
|
|
302
|
+
def test_validate_file_not_found(self):
|
|
303
|
+
"""Should error if graph file doesn't exist."""
|
|
304
|
+
from yamlgraph.cli.graph_commands import cmd_graph_validate
|
|
305
|
+
|
|
306
|
+
args = argparse.Namespace(graph_path="nonexistent.yaml")
|
|
307
|
+
|
|
308
|
+
with pytest.raises(SystemExit):
|
|
309
|
+
cmd_graph_validate(args)
|
|
310
|
+
|
|
311
|
+
def test_validate_valid_graph(self):
|
|
312
|
+
"""Should validate a correct graph without errors."""
|
|
313
|
+
from yamlgraph.cli.graph_commands import cmd_graph_validate
|
|
314
|
+
|
|
315
|
+
args = argparse.Namespace(graph_path="graphs/yamlgraph.yaml")
|
|
316
|
+
|
|
317
|
+
# Should not raise
|
|
318
|
+
cmd_graph_validate(args)
|
|
319
|
+
|
|
320
|
+
def test_validate_subparser_exists(self):
|
|
321
|
+
"""graph validate subcommand should exist."""
|
|
322
|
+
from yamlgraph.cli import create_parser
|
|
323
|
+
|
|
324
|
+
parser = create_parser()
|
|
325
|
+
args = parser.parse_args(["graph", "validate", "graphs/yamlgraph.yaml"])
|
|
326
|
+
assert args.graph_command == "validate"
|
|
327
|
+
assert args.graph_path == "graphs/yamlgraph.yaml"
|