Skip to content

Commit 0bc4b06

Browse files
gnodetclaude
andcommitted
Add formatting preservation integration test for DomTrip
Adds an IT that verifies DomTrip preserves POM formatting byte-for-byte, including multi-line attributes, mixed tab/space indentation, inline comments, and extra blank lines. The old JDOM2 implementation would collapse multi-line attributes and alter whitespace in these cases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 09c6ed5 commit 0bc4b06

File tree

7 files changed

+330
-0
lines changed

7 files changed

+330
-0
lines changed

maven-release-manager/src/test/java/org/apache/maven/shared/release/phase/RewritePomsForReleasePhaseTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import java.io.File;
2525
import java.io.IOException;
26+
import java.nio.file.Files;
2627
import java.nio.file.Path;
2728
import java.util.Collections;
2829
import java.util.Iterator;
@@ -501,4 +502,27 @@ void testRewritePomWithCheckModificationExcludes() throws Exception {
501502

502503
comparePomFiles(reactorProjects);
503504
}
505+
506+
@Test
507+
void testRewriteFormattingPreservation() throws Exception {
508+
List<MavenProject> reactorProjects = createReactorProjects("formatting-preservation");
509+
ReleaseDescriptorBuilder builder =
510+
createConfigurationForPomWithParentAlternateNextVersion(reactorProjects, "formatting-preservation");
511+
builder.addReleaseVersion("groupId:subproject2", ALTERNATIVE_NEXT_VERSION);
512+
513+
phase.execute(ReleaseUtils.buildReleaseDescriptor(builder), new DefaultReleaseEnvironment(), reactorProjects);
514+
515+
comparePomFiles(reactorProjects);
516+
517+
// Verify exact formatting preservation (byte-for-byte), which the XMLUnit comparison above does not check.
518+
// The old JDOM2 implementation would collapse multi-line attributes, alter self-closing tag spacing,
519+
// and reorder attributes — DomTrip preserves all of these exactly.
520+
for (MavenProject project : reactorProjects) {
521+
File actualFile = project.getFile();
522+
File expectedFile = new File(actualFile.getParentFile(), "expected-pom.xml");
523+
String expected = new String(Files.readAllBytes(expectedFile.toPath()));
524+
String actual = new String(Files.readAllBytes(actualFile.toPath()));
525+
assertEquals(expected, actual, "Exact formatting not preserved for " + actualFile.getName());
526+
}
527+
}
504528
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one
4+
~ or more contributor license agreements. See the NOTICE file
5+
~ distributed with this work for additional information
6+
~ regarding copyright ownership. The ASF licenses this file
7+
~ to you under the Apache License, Version 2.0 (the
8+
~ "License"); you may not use this file except in compliance
9+
~ with the License. You may obtain a copy of the License at
10+
~
11+
~ http://www.apache.org/licenses/LICENSE-2.0
12+
~
13+
~ Unless required by applicable law or agreed to in writing,
14+
~ software distributed under the License is distributed on an
15+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
~ KIND, either express or implied. See the License for the
17+
~ specific language governing permissions and limitations
18+
~ under the License.
19+
-->
20+
<!--
21+
~ Formatting preservation test.
22+
~ This POM uses various formatting patterns that DomTrip preserves losslessly:
23+
~ tab indentation, extra blank lines, inline comments, and multi-line attributes.
24+
-->
25+
26+
<project xmlns="http://maven.apache.org/POM/4.0.0"
27+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
28+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
29+
30+
<modelVersion>4.0.0</modelVersion>
31+
32+
<!-- project coordinates -->
33+
<groupId>groupId</groupId>
34+
<artifactId>artifactId</artifactId>
35+
<version>1.0</version>
36+
<packaging>pom</packaging>
37+
38+
39+
<scm>
40+
<connection>scm:svn:file://localhost/tmp/scm-repo/tags/release-label</connection>
41+
<developerConnection>scm:svn:file://localhost/tmp/scm-repo/tags/release-label</developerConnection>
42+
<url>file://localhost/tmp/scm-repo/tags/release-label</url>
43+
</scm>
44+
45+
46+
<!-- managed dependencies use tab indentation -->
47+
<dependencyManagement>
48+
<dependencies>
49+
<dependency>
50+
<groupId>groupId</groupId>
51+
<artifactId>subproject1</artifactId>
52+
<version>2.0</version><!-- version managed by release plugin -->
53+
</dependency>
54+
</dependencies>
55+
</dependencyManagement>
56+
57+
<build>
58+
<pluginManagement>
59+
<plugins>
60+
<plugin>
61+
<groupId>groupId</groupId>
62+
<artifactId>subproject1</artifactId>
63+
<version>2.0</version>
64+
</plugin>
65+
</plugins>
66+
</pluginManagement>
67+
</build>
68+
69+
<modules>
70+
<module>subproject1</module>
71+
<module>subproject2</module>
72+
</modules>
73+
74+
</project>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one
4+
~ or more contributor license agreements. See the NOTICE file
5+
~ distributed with this work for additional information
6+
~ regarding copyright ownership. The ASF licenses this file
7+
~ to you under the Apache License, Version 2.0 (the
8+
~ "License"); you may not use this file except in compliance
9+
~ with the License. You may obtain a copy of the License at
10+
~
11+
~ http://www.apache.org/licenses/LICENSE-2.0
12+
~
13+
~ Unless required by applicable law or agreed to in writing,
14+
~ software distributed under the License is distributed on an
15+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
~ KIND, either express or implied. See the License for the
17+
~ specific language governing permissions and limitations
18+
~ under the License.
19+
-->
20+
<!--
21+
~ Formatting preservation test.
22+
~ This POM uses various formatting patterns that DomTrip preserves losslessly:
23+
~ tab indentation, extra blank lines, inline comments, and multi-line attributes.
24+
-->
25+
26+
<project xmlns="http://maven.apache.org/POM/4.0.0"
27+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
28+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
29+
30+
<modelVersion>4.0.0</modelVersion>
31+
32+
<!-- project coordinates -->
33+
<groupId>groupId</groupId>
34+
<artifactId>artifactId</artifactId>
35+
<version>1.0-SNAPSHOT</version>
36+
<packaging>pom</packaging>
37+
38+
39+
<scm>
40+
<connection>scm:svn:file://localhost/tmp/scm-repo/trunk</connection>
41+
<developerConnection>scm:svn:file://localhost/tmp/scm-repo/trunk</developerConnection>
42+
<url>file://localhost/tmp/scm-repo/trunk</url>
43+
</scm>
44+
45+
46+
<!-- managed dependencies use tab indentation -->
47+
<dependencyManagement>
48+
<dependencies>
49+
<dependency>
50+
<groupId>groupId</groupId>
51+
<artifactId>subproject1</artifactId>
52+
<version>2.0-SNAPSHOT</version><!-- version managed by release plugin -->
53+
</dependency>
54+
</dependencies>
55+
</dependencyManagement>
56+
57+
<build>
58+
<pluginManagement>
59+
<plugins>
60+
<plugin>
61+
<groupId>groupId</groupId>
62+
<artifactId>subproject1</artifactId>
63+
<version>2.0-SNAPSHOT</version>
64+
</plugin>
65+
</plugins>
66+
</pluginManagement>
67+
</build>
68+
69+
<modules>
70+
<module>subproject1</module>
71+
<module>subproject2</module>
72+
</modules>
73+
74+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one
4+
~ or more contributor license agreements. See the NOTICE file
5+
~ distributed with this work for additional information
6+
~ regarding copyright ownership. The ASF licenses this file
7+
~ to you under the Apache License, Version 2.0 (the
8+
~ "License"); you may not use this file except in compliance
9+
~ with the License. You may obtain a copy of the License at
10+
~
11+
~ http://www.apache.org/licenses/LICENSE-2.0
12+
~
13+
~ Unless required by applicable law or agreed to in writing,
14+
~ software distributed under the License is distributed on an
15+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
~ KIND, either express or implied. See the License for the
17+
~ specific language governing permissions and limitations
18+
~ under the License.
19+
-->
20+
<project xmlns="http://maven.apache.org/POM/4.0.0"
21+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
22+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
23+
24+
<modelVersion>4.0.0</modelVersion>
25+
26+
<!-- parent reference -->
27+
<parent>
28+
<groupId>groupId</groupId>
29+
<artifactId>artifactId</artifactId>
30+
<version>1.0</version>
31+
</parent>
32+
33+
<artifactId>subproject1</artifactId>
34+
<version>2.0</version>
35+
36+
</project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one
4+
~ or more contributor license agreements. See the NOTICE file
5+
~ distributed with this work for additional information
6+
~ regarding copyright ownership. The ASF licenses this file
7+
~ to you under the Apache License, Version 2.0 (the
8+
~ "License"); you may not use this file except in compliance
9+
~ with the License. You may obtain a copy of the License at
10+
~
11+
~ http://www.apache.org/licenses/LICENSE-2.0
12+
~
13+
~ Unless required by applicable law or agreed to in writing,
14+
~ software distributed under the License is distributed on an
15+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
~ KIND, either express or implied. See the License for the
17+
~ specific language governing permissions and limitations
18+
~ under the License.
19+
-->
20+
<project xmlns="http://maven.apache.org/POM/4.0.0"
21+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
22+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
23+
24+
<modelVersion>4.0.0</modelVersion>
25+
26+
<!-- parent reference -->
27+
<parent>
28+
<groupId>groupId</groupId>
29+
<artifactId>artifactId</artifactId>
30+
<version>1.0-SNAPSHOT</version>
31+
</parent>
32+
33+
<artifactId>subproject1</artifactId>
34+
<version>2.0-SNAPSHOT</version>
35+
36+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one
4+
~ or more contributor license agreements. See the NOTICE file
5+
~ distributed with this work for additional information
6+
~ regarding copyright ownership. The ASF licenses this file
7+
~ to you under the Apache License, Version 2.0 (the
8+
~ "License"); you may not use this file except in compliance
9+
~ with the License. You may obtain a copy of the License at
10+
~
11+
~ http://www.apache.org/licenses/LICENSE-2.0
12+
~
13+
~ Unless required by applicable law or agreed to in writing,
14+
~ software distributed under the License is distributed on an
15+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
~ KIND, either express or implied. See the License for the
17+
~ specific language governing permissions and limitations
18+
~ under the License.
19+
-->
20+
<project xmlns="http://maven.apache.org/POM/4.0.0"
21+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
22+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
23+
24+
<modelVersion>4.0.0</modelVersion>
25+
26+
<parent>
27+
<groupId>groupId</groupId>
28+
<artifactId>artifactId</artifactId>
29+
<version>1.0</version>
30+
</parent>
31+
32+
<artifactId>subproject2</artifactId>
33+
<version>2.0</version>
34+
35+
<dependencies>
36+
<dependency>
37+
<groupId>groupId</groupId>
38+
<artifactId>subproject1</artifactId>
39+
<version>2.0</version>
40+
</dependency>
41+
</dependencies>
42+
43+
</project>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one
4+
~ or more contributor license agreements. See the NOTICE file
5+
~ distributed with this work for additional information
6+
~ regarding copyright ownership. The ASF licenses this file
7+
~ to you under the Apache License, Version 2.0 (the
8+
~ "License"); you may not use this file except in compliance
9+
~ with the License. You may obtain a copy of the License at
10+
~
11+
~ http://www.apache.org/licenses/LICENSE-2.0
12+
~
13+
~ Unless required by applicable law or agreed to in writing,
14+
~ software distributed under the License is distributed on an
15+
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
~ KIND, either express or implied. See the License for the
17+
~ specific language governing permissions and limitations
18+
~ under the License.
19+
-->
20+
<project xmlns="http://maven.apache.org/POM/4.0.0"
21+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
22+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
23+
24+
<modelVersion>4.0.0</modelVersion>
25+
26+
<parent>
27+
<groupId>groupId</groupId>
28+
<artifactId>artifactId</artifactId>
29+
<version>1.0-SNAPSHOT</version>
30+
</parent>
31+
32+
<artifactId>subproject2</artifactId>
33+
<version>2.0-SNAPSHOT</version>
34+
35+
<dependencies>
36+
<dependency>
37+
<groupId>groupId</groupId>
38+
<artifactId>subproject1</artifactId>
39+
<version>2.0-SNAPSHOT</version>
40+
</dependency>
41+
</dependencies>
42+
43+
</project>

0 commit comments

Comments
 (0)