Browse Source

SONAR-16610 added example plugin to test education topics in SonarQube

tags/9.6.0.59041
Lukasz Jarocki 1 year ago
parent
commit
b65c752c9a
20 changed files with 972 additions and 0 deletions
  1. 43
    0
      plugins/sonar-education-plugin/build.gradle
  2. 42
    0
      plugins/sonar-education-plugin/src/main/java/org/sonar/education/EducationBuiltInQualityProfileDefinition.java
  3. 40
    0
      plugins/sonar-education-plugin/src/main/java/org/sonar/education/EducationLanguage.java
  4. 41
    0
      plugins/sonar-education-plugin/src/main/java/org/sonar/education/EducationPlugin.java
  5. 149
    0
      plugins/sonar-education-plugin/src/main/java/org/sonar/education/EducationRulesDefinition.java
  6. 32
    0
      plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationPrinciplesSensor.java
  7. 97
    0
      plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationRuleSensor.java
  8. 32
    0
      plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationWithContextsSensor.java
  9. 39
    0
      plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationWithDetectedContextSensor.java
  10. 32
    0
      plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationWithSingleContextSensor.java
  11. 41
    0
      plugins/sonar-education-plugin/src/test/java/org/sonar/education/EducationBuiltInQualityProfileDefinitionTest.java
  12. 50
    0
      plugins/sonar-education-plugin/src/test/java/org/sonar/education/EducationLanguageTest.java
  13. 45
    0
      plugins/sonar-education-plugin/src/test/java/org/sonar/education/EducationPluginTest.java
  14. 45
    0
      plugins/sonar-education-plugin/src/test/java/org/sonar/education/EducationRulesDefinitionTest.java
  15. 47
    0
      plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationPrinciplesSensorTest.java
  16. 55
    0
      plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationSensorTest.java
  17. 47
    0
      plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationWithContextsSensorTest.java
  18. 47
    0
      plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationWithDetectedContextSensorTest.java
  19. 47
    0
      plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationWithSingleContextSensorTest.java
  20. 1
    0
      settings.gradle

+ 43
- 0
plugins/sonar-education-plugin/build.gradle View File

@@ -0,0 +1,43 @@
configurations {
testImplementation.extendsFrom(compileOnly)
}

dependencies {
compileOnly 'org.sonarsource.api.plugin:sonar-plugin-api'

testCompile 'junit:junit'
testCompile 'org.assertj:assertj-core'
testCompile 'org.mockito:mockito-core'
testCompile project(':sonar-plugin-api-impl')
}

jar {
manifest {
attributes(
'Plugin-Key': 'education',
'Plugin-Version': project.version,
'Plugin-Class': 'org.sonar.education.EducationPlugin',
'Plugin-ChildFirstClassLoader': 'false',
'Sonar-Version': project.version,
'SonarLint-Supported': 'true',
'Plugin-Name': 'Education'
)
}
into('META-INF/lib') {
from configurations.compileClasspath
}
}

artifactoryPublish.skip = false

publishing {
publications {
mavenJava(MavenPublication) {
from components.java
if (release) {
artifact sourcesJar
artifact javadocJar
}
}
}
}

+ 42
- 0
plugins/sonar-education-plugin/src/main/java/org/sonar/education/EducationBuiltInQualityProfileDefinition.java View File

@@ -0,0 +1,42 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education;

import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;

import static org.sonar.education.EducationRulesDefinition.EDUCATION_KEY;
import static org.sonar.education.EducationRulesDefinition.EDUCATION_RULE_REPOSITORY_KEY;
import static org.sonar.education.sensors.EducationPrinciplesSensor.EDUCATION_WITH_GENERIC_CONCEPTS_RULE_KEY;
import static org.sonar.education.sensors.EducationWithContextsSensor.EDUCATION_WITH_CONTEXTS_RULE_KEY;
import static org.sonar.education.sensors.EducationWithDetectedContextSensor.EDUCATION_WITH_DETECTED_CONTEXT_RULE_KEY;
import static org.sonar.education.sensors.EducationWithSingleContextSensor.EDUCATION_WITH_SINGLE_CONTEXT_RULE_KEY;

