Layered architecture enforcement.
Define layers top-to-bottom; enforce_direction/1 ensures each layer
only depends on layers below it (never upward).
Example
define_layers(
web: "MyApp.Web.**",
context: "MyApp.Context.**",
repo: "MyApp.Repo.**"
)
|> enforce_direction()Onion / Hexagonal Architecture
define_onion(
domain: "MyApp.Domain.**",
application: "MyApp.Application.**",
adapters: "MyApp.Adapters.**"
)
|> enforce_onion_rules()
Summary
Functions
Allows one layer to depend on another layer as an explicit exception to the normal top-to-bottom direction rule.
Defines an ordered list of architecture layers (top to bottom).
Defines an onion/hexagonal architecture with ordered rings (innermost first).
Enforces that each layer only depends on layers below it in the ordered list.
Enforces onion/hexagonal architecture rules
Sets the OTP application to introspect (default: :all).
Adds a custom rule: the given layer may not depend on listed layers.
Adds a custom rule: the given layer may only depend on listed layers.
Types
@type layer_name() :: atom()
@type t() :: %ArchTest.Layers{ allowed_deps: [{layer_name(), layer_name()}], app: atom() | nil, custom_rules: [ {layer_name(), :may_only_depend_on | :may_not_depend_on, [layer_name()]} ], layers: [{layer_name(), String.t()}] }
Functions
@spec allow_layer_dependency(t(), layer_name(), layer_name()) :: t()
Allows one layer to depend on another layer as an explicit exception to the normal top-to-bottom direction rule.
Defines an ordered list of architecture layers (top to bottom).
Accepts a keyword list of layer_name: "Pattern" pairs.
Order matters: earlier entries are "higher" layers.
Defines an onion/hexagonal architecture with ordered rings (innermost first).
Equivalent to define_layers/1 but with onion semantics applied in
enforce_onion_rules/1.
Enforces that each layer only depends on layers below it in the ordered list.
Violations are raised as ExUnit assertion failures.
Enforces onion/hexagonal architecture rules:
- Inner rings (listed first) must not depend on outer rings
- Outer rings may depend on inner rings
In other words: dependencies can only point inward.
Sets the OTP application to introspect (default: :all).
@spec layer_may_not_depend_on(t(), layer_name(), [layer_name()]) :: t()
Adds a custom rule: the given layer may not depend on listed layers.
@spec layer_may_only_depend_on(t(), layer_name(), [layer_name()]) :: t()
Adds a custom rule: the given layer may only depend on listed layers.