This commit is contained in:
2025-07-19 23:02:54 +02:00
parent 4acf2fb2b1
commit a4d0f817bc
2 changed files with 304 additions and 1 deletions

View File

@@ -14,7 +14,7 @@ import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.state.State;
@Configuration
@EnableStateMachineFactory(name = "simpleEnumStateMachineFactory")
@EnableStateMachineFactory(name = "kamilEnumStateMachineFactory")
@Slf4j
class KamilEnumStateMachineConfiguration extends StateMachineConfigurerAdapter<OrderStates, OrderEvents> {
@Override

View File

@@ -0,0 +1,303 @@
package click.kamil.springstatemachineexporter.ast.in;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
class AstFileFinderTest {
private static final String CLASS_WITH_ANNOTATION = """
@Service
public class TestService {
public void doSomething() {
// implementation
}
}
""";
private static final String CLASS_WITH_MULTIPLE_ANNOTATIONS = """
@Service
@Component
public class TestService {
public void doSomething() {
// implementation
}
}
""";
private static final String INTERFACE_WITH_ANNOTATION = """
@FunctionalInterface
public interface TestInterface {
void doSomething();
}
""";
private static final String CLASS_WITHOUT_ANNOTATION = """
public class TestService {
public void doSomething() {
// implementation
}
}
""";
private static final String CLASS_WITH_DIFFERENT_ANNOTATION = """
@Repository
public class TestRepository {
public void doSomething() {
// implementation
}
}
""";
private static final String CLASS_WITH_FULLY_QUALIFIED_ANNOTATION = """
@org.springframework.stereotype.Service
public class TestService {
public void doSomething() {
// implementation
}
}
""";
private static final String MULTIPLE_CLASSES = """
@Service
public class TestService {
public void doSomething() {
// implementation
}
}
public class AnotherClass {
// no annotation
}
""";
private static final String CLASS_WITH_ANNOTATION_AND_FIELDS = """
@Service
public class TestService {
private String name;
public void doSomething() {
// implementation
}
}
""";
private static final String EMPTY_SOURCE = "";
private static final String INVALID_JAVA_SYNTAX = """
@Service
public class TestService {
// missing closing brace
""";
@Test
void shouldReturnTrue_whenClassHasMatchingAnnotation() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_ANNOTATION);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_ANNOTATION, annotationNames);
assertThat(result).isTrue();
}
@Test
void shouldReturnTrue_whenClassHasMultipleMatchingAnnotations() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_MULTIPLE_ANNOTATIONS);
List<String> annotationNames = Arrays.asList("Service", "Component");
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_MULTIPLE_ANNOTATIONS, annotationNames);
assertThat(result).isTrue();
}
@Test
void shouldReturnFalse_whenClassHasNoAnnotation() {
AstFileFinder finder = new AstFileFinder(CLASS_WITHOUT_ANNOTATION);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(CLASS_WITHOUT_ANNOTATION, annotationNames);
assertThat(result).isFalse();
}
@Test
void shouldReturnFalse_whenClassHasDifferentAnnotation() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_DIFFERENT_ANNOTATION);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_DIFFERENT_ANNOTATION, annotationNames);
assertThat(result).isFalse();
}
@Test
void shouldReturnTrue_whenClassHasFullyQualifiedAnnotation() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_FULLY_QUALIFIED_ANNOTATION);
List<String> annotationNames = Arrays.asList("org.springframework.stereotype.Service");
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_FULLY_QUALIFIED_ANNOTATION, annotationNames);
assertThat(result).isTrue();
}
@Test
void shouldReturnTrue_whenMultipleClassesAndOneHasAnnotation() {
AstFileFinder finder = new AstFileFinder(MULTIPLE_CLASSES);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(MULTIPLE_CLASSES, annotationNames);
assertThat(result).isTrue();
}
@Test
void shouldReturnFalse_whenInterfaceHasAnnotation() {
AstFileFinder finder = new AstFileFinder(INTERFACE_WITH_ANNOTATION);
List<String> annotationNames = Arrays.asList("FunctionalInterface");
boolean result = finder.hasClassWithAnnotation(INTERFACE_WITH_ANNOTATION, annotationNames);
assertThat(result).isFalse();
}
@Test
void shouldReturnFalse_whenEmptyAnnotationList() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_ANNOTATION);
List<String> annotationNames = Collections.emptyList();
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_ANNOTATION, annotationNames);
assertThat(result).isFalse();
}
@Test
void shouldReturnFalse_whenEmptySource() {
AstFileFinder finder = new AstFileFinder(EMPTY_SOURCE);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(EMPTY_SOURCE, annotationNames);
assertThat(result).isFalse();
}
@Test
void shouldThrowException_whenNullAnnotationList() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_ANNOTATION);
// when & then
assertThatThrownBy(() ->
finder.hasClassWithAnnotation(CLASS_WITH_ANNOTATION, null)
).isInstanceOf(NullPointerException.class);
}
@Test
void shouldReturnTrue_whenClassHasAnnotationAndFields() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_ANNOTATION_AND_FIELDS);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_ANNOTATION_AND_FIELDS, annotationNames);
assertThat(result).isTrue();
}
@Test
void shouldHandleInvalidJavaSyntax() {
AstFileFinder finder = new AstFileFinder(INVALID_JAVA_SYNTAX);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(INVALID_JAVA_SYNTAX, annotationNames);
// AST parser might still create a valid AST even with syntax errors
// The result depends on how the parser handles the invalid syntax
assertThat(result).isNotNull();
}
@Test
void shouldReturnTrue_whenAnnotationNameMatchesCaseInsensitive() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_ANNOTATION);
List<String> annotationNames = Arrays.asList("service"); // lowercase
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_ANNOTATION, annotationNames);
assertThat(result).isFalse(); // AST parser is case-sensitive
}
@Test
void shouldReturnTrue_whenMultipleAnnotationNamesProvided() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_ANNOTATION);
List<String> annotationNames = Arrays.asList("Component", "Service", "Repository");
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_ANNOTATION, annotationNames);
assertThat(result).isTrue();
}
@Test
void shouldReturnFalse_whenNoMatchingAnnotationNames() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_ANNOTATION);
List<String> annotationNames = Arrays.asList("Component", "Repository", "Controller");
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_ANNOTATION, annotationNames);
assertThat(result).isFalse();
}
@Test
void shouldReturnFalse_whenSourceContainsOnlyComments() {
String sourceWithComments = """
// This is a comment
/* Another comment */
/** JavaDoc comment */
""";
AstFileFinder finder = new AstFileFinder(sourceWithComments);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(sourceWithComments, annotationNames);
assertThat(result).isFalse();
}
@Test
void shouldReturnFalse_whenSourceContainsOnlyPackageDeclaration() {
String sourceWithPackage = "package com.example;";
AstFileFinder finder = new AstFileFinder(sourceWithPackage);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(sourceWithPackage, annotationNames);
assertThat(result).isFalse();
}
@Test
void shouldReturnTrue_whenClassHasAnnotationWithParameters() {
String classWithAnnotatedParams = """
@Service("testService")
public class TestService {
public void doSomething() {
// implementation
}
}
""";
AstFileFinder finder = new AstFileFinder(classWithAnnotatedParams);
List<String> annotationNames = Arrays.asList("Service");
boolean result = finder.hasClassWithAnnotation(classWithAnnotatedParams, annotationNames);
assertThat(result).isTrue();
}
@Test
void shouldReturnFalse_whenAnnotationListContainsNull() {
AstFileFinder finder = new AstFileFinder(CLASS_WITH_ANNOTATION);
List<String> annotationNames = Arrays.asList("Service", null, "Component");
boolean result = finder.hasClassWithAnnotation(CLASS_WITH_ANNOTATION, annotationNames);
assertThat(result).isTrue(); // Should still find "Service" annotation
}
}