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
273 lines
14 KiB
Gherkin
273 lines
14 KiB
Gherkin
Feature: Skill CLI branch coverage round 2
|
|
Cover partial branches in src/cleveragents/cli/commands/skill.py
|
|
Lines 74, 109, 112, 121, 155, 164, 169, and related conditionals.
|
|
All lines are hit but many conditional branches are only tested in one direction.
|
|
|
|
Background:
|
|
Given r2skill- a reset skill CLI service
|
|
|
|
# -------------------------------------------------------------------
|
|
# _get_skill_service singleton (line 74 false branch)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Service singleton returns existing instance on second call
|
|
When r2skill- I call _get_skill_service twice without resetting
|
|
Then r2skill- both calls return the same SkillService object
|
|
|
|
# -------------------------------------------------------------------
|
|
# _skill_spec_dict — missing timestamps (lines 109, 112 false)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Show skill with JSON format when timestamps are absent
|
|
Given r2skill- a registered skill "local/no-timestamps" with tool_refs
|
|
And r2skill- the timestamps for "local/no-timestamps" are removed
|
|
When r2skill- I invoke show "local/no-timestamps" with format "json"
|
|
Then r2skill- the output should be valid JSON
|
|
And r2skill- the JSON output should not contain key "created"
|
|
And r2skill- the JSON output should not contain key "updated"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _tool_count — MCP with no tools (line 121-122 false branch)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Tool count for skill with MCP server having no tools
|
|
Given r2skill- a registered skill "local/mcp-no-tools" with MCP server but no tool list
|
|
When r2skill- I invoke show "local/mcp-no-tools" with format "rich"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "OK"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_registered — no includes (line 155 false)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Add skill with no includes shows no Includes panel
|
|
Given r2skill- a temp YAML config for "local/no-includes" with only tool_refs
|
|
When r2skill- I invoke add with the temp config in rich format
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "Skill Registered"
|
|
And r2skill- the output should not contain "Includes"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_registered — empty sources (line 164 false)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Add skill with no tool sources shows no Tool Sources panel
|
|
Given r2skill- a temp YAML config for "local/empty-skill" with no tools
|
|
When r2skill- I invoke add with the temp config in rich format
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "Skill Registered"
|
|
And r2skill- the output should not contain "Tool Sources"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_registered — source type branches (lines 169, 173, 177, 181)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Add skill with only MCP sources excludes builtin from sources
|
|
Given r2skill- a temp YAML config for "local/mcp-only" with MCP and tools
|
|
When r2skill- I invoke add with the temp config in rich format
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "mcp"
|
|
|
|
Scenario: Add skill with only custom inline tools
|
|
Given r2skill- a temp YAML config for "local/custom-only" with inline tools
|
|
When r2skill- I invoke add with the temp config in rich format
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "custom"
|
|
|
|
# -------------------------------------------------------------------
|
|
# add command — non-rich format (line 483 true branch)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Add skill with JSON format returns JSON output
|
|
Given r2skill- a temp YAML config for "local/json-add" with only tool_refs
|
|
When r2skill- I invoke add with the temp config in format "json"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should be valid JSON
|
|
And r2skill- the JSON output should contain key "name"
|
|
|
|
# -------------------------------------------------------------------
|
|
# add command — update existing skill (lines 474, 491)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Update existing skill via add --update shows Changes panel
|
|
Given r2skill- a temp YAML config for "local/updatable" with only tool_refs
|
|
And r2skill- the skill "local/updatable" is already registered via add
|
|
And r2skill- a second temp YAML config for "local/updatable" with different tools
|
|
When r2skill- I invoke add with the second config and --update in rich format
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "Skill Updated"
|
|
And r2skill- the output should contain "Changes"
|
|
|
|
# -------------------------------------------------------------------
|
|
# add command — duplicate without --update (line 500-510)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Add duplicate skill without update raises already-registered error
|
|
Given r2skill- a temp YAML config for "local/duplicate" with only tool_refs
|
|
And r2skill- the skill "local/duplicate" is already registered via add
|
|
And r2skill- a duplicate temp YAML config for "local/duplicate"
|
|
When r2skill- I invoke add with the duplicate config without update
|
|
Then r2skill- the CLI exit code should not be 0
|
|
And r2skill- the output should contain "already registered"
|
|
And r2skill- the output should contain "--update"
|
|
|
|
# -------------------------------------------------------------------
|
|
# list — empty registry (line 646 true)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: List skills when registry is empty shows message
|
|
When r2skill- I invoke list in rich format
|
|
Then r2skill- the output should contain "No skills found"
|
|
|
|
# -------------------------------------------------------------------
|
|
# list — non-rich format (line 651 true)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: List skills with JSON format
|
|
Given r2skill- a registered skill "local/for-json-list" with tool_refs
|
|
When r2skill- I invoke list in format "json"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should be valid JSON
|
|
|
|
# -------------------------------------------------------------------
|
|
# list — non-local namespace (line 671 else branch)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: List skills with non-local namespace counts server skills
|
|
Given r2skill- a registered skill "server/remote-skill" with tool_refs
|
|
When r2skill- I invoke list in rich format
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "server/remote-skill"
|
|
|
|
# -------------------------------------------------------------------
|
|
# show — non-rich format (line 724 true)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Show skill with JSON format returns structured data
|
|
Given r2skill- a registered skill "local/for-json-show" with tool_refs
|
|
When r2skill- I invoke show "local/for-json-show" with format "json"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should be valid JSON
|
|
And r2skill- the JSON output should contain key "name"
|
|
|
|
# -------------------------------------------------------------------
|
|
# show — KeyError path (line 731-733)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Show nonexistent skill raises not-found error
|
|
When r2skill- I invoke show "local/nonexistent" with format "rich"
|
|
Then r2skill- the CLI exit code should not be 0
|
|
And r2skill- the output should contain "Skill not found"
|
|
|
|
# -------------------------------------------------------------------
|
|
# remove — rich format output (line 564 false, full rich path)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Remove skill with rich format shows removal panel
|
|
Given r2skill- a registered skill "local/to-remove" with tool_refs
|
|
When r2skill- I invoke remove "local/to-remove" with --yes in rich format
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "Skill Removed"
|
|
And r2skill- the output should contain "OK"
|
|
|
|
# -------------------------------------------------------------------
|
|
# remove — non-rich format (line 564 true)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Remove skill with JSON format returns structured output
|
|
Given r2skill- a registered skill "local/to-remove-json" with tool_refs
|
|
When r2skill- I invoke remove "local/to-remove-json" with --yes in format "json"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should be valid JSON
|
|
|
|
# -------------------------------------------------------------------
|
|
# remove — dependent skills (lines 577-587)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Remove skill that is included by another skill shows dependency warning
|
|
Given r2skill- a registered skill "local/base-dep" with tool_refs
|
|
And r2skill- a registered skill "local/parent-dep" that includes "local/base-dep"
|
|
When r2skill- I invoke remove "local/base-dep" with --yes in rich format
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "skill(s) include this skill"
|
|
|
|
# -------------------------------------------------------------------
|
|
# remove — KeyError path (line 601-603)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Remove nonexistent skill raises not-found error
|
|
When r2skill- I invoke remove "local/nonexistent" with --yes in rich format
|
|
Then r2skill- the CLI exit code should not be 0
|
|
And r2skill- the output should contain "Skill not found"
|
|
|
|
# -------------------------------------------------------------------
|
|
# tools — non-rich format (line 801 true)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Tools command with JSON format returns structured tool data
|
|
Given r2skill- a registered skill "local/for-json-tools" with tool_refs
|
|
When r2skill- I invoke tools "local/for-json-tools" with format "json"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should be valid JSON
|
|
|
|
# -------------------------------------------------------------------
|
|
# tools — inline entries in non-rich output (lines 806-811)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Tools command with inline tools in JSON format shows custom source
|
|
Given r2skill- a registered skill "local/inline-tools" with anonymous inline tools
|
|
When r2skill- I invoke tools "local/inline-tools" with format "json"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should be valid JSON
|
|
And r2skill- the JSON tool list should contain source "custom"
|
|
|
|
# -------------------------------------------------------------------
|
|
# tools — KeyError path (line 827-829)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Tools for nonexistent skill raises not-found error
|
|
When r2skill- I invoke tools "local/nonexistent" with format "rich"
|
|
Then r2skill- the CLI exit code should not be 0
|
|
And r2skill- the output should contain "Skill not found"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_registered — MCP servers panel (line 189)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Add skill with MCP servers shows MCP Servers panel
|
|
Given r2skill- a temp YAML config for "local/with-mcp-panel" with MCP servers
|
|
When r2skill- I invoke add with the temp config in rich format
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "MCP Servers"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_detail — no direct tools (line 302 false)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Show skill with no direct tools omits direct tools table
|
|
Given r2skill- a registered skill "local/no-direct-tools" with no tools at all
|
|
When r2skill- I invoke show "local/no-direct-tools" with format "rich"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should not contain "Direct Tools"
|
|
|
|
# -------------------------------------------------------------------
|
|
# _print_skill_detail — MCP tools in show (line 287 true/false)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Show skill with MCP servers displays MCP panel
|
|
Given r2skill- a registered skill "local/show-mcp" with MCP server and explicit tools
|
|
When r2skill- I invoke show "local/show-mcp" with format "rich"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should contain "MCP Servers"
|
|
|
|
# -------------------------------------------------------------------
|
|
# tools — MCP entry in non-rich format (line 806 true)
|
|
# -------------------------------------------------------------------
|
|
|
|
Scenario: Tools command with MCP entries in JSON format
|
|
Given r2skill- a registered skill "local/mcp-tools-json" with MCP server and explicit tools
|
|
When r2skill- I invoke tools "local/mcp-tools-json" with format "json"
|
|
Then r2skill- the CLI exit code should be 0
|
|
And r2skill- the output should be valid JSON
|
|
And r2skill- the JSON tool list should contain source "mcp"
|