Skip to content

Commit

Permalink
Ensure Classes Implementation are Assignable to Certain Classes
Browse files Browse the repository at this point in the history
Closes gh-93
  • Loading branch information
mnhock committed Aug 31, 2024
1 parent d4710f4 commit c863d5e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
16 changes: 15 additions & 1 deletion docs/USERGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ The default mode is `WITHOUT_TESTS`, which excludes test classes from the import
| General | `classesShouldResideOutsidePackage` | Classes matching specific naming patterns should reside outside a specified package. |
| General | `classesShouldBeAnnotatedWith` | Classes matching specific naming patterns should be annotated with a specified annotation. |
| General | `classesShouldNotBeAnnotatedWith` | Classes matching specific naming patterns should not be annotated with a specified annotation. |
| General | `classesShouldBeAssignableTo` | Classes matching specific naming patterns should be assignable to a certain type. |
| General | `fieldsShouldNotBePublic` | Fields should not be `public`, except constants. |
| General | `methodsShouldNotDeclareGenericExceptions` | Methods should not declare generic exceptions, like `Exception` or `RuntimeException`. |
| General | `methodsShouldNotDeclareException` | Methods with names matching a specified pattern should not declare a specified exception type. |
Expand Down Expand Up @@ -266,11 +267,24 @@ Taikai.builder()
.namespace("com.company.yourproject")
.java(java -> java
.classesShouldNotBeAnnotatedWith(".*Internal", PublicApi.class))
.classesShouldNotBeAnnotatedWith(".*Internal", "com.company.yourproject.api"))
.classesShouldNotBeAnnotatedWith(".*Internal", "com.company.yourproject.PublicApi"))
.build()
.check();
```

- **Classes Should Not Be Annotated with Specified Annotation**: Ensure that classes matching a specific regex pattern are not annotated with the specified annotation.

```java
Taikai.builder()
.namespace("com.company.yourproject")
.java(java -> java
.classesShouldBeAssignableTo(".*Repository", SpecialCrudRepository.class))
.classesShouldBeAssignableTo(".*Repository", "com.company.yourproject.SpecialCrudRepository"))
.build()
.check();
```


- **Methods Should Not Throw Generic Exception**: Ensure that methods do not throw generic exceptions like `Exception` and `RuntimeException` and use specific exception types instead.

```java
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/com/enofex/taikai/java/JavaConfigurer.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,32 @@ public JavaConfigurer classesShouldImplementHashCodeAndEquals(Configuration conf
.should(implementHashCodeAndEquals()), configuration));
}

public JavaConfigurer classesShouldBeAssignableTo(String regex, Class<?> clazz) {
return classesShouldBeAssignableTo(regex, clazz, Configuration.defaultConfiguration());
}

public JavaConfigurer classesShouldBeAssignableTo(String regex, Class<?> clazz,
Configuration configuration) {
return addRule(TaikaiRule.of(classes()
.that().haveSimpleNameEndingWith(regex)
.should().beAssignableTo(clazz)
.as("Classes have name matching %s should be assignable to %s".formatted(
regex, clazz)), configuration));
}

public JavaConfigurer classesShouldBeAssignableTo(String regex, String typeName) {
return classesShouldBeAssignableTo(regex, typeName, Configuration.defaultConfiguration());
}

public JavaConfigurer classesShouldBeAssignableTo(String regex, String typeName,
Configuration configuration) {
return addRule(TaikaiRule.of(classes()
.that().haveSimpleNameEndingWith(regex)
.should().beAssignableTo(typeName)
.as("Classes have name matching %s should be assignable to %s".formatted(
regex, typeName)), configuration));
}

public JavaConfigurer fieldsShouldNotBePublic() {
return fieldsShouldNotBePublic(Configuration.defaultConfiguration());
}
Expand Down
3 changes: 3 additions & 0 deletions src/test/java/com/enofex/taikai/Usage.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.tngtech.archunit.core.domain.JavaModifier.FINAL;
import static com.tngtech.archunit.core.domain.JavaModifier.PRIVATE;

import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.EnumSet;
Expand All @@ -27,6 +28,8 @@ public static void main(String[] args) {
.classesShouldResideOutsidePackage("regex", "com.enofex.taikai")
.classesShouldBeAnnotatedWith("regex", DisplayName.class)
.classesAnnotatedWithShouldResideInPackage(DisplayName.class, "com.enofex.taikai")
.classesShouldBeAssignableTo("regex", "java.time.LocalDate")
.classesShouldBeAssignableTo("regex", LocalDate.class)
.methodsShouldNotDeclareGenericExceptions()
.methodsShouldNotDeclareException("regex", RuntimeException.class)
.finalClassesShouldNotHaveProtectedMembers()
Expand Down

0 comments on commit c863d5e

Please sign in to comment.