Skip to content
This repository has been archived by the owner on Sep 22, 2022. It is now read-only.

Commit

Permalink
Issue checkstyle#4675: increase coverage of pitest-checks-misc to 100%
Browse files Browse the repository at this point in the history
  • Loading branch information
Nimfadora committed Sep 1, 2017
1 parent 1282cdf commit c68a90e
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 18 deletions.
5 changes: 3 additions & 2 deletions pom.xml
Expand Up @@ -1643,7 +1643,8 @@
<param>com.puppycrawl.tools.checkstyle.checks.FinalParametersCheck</param>
<param>com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck</param>
<param>com.puppycrawl.tools.checkstyle.checks.OuterTypeFilenameCheck</param>
<param>com.puppycrawl.tools.checkstyle.checks.SuppressWarningsHolder</param>
<!-- this class will be rewritten in future releases -->
<!--<param>com.puppycrawl.tools.checkstyle.checks.SuppressWarningsHolder</param>-->
<param>com.puppycrawl.tools.checkstyle.checks.TodoCommentCheck</param>
<param>com.puppycrawl.tools.checkstyle.checks.TrailingCommentCheck</param>
<param>com.puppycrawl.tools.checkstyle.checks.TranslationCheck</param>
Expand All @@ -1667,7 +1668,7 @@
<param>com.puppycrawl.tools.checkstyle.checks.UniquePropertiesCheckTest</param>
<param>com.puppycrawl.tools.checkstyle.checks.UpperEllCheckTest</param>
</targetTests>
<mutationThreshold>96</mutationThreshold>
<mutationThreshold>100</mutationThreshold>
<timeoutFactor>${pitest.plugin.timeout.factor}</timeoutFactor>
<timeoutConstant>${pitest.plugin.timeout.constant}</timeoutConstant>
<threads>${pitest.plugin.threads}</threads>
Expand Down
2 changes: 1 addition & 1 deletion shippable.yml
Expand Up @@ -14,7 +14,7 @@ env:
- PROFILE="-Ppitest-checks-regexp,no-validations"; POST_ACTION=check_survived
- PROFILE="-Ppitest-checks-sizes,no-validations"; POST_ACTION=check_survived
- PROFILE="-Ppitest-checks-whitespace,no-validations"
- PROFILE="-Ppitest-checks-misc,no-validations"
- PROFILE="-Ppitest-checks-misc,no-validations"; POST_ACTION=check_survived
- PROFILE="-Ppitest-checks-blocks,no-validations"
- PROFILE="-Ppitest-checks-coding,no-validations"
- PROFILE="-Ppitest-checks-design,no-validations"; POST_ACTION=check_survived
Expand Down
Expand Up @@ -47,7 +47,6 @@
import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
import com.puppycrawl.tools.checkstyle.api.FileText;
import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
import com.puppycrawl.tools.checkstyle.api.MessageDispatcher;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;

/**
Expand Down Expand Up @@ -325,11 +324,8 @@ private static Optional<String> getMissingFileName(ResourceBundle bundle, String
* @param fileName file name.
*/
private void logMissingTranslation(String filePath, String fileName) {
final MessageDispatcher dispatcher = getMessageDispatcher();
dispatcher.fireFileStarted(filePath);
log(0, MSG_KEY_MISSING_TRANSLATION_FILE, fileName);
fireErrors(filePath);
dispatcher.fireFileFinished(filePath);
}

