Files
cleveragents-core/features/action_model.feature
T
freemo fd6d41b371
CI / lint (pull_request) Successful in 14s
CI / typecheck (pull_request) Successful in 26s
CI / security (pull_request) Successful in 21s
CI / quality (pull_request) Successful in 16s
CI / integration_tests (pull_request) Successful in 4m15s
CI / build (pull_request) Successful in 16s
CI / unit_tests (pull_request) Successful in 7m41s
CI / docker (pull_request) Successful in 39s
CI / lint (push) Successful in 13s
CI / coverage (pull_request) Successful in 5m38s
CI / typecheck (push) Successful in 26s
CI / security (push) Successful in 22s
CI / quality (push) Successful in 15s
CI / integration_tests (push) Successful in 4m10s
CI / build (push) Successful in 15s
CI / unit_tests (push) Successful in 8m17s
CI / docker (push) Successful in 41s
CI / coverage (push) Successful in 5m30s
feat(domain): align action model with spec
2026-02-13 09:41:28 -05:00

362 lines
16 KiB
Gherkin

Feature: Action Domain Model
As a developer
I want an action domain model that defines reusable plan templates
So that I can create actions via CLI and use them on projects
# Action Argument Parsing Tests
Scenario: Parse required string argument
When I parse the action argument "name:string:required:User name"
Then the argument name should be "name"
And the argument type should be "string"
And the argument should be required
And the argument description should be "User name"
Scenario: Parse optional integer argument
When I parse the action argument "count:integer:optional:Number of items"
Then the argument name should be "count"
And the argument type should be "integer"
And the argument should be optional
Scenario: Parse argument without description
When I parse the action argument "flag:boolean:required"
Then the argument name should be "flag"
And the argument type should be "boolean"
And the argument description should be empty
Scenario: Parse legacy short type names via _missing_
When I parse the action argument "name:str:required:User name"
Then the argument type should be "string"
When I parse the action argument "count:int:optional:Count"
Then the argument type should be "integer"
When I parse the action argument "flag:bool:required:Flag"
Then the argument type should be "boolean"
Scenario: Invalid argument format raises error
When I try to parse the action argument "invalid"
Then an argument parse error should be raised
Scenario: Invalid argument type raises error
When I try to parse the action argument "name:badtype:required:desc"
Then an argument parse error should be raised
Scenario: Invalid argument requirement raises error
When I try to parse the action argument "name:string:sometimes:desc"
Then an argument parse error should be raised
Scenario: Invalid argument name raises error
When I try to create an action argument with invalid name "1invalid"
Then a validation error should be raised
And the error should mention "Argument name must be a valid Python identifier"
Scenario: Invalid argument name with hyphen raises error
When I try to create an action argument with invalid name "invalid-name"
Then a validation error should be raised
And the error should mention "Argument name must be a valid Python identifier"
Scenario: Stringify action argument definition
When I parse the action argument "limit:integer:required:Limit value"
And I stringify the action argument
Then the argument definition string should be "limit:integer:required:Limit value"
Scenario: Stringify optional list argument definition
When I parse the action argument "targets:list:optional:Targets to check"
And I stringify the action argument
Then the argument definition string should be "targets:list:optional:Targets to check"
# Action Creation Tests
Scenario: Create minimal action
When I create an action with name "local/test-action" and definition of done "Tests pass"
Then the action should be created
And the action namespace should be "local"
And the action name should be "test-action"
And the action state should be "available"
Scenario: Create action with arguments
Given I have action arguments
| name | type | requirement | description |
| coverage | integer | required | Target coverage percent |
| framework | string | optional | Test framework to use |
When I create an action with these arguments
Then the action should have 2 arguments
And the action should have 1 required argument
And the action should have 1 optional argument
Scenario: Validate arguments - all required provided
Given I have an action with required argument "target:integer:required:Target value"
When I validate arguments with target 85
Then the validation should pass
Scenario: Validate arguments - missing required
Given I have an action with required argument "target:integer:required:Target value"
When I validate arguments without target
Then the validation should fail with "Missing required argument: target"
Scenario: Validate arguments - unknown argument
Given I have an action with required argument "target:integer:required:Target value"
When I validate arguments with target 85 and extra "foo"
Then the validation should fail with "Unknown argument: extra"
Scenario: Validate arguments - wrong type
Given I have an action with required argument "target:integer:required:Target value"
When I validate arguments with target as string "not-a-number"
Then the validation should fail with "must be an integer"
Scenario: Validate arguments - integer below minimum
Given I have an action with bounded integer argument "priority" min 1 max 5
When I validate arguments with "priority" set to 0
Then the validation should fail with "Argument priority must be >= 1"
Scenario: Validate arguments - integer above maximum
Given I have an action with bounded integer argument "priority" min 1 max 5
When I validate arguments with "priority" set to 6
Then the validation should fail with "Argument priority must be <= 5"
Scenario: Validate arguments - float expects numeric
Given I have an action with argument "threshold" of type "float"
When I validate arguments with "threshold" set to "high"
Then the validation should fail with "Argument threshold must be a number"
Scenario: Validate arguments - boolean expects boolean
Given I have an action with argument "dry_run" of type "boolean"
When I validate arguments with "dry_run" set to "yes"
Then the validation should fail with "Argument dry_run must be a boolean"
Scenario: Validate arguments - list expects list
Given I have an action with argument "targets" of type "list"
When I validate arguments with "targets" set to "api,cli"
Then the validation should fail with "Argument targets must be a list"
# Action State Tests
Scenario: New action starts in available state
When I create a new action
Then the action state should be "available"
Scenario: Action can be archived from available
Given I have an available action
When I set the action state to archived
Then the action state should be "archived"
# Actor Configuration Tests
Scenario: Action requires strategy and execution actors
When I try to create an action without strategy actor
Then a validation error should be raised
Scenario: Action can have optional review actor
When I create an action with review actor "local/code-reviewer"
Then the action should have a review actor
Scenario: Action can have optional estimation actor
When I create an action with estimation actor "local/cost-estimator"
Then the action should have an estimation actor
# Reusability Tests
Scenario: Actions are reusable by default
When I create a new action
Then the action should be reusable
Scenario: Action can be non-reusable
When I create a non-reusable action
Then the action should not be reusable
# Read-only Tests
Scenario: Actions are not read-only by default
When I create a new action
Then the action should not be read-only
Scenario: Action can be marked read-only
When I create a read-only action
Then the action should be read-only
# Invariants Sanitization Tests
Scenario: Invariants are sanitized on creation
When I create an action model with invariants " no secrets " and "" and " no secrets" and "keep data safe"
Then the action model invariants should be "no secrets" and "keep data safe"
Scenario: Invariants None defaults to empty list
When I create an action model with null invariants
Then the action model invariants count should be 0
# from_config Factory Tests
Scenario: Create action from config dict
When I create an action model from config with name "local/my-action" and description "Run tests" and dod "All tests green"
Then the action should be created
And the action name should be "my-action"
And the action model description should be "Run tests"
And the action state should be "available"
Scenario: from_config with arguments
When I create an action model from config with arguments
Then the action should have 2 arguments
And the action should have 1 required argument
And the action should have 1 optional argument
Scenario: from_config missing name raises error
When I try to create an action model from config missing "name"
Then an action model config error should be raised with "name"
Scenario: from_config missing description raises error
When I try to create an action model from config missing "description"
Then an action model config error should be raised with "description"
Scenario: from_config missing strategy_actor raises error
When I try to create an action model from config missing "strategy_actor"
Then an action model config error should be raised with "strategy_actor"
Scenario: from_config missing execution_actor raises error
When I try to create an action model from config missing "execution_actor"
Then an action model config error should be raised with "execution_actor"
Scenario: from_config missing definition_of_done raises error
When I try to create an action model from config missing "definition_of_done"
Then an action model config error should be raised with "definition_of_done"
# as_cli_dict Tests
Scenario: as_cli_dict returns stable dict
When I create an action model and call as_cli_dict
Then the action model cli dict should have key "name"
And the action model cli dict should have key "description"
And the action model cli dict should have key "state"
And the action model cli dict should have key "strategy_actor"
And the action model cli dict should have key "execution_actor"
And the action model cli dict should have key "definition_of_done"
And the action model cli dict should have key "reusable"
And the action model cli dict should have key "read_only"
And the action model cli dict should have key "created_at"
Scenario: as_cli_dict includes optional actors when set
When I create an action model with review actor and call as_cli_dict
Then the action model cli dict should have key "review_actor"
Scenario: as_cli_dict includes arguments when present
When I create an action model with arguments and call as_cli_dict
Then the action model cli dict should have key "arguments"
And the action model cli dict arguments count should be 1
# from_mapping Tests (ActionArgument)
Scenario: ActionArgument from_mapping basic
When I create an action argument from basic mapping "coverage" type "integer" required true
Then the argument name should be "coverage"
And the argument type should be "integer"
And the argument should be required
Scenario: ActionArgument from_mapping optional with default
When I create an action argument from mapping with default "framework" type "string" required false default "pytest"
Then the argument name should be "framework"
And the argument should be optional
And the action model argument default value should be "pytest"
Scenario: ActionArgument from_mapping missing name raises error
When I try to create an action argument from mapping missing name
Then an action model argument mapping error should be raised with "name"
Scenario: ActionArgument from_mapping missing type raises error
When I try to create an action argument from mapping missing type
Then an action model argument mapping error should be raised with "type"
# coerce_value Tests
Scenario: Coerce string value
Given I have an action model string argument named "label"
When I coerce action model value "hello" for the argument
Then the coerced action model value should be string "hello"
Scenario: Coerce integer value
Given I have an action model integer argument named "count"
When I coerce action model value "42" for the argument
Then the coerced action model value should be integer 42
Scenario: Coerce float value
Given I have an action model float argument named "ratio"
When I coerce action model value "3.14" for the argument
Then the coerced action model value should be float 3.14
Scenario: Coerce boolean true values
Given I have an action model boolean argument named "flag"
When I coerce action model value "true" for the argument
Then the coerced action model value should be boolean true
When I coerce action model value "yes" for the argument
Then the coerced action model value should be boolean true
When I coerce action model value "1" for the argument
Then the coerced action model value should be boolean true
Scenario: Coerce boolean false values
Given I have an action model boolean argument named "flag"
When I coerce action model value "false" for the argument
Then the coerced action model value should be boolean false
When I coerce action model value "no" for the argument
Then the coerced action model value should be boolean false
When I coerce action model value "0" for the argument
Then the coerced action model value should be boolean false
Scenario: Coerce invalid boolean raises error
Given I have an action model boolean argument named "flag"
When I try to coerce action model value "maybe" for the argument
Then an action model coerce error should be raised
Scenario: Coerce invalid integer raises error
Given I have an action model integer argument named "count"
When I try to coerce action model value "abc" for the argument
Then an action model coerce error should be raised
Scenario: Coerce list value
Given I have an action model list argument named "items"
When I coerce action model value "a, b, c" for the argument
Then the coerced action model value should be list with 3 items
# render_template Tests
Scenario: Render template with arguments
When I create an action model with description "Cover ${target}% for ${module}"
And I render action model description with target "90" and module "api"
Then the rendered action model description should be "Cover 90% for api"
Scenario: Render template missing placeholder raises error
When I create an action model with description "Cover ${target}% for ${module}"
And I try to render action model description with only target "90"
Then an action model template error should be raised
Scenario: Render definition of done with arguments
When I create an action model with dod template for module and target
And I render action model dod with target "80" and module "core"
Then the rendered action model dod should be "All tests in core pass with 80% coverage"
# inputs_schema Validation Tests
Scenario: inputs_schema accepts valid dict
When I create an action model with inputs schema type "object" and required "name"
Then the action should be created
And the action model inputs schema should not be none
Scenario: inputs_schema accepts None
When I create an action model with null inputs schema
Then the action should be created
And the action model inputs schema should be none
Scenario: inputs_schema rejects non-dict
When I try to create an action model with inputs schema as string
Then a validation error should be raised
# automation_profile Validation Tests
Scenario: automation_profile trims whitespace
When I create an action model with automation profile " fast "
Then the action model automation profile should be "fast"
Scenario: automation_profile blank becomes None
When I create an action model with automation profile " "
Then the action model automation profile should be none
Scenario: automation_profile None stays None
When I create an action model with null automation profile
Then the action model automation profile should be none