public class EducationBuiltInQualityProfileDefinition implements BuiltInQualityProfilesDefinition {
@Override
public void define(Context context) {
NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile("Built in QP for Education", EDUCATION_KEY);
profile.setDefault(true);
profile.activateRule(EDUCATION_RULE_REPOSITORY_KEY, EDUCATION_WITH_GENERIC_CONCEPTS_RULE_KEY);
profile.activateRule(EDUCATION_RULE_REPOSITORY_KEY, EDUCATION_WITH_SINGLE_CONTEXT_RULE_KEY);
profile.activateRule(EDUCATION_RULE_REPOSITORY_KEY, EDUCATION_WITH_CONTEXTS_RULE_KEY);
profile.activateRule(EDUCATION_RULE_REPOSITORY_KEY, EDUCATION_WITH_DETECTED_CONTEXT_RULE_KEY);
profile.done();
}
}

+ 40
- 0
plugins/sonar-education-plugin/src/main/java/org/sonar/education/EducationLanguage.java View File

@@ -0,0 +1,40 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education;

import org.sonar.api.resources.Language;

public class EducationLanguage implements Language {

@Override
public String getKey() {
return EducationRulesDefinition.EDUCATION_KEY;
}

@Override
public String getName() {
return "Education";
}

@Override
public String[] getFileSuffixes() {
return new String[]{".edu"};
}
}

+ 41
- 0
plugins/sonar-education-plugin/src/main/java/org/sonar/education/EducationPlugin.java View File

@@ -0,0 +1,41 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education;

import org.sonar.education.sensors.EducationWithContextsSensor;
import org.sonar.education.sensors.EducationWithDetectedContextSensor;
import org.sonar.education.sensors.EducationPrinciplesSensor;
import org.sonar.education.sensors.EducationWithSingleContextSensor;
import org.sonar.api.Plugin;

public class EducationPlugin implements Plugin {
@Override
public void define(Context context) {
context.addExtensions(
EducationRulesDefinition.class,
EducationLanguage.class,
EducationWithContextsSensor.class,
EducationWithDetectedContextSensor.class,
EducationPrinciplesSensor.class,
EducationWithSingleContextSensor.class,
EducationBuiltInQualityProfileDefinition.class);

}
}

+ 149
- 0
plugins/sonar-education-plugin/src/main/java/org/sonar/education/EducationRulesDefinition.java View File

@@ -0,0 +1,149 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education;

import org.sonar.api.server.rule.RuleDescriptionSection;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.education.sensors.EducationPrinciplesSensor;
import org.sonar.education.sensors.EducationWithContextsSensor;
import org.sonar.education.sensors.EducationWithDetectedContextSensor;

import static org.sonar.education.sensors.EducationWithSingleContextSensor.EDUCATION_WITH_SINGLE_CONTEXT_RULE_KEY;
import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ASSESS_THE_PROBLEM_SECTION_KEY;
import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.HOW_TO_FIX_SECTION_KEY;
import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.INTRODUCTION_SECTION_KEY;
import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.RESOURCES_SECTION_KEY;
import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ROOT_CAUSE_SECTION_KEY;

