Simplify SourceFileAssert assertion methods
Remove assertion methods that turned out not to be needed when testing Spring Framework's AOT generated code. Closes gh-28556
This commit is contained in:
parent
5f4bcf197c
commit
74caa9213a
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aot.test.generator.file;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.thoughtworks.qdox.model.JavaMethod;
|
||||
import com.thoughtworks.qdox.model.JavaParameter;
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Assertion methods for {@code SourceFile} methods.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 6.0
|
||||
*/
|
||||
public class MethodAssert extends AbstractAssert<MethodAssert, JavaMethod> {
|
||||
|
||||
|
||||
MethodAssert(JavaMethod actual) {
|
||||
super(actual, MethodAssert.class);
|
||||
as(describe(actual));
|
||||
}
|
||||
|
||||
|
||||
private String describe(JavaMethod actual) {
|
||||
return actual.getName() + "("
|
||||
+ actual.getParameters().stream().map(
|
||||
this::getFullyQualifiedName).collect(Collectors.joining(", "))
|
||||
+ ")";
|
||||
}
|
||||
|
||||
private String getFullyQualifiedName(JavaParameter parameter) {
|
||||
return parameter.getType().getFullyQualifiedName();
|
||||
}
|
||||
|
||||
public void withBody(String expected) {
|
||||
assertThat(this.actual.getSourceCode()).as(
|
||||
this.info.description()).isEqualToNormalizingWhitespace(expected);
|
||||
}
|
||||
|
||||
public void withBodyContaining(CharSequence... values) {
|
||||
assertThat(this.actual.getSourceCode()).as(this.info.description()).contains(
|
||||
values);
|
||||
}
|
||||
|
||||
}
|
|
@ -23,14 +23,15 @@ import java.nio.charset.StandardCharsets;
|
|||
|
||||
import com.thoughtworks.qdox.JavaProjectBuilder;
|
||||
import com.thoughtworks.qdox.model.JavaClass;
|
||||
import com.thoughtworks.qdox.model.JavaPackage;
|
||||
import com.thoughtworks.qdox.model.JavaSource;
|
||||
import org.assertj.core.api.AssertProvider;
|
||||
import org.assertj.core.util.Strings;
|
||||
|
||||
import org.springframework.core.io.InputStreamSource;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link DynamicFile} that holds Java source code and provides
|
||||
|
@ -48,12 +49,12 @@ public final class SourceFile extends DynamicFile
|
|||
implements AssertProvider<SourceFileAssert> {
|
||||
|
||||
|
||||
private final JavaSource javaSource;
|
||||
private final String className;
|
||||
|
||||
|
||||
private SourceFile(String path, String content, JavaSource javaSource) {
|
||||
private SourceFile(String path, String content, String className) {
|
||||
super(path, content);
|
||||
this.javaSource = javaSource;
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,24 +127,31 @@ public final class SourceFile extends DynamicFile
|
|||
*/
|
||||
public static SourceFile of(@Nullable String path, WritableContent writableContent) {
|
||||
String content = toString(writableContent);
|
||||
if (Strings.isNullOrEmpty(content)) {
|
||||
throw new IllegalStateException("WritableContent did not append any content");
|
||||
Assert.state(StringUtils.hasLength(content), "WritableContent did not append any content");
|
||||
String className = getClassName(content);
|
||||
if (!StringUtils.hasLength(path)) {
|
||||
path = ClassUtils.convertClassNameToResourcePath(className) + ".java";
|
||||
}
|
||||
JavaSource javaSource = parse(content);
|
||||
if (path == null || path.isEmpty()) {
|
||||
path = deducePath(javaSource);
|
||||
}
|
||||
return new SourceFile(path, content, javaSource);
|
||||
return new SourceFile(path, content, className);
|
||||
}
|
||||
|
||||
private static JavaSource parse(String content) {
|
||||
/**
|
||||
* Return the fully-qualified class name.
|
||||
* @return the fully qualified class name
|
||||
*/
|
||||
public String getClassName() {
|
||||
return this.className;
|
||||
}
|
||||
|
||||
private static String getClassName(String content) {
|
||||
JavaProjectBuilder builder = new JavaProjectBuilder();
|
||||
try {
|
||||
JavaSource javaSource = builder.addSource(new StringReader(content));
|
||||
if (javaSource.getClasses().size() != 1) {
|
||||
throw new IllegalStateException("Source must define a single class");
|
||||
}
|
||||
return javaSource;
|
||||
Assert.state(javaSource.getClasses().size() == 1, "Source must define a single class");
|
||||
JavaClass javaClass = javaSource.getClasses().get(0);
|
||||
return (javaSource.getPackage() != null)
|
||||
? javaSource.getPackageName() + "." + javaClass.getName()
|
||||
: javaClass.getName();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
|
@ -151,28 +159,6 @@ public final class SourceFile extends DynamicFile
|
|||
}
|
||||
}
|
||||
|
||||
private static String deducePath(JavaSource javaSource) {
|
||||
JavaPackage javaPackage = javaSource.getPackage();
|
||||
JavaClass javaClass = javaSource.getClasses().get(0);
|
||||
String path = javaClass.getName() + ".java";
|
||||
if (javaPackage != null) {
|
||||
path = javaPackage.getName().replace('.', '/') + "/" + path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
JavaSource getJavaSource() {
|
||||
return this.javaSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class name of the source file.
|
||||
* @return the class name
|
||||
*/
|
||||
public String getClassName() {
|
||||
return this.javaSource.getClasses().get(0).getFullyQualifiedName();
|
||||
}
|
||||
|
||||
/**
|
||||
* AssertJ {@code assertThat} support.
|
||||
* @deprecated use {@code assertThat(sourceFile)} rather than calling this
|
||||
|
@ -184,4 +170,6 @@ public final class SourceFile extends DynamicFile
|
|||
return new SourceFileAssert(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,21 +16,6 @@
|
|||
|
||||
package org.springframework.aot.test.generator.file;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.thoughtworks.qdox.model.JavaClass;
|
||||
import com.thoughtworks.qdox.model.JavaMethod;
|
||||
import com.thoughtworks.qdox.model.JavaParameter;
|
||||
import com.thoughtworks.qdox.model.JavaType;
|
||||
import org.assertj.core.error.BasicErrorMessageFactory;
|
||||
import org.assertj.core.internal.Failures;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Assertion methods for {@code SourceFile} instances.
|
||||
*
|
||||
|
@ -44,87 +29,4 @@ public class SourceFileAssert extends DynamicFileAssert<SourceFileAssert, Source
|
|||
super(actual, SourceFileAssert.class);
|
||||
}
|
||||
|
||||
|
||||
public SourceFileAssert implementsInterface(@Nullable Class<?> type) {
|
||||
return implementsInterface((type != null ? type.getName() : null));
|
||||
}
|
||||
|
||||
public SourceFileAssert implementsInterface(@Nullable String name) {
|
||||
JavaClass javaClass = getJavaClass();
|
||||
assertThat(javaClass.getImplements()).as("implements").map(
|
||||
JavaType::getFullyQualifiedName).contains(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MethodAssert hasMethodNamed(String name) {
|
||||
JavaClass javaClass = getJavaClass();
|
||||
JavaMethod method = null;
|
||||
for (JavaMethod candidate : javaClass.getMethods()) {
|
||||
if (candidate.getName().equals(name)) {
|
||||
if (method != null) {
|
||||
throw Failures.instance().failure(this.info,
|
||||
new BasicErrorMessageFactory(String.format(
|
||||
"%nExpecting actual:%n %s%nto contain unique method:%n %s%n",
|
||||
this.actual.getContent(), name)));
|
||||
}
|
||||
method = candidate;
|
||||
}
|
||||
}
|
||||
if (method == null) {
|
||||
throw Failures.instance().failure(this.info,
|
||||
new BasicErrorMessageFactory(String.format(
|
||||
"%nExpecting actual:%n %s%nto contain method:%n %s%n",
|
||||
this.actual.getContent(), name)));
|
||||
}
|
||||
return new MethodAssert(method);
|
||||
}
|
||||
|
||||
public MethodAssert hasMethod(String name, Class<?>... parameters) {
|
||||
JavaClass javaClass = getJavaClass();
|
||||
JavaMethod method = null;
|
||||
for (JavaMethod candidate : javaClass.getMethods()) {
|
||||
if (candidate.getName().equals(name)
|
||||
&& hasParameters(candidate, parameters)) {
|
||||
if (method != null) {
|
||||
throw Failures.instance().failure(this.info,
|
||||
new BasicErrorMessageFactory(String.format(
|
||||
"%nExpecting actual:%n %s%nto contain unique method:%n %s%n",
|
||||
this.actual.getContent(), name)));
|
||||
}
|
||||
method = candidate;
|
||||
}
|
||||
}
|
||||
if (method == null) {
|
||||
String methodDescription = getMethodDescription(name, parameters);
|
||||
throw Failures.instance().failure(this.info,
|
||||
new BasicErrorMessageFactory(String.format(
|
||||
"%nExpecting actual:%n %s%nto contain method:%n %s%n",
|
||||
this.actual.getContent(), methodDescription)));
|
||||
}
|
||||
return new MethodAssert(method);
|
||||
}
|
||||
|
||||
private boolean hasParameters(JavaMethod method, Class<?>[] requiredParameters) {
|
||||
List<JavaParameter> parameters = method.getParameters();
|
||||
if (parameters.size() != requiredParameters.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < requiredParameters.length; i++) {
|
||||
if (!requiredParameters[i].getName().equals(
|
||||
parameters.get(i).getFullyQualifiedName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getMethodDescription(String name, Class<?>... parameters) {
|
||||
return name + "(" + Arrays.stream(parameters).map(Class::getName).collect(
|
||||
Collectors.joining(", ")) + ")";
|
||||
}
|
||||
|
||||
private JavaClass getJavaClass() {
|
||||
return this.actual.getJavaSource().getClasses().get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.regex.Pattern;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* An immutable collection of {@link SourceFile} instances.
|
||||
|
@ -155,7 +156,7 @@ public final class SourceFiles implements Iterable<SourceFile> {
|
|||
*/
|
||||
public SourceFile getSingleFromPackage(String packageName) {
|
||||
return this.files.getSingle(candidate -> Objects.equals(packageName,
|
||||
candidate.getJavaSource().getPackageName()));
|
||||
ClassUtils.getPackageName(candidate.getClassName())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -100,8 +100,7 @@ class TestCompilerTests {
|
|||
@Test
|
||||
void compileAndGetSourceFile() {
|
||||
TestCompiler.forSystem().withSources(SourceFile.of(HELLO_SPRING)).compile(
|
||||
compiled -> assertThat(compiled.getSourceFile()).hasMethodNamed(
|
||||
"get").withBodyContaining("// !!"));
|
||||
compiled -> assertThat(compiled.getSourceFile()).contains("// !!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aot.test.generator.file;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link MethodAssert}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MethodAssertTests {
|
||||
|
||||
private static final String SAMPLE = """
|
||||
package com.example;
|
||||
|
||||
public class Sample {
|
||||
|
||||
public void run() {
|
||||
System.out.println("Hello World!");
|
||||
}
|
||||
|
||||
}
|
||||
""";
|
||||
|
||||
private final SourceFile sourceFile = SourceFile.of(SAMPLE);
|
||||
|
||||
@Test
|
||||
void withBodyWhenMatches() {
|
||||
assertThat(this.sourceFile).hasMethodNamed("run").withBody("""
|
||||
System.out.println("Hello World!");""");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withBodyWhenDoesNotMatchThrowsException() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(this.sourceFile).hasMethodNamed("run").withBody("""
|
||||
System.out.println("Hello Spring!");""")).withMessageContaining(
|
||||
"to be equal to");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withBodyContainingWhenContainsAll() {
|
||||
assertThat(this.sourceFile).hasMethodNamed("run").withBodyContaining("Hello",
|
||||
"World!");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withBodyWhenDoesNotContainOneThrowsException() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(this.sourceFile).hasMethodNamed(
|
||||
"run").withBodyContaining("Hello",
|
||||
"Spring!")).withMessageContaining("to contain");
|
||||
}
|
||||
|
||||
}
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package org.springframework.aot.test.generator.file;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
@ -77,52 +75,4 @@ class SourceFileAssertTests {
|
|||
"expected", "but was");
|
||||
}
|
||||
|
||||
@Test
|
||||
void implementsInterfaceWhenImplementsInterface() {
|
||||
assertThat(this.sourceFile).implementsInterface(Runnable.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void implementsInterfaceWhenDoesNotImplementInterfaceThrowsException() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(this.sourceFile).implementsInterface(
|
||||
Callable.class)).withMessageContaining("to contain:");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasMethodNamedWhenHasName() {
|
||||
MethodAssert methodAssert = assertThat(this.sourceFile).hasMethodNamed("main");
|
||||
assertThat(methodAssert).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasMethodNameWhenDoesNotHaveMethodThrowsException() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(this.sourceFile).hasMethodNamed(
|
||||
"missing")).withMessageContaining("to contain method");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasMethodNameWhenHasMultipleMethodsWithNameThrowsException() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(this.sourceFile).hasMethodNamed(
|
||||
"run")).withMessageContaining("to contain unique method");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasMethodWhenHasMethod() {
|
||||
MethodAssert methodAssert = assertThat(this.sourceFile).hasMethod("run",
|
||||
String.class);
|
||||
assertThat(methodAssert).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasMethodWhenDoesNotHaveMethod() {
|
||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||
() -> assertThat(this.sourceFile).hasMethod("run",
|
||||
Integer.class)).withMessageContaining(
|
||||
"to contain").withMessageContaining(
|
||||
"run(java.lang.Integer");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.springframework.aot.test.generator.file;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.thoughtworks.qdox.model.JavaSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
@ -90,12 +89,6 @@ class SourceFileTests {
|
|||
assertThat(sourceFile.getContent()).isEqualTo(HELLO_WORLD);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getJavaSourceReturnsJavaSource() {
|
||||
SourceFile sourceFile = SourceFile.of(HELLO_WORLD);
|
||||
assertThat(sourceFile.getJavaSource()).isInstanceOf(JavaSource.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void assertThatReturnsAssert() {
|
||||
|
|
Loading…
Reference in New Issue