Files
HAL9000 79d84c1d12
CI / push-validation (pull_request) Successful in 29s
CI / helm (pull_request) Successful in 35s
CI / lint (pull_request) Successful in 48s
CI / build (pull_request) Successful in 46s
CI / quality (pull_request) Successful in 58s
CI / typecheck (pull_request) Successful in 1m2s
CI / security (pull_request) Successful in 1m6s
CI / unit_tests (pull_request) Successful in 4m26s
CI / docker (pull_request) Successful in 1m30s
CI / integration_tests (pull_request) Successful in 9m49s
CI / coverage (pull_request) Successful in 9m4s
CI / status-check (pull_request) Successful in 3s
fix(robot): fix PureGraph Robot Framework tests and lint violations
- Remove unused `import ast` and fix `set_function_registry` to store
  callable values directly instead of calling eval() on a function object
- Replace try/except/pass with contextlib.suppress (SIM105)
- Add strict=False to zip() call (B905)
- Wrap long line in execute_graph (E501)
- Use list unpacking in assert_topo_order_equals (RUF005)
- Fix keyword name: Remove hyphen from 'Non-Functional' (Python method
  has no hyphen so Robot generates 'Non Functional')
- Rewrite Set Double And Increment Registry to evaluate lambdas directly
  rather than iterating a list of tuples (which paired whole tuples as
  loop variables instead of unpacking them)
- Pass node/function name lists via Robot list variables instead of
  space-delimited positional args

ISSUES CLOSED: #9531
2026-06-03 14:30:16 -04:00

140 lines
5.5 KiB
Python

"""Robot Framework library for PureGraph integration testing."""
import contextlib
class PureGraphLibrary:
"""Custom keywords for exercising PureGraph functionality."""
ROBOT_AUTO_KEYWORDS = True
def __init__(self):
self._graph = None
self._fn_registry = {}
self._topo_order = None
self._exec_result = None
# ------------------------------------------------------------------
# Graph construction helpers
# ------------------------------------------------------------------
def create_linear_graph_with_function_nodes(self, node_names, function_names):
"""Create a linear graph with the specified node and function names."""
from cleveragents.langgraph.nodes import Edge, NodeConfig, NodeType
from cleveragents.langgraph.pure_graph import PureGraph
nodes = {
"start": NodeConfig(name="start", type=NodeType.START),
"end": NodeConfig(name="end", type=NodeType.END),
}
edges = []
previous = "start"
for node_name, function_name in zip(node_names, function_names, strict=False):
nodes[node_name] = NodeConfig(
name=node_name, type=NodeType.FUNCTION, function=function_name
)
edges.append(Edge(source=previous, target=node_name))
previous = node_name
edges.append(Edge(source=previous, target="end"))
self._graph = PureGraph(name="robot-test-graph", nodes=nodes, edges=edges)
def create_linear_graph_with_non_functional_nodes(self, node_names):
"""Create a linear graph with non-functional (inert) nodes."""
from cleveragents.langgraph.nodes import Edge, NodeConfig, NodeType
from cleveragents.langgraph.pure_graph import PureGraph
nodes = {
"start": NodeConfig(name="start", type=NodeType.START),
"end": NodeConfig(name="end", type=NodeType.END),
}
edges = []
previous = "start"
for node_name in node_names:
nodes[node_name] = NodeConfig(
name=node_name, type=NodeType.FUNCTION, function=None
)
edges.append(Edge(source=previous, target=node_name))
previous = node_name
edges.append(Edge(source=previous, target="end"))
self._graph = PureGraph(name="robot-test-inert", nodes=nodes, edges=edges)
def create_graph_with_missing_function(self, unregistered_fn_name):
"""Create a graph where a node references a function not in the registry."""
from cleveragents.langgraph.nodes import Edge, NodeConfig, NodeType
from cleveragents.langgraph.pure_graph import PureGraph
nodes = {
"start": NodeConfig(name="start", type=NodeType.START),
"end": NodeConfig(name="end", type=NodeType.END),
}
edges = []
previous = "start"
node_name = f"skipper_{unregistered_fn_name}"
nodes[node_name] = NodeConfig(
name=node_name, type=NodeType.FUNCTION, function=unregistered_fn_name
)
edges.append(Edge(source=previous, target=node_name))
previous = node_name
edges.append(Edge(source=previous, target="end"))
self._graph = PureGraph(name="robot-test-missing-fn", nodes=nodes, edges=edges)
self._fn_registry = {}
def set_function_registry(self, registry_dict):
"""Set or update the function registry used by execute()."""
self._fn_registry = {}
for key, value in registry_dict.items():
if callable(value):
self._fn_registry[key] = value
elif isinstance(value, str):
with contextlib.suppress(Exception):
self._fn_registry[key] = eval(value)
# ------------------------------------------------------------------
# Topological order queries
# ------------------------------------------------------------------
def compute_topological_order(self):
"""Compute and return the topological ordering of the current graph."""
self._topo_order = self._graph.topological_order()
def get_topological_order(self):
"""Return the last computed topological order as a list."""
return self._topo_order or []
# ------------------------------------------------------------------
# Execution queries
# ------------------------------------------------------------------
def execute_graph(self, initial_value):
"""Execute the current graph starting with the given initial value."""
self._exec_result = self._graph.execute(
self._fn_registry, initial=initial_value
)
return self._exec_result
def get_execution_result(self):
"""Return the last execution result."""
return self._exec_result
# ------------------------------------------------------------------
# Assertion helpers
# ------------------------------------------------------------------
def assert_topo_order_equals(self, *expected_nodes):
"""Assert topological order matches expected: [start, nodes..., end]."""
actual = self._topo_order or []
expected = ["start", *expected_nodes, "end"]
if actual != expected:
raise AssertionError(
f"Topological order mismatch: expected {expected}, got {actual}"
)
def assert_execution_result_equals(self, expected):
"""Assert the last execution result equals expected value."""
actual = self._exec_result
if actual != expected:
raise AssertionError(f"Expected {expected}, got {actual}")