Skip to content

Commit

Permalink
Provide a New Naming Rule checking if methods and fields not match na…
Browse files Browse the repository at this point in the history
…ming

CLoses gh-25
CLoses gh-24
  • Loading branch information
mnhock authored and mnhock committed Jun 14, 2024
1 parent baa5a7f commit c4853d8
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 40 deletions.
70 changes: 37 additions & 33 deletions docs/USERGUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,40 @@ Architecture rules are defined using Taikai's fluent API, allowing developers to

## 3. Usage

| Category | Subcategory | Method Name | Rule Description | Import Options |
|-------------|----------------|-------------|------------------|-------------------------|
| **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 | `methodsShouldNotThrowGenericException` | Methods should not throw 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) |
| | General | `noUsageOfSystemOutOrErr` | Disallow usage of `System.out` or `System.err` | Default (WITHOUT_TESTS) |
| | General | `utilityClassesShouldBeFinalAndHavePrivateConstructor` | Utility classes should be `final` and have a private constructor | Default (WITHOUT_TESTS) |
| | Imports | `shouldHaveNoCycles` | No cyclic dependencies in imports | Default (WITHOUT_TESTS) |
| | Imports | `shouldNotImport` | Disallow specific imports (e.g., `..shaded..`) | Default (WITHOUT_TESTS) |
| | Naming | `classesShouldNotMatch` | Classes should not match specific naming patterns (e.g., `.*Impl`) | 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 | `jclassesShouldNotBeAnnotatedWithDisabled` | Ensure JUnit 5 classes are not annotated with `@Disabled` | Default (WITH_TESTS) |
| | JUnit 5 | `jmethodsShouldNotBeAnnotatedWithDisabled` | Ensure JUnit 5 methods are not annotated with `@Disabled` | Default (WITH_TESTS) |
| **Spring** | Boot | `springBootApplicationShouldBeIn` | Ensure `@SpringBootApplication` is in the default package | Default (WITH_TESTS) |
| | Configurations | `namesShouldEndWithConfiguration` | Configuration classes should end with "Configuration" | Default (WITH_TESTS) |
| | Configurations | `namesShouldMatch` | Configuration classes should match a regex pattern | Default (WITH_TESTS) |
| | Controllers | `namesShouldEndWithController` | Controllers should end with "Controller" | Default (WITH_TESTS) |
| | Controllers | `namesShouldMatch` | Controllers should match a regex pattern | Default (WITH_TESTS) |
| | Controllers | `shouldBeAnnotatedWithRestController` | Controllers should be annotated with `@RestController` | Default (WITH_TESTS) |
| | Controllers | `shouldBePackagePrivate` | Controllers should be package-private | Default (WITH_TESTS) |
| | Controllers | `shouldNotDependOnOtherControllers` | Controllers should not depend on other controllers | Default (WITH_TESTS) |
| | General | `noAutowiredFields` | Fields should not be annotated with `@Autowired` (prefer constructor injection) | Default (WITH_TESTS) |
| | Repositories | `namesShouldEndWithRepository` | Repositories should end with "Repository" | Default (WITH_TESTS) |
| | Repositories | `namesShouldMatch` | Repositories should match a regex pattern | Default (WITH_TESTS) |
| | Repositories | `shouldBeAnnotatedWithRepository` | Repositories should be annotated with `@Repository` | Default (WITH_TESTS) |
| | Services | `namesShouldEndWithService` | Services should end with "Service" | Default (WITH_TESTS) |
| | Services | `namesShouldMatch` | Services should match a regex pattern | Default (WITH_TESTS) |
| | Services | `shouldBeAnnotatedWithService` | Services should be annotated with `@Service` | Default (WITH_TESTS) |
| Category | Subcategory | Method Name | Rule Description | Import Options |
|-------------|----------------|--------------------------------------------------------|---------------------------------------------------------------------------------|-------------------------|
| **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 | `methodsShouldNotThrowGenericException` | Methods should not throw 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) |
| | General | `noUsageOfSystemOutOrErr` | Disallow usage of `System.out` or `System.err` | Default (WITHOUT_TESTS) |
| | General | `utilityClassesShouldBeFinalAndHavePrivateConstructor` | Utility classes should be `final` and have a private constructor | Default (WITHOUT_TESTS) |
| | Imports | `shouldHaveNoCycles` | No cyclic dependencies in imports | Default (WITHOUT_TESTS) |
| | Imports | `shouldNotImport` | Disallow specific imports (e.g., `..shaded..`) | Default (WITHOUT_TESTS) |
| | Naming | `classesShouldNotMatch` | Classes should not match specific naming patterns (e.g., `.*Impl`) | Default (WITHOUT_TESTS) |
| | Naming | `methodsShouldNotMatch` | Methods should not match specific naming patterns | Default (WITHOUT_TESTS) |
| | Naming | `fieldsShouldNotMatch` | Fields should not 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 | `jclassesShouldNotBeAnnotatedWithDisabled` | Ensure JUnit 5 classes are not annotated with `@Disabled` | Default (WITH_TESTS) |
| | JUnit 5 | `jmethodsShouldNotBeAnnotatedWithDisabled` | Ensure JUnit 5 methods are not annotated with `@Disabled` | Default (WITH_TESTS) |
| **Spring** | Boot | `springBootApplicationShouldBeIn` | Ensure `@SpringBootApplication` is in the default package | Default (WITH_TESTS) |
| | Configurations | `namesShouldEndWithConfiguration` | Configuration classes should end with "Configuration" | Default (WITH_TESTS) |
| | Configurations | `namesShouldMatch` | Configuration classes should match a regex pattern | Default (WITH_TESTS) |
| | Controllers | `namesShouldEndWithController` | Controllers should end with "Controller" | Default (WITH_TESTS) |
| | Controllers | `namesShouldMatch` | Controllers should match a regex pattern | Default (WITH_TESTS) |
| | Controllers | `shouldBeAnnotatedWithRestController` | Controllers should be annotated with `@RestController` | Default (WITH_TESTS) |
| | Controllers | `shouldBePackagePrivate` | Controllers should be package-private | Default (WITH_TESTS) |
| | Controllers | `shouldNotDependOnOtherControllers` | Controllers should not depend on other controllers | Default (WITH_TESTS) |
| | General | `noAutowiredFields` | Fields should not be annotated with `@Autowired` (prefer constructor injection) | Default (WITH_TESTS) |
| | Repositories | `namesShouldEndWithRepository` | Repositories should end with "Repository" | Default (WITH_TESTS) |
| | Repositories | `namesShouldMatch` | Repositories should match a regex pattern | Default (WITH_TESTS) |
| | Repositories | `shouldBeAnnotatedWithRepository` | Repositories should be annotated with `@Repository` | Default (WITH_TESTS) |
| | Services | `namesShouldEndWithService` | Services should end with "Service" | Default (WITH_TESTS) |
| | Services | `namesShouldMatch` | Services should match a regex pattern | Default (WITH_TESTS) |
| | Services | `shouldBeAnnotatedWithService` | Services should be annotated with `@Service` | Default (WITH_TESTS) |

