Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ protected void logStart(int numThreads) {
protected void scanFile(PythonInputFile inputFile) throws IOException {
var pythonFile = SonarQubePythonFile.create(inputFile);
InputFile.Type fileType = inputFile.wrappedFile().type();
PythonVisitorContext visitorContext = createVisitorContext(inputFile, pythonFile);
PythonVisitorContext visitorContext = createVisitorContext(inputFile, pythonFile, projectRelativePath(inputFile));
InputFile.Type effectiveTypeForRules = resolveEffectiveTypeForRules(
fileType, projectRelativePath(inputFile), visitorContext.rootTree());
fileType, visitorContext.isLikelyTestFile());
if (!testSourcesConfigured && fileType == InputFile.Type.MAIN) {
indexer.writeEffectiveFileType(inputFile.wrappedFile().key(), effectiveTypeForRules);
}
Expand Down Expand Up @@ -189,7 +189,7 @@ protected void scanFile(PythonInputFile inputFile) throws IOException {
searchForDataBricks(visitorContext);
}

private PythonVisitorContext createVisitorContext(PythonInputFile inputFile, PythonFile pythonFile) throws IOException {
private PythonVisitorContext createVisitorContext(PythonInputFile inputFile, PythonFile pythonFile, String testFilePath) throws IOException {
PythonVisitorContext visitorContext;
try {
AstNode astNode = parserSupplier.get().parse(inputFile.contents());
Expand All @@ -203,10 +203,11 @@ private PythonVisitorContext createVisitorContext(PythonInputFile inputFile, Pyt
.typeTable(indexer.projectLevelTypeTable())
.cacheContext(indexer.cacheContext())
.sonarProduct(context.runtime().getProduct())
.testFilePath(testFilePath)
.build();

} catch (RecognitionException e) {
visitorContext = new PythonVisitorContext(pythonFile, e, context.runtime().getProduct());
visitorContext = new PythonVisitorContext(pythonFile, e, context.runtime().getProduct(), testFilePath);

var line = (inputFile.kind() == PythonInputFile.Kind.IPYTHON) ?
((GeneratedIPythonFile) inputFile).locationMap().get(e.getLine()).line() : e.getLine();
Expand Down Expand Up @@ -373,12 +374,11 @@ private boolean isBypassed(InputFile.Type platformType) {
return testSourcesConfigured || platformType == InputFile.Type.TEST;
}

private InputFile.Type resolveEffectiveTypeForRules(InputFile.Type platformType, String filePath, @Nullable FileInput tree) {
private InputFile.Type resolveEffectiveTypeForRules(InputFile.Type platformType, boolean likelyTestFile) {
if (isBypassed(platformType)) {
return platformType;
}
boolean isTest = TestFileClassifier.looksLikeTestFile(filePath, tree);
if (isTest) {
if (likelyTestFile) {
maybeEmitHeuristicWarning();
return InputFile.Type.TEST;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.File;
import java.io.IOException;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.plugins.python.api.IssueLocation;
Expand All @@ -32,6 +33,19 @@ class IpynbNotebookParserScannerTest {

private final File baseDir = new File("src/test/resources/org/sonar/plugins/python");

@Test
void generated_notebook_python_uses_the_test_file_classifier() throws IOException {
var inputFile = createInputFile(baseDir, "notebook_trailing_whitespace.ipynb", InputFile.Status.CHANGED, InputFile.Type.MAIN);
var notebook = IpynbNotebookParser.parseNotebook(inputFile).get();
var generatedFile = new GeneratedIPythonFile(notebook.wrappedFile(), "import pytest\n", Map.of());
var context = new PythonVisitorContext.Builder(
TestPythonVisitorRunner.parseNotebookFile(Map.of(), "import pytest\n"),
SonarQubePythonFile.create(generatedFile))
.build();

assertThat(context.isLikelyTestFile()).isTrue();
}

@Test
void trailing_whitespace() throws IOException {
var inputFile = createInputFile(baseDir, "notebook_trailing_whitespace.ipynb", InputFile.Status.CHANGED, InputFile.Type.MAIN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class PythonSensorTest {
private static final String FILE_USING_TYPESHED = "uses_typeshed.py";
private static final String FILE_QUICKFIX = "file_quickfix.py";
private static final String FILE_TEST_FILE = "test_file.py";
private static final String FILE_FRAMEWORK_HELPER = "framework_helper.py";
private static final String FILE_INVALID_SYNTAX = "invalid_syntax.py";
private static final String FILE_NO_SONAR_PY = "no_sonar.py";
private static final String ONE_STATEMENT_PER_LINE_RULE_KEY = "OneStatementPerLine";
Expand Down Expand Up @@ -650,6 +651,21 @@ void test_auto_reclassify_filename_heuristic_suppresses_main_rules() {
verify(analysisWarning).addUnique(PythonScanner.UNSET_SONAR_TESTS_WARNING);
}

@Test
void test_auto_reclassify_framework_import_suppresses_main_rules() {
activeRules = new ActiveRulesBuilder()
.addRule(new NewActiveRule.Builder()
.setRuleKey(RuleKey.of(PythonRuleRepository.REPOSITORY_KEY, "S1226"))
.build())
.build();

inputFile(FILE_FRAMEWORK_HELPER, Type.MAIN);
sensor().execute(context);

assertThat(context.allIssues()).isEmpty();
verify(analysisWarning).addUnique(PythonScanner.UNSET_SONAR_TESTS_WARNING);
}

@ParameterizedTest
@CsvSource({
"sonar.tests, tests",
Expand Down
Loading