Skip to content

Commit 46d8164

Browse files
authored
#46: documentation best practices (#51)
1 parent bbe7319 commit 46d8164

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

best-practices.adoc

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
:toc: macro
2+
toc::[]
3+
:idprefix:
4+
:idseparator: -
5+
6+
## Hexagonal Architecture
7+
The sample app provided in this github repository is using a layered architecture.
8+
However, if you use hexagonal architecture instead, you can use https://www.archunit.org/userguide/html/000_Index.html#_onion_architecture[onion] instead.
9+
An example can be found in the https://github.com/TNG/ArchUnit-Examples/blob/main/example-plain/src/test/java/com/tngtech/archunit/exampletest/OnionArchitectureTest.java[official ArchUnit example repository].
10+
11+
## Layered Architecture
12+
The layered architecture used in this sample app is based on the template of https://github.com/devonfw/java/blob/main/modules/ROOT/pages/architecture/layered_architecture.adoc[devonfw Java architecture].
13+
It uses a classic three-layered architecture as descibed in the documentation linked above.
14+
ArchUnit provides the method `layeredArchitecture()` to easily construct rules to enforce a layered architecture.
15+
An example from this repository can be found https://github.com/devonfw-sample/archunit/blob/master/src/test/java/com/devonfw/sample/archunit/LayerRules.java[here].
16+
17+
## ArchRule
18+
19+
### General
20+
21+
The class `ArchRuleDefinition` provides methods like `classes()`,`noClasses()`, `methods()` to construct an `ArchRule`. Examples can be found in in this https://github.com/devonfw-sample/archunit/blob/f547ddd11e3eabd2437c067a2196a49ef3505904/src/test/java/com/devonfw/sample/archunit/ThirdPartyRules.java#L44-L48[repository] or in the https://github.com/TNG/ArchUnit-Examples/tree/main/example-junit4/src/test/java/com/tngtech/archunit/exampletest/junit4[official example repository of ArchUnit].
22+
23+
### Custom Rules
24+
25+
To implement a custom `ArchRule` `DescribedPredicate` and `ArchCondition` can be used like this:
26+
27+
`classes that ${PREDICATE} should ${CONDITION}`
28+
29+
The predicate filters a set of classes to verify some condition.
30+
An example can be found in this https://github.com/devonfw-sample/archunit/blob/master/src/test/java/com/devonfw/sample/archunit/AbstractRules.java#L25-L35[repository].
31+
32+
The ArchCondition checks whether the filtered set satisfies a given condition.
33+
An example can be found in this https://github.com/devonfw-sample/archunit/blob/master/src/test/java/com/devonfw/sample/archunit/AbstractRules.java#L62-L86[repository].
34+
35+
Further information is available in the https://www.archunit.org/userguide/html/000_Index.html#_creating_custom_rules[official user guide].
36+
37+
### Error Message
38+
39+
Sometimes rules need custom error messages. `because()` and `as()` can be used to modify the output of error messages. Further information can be found in the https://www.archunit.org/userguide/html/000_Index.html#_controlling_the_rule_text[official user guide].
40+
41+
`because("message")` concatenates the fluent API messages utilized by ArchUnit.
42+
43+
For example:
44+
[,java]
45+
----
46+
noClasses()
47+
.that(DescribedPredicate("message1"))
48+
.should(ArchCondition("message2"))
49+
.because("message3")
50+
----
51+
52+
would result in [red]#'no classes that "message1" should "message2", because "message3"'#.
53+
54+
Using `as("message")` enforces printing only the `message` string.
55+
56+
For example:
57+
[,java]
58+
----
59+
noClasses()
60+
.that(DescribedPredicate("message1"))
61+
.should(ArchCondition("message2"))
62+
.as("message3")
63+
----
64+
would result in [red]#'"message3"'#.
65+
66+
### Error Handling
67+
68+
If a rule failed unexpectedly, it might failed to check any classes, as that either means that no classes have been passed to the rule at all or that no classes passed the rule matching the `that()` clause. To allow rules being evaluated without checking any classes you can either use `ArchRule.allowEmptyShould(true)` on a single rule or set the configuration property `archRule.failOnEmptyShould = false` to change the behavior globally.
69+
70+
Further information can be found in the https://www.archunit.org/userguide/html/000_Index.html#_fail_rules_on_empty_should[official user guide].

0 commit comments

Comments
 (0)