blob: 65bf7e6be5c216f24832ca13ca0615699ceabcb0 [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2017 the original author or authors.
//
// This library 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 2.1 of the License, or (at your option) any later version.
//
// This library 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 library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle.checks;
import static com.puppycrawl.tools.checkstyle.checks.UniquePropertiesCheck.MSG_IO_EXCEPTION_KEY;
import static com.puppycrawl.tools.checkstyle.checks.UniquePropertiesCheck.MSG_KEY;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
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.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
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.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.api.FileText;
import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Closeables.class)
public class UniquePropertiesCheckTest extends AbstractModuleTestSupport {
@Override
protected String getPackageLocation() {
return "com/puppycrawl/tools/checkstyle/checks/uniqueproperties";
}
/* Additional test for jacoco, since valueOf()
* is generated by javac and jacoco reports that
* valueOf() is uncovered.
*/
@Test
public void testLineSeparatorOptionValueOf() {
final LineSeparatorOption option = LineSeparatorOption.valueOf("CR");
assertEquals("Invalid valueOf result", LineSeparatorOption.CR, option);
}
/**
* Tests the ordinal work of a check.
*/
@Test
public void testDefault() throws Exception {
final DefaultConfiguration checkConfig = createModuleConfig(UniquePropertiesCheck.class);
final String[] expected = {
"3: " + getCheckMessage(MSG_KEY, "general.exception", 2),
"5: " + getCheckMessage(MSG_KEY, "DefaultLogger.auditStarted", 2),
"11: " + getCheckMessage(MSG_KEY, "onlineManual", 3),
"22: " + getCheckMessage(MSG_KEY, "time stamp", 3),
"28: " + getCheckMessage(MSG_KEY, "Support Link ", 2),
"34: " + getCheckMessage(MSG_KEY, "failed", 2),
};
verify(checkConfig, getPath("InputUniqueProperties.properties"), expected);
}
/**
* Pitest requires all closes of streams and readers to be verified. Using PowerMock
* is almost only possibility to check it without rewriting production code.
*
* @throws Exception when code tested throws some exception
*/
@Test
public void testCloseInputStream() throws Exception {
mockStatic(Closeables.class);
doNothing().when(Closeables.class);
Closeables.closeQuietly(any(FileInputStream.class));
final DefaultConfiguration checkConfig = createModuleConfig(UniquePropertiesCheck.class);
final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
verify(checkConfig, getPath("InputUniquePropertiesWithoutErrors.properties"), expected);
verifyStatic(times(1));
Closeables.closeQuietly(any(FileInputStream.class));
}
/**
* Tests the {@link UniquePropertiesCheck#getLineNumber(FileText, String)}
* method return value.
*/
@Test
public void testNotFoundKey() throws Exception {
final List<String> testStrings = new ArrayList<>(3);
final Method getLineNumber = UniquePropertiesCheck.class.getDeclaredMethod(
"getLineNumber", FileText.class, String.class);
Assert.assertNotNull("Get line number method should be present", getLineNumber);
getLineNumber.setAccessible(true);
testStrings.add("");
testStrings.add("0 = 0");
testStrings.add("445");
final FileText fileText = new FileText(new File("some.properties"), testStrings);
final Object lineNumber = getLineNumber.invoke(UniquePropertiesCheck.class,
fileText, "some key");
Assert.assertNotNull("Line number should not be null", lineNumber);
assertEquals("Invalid line number", 0, lineNumber);
}
@Test
public void testDuplicatedProperty() throws Exception {
final DefaultConfiguration checkConfig = createModuleConfig(UniquePropertiesCheck.class);
final String[] expected = {
"2: " + getCheckMessage(MSG_KEY, "key", 2),
};
verify(checkConfig, getPath("InputUniquePropertiesWithDuplicates.properties"), expected);
}
@Test
public void testShouldNotProcessFilesWithWrongFileExtension() throws Exception {
final DefaultConfiguration checkConfig = createModuleConfig(UniquePropertiesCheck.class);
final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
verify(checkConfig, getPath("InputUniqueProperties.txt"), expected);
}
/**
* Tests IO exception, that can occur during reading of properties file.
*/
@Test
public void testIoException() throws Exception {
final DefaultConfiguration checkConfig = createModuleConfig(UniquePropertiesCheck.class);
final UniquePropertiesCheck check = new UniquePropertiesCheck();
check.configure(checkConfig);
final String fileName =
getPath("InputUniquePropertiesCheckNotExisting.properties");
final File file = new File(fileName);
final FileText fileText = new FileText(file, Collections.emptyList());
final SortedSet<LocalizedMessage> messages =
check.process(file, fileText);
assertEquals("Wrong messages count: " + messages.size(),
1, messages.size());
final LocalizedMessage message = messages.iterator().next();
final String retrievedMessage = messages.iterator().next().getKey();
assertEquals("Message key '" + retrievedMessage
+ "' is not valid", "unable.open.cause",
retrievedMessage);
assertEquals("Message '" + message.getMessage()
+ "' is not valid", message.getMessage(),
getCheckMessage(MSG_IO_EXCEPTION_KEY, fileName, getFileNotFoundDetail(file)));
}
@Test
public void testWrongKeyTypeInProperties() throws Exception {
final Class<?> uniquePropertiesClass = Class
.forName("com.puppycrawl.tools.checkstyle.checks."
+ "UniquePropertiesCheck$UniqueProperties");
final Constructor<?> constructor = uniquePropertiesClass.getDeclaredConstructor();
constructor.setAccessible(true);
final Object uniqueProperties = constructor.newInstance();
final Method method = uniqueProperties.getClass().getDeclaredMethod("put", Object.class,
Object.class);
final Object result = method.invoke(uniqueProperties, 1, "value");
final Map<Object, Object> table = new HashMap<>();
final Object expected = table.put(1, "value");
assertEquals("Invalid result of put method", expected, result);
final Object result2 = method.invoke(uniqueProperties, 1, "value");
final Object expected2 = table.put(1, "value");
assertEquals("Value should be substituted", expected2, result2);
}
/**
* Method generates FileNotFound exception details. It tries to open file,
* that does not exist.
* @param file to be opened
* @return detail message of {@link FileNotFoundException}
*/
private static String getFileNotFoundDetail(File file) throws Exception {
// Create exception to know detail message we should wait in
// LocalisedMessage
try {
final InputStream stream = new FileInputStream(file);
stream.close();
throw new IllegalStateException("File " + file.getPath() + " should not exist");
}
catch (FileNotFoundException ex) {
return ex.getLocalizedMessage();
}
}
}