View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.model.building;
20  
21  import java.beans.BeanInfo;
22  import java.beans.Introspector;
23  import java.beans.PropertyDescriptor;
24  import java.nio.file.Path;
25  import java.nio.file.Paths;
26  import java.util.Collections;
27  import java.util.List;
28  import java.util.Objects;
29  
30  import org.apache.maven.model.Model;
31  import org.junit.jupiter.api.Test;
32  import org.mockito.Mockito;
33  
34  import static org.junit.jupiter.api.Assertions.assertTrue;
35  
36  public class BuildModelSourceTransformerTest {
37  
38      Path pomFile;
39      TransformerContext context = org.mockito.Mockito.mock(TransformerContext.class);
40  
41      @Test
42      void testModelVersion() {
43          Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
44                  .namespaceUri("http://maven.apache.org/POM/4.0.0")
45                  .build());
46          Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
47                  .namespaceUri("http://maven.apache.org/POM/4.0.0")
48                  .modelVersion("4.0.0")
49                  .build());
50          Model actual = transform(initial);
51          assertTrue(equalsDeep(expected, actual));
52      }
53  
54      @Test
55      void testParent() {
56          Path root = Paths.get(".").toAbsolutePath().normalize();
57          pomFile = root.resolve("child/pom.xml");
58          Model parent = new Model(org.apache.maven.api.model.Model.newBuilder()
59                  .groupId("GROUPID")
60                  .artifactId("ARTIFACTID")
61                  .version("1.0-SNAPSHOT")
62                  .build());
63          Mockito.when(context.getRawModel(pomFile, root.resolve("pom.xml"))).thenReturn(parent);
64          Mockito.when(context.locate(root)).thenReturn(root.resolve("pom.xml"));
65          Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
66                  .parent(org.apache.maven.api.model.Parent.newBuilder()
67                          .groupId("GROUPID")
68                          .artifactId("ARTIFACTID")
69                          .build())
70                  .build());
71          Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
72                  .parent(org.apache.maven.api.model.Parent.newBuilder()
73                          .groupId("GROUPID")
74                          .artifactId("ARTIFACTID")
75                          .version("1.0-SNAPSHOT")
76                          .build())
77                  .build());
78          Model actual = transform(initial);
79          assertTrue(equalsDeep(expected, actual));
80      }
81  
82      @Test
83      void testReactorDependencies() {
84          Model dep = new Model(org.apache.maven.api.model.Model.newBuilder()
85                  .groupId("GROUPID")
86                  .artifactId("ARTIFACTID")
87                  .version("1.0-SNAPSHOT")
88                  .build());
89          Mockito.when(context.getRawModel(pomFile, "GROUPID", "ARTIFACTID")).thenReturn(dep);
90          Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
91                  .dependencies(Collections.singleton(org.apache.maven.api.model.Dependency.newBuilder()
92                          .groupId("GROUPID")
93                          .artifactId("ARTIFACTID")
94                          .build()))
95                  .build());
96          Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
97                  .dependencies(Collections.singleton(org.apache.maven.api.model.Dependency.newBuilder()
98                          .groupId("GROUPID")
99                          .artifactId("ARTIFACTID")
100                         .version("1.0-SNAPSHOT")
101                         .build()))
102                 .build());
103         Model actual = transform(initial);
104         assertTrue(equalsDeep(expected, actual));
105     }
106 
107     @Test
108     void testCiFriendlyVersion() {
109         Model initial = new Model(org.apache.maven.api.model.Model.newBuilder()
110                 .version("${revision}-${sha1}")
111                 .build());
112         Mockito.when(context.getUserProperty("revision")).thenReturn("therev");
113         Mockito.when(context.getUserProperty("sha1")).thenReturn("thesha");
114         Model expected = new Model(org.apache.maven.api.model.Model.newBuilder()
115                 .version("therev-thesha")
116                 .build());
117         Model actual = transform(initial);
118         assertTrue(equalsDeep(expected, actual));
119     }
120 
121     Model transform(Model model) {
122         Model transformed = model.clone();
123         new BuildModelSourceTransformer().transform(pomFile, context, transformed);
124         return transformed;
125     }
126 
127     public static boolean equalsDeep(Object m1, Object m2) {
128         try {
129             if (m1 == m2) {
130                 return true;
131             }
132             if (m1 == null || m2 == null) {
133                 return false;
134             }
135             if (!Objects.equals(m1.getClass(), m2.getClass())) {
136                 return false;
137             }
138             BeanInfo bean = Introspector.getBeanInfo(m1.getClass());
139             for (PropertyDescriptor prop : bean.getPropertyDescriptors()) {
140                 if (("first".equals(prop.getName()) || "last".equals(prop.getName()))
141                         && List.class.equals(prop.getReadMethod().getDeclaringClass())) {
142                     continue;
143                 }
144                 Object p1 = prop.getReadMethod().invoke(m1);
145                 Object p2 = prop.getReadMethod().invoke(m2);
146                 if (!equalsDeep(p1, p2)) {
147                     return false;
148                 }
149             }
150             return true;
151         } catch (Exception e) {
152             throw new RuntimeException(e);
153         }
154     }
155 }