SourceStrategyTest.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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
*
* http://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.apache.maven.cling.invoker.mvnup.goals;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import eu.maveniverse.domtrip.Document;
import eu.maveniverse.domtrip.Element;
import org.apache.maven.cling.invoker.mvnup.UpgradeContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@DisplayName("SourceStrategy")
class SourceStrategyTest {
private SourceStrategy strategy;
@BeforeEach
void setUp() {
strategy = new SourceStrategy();
}
@Nested
@DisplayName("Applicability")
class ApplicabilityTests {
@Test
@DisplayName("should not be applicable by default")
void shouldNotBeApplicableByDefault() {
UpgradeContext context = TestUtils.createMockContext(TestUtils.createDefaultOptions());
assertFalse(strategy.isApplicable(context));
}
@Test
@DisplayName("should be applicable with --model-version 4.1.0")
void shouldBeApplicableWithModelVersion410() {
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
assertTrue(strategy.isApplicable(context));
}
@Test
@DisplayName("should be applicable with --model-version 4.2.0")
void shouldBeApplicableWithModelVersion420() {
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.2.0"));
assertTrue(strategy.isApplicable(context));
}
@Test
@DisplayName("should not be applicable with --model-version 4.0.0")
void shouldNotBeApplicableWithModelVersion400() {
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.0.0"));
assertFalse(strategy.isApplicable(context));
}
@Test
@DisplayName("should be applicable with --all")
void shouldBeApplicableWithAll() {
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithAll(true));
assertTrue(strategy.isApplicable(context));
}
}
@Nested
@DisplayName("Compiler Properties Migration")
class CompilerPropertiesTests {
@Test
@DisplayName("should migrate maven.compiler.release to targetVersion")
void shouldMigrateCompilerRelease() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("17", source.childTextTrimmed("targetVersion"));
assertFalse(doc.root().childElement("properties").isPresent());
}
@Test
@DisplayName("should migrate matching maven.compiler.source and target")
void shouldMigrateMatchingSourceTarget() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("11", source.childTextTrimmed("targetVersion"));
assertFalse(doc.root().childElement("properties").isPresent());
}
@Test
@DisplayName("should skip when source and target differ")
void shouldSkipWhenSourceTargetDiffer() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
UpgradeResult result = strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
assertFalse(doc.root().childElement("build").isPresent());
assertTrue(doc.root().childElement("properties").isPresent());
assertEquals(0, result.modifiedCount());
}
@Test
@DisplayName("should prefer release over source/target")
void shouldPreferReleaseOverSourceTarget() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>21</maven.compiler.release>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("21", source.childTextTrimmed("targetVersion"));
assertFalse(doc.root().childElement("properties").isPresent());
}
@Test
@DisplayName("should keep other properties when removing compiler properties")
void shouldKeepOtherProperties() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element properties = doc.root().childElement("properties").orElseThrow();
assertEquals("UTF-8", properties.childTextTrimmed("project.build.sourceEncoding"));
assertFalse(properties.childElement("maven.compiler.release").isPresent());
}
}
@Nested
@DisplayName("Compiler Plugin Migration")
class CompilerPluginTests {
@Test
@DisplayName("should migrate plugin release configuration")
void shouldMigratePluginRelease() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>17</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("17", source.childTextTrimmed("targetVersion"));
// Plugin should be removed since it has no remaining config
assertFalse(doc.root().path("build", "plugins").isPresent());
}
@Test
@DisplayName("should migrate plugin source/target configuration")
void shouldMigratePluginSourceTarget() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("11", source.childTextTrimmed("targetVersion"));
}
@Test
@DisplayName("should keep plugin with remaining executions")
void shouldKeepPluginWithExecutions() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>17</release>
</configuration>
<executions>
<execution>
<id>custom</id>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element plugin = doc.root().path("build", "plugins", "plugin").orElseThrow();
assertFalse(plugin.childElement("configuration").isPresent());
assertTrue(plugin.childElement("executions").isPresent());
}
@Test
@DisplayName("should not extract from plugin when properties already provided targetVersion")
void shouldNotDuplicateTargetVersion() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>21</maven.compiler.release>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>21</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
var sources = doc.root()
.path("build", "sources")
.orElseThrow()
.childElements("source")
.toList();
assertEquals(1, sources.size());
assertEquals("21", sources.get(0).childTextTrimmed("targetVersion"));
assertFalse(doc.root().path("build", "plugins").isPresent());
}
@Test
@DisplayName("should preserve plugin config when it differs from migrated property value")
void shouldPreservePluginConfigWhenDifferent() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>21</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element plugin = doc.root().path("build", "plugins", "plugin").orElseThrow();
Element configuration = plugin.childElement("configuration").orElseThrow();
assertEquals("21", configuration.childTextTrimmed("release"));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("17", source.childTextTrimmed("targetVersion"));
}
@Test
@DisplayName("should migrate compiler plugin from pluginManagement")
void shouldMigrateFromPluginManagement() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>17</release>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("17", source.childTextTrimmed("targetVersion"));
assertFalse(doc.root().path("build", "pluginManagement").isPresent());
}
}
@Nested
@DisplayName("Source Directory Migration")
class SourceDirectoryTests {
@Test
@DisplayName("should migrate non-default sourceDirectory")
void shouldMigrateNonDefaultSourceDirectory() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<sourceDirectory>src/main/java-custom</sourceDirectory>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("src/main/java-custom", source.childTextTrimmed("directory"));
assertFalse(doc.root().path("build", "sourceDirectory").isPresent());
}
@Test
@DisplayName("should migrate non-default testSourceDirectory")
void shouldMigrateNonDefaultTestSourceDirectory() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<testSourceDirectory>src/test/java-custom</testSourceDirectory>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("test", source.childTextTrimmed("scope"));
assertEquals("src/test/java-custom", source.childTextTrimmed("directory"));
}
@Test
@DisplayName("should remove default sourceDirectory without creating source element")
void shouldRemoveDefaultSourceDirectory() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
UpgradeResult result = strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
assertFalse(doc.root().childElement("build").isPresent());
assertEquals(1, result.modifiedCount());
}
}
@Nested
@DisplayName("Resource Migration")
class ResourceTests {
@Test
@DisplayName("should migrate resource with filtering")
void shouldMigrateResourceWithFiltering() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("resources", source.childTextTrimmed("lang"));
assertEquals("true", source.childTextTrimmed("stringFiltering"));
assertFalse(doc.root().path("build", "resources").isPresent());
}
@Test
@DisplayName("should migrate resource with includes and excludes")
void shouldMigrateResourceWithIncludesExcludes() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
<excludes>
<exclude>**/*.bak</exclude>
</excludes>
</resource>
</resources>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("resources", source.childTextTrimmed("lang"));
assertEquals("**/*.xml", source.path("includes").orElseThrow().childTextTrimmed("include"));
assertEquals("**/*.bak", source.path("excludes").orElseThrow().childTextTrimmed("exclude"));
}
@Test
@DisplayName("should migrate resource with targetPath")
void shouldMigrateResourceWithTargetPath() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>META-INF</targetPath>
</resource>
</resources>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("resources", source.childTextTrimmed("lang"));
assertEquals("META-INF", source.childTextTrimmed("targetPath"));
}
@Test
@DisplayName("should migrate test resource")
void shouldMigrateTestResource() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
Element source = doc.root().path("build", "sources", "source").orElseThrow();
assertEquals("test", source.childTextTrimmed("scope"));
assertEquals("resources", source.childTextTrimmed("lang"));
assertEquals("true", source.childTextTrimmed("stringFiltering"));
}
@Test
@DisplayName("should remove default resource without creating source element")
void shouldRemoveDefaultResource() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
UpgradeResult result = strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
assertFalse(doc.root().childElement("build").isPresent());
assertEquals(1, result.modifiedCount());
}
}
@Nested
@DisplayName("Model Version Filtering")
class ModelVersionFilteringTests {
@Test
@DisplayName("should skip POM at model version 4.0.0")
void shouldSkipPomAt400() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
UpgradeResult result = strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
assertTrue(doc.root().childElement("properties").isPresent());
assertEquals(0, result.modifiedCount());
}
@Test
@DisplayName("should process POM at model version 4.1.0")
void shouldProcessPomAt410() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
UpgradeResult result = strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
assertEquals(1, result.modifiedCount());
}
}
@Nested
@DisplayName("Combined Migration")
class CombinedTests {
@Test
@DisplayName("should merge targetVersion and directory into single source element")
void shouldMergeTargetVersionAndDirectory() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<build>
<sourceDirectory>src/main/java-custom</sourceDirectory>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
var sources = doc.root()
.path("build", "sources")
.orElseThrow()
.childElements("source")
.toList();
assertEquals(1, sources.size());
assertEquals("17", sources.get(0).childTextTrimmed("targetVersion"));
assertEquals("src/main/java-custom", sources.get(0).childTextTrimmed("directory"));
}
@Test
@DisplayName("should reuse existing source element when adding targetVersion")
void shouldReuseExistingSourceElement() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<build>
<sources>
<source>
<directory>src/main/java-custom</directory>
</source>
</sources>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
var sources = doc.root()
.path("build", "sources")
.orElseThrow()
.childElements("source")
.toList();
assertEquals(1, sources.size());
assertEquals("17", sources.get(0).childTextTrimmed("targetVersion"));
assertEquals("src/main/java-custom", sources.get(0).childTextTrimmed("directory"));
}
@Test
@DisplayName("should create multiple source elements for different resource configs")
void shouldCreateMultipleResourceSources() {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0">
<modelVersion>4.1.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources-extra</directory>
</resource>
</resources>
</build>
</project>
""";
Document doc = Document.of(pomXml);
UpgradeContext context = TestUtils.createMockContext(TestUtils.createOptionsWithModelVersion("4.1.0"));
strategy.doApply(context, new HashMap<>(Map.of(Paths.get("pom.xml"), doc)));
var sources = doc.root()
.path("build", "sources")
.orElseThrow()
.childElements("source")
.toList();
assertEquals(2, sources.size());
}
}
}