diff --git a/initializr-docs/src/main/asciidoc/configuration-guide.adoc b/initializr-docs/src/main/asciidoc/configuration-guide.adoc index 5fb3d235..57b46da5 100644 --- a/initializr-docs/src/main/asciidoc/configuration-guide.adoc +++ b/initializr-docs/src/main/asciidoc/configuration-guide.adoc @@ -129,7 +129,9 @@ include::{code-examples}/doc/generator/project/SampleContributor.java[tag=code] ==== Project Generation Lifecycle When a `ProjectGenerator` is instructed to generate a project, the specified `ProjectDescription` can be customized using available `ProjectDescriptionCustomizer` -beans and can be ordered using Spring's `Ordered` interface. +beans and can be ordered using Spring's `Ordered` interface. A `ProjectDescriptionDiff` +bean is available for extensions that wish to know if an attribute of the original +`ProjectDescription` was modified. Once the description has been customized based on the available ``ProjectDescriptionCustomizer``s, the generator uses a `ProjectAssetGenerator` to diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/project/diff/DefaultProjectDescriptionDiffFactory.java b/initializr-generator/src/main/java/io/spring/initializr/generator/project/DefaultProjectDescriptionDiffFactory.java similarity index 78% rename from initializr-generator/src/main/java/io/spring/initializr/generator/project/diff/DefaultProjectDescriptionDiffFactory.java rename to initializr-generator/src/main/java/io/spring/initializr/generator/project/DefaultProjectDescriptionDiffFactory.java index 717ce260..8a304b8a 100644 --- a/initializr-generator/src/main/java/io/spring/initializr/generator/project/diff/DefaultProjectDescriptionDiffFactory.java +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/project/DefaultProjectDescriptionDiffFactory.java @@ -14,9 +14,7 @@ * limitations under the License. */ -package io.spring.initializr.generator.project.diff; - -import io.spring.initializr.generator.project.ProjectDescription; +package io.spring.initializr.generator.project; /** * A default {@link ProjectDescriptionDiffFactory} implementation that creates default @@ -24,10 +22,10 @@ import io.spring.initializr.generator.project.ProjectDescription; * * @author Chris Bono */ -public class DefaultProjectDescriptionDiffFactory implements ProjectDescriptionDiffFactory { +public class DefaultProjectDescriptionDiffFactory implements ProjectDescriptionDiffFactory { @Override - public ProjectDescriptionDiff create(final ProjectDescription description) { + public ProjectDescriptionDiff create(ProjectDescription description) { return new ProjectDescriptionDiff(description); } diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/project/MutableProjectDescription.java b/initializr-generator/src/main/java/io/spring/initializr/generator/project/MutableProjectDescription.java index dc435e70..87b4399c 100644 --- a/initializr-generator/src/main/java/io/spring/initializr/generator/project/MutableProjectDescription.java +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/project/MutableProjectDescription.java @@ -62,24 +62,26 @@ public class MutableProjectDescription implements ProjectDescription { private String baseDirectory; public MutableProjectDescription() { - super(); } - protected MutableProjectDescription(final MutableProjectDescription source) { - super(); - setPlatformVersion(source.getPlatformVersion()); - setBuildSystem(source.getBuildSystem()); - setPackaging(source.getPackaging()); - setLanguage(source.getLanguage()); - source.getRequestedDependencies().forEach(this::addDependency); - setGroupId(source.getGroupId()); - setArtifactId(source.getArtifactId()); - setVersion(source.getVersion()); - setName(source.getName()); - setDescription(source.getDescription()); - setApplicationName(source.getApplicationName()); - setPackageName(source.getPackageName()); - setBaseDirectory(source.getBaseDirectory()); + /** + * Create a new instance with the state of the specified {@code source}. + * @param source the source description to initialize this instance with + */ + protected MutableProjectDescription(MutableProjectDescription source) { + this.platformVersion = source.getPlatformVersion(); + this.buildSystem = source.getBuildSystem(); + this.packaging = source.getPackaging(); + this.language = source.getLanguage(); + this.requestedDependencies.putAll(source.getRequestedDependencies()); + this.groupId = source.getGroupId(); + this.artifactId = source.getArtifactId(); + this.version = source.getVersion(); + this.name = source.getName(); + this.description = source.getDescription(); + this.applicationName = source.getApplicationName(); + this.packageName = source.getPackageName(); + this.baseDirectory = source.getBaseDirectory(); } @Override diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescription.java b/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescription.java index 28dcc5d7..be89723e 100644 --- a/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescription.java +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescription.java @@ -32,6 +32,15 @@ import io.spring.initializr.generator.version.Version; */ public interface ProjectDescription { + /** + * Create a full copy of this description so that any additional changes made on this + * instance are not reflected on the returned copy. + * @return a clone of this instance + */ + default ProjectDescription createCopy() { + throw new UnsupportedOperationException(); + } + /** * Return a immutable mapping of requested {@link Dependency dependencies}. * @return the requested dependencies @@ -110,15 +119,4 @@ public interface ProjectDescription { */ String getBaseDirectory(); - /** - * ProjectDescription implementations should implement this to create a copy of - * themselves. However, the default implementation throws - * UnsupportedOperationException. - * @return never - * @throws UnsupportedOperationException always - */ - default ProjectDescription createCopy() { - throw new UnsupportedOperationException(); - } - } diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/project/diff/ProjectDescriptionDiff.java b/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescriptionDiff.java similarity index 66% rename from initializr-generator/src/main/java/io/spring/initializr/generator/project/diff/ProjectDescriptionDiff.java rename to initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescriptionDiff.java index 7ab832e5..712e9b28 100644 --- a/initializr-generator/src/main/java/io/spring/initializr/generator/project/diff/ProjectDescriptionDiff.java +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescriptionDiff.java @@ -14,42 +14,39 @@ * limitations under the License. */ -package io.spring.initializr.generator.project.diff; +package io.spring.initializr.generator.project; -import java.lang.reflect.Field; import java.util.Objects; import java.util.function.BiConsumer; import io.spring.initializr.generator.buildsystem.BuildSystem; import io.spring.initializr.generator.language.Language; import io.spring.initializr.generator.packaging.Packaging; -import io.spring.initializr.generator.project.ProjectDescription; import io.spring.initializr.generator.version.Version; -import org.springframework.util.ReflectionUtils; - /** * Provides a convenient API for determining if certain fields on a * {@link ProjectDescription} were modified. * * @author Chris Bono + * @author Stephane Nicoll */ public class ProjectDescriptionDiff { private final ProjectDescription original; /** - * Construct a {@link ProjectDescriptionDiff} that creates and uses a copy of the - * specified description as its source. + * Create a {@link ProjectDescriptionDiff} that uses a copy of the specified + * description as its source. * @param original the description to copy as the source */ - public ProjectDescriptionDiff(final ProjectDescription original) { + public ProjectDescriptionDiff(ProjectDescription original) { this.original = original.createCopy(); } /** - * Gets the copy of the originally specified description that is being tracked. - * @return copy of the originally specified description + * Return the original {@link ProjectDescription} that is being tracked. + * @return the original description */ public ProjectDescription getOriginal() { return this.original; @@ -61,8 +58,7 @@ public class ProjectDescriptionDiff { * @param current the project description to test against * @param consumer to call if the property has changed */ - public void ifPlatformVersionChanged(final ProjectDescription current, - final BiConsumer consumer) { + public void ifPlatformVersionChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getPlatformVersion(), current.getPlatformVersion())) { consumer.accept(this.original.getPlatformVersion(), current.getPlatformVersion()); } @@ -74,8 +70,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifBuildSystemChanged(final ProjectDescription current, - final BiConsumer consumer) { + public void ifBuildSystemChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getBuildSystem(), current.getBuildSystem())) { consumer.accept(this.original.getBuildSystem(), current.getBuildSystem()); } @@ -87,7 +82,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifPackagingChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifPackagingChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getPackaging(), current.getPackaging())) { consumer.accept(this.original.getPackaging(), current.getPackaging()); } @@ -99,7 +94,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifLanguageChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifLanguageChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getLanguage(), current.getLanguage())) { consumer.accept(this.original.getLanguage(), current.getLanguage()); } @@ -111,7 +106,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifGroupIdChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifGroupIdChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getGroupId(), current.getGroupId())) { consumer.accept(this.original.getGroupId(), current.getGroupId()); } @@ -123,7 +118,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifArtifactIdChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifArtifactIdChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getArtifactId(), current.getArtifactId())) { consumer.accept(this.original.getArtifactId(), current.getArtifactId()); } @@ -135,7 +130,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifVersionChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifVersionChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getVersion(), current.getVersion())) { consumer.accept(this.original.getVersion(), current.getVersion()); } @@ -147,7 +142,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifNameChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifNameChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getName(), current.getName())) { consumer.accept(this.original.getName(), current.getName()); } @@ -159,7 +154,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifDescriptionChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifDescriptionChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getDescription(), current.getDescription())) { consumer.accept(this.original.getDescription(), current.getDescription()); } @@ -171,7 +166,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifApplicationNameChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifApplicationNameChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getApplicationName(), current.getApplicationName())) { consumer.accept(this.original.getApplicationName(), current.getApplicationName()); } @@ -183,7 +178,7 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifPackageNameChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifPackageNameChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getPackageName(), current.getPackageName())) { consumer.accept(this.original.getPackageName(), current.getPackageName()); } @@ -195,39 +190,10 @@ public class ProjectDescriptionDiff { * @param current the description to test against * @param consumer to call if the property has changed */ - public void ifBaseDirectoryChanged(final ProjectDescription current, final BiConsumer consumer) { + public void ifBaseDirectoryChanged(ProjectDescription current, BiConsumer consumer) { if (!Objects.equals(this.original.getBaseDirectory(), current.getBaseDirectory())) { consumer.accept(this.original.getBaseDirectory(), current.getBaseDirectory()); } } - /** - * Calls the specified consumer if the value of the specified property is different on - * the original source project description than the specified project description. - * @param current the description to test against - * @param property the name of the property to check - * @param propertyClass the class of the property to check - * @param consumer to call if the property has changed - * @param type of the property - */ - public void ifPropertyChanged(final ProjectDescription current, final String property, - final Class propertyClass, final BiConsumer consumer) { - final V originalValue = getPropertyValueReflectively(this.original, property); - final V currentValue = getPropertyValueReflectively(current, property); - if (!Objects.equals(originalValue, currentValue)) { - consumer.accept(originalValue, currentValue); - } - } - - private V getPropertyValueReflectively(final ProjectDescription description, final String property) { - final Class descriptionClass = description.getClass(); - final Field field = ReflectionUtils.findField(descriptionClass, property); - if (field == null) { - throw new IllegalArgumentException( - String.format("No property named '%s' in '%s'.", property, descriptionClass.getSimpleName())); - } - ReflectionUtils.makeAccessible(field); - return (V) ReflectionUtils.getField(field, description); - } - } diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/project/diff/ProjectDescriptionDiffFactory.java b/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescriptionDiffFactory.java similarity index 66% rename from initializr-generator/src/main/java/io/spring/initializr/generator/project/diff/ProjectDescriptionDiffFactory.java rename to initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescriptionDiffFactory.java index eda62aa9..d1fecc6f 100644 --- a/initializr-generator/src/main/java/io/spring/initializr/generator/project/diff/ProjectDescriptionDiffFactory.java +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectDescriptionDiffFactory.java @@ -14,25 +14,23 @@ * limitations under the License. */ -package io.spring.initializr.generator.project.diff; - -import io.spring.initializr.generator.project.ProjectDescription; +package io.spring.initializr.generator.project; /** - * A factory for {@link ProjectDescriptionDiff} objects. + * A factory for {@link ProjectDescriptionDiff}. * - * @param the type of {@link ProjectDescription} * @author Chris Bono */ -public interface ProjectDescriptionDiffFactory { +public interface ProjectDescriptionDiffFactory { /** - * Construct a diff for the specified {@link ProjectDescription}. - *

+ * Create a {@link ProjectDescriptionDiff} for the specified + * {@link ProjectDescription}. Any change on the specified {@code description} is + * tracked by the returned instance. * @param description the project description to use as the source of the diff * @return a diff instance using the current state of the specified description as its * source */ - ProjectDescriptionDiff create(T description); + ProjectDescriptionDiff create(ProjectDescription description); } diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectGenerator.java b/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectGenerator.java index efaa8c83..c4bce087 100644 --- a/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectGenerator.java +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/project/ProjectGenerator.java @@ -21,10 +21,6 @@ import java.util.List; import java.util.function.Consumer; import java.util.function.Supplier; -import io.spring.initializr.generator.project.diff.DefaultProjectDescriptionDiffFactory; -import io.spring.initializr.generator.project.diff.ProjectDescriptionDiff; -import io.spring.initializr.generator.project.diff.ProjectDescriptionDiffFactory; - import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.ImportSelector; @@ -123,20 +119,13 @@ public class ProjectGenerator { private Supplier resolve(ProjectDescription description, ProjectGenerationContext context) { return () -> { - if (description instanceof MutableProjectDescription) { - - final MutableProjectDescription mutableProjectDesc = (MutableProjectDescription) description; - - // Find the diff factory and use it to create and register a diff bean - final ProjectDescriptionDiffFactory diffFactory = context - .getBeanProvider(ProjectDescriptionDiffFactory.class) - .getIfAvailable(() -> new DefaultProjectDescriptionDiffFactory()); - final ProjectDescriptionDiff diff = diffFactory.create(mutableProjectDesc); - context.registerBean(ProjectDescriptionDiff.class, () -> diff); - + MutableProjectDescription mutableDescription = (MutableProjectDescription) description; + ProjectDescriptionDiffFactory diffFactory = context.getBeanProvider(ProjectDescriptionDiffFactory.class) + .getIfAvailable(DefaultProjectDescriptionDiffFactory::new); + context.registerBean(ProjectDescriptionDiff.class, () -> diffFactory.create(mutableDescription)); context.getBeanProvider(ProjectDescriptionCustomizer.class).orderedStream() - .forEach((customizer) -> customizer.customize(mutableProjectDesc)); + .forEach((customizer) -> customizer.customize(mutableDescription)); } return description; }; diff --git a/initializr-generator/src/test/java/io/spring/initializr/generator/project/ProjectDescriptionDiffTests.java b/initializr-generator/src/test/java/io/spring/initializr/generator/project/ProjectDescriptionDiffTests.java new file mode 100644 index 00000000..27537691 --- /dev/null +++ b/initializr-generator/src/test/java/io/spring/initializr/generator/project/ProjectDescriptionDiffTests.java @@ -0,0 +1,226 @@ +/* + * 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.util.function.BiConsumer; +import java.util.function.Consumer; + +import io.spring.initializr.generator.buildsystem.BuildSystem; +import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystem; +import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem; +import io.spring.initializr.generator.language.Language; +import io.spring.initializr.generator.language.java.JavaLanguage; +import io.spring.initializr.generator.packaging.Packaging; +import io.spring.initializr.generator.packaging.jar.JarPackaging; +import io.spring.initializr.generator.version.Version; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +/** + * Tests for {@link ProjectDescriptionDiff}. + * + * @author Chris Bono + * @author Stephane Nicoll + */ +class ProjectDescriptionDiffTests { + + @Test + void projectDescriptionDiffCopySource() { + ProjectDescription original = createFullProjectDescription(); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(original); + assertThat(diff.getOriginal()).usingRecursiveComparison().isEqualTo(original); + assertThat(diff.getOriginal()).isNotSameAs(original); + } + + @Test + void projectDescriptionDiffWithUnmodifiedDescriptionDoesNotInvokeConsumer() { + ProjectDescription description = createFullProjectDescription(); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + diff.ifPlatformVersionChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifBuildSystemChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifPackagingChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifLanguageChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifGroupIdChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifArtifactIdChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifVersionChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifNameChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifDescriptionChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifApplicationNameChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifPackageNameChanged(description, (original, actual) -> fail("Values should not have changed")); + diff.ifBaseDirectoryChanged(description, (original, actual) -> fail("Values should not have changed")); + } + + @Test + void projectDescriptionDiffWithModifiedPlatformVersionInvokesConsumer() { + Version original = Version.parse("2.1.0.RELEASE"); + Version actual = Version.parse("2.2.0.RELEASE"); + MutableProjectDescription description = new MutableProjectDescription(); + description.setPlatformVersion(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setPlatformVersion(actual); + validateConsumer(original, actual, (consumer) -> diff.ifPlatformVersionChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedBuildSystemInvokesConsumer() { + BuildSystem original = BuildSystem.forId(MavenBuildSystem.ID); + BuildSystem actual = BuildSystem.forId(GradleBuildSystem.ID); + MutableProjectDescription description = new MutableProjectDescription(); + description.setBuildSystem(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setBuildSystem(actual); + validateConsumer(original, actual, (consumer) -> diff.ifBuildSystemChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedPackagingInvokesConsumer() { + Packaging original = Packaging.forId(JarPackaging.ID); + Packaging actual = Packaging.forId("war"); + MutableProjectDescription description = new MutableProjectDescription(); + description.setPackaging(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setPackaging(actual); + validateConsumer(original, actual, (consumer) -> diff.ifPackagingChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedLanguageInvokesConsumer() { + Language original = Language.forId(JavaLanguage.ID, "11"); + Language actual = Language.forId(JavaLanguage.ID, "13"); + MutableProjectDescription description = new MutableProjectDescription(); + description.setLanguage(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setLanguage(actual); + validateConsumer(original, actual, (consumer) -> diff.ifLanguageChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedGroupIdInvokesConsumer() { + String original = "com.example"; + String actual = "com.example.app"; + MutableProjectDescription description = new MutableProjectDescription(); + description.setGroupId(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setGroupId(actual); + validateConsumer(original, actual, (consumer) -> diff.ifGroupIdChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedArtifactIdInvokesConsumer() { + String original = "demo"; + String actual = "app"; + MutableProjectDescription description = new MutableProjectDescription(); + description.setArtifactId(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setArtifactId(actual); + validateConsumer(original, actual, (consumer) -> diff.ifArtifactIdChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedVersionInvokesConsumer() { + String original = "1.0.0"; + String actual = "1.1.0"; + MutableProjectDescription description = new MutableProjectDescription(); + description.setVersion(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setVersion(actual); + validateConsumer(original, actual, (consumer) -> diff.ifVersionChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedNameInvokesConsumer() { + String original = "demo"; + String actual = "application"; + MutableProjectDescription description = new MutableProjectDescription(); + description.setName(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setName(actual); + validateConsumer(original, actual, (consumer) -> diff.ifNameChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedDescriptionInvokesConsumer() { + String original = "Demo Application"; + String actual = "Application"; + MutableProjectDescription description = new MutableProjectDescription(); + description.setDescription(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setDescription(actual); + validateConsumer(original, actual, (consumer) -> diff.ifDescriptionChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedApplicationNameInvokesConsumer() { + String original = "DemoApplication"; + String actual = "Application"; + MutableProjectDescription description = new MutableProjectDescription(); + description.setApplicationName(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setApplicationName(actual); + validateConsumer(original, actual, (consumer) -> diff.ifApplicationNameChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedPackageNameInvokesConsumer() { + String original = "com.example"; + String actual = "com.example.app"; + MutableProjectDescription description = new MutableProjectDescription(); + description.setPackageName(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setPackageName(actual); + validateConsumer(original, actual, (consumer) -> diff.ifPackageNameChanged(description, consumer)); + } + + @Test + void projectDescriptionDiffWithModifiedBaseDirectoryInvokesConsumer() { + String original = null; + String actual = "demo-app"; + MutableProjectDescription description = new MutableProjectDescription(); + description.setBaseDirectory(original); + ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); + description.setBaseDirectory(actual); + validateConsumer(original, actual, (consumer) -> diff.ifBaseDirectoryChanged(description, consumer)); + } + + private MutableProjectDescription createFullProjectDescription() { + MutableProjectDescription description = new MutableProjectDescription(); + description.setBuildSystem(BuildSystem.forId(MavenBuildSystem.ID)); + description.setLanguage(Language.forId(JavaLanguage.ID, "11")); + description.setPlatformVersion(Version.parse("2.2.0.RELEASE")); + description.setGroupId("com.example"); + description.setArtifactId("demo"); + description.setName("demo"); + description.setVersion("0.0.8"); + description.setApplicationName("DemoApplication"); + description.setPackageName("com.example.demo"); + description.setPackaging(Packaging.forId("jar")); + description.setBaseDirectory("."); + return description; + } + + @SuppressWarnings("unchecked") + private void validateConsumer(T original, T actual, Consumer> test) { + BiConsumer consumer = mock(BiConsumer.class); + test.accept(consumer); + verify(consumer).accept(original, actual); + } + +} diff --git a/initializr-generator/src/test/java/io/spring/initializr/generator/project/ProjectGeneratorTests.java b/initializr-generator/src/test/java/io/spring/initializr/generator/project/ProjectGeneratorTests.java index 4d837230..d2cec6ec 100644 --- a/initializr-generator/src/test/java/io/spring/initializr/generator/project/ProjectGeneratorTests.java +++ b/initializr-generator/src/test/java/io/spring/initializr/generator/project/ProjectGeneratorTests.java @@ -20,9 +20,6 @@ import java.io.IOException; import java.util.Map; import java.util.function.Consumer; -import io.spring.initializr.generator.project.diff.DefaultProjectDescriptionDiffFactory; -import io.spring.initializr.generator.project.diff.ProjectDescriptionDiff; -import io.spring.initializr.generator.project.diff.ProjectDescriptionDiffFactory; import org.junit.jupiter.api.Test; import org.mockito.InOrder; @@ -35,6 +32,7 @@ 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.verify; import static org.mockito.Mockito.verifyNoInteractions; /** @@ -57,14 +55,30 @@ public class ProjectGeneratorTests { } @Test - void generateRegisterProjectDescriptionDiff() { - ProjectGenerator generator = new ProjectGenerator((context) -> context - .registerBean(ProjectDescriptionDiffFactory.class, () -> new DefaultProjectDescriptionDiffFactory())); + void generateProvideDefaultProjectDescriptionDiff() { + ProjectGenerator generator = new ProjectGenerator(mockContextInitializr()); MutableProjectDescription description = new MutableProjectDescription(); - generator.generate(description, (context) -> { + ProjectDescriptionDiff diff = generator.generate(description, (context) -> { assertThat(context.getBeansOfType(ProjectDescriptionDiff.class)).hasSize(1); return context.getBean(ProjectDescriptionDiff.class); }); + assertThat(diff).isInstanceOf(ProjectDescriptionDiff.class); + } + + @Test + void generateUseAvailableProjectDescriptionDiffFactory() { + ProjectDescriptionDiff diff = mock(ProjectDescriptionDiff.class); + ProjectDescriptionDiffFactory diffFactory = mock(ProjectDescriptionDiffFactory.class); + MutableProjectDescription description = new MutableProjectDescription(); + given(diffFactory.create(description)).willReturn(diff); + ProjectGenerator generator = new ProjectGenerator( + (context) -> context.registerBean(ProjectDescriptionDiffFactory.class, () -> diffFactory)); + ProjectDescriptionDiff actualDiff = generator.generate(description, (context) -> { + assertThat(context.getBeansOfType(ProjectDescriptionDiff.class)).hasSize(1); + return context.getBean(ProjectDescriptionDiff.class); + }); + assertThat(actualDiff).isSameAs(diff); + verify(diffFactory).create(description); } @Test diff --git a/initializr-generator/src/test/java/io/spring/initializr/generator/project/diff/ProjectDescriptionDiffTest.java b/initializr-generator/src/test/java/io/spring/initializr/generator/project/diff/ProjectDescriptionDiffTest.java deleted file mode 100644 index c611117c..00000000 --- a/initializr-generator/src/test/java/io/spring/initializr/generator/project/diff/ProjectDescriptionDiffTest.java +++ /dev/null @@ -1,283 +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.project.diff; - -import java.util.function.BiConsumer; - -import io.spring.initializr.generator.buildsystem.BuildSystem; -import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystem; -import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem; -import io.spring.initializr.generator.language.Language; -import io.spring.initializr.generator.language.java.JavaLanguage; -import io.spring.initializr.generator.packaging.Packaging; -import io.spring.initializr.generator.project.MutableProjectDescription; -import io.spring.initializr.generator.project.ProjectDescription; -import io.spring.initializr.generator.version.Version; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -class ProjectDescriptionDiffTest { - - @Test - void originalIsCopied() { - ProjectDescription original = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(original); - assertThat(diff.getOriginal()).usingRecursiveComparison().isEqualTo(original); - assertThat(diff.getOriginal()).isNotSameAs(original); - } - - @Test - void noChanges() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - BiConsumer failIfCalled = (v1, v2) -> fail("Values should not have changed"); - diff.ifPlatformVersionChanged(description, failIfCalled); - diff.ifBuildSystemChanged(description, failIfCalled); - diff.ifPackagingChanged(description, failIfCalled); - diff.ifLanguageChanged(description, failIfCalled); - diff.ifGroupIdChanged(description, failIfCalled); - diff.ifArtifactIdChanged(description, failIfCalled); - diff.ifVersionChanged(description, failIfCalled); - diff.ifNameChanged(description, failIfCalled); - diff.ifDescriptionChanged(description, failIfCalled); - diff.ifApplicationNameChanged(description, failIfCalled); - diff.ifPackageNameChanged(description, failIfCalled); - diff.ifBaseDirectoryChanged(description, failIfCalled); - diff.ifPropertyChanged(description, "name", String.class, failIfCalled); - } - - @Test - void platformVersionChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - Version original = description.getPlatformVersion(); - description.setPlatformVersion(Version.parse("2.0.0.RELEASE")); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getPlatformVersion()); - }); - diff.ifPlatformVersionChanged(description, changeHandler); - diff.ifPropertyChanged(description, "platformVersion", Version.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void buildSystemChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - BuildSystem original = description.getBuildSystem(); - description.setBuildSystem(BuildSystem.forId(GradleBuildSystem.ID)); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getBuildSystem()); - }); - diff.ifBuildSystemChanged(description, changeHandler); - diff.ifPropertyChanged(description, "buildSystem", BuildSystem.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void packagingChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - Packaging original = description.getPackaging(); - description.setPackaging(Packaging.forId("war")); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getPackaging()); - }); - diff.ifPackagingChanged(description, changeHandler); - diff.ifPropertyChanged(description, "packaging", Packaging.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void languageChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - Language original = description.getLanguage(); - description.setLanguage(Language.forId(JavaLanguage.ID, "13")); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getLanguage()); - }); - diff.ifLanguageChanged(description, changeHandler); - diff.ifPropertyChanged(description, "language", String.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void groupIdChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - String original = description.getGroupId(); - description.setGroupId("group5150"); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getGroupId()); - }); - diff.ifGroupIdChanged(description, changeHandler); - diff.ifPropertyChanged(description, "groupId", String.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void artifactIdChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - String original = description.getArtifactId(); - description.setArtifactId("artifact5150"); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getArtifactId()); - }); - diff.ifArtifactIdChanged(description, changeHandler); - diff.ifPropertyChanged(description, "artifactId", String.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void versionChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - String original = description.getVersion(); - description.setVersion("version5150"); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getVersion()); - }); - diff.ifVersionChanged(description, changeHandler); - diff.ifPropertyChanged(description, "version", String.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void nameChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - String original = description.getName(); - description.setName("name5150"); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getName()); - }); - diff.ifNameChanged(description, changeHandler); - diff.ifPropertyChanged(description, "name", String.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void descriptionChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - String original = description.getDescription(); - description.setDescription("desc5150"); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getDescription()); - }); - diff.ifDescriptionChanged(description, changeHandler); - diff.ifPropertyChanged(description, "description", String.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void applicationNameChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - String original = description.getApplicationName(); - description.setApplicationName("appname5150"); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getApplicationName()); - }); - diff.ifApplicationNameChanged(description, changeHandler); - diff.ifPropertyChanged(description, "applicationName", String.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void packageNameChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - String original = description.getPackageName(); - description.setPackageName("pkg5150"); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getPackageName()); - }); - diff.ifPackageNameChanged(description, changeHandler); - diff.ifPropertyChanged(description, "packageName", String.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - @Test - void baseDirectoryChanged() { - MutableProjectDescription description = createProjectDescription(); - ProjectDescriptionDiff diff = new ProjectDescriptionDiff(description); - String original = description.getBaseDirectory(); - description.setBaseDirectory("baseDir5150"); - CallTrackingBiConsumer changeHandler = new CallTrackingBiConsumer<>((prev, curr) -> { - assertThat(prev).isEqualTo(original); - assertThat(curr).isEqualTo(description.getBaseDirectory()); - }); - diff.ifBaseDirectoryChanged(description, changeHandler); - diff.ifPropertyChanged(description, "baseDirectory", String.class, changeHandler); - assertThat(changeHandler.timesCalled()).isEqualTo(2); - } - - private MutableProjectDescription createProjectDescription() { - MutableProjectDescription description = new MutableProjectDescription(); - description.setBuildSystem(BuildSystem.forId(MavenBuildSystem.ID)); - description.setLanguage(Language.forId(JavaLanguage.ID, "11")); - description.setPlatformVersion(Version.parse("2.2.0.RELEASE")); - description.setGroupId("com.example"); - description.setArtifactId("demo"); - description.setName("demo"); - description.setVersion("0.0.8"); - description.setApplicationName("DemoApplication"); - description.setPackageName("com.example.demo"); - description.setPackaging(Packaging.forId("jar")); - description.setBaseDirectory("."); - return description; - } - - static class CallTrackingBiConsumer implements BiConsumer { - - private final BiConsumer delegate; - - private int callCount; - - CallTrackingBiConsumer(BiConsumer delegate) { - this.delegate = delegate; - } - - @Override - public void accept(T t, U u) { - this.callCount++; - this.delegate.accept(t, u); - } - - int timesCalled() { - return this.callCount; - } - - } - -} diff --git a/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.java b/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.java index a08dcf4c..079a6169 100644 --- a/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.java +++ b/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.java @@ -28,8 +28,6 @@ import io.spring.initializr.generator.io.SimpleIndentStrategy; import io.spring.initializr.generator.io.template.MustacheTemplateRenderer; import io.spring.initializr.generator.io.template.TemplateRenderer; import io.spring.initializr.generator.project.ProjectDirectoryFactory; -import io.spring.initializr.generator.project.diff.DefaultProjectDescriptionDiffFactory; -import io.spring.initializr.generator.project.diff.ProjectDescriptionDiffFactory; import io.spring.initializr.metadata.DependencyMetadataProvider; import io.spring.initializr.metadata.InitializrMetadata; import io.spring.initializr.metadata.InitializrMetadataBuilder; @@ -131,12 +129,6 @@ public class InitializrAutoConfiguration { return new DefaultDependencyMetadataProvider(); } - @Bean - @ConditionalOnMissingBean - ProjectDescriptionDiffFactory projectDescriptionDiffFactory() { - return new DefaultProjectDescriptionDiffFactory(); - } - /** * Initializr web configuration. */ diff --git a/initializr-web/src/test/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfigurationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfigurationTests.java index 3f39972f..c5a36e81 100755 --- a/initializr-web/src/test/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfigurationTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfigurationTests.java @@ -17,7 +17,6 @@ package io.spring.initializr.web.autoconfigure; import io.spring.initializr.generator.io.template.TemplateRenderer; -import io.spring.initializr.generator.project.diff.ProjectDescriptionDiffFactory; import io.spring.initializr.metadata.DependencyMetadataProvider; import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.web.controller.CommandLineMetadataController; @@ -64,11 +63,6 @@ class InitializrAutoConfigurationTests { this.contextRunner.run((context) -> assertThat(context).hasSingleBean(TemplateRenderer.class)); } - @Test - void autoConfigRegistersDiffFactory() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ProjectDescriptionDiffFactory.class)); - } - @Test void autoConfigWhenTemplateRendererBeanPresentDoesNotRegisterTemplateRenderer() { this.contextRunner.withUserConfiguration(CustomTemplateRendererConfiguration.class).run((context) -> { diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectContributor.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectContributor.java index 5e3cca91..cc135c95 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectContributor.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectContributor.java @@ -44,7 +44,6 @@ class CustomProjectContributor implements ProjectContributor { && ((CustomProjectDescription) this.description).isCustomFlag()) { Files.createFile(projectRoot.resolve("custom.txt")); } - } } diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescription.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescription.java index c4cb8eef..668078f9 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescription.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescription.java @@ -29,12 +29,11 @@ class CustomProjectDescription extends MutableProjectDescription { private boolean customFlag; CustomProjectDescription() { - super(); } - CustomProjectDescription(final CustomProjectDescription source) { + CustomProjectDescription(CustomProjectDescription source) { super(source); - setCustomFlag(source.isCustomFlag()); + this.customFlag = source.isCustomFlag(); } @Override diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiff.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiff.java index 16742bde..556d485c 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiff.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiff.java @@ -16,32 +16,36 @@ package io.spring.initializr.web.controller.custom; +import java.util.Objects; import java.util.function.BiConsumer; -import io.spring.initializr.generator.project.diff.ProjectDescriptionDiff; +import io.spring.initializr.generator.project.ProjectDescriptionDiff; /** * Extends the base {@link ProjectDescriptionDiff} to provide convenient diff methods on * {@link CustomProjectDescription}. * - * @author cbono + * @author Chris Bono + * @author Stephane Nicoll */ class CustomProjectDescriptionDiff extends ProjectDescriptionDiff { - CustomProjectDescriptionDiff(final CustomProjectDescription original) { + private final CustomProjectDescription original; + + CustomProjectDescriptionDiff(CustomProjectDescription original) { super(original); + this.original = original; } /** - * Optionally calls the specified consumer if the {@code customFlag} is different on - * the original source description and the specified current description. - * @param current the description to test against + * Calls the specified consumer if the {@code customFlag} is different on the original + * source project description than the specified project description. + * @param current the project description to test against * @param consumer to call if the property has changed */ - void ifCUstomFlagChanged(final CustomProjectDescription current, final BiConsumer consumer) { - final CustomProjectDescription original = (CustomProjectDescription) super.getOriginal(); - if (original.isCustomFlag() != current.isCustomFlag()) { - consumer.accept(original.isCustomFlag(), current.isCustomFlag()); + void ifCustomFlagChanged(CustomProjectDescription current, BiConsumer consumer) { + if (!Objects.equals(this.original.isCustomFlag(), current.isCustomFlag())) { + consumer.accept(this.original.isCustomFlag(), current.isCustomFlag()); } } diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiffFactory.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiffFactory.java deleted file mode 100644 index bd56bdd6..00000000 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiffFactory.java +++ /dev/null @@ -1,35 +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.web.controller.custom; - -import io.spring.initializr.generator.project.diff.ProjectDescriptionDiff; -import io.spring.initializr.generator.project.diff.ProjectDescriptionDiffFactory; - -/** - * A custom {@link ProjectDescriptionDiffFactory} implementation that creates custom - * {@link CustomProjectDescriptionDiff} instances. - * - * @author cbono - */ -public class CustomProjectDescriptionDiffFactory implements ProjectDescriptionDiffFactory { - - @Override - public ProjectDescriptionDiff create(final CustomProjectDescription description) { - return new CustomProjectDescriptionDiff(description); - } - -} diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiffTest.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiffTest.java deleted file mode 100644 index 0085fa67..00000000 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/CustomProjectDescriptionDiffTest.java +++ /dev/null @@ -1,81 +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.web.controller.custom; - -import io.spring.initializr.generator.buildsystem.BuildSystem; -import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem; -import io.spring.initializr.generator.language.Language; -import io.spring.initializr.generator.language.java.JavaLanguage; -import io.spring.initializr.generator.packaging.Packaging; -import io.spring.initializr.generator.version.Version; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -/** - * Simple sanity test around the custom diff extension model. - */ -class CustomProjectDescriptionDiffTest { - - @Test - void sanityCheck() { - - CustomProjectDescription description = customProjectDescription(); - CustomProjectDescriptionDiffFactory diffFactory = new CustomProjectDescriptionDiffFactory(); - CustomProjectDescriptionDiff diff = (CustomProjectDescriptionDiff) diffFactory.create(description); - - // copied - assertThat(diff.getOriginal()).usingRecursiveComparison().isEqualTo(description); - assertThat(diff.getOriginal()).isNotSameAs(description); - - // no changes - diff.ifCUstomFlagChanged(description, (v1, v2) -> fail("Values should not have changed")); - - // changes - boolean originalValue = description.isCustomFlag(); - description.setCustomFlag(!originalValue); - - // TODO could use the CallTrackingBiConsumer that I used in initializr-generator - // tests but then where to put it? - final boolean[] called = { false }; - diff.ifCUstomFlagChanged(description, (prev, curr) -> { - assertThat(prev).isEqualTo(originalValue); - assertThat(curr).isEqualTo(description.isCustomFlag()); - called[0] = true; - }); - assertThat(called[0]).isTrue(); - } - - private CustomProjectDescription customProjectDescription() { - CustomProjectDescription description = new CustomProjectDescription(); - description.setBuildSystem(BuildSystem.forId(MavenBuildSystem.ID)); - description.setLanguage(Language.forId(JavaLanguage.ID, "11")); - description.setPlatformVersion(Version.parse("2.2.0.RELEASE")); - description.setGroupId("com.example"); - description.setArtifactId("demo"); - description.setName("demo"); - description.setVersion("0.0.8"); - description.setApplicationName("DemoApplication"); - description.setPackageName("com.example.demo"); - description.setPackaging(Packaging.forId("jar")); - description.setBaseDirectory("."); - description.setCustomFlag(true); - return description; - } - -} diff --git a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/ProjectGenerationControllerCustomRequestIntegrationTests.java b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/ProjectGenerationControllerCustomRequestIntegrationTests.java index 9144d89e..1ea03f50 100644 --- a/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/ProjectGenerationControllerCustomRequestIntegrationTests.java +++ b/initializr-web/src/test/java/io/spring/initializr/web/controller/custom/ProjectGenerationControllerCustomRequestIntegrationTests.java @@ -16,7 +16,10 @@ package io.spring.initializr.web.controller.custom; +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.ProjectDescriptionDiffFactory; import io.spring.initializr.generator.test.project.ProjectStructure; import io.spring.initializr.metadata.InitializrMetadata; import io.spring.initializr.metadata.InitializrMetadataProvider; @@ -33,6 +36,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.test.context.ActiveProfiles; +import org.springframework.util.Assert; import static org.assertj.core.api.Assertions.assertThat; @@ -44,8 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat; */ @ActiveProfiles("test-default") @Import(CustomProjectGenerationConfiguration.class) -public class ProjectGenerationControllerCustomRequestIntegrationTests - extends AbstractInitializrControllerIntegrationTests { +class ProjectGenerationControllerCustomRequestIntegrationTests extends AbstractInitializrControllerIntegrationTests { @Test void createProjectWithCustomFlagEnabled() { @@ -79,6 +82,11 @@ public class ProjectGenerationControllerCustomRequestIntegrationTests return new CustomProjectGenerationController(metadataProvider, projectGenerationInvoker); } + @Bean + CustomProjectDescriptionCustomizer customProjectDescriptionCustomizer() { + return new CustomProjectDescriptionCustomizer(); + } + @Bean CustomProjectDescriptionDiffFactory customProjectDescriptionDiffFactory() { return new CustomProjectDescriptionDiffFactory(); @@ -96,10 +104,28 @@ public class ProjectGenerationControllerCustomRequestIntegrationTests description.setCustomFlag(request.isCustomFlag()); // Override attributes for test purposes description.setPackageName("org.example.custom"); - description.setApplicationName("CustomApp"); return description; } } + static class CustomProjectDescriptionCustomizer implements ProjectDescriptionCustomizer { + + @Override + public void customize(MutableProjectDescription description) { + description.setApplicationName("CustomApp"); + } + + } + + static class CustomProjectDescriptionDiffFactory implements ProjectDescriptionDiffFactory { + + @Override + public CustomProjectDescriptionDiff create(ProjectDescription description) { + Assert.isInstanceOf(CustomProjectDescription.class, description); + return new CustomProjectDescriptionDiff((CustomProjectDescription) description); + } + + } + }