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.rat.mp;
20  
21  import org.apache.commons.cli.Option;
22  import org.apache.commons.io.IOUtils;
23  import org.apache.commons.lang3.tuple.Pair;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.project.MavenProject;
26  import org.apache.maven.project.ProjectBuilder;
27  import org.apache.maven.project.ProjectBuildingRequest;
28  import org.apache.rat.test.AbstractConfigurationOptionsProvider;
29  import org.apache.rat.OptionCollectionTest;
30  import org.apache.rat.ReportConfiguration;
31  import org.apache.rat.plugin.BaseRatMojo;
32  import org.apache.rat.utils.DefaultLog;
33  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
34  import org.junit.jupiter.api.AfterAll;
35  import org.junit.jupiter.api.AfterEach;
36  import org.junit.jupiter.api.Assertions;
37  import org.junit.jupiter.api.BeforeAll;
38  import org.junit.jupiter.api.condition.EnabledOnOs;
39  import org.junit.jupiter.api.condition.OS;
40  import org.junit.jupiter.api.io.TempDir;
41  import org.junit.jupiter.params.ParameterizedTest;
42  import org.junit.jupiter.params.provider.ArgumentsProvider;
43  import org.junit.jupiter.params.provider.ArgumentsSource;
44  
45  import java.io.File;
46  import java.io.FileWriter;
47  import java.io.IOException;
48  import java.lang.reflect.Method;
49  import java.nio.charset.StandardCharsets;
50  import java.nio.file.Path;
51  import java.util.ArrayList;
52  import java.util.List;
53  
54  import static java.lang.String.format;
55  import static org.junit.jupiter.api.Assertions.fail;
56  
57  
58  public class OptionMojoTest {
59  
60      @TempDir
61      static Path testPath;
62  
63      static String POM_FMT;
64  
65      @BeforeAll
66      public static void makeDirs() throws IOException {
67          POM_FMT = IOUtils.resourceToString("/optionTest/pom.tpl", StandardCharsets.UTF_8);
68      }
69  
70      @AfterAll
71      static void preserveData() {
72           AbstractConfigurationOptionsProvider.preserveData(testPath.toFile(), "optionTest");
73      }
74  
75      /**
76       * This method is a known workaround for
77       * {@link <a href="https://github.com/junit-team/junit5/issues/2811">junit 5 issue #2811</a> }.
78       */
79      @AfterEach
80      @EnabledOnOs(OS.WINDOWS)
81      void cleanUp() {
82          System.gc();
83      }
84  
85      @ParameterizedTest
86      @ArgumentsSource(MojoOptionsProvider.class)
87      void testOptionsUpdateConfig(String name, OptionCollectionTest.OptionTest test) {
88          DefaultLog.getInstance().info("Running " + name);
89          test.test();
90      }
91  
92      static class MojoOptionsProvider extends AbstractConfigurationOptionsProvider implements ArgumentsProvider  {
93  
94          private RatCheckMojo mojo = null;
95  
96          public MojoOptionsProvider() {
97              super(BaseRatMojo.unsupportedArgs(), testPath.toFile());
98          }
99  
100        private RatCheckMojo generateMojo(List<Pair<Option, String[]>> args) throws IOException {
101            MavenOption keyOption = new MavenOption(args.get(0).getKey() == null ?
102                    Option.builder().longOpt("no-option").build() :
103                    args.get(0).getKey());
104            List<String> mavenOptions = new ArrayList<>();
105            for (Pair<Option, String[]> pair : args) {
106                if (pair.getKey() != null) {
107                    String[] values = pair.getValue();
108                    if (values != null) {
109                        for (String value : values) {
110                            mavenOptions.add(new MavenOption(pair.getKey()).xmlNode(value));
111                        }
112                    } else {
113                        mavenOptions.add(new MavenOption(pair.getKey()).xmlNode("true"));
114                    }
115                }
116            }
117            // StringBuilder develops the core pom commands.
118            StringBuilder sb = new StringBuilder();
119            mavenOptions.forEach(sb::append);
120            Path pomPath = testPath.resolve(keyOption.name).resolve("pom.xml");
121            File pomFile = pomPath.toFile();
122            pomFile.getParentFile().mkdirs();
123            try (FileWriter writer = new FileWriter(pomFile)) {
124                writer.append(format(POM_FMT, keyOption.name, sb));
125                writer.flush();
126            }
127            try {
128                final RatCheckMojo mojo = new SimpleMojoTestcase(){}.getMojo(pomFile);
129                Assertions.assertNotNull(mojo);
130                return mojo;
131            } catch (IOException e) {
132                throw e;
133            } catch (Exception e) {
134                throw new IOException(format("Unable to generate mojo for %s (%s)", keyOption.name, keyOption), e);
135            }
136        }
137 
138         @Override
139         protected final ReportConfiguration generateConfig(List<Pair<Option, String[]>> args) throws IOException {
140             try {
141                 this.mojo = generateMojo(args);
142                 AbstractConfigurationOptionsProvider.setup(this.mojo.getProject().getBasedir());
143                 return mojo.getConfiguration();
144             } catch (MojoExecutionException e) {
145                 throw new IOException(e.getMessage(), e);
146             }
147         }
148 
149         @Override
150         protected void helpTest() {
151             fail("Should not call help");
152         }
153     }
154 
155     public abstract static class SimpleMojoTestcase extends BetterAbstractMojoTestCase {
156         public RatCheckMojo getMojo(File pomFile) throws Exception {
157             setUp();
158             ProjectBuildingRequest buildingRequest = newMavenSession().getProjectBuildingRequest();
159             ProjectBuilder projectBuilder = lookup(ProjectBuilder.class);
160             MavenProject project = projectBuilder.build(pomFile, buildingRequest).getProject();
161             try {
162                 return (RatCheckMojo) lookupConfiguredMojo(project, "check");
163             } catch (ComponentConfigurationException e) {
164                 for (Method m : RatCheckMojo.class.getMethods()) {
165                     System.out.println( m );
166                 }
167                 throw e;
168             }
169         }
170     }
171 }