"""Step definitions for devcontainer_sandbox_strategy.feature. Tests that devcontainer-instance uses snapshot sandbox strategy, has the correct child types, and that ContainerLifecycleState uses 'discovered' as the initial state. """ from __future__ import annotations from behave import then, when from behave.runner import Context from cleveragents.application.services._resource_registry_data import ( BUILTIN_TYPES, ) from cleveragents.domain.models.core.container_lifecycle import ( ContainerLifecycleTracker, ) from cleveragents.resource.handlers.devcontainer import DevcontainerHandler # ── When steps ─────────────────────────────────────────────── @when("I inspect DevcontainerHandler class attributes") def step_inspect_devcontainer_handler(context: Context) -> None: """Capture DevcontainerHandler class attributes for inspection.""" context.devcontainer_handler_strategy = DevcontainerHandler._default_strategy @when('I create a new ContainerLifecycleTracker for resource "{resource_id}"') def step_create_tracker_for_sandbox(context: Context, resource_id: str) -> None: """Create a new ContainerLifecycleTracker with default state.""" context.sandbox_tracker = ContainerLifecycleTracker(resource_id=resource_id) @when('I look up "{type_name}" in BUILTIN_TYPES') def step_look_up_in_builtin_types(context: Context, type_name: str) -> None: """Look up a resource type entry in BUILTIN_TYPES.""" context.builtin_type_entry = None for entry in BUILTIN_TYPES: if entry.get("name") == type_name: context.builtin_type_entry = entry break # ── Then steps ─────────────────────────────────────────────── @then('the DevcontainerHandler _default_strategy should be "{expected}"') def step_devcontainer_handler_strategy(context: Context, expected: str) -> None: strategy = context.devcontainer_handler_strategy strategy_value = strategy.value if hasattr(strategy, "value") else str(strategy) assert strategy_value == expected, ( f"Expected DevcontainerHandler._default_strategy to be '{expected}', " f"got '{strategy_value}'" ) @then('the spec sandbox_strategy should be "{expected}"') def step_spec_sandbox_strategy(context: Context, expected: str) -> None: spec = context.resource_type_spec assert spec is not None, "No resource type spec found" actual = spec.get("sandbox_strategy") assert actual == expected, f"Expected sandbox_strategy '{expected}', got '{actual}'" @then('the spec child_types should contain "{child_type}"') def step_spec_child_types_contains(context: Context, child_type: str) -> None: spec = context.resource_type_spec assert spec is not None, "No resource type spec found" child_types: list[str] = spec.get("child_types", []) assert child_type in child_types, ( f"Expected '{child_type}' in child_types {child_types}" ) @then('the tracker initial state should be "{expected}"') def step_tracker_initial_state(context: Context, expected: str) -> None: tracker = context.sandbox_tracker actual = tracker.current_state.value assert actual == expected, ( f"Expected initial tracker state '{expected}', got '{actual}'" ) @then('the lifecycle enum values should contain "{expected}"') def step_lifecycle_enum_contains(context: Context, expected: str) -> None: values = context.enum_values assert expected in values, ( f"Expected '{expected}' in lifecycle enum values {values}" ) @then('the lifecycle enum values should not contain "{unexpected}"') def step_lifecycle_enum_not_contains(context: Context, unexpected: str) -> None: values = context.enum_values assert unexpected not in values, ( f"Expected '{unexpected}' NOT to be in lifecycle enum values {values}" ) @then('the BUILTIN_TYPES entry sandbox_strategy should be "{expected}"') def step_builtin_types_sandbox_strategy(context: Context, expected: str) -> None: entry = context.builtin_type_entry assert entry is not None, "No BUILTIN_TYPES entry found" actual = entry.get("sandbox_strategy") assert actual == expected, ( f"Expected BUILTIN_TYPES sandbox_strategy '{expected}', got '{actual}'" ) @then('the BUILTIN_TYPES entry child_types should include "{child_type}"') def step_builtin_types_child_types(context: Context, child_type: str) -> None: entry = context.builtin_type_entry assert entry is not None, "No BUILTIN_TYPES entry found" child_types: list[str] = entry.get("child_types", []) assert child_type in child_types, ( f"Expected '{child_type}' in BUILTIN_TYPES child_types {child_types}" )