Feature: Edge case data variation — empty, null, boundary, special characters, invalid types As a CleverAgents developer I want edge case tests to cover empty/null values, boundary lengths, special characters, and invalid input types systematically So that the system handles all boundary conditions correctly # ───────────────────────────────────────────────────────────────────────── # New edge-case scenarios added as part of issue #2772. # These complement the Scenario Outline refactoring in the other # data_variation_*.feature files. # ───────────────────────────────────────────────────────────────────────── # ───────────────────────────────────────────────────────────────────────── # Python content sanitization — edge cases # ───────────────────────────────────────────────────────────────────────── Background: Given I have a plan service for sanitization tests Scenario Outline: Sanitize valid Python expressions of varying complexity When I sanitize the python content "" Then the sanitized content should be "" And the sanitization error should be None And the sanitization reason should be None Examples: Simple valid Python expressions | content | description | | x = 1 + 2 | simple arithmetic assignment | | result = "hello" | string assignment | | items = [] | empty list assignment | | data = {} | empty dict assignment | | flag = True | boolean assignment | | value = None | None assignment | | count = 0 | zero assignment | Scenario Outline: Sanitize Python with markdown code fences strips fences When I sanitize the python content with code fences wrapping "" Then the sanitized content should be "" And the sanitization error should be None And the sanitization reason should be "code_fence_removed" Examples: Code fence variations | inner | description | | x = 42 | simple assignment in fences | | result = "hello" | string assignment in fences | | items = [1, 2, 3] | list assignment in fences | | def foo(): pass | function definition in fences | Scenario Outline: Sanitize non-Python prose wraps in docstring When I sanitize the python content "" Then the sanitization error should be None And the sanitization reason should be "docstring_wrapped" Examples: Non-Python prose inputs | prose | description | | This is just plain English text, not code. | plain English sentence | | Please implement the feature as described. | instruction-style prose | | The function should return a list of items. | description-style prose | Scenario: Sanitize content with null byte returns error When I sanitize python content containing a null byte Then the sanitization error should not be None # ───────────────────────────────────────────────────────────────────────── # Project name validation — edge cases with special characters # ───────────────────────────────────────────────────────────────────────── Scenario Outline: Project rejects names with various special characters When I try to create a project with name "" Then a project validation error should be raised mentioning "alphanumeric" Examples: Special character edge cases | invalid_name | description | | my@project | at-sign | | my/project | forward slash | | project! | exclamation mark | | proj#tag | hash symbol | | proj%done | percent sign | | proj^up | caret | | proj&more | ampersand | | proj*star | asterisk | | proj+plus | plus sign | | proj=eq | equals sign | | projmore | greater-than sign | | proj?q | question mark | | proj.pipe | period character | | proj:colon | colon | | proj;semi | semicolon | Scenario: Project rejects empty name When I try to create a project with empty name Then a project validation error should be raised Scenario Outline: Project accepts valid names with allowed characters When I create a project fixture with name "" Then the project should be created with that name Examples: Valid name formats | valid_name | description | | simple | plain alphanumeric | | my-project | hyphenated name | | my_project | underscored name | | my project | name with space | | project123 | name with trailing numbers | | 123project | name starting with numbers | | a | single character | | My Project Name | mixed case with spaces | # ───────────────────────────────────────────────────────────────────────── # NamespacedName — special character edge cases # ───────────────────────────────────────────────────────────────────────── Scenario Outline: NamespacedName rejects names with special characters in namespace When I parse the namespaced name "" expecting an error Then a ValueError should be raised Examples: Special characters in namespace | full_name | description | | bad@ns/name | at-sign in namespace | | bad ns/name | space in namespace | | bad!ns/name | exclamation in namespace | | bad#ns/name | hash in namespace | Scenario Outline: NamespacedName rejects names with special characters in name component When I parse the namespaced name "" expecting an error Then a ValueError should be raised Examples: Special characters in name component | full_name | description | | ns/bad name | space in name component | | ns/bad@name | at-sign in name component | | ns/bad!name | exclamation in name component | | ns/bad#name | hash in name component | | ns/bad/extra | extra slash (three components) | Scenario Outline: NamespacedName accepts names at various boundary lengths When I parse the namespaced name "" Then the parsed namespace should be "" And the parsed item name should be "" Examples: Boundary length names | full_name | namespace | item_name | description | | a/b | a | b | minimum length (1 char each) | | ab/cd | ab | cd | two chars each | | abc/def | abc | def | three chars each | | local/my-tool | local | my-tool | standard short name | | my-namespace/my-tool-name | my-namespace | my-tool-name | medium length names | # ───────────────────────────────────────────────────────────────────────── # ULID validation — boundary and special character edge cases # ───────────────────────────────────────────────────────────────────────── Scenario Outline: ULID validation rejects inputs at boundary lengths When I call _validate_plan_ulid with "" Then ulid-val the validation should raise ValidationError And ulid-val the error message should contain "ULID" Examples: Boundary length inputs | input | description | | 01ARZ3NDEKTSV4RRFFQ69G5FA | 25 chars (one short of valid) | | 01ARZ3NDEKTSV4RRFFQ69G5FAVX | 27 chars (one over valid) | | A | single character | | 01ARZ3NDEK | 10 chars (too short) | Scenario Outline: ULID validation accepts valid ULIDs at boundary values When I call _validate_plan_ulid with "" Then ulid-val the validation should succeed and return "" Examples: Valid ULIDs at boundary values | ulid | description | | 00000000000000000000000000 | all zeros (minimum value) | | 7ZZZZZZZZZZZZZZZZZZZZZZZZZ | all max chars (maximum value) | | 01HXM8C2ZK4Q7C2B3F2R4VYV6J | standard valid ULID | Scenario Outline: ULID validation rejects ULIDs with illegal characters When I call _validate_plan_ulid with "" Then ulid-val the validation should raise ValidationError And ulid-val the error message should contain "ULID" Examples: Crockford base32 excluded characters | input | description | | 01ARZ3NDEKTSV4RRFFQ69G5FII | contains I (excluded from base32) | | 01ARZ3NDEKTSV4RRFFQ69G5FLL | contains L (excluded from base32) | | 01ARZ3NDEKTSV4RRFFQ69G5FOO | contains O (excluded from base32) | | 01ARZ3NDEKTSV4RRFFQ69G5FUU | contains U (excluded from base32) | | 01ARZ3NDEKTSV4RRFFQ69G5F!@ | contains special characters | | 01ARZ3NDEKTSV4RRFFQ69G5F-X | contains hyphen | | 01ARZ3NDEKTSV4RRFFQ69G5F.X | contains period | # ───────────────────────────────────────────────────────────────────────── # Skill schema — edge cases for inline tool source values # ───────────────────────────────────────────────────────────────────────── Scenario Outline: Skill schema rejects invalid inline tool source values Given a skill YAML string with an inline tool source "" When I validate the skill schema expecting failure Then the skill schema validation should fail And the skill schema error should mention "custom" Examples: Invalid source values | source | description | | plugin | plugin source (not supported) | | external | external source (not supported) | | remote | remote source (not supported) | | builtin | builtin source (not supported) | | inline | inline source (not supported) | | file | file source (not supported) | # ───────────────────────────────────────────────────────────────────────── # Skill schema — edge cases for MCP transport values # ───────────────────────────────────────────────────────────────────────── Scenario Outline: Skill schema rejects invalid MCP transport values Given a skill YAML string with MCP transport "" When I validate the skill schema expecting failure Then the skill schema validation should fail And the skill schema error should mention "transport" Examples: Invalid transport values | transport | description | | grpc | gRPC (not supported) | | websocket | WebSocket (not supported) | | http | plain HTTP (not supported) | | tcp | TCP (not supported) | | invalid | completely invalid value | | ftp | FTP (not supported) | | amqp | AMQP (not supported) |