--- source_files: - DataPRO/StateMachine.Tests/StatesShould.cs generated_at: "2026-04-16T03:49:48.727573+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "ae00661176117a50" --- # StateMachine.Tests ## Documentation Page: `States` Class (StateMachine Module) --- ### 1. Purpose The `States` class serves as a **singleton registry and factory** for all known DAS (Data Acquisition System) state objects, ensuring consistent access to state instances and enabling centralized configuration of shared dependencies (e.g., `IDASFactory`). It abstracts the instantiation and management of state objects—each corresponding to a value in the `State` enum—so that other parts of the system can retrieve fully initialized, type-safe state representations without duplicating construction logic or state-specific dependencies. --- ### 2. Public Interface #### `public static States Instance { get; }` - **Type**: Static read-only property - **Behavior**: Returns the singleton instance of `States`. Guaranteed to be non-null and identical across all calls (verified by `Instance_ShouldBeSame` test). #### `public static void SetDASFactory(IDASFactory factory)` - **Behavior**: Assigns the provided `IDASFactory` instance to *all* state objects managed by `States`. After calling this, every state retrieved via `GetIDASState(...)` will have its `DASFactory` property set to the provided factory. - **Note**: Must be called *before* states are accessed (or at least before `GetIDASState` is invoked), as state objects are lazily initialized and only receive the factory upon first access (inferred from test `SetDASFactory_ShouldSetToAnInstanceOfDASFactory`). #### `public IDASState GetIDASState(State state)` - **Parameters**: - `state`: A value from the `State` enum (e.g., `State.Arm`, `State.Realtime`). - **Returns**: An `IDASState` instance corresponding to the requested `State`. - **Behavior**: - Returns a state object whose `State` property matches the input `state`. - Throws `InvalidOperationException` with message `"Undefined State"` if passed a `State` value not defined in the `State` enum (e.g., `(State)45`). - The returned `IDASState` will have its `DASFactory` property set *if* `SetDASFactory` was previously called. #### `public DASState Arm { get; }` #### `public DASState Arming { get; }` #### `public DASState Configure { get; }` #### `public DASState ConfigureStart { get; }` #### `public DASState Diagnose { get; }` #### `public DASState Download { get; }` #### `public DASState HardwareDiscovery { get; }` #### `public DASState HardwareDiscoveryStart { get; }` #### `public DASState Prepare { get; }` #### `public DASState Realtime { get; }` #### `public DASState RealtimeStart { get; }` - **Type**: Read-only properties (return type inferred as `DASState`, a concrete implementation of `IDASState`). - **Behavior**: Each property exposes a pre-instantiated state object corresponding to its name (e.g., `Arm` returns the `DASState` for `State.Arm`). All are non-null and initialized with their respective `State` enum value. --- ### 3. Invariants - **Singleton Consistency**: `States.Instance` always returns the same object reference. - **State Completeness**: For every defined `State` enum value, `States.Instance.GetIDASState(state)` returns a valid `IDASState` with `State == state`. - **Factory Propagation**: After `SetDASFactory(factory)` is called, *all* states returned by `GetIDASState(...)` (and exposed via named properties like `Arm`, `Realtime`, etc.) must have `DASFactory == factory`. - **Enum Validity Enforcement**: `GetIDASState(...)` rejects any `State` value not present in the `State` enum via `InvalidOperationException`. - **Non-null States**: All state properties (`Arm`, `Arming`, etc.) and results from `GetIDASState(...)` are non-null. --- ### 4. Dependencies #### **Depends on** - `DTS.DASLib.Service.StateMachine` namespace (contains `States`, `IDASState`, `DASState`, `State` enum). - `DTS.Common.Interface.DASFactory` namespace (contains `IDASFactory`). - `NUnit.Framework` (for test assertions). - `NSubstitute` (for mocking `IDASFactory` in tests). #### **Depended on by** - `StateMachine.Tests` (this file), which validates `States` behavior. - Inferred: Other modules in `DTS.DASLib.Service.StateMachine` (and possibly higher-level services) rely on `States` to obtain state objects. --- ### 5. Gotchas - **Factory Initialization Timing**: `SetDASFactory` must be called *before* accessing state objects via `GetIDASState(...)` or named properties (e.g., `States.Instance.Arm`), otherwise states may be initialized with a `null` `DASFactory`. - **Lazy Initialization**: State objects are not pre-instantiated at `Instance` construction; they are created on first access (e.g., when `Arm` or `GetIDASState(State.Arm)` is called), and only *then* receive the factory if `SetDASFactory` has been called. - **No Explicit State Transition Logic**: This module *only* manages state *instances* and their shared dependencies. It does *not* define state transitions, guards, or event handling (those are likely elsewhere in the `StateMachine` namespace). - **Test Interdependence**: The `SetDASFactory_ShouldSetToAnInstanceOfDASFactory` test assumes `GetIDASState` works correctly (see inline comment). If `GetIDASState` fails, this test’s failure mode is ambiguous. - **Undefined State Handling**: Passing an invalid `State` enum value (e.g., via cast `(State)45`) throws `InvalidOperationException`—not `ArgumentOutOfRangeException`—despite the input being an enum value. *None identified beyond the above.*