/**
Expand Down Expand Up @@ -434,7 +430,7 @@ private static String getPath(String fileNameWithPath) {
*/
private void checkTranslationKeys(ResourceBundle bundle) {
final Set<File> filesInBundle = bundle.getFiles();
if (filesInBundle.size() > 1) {
if (filesInBundle.size() >= 2) {
// build a map from files to the keys they contain
final Set<String> allTranslationKeys = new HashSet<>();
final SetMultimap<File, String> filesAssociatedWithKeys = HashMultimap.create();
Expand All @@ -456,9 +452,6 @@ private void checkTranslationKeys(ResourceBundle bundle) {
private void checkFilesForConsistencyRegardingTheirKeys(SetMultimap<File, String> fileKeys,
Set<String> keysThatMustExist) {
for (File currentFile : fileKeys.keySet()) {
final MessageDispatcher dispatcher = getMessageDispatcher();
final String path = currentFile.getPath();
dispatcher.fireFileStarted(path);
final Set<String> currentFileKeys = fileKeys.get(currentFile);
final Set<String> missingKeys = keysThatMustExist.stream()
.filter(e -> !currentFileKeys.contains(e)).collect(Collectors.toSet());
Expand All @@ -467,8 +460,7 @@ private void checkFilesForConsistencyRegardingTheirKeys(SetMultimap<File, String
log(0, MSG_KEY, key);
}
}
fireErrors(path);
dispatcher.fireFileFinished(path);
fireErrors(currentFile.getPath());
}
}

Expand Down
Expand Up @@ -94,9 +94,6 @@ public void beginTree(DetailAST rootAST) {
@Override
public void leaveToken(DetailAST ast) {
if (ast.getType() == TokenTypes.CLASS_DEF) {
if (classDepth == 1) {
currentClass = null;
}
classDepth--;
}
}
Expand Down
Expand Up @@ -23,16 +23,25 @@
import static com.puppycrawl.tools.checkstyle.checks.TranslationCheck.MSG_KEY_MISSING_TRANSLATION_FILE;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.endsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.powermock.api.mockito.PowerMockito.doNothing;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.verifyStatic;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Set;
import java.util.SortedSet;

Expand All @@ -41,17 +50,23 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.google.common.io.Closeables;
import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
import com.puppycrawl.tools.checkstyle.Checker;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import com.puppycrawl.tools.checkstyle.api.FileText;
import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
import com.puppycrawl.tools.checkstyle.api.MessageDispatcher;
import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
import com.puppycrawl.tools.checkstyle.api.SeverityLevelCounter;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;

@RunWith(MockitoJUnitRunner.class)
@RunWith(PowerMockRunner.class)
@PrepareForTest(Closeables.class)
public class TranslationCheckTest extends AbstractModuleTestSupport {
@Captor
private ArgumentCaptor<SortedSet<LocalizedMessage>> captor;
Expand All @@ -78,6 +93,43 @@ public void testTranslation() throws Exception {
expected);
}

/**
* Even when we pass several files to AbstractModuleTestSupport#verify,
* the check processes it during one run, so we cannot reproduce situation
* when TranslationCheck#beginProcessing called several times during single run.
* So, we have to use reflection to check this particular case.
*
* @throws Exception when code tested throws exception
*/
@Test
@SuppressWarnings("unchecked")
public void testStateIsCleared() throws Exception {
final File fileToProcess = new File(getPath("messages_test_de.properties"));
final String charset = StandardCharsets.UTF_8.name();
final TranslationCheck check = new TranslationCheck();
check.beginProcessing(charset);
check.processFiltered(fileToProcess, new FileText(fileToProcess, charset));
check.beginProcessing(charset);
final Field field = check.getClass().getDeclaredField("filesToProcess");
field.setAccessible(true);

assertTrue("Stateful field is not cleared on beginProcessiong",
((Collection<File>) field.get(check)).isEmpty());
}

@Test
public void testFileExtension() throws Exception {
final Configuration checkConfig = createModuleConfig(TranslationCheck.class);
final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
final File[] propertyFiles = {
new File(getPath("messages_test_de.txt")),
};
verify(createChecker(checkConfig),
propertyFiles,
getPath("messages_test_de.txt"),
expected);
}

@Test
public void testOnePropertyFileSet() throws Exception {
final DefaultConfiguration checkConfig = createModuleConfig(TranslationCheck.class);
Expand All @@ -102,13 +154,16 @@ public void testLogIoExceptionFileNotFound() throws Exception {
final DefaultConfiguration checkConfig = createModuleConfig(TranslationCheck.class);
check.configure(checkConfig);
final Checker checker = createChecker(checkConfig);
final SeverityLevelCounter counter = new SeverityLevelCounter(SeverityLevel.ERROR);
checker.addListener(counter);
check.setMessageDispatcher(checker);

final Method loadKeys =
check.getClass().getDeclaredMethod("getTranslationKeys", File.class);
loadKeys.setAccessible(true);
final Set<String> keys = (Set<String>) loadKeys.invoke(check, new File(""));
assertTrue("Translation keys should be empty when File is not found", keys.isEmpty());
assertEquals("Invalid error count", 1, counter.getCount());
}

@Test
Expand Down Expand Up @@ -276,6 +331,36 @@ public void testTranslationFileWithLanguageCountryVariantArePresent() throws Exc
expected);
}

/**
* Pitest requires all closes of streams and readers to be verified. Using PowerMock
* is almost only posibility to check it without rewriting production code.
*
* @throws Exception when code tested throws some exception
*/
@Test
public void testResourcesAreClosed() throws Exception {
mockStatic(Closeables.class);
doNothing().when(Closeables.class);
Closeables.closeQuietly(any(InputStream.class));

final DefaultConfiguration checkConfig = createModuleConfig(TranslationCheck.class);
checkConfig.addAttribute("requiredTranslations", "es");

final File[] propertyFiles = {
new File(getPath("messages_home.properties")),
new File(getPath("messages_home_es_US.properties")),
};

final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
verify(
createChecker(checkConfig),
propertyFiles,
getPath(""),
expected);
verifyStatic(times(2));
Closeables.closeQuietly(any(FileInputStream.class));
}

@Test
public void testBaseNameOption() throws Exception {
final DefaultConfiguration checkConfig = createModuleConfig(TranslationCheck.class);
Expand Down
@@ -0,0 +1,2 @@
someKey=Some key
anotherKey=one more
@@ -0,0 +1 @@
someKey=einige Schlüssel
@@ -0,0 +1,12 @@
# input file for TranslationCheck

# a key that is available in all translations
hello=Hallo

# whitespace at end of key should be trimmed before comparing.
# the german translation does not contain whitespace, no error should
# be reported here
cancel=Abbrechen

# a key that is missing in german translation
#only.english=only english

0 comments on commit c68a90e

Please sign in to comment.