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
362 lines
16 KiB
Gherkin
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
|