type: narrow core model test fixtures

This commit is contained in:
lda
2026-08-29 19:10:30 +07:00 Verified
parent ac09a577a2
commit c87911236a
6 changed files with 57 additions and 39 deletions
+2
View File
@@ -221,6 +221,7 @@ def test_subgraph_ref_accepts_composite_child_input_binding() -> None:
id="run_child",
workflow=child,
input=[
InputExpressionBinding.model_validate(
{
"target": "folder_id",
"expression": {
@@ -228,6 +229,7 @@ def test_subgraph_ref_accepts_composite_child_input_binding() -> None:
"value": "demo-folder",
},
}
)
],
)
+37 -25
View File
@@ -15,13 +15,16 @@ from wf_core import (
SchemaRef,
StateField,
StateSchema,
StepInputBinding,
SubgraphNode,
Workflow,
WorkflowExecutionError,
WorkflowRef,
execute_workflow,
resume_workflow,
)
from wf_core.models.steps import InterruptNode
from wf_core.models.steps import InterruptNode, Step
from wf_core.paths import GraphSourcePath, LocalPath
from wf_core.runtime.input_bindings import (
resolve_input_expression,
resolve_step_input_bindings,
@@ -45,6 +48,11 @@ COMPOSITE_BINDING = {
}
def _composite_binding() -> StepInputBinding:
"""Build this raw fixture through the canonical binding model."""
return InputExpressionBinding.model_validate(COMPOSITE_BINDING)
def test_resolver_builds_nested_json_with_input_state_and_context_paths() -> None:
expression = InputExpressionBinding.model_validate(
{
@@ -107,7 +115,12 @@ def test_simple_path_binding_preserves_legacy_value_identity() -> None:
legacy_value = {"opaque": object()}
resolved = resolve_step_input_bindings(
[InputPathBinding(target="request.value", path="state.value")],
[
InputPathBinding(
target=LocalPath.parse("request.value"),
path=GraphSourcePath.parse("state.value"),
)
],
state={"value": legacy_value},
workflow_input={},
context={},
@@ -210,7 +223,7 @@ def test_normal_node_execution_resolves_composite_input() -> None:
return {"outcome": "ok", "output": {}}
workflow = _node_workflow(
input_bindings=[COMPOSITE_BINDING],
input_bindings=[_composite_binding()],
state_fields={"foo": StateField(type="string", default="hello")},
)
run = execute_workflow(workflow, {}, {"concat": concat})
@@ -220,7 +233,8 @@ def test_normal_node_execution_resolves_composite_input() -> None:
def test_prepared_subgraph_input_resolves_composite_input() -> None:
parent = _parent_subgraph_workflow([COMPOSITE_BINDING])
parent = _parent_subgraph_workflow([_composite_binding()])
child_step: Step = EndNode(id="done", type="end", outcome="ok")
child = Workflow(
name="child",
input_schema=_schema({"request": {"type": "object"}}),
@@ -228,7 +242,7 @@ def test_prepared_subgraph_input_resolves_composite_input() -> None:
output_schema=_schema({}),
outcomes=["ok"],
start="done",
nodes=[EndNode(id="done", type="end", outcome="ok")],
nodes=[child_step],
edges=[],
)
@@ -290,9 +304,15 @@ def test_interrupt_request_resolves_composite_input_and_resume_continues() -> No
def _node_workflow(
*,
input_bindings: list[dict[str, object]],
input_bindings: list[StepInputBinding],
state_fields: dict[str, StateField],
) -> Workflow:
node_step: Step = NodeUse(
id="concat",
type="node",
node="concat",
input=input_bindings,
)
return Workflow(
name="node_expression",
input_schema=_schema({}),
@@ -308,19 +328,20 @@ def _node_workflow(
outcomes=["ok"],
)
],
nodes=[
NodeUse(
id="concat",
type="node",
node="concat",
input=input_bindings,
)
],
nodes=[node_step],
edges=[Edge.model_validate({"from": "concat", "outcome": "ok", "to": END})],
)
def _parent_subgraph_workflow(input_bindings: list[dict[str, object]]) -> Workflow:
def _parent_subgraph_workflow(input_bindings: list[StepInputBinding]) -> Workflow:
child_step: Step = SubgraphNode(
id="child",
type="subgraph",
workflow=WorkflowRef(name="child"),
input_schema=_schema({"request": {"type": "object"}}),
output_schema=_schema({}),
input=input_bindings,
)
return Workflow(
name="parent",
input_schema=_schema({}),
@@ -330,16 +351,7 @@ def _parent_subgraph_workflow(input_bindings: list[dict[str, object]]) -> Workfl
output_schema=_schema({}),
outcomes=["ok"],
start="child",
nodes=[
SubgraphNode(
id="child",
type="subgraph",
workflow="child",
input_schema=_schema({"request": {"type": "object"}}),
output_schema=_schema({}),
input=input_bindings,
)
],
nodes=[child_step],
edges=[Edge.model_validate({"from": "child", "outcome": "ok", "to": END})],
)
+3 -2
View File
@@ -13,6 +13,7 @@ from wf_artifacts.drafts.models import (
)
from wf_core import Workflow
from wf_core.models.input_bindings import ArrayExpression, LiteralExpression
from wf_core.models.json_values import JsonValue
from wf_core.models.steps import (
InputExpressionBinding,
InputPathBinding,
@@ -152,8 +153,8 @@ def _nested_expression_array(depth: int) -> dict[str, object]:
return expression
def _nested_json_list(depth: int) -> list[object]:
value: list[object] = ["leaf"]
def _nested_json_list(depth: int) -> list[JsonValue]:
value: list[JsonValue] = ["leaf"]
for _ in range(depth - 1):
value = [value]
return value
+5 -2
View File
@@ -4,6 +4,7 @@ from collections.abc import Iterator, Mapping
from typing import Any
from wf_contract_manifest import generate_manifest
from wf_contract_manifest.model import ManifestOperation
UNION_RESULTS = {
"InspectCapabilityResult",
@@ -148,7 +149,9 @@ def test_manifest_separates_recursive_step_inputs_from_workflow_outputs() -> Non
} <= schemas.keys()
input_binding_schema = schemas["InputExpressionBinding"]
assert input_binding_schema["properties"]["expression"] == {
properties = input_binding_schema.get("properties")
assert isinstance(properties, dict)
assert properties["expression"] == {
"$ref": "#/components/schemas/InputExpression"
}
expression_schema = schemas["InputExpression"]
@@ -162,7 +165,7 @@ def test_manifest_separates_recursive_step_inputs_from_workflow_outputs() -> Non
"propertyName": "kind",
}
def operation(method: str) -> dict[str, Any]:
def operation(method: str) -> ManifestOperation:
return next(item for item in manifest["operations"] if item["method"] == method)
step_input = operation("workflow.draft_workspaces.set_step_input_bindings")
+2 -2
View File
@@ -164,8 +164,8 @@ export const WorkflowGraph = ({
: {})}
fitView
proOptions={{ hideAttribution: true }}
nodesDraggable={false}
nodesConnectable={false}
nodesDraggable={true}
nodesConnectable={true}
elementsSelectable={Boolean(onNodeSelect || onEdgeSelect)}
>
<Background />
+1 -1
View File
@@ -1698,7 +1698,7 @@ tbody tr:hover {
font-weight: 700;
letter-spacing: 0.02em;
line-height: 1;
text-transform: uppercase;
/* text-transform: uppercase; */
}
.graph-node__ref {