From 5b9efb6b5b7592e01a41532b385a20eaa6546ee9 Mon Sep 17 00:00:00 2001 From: Oleh Kurpiak Date: Mon, 28 Feb 2022 01:59:41 +0200 Subject: [PATCH] [Java] Java class assert (#11738) * [Java] java file assert * [Java] java file assert --- .../assertions/AbstractAnnotationAssert.java | 53 +++++++++++++ .../java/assertions/JavaFileAssert.java | 78 +++++++++++++++++++ .../assertions/MethodAnnotationAssert.java | 19 +++++ .../codegen/java/assertions/MethodAssert.java | 42 ++++++++++ .../assertions/ParameterAnnotationAssert.java | 19 +++++ .../java/assertions/ParameterAssert.java | 31 ++++++++ .../assertions/PropertyAnnotationAssert.java | 19 +++++ .../java/assertions/PropertyAssert.java | 32 ++++++++ .../java/assertions/TypeAnnotationAssert.java | 19 +++++ .../java/spring/SpringCodegenTest.java | 47 +++++++++++ 10 files changed, 359 insertions(+) create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/AbstractAnnotationAssert.java create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/JavaFileAssert.java create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/MethodAnnotationAssert.java create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/MethodAssert.java create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/ParameterAnnotationAssert.java create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/ParameterAssert.java create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/PropertyAnnotationAssert.java create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/PropertyAssert.java create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/TypeAnnotationAssert.java diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/AbstractAnnotationAssert.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/AbstractAnnotationAssert.java new file mode 100644 index 00000000000..615fdbf1ec4 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/AbstractAnnotationAssert.java @@ -0,0 +1,53 @@ +package org.openapitools.codegen.java.assertions; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.assertj.core.api.ListAssert; + +import com.github.javaparser.ast.expr.AnnotationExpr; +import com.github.javaparser.ast.expr.MemberValuePair; +import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; + +public abstract class AbstractAnnotationAssert> extends ListAssert { + + protected AbstractAnnotationAssert(final List annotationExpr) { + super(annotationExpr); + } + + public ACTUAL hasSize(final int size) { + super.hasSize(size); + return myself(); + } + + public ACTUAL containsWithName(final String name) { + super + .withFailMessage("Should have annotation with name: " + name) + .anyMatch(annotation -> annotation.getNameAsString().equals(name)); + return myself(); + } + + public ACTUAL containsWithNameAndAttributes(final String name, final Map attributes) { + super + .withFailMessage("Should have annotation with name: " + name + " and attributes: " + attributes + ", but was: " + actual) + .anyMatch(annotation -> annotation.getNameAsString().equals(name) && hasAttributes(annotation, attributes)); + return myself(); + } + + private static boolean hasAttributes(final AnnotationExpr annotation, final Map expectedAttributesToContains) { + final Map actualAttributes = annotation.getChildNodes().stream() + .filter(MemberValuePair.class::isInstance) + .map(MemberValuePair.class::cast) + .collect(Collectors.toMap(NodeWithSimpleName::getNameAsString, pair -> pair.getValue().toString())); + + return expectedAttributesToContains.entrySet().stream() + .allMatch(expected -> Objects.equals(actualAttributes.get(expected.getKey()), expected.getValue())); + } + + @SuppressWarnings("unchecked") + private ACTUAL myself() { + return (ACTUAL) this; + } +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/JavaFileAssert.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/JavaFileAssert.java new file mode 100644 index 00000000000..629a86a71b7 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/JavaFileAssert.java @@ -0,0 +1,78 @@ +package org.openapitools.codegen.java.assertions; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.Assertions; + +import com.github.javaparser.StaticJavaParser; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.FieldDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.nodeTypes.NodeWithName; + +public class JavaFileAssert extends AbstractAssert { + + private JavaFileAssert(final CompilationUnit actual) { + super(actual, JavaFileAssert.class); + } + + public static JavaFileAssert assertThat(final String source) { + return new JavaFileAssert(StaticJavaParser.parse(source)); + } + + public static JavaFileAssert assertThat(final Path path) { + try { + return new JavaFileAssert(StaticJavaParser.parse(path)); + } catch (IOException e) { + throw new RuntimeException("Exception while reading file: " + path, e); + } + } + + public MethodAssert assertMethod(final String methodName, final String... paramTypes) { + List methods = paramTypes.length == 0 + ? actual.getType(0).getMethodsByName(methodName) + : actual.getType(0).getMethodsBySignature(methodName, paramTypes); + String message = paramTypes.length == 0 + ? "Expected to be a single method %s, but found " + methods.size() + : "Expected to be a single method %s with parameter(s) %s, but found " + methods.size(); + Assertions.assertThat(methods) + .withFailMessage(message, methodName, Arrays.toString(paramTypes)) + .hasSize(1); + + return new MethodAssert(this, methods.get(0)); + } + + public PropertyAssert hasProperty(final String propertyName) { + Optional fieldOptional = actual.getType(0).getMembers().stream() + .filter(FieldDeclaration.class::isInstance) + .map(FieldDeclaration.class::cast) + .filter(field -> field.getVariables().getFirst().map(var -> var.getNameAsString().equals(propertyName)).orElse(Boolean.FALSE)) + .findFirst(); + Assertions.assertThat(fieldOptional) + .withFailMessage("Should have field with name %s", propertyName) + .isPresent(); + + return new PropertyAssert(this, fieldOptional.get()); + } + + public JavaFileAssert hasImports(final String... imports) { + Assertions.assertThat(actual.getImports().stream().map(NodeWithName::getNameAsString)) + .containsAll(Arrays.asList(imports)); + return this; + } + + public JavaFileAssert printFileContent() { + System.out.println(actual); + return this; + } + + public TypeAnnotationAssert assertTypeAnnotations() { + return new TypeAnnotationAssert(this, actual.getType(0).getAnnotations()); + } + +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/MethodAnnotationAssert.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/MethodAnnotationAssert.java new file mode 100644 index 00000000000..60fc9d6f8fd --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/MethodAnnotationAssert.java @@ -0,0 +1,19 @@ +package org.openapitools.codegen.java.assertions; + +import java.util.List; + +import com.github.javaparser.ast.expr.AnnotationExpr; + +public class MethodAnnotationAssert extends AbstractAnnotationAssert { + + private final MethodAssert methodAssert; + + protected MethodAnnotationAssert(final MethodAssert methodAssert, final List annotationExpr) { + super(annotationExpr); + this.methodAssert = methodAssert; + } + + public MethodAssert toMethod() { + return methodAssert; + } +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/MethodAssert.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/MethodAssert.java new file mode 100644 index 00000000000..61ef3bdd6a2 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/MethodAssert.java @@ -0,0 +1,42 @@ +package org.openapitools.codegen.java.assertions; + +import java.util.Optional; + +import org.assertj.core.api.AbstractAssert; +import org.assertj.core.api.Assertions; + +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.Parameter; + +public class MethodAssert extends AbstractAssert { + + private final JavaFileAssert fileAssert; + + MethodAssert(final JavaFileAssert fileAssert, final MethodDeclaration methodDeclaration) { + super(methodDeclaration, MethodAssert.class); + this.fileAssert = fileAssert; + } + + public JavaFileAssert and() { + return fileAssert; + } + + public MethodAnnotationAssert assertMethodAnnotations() { + return new MethodAnnotationAssert(this, actual.getAnnotations()); + } + + public MethodAssert hasReturnType(final String returnType) { + Assertions.assertThat(actual.getType().toString()) + .isEqualTo(returnType); + return this; + } + + public ParameterAssert hasParameter(final String paramName) { + final Optional parameter = actual.getParameterByName(paramName); + Assertions.assertThat(parameter) + .withFailMessage("Method %s should have parameter %s, but it doesn't", actual.getNameAsString(), paramName) + .isPresent(); + return new ParameterAssert(this, parameter.get()); + } + +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/ParameterAnnotationAssert.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/ParameterAnnotationAssert.java new file mode 100644 index 00000000000..7348d34f04c --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/ParameterAnnotationAssert.java @@ -0,0 +1,19 @@ +package org.openapitools.codegen.java.assertions; + +import java.util.List; + +import com.github.javaparser.ast.expr.AnnotationExpr; + +public class ParameterAnnotationAssert extends AbstractAnnotationAssert { + + private final ParameterAssert parameterAssert; + + protected ParameterAnnotationAssert(final ParameterAssert parameterAssert, final List annotationExpr) { + super(annotationExpr); + this.parameterAssert = parameterAssert; + } + + public ParameterAssert toParameter() { + return parameterAssert; + } +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/ParameterAssert.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/ParameterAssert.java new file mode 100644 index 00000000000..6fe73ce5899 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/ParameterAssert.java @@ -0,0 +1,31 @@ +package org.openapitools.codegen.java.assertions; + +import org.assertj.core.api.Assertions; +import org.assertj.core.api.ObjectAssert; + +import com.github.javaparser.ast.body.Parameter; + +public class ParameterAssert extends ObjectAssert { + + private final MethodAssert methodAssert; + + protected ParameterAssert(final MethodAssert methodAssert, final Parameter parameter) { + super(parameter); + this.methodAssert = methodAssert; + } + + public MethodAssert toMethod() { + return methodAssert; + } + + public ParameterAssert withType(final String expectedType) { + Assertions.assertThat(actual.getTypeAsString()) + .withFailMessage("Expected parameter to have type %s, but was %s", expectedType, actual.getTypeAsString()) + .isEqualTo(expectedType); + return this; + } + + public ParameterAnnotationAssert assertParameterAnnotations() { + return new ParameterAnnotationAssert(this, actual.getAnnotations()); + } +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/PropertyAnnotationAssert.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/PropertyAnnotationAssert.java new file mode 100644 index 00000000000..3db06d49aed --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/PropertyAnnotationAssert.java @@ -0,0 +1,19 @@ +package org.openapitools.codegen.java.assertions; + +import java.util.List; + +import com.github.javaparser.ast.expr.AnnotationExpr; + +public class PropertyAnnotationAssert extends AbstractAnnotationAssert { + + private final PropertyAssert propertyAssert; + + protected PropertyAnnotationAssert(final PropertyAssert propertyAssert, final List annotationExpr) { + super(annotationExpr); + this.propertyAssert = propertyAssert; + } + + public PropertyAssert toProperty() { + return propertyAssert; + } +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/PropertyAssert.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/PropertyAssert.java new file mode 100644 index 00000000000..476b530f4b2 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/PropertyAssert.java @@ -0,0 +1,32 @@ +package org.openapitools.codegen.java.assertions; + +import org.assertj.core.api.Assertions; +import org.assertj.core.api.ObjectAssert; + +import com.github.javaparser.ast.body.FieldDeclaration; +import com.github.javaparser.ast.body.Parameter; + +public class PropertyAssert extends ObjectAssert { + + private final JavaFileAssert javaFileAssert; + + protected PropertyAssert(final JavaFileAssert javaFileAssert, final FieldDeclaration fieldDeclaration) { + super(fieldDeclaration); + this.javaFileAssert = javaFileAssert; + } + + public JavaFileAssert toType() { + return javaFileAssert; + } + + public PropertyAssert withType(final String expectedType) { + Assertions.assertThat(actual.getElementType().toString()) + .withFailMessage("Expected property %s to have type %s, but was %s", actual.getVariable(0).getNameAsString(), expectedType, actual.getElementType().toString()) + .isEqualTo(expectedType); + return this; + } + + public PropertyAnnotationAssert assertPropertyAnnotations() { + return new PropertyAnnotationAssert(this, actual.getAnnotations()); + } +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/TypeAnnotationAssert.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/TypeAnnotationAssert.java new file mode 100644 index 00000000000..286474fa29e --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/assertions/TypeAnnotationAssert.java @@ -0,0 +1,19 @@ +package org.openapitools.codegen.java.assertions; + +import java.util.List; + +import com.github.javaparser.ast.expr.AnnotationExpr; + +public class TypeAnnotationAssert extends AbstractAnnotationAssert { + + private final JavaFileAssert fileAssert; + + protected TypeAnnotationAssert(final JavaFileAssert fileAssert, final List annotationExpr) { + super(annotationExpr); + this.fileAssert = fileAssert; + } + + public JavaFileAssert toType() { + return fileAssert; + } +} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 91769f5faec..e7f1067145f 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -40,6 +40,7 @@ import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.stream.Collectors; +import org.openapitools.codegen.java.assertions.JavaFileAssert; import org.openapitools.codegen.CliOption; import org.openapitools.codegen.ClientOptInput; import org.openapitools.codegen.CodegenConstants; @@ -58,6 +59,8 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Ignore; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; + public class SpringCodegenTest { @Test @@ -95,9 +98,53 @@ public class SpringCodegenTest { generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); generator.opts(input).generate(); + JavaFileAssert.assertThat(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java")) + .assertTypeAnnotations() + .hasSize(3) + .containsWithName("Validated") + .containsWithName("Generated") + .containsWithNameAndAttributes("Generated", ImmutableMap.of( + "value", "\"org.openapitools.codegen.languages.SpringCodegen\"" + )) + .containsWithNameAndAttributes("Tag", ImmutableMap.of( + "name", "\"zebras\"" + )) + .toType() + .assertMethod("getZebras") + .hasReturnType("ResponseEntity") + .assertMethodAnnotations() + .hasSize(2) + .containsWithNameAndAttributes("Operation", ImmutableMap.of("operationId", "\"getZebras\"")) + .containsWithNameAndAttributes("RequestMapping", ImmutableMap.of( + "method", "RequestMethod.GET", + "value", "\"/zebras\"" + )) + .toMethod() + .hasParameter("limit").withType("BigDecimal") + .assertParameterAnnotations() + .containsWithName("Valid") + .containsWithNameAndAttributes("Parameter", ImmutableMap.of("name", "\"limit\"")) + .containsWithNameAndAttributes("RequestParam", ImmutableMap.of("required", "false", "value", "\"limit\"")) + .toParameter() + .toMethod() + .hasParameter("animalParams").withType("AnimalParams"); + + // todo: to remove assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java"), "AnimalParams"); + JavaFileAssert.assertThat(Paths.get(outputPath + "/src/main/java/org/openapitools/model/AnimalParams.java")) + .hasImports("org.springframework.format.annotation.DateTimeFormat") + .hasProperty("born").withType("LocalDate") + .assertPropertyAnnotations() + .containsWithNameAndAttributes("DateTimeFormat", ImmutableMap.of("iso", "DateTimeFormat.ISO.DATE")) + .toProperty() + .toType() + .hasProperty("lastSeen").withType("OffsetDateTime") + .assertPropertyAnnotations() + .containsWithNameAndAttributes("DateTimeFormat", ImmutableMap.of("iso", "DateTimeFormat.ISO.DATE_TIME")); + + // todo: to remove assertFileContains(Paths.get(outputPath + "/src/main/java/org/openapitools/model/AnimalParams.java"), "@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)", "@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)");