improve autoid
This commit is contained in:
@@ -21,6 +21,7 @@ from wf_core import (
|
|||||||
)
|
)
|
||||||
from wf_core.errors import WorkflowExecutionError
|
from wf_core.errors import WorkflowExecutionError
|
||||||
from wf_core.models.conditions import Condition as CoreCondition
|
from wf_core.models.conditions import Condition as CoreCondition
|
||||||
|
from wf_core.models.conditions import BinaryCondition, ExistsCondition, PathOperand
|
||||||
from wf_core.runtime.ops.merges import ReducerDefinition
|
from wf_core.runtime.ops.merges import ReducerDefinition
|
||||||
|
|
||||||
from ..dsl import Expr, PathArg, PathExpr, compile_condition
|
from ..dsl import Expr, PathArg, PathExpr, compile_condition
|
||||||
@@ -40,6 +41,17 @@ from .mapping import (
|
|||||||
from .refs import BranchRef, RouteRef, StepRef, is_node_spec, step_id
|
from .refs import BranchRef, RouteRef, StepRef, is_node_spec, step_id
|
||||||
|
|
||||||
|
|
||||||
|
def _condition_base(condition: CoreCondition) -> str:
|
||||||
|
"""Return a small source-derived id base when one path is obvious."""
|
||||||
|
if isinstance(condition, ExistsCondition):
|
||||||
|
return slug_id(condition.path)
|
||||||
|
if isinstance(condition, BinaryCondition) and isinstance(
|
||||||
|
condition.left, PathOperand
|
||||||
|
):
|
||||||
|
return slug_id(condition.left.path)
|
||||||
|
return "condition"
|
||||||
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class WorkflowBuilder:
|
class WorkflowBuilder:
|
||||||
name: str
|
name: str
|
||||||
@@ -162,10 +174,11 @@ class WorkflowBuilder:
|
|||||||
def condition(
|
def condition(
|
||||||
self, *, id: str | None = None, check: CoreCondition | Expr
|
self, *, id: str | None = None, check: CoreCondition | Expr
|
||||||
) -> ConditionNode:
|
) -> ConditionNode:
|
||||||
|
compiled = compile_condition(check)
|
||||||
node = ConditionNode(
|
node = ConditionNode(
|
||||||
id=id or self._next_step_id("condition"),
|
id=id or self._next_step_id(_condition_base(compiled)),
|
||||||
type="condition",
|
type="condition",
|
||||||
check=compile_condition(check),
|
check=compiled,
|
||||||
)
|
)
|
||||||
self.nodes.append(node)
|
self.nodes.append(node)
|
||||||
return node
|
return node
|
||||||
@@ -273,7 +286,7 @@ class WorkflowBuilder:
|
|||||||
conditions: list[ConditionNode] = []
|
conditions: list[ConditionNode] = []
|
||||||
default_target = self.use(default) if is_node_spec(default) else default
|
default_target = self.use(default) if is_node_spec(default) else default
|
||||||
previous_condition: ConditionNode | None = None
|
previous_condition: ConditionNode | None = None
|
||||||
condition_base = id or "condition"
|
condition_base = id or slug_id(value.path)
|
||||||
for case_value, target in cases.items():
|
for case_value, target in cases.items():
|
||||||
condition = self.condition(
|
condition = self.condition(
|
||||||
id=self._next_step_id(condition_base),
|
id=self._next_step_id(condition_base),
|
||||||
@@ -334,7 +347,7 @@ class WorkflowBuilder:
|
|||||||
conditions: list[ConditionNode] = []
|
conditions: list[ConditionNode] = []
|
||||||
resolved_targets: dict[object, StepRef] = {}
|
resolved_targets: dict[object, StepRef] = {}
|
||||||
previous_condition: ConditionNode | None = None
|
previous_condition: ConditionNode | None = None
|
||||||
condition_base = id or "condition"
|
condition_base = id or _condition_base(compile_condition(clauses[0][0]))
|
||||||
for index, (condition_expr, target) in enumerate(clauses):
|
for index, (condition_expr, target) in enumerate(clauses):
|
||||||
condition = self.condition(
|
condition = self.condition(
|
||||||
id=self._next_step_id(condition_base),
|
id=self._next_step_id(condition_base),
|
||||||
|
|||||||
@@ -164,8 +164,8 @@ def test_builder_can_auto_id_condition_foreach_and_interrupt() -> None:
|
|||||||
foreach = builder.foreach(over="state.tags", as_="tag")
|
foreach = builder.foreach(over="state.tags", as_="tag")
|
||||||
interrupt = builder.interrupt(kind="approval")
|
interrupt = builder.interrupt(kind="approval")
|
||||||
|
|
||||||
assert first_condition.id == "condition"
|
assert first_condition.id == "state_count"
|
||||||
assert second_condition.id == "condition_2"
|
assert second_condition.id == "state_count_2"
|
||||||
assert foreach.id == "foreach_tag"
|
assert foreach.id == "foreach_tag"
|
||||||
assert interrupt.id == "interrupt_approval"
|
assert interrupt.id == "interrupt_approval"
|
||||||
|
|
||||||
|
|||||||
@@ -84,15 +84,15 @@ def test_builder_match_expands_state_value_cases_into_condition_chain() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert [node.id for node in targets.conditions] == [
|
assert [node.id for node in targets.conditions] == [
|
||||||
"condition",
|
"state_value",
|
||||||
"condition_2",
|
"state_value_2",
|
||||||
]
|
]
|
||||||
assert targets.entry.id == "condition"
|
assert targets.entry.id == "state_value"
|
||||||
assert [(edge.from_, edge.outcome, edge.to) for edge in builder.edges] == [
|
assert [(edge.from_, edge.outcome, edge.to) for edge in builder.edges] == [
|
||||||
("condition", "true", "left"),
|
("state_value", "true", "left"),
|
||||||
("condition", "false", "condition_2"),
|
("state_value", "false", "state_value_2"),
|
||||||
("condition_2", "true", "right"),
|
("state_value_2", "true", "right"),
|
||||||
("condition_2", "false", "fallback"),
|
("state_value_2", "false", "fallback"),
|
||||||
]
|
]
|
||||||
assert targets["left"] is left
|
assert targets["left"] is left
|
||||||
assert targets["right"] is right
|
assert targets["right"] is right
|
||||||
@@ -135,11 +135,11 @@ def test_builder_when_routes_one_boolean_condition_expression() -> None:
|
|||||||
|
|
||||||
targets = builder.when(state("count").ge(1), then=left, otherwise=right)
|
targets = builder.when(state("count").ge(1), then=left, otherwise=right)
|
||||||
|
|
||||||
assert targets.entry.id == "condition"
|
assert targets.entry.id == "state_count"
|
||||||
assert [node.id for node in targets.conditions] == ["condition"]
|
assert [node.id for node in targets.conditions] == ["state_count"]
|
||||||
assert [(edge.from_, edge.outcome, edge.to) for edge in builder.edges] == [
|
assert [(edge.from_, edge.outcome, edge.to) for edge in builder.edges] == [
|
||||||
("condition", "true", "left"),
|
("state_count", "true", "left"),
|
||||||
("condition", "false", "right"),
|
("state_count", "false", "right"),
|
||||||
]
|
]
|
||||||
assert targets[True] is left
|
assert targets[True] is left
|
||||||
assert targets[False] is right
|
assert targets[False] is right
|
||||||
|
|||||||
Reference in New Issue
Block a user