test: align output binding integration coverage
This commit is contained in:
@@ -9,32 +9,21 @@ import typer
|
|||||||
from typer.testing import CliRunner
|
from typer.testing import CliRunner
|
||||||
|
|
||||||
from wf_cli.app import app
|
from wf_cli.app import app
|
||||||
from wf_cli.commands import draft_options
|
|
||||||
from wf_cli.commands.draft_options import (
|
from wf_cli.commands.draft_options import (
|
||||||
parse_json_file,
|
parse_json_file,
|
||||||
parse_step_input_binding_flags,
|
parse_step_input_binding_flags,
|
||||||
parse_step_input_bindings_file,
|
parse_step_input_bindings_file,
|
||||||
parse_step_input_value_flags,
|
parse_step_input_value_flags,
|
||||||
|
parse_step_output_binding_flags,
|
||||||
|
parse_step_output_bindings_file,
|
||||||
route_source,
|
route_source,
|
||||||
)
|
)
|
||||||
|
|
||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
|
|
||||||
|
|
||||||
def _parse_step_output_binding_flags(values: list[str] | None):
|
|
||||||
parser = getattr(draft_options, "parse_step_output_binding_flags", None)
|
|
||||||
assert callable(parser), "step output binding flag parser is not available"
|
|
||||||
return parser(values)
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_step_output_bindings_file(path):
|
|
||||||
parser = getattr(draft_options, "parse_step_output_bindings_file", None)
|
|
||||||
assert callable(parser), "step output bindings file parser is not available"
|
|
||||||
return parser(path)
|
|
||||||
|
|
||||||
|
|
||||||
def test_draft_options_parse_step_output_bindings_preserves_source_fan_out() -> None:
|
def test_draft_options_parse_step_output_bindings_preserves_source_fan_out() -> None:
|
||||||
bindings = _parse_step_output_binding_flags(
|
bindings = parse_step_output_binding_flags(
|
||||||
[
|
[
|
||||||
"report.title=state.report.title",
|
"report.title=state.report.title",
|
||||||
"report.title=state.audit.title",
|
"report.title=state.audit.title",
|
||||||
@@ -61,7 +50,7 @@ def test_draft_options_parse_step_output_bindings_file_preserves_order(
|
|||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
|
|
||||||
bindings = _parse_step_output_bindings_file(path)
|
bindings = parse_step_output_bindings_file(path)
|
||||||
|
|
||||||
assert [binding.model_dump(mode="json") for binding in bindings] == [
|
assert [binding.model_dump(mode="json") for binding in bindings] == [
|
||||||
{"source": "report.title", "target": "state.report.title"},
|
{"source": "report.title", "target": "state.report.title"},
|
||||||
@@ -89,7 +78,7 @@ def test_draft_options_parse_step_output_bindings_file_rejects_invalid_payload(
|
|||||||
path.write_text(json.dumps(payload), encoding="utf-8")
|
path.write_text(json.dumps(payload), encoding="utf-8")
|
||||||
|
|
||||||
with pytest.raises(typer.BadParameter) as exc_info:
|
with pytest.raises(typer.BadParameter) as exc_info:
|
||||||
_parse_step_output_bindings_file(path)
|
parse_step_output_bindings_file(path)
|
||||||
|
|
||||||
assert expected_text in str(exc_info.value).lower()
|
assert expected_text in str(exc_info.value).lower()
|
||||||
assert "traceback" not in str(exc_info.value).lower()
|
assert "traceback" not in str(exc_info.value).lower()
|
||||||
@@ -653,7 +642,7 @@ def test_wf_draft_map_help_explains_replace_merge_and_validate() -> None:
|
|||||||
assert "input.title=report.title" in input_help
|
assert "input.title=report.title" in input_help
|
||||||
assert "LOCAL_SOURCE=STATE_TARGET" in output_help
|
assert "LOCAL_SOURCE=STATE_TARGET" in output_help
|
||||||
assert "ordered canonical JSON array" in output_help
|
assert "ordered canonical JSON array" in output_help
|
||||||
assert "replace with no bindings" in output_help
|
assert "replace with no bindings" in output_help.lower()
|
||||||
assert "compatibility-only and potentially lossy" in output_help
|
assert "compatibility-only and potentially lossy" in output_help
|
||||||
assert "draft validate" in output_help
|
assert "draft validate" in output_help
|
||||||
assert "replaces the full workflow output map" in workflow_output_help
|
assert "replaces the full workflow output map" in workflow_output_help
|
||||||
|
|||||||
@@ -682,6 +682,7 @@ def test_wf_remote_draft_artifact_deploy_lifecycle(monkeypatch, tmp_path) -> Non
|
|||||||
"call",
|
"call",
|
||||||
"--map",
|
"--map",
|
||||||
"value=state.missing",
|
"value=state.missing",
|
||||||
|
"--merge",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert invalid_patch.exit_code == 0, invalid_patch.output
|
assert invalid_patch.exit_code == 0, invalid_patch.output
|
||||||
@@ -1174,7 +1175,7 @@ def test_wf_draft_focused_edit_commands_use_rpc_target(monkeypatch, tmp_path) ->
|
|||||||
"--step",
|
"--step",
|
||||||
"call",
|
"call",
|
||||||
"--map",
|
"--map",
|
||||||
"value=state.value",
|
"value=state.primary",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
input_merged = runner.invoke(
|
input_merged = runner.invoke(
|
||||||
@@ -1238,7 +1239,7 @@ def test_wf_draft_focused_edit_commands_use_rpc_target(monkeypatch, tmp_path) ->
|
|||||||
assert draft["steps"]["call"]["output"] == [
|
assert draft["steps"]["call"]["output"] == [
|
||||||
{
|
{
|
||||||
"source": "value",
|
"source": "value",
|
||||||
"target": "state.value",
|
"target": "state.primary",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "extra",
|
"source": "extra",
|
||||||
|
|||||||
@@ -103,7 +103,9 @@ async def test_registered_output_bindings_tool_delegates_typed_bindings_once(
|
|||||||
)
|
)
|
||||||
service = WfMcpService(
|
service = WfMcpService(
|
||||||
store=FileStore(tmp_path / "tool_invocation_store"),
|
store=FileStore(tmp_path / "tool_invocation_store"),
|
||||||
artifact_store=FileWorkflowArtifactStore(tmp_path / "tool_invocation_artifacts"),
|
artifact_store=FileWorkflowArtifactStore(
|
||||||
|
tmp_path / "tool_invocation_artifacts"
|
||||||
|
),
|
||||||
draft_workspace_store=FileDraftWorkspaceStore(
|
draft_workspace_store=FileDraftWorkspaceStore(
|
||||||
tmp_path / "tool_invocation_drafts"
|
tmp_path / "tool_invocation_drafts"
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -361,8 +361,14 @@ def test_workflow_surface_sets_ordered_canonical_step_output_bindings(
|
|||||||
revision=created["revision"],
|
revision=created["revision"],
|
||||||
step_id="call",
|
step_id="call",
|
||||||
bindings=[
|
bindings=[
|
||||||
OutputBinding(source="value", target="state.report"),
|
OutputBinding(
|
||||||
OutputBinding(source="value", target="state.audit"),
|
source=LocalPath.parse("value"),
|
||||||
|
target=StatePath.parse("state.report"),
|
||||||
|
),
|
||||||
|
OutputBinding(
|
||||||
|
source=LocalPath.parse("value"),
|
||||||
|
target=StatePath.parse("state.audit"),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user