public class EducationRulesDefinition implements RulesDefinition {

public static final String EDUCATION_RULE_REPOSITORY_KEY = "edu";
public static final String EDUCATION_KEY = "education";

private static final String IGNORED_FAKE_SECTION = "fake_section_to_be_ignored";

public static final String[] CONTEXTS = {"spring", "hibernate", "apache-commons", "vaadin", "mybatis"};

private static final String HTML_LOREM_IPSUM = "<a href=\"https://google.com\">Lorem</a> ipsum dolor sit amet, consectetur adipiscing " +
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
"laboris nisi ut aliquip ex ea commodo consequat.<br />Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
"fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";

@Override
public void define(Context context) {
NewRepository repo = context.createRepository(EDUCATION_RULE_REPOSITORY_KEY, EDUCATION_KEY);

createRuleWithDescriptionSectionsAndEducationPrinciples(repo);
createRuleWithDescriptionSectionsAndSingleContext(repo);
createRuleWithDescriptionSectionsAndMultipleContexts(repo);
createRuleWithDescriptionSectionsAndMultipleContextsIncludingOneDetected(repo);

repo.done();
}

private void createRuleWithDescriptionSectionsAndEducationPrinciples(NewRepository repo) {
String[] educationPrinciples = {"defense_in_depth", "least_trust_principle"};
String ruleKey = EducationPrinciplesSensor.EDUCATION_WITH_GENERIC_CONCEPTS_RULE_KEY;
NewRule ruleWithSingleContext = repo.createRule(ruleKey).setName("Rule with description sections and education principles")
.addTags(EDUCATION_KEY);

ruleWithSingleContext
.setHtmlDescription(String.format("This rule contains description sections. To trigger an issue using this rule you need to " +
"scan any text file with a line containing %s key word. This rule also contains 2 education principles - %s and %s",
ruleKey, educationPrinciples[0], educationPrinciples[1]))
.addEducationPrincipleKeys(educationPrinciples);

addNonContextualizedDescriptionSections(ruleWithSingleContext);
descriptionSection(HOW_TO_FIX_SECTION_KEY);
}

private void createRuleWithDescriptionSectionsAndSingleContext(NewRepository repo) {
String ruleKey = EDUCATION_WITH_SINGLE_CONTEXT_RULE_KEY;
NewRule ruleWithSingleContext = repo.createRule(ruleKey).setName("Rule with description sections and single " +
"contexts for 'how to fix'")
.addTags(EDUCATION_KEY);

ruleWithSingleContext
.setHtmlDescription(String.format("This rule contains description sections and single context for 'how to fix' section. To " +
"trigger an issue using this rule you need to scan any text file with a line containing %s key word.", ruleKey));

addNonContextualizedDescriptionSections(ruleWithSingleContext);

ruleWithSingleContext.addDescriptionSection(descriptionHowToFixSectionWithContext(CONTEXTS[0]));
}

private void createRuleWithDescriptionSectionsAndMultipleContexts(NewRepository repo) {
NewRule ruleWithMultipleContexts = repo.createRule(EducationWithContextsSensor.EDUCATION_WITH_CONTEXTS_RULE_KEY)
.setName("Rule with description sections and multiple contexts for 'how to fix'")
.addTags(EDUCATION_KEY);

ruleWithMultipleContexts
.setHtmlDescription(String.format("This rule contains description sections and multiple contexts for 'how to fix' section. To trigger " +
"an issue using this rule you need to scan any text file with a line containing %s keyword.",
EducationWithContextsSensor.EDUCATION_WITH_CONTEXTS_RULE_KEY));

addNonContextualizedDescriptionSections(ruleWithMultipleContexts);

for (String context : CONTEXTS) {
ruleWithMultipleContexts.addDescriptionSection(descriptionHowToFixSectionWithContext(context));
}
}

private void createRuleWithDescriptionSectionsAndMultipleContextsIncludingOneDetected(NewRepository repo) {
NewRule ruleWithMultipleContexts = repo.createRule(EducationWithDetectedContextSensor.EDUCATION_WITH_DETECTED_CONTEXT_RULE_KEY)
.setName("Rule with description sections and multiple contexts (including one detected) for 'how to fix'")
.addTags(EDUCATION_KEY);

ruleWithMultipleContexts
.setHtmlDescription(String.format("This rule contains description sections and multiple contexts (including one detected) for " +
"'how to fix' section. To trigger an issue using this rule you need to scan any text file with a line containing %s keyword.",
EducationWithDetectedContextSensor.EDUCATION_WITH_DETECTED_CONTEXT_RULE_KEY));

addNonContextualizedDescriptionSections(ruleWithMultipleContexts);

for (String context : CONTEXTS) {
ruleWithMultipleContexts.addDescriptionSection(descriptionHowToFixSectionWithContext(context));
}
}

private static void addNonContextualizedDescriptionSections(NewRule newRule) {
newRule.addDescriptionSection(descriptionSection(INTRODUCTION_SECTION_KEY))
.addDescriptionSection(descriptionSection(ROOT_CAUSE_SECTION_KEY))
.addDescriptionSection(descriptionSection(ASSESS_THE_PROBLEM_SECTION_KEY))
.addDescriptionSection(descriptionSection(RESOURCES_SECTION_KEY))
.addDescriptionSection(descriptionSection(IGNORED_FAKE_SECTION));
}

private static RuleDescriptionSection descriptionHowToFixSectionWithContext(String context) {
var ruleContext = new org.sonar.api.server.rule.Context(context, context);
return RuleDescriptionSection.builder()
.sectionKey(HOW_TO_FIX_SECTION_KEY)
.context(ruleContext)
.htmlContent(String.format("%s: %s", HOW_TO_FIX_SECTION_KEY, HTML_LOREM_IPSUM))
.build();
}

private static RuleDescriptionSection descriptionSection(String sectionKey) {
return RuleDescriptionSection.builder()
.sectionKey(sectionKey)
.htmlContent(String.format("%s: %s", sectionKey, HTML_LOREM_IPSUM))
.build();
}
}

