Skip to content

Commit

Permalink
Provide a new JUnit 5 Rule checking test classes are package private
Browse files Browse the repository at this point in the history
Closes gh-28
  • Loading branch information
mnhock committed Jun 16, 2024
1 parent b40ddc0 commit 20468a0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 19 deletions.
21 changes: 17 additions & 4 deletions docs/USERGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Architecture rules are defined using Taikai's fluent API, allowing developers to
|------------|----------------|--------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|-------------------------|
| **Java** | General | `classesShouldImplementHashCodeAndEquals` | Classes should implement `hashCode` and `equals` | Default (WITHOUT_TESTS) |
| | General | `fieldsShouldNotBePublic` | Fields should not be `public` (except constants) | Default (WITHOUT_TESTS) |
| | General | `methodsShouldNotDeclareGenericExceptions` | Methods should not declare generic exceptions (`Exception`, `RuntimeException`) | Default (WITHOUT_TESTS) |
| | General | `methodsShouldNotDeclareGenericExceptions` | Methods should not declare generic exceptions (`Exception`, `RuntimeException`) | Default (WITHOUT_TESTS) |
| | General | `noUsageOf` | Disallow usage of specific classes | Default (WITHOUT_TESTS) |
| | General | `noUsageOf` | Disallow usage of specific classes by class reference | Default (WITHOUT_TESTS) |
| | General | `noUsageOfDeprecatedAPIs` | No usage of deprecated APIs annotated with `Deprecated` | Default (WITHOUT_TESTS) |
Expand All @@ -40,9 +40,10 @@ Architecture rules are defined using Taikai's fluent API, allowing developers to
| | Naming | `fieldsAnnotatedWithShouldMatch` | Fields annotated with should match specific naming patterns | Default (WITHOUT_TESTS) |
| | Naming | `constantsShouldFollowConvention` | Constants should follow naming conventions | Default (WITHOUT_TESTS) |
| | Naming | `interfacesShouldNotHavePrefixI` | Interfaces should not have the prefix `I` | Default (WITHOUT_TESTS) |
| **Test** | JUnit 5 | `classesShouldNotBeAnnotatedWithDisabled` | Ensure classes are not annotated with `@Disabled` | Default (ONLY_TESTS) |
| | JUnit 5 | `methodsShouldNotBeAnnotatedWithDisabled` | Ensure methods are not annotated with `@Disabled` | Default (ONLY_TESTS) |
| **Test** | JUnit 5 | `classesShouldBePackagePrivate` | Ensure that classes whose names match a specific naming pattern are declared as package-private. | Default (ONLY_TESTS) |
| | JUnit 5 | `classesShouldNotBeAnnotatedWithDisabled` | Ensure classes are not annotated with `@Disabled` | Default (ONLY_TESTS) |
| | JUnit 5 | `methodsShouldBePackagePrivate` | Ensure that test methods annotated with `@Test` or `@ParameterizedTest` are package-private. | Default (ONLY_TESTS) |
| | JUnit 5 | `methodsShouldNotBeAnnotatedWithDisabled` | Ensure methods are not annotated with `@Disabled` | Default (ONLY_TESTS) |
| | JUnit 5 | `methodsShouldBeAnnotatedWithDisplayName` | Ensure that test methods annotated with `@Test` or `@ParameterizedTest` are annotated with `@DisplayName`. | Default (ONLY_TESTS) |
| | JUnit 5 | `methodsShouldMatch` | Ensure that test methods annotated with `@Test` or `@ParameterizedTest` have names matching a specific regex pattern. | Default (ONLY_TESTS) |
| | JUnit 5 | `methodsShouldNotDeclareExceptions` | Ensure that test methods annotated with `@Test` or `@ParameterizedTest` do not declare any thrown exceptions. | Default (ONLY_TESTS) |
Expand Down Expand Up @@ -251,7 +252,7 @@ Taikai.builder()
.check();
```

- **Ensure Test Methods Do Not Declare Thrown Exceptions** Ensure that JUnit 5 test methods annotated with `@Test` or `@ParameterizedTest` do not declare any thrown exceptions.
- **Ensure Test Methods Do Not Declare Thrown Exceptions**: Ensure that JUnit 5 test methods annotated with `@Test` or `@ParameterizedTest` do not declare any thrown exceptions.

```java
Taikai.builder()
Expand All @@ -263,6 +264,18 @@ Taikai.builder()
.check();
```

- **Ensure Classes with Matching Names are Package-Private**: Ensure that classes whose names match a specified regex pattern are declared as package-private.

```java
Taikai.builder()
.namespace("com.company.yourproject")
.test(test -> test
.junit5(junit5 -> junit5
.classesShouldBePackagePrivate(".*Test"))
.build()
.check();
```

### Spring Configuration

Spring configuration involves defining constraints specific to Spring Framework usage.
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/enofex/taikai/test/JUnit5Configurer.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static com.enofex.taikai.test.JUnit5Predicates.ANNOTATION_TEST;
import static com.enofex.taikai.test.JUnit5Predicates.annotatedWithTestOrParameterizedTest;
import static com.tngtech.archunit.lang.conditions.ArchPredicates.are;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noMethods;
Expand Down Expand Up @@ -38,6 +39,18 @@ public JUnit5Configurer methodsShouldMatch(String regex, Configuration configura
configuration));
}

public JUnit5Configurer classesShouldBePackagePrivate(String regex) {
return classesShouldBePackagePrivate(regex, CONFIGURATION);
}

public JUnit5Configurer classesShouldBePackagePrivate(String regex, Configuration configuration) {
return addRule(TaikaiRule.of(classes()
.that().haveNameMatching(regex)
.should().bePackagePrivate()
.as("Classes with names matching %s should be package-private".formatted(regex)),
configuration));
}

public JUnit5Configurer methodsShouldNotDeclareExceptions() {
return methodsShouldNotDeclareExceptions(CONFIGURATION);
}
Expand Down
11 changes: 6 additions & 5 deletions src/test/java/com/enofex/taikai/ArchitectureTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,22 @@ void shouldFulfilConstrains() {
.test(test -> test
.junit5(junit5 -> junit5
.classesShouldNotBeAnnotatedWithDisabled()
.classesShouldBePackagePrivate(".*Test")
.methodsShouldNotBeAnnotatedWithDisabled()
.methodsShouldMatch("should.*")
.methodsShouldBePackagePrivate()
.methodsShouldNotDeclareExceptions()))
.java(java -> java
.noUsageOfDeprecatedAPIs()
.finalClassesShouldNotHaveProtectedMembers()
.classesShouldImplementHashCodeAndEquals()
.methodsShouldNotDeclareGenericExceptions()
.utilityClassesShouldBeFinalAndHavePrivateConstructor()
.fieldsShouldNotBePublic()
.noUsageOfSystemOutOrErr()
.noUsageOf(Date.class)
.noUsageOf(Calendar.class)
.noUsageOf(SimpleDateFormat.class)
.classesShouldImplementHashCodeAndEquals()
.finalClassesShouldNotHaveProtectedMembers()
.utilityClassesShouldBeFinalAndHavePrivateConstructor()
.methodsShouldNotDeclareGenericExceptions()
.fieldsShouldNotBePublic()
.imports(imports -> imports
.shouldHaveNoCycles()
.shouldNotImport("..shaded..")
Expand Down
17 changes: 7 additions & 10 deletions src/test/java/com/enofex/taikai/Usage.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
import java.util.Calendar;
import java.util.Date;

final class Usage {

private Usage() {
}
class Usage {

public static void main(String[] args) {
Taikai taikai = Taikai.builder()
Taikai.builder()
.namespace("com.enofex.taikai")
.spring(spring -> spring
.noAutowiredFields()
Expand Down Expand Up @@ -38,8 +35,9 @@ public static void main(String[] args) {
.methodsShouldMatch("should.*")
.methodsShouldBePackagePrivate()
.methodsShouldBeAnnotatedWithDisplayName()
.classesShouldNotBeAnnotatedWithDisabled()
.methodsShouldNotBeAnnotatedWithDisabled()))
.methodsShouldNotBeAnnotatedWithDisabled()
.classesShouldBePackagePrivate(".*Test")
.classesShouldNotBeAnnotatedWithDisabled()))
.java(java -> java
.noUsageOf(Date.class)
.noUsageOf(Calendar.class)
Expand All @@ -61,8 +59,7 @@ public static void main(String[] args) {
.fieldsShouldNotMatch("bar")
.constantsShouldFollowConvention()
.interfacesShouldNotHavePrefixI()))
.build();

taikai.check();
.build()
.check();
}
}

0 comments on commit 20468a0

Please sign in to comment.