SonarQube custom JavaScript plugin, unit tests
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Mon, 22 Aug 2016 21:01:02 +0000 (23:01 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Mon, 22 Aug 2016 21:01:02 +0000 (23:01 +0200)
Sonar/Plugins/sonar-custom-javascript-plugin/pom.xml
Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/custom/javascript/checks/AngularJSRootOnEventSubscriptionCheckTest.java
Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/custom/javascript/checks/CheckListTest.java [new file with mode: 0644]
Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/plugins/custom/javascript/CustomPluginTest.java [new file with mode: 0644]
Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/plugins/custom/javascript/CustomRulesDefinitionTest.java [new file with mode: 0644]

index 9f3b843..7cc18bc 100644 (file)
     <sonar.apiVersion>5.6.1</sonar.apiVersion>
     <javascript.plugin.version>2.15</javascript.plugin.version>
     <jdk.min.version>1.8</jdk.min.version>
+    <maven.javadoc.version>2.10.4</maven.javadoc.version>
+       <maven.source.version>3.0.1</maven.source.version>
+    <!-- Be careful these two paths must match the ones configured in SONARQUBE JaCoCo plugin -->
+    <jacoco.it.execution.data.file>${project.basedir}/target/jacoco-it.exec</jacoco.it.execution.data.file>
+    <jacoco.ut.execution.data.file>${project.basedir}/target/jacoco.exec</jacoco.ut.execution.data.file>
+
+    <skip.unit.tests>false</skip.unit.tests>
+    <skip.integration.tests>true</skip.integration.tests>
     <sonar.pluginKey>customjavascriptplugin</sonar.pluginKey>
   </properties>
 
   </dependencies>
 
   <build>
+
+               <pluginManagement>
+                       <plugins>
+              <plugin>
+                  <groupId>org.apache.maven.plugins</groupId>
+                  <artifactId>maven-site-plugin</artifactId>
+                  <version>3.5.1</version>
+                  <dependencies>
+                      <dependency><!-- add support for ssh/scp -->
+                          <groupId>org.apache.maven.wagon</groupId>
+                          <artifactId>wagon-ssh</artifactId>
+                          <version>2.10</version>
+                      </dependency>
+                  </dependencies>
+              </plugin>
+                       </plugins>
+               </pluginManagement>
+
     <plugins>
       <plugin>
         <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
           <encoding>${project.build.sourceEncoding}</encoding>
         </configuration>
       </plugin>
+       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-resources-plugin</artifactId>
+                               <version>2.7</version>
+                               <configuration>
+                                       <encoding>${project.build.sourceEncoding}</encoding>
+                               </configuration>
+                       </plugin>
+            <plugin>
+                <artifactId>maven-site-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-descriptor</id>
+                        <goals>
+                            <goal>attach-descriptor</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-jar-plugin</artifactId>
+                               <version>2.6</version>
+                               <configuration>
+                                       <archive>
+                                               <manifestEntries>
+                                                       <Specification-Title>${project.description}</Specification-Title>
+                                                       <Specification-Version>${project.version}</Specification-Version>
+                                                       <Specification-Vendor>${project.organization.name}</Specification-Vendor>
+                                                       <Implementation-Title>${project.description}</Implementation-Title>
+                                                       <Implementation-Version>${project.version}</Implementation-Version>
+                                                       <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+                                               </manifestEntries>
+                                       </archive>
+                               </configuration>
+                       </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>${maven.javadoc.version}</version>
+                <configuration>
+                    <quiet>true</quiet>
+                    <docencoding>${project.build.sourceEncoding}</docencoding>
+                    <charset>${project.build.sourceEncoding}</charset>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                    <additionalparam>-Xdoclint:none</additionalparam>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>${maven.source.version}</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>jar-no-fork</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <version>0.7.7.201606060606</version>
+                <executions>
+                    <!-- Prepares the property pointing to the JaCoCo runtime agent which 
+                        is passed as VM argument when Maven the Surefire plugin is executed. -->
+                    <execution>
+                        <id>pre-unit-test</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                        <configuration>
+                            <!-- Sets the path to the file which contains the execution data. -->
+                            <destFile>${jacoco.ut.execution.data.file}</destFile>
+                            <!-- Sets the name of the property containing the settings for JaCoCo 
+                                runtime agent. -->
+                            <propertyName>surefireArgLine</propertyName>
+                        </configuration>
+                    </execution>
+                    <!-- Ensures that the code coverage report for unit tests is created 
+                        after unit tests have been run. -->
+                    <execution>
+                        <id>post-unit-test</id>
+                        <phase>test</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                        <configuration>
+                            <!-- Sets the path to the file which contains the execution data. -->
+                            <dataFile>${jacoco.ut.execution.data.file}</dataFile>
+                            <!-- Sets the output directory for the code coverage report. -->
+                            <outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
+                        </configuration>
+                    </execution>
+                    <!-- Prepares the property pointing to the JaCoCo runtime agent which 
+                        is passed as VM argument when Maven the Failsafe plugin is executed. -->
+                    <execution>
+                        <id>pre-integration-test</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                        <configuration>
+                            <!-- Sets the path to the file which contains the execution data. -->
+                            <destFile>${jacoco.it.execution.data.file}</destFile>
+                            <!-- Sets the name of the property containing the settings for JaCoCo 
+                                runtime agent. -->
+                            <propertyName>failsafeArgLine</propertyName>
+                        </configuration>
+                    </execution>
+                    <!-- Ensures that the code coverage report for integration tests after 
+                        integration tests have been run. -->
+                    <execution>
+                        <id>post-integration-test</id>
+                        <phase>post-integration-test</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                        <configuration>
+                            <!-- Sets the path to the file which contains the execution data. -->
+                            <dataFile>${jacoco.it.execution.data.file}</dataFile>
+                            <!-- Sets the output directory for the code coverage report. -->
+                            <outputDirectory>${project.reporting.outputDirectory}/jacoco-it</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.m2e</groupId>
+                <artifactId>lifecycle-mapping</artifactId>
+                <version>1.0.0</version>
+                <configuration>
+                    <lifecycleMappingMetadata>
+                        <pluginExecutions>
+                            <pluginExecution>
+                                <pluginExecutionFilter>
+                                    <groupId>org.jacoco</groupId>
+                                    <artifactId>jacoco-maven-plugin</artifactId>
+                                    <versionRange>[0.5,)
+                                    </versionRange>
+                                    <goals>
+                                        <goal>prepare-agent</goal>
+                                    </goals>
+                                </pluginExecutionFilter>
+                                <action>
+                                    <!-- m2e doesn't know what to do with jacoco, let's ignore it or 
+                                        annoying error markers appear see http://wiki.eclipse.org/M2E_plugin_execution_not_covered -->
+                                    <ignore />
+                                </action>
+                            </pluginExecution>
+                        </pluginExecutions>
+                    </lifecycleMappingMetadata>
+                </configuration>
+            </plugin>
+               <!-- Used for unit tests -->
+               <plugin>
+                       <groupId>org.apache.maven.plugins</groupId>
+                       <artifactId>maven-surefire-plugin</artifactId>
+                       <version>2.19.1</version>
+                       <dependencies>
+                               <dependency>
+                                       <groupId>org.apache.maven.surefire</groupId>
+                                       <artifactId>surefire-junit47</artifactId>
+                                       <version>2.19.1</version>
+                               </dependency>
+                       </dependencies>
+                       <configuration>
+                               <!-- Sets the VM argument line used when unit tests are run. -->
+                               <argLine>-Dfile.encoding=${project.build.sourceEncoding}
+                                       ${surefireArgLine}</argLine>
+                               <!-- Skips unit tests if the value of skip.unit.tests property is true -->
+                               <skipTests>${skip.unit.tests}</skipTests>
+                               <!-- Excludes integration tests when unit tests are run. -->
+                               <excludes>
+                                       <exclude>**/*IT.java</exclude>
+                                       <exclude>**/*IntegrationTest.java</exclude>
+                               </excludes>
+                       </configuration>
+               </plugin>
     </plugins>
   </build>
+  
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <version>2.9</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>${maven.javadoc.version}</version>
+                <reportSets>
+                    <reportSet>
+                        <id>html</id>
+                        <configuration>
+
+                            <doctitle>API for ${project.name} ${project.version}</doctitle>
+                            <windowtitle>API for ${project.name} ${project.version}</windowtitle>
+                        </configuration>
+                        <reports>
+                            <report>javadoc</report>
+                            <report>aggregate</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-report-plugin</artifactId>
+                <version>2.19.1</version>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>report-only</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jxr-plugin</artifactId>
+                <version>2.5</version>
+            </plugin>
+        </plugins>
+    </reporting>
 
 </project>
index 40994ec..ddada54 100644 (file)
@@ -10,7 +10,7 @@ public class AngularJSRootOnEventSubscriptionCheckTest {
          private AngularJSRootOnEventSubscriptionCheck check = new AngularJSRootOnEventSubscriptionCheck();
 
          @Test
-         public void testDefault() {
+         public void whenUsingRootScopeOnEventThenGenerateIssues() {
            JavaScriptCheckVerifier.verify(check, new File("src/test/files/checks/AngularJSRootOnEventSubscriptionCheck.js"));
          }
 }
diff --git a/Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/custom/javascript/checks/CheckListTest.java b/Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/custom/javascript/checks/CheckListTest.java
new file mode 100644 (file)
index 0000000..86f1820
--- /dev/null
@@ -0,0 +1,29 @@
+package de.example.custom.javascript.checks;
+
+import static org.junit.Assert.*;
+import static org.hamcrest.CoreMatchers.*;
+
+import java.io.File;
+import java.util.Collection;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Test;
+
+public class CheckListTest {
+
+         @Test
+         public void whenRetrievingJavaScriptChecksThenGetRightNumberOfClasses() {
+           int count = 0;
+           Collection<File> files = FileUtils.listFiles(
+                       new File("src/main/java/de/example/custom/javascript/checks/"),
+                       new String[] {"java"},
+                       true);
+           for (File file : files) {
+             if (file.getName().endsWith("Check.java")) {
+               count++;
+             }
+           }
+           assertThat(CheckList.getChecks().size(), is(count));
+         }
+
+}
diff --git a/Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/plugins/custom/javascript/CustomPluginTest.java b/Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/plugins/custom/javascript/CustomPluginTest.java
new file mode 100644 (file)
index 0000000..5d0912c
--- /dev/null
@@ -0,0 +1,22 @@
+package de.example.plugins.custom.javascript;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.sonar.api.Plugin;
+import org.sonar.api.SonarQubeVersion;
+
+public class CustomPluginTest {
+
+       @Test
+       public void whenCreatingCustomJavaScriptPluginThenRetrieveRightNumberOfExtensions() {
+               CustomPlugin javaPlugin = new CustomPlugin();
+               Plugin.Context context = new Plugin.Context(SonarQubeVersion.V5_6);
+               
+               javaPlugin.define(context);
+
+               assertThat(context.getExtensions().size(), is(1));
+       }
+
+}
diff --git a/Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/plugins/custom/javascript/CustomRulesDefinitionTest.java b/Sonar/Plugins/sonar-custom-javascript-plugin/src/test/java/de/example/plugins/custom/javascript/CustomRulesDefinitionTest.java
new file mode 100644 (file)
index 0000000..dd845ab
--- /dev/null
@@ -0,0 +1,159 @@
+package de.example.plugins.custom.javascript;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.check.Rule;
+import org.sonar.plugins.javascript.JavaScriptLanguage;
+import org.sonar.plugins.javascript.api.JavaScriptCheck;
+import org.sonar.plugins.javascript.api.tree.Tree;
+import org.sonar.plugins.javascript.api.visitors.Issue;
+import org.sonar.plugins.javascript.api.visitors.LineIssue;
+import org.sonar.plugins.javascript.api.visitors.PreciseIssue;
+import org.sonar.plugins.javascript.api.visitors.TreeVisitorContext;
+
+import de.example.custom.javascript.checks.CheckList;
+
+public class CustomRulesDefinitionTest {
+
+       @Test
+       public void whenCreatingCustomJavaRulesDefinitionThenGenerateRulesDefinition() {
+               RulesDefinition.Context context = new RulesDefinition.Context();
+               CustomRulesDefinition rulesDefinition = new CustomRulesDefinition();
+               
+               rulesDefinition.define(context);
+               
+               RulesDefinition.Repository repository = context.repository(CheckList.REPOSITORY_KEY);
+           assertThat(repository.name(), is(CheckList.REPOSITORY_NAME));
+           assertThat(repository.language(), is(JavaScriptLanguage.KEY));
+           assertThat(repository.rules().size(), is(CheckList.getChecks().size()));
+       }
+
+       @Test(expected=IllegalArgumentException.class)
+       public void shouldThrowIllegalArgumentExceptionWhenNoRuleAnnotationIsFound() {
+           RulesDefinition.Context context = new RulesDefinition.Context();
+           RulesDefinition.NewRepository newRepository = context.createRepository(CheckList.REPOSITORY_KEY, CheckList.REPOSITORY_NAME);
+           CustomRulesDefinition rulesDefinition = new CustomRulesDefinition();
+           
+           rulesDefinition.newRule(CheckWithNoAnnotation.class, newRepository);
+       }
+       
+       @Test(expected=IllegalArgumentException.class)
+       public void shouldThrowIllegalArgumentExceptionWhenNoKeyIsFoundInRuleAnnotation() {
+           RulesDefinition.Context context = new RulesDefinition.Context();
+           RulesDefinition.NewRepository newRepository = context.createRepository(CheckList.REPOSITORY_KEY, CheckList.REPOSITORY_NAME);
+           CustomRulesDefinition rulesDefinition = new CustomRulesDefinition();
+           
+           rulesDefinition.newRule(EmptyRuleKey.class, newRepository);
+       }
+       
+       @Test(expected=IllegalStateException.class)
+       public void shouldThrowIllegalStateExceptionWhenNoKeyIsFoundInRuleAnnotation() {
+           RulesDefinition.Context context = new RulesDefinition.Context();
+           RulesDefinition.NewRepository newRepository = context.createRepository(CheckList.REPOSITORY_KEY, CheckList.REPOSITORY_NAME);
+           newRepository.createRule("myCardinality");
+           newRepository.createRule("correctRule");
+           CustomRulesDefinition rulesDefinition = new CustomRulesDefinition();
+           
+           rulesDefinition.newRule(UnregisteredRule.class, newRepository);
+       }
+         
+       private class CheckWithNoAnnotation implements JavaScriptCheck {
+
+               @Override
+               public <T extends Issue> T addIssue(T arg0) {
+                       return null;
+               }
+
+               @Override
+               public PreciseIssue addIssue(Tree arg0, String arg1) {
+                       return null;
+               }
+
+               @Override
+               public LineIssue addLineIssue(Tree arg0, String arg1) {
+                       return null;
+               }
+
+               @Override
+               public List<Issue> scanFile(TreeVisitorContext arg0) {
+                       return null;
+               }
+       }
+
+       @Rule(key = "")
+       private class EmptyRuleKey implements JavaScriptCheck {
+
+               @Override
+               public <T extends Issue> T addIssue(T arg0) {
+                       return null;
+               }
+
+               @Override
+               public PreciseIssue addIssue(Tree arg0, String arg1) {
+                       return null;
+               }
+
+               @Override
+               public LineIssue addLineIssue(Tree arg0, String arg1) {
+                       return null;
+               }
+
+               @Override
+               public List<Issue> scanFile(TreeVisitorContext arg0) {
+                       return null;
+               }
+       }
+
+       @Rule(key = "myKey")
+       private class UnregisteredRule implements JavaScriptCheck {
+
+               @Override
+               public <T extends Issue> T addIssue(T arg0) {
+                       return null;
+               }
+
+               @Override
+               public PreciseIssue addIssue(Tree arg0, String arg1) {
+                       return null;
+               }
+
+               @Override
+               public LineIssue addLineIssue(Tree arg0, String arg1) {
+                       return null;
+               }
+
+               @Override
+               public List<Issue> scanFile(TreeVisitorContext arg0) {
+                       return null;
+               }
+       }
+
+       @Rule(key = "correctRule")
+       private class CorrectRule implements JavaScriptCheck {
+
+               @Override
+               public <T extends Issue> T addIssue(T arg0) {
+                       return null;
+               }
+
+               @Override
+               public PreciseIssue addIssue(Tree arg0, String arg1) {
+                       return null;
+               }
+
+               @Override
+               public LineIssue addLineIssue(Tree arg0, String arg1) {
+                       return null;
+               }
+
+               @Override
+               public List<Issue> scanFile(TreeVisitorContext arg0) {
+                       return null;
+               }
+       }
+}