+ 32
- 0
plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationPrinciplesSensor.java View File

@@ -0,0 +1,32 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.rule.ActiveRules;

public class EducationPrinciplesSensor extends EducationRuleSensor {

public static final String EDUCATION_WITH_GENERIC_CONCEPTS_RULE_KEY = "EDUCATION";

public EducationPrinciplesSensor(FileSystem fs, ActiveRules activeRules) {
super(fs, activeRules, EDUCATION_WITH_GENERIC_CONCEPTS_RULE_KEY);
}
}

+ 97
- 0
plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationRuleSensor.java View File

@@ -0,0 +1,97 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.rule.RuleKey;

import static org.sonar.education.EducationRulesDefinition.EDUCATION_KEY;
import static org.sonar.education.EducationRulesDefinition.EDUCATION_RULE_REPOSITORY_KEY;

public abstract class EducationRuleSensor implements Sensor {

private final FileSystem fs;
private final ActiveRules activeRules;
private final String ruleKeyName;
private final String tag;

EducationRuleSensor(FileSystem fs, ActiveRules activeRules, String ruleKey) {
this.fs = fs;
this.activeRules = activeRules;
this.ruleKeyName = ruleKey;
this.tag = ruleKey;
}

@Override
public void describe(SensorDescriptor descriptor) {
descriptor
.name("Education sensor for " + tag)
.createIssuesForRuleRepository(EDUCATION_RULE_REPOSITORY_KEY);
}

@Override
public void execute(SensorContext context) {
RuleKey ruleKey = RuleKey.of(EDUCATION_RULE_REPOSITORY_KEY, ruleKeyName);
if (activeRules.find(ruleKey) == null) {
return;
}
for (InputFile inputFile : fs.inputFiles(fs.predicates().hasLanguage(EDUCATION_KEY))) {
processFile(inputFile, context, ruleKey);
}
}

protected String getDetectedContext() {
return null;
}

protected void processFile(InputFile inputFile, SensorContext context, RuleKey ruleKey) {
try {
int[] lineCounter = {1};
try (InputStreamReader isr = new InputStreamReader(inputFile.inputStream(), inputFile.charset());
BufferedReader reader = new BufferedReader(isr)) {
reader.lines().forEachOrdered(lineStr -> {
int startIndex = -1;
while ((startIndex = lineStr.indexOf(tag, startIndex + 1)) != -1) {
NewIssue newIssue = context.newIssue();
newIssue
.forRule(ruleKey)
.at(newIssue.newLocation()
.on(inputFile)
.at(inputFile.newRange(lineCounter[0], startIndex, lineCounter[0], startIndex + tag.length())))
.setRuleDescriptionContextKey(getDetectedContext())
.save();
}
lineCounter[0]++;
});
}
} catch (IOException e) {
throw new IllegalStateException("Fail to process " + inputFile, e);
}
}
}

+ 32
- 0
plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationWithContextsSensor.java View File

@@ -0,0 +1,32 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.rule.ActiveRules;

public class EducationWithContextsSensor extends EducationRuleSensor {

public static final String EDUCATION_WITH_CONTEXTS_RULE_KEY = "CONTEXTS";

public EducationWithContextsSensor(FileSystem fs, ActiveRules activeRules) {
super(fs, activeRules, EDUCATION_WITH_CONTEXTS_RULE_KEY);
}
}

+ 39
- 0
plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationWithDetectedContextSensor.java View File

@@ -0,0 +1,39 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.rule.ActiveRules;

import static org.sonar.education.EducationRulesDefinition.CONTEXTS;

public class EducationWithDetectedContextSensor extends EducationRuleSensor {

public static final String EDUCATION_WITH_DETECTED_CONTEXT_RULE_KEY = "DETECTED_CONTEXT";

public EducationWithDetectedContextSensor(FileSystem fs, ActiveRules activeRules) {
super(fs, activeRules, EDUCATION_WITH_DETECTED_CONTEXT_RULE_KEY);
}

@Override
protected String getDetectedContext() {
return CONTEXTS[0];
}
}

+ 32
- 0
plugins/sonar-education-plugin/src/main/java/org/sonar/education/sensors/EducationWithSingleContextSensor.java View File

@@ -0,0 +1,32 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.rule.ActiveRules;

