arch_test_core

Crates.ioarch_test_core
lib.rsarch_test_core
version0.1.5
sourcesrc
created_at2021-06-13 10:22:01.766162
updated_at2021-06-15 10:55:19.734826
descriptionRule based architecture test library
homepage
repositoryhttps://github.com/Geigerkind/arch_test.git
max_upload_size
id409520
size134,570
Tom Dymel (Geigerkind)

documentation

README

ArchTest

crates.io crates.io codecov license Crates.io Crates.2io

ArchTest is a rule based architecture testing tool. It applies static analyses on the specified rust project to extract use relationships.

Features

  • Detect cyclic dependencies level wise or module wise
  • Prohibit parent access
  • Define layer relationships like MayNotAccess, MayOnlyAccess, MyNotBeAccessedBy, MayOnlyBeAccessedBy
  • And more, please consult the documentation.

Install

You can install it either as sub command of Cargo or as a package in your developer dependencies.

# Sub command
cargo install cargo-archtest --force

# Package
[dev-dependencies]
arch_test_core = "*"

How to use it

Using the Cargo sub command

Define in the cargo root path a file called architecture.json. Fill it according to the Specification struct. Example:

{
  "layer_names": ["analyzer", "parser", "domain_values", "entities", "materials", "services", "tests", "utils"],
  "access_rules": [
    "NoLayerCyclicDependencies",
    "NoModuleCyclicDependencies",
    "NoParentAccess",
    {
      "MayNotAccess": {
        "accessor": "parser",
        "accessed": ["analyzer"],
        "when_same_parent": true
      }
    },
    {
      "MayOnlyBeAccessedBy": {
        "accessors": ["services", "tests"],
        "accessed": "materials",
        "when_same_parent": false
      }
    },
    {
      "MayNotBeAccessedBy": {
        "accessors": ["materials", "domain_values", "entities", "utils"],
        "accessed": "services",
        "when_same_parent": true
      }
    }
  ]
}

Using a rust test

You can use the Architecture struct in order to define your architecture. Afterwards you check it for failures.

let architecture = Architecture::new(hash_set!["analyzer".to_owned(), "parser".to_owned(), ...])
.with_access_rule(NoParentAccess)
.with_access_rule(NoModuleCyclicDependencies)
.with_access_rule(NoLayerCyclicDependencies)
...
.with_access_rule(MayNotAccess::new(
    "materials".to_owned(),
    hash_set!["tests".to_owned()],
    true,
));
let module_tree = ModuleTree::new("src/lib.rs");
assert!(architecture.validate_access_rules().is_ok());
assert!(architecture.check_access_rules(&module_tree).is_ok());

If you are interested in the failure you can pretty print it like this:

architecture.check_access_rules(&module_tree).err().unwrap().print(module_tree.tree());

Continuous integration

You can use it in continuous integration by using either methods. If you decide to use the Cargo sub command on GitHub, the following snippet will allow you to test your project.

arch_test:
  name: ArchTest
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v2
    - uses: actions-rs/install@v0.1
      with:
        crate: cargo-archtest
        version: latest
    - run: cargo archtest
Commit count: 145

cargo fmt