Files
cleveragents-core/features/plan_lifecycle_error_r2.feature
freemo 3a2b134f3c
CI / lint (pull_request) Successful in 14s
CI / benchmark-publish (pull_request) Has been skipped
CI / quality (pull_request) Successful in 27s
CI / typecheck (pull_request) Successful in 37s
CI / security (pull_request) Successful in 39s
CI / build (pull_request) Successful in 29s
CI / integration_tests (pull_request) Successful in 5m51s
CI / benchmark-regression (pull_request) Successful in 22m39s
CI / unit_tests (pull_request) Successful in 29m35s
CI / docker (pull_request) Successful in 13s
CI / coverage (pull_request) Successful in 2h3m1s
CI / lint (push) Successful in 21s
CI / typecheck (push) Successful in 57s
CI / security (push) Successful in 51s
CI / quality (push) Successful in 27s
CI / integration_tests (push) Successful in 4m59s
CI / build (push) Successful in 23s
CI / benchmark-publish (push) Successful in 14m39s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 29m48s
CI / docker (push) Successful in 15s
CI / coverage (push) Successful in 1h45m42s
test(coverage): add Behave scenarios for remaining under-tested modules
Added Behave BDD feature files and step definitions targeting coverage
gaps in six modules:

- container.py: exercise get_database_url env-var fallback, AI provider
  None path, cached container singleton, override_providers edge cases
  (lines 66-69, 125-130; branches at 51, 57, 82, 87, 256, 284-288)
- correction_service.py: exercise exception-handling paths in
  execute_revert and execute_append via monkeypatched analyze_impact
  and ULID failures (lines 254-262, 320-328)
- plan_lifecycle_service.py: exercise _persisted UoW commit paths,
  InvalidPhaseTransitionError custom message branch, non-reusable
  action archive, and error_details merge logic (branches at 100,
  216, 237, 327, 461, 570, 576, 607)
- plan.py (CLI): exercise spec-dict optional field branches,
  _print_lifecycle_plan conditional rendering, use_action argument
  parsing, auto-resolve paths, legacy wrappers, and validation
  error branches across 66 scenarios
- skill.py (CLI): exercise singleton cache, timestamp-absent show,
  no-tools MCP, add/remove/list/show format and error branches
  across 26 scenarios
- models.py (DB): exercise to_domain/from_domain None-field branches
  in SkillModel, SessionModel, ToolModel, LifecycleActionModel,
  LifecyclePlanModel, NamespacedProjectModel, and SessionMessageModel
  across 41 scenarios

All 302 features, 6503 scenarios, 28271 steps pass (nox -e unit_tests).

ISSUES CLOSED: #446
2026-02-25 19:38:43 -05:00