public class EducationWithSingleContextSensor extends EducationRuleSensor {

public static final String EDUCATION_WITH_SINGLE_CONTEXT_RULE_KEY = "SINGLE_CONTEXT";

public EducationWithSingleContextSensor(FileSystem fs, ActiveRules activeRules) {
super(fs, activeRules, EDUCATION_WITH_SINGLE_CONTEXT_RULE_KEY);
}
}

+ 41
- 0
plugins/sonar-education-plugin/src/test/java/org/sonar/education/EducationBuiltInQualityProfileDefinitionTest.java View File

@@ -0,0 +1,41 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education;

import org.junit.Test;
import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;

import static org.assertj.core.api.Assertions.assertThat;

public class EducationBuiltInQualityProfileDefinitionTest {

private final EducationBuiltInQualityProfileDefinition underTest = new EducationBuiltInQualityProfileDefinition();

@Test
public void define_definesAtLeast4rules() {
BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();

underTest.define(context);

BuiltInQualityProfilesDefinition.BuiltInQualityProfile profile = context.profile("education", "Built in QP for Education");
assertThat(profile.isDefault()).isTrue();
assertThat(profile.rules()).hasSizeGreaterThanOrEqualTo(4);
}
}

+ 50
- 0
plugins/sonar-education-plugin/src/test/java/org/sonar/education/EducationLanguageTest.java View File

@@ -0,0 +1,50 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education;

import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class EducationLanguageTest {

private final EducationLanguage underTest = new EducationLanguage();

@Test
public void getFileSuffixes_notEmpty() {
String[] fileSuffixes = underTest.getFileSuffixes();

assertThat(fileSuffixes).isNotEmpty();
}

@Test
public void getName_notEmpty() {
String name = underTest.getName();

assertThat(name).isNotEmpty();
}

@Test
public void getKey_notEmpty() {
String key = underTest.getKey();

assertThat(key).isNotEmpty();
}
}

+ 45
- 0
plugins/sonar-education-plugin/src/test/java/org/sonar/education/EducationPluginTest.java View File

@@ -0,0 +1,45 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education;

import org.junit.Test;
import org.sonar.api.Plugin;
import org.sonar.api.SonarEdition;
import org.sonar.api.SonarQubeSide;
import org.sonar.api.SonarRuntime;
import org.sonar.api.internal.PluginContextImpl;
import org.sonar.api.internal.SonarRuntimeImpl;
import org.sonar.api.utils.Version;

import static org.assertj.core.api.Assertions.assertThat;

public class EducationPluginTest {

@Test
public void define_addSomeExtensionsForSonarQube() {
SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("9.5"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY);
Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build();
EducationPlugin plugin = new EducationPlugin();

plugin.define(context);

assertThat(context.getExtensions()).isNotEmpty();
}
}

+ 45
- 0
plugins/sonar-education-plugin/src/test/java/org/sonar/education/EducationRulesDefinitionTest.java View File

@@ -0,0 +1,45 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education;

import java.util.List;
import org.junit.Test;
import org.sonar.api.server.rule.RulesDefinition;

import static org.assertj.core.api.Assertions.assertThat;

public class EducationRulesDefinitionTest {

@Test
public void define_addsRuleDefinitions() {
EducationRulesDefinition educationRulesDefinition = new EducationRulesDefinition();

RulesDefinition.Context context = new RulesDefinition.Context();

educationRulesDefinition.define(context);

List<RulesDefinition.Repository> repositories = context.repositories();
assertThat(repositories).hasSize(1);

RulesDefinition.Repository repository = context.repositories().get(0);
List<RulesDefinition.Rule> rules = repository.rules();
assertThat(rules).hasSizeGreaterThanOrEqualTo(4);
}
}

+ 47
- 0
plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationPrinciplesSensorTest.java View File

@@ -0,0 +1,47 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import java.io.IOException;
import org.junit.Test;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.internal.SensorContextTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.education.sensors.EducationPrinciplesSensor.EDUCATION_WITH_GENERIC_CONCEPTS_RULE_KEY;

public class EducationPrinciplesSensorTest extends EducationSensorTest {

@Test
public void processFile_givenCorrectTagPassed_oneSecurityHotspotWithContextsIsRaised() throws IOException {
DefaultInputFile inputFile = newTestFile(EDUCATION_WITH_GENERIC_CONCEPTS_RULE_KEY);

DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
fs.add(inputFile);

SensorContextTester sensorContextTester = SensorContextTester.create(temp.newFolder().toPath());
var sensor = new EducationPrinciplesSensor(fs, activeRules);

sensor.execute(sensorContextTester);

assertThat(sensorContextTester.allIssues()).hasSize(1);
}
}

