Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation for State Machine Configuration Structure #91

Open
wants to merge 50 commits into
base: main
Choose a base branch
from

Conversation

deligoez
Copy link
Member

@deligoez deligoez commented Dec 12, 2024

Introduces strict validation for state machine configurations through the new StateConfigValidator class, ensuring consistency and early error detection.

Key Changes

  • Add validation for root-level machine configuration
  • Validate state properties and transitions
  • Enforce proper structure for guards and actions
  • Improve error messages for configuration issues

Example usage in machine definitions:

MachineDefinition::define([
    'id' => 'order',
    'initial' => 'pending',
    'states' => [
        'pending' => [
            'on' => {
                'APPROVE' => [
                    'target' => 'approved',
                    'guards' => 'isValid'  // Now validated
                ]
            }
        ]
    ]
]);

The validator checks for:

  • Valid keys at each configuration level
  • Proper structure for transitions and guards
  • Correct state type definitions
  • Valid entry/exit actions format

Any configuration issues now throw InvalidArgumentException with clear error messages, helping developers catch problems early in development rather than at runtime. For example:

// Invalid configuration - will throw exception
MachineDefinition::define([
    'states' => [
        'pending' => [
            'invalid_key' => 'value',  // Invalid state key
            'on' => [
                '@always' => 'next'    // Must be under 'on'
            ]
        ]
    ]
]);

This enhancement improves developer experience by providing immediate feedback on configuration errors and enforcing consistent machine definitions across your application.

Introduce a StateConfigValidator class to validate machine configuration keys and state types. This establishes clear validation rules for root, state, and transition levels, improving configuration consistency.
…utility

Add normalizeArrayOrString method to normalize input into an array or null, throwing an exception for unsupported types.
…ethod

Add `validate` method to verify the structure of machine configurations, including root-level settings, states, and transitions.
Add `validateRootConfig` method to ensure root-level keys in config are valid. Throws `InvalidArgumentException` for any invalid keys.
Updated method calls to use named arguments, improving code readability and maintainability.
Introduce a new `validateStateConfig` method in `StateConfigValidator` to ensure proper state configurations. This includes checks for invalid keys, transition placement, state types, entry/exit actions, nested states, and transitions under the 'on' key.
Introduce `validateStateType` method to enforce allowed state types. Throws `InvalidArgumentException` for invalid states, improving validation robustness.
…ints

Ensure final states cannot have transitions or child states.
…exit actions

Ensure entry and exit actions in state configurations are either a string or an array. Throws exception for invalid types to improve error handling and robustness.
Add a static method to validate transitions configuration in StateConfigValidator. Ensures 'on' definition is an array and validates each transition. Throws InvalidArgumentException for invalid configurations.
…onfig

Add `validateTransition` method to ensure proper validation for single and guarded transitions. This enhances error handling for invalid transition configurations.
Add validateTransitionConfig method to check transition configuration, ensuring allowed keys and proper normalization. Throws InvalidArgumentException for invalid keys, improving state config validation robustness.
Introduce `validateTransitionBehaviors` to verify and normalize guards, actions, and calculators in state transition configurations. Throws clear errors for invalid input formats.
Add `validateGuardedTransitions` method to ensure guarded transitions have valid conditions, targets are defined, and default conditions are ordered correctly.
Add `StateConfigValidator::validate` to ensure machine configuration integrity during initialization. Validates the `config` and `id` properties to prevent misconfiguration issues.
Add a test to ensure invalid root-level configuration keys in state machine definitions throw appropriate exceptions.
… definition

Add validation test to ensure transitions must be defined under the 'on' key, catching improper definitions with '@Always'.
…erty as array

Add a test case to ensure that the 'on' property in state definitions is validated as an array, throwing an appropriate exception if invalid.
…arget

Add a test to ensure transition targets are validated as either a string or an array, raising an exception for invalid definitions.
Add a test to ensure transition configurations throw an exception for invalid keys, verifying allowed keys in 'transition config' are strictly enforced.
…alidation

Add a test to validate that state types must be 'atomic', 'compound', or 'final', and throw an exception for invalid types.
…tions validation

Add a test to ensure final states do not have transitions, throwing an appropriate exception.
… child states

Add test to ensure final states cannot have child states, throwing an appropriate exception.
…configuration validation

Add a new test to validate state configurations with all possible features, including initial states, transitions, guards, actions, and nested states.
…ehaviors

Add a test to ensure string behaviors like guards, actions, and calculators are normalized to arrays without throwing exceptions.
…tions array

Add test to ensure that an exception is thrown when a state has an empty conditions array for a guarded transition, improving validation coverage.
…der in guarded transitions

Add test to validate that default conditions (no guards) must be the last in guarded transitions.
…uarded transitions

Add a new test to validate that guarded transitions must specify a target. Throws `InvalidArgumentException` with a clear error message when the target is missing.
…sitions

Verify state machine accepts valid transitions with multiple conditions.
…actions configuration

Improve error message to specify "entry/exit actions" for better clarity.
…r behaviors

Update behavior labels for error messages to improve readability.
Clarify error message for invalid conditions in state transitions, specifying required elements in the array (target/guards/actions).
…on arrays in transitions

Add a new test to ensure that transition conditions in state configurations are properly validated as arrays, throwing an exception for invalid formats.
…iguration in transitions

Add a new test case to validate that actions in transitions must be an array or string. Throws an exception for invalid configurations.
…config

Add a test case to verify that calculators in transitions must be an array or string.
…t actions

Ensure entry and exit actions in state configuration are arrays or strings, throwing an exception for invalid types.
…guration

Add a test to validate that guards in state transitions are properly configured as an array or string. Throws an exception for invalid configurations to ensure proper validation.
Expand the set of allowed state keys in `StateConfigValidator` to include 'id' and 'result', enabling additional configuration flexibility.
These tests were removed as the associated validation for final state definitions is no longer necessary or applicable.
Remove unnecessary parameters from the 'result' callback in the StateDefinitionTypeTest to simplify the test logic and ensure compatibility with current use cases.
@deligoez deligoez self-assigned this Dec 12, 2024
…lidation

Simplify logic for validating default condition order, ensuring proper error handling for improperly ordered conditions with no guards.
Remove `$this->id` from `StateConfigValidator::validate` call as it is not utilized. This refactor ensures cleaner code and prevents potential confusion.
…rrors

Reorder `isset` and `has` condition evaluation to ensure proper logical flow and avoid potential issues with undefined keys in `idMap`.
Update `getInvokableBehavior` method to include `InvokableBehavior` in return type, enhancing type safety and clarity.
…rioStateIfAvailable

Adjust parameter name from `eventBehavior` to `event` in method call to ensure accurate functionality.
Fixes improper use of null safe operator when comparing state IDs. Prevents potential logic issues in machine state transitions.
Ensure correct invocation of validateRequiredContext using the static method call, resolving potential issues with method resolution and adherence to coding standards.
…uardBehavior

Update `validateRequiredContext` to be called statically to align with correct usage and avoid potential runtime errors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants