DomUtilsTest.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 eu.maveniverse.domtrip.Document;
import eu.maveniverse.domtrip.Element;
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.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Unit tests for DomUtils functionality with domtrip backend.
*/
class DomUtilsTest {
@Test
void testFindChildElement() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
</plugins>
</build>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element buildElement = DomUtils.findChildElement(root, "build");
assertNotNull(buildElement, "Should find build element");
Element pluginsElement = DomUtils.findChildElement(buildElement, "plugins");
assertNotNull(pluginsElement, "Should find plugins element");
}
@Test
void testInsertNewElement() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
</plugins>
</build>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element buildElement = DomUtils.findChildElement(root, "build");
Element pluginManagementElement = DomUtils.insertNewElement("pluginManagement", buildElement);
assertNotNull(pluginManagementElement, "Should create pluginManagement element");
// Verify it was added to the document
String xmlOutput = DomUtils.toXml(doc);
assertTrue(xmlOutput.contains("<pluginManagement>"), "Should contain pluginManagement element");
}
@Test
void testInsertContentElement() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element descriptionElement = DomUtils.insertContentElement(root, "description", "Test project description");
assertNotNull(descriptionElement, "Should create description element");
// Verify it was added to the document with content
String xmlOutput = DomUtils.toXml(doc);
assertTrue(
xmlOutput.contains("<description>Test project description</description>"),
"Should contain description element with content");
}
@Test
void testToXml() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
</project>
""";
Document doc = Document.of(pomXml);
String xmlOutput = DomUtils.toXml(doc);
assertNotNull(xmlOutput, "Should produce XML output");
assertTrue(xmlOutput.contains("<project"), "Should contain project element");
assertTrue(xmlOutput.contains("<modelVersion>4.0.0</modelVersion>"), "Should contain modelVersion");
assertTrue(xmlOutput.contains("<groupId>test</groupId>"), "Should contain groupId");
}
@Test
void testElementOrderingInProject() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
// Insert elements that should be ordered according to ELEMENT_ORDER
DomUtils.insertContentElement(root, "description", "Test description");
DomUtils.insertContentElement(root, "name", "Test Project");
DomUtils.insertNewElement("properties", root);
String xmlOutput = DomUtils.toXml(doc);
// Verify that elements appear in the correct order according to ELEMENT_ORDER
int nameIndex = xmlOutput.indexOf("<name>");
int descriptionIndex = xmlOutput.indexOf("<description>");
int propertiesIndex = xmlOutput.indexOf("<properties>");
assertTrue(nameIndex > 0, "Should contain name element");
assertTrue(descriptionIndex > 0, "Should contain description element");
assertTrue(propertiesIndex > 0, "Should contain properties element");
// According to ELEMENT_ORDER: name should come before description, and properties should come much later
assertTrue(nameIndex < descriptionIndex, "name should come before description");
assertTrue(descriptionIndex < propertiesIndex, "description should come before properties");
}
@Test
void testInsertElementWithCorrectPositioning() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
</properties>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
// Insert elements that should be positioned according to ELEMENT_ORDER
DomUtils.insertContentElement(root, "name", "Test Project");
DomUtils.insertContentElement(root, "description", "Test description");
DomUtils.insertContentElement(root, "url", "https://example.com");
String xmlOutput = DomUtils.toXml(doc);
// Find positions of all elements
int modelVersionIndex = xmlOutput.indexOf("<modelVersion>");
int groupIdIndex = xmlOutput.indexOf("<groupId>");
int nameIndex = xmlOutput.indexOf("<name>");
int descriptionIndex = xmlOutput.indexOf("<description>");
int urlIndex = xmlOutput.indexOf("<url>");
int propertiesIndex = xmlOutput.indexOf("<properties>");
// Verify correct ordering according to ELEMENT_ORDER for project
assertTrue(modelVersionIndex < groupIdIndex, "modelVersion should come before groupId");
assertTrue(groupIdIndex < nameIndex, "groupId should come before name");
assertTrue(nameIndex < descriptionIndex, "name should come before description");
assertTrue(descriptionIndex < urlIndex, "description should come before url");
assertTrue(urlIndex < propertiesIndex, "url should come before properties");
}
@Test
void testInsertElementBetweenExistingElements() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<name>Test Project</name>
<url>https://example.com</url>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
// Insert description between name and url
DomUtils.insertContentElement(root, "description", "Test description");
String xmlOutput = DomUtils.toXml(doc);
int nameIndex = xmlOutput.indexOf("<name>");
int descriptionIndex = xmlOutput.indexOf("<description>");
int urlIndex = xmlOutput.indexOf("<url>");
// Verify description is inserted between name and url
assertTrue(nameIndex < descriptionIndex, "name should come before description");
assertTrue(descriptionIndex < urlIndex, "description should come before url");
}
@Test
void testInsertElementNotInOrdering() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
// Insert an element that's not in the ELEMENT_ORDER (should be appended at the end)
DomUtils.insertContentElement(root, "customElement", "custom value");
String xmlOutput = DomUtils.toXml(doc);
int versionIndex = xmlOutput.indexOf("<version>");
int customElementIndex = xmlOutput.indexOf("<customElement>");
// Custom element should be appended at the end
assertTrue(customElementIndex > versionIndex, "customElement should come after version");
assertTrue(
xmlOutput.contains("<customElement>custom value</customElement>"),
"Should contain custom element with content");
}
@Test
void testInsertElementInParentWithoutOrdering() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<customParent>
<existingChild>value</existingChild>
</customParent>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element customParent = root.child("customParent").orElse(null);
assertNotNull(customParent, "customParent should exist");
// Insert element in parent that has no ordering defined
DomUtils.insertContentElement(customParent, "newChild", "new value");
String xmlOutput = DomUtils.toXml(doc);
// Should be appended at the end since no ordering is defined for customParent
assertTrue(xmlOutput.contains("<newChild>new value</newChild>"), "Should contain new child element");
int existingChildIndex = xmlOutput.indexOf("<existingChild>");
int newChildIndex = xmlOutput.indexOf("<newChild>");
assertTrue(newChildIndex > existingChildIndex, "newChild should come after existingChild");
}
@Test
void testInsertElementInDependency() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.0</version>
</dependency>
</dependencies>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element dependencies = root.child("dependencies").orElse(null);
assertNotNull(dependencies, "dependencies should exist");
Element dependency = dependencies.child("dependency").orElse(null);
assertNotNull(dependency, "dependency should exist");
// Insert elements in dependency according to dependency ordering
DomUtils.insertContentElement(dependency, "scope", "test");
DomUtils.insertContentElement(dependency, "type", "jar");
String xmlOutput = DomUtils.toXml(doc);
// Verify dependency element ordering: groupId, artifactId, version, type, scope
int groupIdIndex = xmlOutput.indexOf("<groupId>org.junit.jupiter</groupId>");
int artifactIdIndex = xmlOutput.indexOf("<artifactId>junit-jupiter</artifactId>");
int versionIndex = xmlOutput.indexOf("<version>5.9.0</version>");
int typeIndex = xmlOutput.indexOf("<type>jar</type>");
int scopeIndex = xmlOutput.indexOf("<scope>test</scope>");
assertTrue(groupIdIndex < artifactIdIndex, "groupId should come before artifactId");
assertTrue(artifactIdIndex < versionIndex, "artifactId should come before version");
assertTrue(versionIndex < typeIndex, "version should come before type");
assertTrue(typeIndex < scopeIndex, "type should come before scope");
}
@Test
void testInsertElementInBuild() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<build>
<finalName>test-app</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element build = root.child("build").orElse(null);
assertNotNull(build, "build should exist");
// Insert elements in build according to build ordering
DomUtils.insertContentElement(build, "directory", "target");
DomUtils.insertContentElement(build, "sourceDirectory", "src/main/java");
String xmlOutput = DomUtils.toXml(doc);
// Verify build element ordering: directory, finalName, sourceDirectory, plugins
int directoryIndex = xmlOutput.indexOf("<directory>target</directory>");
int finalNameIndex = xmlOutput.indexOf("<finalName>test-app</finalName>");
int sourceDirectoryIndex = xmlOutput.indexOf("<sourceDirectory>src/main/java</sourceDirectory>");
int pluginsIndex = xmlOutput.indexOf("<plugins>");
assertTrue(directoryIndex < finalNameIndex, "directory should come before finalName");
assertTrue(finalNameIndex < sourceDirectoryIndex, "finalName should come before sourceDirectory");
assertTrue(sourceDirectoryIndex < pluginsIndex, "sourceDirectory should come before plugins");
}
@Test
void testInsertElementWithTextContent() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
// Insert elements with various text content scenarios
DomUtils.insertContentElement(root, "name", "Test Project Name");
DomUtils.insertContentElement(root, "description", ""); // Empty content
DomUtils.insertContentElement(root, "url", null); // Null content
DomUtils.insertContentElement(root, "inceptionYear", "2023");
String xmlOutput = DomUtils.toXml(doc);
// Verify text content handling
assertTrue(xmlOutput.contains("<name>Test Project Name</name>"), "Should contain name with text content");
assertTrue(
xmlOutput.contains("<description></description>") || xmlOutput.contains("<description/>"),
"Should contain empty description element");
assertTrue(
xmlOutput.contains("<url></url>") || xmlOutput.contains("<url/>"), "Should contain empty url element");
assertTrue(
xmlOutput.contains("<inceptionYear>2023</inceptionYear>"),
"Should contain inceptionYear with text content");
}
@Test
void testInsertNewElementWithoutContent() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
// Insert empty elements using insertNewElement
Element properties = DomUtils.insertNewElement("properties", root);
Element dependencies = DomUtils.insertNewElement("dependencies", root);
assertNotNull(properties, "properties element should be created");
assertNotNull(dependencies, "dependencies element should be created");
String xmlOutput = DomUtils.toXml(doc);
// Verify elements are created and positioned correctly
int versionIndex = xmlOutput.indexOf("<version>1.0.0</version>");
int propertiesIndex = xmlOutput.indexOf("<properties>");
int dependenciesIndex = xmlOutput.indexOf("<dependencies>");
assertTrue(versionIndex < propertiesIndex, "version should come before properties");
assertTrue(propertiesIndex < dependenciesIndex, "properties should come before dependencies");
// Verify elements are empty
assertTrue(
xmlOutput.contains("<properties></properties>") || xmlOutput.contains("<properties/>"),
"properties should be empty");
assertTrue(
xmlOutput.contains("<dependencies></dependencies>") || xmlOutput.contains("<dependencies/>"),
"dependencies should be empty");
}
@Test
void testInsertMultipleElementsInCorrectOrder() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
// Insert elements in random order - they should be positioned correctly
DomUtils.insertContentElement(root, "licenses", "");
DomUtils.insertContentElement(root, "name", "Test Project");
DomUtils.insertNewElement("dependencies", root);
DomUtils.insertContentElement(root, "description", "A test project");
DomUtils.insertNewElement("properties", root);
DomUtils.insertContentElement(root, "url", "https://example.com");
DomUtils.insertNewElement("build", root);
String xmlOutput = DomUtils.toXml(doc);
// Find all element positions
int modelVersionIndex = xmlOutput.indexOf("<modelVersion>");
int groupIdIndex = xmlOutput.indexOf("<groupId>");
int nameIndex = xmlOutput.indexOf("<name>");
int descriptionIndex = xmlOutput.indexOf("<description>");
int urlIndex = xmlOutput.indexOf("<url>");
int licensesIndex = xmlOutput.indexOf("<licenses>");
int propertiesIndex = xmlOutput.indexOf("<properties>");
int dependenciesIndex = xmlOutput.indexOf("<dependencies>");
int buildIndex = xmlOutput.indexOf("<build>");
// Verify correct ordering according to ELEMENT_ORDER
assertTrue(modelVersionIndex < groupIdIndex, "modelVersion should come before groupId");
assertTrue(groupIdIndex < nameIndex, "groupId should come before name");
assertTrue(nameIndex < descriptionIndex, "name should come before description");
assertTrue(descriptionIndex < urlIndex, "description should come before url");
assertTrue(urlIndex < licensesIndex, "url should come before licenses");
assertTrue(licensesIndex < propertiesIndex, "licenses should come before properties");
assertTrue(propertiesIndex < dependenciesIndex, "properties should come before dependencies");
assertTrue(dependenciesIndex < buildIndex, "dependencies should come before build");
}
@Test
void testRemoveElement() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<name>Test Project</name>
<description>Test description</description>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element nameElement = DomUtils.findChildElement(root, "name");
// Test removing existing element
DomUtils.removeElement(nameElement);
String xmlOutput = DomUtils.toXml(doc);
assertFalse(xmlOutput.contains("<name>Test Project</name>"), "Should not contain removed name element");
assertTrue(
xmlOutput.contains("<description>Test description</description>"), "Should still contain description");
}
@Test
void testChildTextContent() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<name>Test Project</name>
<description></description>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
// Test getting text from existing elements
assertEquals("4.0.0", root.childText("modelVersion"), "Should get modelVersion text");
assertEquals("test", root.childText("groupId"), "Should get groupId text");
assertEquals("Test Project", root.childText("name"), "Should get name text");
assertEquals("", root.childText("description"), "Should get empty description text");
// Test getting text from non-existing element
assertNull(root.childText("nonexistent"), "Should return null for non-existing element");
}
@Test
void testAddGAVElements() throws Exception {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<dependencies>
<dependency>
</dependency>
</dependencies>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element dependencies = DomUtils.findChildElement(root, "dependencies");
Element dependency = DomUtils.findChildElement(dependencies, "dependency");
// Test adding GAV elements with version
DomUtils.addGAVElements(dependency, "org.example", "test-artifact", "1.0.0");
String xmlOutput = DomUtils.toXml(doc);
assertTrue(xmlOutput.contains("<groupId>org.example</groupId>"), "Should contain groupId");
assertTrue(xmlOutput.contains("<artifactId>test-artifact</artifactId>"), "Should contain artifactId");
assertTrue(xmlOutput.contains("<version>1.0.0</version>"), "Should contain version");
// Test adding GAV elements without version
Element dependency2 = DomUtils.insertNewElement("dependency", dependencies);
DomUtils.addGAVElements(dependency2, "org.example", "test-artifact2", null);
xmlOutput = DomUtils.toXml(doc);
assertTrue(xmlOutput.contains("<artifactId>test-artifact2</artifactId>"), "Should contain second artifactId");
assertFalse(
xmlOutput.contains("test-artifact2</artifactId>\n <version>"),
"Should not add version element for null version");
}
@Test
void testCreateDependency() throws Exception {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<dependencies>
</dependencies>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element dependencies = DomUtils.findChildElement(root, "dependencies");
// Test creating dependency with version
Element dependency = DomUtils.createDependency(dependencies, "org.junit.jupiter", "junit-jupiter", "5.9.0");
assertNotNull(dependency, "Should create dependency element");
String xmlOutput = DomUtils.toXml(doc);
assertTrue(xmlOutput.contains("<dependency>"), "Should contain dependency element");
assertTrue(xmlOutput.contains("<groupId>org.junit.jupiter</groupId>"), "Should contain groupId");
assertTrue(xmlOutput.contains("<artifactId>junit-jupiter</artifactId>"), "Should contain artifactId");
assertTrue(xmlOutput.contains("<version>5.9.0</version>"), "Should contain version");
// Test creating dependency without version
Element dependency2 = DomUtils.createDependency(dependencies, "org.example", "test-lib", null);
assertNotNull(dependency2, "Should create second dependency element");
xmlOutput = DomUtils.toXml(doc);
assertTrue(xmlOutput.contains("<artifactId>test-lib</artifactId>"), "Should contain second artifactId");
}
@Test
void testCreatePlugin() throws Exception {
String pomXml = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<build>
<plugins>
</plugins>
</build>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
Element build = DomUtils.findChildElement(root, "build");
Element plugins = DomUtils.findChildElement(build, "plugins");
// Test creating plugin with version
Element plugin = DomUtils.createPlugin(plugins, "org.apache.maven.plugins", "maven-compiler-plugin", "3.11.0");
assertNotNull(plugin, "Should create plugin element");
String xmlOutput = DomUtils.toXml(doc);
assertTrue(xmlOutput.contains("<plugin>"), "Should contain plugin element");
assertTrue(xmlOutput.contains("<groupId>org.apache.maven.plugins</groupId>"), "Should contain groupId");
assertTrue(xmlOutput.contains("<artifactId>maven-compiler-plugin</artifactId>"), "Should contain artifactId");
assertTrue(xmlOutput.contains("<version>3.11.0</version>"), "Should contain version");
// Test creating plugin without version
Element plugin2 = DomUtils.createPlugin(plugins, "org.example", "test-plugin", "");
assertNotNull(plugin2, "Should create second plugin element");
xmlOutput = DomUtils.toXml(doc);
assertTrue(xmlOutput.contains("<artifactId>test-plugin</artifactId>"), "Should contain second artifactId");
}
@Test
void testUpdateOrCreateChildElement() throws Exception {
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>test</groupId>
<artifactId>test</artifactId>
<version>1.0.0</version>
<name>Old Name</name>
</project>
""";
Document doc = Document.of(pomXml);
Element root = doc.root();
// Test updating existing element
Element updatedName = DomUtils.updateOrCreateChildElement(root, "name", "New Name");
assertNotNull(updatedName, "Should return updated element");
String xmlOutput = DomUtils.toXml(doc);
assertTrue(xmlOutput.contains("<name>New Name</name>"), "Should contain updated name");
assertFalse(xmlOutput.contains("<name>Old Name</name>"), "Should not contain old name");
// Test creating new element
Element description = DomUtils.updateOrCreateChildElement(root, "description", "Test Description");
assertNotNull(description, "Should return created element");
xmlOutput = DomUtils.toXml(doc);
assertTrue(xmlOutput.contains("<description>Test Description</description>"), "Should contain new description");
// Verify element ordering is maintained
int nameIndex = xmlOutput.indexOf("<name>");
int descriptionIndex = xmlOutput.indexOf("<description>");
assertTrue(nameIndex < descriptionIndex, "name should come before description");
}
}