+ 55
- 0
plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationSensorTest.java View File

@@ -0,0 +1,55 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import java.nio.charset.Charset;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.rule.ActiveRule;
import org.sonar.api.batch.rule.ActiveRules;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.education.EducationRulesDefinition.EDUCATION_KEY;

public class EducationSensorTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();

protected final ActiveRules activeRules = mock(ActiveRules.class);

@Before
public void before() {
when(activeRules.find(any())).thenReturn(mock(ActiveRule.class));
}

protected DefaultInputFile newTestFile(String content) {
return new TestInputFileBuilder("foo", "hello.edu")
.setLanguage(EDUCATION_KEY)
.setContents(content)
.setCharset(Charset.defaultCharset())
.build();
}
}

+ 47
- 0
plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationWithContextsSensorTest.java View File

@@ -0,0 +1,47 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import java.io.IOException;
import org.junit.Test;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.internal.SensorContextTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.education.sensors.EducationWithContextsSensor.EDUCATION_WITH_CONTEXTS_RULE_KEY;

public class EducationWithContextsSensorTest extends EducationSensorTest {

@Test
public void processFile_givenCorrectTagPassed_oneSecurityHotspotWithContextsIsRaised() throws IOException {
DefaultInputFile inputFile = newTestFile(EDUCATION_WITH_CONTEXTS_RULE_KEY);

DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
fs.add(inputFile);

SensorContextTester sensorContextTester = SensorContextTester.create(temp.newFolder().toPath());
var sensor = new EducationWithContextsSensor(fs, activeRules);

sensor.execute(sensorContextTester);

assertThat(sensorContextTester.allIssues()).hasSize(1);
}
}

+ 47
- 0
plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationWithDetectedContextSensorTest.java View File

@@ -0,0 +1,47 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import java.io.IOException;
import org.junit.Test;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.internal.SensorContextTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.education.sensors.EducationWithDetectedContextSensor.EDUCATION_WITH_DETECTED_CONTEXT_RULE_KEY;

public class EducationWithDetectedContextSensorTest extends EducationSensorTest {

@Test
public void processFile_givenCorrectTagPassed_oneSecurityHotspotWithContextsIsRaised() throws IOException {
DefaultInputFile inputFile = newTestFile(EDUCATION_WITH_DETECTED_CONTEXT_RULE_KEY);

DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
fs.add(inputFile);

SensorContextTester sensorContextTester = SensorContextTester.create(temp.newFolder().toPath());
var sensor = new EducationWithDetectedContextSensor(fs, activeRules);

sensor.execute(sensorContextTester);

assertThat(sensorContextTester.allIssues()).hasSize(1);
}
}

+ 47
- 0
plugins/sonar-education-plugin/src/test/java/org/sonar/education/sensors/EducationWithSingleContextSensorTest.java View File

@@ -0,0 +1,47 @@
/*
* SonarQube
* Copyright (C) 2009-2022 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.education.sensors;

import java.io.IOException;
import org.junit.Test;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.internal.SensorContextTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.education.sensors.EducationWithSingleContextSensor.EDUCATION_WITH_SINGLE_CONTEXT_RULE_KEY;

public class EducationWithSingleContextSensorTest extends EducationSensorTest {

@Test
public void processFile_givenCorrectTagPassed_oneSecurityHotspotWithContextsIsRaised() throws IOException {
DefaultInputFile inputFile = newTestFile(EDUCATION_WITH_SINGLE_CONTEXT_RULE_KEY);

DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
fs.add(inputFile);

SensorContextTester sensorContextTester = SensorContextTester.create(temp.newFolder().toPath());
var sensor = new EducationWithSingleContextSensor(fs, activeRules);

sensor.execute(sensorContextTester);

assertThat(sensorContextTester.allIssues()).hasSize(1);
}
}

+ 1
- 0
settings.gradle View File

@@ -13,6 +13,7 @@ pluginManagement {
rootProject.name = 'sonarqube'

include 'plugins:sonar-xoo-plugin'
include 'plugins:sonar-education-plugin'

include 'server:sonar-auth-common'
include 'server:sonar-auth-bitbucket'

Loading…
Cancel
Save