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.plugins.help;
20  
21  import java.lang.reflect.Field;
22  import java.lang.reflect.InvocationTargetException;
23  import java.lang.reflect.Method;
24  import java.util.Collections;
25  
26  import org.apache.maven.execution.MavenSession;
27  import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
28  import org.apache.maven.model.Plugin;
29  import org.apache.maven.plugin.MavenPluginManager;
30  import org.apache.maven.plugin.descriptor.MojoDescriptor;
31  import org.apache.maven.plugin.descriptor.Parameter;
32  import org.apache.maven.plugin.descriptor.PluginDescriptor;
33  import org.apache.maven.plugin.version.PluginVersionRequest;
34  import org.apache.maven.plugin.version.PluginVersionResolver;
35  import org.apache.maven.plugin.version.PluginVersionResult;
36  import org.apache.maven.plugins.help.DescribeMojo.PluginInfo;
37  import org.apache.maven.project.MavenProject;
38  import org.eclipse.aether.RepositorySystemSession;
39  import org.junit.Test;
40  import org.mockito.ArgumentCaptor;
41  
42  import static org.junit.Assert.*;
43  import static org.mockito.Mockito.*;
44  
45  /**
46   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
47   */
48  public class DescribeMojoTest {
49      /**
50       * Test method for {@link org.apache.maven.plugins.help.DescribeMojo#toLines(java.lang.String, int, int, int)}.
51       *
52       */
53      @Test
54      public void testGetExpressionsRoot() {
55          try {
56              DescribeMojo describeMojo = new DescribeMojo();
57              Method toLines =
58                      describeMojo.getClass().getDeclaredMethod("toLines", String.class, int.class, int.class, int.class);
59              toLines.setAccessible(true);
60              toLines.invoke(null, "", 2, 2, 80);
61          } catch (Throwable e) {
62              fail("The API changes");
63          }
64      }
65  
66      @Test
67      public void testValidExpression() throws Exception {
68          StringBuilder sb = new StringBuilder();
69          MojoDescriptor md = new MojoDescriptor();
70          Parameter parameter = new Parameter();
71          parameter.setName("name");
72          parameter.setExpression("${valid.expression}");
73          md.addParameter(parameter);
74  
75          String ls = System.getProperty("line.separator");
76  
77          try {
78              Method describeMojoParameters = DescribeMojo.class.getDeclaredMethod(
79                      "describeMojoParameters", MojoDescriptor.class, StringBuilder.class);
80              describeMojoParameters.setAccessible(true);
81              describeMojoParameters.invoke(new DescribeMojo(), md, sb);
82  
83              assertEquals(
84                      "  Available parameters:" + ls + ls + "    name" + ls + "      User property: valid.expression" + ls
85                              + "      (no description available)" + ls,
86                      sb.toString());
87          } catch (Throwable e) {
88              fail(e.getMessage());
89          }
90      }
91  
92      @Test
93      public void testInvalidExpression() throws Exception {
94          StringBuilder sb = new StringBuilder();
95          MojoDescriptor md = new MojoDescriptor();
96          Parameter parameter = new Parameter();
97          parameter.setName("name");
98          parameter.setExpression("${project.build.directory}/generated-sources/foobar"); // this is a defaultValue
99          md.addParameter(parameter);
100 
101         String ls = System.getProperty("line.separator");
102 
103         try {
104             Method describeMojoParameters = DescribeMojo.class.getDeclaredMethod(
105                     "describeMojoParameters", MojoDescriptor.class, StringBuilder.class);
106             describeMojoParameters.setAccessible(true);
107             describeMojoParameters.invoke(new DescribeMojo(), md, sb);
108 
109             assertEquals(
110                     "  Available parameters:" + ls + ls
111                             + "    name"
112                             + ls + "      Expression: ${project.build.directory}/generated-sources/foobar"
113                             + ls + "      (no description available)"
114                             + ls,
115                     sb.toString());
116         } catch (Throwable e) {
117             fail(e.getMessage());
118         }
119     }
120 
121     @Test
122     public void testParsePluginInfoGAV() throws Throwable {
123         DescribeMojo mojo = new DescribeMojo();
124         setFieldWithReflection(mojo, "groupId", "org.test");
125         setFieldWithReflection(mojo, "artifactId", "test");
126         setFieldWithReflection(mojo, "version", "1.0");
127 
128         Method parsePluginLookupInfo = setParsePluginLookupInfoAccessibility();
129         PluginInfo pi = (PluginInfo) parsePluginLookupInfo.invoke(mojo);
130 
131         assertEquals("org.test", pi.getGroupId());
132         assertEquals("test", pi.getArtifactId());
133         assertEquals("1.0", pi.getVersion());
134         assertNull(pi.getPrefix());
135     }
136 
137     @Test
138     public void testParsePluginInfoPluginPrefix() throws Throwable {
139         DescribeMojo mojo = new DescribeMojo();
140         setFieldWithReflection(mojo, "plugin", "help");
141 
142         Method parsePluginLookupInfo = setParsePluginLookupInfoAccessibility();
143         PluginInfo pi = (PluginInfo) parsePluginLookupInfo.invoke(mojo);
144 
145         assertNull(pi.getGroupId());
146         assertNull(pi.getArtifactId());
147         assertNull(pi.getVersion());
148         assertEquals("help", pi.getPrefix());
149 
150         setFieldWithReflection(mojo, "plugin", "help2:::");
151 
152         pi = (PluginInfo) parsePluginLookupInfo.invoke(mojo);
153 
154         assertEquals("help2", pi.getPrefix());
155     }
156 
157     @Test
158     public void testParsePluginInfoPluginGA() throws Throwable {
159         DescribeMojo mojo = new DescribeMojo();
160         setFieldWithReflection(mojo, "plugin", "org.test:test");
161 
162         Method parsePluginLookupInfo = setParsePluginLookupInfoAccessibility();
163         PluginInfo pi = (PluginInfo) parsePluginLookupInfo.invoke(mojo);
164 
165         assertEquals("org.test", pi.getGroupId());
166         assertEquals("test", pi.getArtifactId());
167         assertNull(pi.getVersion());
168         assertNull(pi.getPrefix());
169     }
170 
171     @Test
172     public void testParsePluginInfoPluginGAV() throws Throwable {
173         DescribeMojo mojo = new DescribeMojo();
174         setFieldWithReflection(mojo, "plugin", "org.test:test:1.0");
175 
176         Method parsePluginLookupInfo = setParsePluginLookupInfoAccessibility();
177         PluginInfo pi = (PluginInfo) parsePluginLookupInfo.invoke(mojo);
178 
179         assertEquals("org.test", pi.getGroupId());
180         assertEquals("test", pi.getArtifactId());
181         assertEquals("1.0", pi.getVersion());
182         assertNull(pi.getPrefix());
183     }
184 
185     @Test
186     public void testParsePluginInfoPluginIncorrect() throws Throwable {
187         DescribeMojo mojo = new DescribeMojo();
188         setFieldWithReflection(mojo, "plugin", "org.test:test:1.0:invalid");
189         try {
190             Method parsePluginLookupInfo = setParsePluginLookupInfoAccessibility();
191             parsePluginLookupInfo.invoke(mojo);
192             fail();
193         } catch (Exception e) {
194             // expected
195         }
196     }
197 
198     @Test
199     public void testLookupPluginDescriptorPrefixWithVersion() throws Throwable {
200         DescribeMojo mojo = new DescribeMojo();
201 
202         PluginInfo pi = new PluginInfo();
203         pi.setPrefix("help");
204         pi.setVersion("1.0");
205 
206         Plugin plugin = new Plugin();
207         plugin.setGroupId("org.test");
208         plugin.setArtifactId("test");
209 
210         PluginDescriptor pd = new PluginDescriptor();
211 
212         MojoDescriptorCreator mojoDescriptorCreator = mock(MojoDescriptorCreator.class);
213         PluginVersionResolver pluginVersionResolver = mock(PluginVersionResolver.class);
214         MavenPluginManager pluginManager = mock(MavenPluginManager.class);
215         MavenSession session = mock(MavenSession.class);
216         when(session.getRepositorySession()).thenReturn(mock(RepositorySystemSession.class));
217         setFieldsOnMojo(mojo, mojoDescriptorCreator, pluginVersionResolver, pluginManager, session);
218         MavenProject mavenProject = new MavenProject();
219         mavenProject.setPluginArtifactRepositories(Collections.emptyList());
220         setParentFieldWithReflection(mojo, "project", mavenProject);
221         when(mojoDescriptorCreator.findPluginForPrefix("help", session)).thenReturn(plugin);
222         when(pluginManager.getPluginDescriptor(any(Plugin.class), anyList(), any()))
223                 .thenReturn(pd);
224 
225         Method lookupPluginDescriptor = setLookupPluginDescriptorAccessibility();
226         PluginDescriptor returned = (PluginDescriptor) lookupPluginDescriptor.invoke(mojo, pi);
227 
228         assertEquals(pd, returned);
229 
230         verify(mojoDescriptorCreator).findPluginForPrefix("help", session);
231         verify(pluginVersionResolver, never()).resolve(any(PluginVersionRequest.class));
232         ArgumentCaptor<Plugin> argument = ArgumentCaptor.forClass(Plugin.class);
233         verify(pluginManager).getPluginDescriptor(argument.capture(), anyList(), any());
234         Plugin capturedPlugin = argument.getValue();
235         assertEquals("org.test", capturedPlugin.getGroupId());
236         assertEquals("test", capturedPlugin.getArtifactId());
237         assertEquals("1.0", capturedPlugin.getVersion());
238     }
239 
240     @Test
241     public void testLookupPluginDescriptorPrefixWithoutVersion() throws Throwable {
242         DescribeMojo mojo = new DescribeMojo();
243 
244         PluginInfo pi = new PluginInfo();
245         pi.setPrefix("help");
246 
247         Plugin plugin = new Plugin();
248         plugin.setGroupId("org.test");
249         plugin.setArtifactId("test");
250 
251         PluginDescriptor pd = new PluginDescriptor();
252 
253         MojoDescriptorCreator mojoDescriptorCreator = mock(MojoDescriptorCreator.class);
254         PluginVersionResolver pluginVersionResolver = mock(PluginVersionResolver.class);
255         MavenPluginManager pluginManager = mock(MavenPluginManager.class);
256         PluginVersionResult versionResult = mock(PluginVersionResult.class);
257         MavenSession session = mock(MavenSession.class);
258         when(session.getRepositorySession()).thenReturn(mock(RepositorySystemSession.class));
259         setFieldsOnMojo(mojo, mojoDescriptorCreator, pluginVersionResolver, pluginManager, session);
260         MavenProject mavenProject = new MavenProject();
261         mavenProject.setPluginArtifactRepositories(Collections.emptyList());
262         setParentFieldWithReflection(mojo, "project", mavenProject);
263         when(mojoDescriptorCreator.findPluginForPrefix("help", session)).thenReturn(plugin);
264         when(pluginVersionResolver.resolve(any(PluginVersionRequest.class))).thenReturn(versionResult);
265         when(versionResult.getVersion()).thenReturn("1.0");
266         when(pluginManager.getPluginDescriptor(any(Plugin.class), anyList(), any()))
267                 .thenReturn(pd);
268 
269         Method lookupPluginDescriptor = setLookupPluginDescriptorAccessibility();
270         PluginDescriptor returned = (PluginDescriptor) lookupPluginDescriptor.invoke(mojo, pi);
271         assertEquals(pd, returned);
272 
273         verify(mojoDescriptorCreator).findPluginForPrefix("help", session);
274         ArgumentCaptor<PluginVersionRequest> versionArgument = ArgumentCaptor.forClass(PluginVersionRequest.class);
275         verify(pluginVersionResolver).resolve(versionArgument.capture());
276         assertEquals("org.test", versionArgument.getValue().getGroupId());
277         assertEquals("test", versionArgument.getValue().getArtifactId());
278         ArgumentCaptor<Plugin> argument = ArgumentCaptor.forClass(Plugin.class);
279         verify(pluginManager).getPluginDescriptor(argument.capture(), anyList(), any());
280         Plugin capturedPlugin = argument.getValue();
281         assertEquals("org.test", capturedPlugin.getGroupId());
282         assertEquals("test", capturedPlugin.getArtifactId());
283         assertEquals("1.0", capturedPlugin.getVersion());
284     }
285 
286     @Test
287     public void testLookupPluginDescriptorGAV() throws Throwable {
288         DescribeMojo mojo = new DescribeMojo();
289 
290         PluginInfo pi = new PluginInfo();
291         pi.setGroupId("org.test");
292         pi.setArtifactId("test");
293         pi.setVersion("1.0");
294 
295         PluginDescriptor pd = new PluginDescriptor();
296 
297         MojoDescriptorCreator mojoDescriptorCreator = mock(MojoDescriptorCreator.class);
298         PluginVersionResolver pluginVersionResolver = mock(PluginVersionResolver.class);
299         MavenPluginManager pluginManager = mock(MavenPluginManager.class);
300         MavenSession session = mock(MavenSession.class);
301         when(session.getRepositorySession()).thenReturn(mock(RepositorySystemSession.class));
302         setFieldsOnMojo(mojo, mojoDescriptorCreator, pluginVersionResolver, pluginManager, session);
303         MavenProject mavenProject = new MavenProject();
304         mavenProject.setPluginArtifactRepositories(Collections.emptyList());
305         setParentFieldWithReflection(mojo, "project", mavenProject);
306         when(pluginManager.getPluginDescriptor(any(Plugin.class), anyList(), any()))
307                 .thenReturn(pd);
308 
309         Method lookupPluginDescriptor = setLookupPluginDescriptorAccessibility();
310         PluginDescriptor returned = (PluginDescriptor) lookupPluginDescriptor.invoke(mojo, pi);
311 
312         assertEquals(pd, returned);
313 
314         verify(mojoDescriptorCreator, never()).findPluginForPrefix(any(String.class), any(MavenSession.class));
315         verify(pluginVersionResolver, never()).resolve(any(PluginVersionRequest.class));
316         ArgumentCaptor<Plugin> argument = ArgumentCaptor.forClass(Plugin.class);
317         verify(pluginManager).getPluginDescriptor(argument.capture(), anyList(), any());
318         Plugin capturedPlugin = argument.getValue();
319         assertEquals("org.test", capturedPlugin.getGroupId());
320         assertEquals("test", capturedPlugin.getArtifactId());
321         assertEquals("1.0", capturedPlugin.getVersion());
322     }
323 
324     @Test
325     public void testLookupPluginDescriptorGMissingA() {
326         DescribeMojo mojo = new DescribeMojo();
327         PluginInfo pi = new PluginInfo();
328         pi.setGroupId("org.test");
329         try {
330             Method lookupPluginDescriptor = setLookupPluginDescriptorAccessibility();
331             lookupPluginDescriptor.invoke(mojo, pi);
332             fail();
333         } catch (InvocationTargetException e) {
334             assertTrue(e.getTargetException().getMessage().startsWith("You must specify either"));
335         } catch (NoSuchMethodException | IllegalAccessException e) {
336             fail();
337         }
338     }
339 
340     @Test
341     public void testLookupPluginDescriptorAMissingG() {
342         DescribeMojo mojo = new DescribeMojo();
343         PluginInfo pi = new PluginInfo();
344         pi.setArtifactId("test");
345         try {
346             Method lookupPluginDescriptor = setLookupPluginDescriptorAccessibility();
347             lookupPluginDescriptor.invoke(mojo, pi);
348             fail();
349         } catch (InvocationTargetException e) {
350             assertTrue(e.getTargetException().getMessage().startsWith("You must specify either"));
351         } catch (Exception e) {
352             fail(e.getMessage());
353         }
354     }
355 
356     private static void setParentFieldWithReflection(
357             final DescribeMojo mojo, final String fieldName, final Object value)
358             throws NoSuchFieldException, IllegalAccessException {
359         final Field field = mojo.getClass().getSuperclass().getDeclaredField(fieldName);
360         field.setAccessible(true);
361         field.set(mojo, value);
362         field.setAccessible(false);
363     }
364 
365     private static void setFieldWithReflection(final Object mojo, final String fieldName, final Object value)
366             throws NoSuchFieldException, IllegalAccessException {
367         final Field field = mojo.getClass().getDeclaredField(fieldName);
368         field.setAccessible(true);
369         field.set(mojo, value);
370         field.setAccessible(false);
371     }
372 
373     private static void setFieldsOnMojo(
374             final DescribeMojo mojo,
375             final MojoDescriptorCreator mojoDescriptorCreator,
376             final PluginVersionResolver pluginVersionResolver,
377             final MavenPluginManager pluginManager,
378             final MavenSession session)
379             throws NoSuchFieldException, IllegalAccessException {
380         setFieldWithReflection(mojo, "mojoDescriptorCreator", mojoDescriptorCreator);
381         setFieldWithReflection(mojo, "pluginVersionResolver", pluginVersionResolver);
382         setFieldWithReflection(mojo, "pluginManager", pluginManager);
383         setParentFieldWithReflection(mojo, "session", session);
384     }
385 
386     private static Method setLookupPluginDescriptorAccessibility() throws NoSuchMethodException {
387         Method lookupPluginDescriptor =
388                 DescribeMojo.class.getDeclaredMethod("lookupPluginDescriptor", PluginInfo.class);
389         lookupPluginDescriptor.setAccessible(true);
390         return lookupPluginDescriptor;
391     }
392 
393     private static Method setParsePluginLookupInfoAccessibility() throws NoSuchMethodException {
394         Method parsePluginLookupInfo = DescribeMojo.class.getDeclaredMethod("parsePluginLookupInfo");
395         parsePluginLookupInfo.setAccessible(true);
396         return parsePluginLookupInfo;
397     }
398 }