macro_rules! plugin_test {
(@output_ty $InputType:ty) => { ... };
(@output_ty $InputType:ty, $OutputType:ty) => { ... };
(
model: $ModelName:ty,
input: $InputTy:ty,
output: $OutputTy:ty,
context: $ContextTy:ty,
value: $ContextExpr:expr,
cases: { $(($test_name:ident, $input_expr:expr, $expected:expr)),* $(,)? }
) => { ... };
(
model: $ModelName:ty,
input: $InputTy:ty,
context: $ContextTy:ty,
value: $ContextExpr:expr,
cases: { $(($test_name:ident, $input_expr:expr, $expected:expr)),* $(,)? }
) => { ... };
(
model: $ModelName:ty,
input: $InputTy:ty,
output: $OutputTy:ty,
cases: { $(($test_name:ident, $input_expr:expr, $expected:expr)),* $(,)? }
) => { ... };
(
model: $ModelName:ty,
input: $InputTy:ty,
cases: { $(($test_name:ident, $input_expr:expr, $expected:expr)),* $(,)? }
) => { ... };
(
model: $ModelName:ty,
input: mut $InputTy:ty,
output: $OutputTy:ty,
context: $ContextTy:ty,
value: $ContextExpr:expr,
cases: { $(($test_name:ident, $input_expr:expr, $expected:expr $(, $expected_input:expr)?)),* $(,)? }
) => { ... };
(
model: $ModelName:ty,
input: mut $InputTy:ty,
context: $ContextTy:ty,
value: $ContextExpr:expr,
cases: { $(($test_name:ident, $input_expr:expr, $expected:expr $(, $expected_input:expr)?)),* $(,)? }
) => { ... };
(
model: $ModelName:ty,
input: mut $InputTy:ty,
output: $OutputTy:ty,
cases: { $(($test_name:ident, $input_expr:expr, $expected:expr $(, $expected_input:expr)?)),* $(,)? }
) => { ... };
(
model: $ModelName:ty,
input: mut $InputTy:ty,
cases: { $(($test_name:ident, $input_expr:expr, $expected:expr $(, $expected_input:expr)?)),* $(,)? }
) => { ... };
}Expand description
Generates table-driven unit tests for plugin models.
It supports both immutable and mutable models, with or without context, and with either explicit or inferred output types.
For each test case, the macro:
- Instantiates the plugin model using
Default - Constructs the required context (if any)
- Executes the model’s computation (
computefor immutable models,compute_mutfor mutable models) - Asserts that the computed output matches the expected value
- Optionally asserts the final mutated input state for mutable models
Each test case expands into an independent #[test] function, ensuring
clear isolation and accurate failure reporting.
§Features
- Supports immutable (
PurePluginModel) and mutable (MutablePluginModel) models - Supports context-aware and context-free plugin models
- Supports explicit output types or implicit output = input
- Optional assertion of the mutated input value for mutable models
- Generates one
#[test]function per case - Avoids boilerplate while preserving full type safety
- Mirrors the exact runtime execution contract of plugin models
§Supported Forms
The macro supports the same four combinations for both immutable and mutable models:
| Context | Output | +—––+——+ | Yes | Explicit | | Yes | Inferred (output = input) | | No | Explicit | | No | Inferred (output = input) |
Mutable models are declared by using input: mut Type, which indicates that the
model will receive &mut Type and may transform the input in-place.
§Syntax
plugin_test! {
model: ModelType, // Plugin model type to test
input: InputType | mut InputType, // `mut` enables mutable model testing
output: OutputType, // Optional: defaults to `InputType` if omitted
context: ContextType, // Optional: required if model uses context
value: context_expr, // Optional: expression constructing the context
cases: {
(test_name, input_expr, expected_output),
(test_name_2, input_expr_2, expected_output_2, expected_mutated_input), // mutable only
}
}model: Plugin model type implementingPurePluginModelorMutablePluginModelinput: Input type consumed by the model (mutindicates in-place mutation)output: Output type produced by the model (defaults to input type if omitted)context: Context type required by the model (omit for())value: Expression that constructs the context instancecases: List of test tuples
Each case tuple has the form:
(name, input, expected_output)for immutable models(name, input, expected_output)for mutable models when only output is asserted(name, input, expected_output, expected_mutated_input)to also verify the final mutated state of the input
When the fourth element is provided, the macro additionally checks that the input was correctly transformed in-place.
§Notes
- Each test case expands into a separate
#[test]function - Context and input types must match the model’s trait implementation
- Output inference (
output = input) follows the same rule asplugin_model! - Compilation fails if input, context, or output types are incompatible
This macro is intended for testing plugin model logic in isolation and should not be used for testing pallet storage, dispatchables, or runtime configuration.