Skip to content

Commit

Permalink
scanSingleInputFile
Browse files Browse the repository at this point in the history
  • Loading branch information
guwirth committed May 14, 2021
1 parent 37479e1 commit 1afeeb1
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@

public class CxxFileTesterHelper {

private CxxFileTesterHelper() {
// utility class
}

public static CxxFileTester create(String fileName, String basePath)
throws UnsupportedEncodingException, IOException {
return create(fileName, basePath, Charset.defaultCharset());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@
package org.sonar.cxx.postjobs;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.input.BOMInputStream;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.postjob.PostJobContext;
import org.sonar.api.batch.sensor.internal.SensorContextTester;
Expand All @@ -46,15 +53,15 @@ public void scanFile() {
}

@Test
public void finalReportTest() {
public void finalReportTest() throws IOException {
var dir = "src/test/resources/org/sonar/cxx/postjobs";
var context = SensorContextTester.create(new File(dir));
InputFile inputFile = TestInputFileBuilder.create("", dir + "/syntaxerror.cc").build();
InputFile inputFile = createInputFile(dir + "/syntaxerror.cc", ".", Charset.defaultCharset());
context.fileSystem().add(inputFile);

CxxParseErrorLoggerVisitor.resetReport();
CxxPreprocessor.resetReport();
CxxAstScanner.scanSingleFile(new File(inputFile.uri().getPath()));
CxxAstScanner.scanSingleInputFile(inputFile);

var postjob = new FinalReport();
postjob.execute(postJobContext);
Expand All @@ -65,4 +72,29 @@ public void finalReportTest() {
assertThat(log.get(1)).contains("syntax error(s) detected");
}

private static DefaultInputFile createInputFile(String fileName, String basePath, Charset charset)
throws IOException {
TestInputFileBuilder fb = TestInputFileBuilder.create("", fileName);

fb.setCharset(charset);
fb.setProjectBaseDir(Paths.get(basePath));
fb.setContents(getSourceCode(Paths.get(basePath, fileName).toFile(), charset));

return fb.build();
}

private static String getSourceCode(File filename, Charset defaultCharset) throws IOException {
try ( BOMInputStream bomInputStream = new BOMInputStream(new FileInputStream(filename),
ByteOrderMark.UTF_8,
ByteOrderMark.UTF_16LE,
ByteOrderMark.UTF_16BE,
ByteOrderMark.UTF_32LE,
ByteOrderMark.UTF_32BE)) {
ByteOrderMark bom = bomInputStream.getBOM();
Charset charset = bom != null ? Charset.forName(bom.getCharsetName()) : defaultCharset;
byte[] bytes = bomInputStream.readAllBytes();
return new String(bytes, charset);
}
}

}
25 changes: 2 additions & 23 deletions cxx-squid/src/main/java/org/sonar/cxx/CxxAstScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.sonar.sslr.api.AstNode;
import com.sonar.sslr.api.GenericTokenType;
import com.sonar.sslr.api.Grammar;
import java.io.File;
import static java.lang.Math.min;
import java.util.Collection;
import org.sonar.api.batch.fs.InputFile;
Expand Down Expand Up @@ -67,15 +66,10 @@ private CxxAstScanner() {
/**
* Helper method for testing checks without having to deploy them on a Sonar instance.
*
* @param file is the file to be checked
* @param inputFile is the file to be checked
* @param visitors AST checks and visitors to use
* @return file checked with measures and issues
*/
@SafeVarargs
public static SourceFile scanSingleFile(File file, SquidAstVisitor<Grammar>... visitors) {
return scanSingleFileConfig(file, new CxxSquidConfiguration(), visitors);
}

@SafeVarargs
public static SourceFile scanSingleInputFile(InputFile inputFile, SquidAstVisitor<Grammar>... visitors) {
return scanSingleInputFileConfig(inputFile, new CxxSquidConfiguration(), visitors);
Expand All @@ -84,26 +78,11 @@ public static SourceFile scanSingleInputFile(InputFile inputFile, SquidAstVisito
/**
* Helper method for scanning a single file
*
* @param file is the file to be checked
* @param inputFile is the file to be checked
* @param squidConfig the Squid configuration
* @param visitors AST checks and visitors to use
* @return file checked with measures and issues
*/
public static SourceFile scanSingleFileConfig(File file, CxxSquidConfiguration squidConfig,
SquidAstVisitor<Grammar>... visitors) {
if (!file.isFile()) {
throw new IllegalArgumentException("File '" + file + "' not found.");
}
AstScanner<Grammar> scanner = create(squidConfig, visitors);
scanner.scanFile(file);
Collection<SourceCode> sources = scanner.getIndex().search(new QueryByType(SourceFile.class));
if (sources.size() != 1) {
throw new IllegalStateException("Only one SourceFile was expected whereas "
+ sources.size() + " has been returned.");
}
return (SourceFile) sources.iterator().next();
}

public static SourceFile scanSingleInputFileConfig(InputFile inputFile, CxxSquidConfiguration squidConfig,
SquidAstVisitor<Grammar>... visitors) {
if (!inputFile.isFile()) {
Expand Down
53 changes: 25 additions & 28 deletions cxx-squid/src/test/java/org/sonar/cxx/CxxAstScannerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
*/
package org.sonar.cxx;

import org.sonar.cxx.config.CxxSquidConfiguration;
import com.sonar.sslr.api.Grammar;
import java.io.File;
import java.io.IOException;
Expand All @@ -30,6 +29,7 @@
import org.assertj.core.api.SoftAssertions;
import org.junit.Test;
import org.sonar.cxx.api.CxxMetric;
import org.sonar.cxx.config.CxxSquidConfiguration;
import org.sonar.cxx.squidbridge.AstScanner;
import org.sonar.cxx.squidbridge.api.SourceFile;
import org.sonar.cxx.squidbridge.api.SourceProject;
Expand All @@ -40,8 +40,8 @@ public class CxxAstScannerTest {
@Test
public void files() throws UnsupportedEncodingException, IOException {

CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/trivial.cc", ".", "");
CxxFileTesterHelper.AddFileToContext(tester, "src/test/resources/metrics/trivial.cc", "");
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/trivial.cc", ".", "");
CxxFileTesterHelper.add(tester, "src/test/resources/metrics/trivial.cc", "");

AstScanner<Grammar> scanner = CxxAstScanner.create(new CxxSquidConfiguration());
scanner.scanFiles(new ArrayList<>(Arrays.asList(
Expand All @@ -55,8 +55,8 @@ public void files() throws UnsupportedEncodingException, IOException {

@Test
public void comments() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/comments.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/comments.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
var softly = new SoftAssertions();
softly.assertThat(file.getInt(CxxMetric.COMMENT_LINES)).isEqualTo(6);
softly.assertThat(file.getNoSonarTagLines()).contains(8).hasSize(1);
Expand All @@ -65,75 +65,72 @@ public void comments() throws UnsupportedEncodingException, IOException {

@Test
public void lines() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/classes.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/classes.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getInt(CxxMetric.LINES)).isEqualTo(7);
}

@Test
public void lines_of_code() throws UnsupportedEncodingException, IOException {

CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/classes.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/classes.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getInt(CxxMetric.LINES_OF_CODE)).isEqualTo(5);
}

@Test
public void statements() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/statements.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/statements.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getInt(CxxMetric.STATEMENTS)).isEqualTo(4);
}

@Test
public void functions() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/functions.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/functions.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getInt(CxxMetric.FUNCTIONS)).isEqualTo(2);
}

@Test
public void classes() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/classes.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/classes.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getInt(CxxMetric.CLASSES)).isEqualTo(2);
}

@Test
public void complexity() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/complexity.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/complexity.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getInt(CxxMetric.COMPLEXITY)).isEqualTo(14);
}

@Test
public void complexity_alternative() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester(
"src/test/resources/metrics/complexity_alternative.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/complexity_alternative.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getInt(CxxMetric.COMPLEXITY)).isEqualTo(14);
}

@Test
public void complexity_macro() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper
.CreateCxxFileTester("src/test/resources/metrics/complexity_macro.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/complexity_macro.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getInt(CxxMetric.COMPLEXITY)).isEqualTo(1);
}

@Test
public void error_recovery_declaration() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester(
"src/test/resources/parser/bad/error_recovery_declaration.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/parser/bad/error_recovery_declaration.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getInt(CxxMetric.FUNCTIONS)).isEqualTo(2);
}

@Test
public void nosonar_comments() throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester("src/test/resources/metrics/nosonar.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create("src/test/resources/metrics/nosonar.cc", ".", "");
SourceFile file = CxxAstScanner.scanSingleInputFile(tester.asInputFile());
assertThat(file.getNoSonarTagLines()).containsOnlyElementsOf(Arrays.asList(3, 6, 9, 11));
}

Expand Down
5 changes: 2 additions & 3 deletions cxx-squid/src/test/java/org/sonar/cxx/CxxFileTester.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
*/
package org.sonar.cxx;

import java.io.File;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.internal.SensorContextTester;

Expand All @@ -28,8 +27,8 @@ public class CxxFileTester {
public InputFile cxxFile;
public SensorContextTester context;

public File asFile() {
return new File(cxxFile.uri().getPath());
public InputFile asInputFile() {
return cxxFile;
}

}
63 changes: 45 additions & 18 deletions cxx-squid/src/test/java/org/sonar/cxx/CxxFileTesterHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,66 @@
package org.sonar.cxx;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.input.BOMInputStream;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.sensor.internal.SensorContextTester;

/**
*
* @author jocs
*/
public class CxxFileTesterHelper {

public static CxxFileTester CreateCxxFileTester(String fileName, String basePath, String module) throws
UnsupportedEncodingException, IOException {
CxxFileTester tester = new CxxFileTester();
tester.context = SensorContextTester.create(new File(basePath));
private CxxFileTesterHelper() {
// utility class
}

tester.context.fileSystem().add(TestInputFileBuilder.create(module, fileName).build());
tester.cxxFile = tester.context.fileSystem().inputFile(tester.context.fileSystem().predicates().hasPath(
fileName));
public static CxxFileTester create(String fileName, String basePath, String moduleKey)
throws UnsupportedEncodingException, IOException {
var tester = new CxxFileTester();

tester.context = SensorContextTester.create(new File(basePath));
tester.cxxFile = createInputFile(moduleKey, fileName, basePath, Charset.defaultCharset());
tester.context.fileSystem().add(tester.cxxFile);

return tester;
}

public static CxxFileTester AddFileToContext(CxxFileTester tester, String fileName, String module) throws
UnsupportedEncodingException, IOException {
tester.context.fileSystem().add(TestInputFileBuilder.create(module, fileName).build());
tester.cxxFile = tester.context.fileSystem().inputFile(tester.context.fileSystem().predicates().hasPath(
fileName));
public static CxxFileTester add(CxxFileTester tester, String fileName, String moduleKey)
throws UnsupportedEncodingException, IOException {

tester.cxxFile = createInputFile(moduleKey, fileName, "", Charset.defaultCharset());
tester.context.fileSystem().add(tester.cxxFile);

return tester;
}

private CxxFileTesterHelper() {
// utility class
private static DefaultInputFile createInputFile(String moduleKey, String fileName, String basePath, Charset charset)
throws IOException {
TestInputFileBuilder fb = TestInputFileBuilder.create(moduleKey, fileName);

fb.setCharset(charset);
fb.setProjectBaseDir(Paths.get(basePath));
fb.setContents(getSourceCode(Paths.get(basePath, fileName).toFile(), charset));

return fb.build();
}

private static String getSourceCode(File filename, Charset defaultCharset) throws IOException {
try ( BOMInputStream bomInputStream = new BOMInputStream(new FileInputStream(filename),
ByteOrderMark.UTF_8,
ByteOrderMark.UTF_16LE,
ByteOrderMark.UTF_16BE,
ByteOrderMark.UTF_32LE,
ByteOrderMark.UTF_32BE)) {
ByteOrderMark bom = bomInputStream.getBOM();
Charset charset = bom != null ? Charset.forName(bom.getCharsetName()) : defaultCharset;
byte[] bytes = bomInputStream.readAllBytes();
return new String(bytes, charset);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ public void to_regexp() throws UnsupportedEncodingException, IOException {
}

private int testFile(String fileName) throws UnsupportedEncodingException, IOException {
CxxFileTester tester = CxxFileTesterHelper.CreateCxxFileTester(fileName, ".", "");
SourceFile sourceFile = CxxAstScanner.scanSingleFile(tester.asFile());
var tester = CxxFileTesterHelper.create(fileName, ".", "");
SourceFile sourceFile = CxxAstScanner.scanSingleInputFile(tester.asInputFile());

return (sourceFile.getInt(CxxMetric.COGNITIVE_COMPLEXITY));
}
Expand Down
Loading

0 comments on commit 1afeeb1

Please sign in to comment.