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
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
119 lines
6.1 KiB
Gherkin
119 lines
6.1 KiB
Gherkin
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"
|