forked from cleveragents/cleveragents-core
9f2e7e88b0
Add PlanApplyService with diff(), artifacts(), persist_apply_summary(), handle_merge_failure(), and guard_empty_changeset() methods. - plan diff: renders changeset in rich/plain/json/yaml formats - plan artifacts: shows plan metadata, changeset summary, sandbox refs - persist_apply_summary: stores files_changed/validations_run in plan metadata - handle_merge_failure: transitions plan to error state with conflict details - guard_empty_changeset: blocks apply on empty changeset (--allow-empty override) CLI: plan diff and plan artifacts commands with --format flag. Tests: 20 Behave scenarios, 8 Robot integration tests, 4 ASV benchmarks. Docs: docs/reference/plan_apply.md with CLI reference. Implements D0b.apply from the implementation plan.
141 lines
5.5 KiB
Gherkin
141 lines
5.5 KiB
Gherkin
Feature: Plan Diff and Artifacts Output
|
|
As a developer using the plan lifecycle
|
|
I want to review diffs and artifacts before applying changes
|
|
So that I can verify what will be applied and catch issues early
|
|
|
|
Background:
|
|
Given I have a plan apply service with an in-memory changeset store
|
|
|
|
# Diff output tests
|
|
|
|
Scenario: Plan diff shows file changes in rich format
|
|
Given a plan with a changeset containing file changes
|
|
When I request the diff in rich format
|
|
Then the diff output should contain the changeset ID
|
|
And the diff output should contain file paths
|
|
And the diff output should contain operation labels
|
|
|
|
Scenario: Plan diff shows file changes in plain format
|
|
Given a plan with a changeset containing file changes
|
|
When I request the diff in plain format
|
|
Then the diff output should contain unified diff markers
|
|
And the diff output should contain the plan ID
|
|
|
|
Scenario: Plan diff shows file changes in JSON format
|
|
Given a plan with a changeset containing file changes
|
|
When I request the diff in JSON format
|
|
Then the diff output should be valid JSON
|
|
And the JSON diff should contain entries list
|
|
And the JSON diff should contain summary counts
|
|
|
|
Scenario: Plan diff shows file changes in YAML format
|
|
Given a plan with a changeset containing file changes
|
|
When I request the diff in YAML format
|
|
Then the diff output should contain YAML keys
|
|
And the diff output should contain the changeset ID
|
|
|
|
Scenario: Plan diff raises error when no changeset exists
|
|
Given a plan with no changeset
|
|
When I try to get the diff
|
|
Then a plan error about missing changeset should be raised
|
|
|
|
Scenario: Plan diff with empty changeset shows no changes
|
|
Given a plan with an empty changeset
|
|
When I request the diff in rich format
|
|
Then the diff output should indicate no changes
|
|
|
|
# Artifacts output tests
|
|
|
|
Scenario: Plan artifacts shows changeset summary
|
|
Given a plan with a changeset containing file changes
|
|
When I request the artifacts
|
|
Then the artifacts should contain the plan ID
|
|
And the artifacts should contain the changeset ID
|
|
And the artifacts should contain sandbox refs
|
|
And the artifacts should contain files changed list
|
|
|
|
Scenario: Plan artifacts shows validation results when available
|
|
Given a plan with a changeset and validation summary
|
|
When I request the artifacts in JSON format
|
|
Then the artifacts JSON should contain validation summary
|
|
|
|
Scenario: Plan artifacts for plan without changeset
|
|
Given a plan with no changeset
|
|
When I request the artifacts
|
|
Then the artifacts should show null changeset
|
|
|
|
# Empty ChangeSet guard tests
|
|
|
|
Scenario: Apply with empty changeset is blocked
|
|
Given a plan with an empty changeset
|
|
When I check the empty changeset guard
|
|
Then a plan error about empty changeset should be raised
|
|
|
|
Scenario: Apply with empty changeset allowed via flag
|
|
Given a plan with an empty changeset
|
|
When I check the empty changeset guard with allow_empty
|
|
Then the guard should return True
|
|
|
|
Scenario: Apply with non-empty changeset passes guard
|
|
Given a plan with a changeset containing file changes
|
|
When I check the empty changeset guard
|
|
Then the guard should return True
|
|
|
|
# Apply summary persistence tests
|
|
|
|
Scenario: Apply persists summary metadata
|
|
Given a plan in apply processing state
|
|
When I persist the apply summary with 5 files and 3 validations
|
|
Then the plan metadata should contain apply_files_changed of 5
|
|
And the plan metadata should contain apply_validations_run of 3
|
|
And the plan metadata should contain apply_completed_at timestamp
|
|
|
|
# Merge failure handling tests
|
|
|
|
Scenario: Merge failure triggers error state
|
|
Given a plan in apply processing state
|
|
When a merge failure occurs with conflict details
|
|
Then the plan should be in errored state
|
|
And the plan error message should contain merge conflict info
|
|
And the plan metadata should contain merge_conflict details
|
|
And the plan metadata should contain sandbox_rollback pending
|
|
|
|
# Service initialization tests
|
|
|
|
Scenario: PlanApplyService requires lifecycle service
|
|
When I try to create PlanApplyService with None lifecycle
|
|
Then a validation error should be raised for lifecycle service
|
|
|
|
# Multiple format outputs
|
|
|
|
Scenario: Artifacts output in plain format
|
|
Given a plan with a changeset containing file changes
|
|
When I request the artifacts in plain format
|
|
Then the artifacts output should contain key-value pairs
|
|
|
|
Scenario: Artifacts output in YAML format
|
|
Given a plan with a changeset containing file changes
|
|
When I request the artifacts in YAML format
|
|
Then the artifacts output should contain YAML structure
|
|
|
|
# Coverage: _render_diff_plain with empty changeset (line 70)
|
|
|
|
Scenario: Plan diff in plain format with empty changeset
|
|
Given a plan with an empty changeset
|
|
When I request the diff in plain format
|
|
Then the diff output should indicate no changes
|
|
|
|
# Coverage: artifacts with apply summary metadata (line 181)
|
|
|
|
Scenario: Artifacts include apply summary from metadata
|
|
Given a plan with a changeset and apply summary metadata
|
|
When I request the artifacts in JSON format
|
|
Then the artifacts JSON should contain apply summary
|
|
|
|
# Coverage: changeset store miss fallback (line 432)
|
|
|
|
Scenario: Diff falls back to stub changeset when store misses
|
|
Given a plan with a changeset ID but store has no entry
|
|
When I request the diff in rich format
|
|
Then the diff output should indicate no changes
|