This commit is contained in:
Stephane Nicoll 2019-08-25 04:41:44 +02:00
parent c36ae847fb
commit 0b37199b3e
6 changed files with 288 additions and 130 deletions

View File

@ -24,8 +24,6 @@ import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Supplier;
import io.spring.initializr.generator.io.IndentingWriterFactory;
import io.spring.initializr.generator.io.SimpleIndentStrategy;
import io.spring.initializr.generator.project.MutableProjectDescription;
import io.spring.initializr.generator.project.ProjectDirectoryFactory;
import io.spring.initializr.generator.project.ProjectGenerationContext;
@ -72,11 +70,6 @@ public abstract class AbstractProjectGenerationTester<SELF extends AbstractProje
() -> (description) -> Files.createTempDirectory(directory, "project-"));
}
public SELF withIndentingWriterFactory() {
return withBean(IndentingWriterFactory.class,
() -> IndentingWriterFactory.create(new SimpleIndentStrategy(" ")));
}
public SELF withContextInitializer(Consumer<ProjectGenerationContext> context) {
return newInstance(this.beanDefinitions, this.contextInitializer.andThen(context), this.descriptionCustomizer);
}

View File

@ -24,6 +24,8 @@ import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import io.spring.initializr.generator.io.IndentingWriterFactory;
import io.spring.initializr.generator.io.SimpleIndentStrategy;
import io.spring.initializr.generator.project.MutableProjectDescription;
import io.spring.initializr.generator.project.ProjectAssetGenerator;
import io.spring.initializr.generator.project.ProjectDescription;
@ -33,8 +35,8 @@ import io.spring.initializr.generator.project.contributor.ProjectContributor;
/**
* A tester for project asset that does not detect available {@link ProjectContributor
* contributors}. By default, no contributor is available and can be added using a
* {@link #withConfiguration(Class[]) configuration class} or a
* contributors} and does not register any bean to the context. Contributors can be added
* using a {@link #withConfiguration(Class[]) configuration class} or a
* {@link #withContextInitializer(Consumer) customization of the project generation
* context}.
*
@ -59,6 +61,11 @@ public class ProjectAssetTester extends AbstractProjectGenerationTester<ProjectA
return new ProjectAssetTester(beanDefinitions, contextInitializer, descriptionCustomizer);
}
public ProjectAssetTester withIndentingWriterFactory() {
return withBean(IndentingWriterFactory.class,
() -> IndentingWriterFactory.create(new SimpleIndentStrategy(" ")));
}
public ProjectAssetTester withConfiguration(Class<?>... configurationClasses) {
return withContextInitializer((context) -> context.register(configurationClasses));
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 2012-2019 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 io.spring.initializr.generator.test.project;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import io.spring.initializr.generator.io.IndentingWriterFactory;
import io.spring.initializr.generator.project.MutableProjectDescription;
import io.spring.initializr.generator.project.contributor.ProjectContributor;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ProjectAssetTester}.
*
* @author Stephane Nicoll
*/
class ProjectAssetTesterTests {
@Test
void testerHasNoRegisteredIndentingWriterFactoryByDefault() {
Map<String, IndentingWriterFactory> contributors = new ProjectAssetTester().generate(
new MutableProjectDescription(), (context) -> context.getBeansOfType(IndentingWriterFactory.class));
assertThat(contributors).isEmpty();
}
@Test
void testerWithIndentingWriterFactory() {
new ProjectAssetTester().withIndentingWriterFactory().generate(new MutableProjectDescription(),
(context) -> assertThat(context.getBeansOfType(IndentingWriterFactory.class)).hasSize(1));
}
@Test
void testerWithExplicitProjectContributors(@TempDir Path directory) {
ProjectStructure project = new ProjectAssetTester().withDirectory(directory)
.withConfiguration(ContributorsConfiguration.class).generate(new MutableProjectDescription());
assertThat(project).filePaths().containsOnly("test.text", "test2.text");
}
@Configuration
static class ContributorsConfiguration {
@Bean
ProjectContributor contributor1() {
return (projectDirectory) -> Files.createFile(projectDirectory.resolve("test.text"));
}
@Bean
ProjectContributor contributor2() {
return (projectDirectory) -> Files.createFile(projectDirectory.resolve("test2.text"));
}
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright 2012-2019 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 io.spring.initializr.generator.test.project;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import io.spring.initializr.generator.io.IndentingWriterFactory;
import io.spring.initializr.generator.project.MutableProjectDescription;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.project.contributor.ProjectContributor;
import io.spring.initializr.generator.version.Version;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ProjectGeneratorTester}.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
*/
class ProjectGeneratorTesterTests {
@Test
void testerHasNoRegisteredContributorByDefault() {
Map<String, ProjectContributor> contributors = new ProjectGeneratorTester().generate(
new MutableProjectDescription(), (context) -> context.getBeansOfType(ProjectContributor.class));
assertThat(contributors).isEmpty();
}
@Test
void testerHasIndentingWriterFactoryByDefault() {
new ProjectGeneratorTester().generate(new MutableProjectDescription(),
(context) -> assertThat(context.getBeansOfType(IndentingWriterFactory.class)).hasSize(1));
}
@Test
void testerWithDescriptionCustomizer() {
Version platformVersion = Version.parse("2.1.0.RELEASE");
MutableProjectDescription description = new MutableProjectDescription();
description.setPackageName("com.example.test");
ProjectDescription customizedDescription = new ProjectGeneratorTester().withDescriptionCustomizer((desc) -> {
desc.setPlatformVersion(Version.parse("2.1.0.RELEASE"));
desc.setPackageName("com.example.another");
}).generate(description, (context) -> context.getBean(ProjectDescription.class));
assertThat(customizedDescription.getPlatformVersion()).isEqualTo(platformVersion);
assertThat(customizedDescription.getPackageName()).isEqualTo("com.example.another");
}
@Test
void testerWithExplicitProjectContributors(@TempDir Path directory) {
ProjectGeneratorTester tester = new ProjectGeneratorTester().withDirectory(directory)
.withContextInitializer((context) -> {
context.registerBean("contributor1", ProjectContributor.class,
() -> (projectDirectory) -> Files.createFile(projectDirectory.resolve("test.text")));
context.registerBean("contributor2", ProjectContributor.class, () -> (projectDirectory) -> {
Path subDir = projectDirectory.resolve("src/main/test");
Files.createDirectories(subDir);
Files.createFile(subDir.resolve("Test.src"));
});
});
ProjectStructure project = tester.generate(new MutableProjectDescription());
assertThat(project).filePaths().containsOnly("test.text", "src/main/test/Test.src");
}
}

View File

@ -1,121 +0,0 @@
/*
* Copyright 2012-2019 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 io.spring.initializr.generator.test.project;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Consumer;
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
import io.spring.initializr.generator.project.MutableProjectDescription;
import io.spring.initializr.generator.project.ProjectDescription;
import io.spring.initializr.generator.project.ProjectDescriptionCustomizer;
import io.spring.initializr.generator.project.ProjectGenerator;
import io.spring.initializr.generator.project.contributor.ProjectContributor;
import io.spring.initializr.generator.version.Version;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ProjectGenerator}.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
*/
class ProjectGeneratorTests {
private final ProjectGeneratorTester projectTester = new ProjectGeneratorTester()
.withDescriptionCustomizer((description) -> {
description.setBuildSystem(new MavenBuildSystem());
description.setPlatformVersion(Version.parse("2.1.0.RELEASE"));
});
@Test
void generateInvokedProcessor() {
MutableProjectDescription description = new MutableProjectDescription();
description.setBuildSystem(new MavenBuildSystem());
Version platformVersion = Version.parse("2.1.0.RELEASE");
description.setPackageName("com.example.test");
ProjectDescription customizedDescription = this.projectTester.generate(description,
(projectGenerationContext) -> projectGenerationContext.getBean(ProjectDescription.class));
assertThat(customizedDescription.getPlatformVersion()).isEqualTo(platformVersion);
assertThat(customizedDescription.getPackageName()).isEqualTo("com.example.test");
}
@Test
void generateInvokesCustomizers() {
ProjectGeneratorTester tester = this.projectTester.withContextInitializer((context) -> {
context.registerBean("customizer1", TestProjectDescriptionCustomizer.class,
() -> new TestProjectDescriptionCustomizer(5, (description) -> description.setName("Test")));
context.registerBean("customizer2", TestProjectDescriptionCustomizer.class,
() -> new TestProjectDescriptionCustomizer(3, (description) -> {
description.setName("First");
description.setGroupId("com.acme");
}));
});
MutableProjectDescription description = new MutableProjectDescription();
description.setGroupId("com.example.demo");
description.setName("Original");
ProjectDescription customizedDescription = tester.generate(description,
(projectGenerationContext) -> projectGenerationContext.getBean(ProjectDescription.class));
assertThat(customizedDescription.getGroupId()).isEqualTo("com.acme");
assertThat(customizedDescription.getName()).isEqualTo("Test");
}
@Test
void generateInvokeProjectContributors(@TempDir Path directory) {
ProjectGeneratorTester tester = this.projectTester.withDirectory(directory)
.withContextInitializer((context) -> {
context.registerBean("contributor1", ProjectContributor.class,
() -> (projectDirectory) -> Files.createFile(projectDirectory.resolve("test.text")));
context.registerBean("contributor2", ProjectContributor.class, () -> (projectDirectory) -> {
Path subDir = projectDirectory.resolve("src/main/test");
Files.createDirectories(subDir);
Files.createFile(subDir.resolve("Test.src"));
});
});
ProjectStructure project = tester.generate(new MutableProjectDescription());
assertThat(project).filePaths().containsOnly("test.text", "src/main/test/Test.src");
}
private static class TestProjectDescriptionCustomizer implements ProjectDescriptionCustomizer {
private final Integer order;
private final Consumer<MutableProjectDescription> projectDescription;
TestProjectDescriptionCustomizer(Integer order, Consumer<MutableProjectDescription> projectDescription) {
this.order = order;
this.projectDescription = projectDescription;
}
@Override
public void customize(MutableProjectDescription description) {
this.projectDescription.accept(description);
}
@Override
public int getOrder() {
return this.order;
}
}
}

View File

@ -0,0 +1,120 @@
/*
* Copyright 2012-2019 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 io.spring.initializr.generator.project;
import java.io.IOException;
import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
import org.mockito.InOrder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Tests for {@link ProjectGenerator}.
*
* @author Stephane Nicoll
*/
public class ProjectGeneratorTests {
@Test
void generateRegisterProjectDescription() {
Consumer<ProjectGenerationContext> contextInitializer = mockContextInitializr();
ProjectGenerator generator = new ProjectGenerator(contextInitializer);
MutableProjectDescription description = new MutableProjectDescription();
ProjectDescription beanDescription = generator.generate(description, (context) -> {
assertThat(context.getBeansOfType(ProjectDescription.class)).hasSize(1);
return context.getBean(ProjectDescription.class);
});
assertThat(description).isSameAs(beanDescription);
}
@Test
void generateInvokeContextInitializerBeforeContextIsRefreshed() {
ProjectGenerator generator = new ProjectGenerator((context) -> {
assertThat(context.isActive()).isFalse();
context.registerBean(String.class, () -> "Test");
});
String customBean = generator.generate(new MutableProjectDescription(), (context) -> {
assertThat(context.getBeansOfType(String.class)).hasSize(1);
return context.getBean(String.class);
});
assertThat(customBean).isEqualTo("Test");
}
@Test
void generateInvokeProjectDescriptionCustomizer() {
ProjectGenerator generator = new ProjectGenerator((context) -> context.registerBean(
ProjectDescriptionCustomizer.class, () -> (description) -> description.setGroupId("com.acme")));
MutableProjectDescription description = new MutableProjectDescription();
description.setGroupId("com.example");
ProjectDescription descriptionFromContext = generator.generate(description,
(context) -> context.getBean(ProjectDescription.class));
assertThat(descriptionFromContext.getGroupId()).isEqualTo("com.acme");
}
@Test
void generateInvokeProjectDescriptionCustomizersInOrder() {
ProjectDescriptionCustomizer firstCustomizer = mock(ProjectDescriptionCustomizer.class);
given(firstCustomizer.getOrder()).willReturn(5);
ProjectDescriptionCustomizer secondCustomizer = mock(ProjectDescriptionCustomizer.class);
given(secondCustomizer.getOrder()).willReturn(10);
ProjectGenerator generator = new ProjectGenerator((context) -> {
context.registerBean("first", ProjectDescriptionCustomizer.class, () -> secondCustomizer);
context.registerBean("second", ProjectDescriptionCustomizer.class, () -> firstCustomizer);
});
MutableProjectDescription description = new MutableProjectDescription();
generator.generate(description, (context) -> null);
InOrder inOrder = inOrder(firstCustomizer, secondCustomizer);
inOrder.verify(firstCustomizer).customize(description);
inOrder.verify(secondCustomizer).customize(description);
}
@Test
void generateIgnoreProjectDescriptionCustomizerOnNonMutableDescription() {
ProjectDescriptionCustomizer customizer = mock(ProjectDescriptionCustomizer.class);
ProjectGenerator generator = new ProjectGenerator(
(context) -> context.registerBean(ProjectDescriptionCustomizer.class, () -> customizer));
ProjectDescription description = mock(ProjectDescription.class);
ProjectDescription descriptionFromContext = generator.generate(description,
(context) -> context.getBean(ProjectDescription.class));
assertThat(descriptionFromContext).isSameAs(description);
verifyZeroInteractions(customizer);
}
@Test
void generateWithIoExceptionThrowsProjectGenerationException() throws IOException {
ProjectGenerator generator = new ProjectGenerator(mockContextInitializr());
ProjectAssetGenerator<?> assetGenerator = mock(ProjectAssetGenerator.class);
IOException exception = new IOException("test");
given(assetGenerator.generate(any())).willThrow(exception);
assertThatThrownBy(() -> generator.generate(new MutableProjectDescription(), assetGenerator))
.isInstanceOf(ProjectGenerationException.class).hasCause(exception);
}
@SuppressWarnings("unchecked")
private Consumer<ProjectGenerationContext> mockContextInitializr() {
return mock(Consumer.class);
}
}