type: narrow core model test fixtures
This commit is contained in:
@@ -221,13 +221,15 @@ def test_subgraph_ref_accepts_composite_child_input_binding() -> None:
|
|||||||
id="run_child",
|
id="run_child",
|
||||||
workflow=child,
|
workflow=child,
|
||||||
input=[
|
input=[
|
||||||
{
|
InputExpressionBinding.model_validate(
|
||||||
"target": "folder_id",
|
{
|
||||||
"expression": {
|
"target": "folder_id",
|
||||||
"kind": "literal",
|
"expression": {
|
||||||
"value": "demo-folder",
|
"kind": "literal",
|
||||||
},
|
"value": "demo-folder",
|
||||||
}
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,16 @@ from wf_core import (
|
|||||||
SchemaRef,
|
SchemaRef,
|
||||||
StateField,
|
StateField,
|
||||||
StateSchema,
|
StateSchema,
|
||||||
|
StepInputBinding,
|
||||||
SubgraphNode,
|
SubgraphNode,
|
||||||
Workflow,
|
Workflow,
|
||||||
WorkflowExecutionError,
|
WorkflowExecutionError,
|
||||||
|
WorkflowRef,
|
||||||
execute_workflow,
|
execute_workflow,
|
||||||
resume_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 (
|
from wf_core.runtime.input_bindings import (
|
||||||
resolve_input_expression,
|
resolve_input_expression,
|
||||||
resolve_step_input_bindings,
|
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:
|
def test_resolver_builds_nested_json_with_input_state_and_context_paths() -> None:
|
||||||
expression = InputExpressionBinding.model_validate(
|
expression = InputExpressionBinding.model_validate(
|
||||||
{
|
{
|
||||||
@@ -107,7 +115,12 @@ def test_simple_path_binding_preserves_legacy_value_identity() -> None:
|
|||||||
legacy_value = {"opaque": object()}
|
legacy_value = {"opaque": object()}
|
||||||
|
|
||||||
resolved = resolve_step_input_bindings(
|
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},
|
state={"value": legacy_value},
|
||||||
workflow_input={},
|
workflow_input={},
|
||||||
context={},
|
context={},
|
||||||
@@ -210,7 +223,7 @@ def test_normal_node_execution_resolves_composite_input() -> None:
|
|||||||
return {"outcome": "ok", "output": {}}
|
return {"outcome": "ok", "output": {}}
|
||||||
|
|
||||||
workflow = _node_workflow(
|
workflow = _node_workflow(
|
||||||
input_bindings=[COMPOSITE_BINDING],
|
input_bindings=[_composite_binding()],
|
||||||
state_fields={"foo": StateField(type="string", default="hello")},
|
state_fields={"foo": StateField(type="string", default="hello")},
|
||||||
)
|
)
|
||||||
run = execute_workflow(workflow, {}, {"concat": concat})
|
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:
|
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(
|
child = Workflow(
|
||||||
name="child",
|
name="child",
|
||||||
input_schema=_schema({"request": {"type": "object"}}),
|
input_schema=_schema({"request": {"type": "object"}}),
|
||||||
@@ -228,7 +242,7 @@ def test_prepared_subgraph_input_resolves_composite_input() -> None:
|
|||||||
output_schema=_schema({}),
|
output_schema=_schema({}),
|
||||||
outcomes=["ok"],
|
outcomes=["ok"],
|
||||||
start="done",
|
start="done",
|
||||||
nodes=[EndNode(id="done", type="end", outcome="ok")],
|
nodes=[child_step],
|
||||||
edges=[],
|
edges=[],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -290,9 +304,15 @@ def test_interrupt_request_resolves_composite_input_and_resume_continues() -> No
|
|||||||
|
|
||||||
def _node_workflow(
|
def _node_workflow(
|
||||||
*,
|
*,
|
||||||
input_bindings: list[dict[str, object]],
|
input_bindings: list[StepInputBinding],
|
||||||
state_fields: dict[str, StateField],
|
state_fields: dict[str, StateField],
|
||||||
) -> Workflow:
|
) -> Workflow:
|
||||||
|
node_step: Step = NodeUse(
|
||||||
|
id="concat",
|
||||||
|
type="node",
|
||||||
|
node="concat",
|
||||||
|
input=input_bindings,
|
||||||
|
)
|
||||||
return Workflow(
|
return Workflow(
|
||||||
name="node_expression",
|
name="node_expression",
|
||||||
input_schema=_schema({}),
|
input_schema=_schema({}),
|
||||||
@@ -308,19 +328,20 @@ def _node_workflow(
|
|||||||
outcomes=["ok"],
|
outcomes=["ok"],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
nodes=[
|
nodes=[node_step],
|
||||||
NodeUse(
|
|
||||||
id="concat",
|
|
||||||
type="node",
|
|
||||||
node="concat",
|
|
||||||
input=input_bindings,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
edges=[Edge.model_validate({"from": "concat", "outcome": "ok", "to": END})],
|
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(
|
return Workflow(
|
||||||
name="parent",
|
name="parent",
|
||||||
input_schema=_schema({}),
|
input_schema=_schema({}),
|
||||||
@@ -330,16 +351,7 @@ def _parent_subgraph_workflow(input_bindings: list[dict[str, object]]) -> Workfl
|
|||||||
output_schema=_schema({}),
|
output_schema=_schema({}),
|
||||||
outcomes=["ok"],
|
outcomes=["ok"],
|
||||||
start="child",
|
start="child",
|
||||||
nodes=[
|
nodes=[child_step],
|
||||||
SubgraphNode(
|
|
||||||
id="child",
|
|
||||||
type="subgraph",
|
|
||||||
workflow="child",
|
|
||||||
input_schema=_schema({"request": {"type": "object"}}),
|
|
||||||
output_schema=_schema({}),
|
|
||||||
input=input_bindings,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
edges=[Edge.model_validate({"from": "child", "outcome": "ok", "to": END})],
|
edges=[Edge.model_validate({"from": "child", "outcome": "ok", "to": END})],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from wf_artifacts.drafts.models import (
|
|||||||
)
|
)
|
||||||
from wf_core import Workflow
|
from wf_core import Workflow
|
||||||
from wf_core.models.input_bindings import ArrayExpression, LiteralExpression
|
from wf_core.models.input_bindings import ArrayExpression, LiteralExpression
|
||||||
|
from wf_core.models.json_values import JsonValue
|
||||||
from wf_core.models.steps import (
|
from wf_core.models.steps import (
|
||||||
InputExpressionBinding,
|
InputExpressionBinding,
|
||||||
InputPathBinding,
|
InputPathBinding,
|
||||||
@@ -152,8 +153,8 @@ def _nested_expression_array(depth: int) -> dict[str, object]:
|
|||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
def _nested_json_list(depth: int) -> list[object]:
|
def _nested_json_list(depth: int) -> list[JsonValue]:
|
||||||
value: list[object] = ["leaf"]
|
value: list[JsonValue] = ["leaf"]
|
||||||
for _ in range(depth - 1):
|
for _ in range(depth - 1):
|
||||||
value = [value]
|
value = [value]
|
||||||
return value
|
return value
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from collections.abc import Iterator, Mapping
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from wf_contract_manifest import generate_manifest
|
from wf_contract_manifest import generate_manifest
|
||||||
|
from wf_contract_manifest.model import ManifestOperation
|
||||||
|
|
||||||
UNION_RESULTS = {
|
UNION_RESULTS = {
|
||||||
"InspectCapabilityResult",
|
"InspectCapabilityResult",
|
||||||
@@ -148,7 +149,9 @@ def test_manifest_separates_recursive_step_inputs_from_workflow_outputs() -> Non
|
|||||||
} <= schemas.keys()
|
} <= schemas.keys()
|
||||||
|
|
||||||
input_binding_schema = schemas["InputExpressionBinding"]
|
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"
|
"$ref": "#/components/schemas/InputExpression"
|
||||||
}
|
}
|
||||||
expression_schema = schemas["InputExpression"]
|
expression_schema = schemas["InputExpression"]
|
||||||
@@ -162,7 +165,7 @@ def test_manifest_separates_recursive_step_inputs_from_workflow_outputs() -> Non
|
|||||||
"propertyName": "kind",
|
"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)
|
return next(item for item in manifest["operations"] if item["method"] == method)
|
||||||
|
|
||||||
step_input = operation("workflow.draft_workspaces.set_step_input_bindings")
|
step_input = operation("workflow.draft_workspaces.set_step_input_bindings")
|
||||||
|
|||||||
@@ -164,8 +164,8 @@ export const WorkflowGraph = ({
|
|||||||
: {})}
|
: {})}
|
||||||
fitView
|
fitView
|
||||||
proOptions={{ hideAttribution: true }}
|
proOptions={{ hideAttribution: true }}
|
||||||
nodesDraggable={false}
|
nodesDraggable={true}
|
||||||
nodesConnectable={false}
|
nodesConnectable={true}
|
||||||
elementsSelectable={Boolean(onNodeSelect || onEdgeSelect)}
|
elementsSelectable={Boolean(onNodeSelect || onEdgeSelect)}
|
||||||
>
|
>
|
||||||
<Background />
|
<Background />
|
||||||
|
|||||||
@@ -1698,7 +1698,7 @@ tbody tr:hover {
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
letter-spacing: 0.02em;
|
letter-spacing: 0.02em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
text-transform: uppercase;
|
/* text-transform: uppercase; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph-node__ref {
|
.graph-node__ref {
|
||||||
|
|||||||
Reference in New Issue
Block a user