119 lines
6.1 KiB
Gherkin
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Feature: PlanLifecycleService error and persistence branch coverage (round 2)
As a developer maintaining PlanLifecycleService
I want every partial branch fully exercised
So that plan_lifecycle_service.py branch coverage reaches 100%
# Targets the following partial branches:
# Line 100 InvalidPhaseTransitionError.__init__ `if not message:` False branch
# Line 216 _commit_plan `if self._persisted ` True branch (via mock UoW)
# Line 327 create_action `if self._persisted ` True branch
# Line 364 get_action `if self._persisted ` True branch (not-found fallback)
# Line 461 archive_action `if self._persisted ` True branch
# Line 570 use_action `if self._persisted ` True branch
# Line 607 get_plan `if self._persisted ` True branch (not-found fallback)
# -------------------------------------------------------------------
# In-memory mode (no UoW) validates False side of _persisted checks
# -------------------------------------------------------------------
Background:
Given r2plc-a fresh plan lifecycle service with mock UoW
# -------------------------------------------------------------------
# InvalidPhaseTransitionError with custom message (line 100 False)
# -------------------------------------------------------------------
Scenario: InvalidPhaseTransitionError raised with explicit custom message
When r2plc-I construct InvalidPhaseTransitionError with a custom message
Then r2plc-the error message should be the custom message
And r2plc-the from_phase should be STRATEGIZE
And r2plc-the to_phase should be APPLY
Scenario: InvalidPhaseTransitionError raised with default message
When r2plc-I construct InvalidPhaseTransitionError without a message
Then r2plc-the error message should contain "Invalid phase transition"
And r2plc-the from_phase should be STRATEGIZE
And r2plc-the to_phase should be EXECUTE
Scenario: revert_plan raises InvalidPhaseTransitionError with custom message
Given r2plc-a plan in STRATEGIZE phase
When r2plc-I attempt to revert the plan to APPLY phase
Then r2plc-an InvalidPhaseTransitionError should have been raised
And r2plc-the caught error message should contain "Cannot revert"
# -------------------------------------------------------------------
# _commit_plan in persisted mode (line 216 True)
# -------------------------------------------------------------------
Scenario: _commit_plan persists via UoW when persisted mode is active
Given r2plc-a plan in STRATEGIZE phase
When r2plc-I start strategize on the plan
Then r2plc-the mock UoW should have received a plan update call
Scenario: fail_strategize commits plan via persisted _commit_plan
Given r2plc-a plan in STRATEGIZE PROCESSING state
When r2plc-I fail the strategize with error "something broke"
Then r2plc-the mock UoW should have received a plan update call
And r2plc-the plan processing state should be "errored"
# -------------------------------------------------------------------
# create_action persisted mode (line 327 True)
# -------------------------------------------------------------------
Scenario: create_action persists via UoW when persisted
When r2plc-I create an action "local/r2-persist-test" in persisted mode
Then r2plc-the mock UoW should have received an action create call
And r2plc-the action should also be in the in-memory cache
# -------------------------------------------------------------------
# use_action persisted mode (line 570 True)
# -------------------------------------------------------------------
Scenario: use_action persists the new plan via UoW
Given r2plc-an action "local/r2-use-persist" exists
When r2plc-I use the action to create a plan in persisted mode
Then r2plc-the mock UoW should have received a plan create call
And r2plc-the plan should also be in the in-memory plan cache
# -------------------------------------------------------------------
# archive_action persisted mode (line 461 True)
# -------------------------------------------------------------------
Scenario: archive_action persists via UoW when persisted
Given r2plc-an action "local/r2-archive-persist" exists
When r2plc-I archive the action "local/r2-archive-persist" in persisted mode
Then r2plc-the mock UoW should have received an action update call
And r2plc-the action state should be archived
# -------------------------------------------------------------------
# get_action persistence fallback returns None (line 364-370)
# -------------------------------------------------------------------
Scenario: get_action raises NotFoundError when persistence also returns None
When r2plc-I attempt to get action "local/nonexistent-r2" in persisted mode
Then r2plc-a NotFoundError should have been raised for action
# -------------------------------------------------------------------
# get_plan persistence fallback returns None (line 607-613)
# -------------------------------------------------------------------
Scenario: get_plan raises NotFoundError when persistence also returns None
When r2plc-I attempt to get plan "01ZZZZZZZZZZZZZZZZZZZZZZZZ" in persisted mode
Then r2plc-a NotFoundError should have been raised for plan
# -------------------------------------------------------------------
# update_error_details in persisted mode (hits _commit_plan True)
# -------------------------------------------------------------------
Scenario: update_error_details merges details and persists
Given r2plc-a plan in STRATEGIZE phase
When r2plc-I update error details with key "reason" value "timeout"
Then r2plc-the plan error_details should contain key "reason"
And r2plc-the mock UoW should have received a plan update call
Scenario: update_error_details merges into existing error_details
Given r2plc-a plan in STRATEGIZE phase with existing error_details
When r2plc-I update error details with key "extra" value "info"
Then r2plc-the plan error_details should contain key "extra"
And r2plc-the plan error_details should contain key "original"