c9abb45adf
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 16s
CI / quality (pull_request) Successful in 18s
CI / security (pull_request) Successful in 31s
CI / typecheck (pull_request) Successful in 55s
CI / integration_tests (pull_request) Successful in 3m28s
CI / unit_tests (pull_request) Successful in 10m38s
CI / docker (pull_request) Successful in 16s
CI / benchmark-regression (pull_request) Successful in 20m39s
CI / coverage (pull_request) Successful in 41m22s
CI / lint (push) Successful in 13s
CI / quality (push) Successful in 17s
CI / build (push) Successful in 22s
CI / typecheck (push) Successful in 29s
CI / security (push) Successful in 29s
CI / benchmark-regression (push) Has been skipped
CI / integration_tests (push) Successful in 2m40s
CI / unit_tests (push) Successful in 11m4s
CI / docker (push) Successful in 1m5s
CI / benchmark-publish (push) Successful in 12m10s
CI / coverage (push) Successful in 1h7m46s
Added 246 new BDD scenarios across 9 feature files to improve unit test coverage for modules that were either entirely untested or had significant coverage gaps: - lock_service_coverage.feature (27 scenarios): validation branches, TTL boundaries, re-entrant acquisition, rollback on exceptions - plan_apply_service_coverage.feature (54 scenarios): operation labels, diff rendering (plain/rich/json), artifact building, validation gate, changeset resolution and cleanup - plan_executor_coverage.feature (51 scenarios): step parsing, execute actor integration, strategize/execute guards, stub retry/recovery, decision tree construction - skill_cli_coverage_r3.feature (22 scenarios): tools refresh, list/show JSON fallback, capability summary errors, remove confirmation - changeset_repository_coverage.feature (39 scenarios): entry/tool repos validation, database error wrapping, domain conversion, SQLite store CRUD operations - repositories_coverage.feature (20 scenarios): get_by_name/namespace errors, list_available filters, delete with ActionInUseError, plan update with invariants/processing_state/error_details - sandbox_copy_on_write_coverage.feature (12 scenarios): create OSError wrapping, get_path state transitions, commit edge cases, rollback errors, cleanup with missing paths - bridge_coverage.feature (8 scenarios): __del__ suppression, async task cancellation, execute_graph message type handling, stream config, state checkpointer - plan_cli_coverage.feature (13 scenarios): legacy apply/list/cd paths, use-action with estimation/invariant actors, lifecycle-apply guards, status errors, error recovery display All 246 scenarios (1105 steps) pass. Step definitions use unique prefixes to prevent ambiguous step conflicts with existing tests. ISSUES CLOSED: #467
249 lines
13 KiB
Gherkin
249 lines
13 KiB
Gherkin
Feature: Skill CLI coverage round 3
|
|
Cover remaining uncovered branches in src/cleveragents/cli/commands/skill.py:
|
|
tools --refresh flag, list/show non-rich capability error fallback,
|
|
refresh with agent_skills_paths discovery, refresh errors, long
|
|
description truncation, and the tools ValueError path.
|
|
|
|
Background:
|
|
Given r3skill- a fresh skill CLI service
|
|
|
|
# -------------------------------------------------------------------
|
|
# tools --refresh flag with agent_skills_paths configured (lines 815-838)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Tools command with --refresh and configured agent_skills paths
|
|
Given r3skill- a registered skill "local/refreshable" with tool_refs
|
|
And r3skill- agent_skills_paths config resolves to a valid path with discovered skills
|
|
When r3skill- I invoke tools "local/refreshable" with --refresh
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "Refreshed"
|
|
And r3skill- the output should contain "agent skill"
|
|
|
|
Scenario: Tools command with --refresh and empty agent_skills_paths
|
|
Given r3skill- a registered skill "local/no-agent-paths" with tool_refs
|
|
And r3skill- agent_skills_paths config resolves to empty string
|
|
When r3skill- I invoke tools "local/no-agent-paths" with --refresh
|
|
Then r3skill- the CLI exit code should be 0
|
|
|
|
Scenario: Tools command with --refresh and discovery errors
|
|
Given r3skill- a registered skill "local/disc-errors" with tool_refs
|
|
And r3skill- agent_skills_paths config resolves with discovery errors
|
|
When r3skill- I invoke tools "local/disc-errors" with --refresh
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "Warning"
|
|
|
|
# -------------------------------------------------------------------
|
|
# tools ValueError path (lines 887-889)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Tools command when resolve_tools raises ValueError
|
|
Given r3skill- a registered skill "local/val-err-tools" with tool_refs
|
|
And r3skill- resolve_tools will raise ValueError for "local/val-err-tools"
|
|
When r3skill- I invoke tools "local/val-err-tools" in rich format
|
|
Then r3skill- the CLI exit code should not be 0
|
|
And r3skill- the output should contain "Resolution error"
|
|
|
|
# -------------------------------------------------------------------
|
|
# list non-rich format: capability summary ValueError fallback (lines 667-669)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: List with JSON format falls back when capability summary raises ValueError
|
|
Given r3skill- a registered skill "local/cap-fallback" with tool_refs
|
|
And r3skill- compute_capability_summary will raise ValueError
|
|
When r3skill- I invoke list in format "json"
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should be valid JSON
|
|
And r3skill- the JSON list first item should have key "tool_count"
|
|
And r3skill- the JSON list first item "capability_summary" should be null
|
|
|
|
# -------------------------------------------------------------------
|
|
# show non-rich format: capability summary ValueError fallback (lines 764-766)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Show with JSON format falls back when capability summary raises ValueError
|
|
Given r3skill- a registered skill "local/show-cap-err" with tool_refs
|
|
And r3skill- compute_capability_summary will raise ValueError
|
|
When r3skill- I invoke show "local/show-cap-err" in format "json"
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should be valid JSON
|
|
And r3skill- the JSON output key "capability_summary" should be null
|
|
|
|
# -------------------------------------------------------------------
|
|
# list rich format: long description truncation (lines 696-700)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: List in rich format truncates long descriptions
|
|
Given r3skill- a registered skill "local/long-desc" with a description longer than 50 chars
|
|
When r3skill- I invoke list in rich format
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the long description in the output should be truncated
|
|
|
|
# -------------------------------------------------------------------
|
|
# refresh: agent_skills_paths discovery (lines 953-980)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Refresh single skill with agent_skills_paths discovery
|
|
Given r3skill- a registered skill "local/refresh-agent" with tool_refs
|
|
And r3skill- agent_skills_paths config resolves to a valid path with discovered skills
|
|
When r3skill- I invoke refresh "local/refresh-agent" in rich format
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "Agent Skills"
|
|
And r3skill- the output should contain "Discovered"
|
|
|
|
Scenario: Refresh all skills with agent_skills_paths and discovery errors
|
|
Given r3skill- a registered skill "local/refresh-err" with tool_refs
|
|
And r3skill- agent_skills_paths config resolves with discovery errors
|
|
When r3skill- I invoke refresh --all in rich format
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "Warning"
|
|
|
|
# -------------------------------------------------------------------
|
|
# refresh: single skill resolve_tools ValueError (lines 1017-1026, 1044-1046)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Refresh single skill with ValueError during resolve_tools
|
|
Given r3skill- a registered skill "local/refresh-fail" with tool_refs
|
|
And r3skill- resolve_tools will raise ValueError for "local/refresh-fail"
|
|
When r3skill- I invoke refresh "local/refresh-fail" in rich format
|
|
Then r3skill- the CLI exit code should not be 0
|
|
And r3skill- the output should contain "Refresh failed"
|
|
|
|
# -------------------------------------------------------------------
|
|
# refresh: all skills with one skill ValueError (lines 1017-1026 in loop)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Refresh all skills where one skill has resolve_tools ValueError
|
|
Given r3skill- a registered skill "local/good-skill" with tool_refs
|
|
And r3skill- a registered skill "local/bad-skill" with tool_refs
|
|
And r3skill- resolve_tools will raise ValueError for "local/bad-skill"
|
|
When r3skill- I invoke refresh --all in rich format
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "Errors"
|
|
|
|
# -------------------------------------------------------------------
|
|
# refresh: non-rich format with mcp_errors (lines 1035-1036)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Refresh all in JSON format with mcp errors
|
|
Given r3skill- a registered skill "local/ok-skill" with tool_refs
|
|
And r3skill- a registered skill "local/err-skill" with tool_refs
|
|
And r3skill- resolve_tools will raise ValueError for "local/err-skill"
|
|
When r3skill- I invoke refresh --all in format "json"
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should be valid JSON
|
|
And r3skill- the JSON output should have key "errors"
|
|
|
|
# -------------------------------------------------------------------
|
|
# refresh: general Exception catch (lines 1106-1108)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Refresh raises unexpected Exception
|
|
Given r3skill- a registered skill "local/exc-skill" with tool_refs
|
|
And r3skill- list_skills will raise RuntimeError
|
|
When r3skill- I invoke refresh --all in rich format
|
|
Then r3skill- the CLI exit code should not be 0
|
|
And r3skill- the output should contain "Refresh error"
|
|
|
|
# -------------------------------------------------------------------
|
|
# refresh: agent_skills_paths empty path (lines 961-962 false branch)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Refresh with empty agent_skills_paths skips discovery
|
|
Given r3skill- a registered skill "local/no-discovery" with tool_refs
|
|
And r3skill- agent_skills_paths config resolves to empty string
|
|
When r3skill- I invoke refresh "local/no-discovery" in rich format
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should not contain "Discovered"
|
|
|
|
# -------------------------------------------------------------------
|
|
# refresh: non-rich single skill (lines 1029-1037)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Refresh single skill with JSON format returns structured output
|
|
Given r3skill- a registered skill "local/json-refresh" with tool_refs
|
|
When r3skill- I invoke refresh "local/json-refresh" in format "json"
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should be valid JSON
|
|
And r3skill- the JSON output should have key "refreshed"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_detail: both timestamps None (lines 253-254)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Show skill in rich format with no timestamps shows unknown
|
|
Given r3skill- a registered skill "local/no-ts" with tool_refs
|
|
And r3skill- timestamps for "local/no-ts" are removed
|
|
When r3skill- I invoke show "local/no-ts" in rich format
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "unknown"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_registered: include present AND registered (line 159 true)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Add skill with includes where included skill IS registered
|
|
Given r3skill- a registered skill "local/base-inc" with tool_refs
|
|
And r3skill- a temp YAML for "local/parent-inc" that includes "local/base-inc"
|
|
When r3skill- I invoke add with the temp config in rich format
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "registered"
|
|
And r3skill- the output should contain "Includes"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_update_changes: old_skill with includes/mcp changed
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Update skill changes includes and MCP servers shows diff
|
|
Given r3skill- a temp YAML for "local/upd-diff" with tool_refs and MCP
|
|
And r3skill- the skill "local/upd-diff" is pre-registered via add
|
|
And r3skill- a second temp YAML for "local/upd-diff" with different includes and MCP
|
|
When r3skill- I invoke add with the second config and --update in rich format
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "Changes"
|
|
And r3skill- the output should contain "Includes Changed"
|
|
And r3skill- the output should contain "MCP Servers Changed"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_tools: inline tool with writes and checkpointable
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Tools command with inline tool having writes and checkpointable
|
|
Given r3skill- a registered skill "local/inline-caps" with inline tools having capabilities
|
|
When r3skill- I invoke tools "local/inline-caps" in rich format
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "custom"
|
|
|
|
# -------------------------------------------------------------------
|
|
# remove: confirm prompt with yes (line 553 true branch via input)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Remove skill without --yes and confirm with y
|
|
Given r3skill- a registered skill "local/confirm-rm" with tool_refs
|
|
When r3skill- I invoke remove "local/confirm-rm" without --yes and confirm
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should contain "Skill Removed"
|
|
|
|
# -------------------------------------------------------------------
|
|
# list non-rich: capability summary KeyError fallback
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: List with JSON format falls back when capability summary raises KeyError
|
|
Given r3skill- a registered skill "local/key-err-list" with tool_refs
|
|
And r3skill- compute_capability_summary will raise KeyError
|
|
When r3skill- I invoke list in format "json"
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should be valid JSON
|
|
And r3skill- the JSON list first item "capability_summary" should be null
|
|
|
|
# -------------------------------------------------------------------
|
|
# show non-rich: capability summary KeyError fallback
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Show with JSON format falls back when capability summary raises KeyError
|
|
Given r3skill- a registered skill "local/key-err-show" with tool_refs
|
|
And r3skill- compute_capability_summary will raise KeyError
|
|
When r3skill- I invoke show "local/key-err-show" in format "json"
|
|
Then r3skill- the CLI exit code should be 0
|
|
And r3skill- the output should be valid JSON
|
|
And r3skill- the JSON output key "capability_summary" should be null
|