/*
* Copyright 2014 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.errorprone;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.io.CharStreams;
import com.google.errorprone.BugPattern.Category;
import com.google.errorprone.BugPattern.SeverityLevel;
import com.google.errorprone.BugPattern.Suppressibility;
import com.google.gson.Gson;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class BugPatternFileGeneratorTest {
@Rule
public TemporaryFolder tmpfolder = new TemporaryFolder();
private Path exampleDir;
private Path wikiDir;
private Path exampleDirBase;
private Path explanationDirBase;
@Before
public void setUp() throws Exception {
wikiDir = tmpfolder.newFolder("wiki").toPath();
exampleDirBase = tmpfolder.newFolder("examples").toPath();
explanationDirBase = tmpfolder.newFolder("explanations").toPath();
exampleDir = exampleDirBase.resolve("com/google/errorprone/bugpatterns");
Files.createDirectories(exampleDir);
Files.write(exampleDir.resolve("DeadExceptionPositiveCase.java"),
Arrays.asList("here is an example"), UTF_8);
}
private static BugPatternInstance deadExceptionTestInfo() {
BugPatternInstance instance = new BugPatternInstance();
instance.className = "com.google.errorprone.bugpatterns.DeadException";
instance.name = "DeadException";
instance.summary = "Exception created but not thrown";
instance.explanation =
"The exception is created with new, but is not thrown, and the reference is lost.";
instance.altNames = new String[] {"ThrowableInstanceNeverThrown"};
instance.category = Category.JDK.toString();
instance.severity = SeverityLevel.ERROR;
instance.suppressibility = Suppressibility.SUPPRESS_WARNINGS;
instance.customSuppressionAnnotations =
new String[] {"com.google.errorprone.BugPattern.NoCustomSuppression.class"};
return instance;
}
private static final String BUGPATTERN_LINE;
static {
BugPatternInstance instance = deadExceptionTestInfo();
BUGPATTERN_LINE = new Gson().toJson(instance);
}
private static final String BUGPATTERN_LINE_SIDECAR;
static {
BugPatternInstance instance = deadExceptionTestInfo();
instance.explanation = "";
BUGPATTERN_LINE_SIDECAR = new Gson().toJson(instance);
}
// Assert that the generator produces the same output it did before.
// This is brittle, but you can open the golden file
// src/test/resources/com/google/errorprone/DeadException.md
// in the same Jekyll environment you use for prod, and verify it looks good.
@Test
public void regressionTest_frontmatter_pygments() throws Exception {
BugPatternFileGenerator generator =
new BugPatternFileGenerator(wikiDir, exampleDirBase, explanationDirBase, true, true, null);
generator.processLine(BUGPATTERN_LINE);
String expected = CharStreams.toString(new InputStreamReader(
getClass().getResourceAsStream("testdata/DeadException_frontmatter_pygments.md"), UTF_8));
String actual = CharStreams.toString(
Files.newBufferedReader(wikiDir.resolve("DeadException.md"), UTF_8));
assertThat(expected.trim()).isEqualTo(actual.trim());
}
@Test
public void regressionTest_nofrontmatter_gfm() throws Exception {
BugPatternFileGenerator generator =
new BugPatternFileGenerator(
wikiDir, exampleDirBase, explanationDirBase, false, false, null);
generator.processLine(BUGPATTERN_LINE);
String expected = CharStreams.toString(new InputStreamReader(
getClass().getResourceAsStream("testdata/DeadException_nofrontmatter_gfm.md"), UTF_8));
String actual = new String(Files.readAllBytes(wikiDir.resolve("DeadException.md")), UTF_8);
assertThat(expected.trim()).isEqualTo(actual.trim());
}
@Test
public void regressionTest_sidecar() throws Exception {
BugPatternFileGenerator generator =
new BugPatternFileGenerator(
wikiDir, exampleDirBase, explanationDirBase, false, false, null);
Files.write(
explanationDirBase.resolve("DeadException.md"),
Arrays.asList(
"The exception is created with new, but is not thrown, and the reference is lost."),
UTF_8);
generator.processLine(BUGPATTERN_LINE_SIDECAR);
String expected = CharStreams.toString(new InputStreamReader(
getClass().getResourceAsStream("testdata/DeadException_nofrontmatter_gfm.md"), UTF_8));
String actual = new String(Files.readAllBytes(wikiDir.resolve("DeadException.md")), UTF_8);
assertThat(expected.trim()).isEqualTo(actual.trim());
}
@Test
public void testEscapeAngleBracketsInSummary() throws Exception {
// Create a BugPattern with angle brackets in the summary
BugPatternInstance instance = new BugPatternInstance();
instance.className = "com.google.errorprone.bugpatterns.DontDoThis";
instance.name = "DontDoThis";
instance.summary = "Don't do this; do List<Foo> instead";
instance.explanation = "This is a bad idea, you want `List<Foo>` instead";
instance.altNames = new String[0];
instance.category = Category.ONE_OFF.toString();
instance.severity = SeverityLevel.ERROR;
instance.suppressibility = Suppressibility.SUPPRESS_WARNINGS;
instance.customSuppressionAnnotations =
new String[] {"com.google.errorprone.BugPattern.NoCustomSuppression.class"};
// Write markdown file
BugPatternFileGenerator generator =
new BugPatternFileGenerator(
wikiDir, exampleDirBase, explanationDirBase, false, false, null);
generator.processLine(new Gson().toJson(instance));
String expected =
CharStreams.toString(
new InputStreamReader(
getClass().getResourceAsStream("testdata/DontDoThis_nofrontmatter_gfm.md"), UTF_8));
String actual = new String(Files.readAllBytes(wikiDir.resolve("DontDoThis.md")), UTF_8);
assertThat(expected.trim()).isEqualTo(actual.trim());
}
}