Feature: ULID validation data variation — Scenario Outline refactoring As a CleverAgents developer I want ULID validation tests to cover a wide range of inputs So that edge cases and boundary conditions are systematically exercised # ───────────────────────────────────────────────────────────────────────── # Refactored from plan_ulid_validation.feature using Scenario Outline. # Each Examples table row exercises a distinct code path or boundary. # ───────────────────────────────────────────────────────────────────────── # ───────────────────────────────────────────────────────────────────────── # Valid ULID inputs — all should pass validation # ───────────────────────────────────────────────────────────────────────── Scenario Outline: _validate_plan_ulid accepts valid ULID strings When I call _validate_plan_ulid with "" Then ulid-val the validation should succeed and return "" Examples: Valid ULID formats | ulid | description | | 01HXM8C2ZK4Q7C2B3F2R4VYV6J | standard uppercase ULID | | 01hxm8c2zk4q7c2b3f2r4vyv6j | lowercase ULID (case-insensitive) | | 01ARZ3NDEKTSV4RRFFQ69G5FAV | another valid uppercase ULID | | 00000000000000000000000000 | minimum value ULID (all zeros) | | 7ZZZZZZZZZZZZZZZZZZZZZZZZZ | maximum value ULID (all max chars) | # ───────────────────────────────────────────────────────────────────────── # Invalid ULID inputs — wrong length # ───────────────────────────────────────────────────────────────────────── Scenario Outline: _validate_plan_ulid rejects ULIDs with wrong length 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: Wrong length inputs | invalid_input | description | | 01ARZ3NDEK | too short (10 chars) | | 01ARZ3NDEKTSV4RRFFQ69G5FAAEXTRA | too long (32 chars) | | 01ARZ3NDEKTSV4RRFFQ69G5FA | too short by one (25 chars) | | 01ARZ3NDEKTSV4RRFFQ69G5FAVXX | too long by one (27 chars) | | A | single character | | 01ARZ3NDEKTSV4RRFFQ69G5FAVXXX | too long by three (28 chars) | # ───────────────────────────────────────────────────────────────────────── # Invalid ULID inputs — illegal characters (I, L, O, U excluded from # Crockford base32 alphabet to avoid visual ambiguity) # ───────────────────────────────────────────────────────────────────────── Scenario Outline: _validate_plan_ulid 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 | invalid_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) | Examples: Special characters and whitespace | invalid_input | description | | 01ARZ3NDEKTSV4RRFFQ69G5F!@ | contains special characters | | 01ARZ3NDEKTSV4RRFFQ69G5F-X | contains hyphen | | 01ARZ3NDEKTSV4RRFFQ69G5F.X | contains period | # ───────────────────────────────────────────────────────────────────────── # Invalid ULID inputs — plain strings and legacy names # ───────────────────────────────────────────────────────────────────────── Scenario Outline: _validate_plan_ulid rejects plain strings that are not ULIDs 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: Plain non-ULID strings | invalid_input | description | | not-a-ulid | plain hyphenated string | | hello | short plain word | | plan-123 | legacy-style plan name | | abc | very short plain string | # ───────────────────────────────────────────────────────────────────────── # Legacy plan names — should include actionable error guidance # ───────────────────────────────────────────────────────────────────────── Scenario Outline: _validate_plan_ulid rejects legacy plan names with guidance When I call _validate_plan_ulid with "" Then ulid-val the validation should raise ValidationError And ulid-val the error message should contain "ULID" And ulid-val the error message should contain "legacy" And ulid-val the error message should contain "agents plan use" Examples: Legacy plan name formats | legacy_name | description | | 64-bit port plan | legacy name with spaces | | my-legacy-plan | legacy hyphenated name | | add error handling | legacy descriptive name | | refactor authentication module | legacy multi-word name | # ───────────────────────────────────────────────────────────────────────── # CLI command ULID validation — multiple commands, multiple invalid inputs # ───────────────────────────────────────────────────────────────────────── Scenario Outline: plan rejects non-ULID input with actionable error Given a ulid-validation CLI runner When I invoke ulid-validation plan with "" Then the ulid-validation command should abort And the ulid-validation output should contain "ULID" Examples: CLI commands with plain non-ULID strings | command | invalid_input | description | | execute | not-a-valid-id | execute with plain string | | apply | not-a-valid-id | apply with plain string | | execute | short | execute with very short string | | apply | plan-123 | apply with legacy-style name | Scenario Outline: plan rejects legacy plan names with full guidance Given a ulid-validation CLI runner When I invoke ulid-validation plan with "" Then the ulid-validation command should abort And the ulid-validation output should contain "not found" And the ulid-validation output should contain "ULID" And the ulid-validation output should contain "legacy" And the ulid-validation output should contain "agents plan use" Examples: CLI commands with legacy plan names | command | legacy_name | description | | execute | my-legacy-plan | execute with legacy hyphenated name | | apply | 64-bit port plan | apply with legacy spaced name | | execute | add error handling | execute with legacy descriptive name |