### Java Configuration

Expand Down Expand Up @@ -125,14 +127,16 @@ Taikai.builder()
.check();
```

- **Naming Configuration**: Define naming conventions for classes, constants, and interfaces.
- **Naming Configuration**: Define naming conventions for classes, methods, fields, constants, and interfaces.

```java
Taikai.builder()
.namespace("com.company.yourproject")
.java(java -> java
.naming(naming -> naming
.classesShouldNotMatch(".*Impl")
.methodsShouldNotMatch("blameThrower")
.fieldsShouldNotMatch("notGonnaGiveYouUp")
.constantsShouldFollowConvention()
.interfacesShouldNotHavePrefixI())))
.build()
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/com/enofex/taikai/java/NamingConfigurer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noFields;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noMethods;

import com.enofex.taikai.TaikaiRule;
import com.enofex.taikai.TaikaiRule.Configuration;
Expand Down Expand Up @@ -31,6 +33,26 @@ public NamingConfigurer classesShouldNotMatch(String regex, Configuration config
.as("Classes should not have names matching %s".formatted(regex)), configuration));
}

public NamingConfigurer methodsShouldNotMatch(String regex) {
return methodsShouldNotMatch(regex, null);
}

public NamingConfigurer methodsShouldNotMatch(String regex, Configuration configuration) {
return addRule(TaikaiRule.of(noMethods()
.should().haveNameMatching(regex)
.as("Methods should not have names matching %s".formatted(regex)), configuration));
}

public NamingConfigurer fieldsShouldNotMatch(String regex) {
return fieldsShouldNotMatch(regex, null);
}

public NamingConfigurer fieldsShouldNotMatch(String regex, Configuration configuration) {
return addRule(TaikaiRule.of(noFields()
.should().haveNameMatching(regex)
.as("Fields should not have names matching %s".formatted(regex)), configuration));
}

public NamingConfigurer interfacesShouldNotHavePrefixI() {
return interfacesShouldNotHavePrefixI(null);
}
Expand Down
15 changes: 8 additions & 7 deletions src/test/java/com/enofex/taikai/Usage.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ public static void main(String[] args) {
.namesShouldMatch("regex"))
.controllers(controllers -> controllers
.shouldBeAnnotatedWithRestController()
.namesShouldEndWithController()
.namesShouldMatch("regex")
.shouldNotDependOnOtherControllers()
.shouldBePackagePrivate())
.shouldBePackagePrivate()
.namesShouldEndWithController()
.namesShouldMatch("regex"))
.services(services -> services
.shouldBeAnnotatedWithService()
.namesShouldMatch("regex")
Expand All @@ -34,26 +34,27 @@ public static void main(String[] args) {
.classesShouldNotBeAnnotatedWithDisabled()
.methodsShouldNotBeAnnotatedWithDisabled()))
.java(java -> java
.noUsageOf(Date.class)
.noUsageOf(Calendar.class)
.noUsageOf("java.text.SimpleDateFormat")
.noUsageOfSystemOutOrErr()
.noUsageOfDeprecatedAPIs()
.classesShouldImplementHashCodeAndEquals()
.methodsShouldNotThrowGenericException()
.utilityClassesShouldBeFinalAndHavePrivateConstructor()
.noUsageOf(Date.class)
.noUsageOf(Calendar.class)
.noUsageOf("java.text.SimpleDateFormat")
.imports(imports -> imports
.shouldHaveNoCycles()
.shouldNotImport("..shaded..")
.shouldNotImport("..lombok..")
.shouldNotImport("org.junit.."))
.naming(naming -> naming
.classesShouldNotMatch(".*Impl")
.methodsShouldNotMatch("foo")
.fieldsShouldNotMatch("bar")
.constantsShouldFollowConvention()
.interfacesShouldNotHavePrefixI()))
.build();

taikai.check();
}

}

0 comments on commit c4853d8

Please sign in to comment.