/* * SonarQube Java * Copyright (C) 2012-2016 SonarSource SA * mailto:contact AT sonarsource DOT com * * This program 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 3 of the License, or (at your option) any later version. * * This program 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 program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.sonar.java.checks.helpers; import com.google.common.collect.Lists; import com.sonar.sslr.api.typed.ActionParser; import org.junit.Test; import org.sonar.java.ast.parser.JavaParser; import org.sonar.java.resolve.SemanticModel; import org.sonar.plugins.java.api.tree.ClassTree; import org.sonar.plugins.java.api.tree.CompilationUnitTree; import org.sonar.plugins.java.api.tree.ExpressionStatementTree; import org.sonar.plugins.java.api.tree.ExpressionTree; import org.sonar.plugins.java.api.tree.MethodInvocationTree; import org.sonar.plugins.java.api.tree.MethodTree; import org.sonar.plugins.java.api.tree.StatementTree; import org.sonar.plugins.java.api.tree.Tree; import java.io.File; import java.lang.reflect.Constructor; import java.nio.charset.StandardCharsets; import static org.assertj.core.api.Assertions.assertThat; public class JavaPropertiesHelperTest { private final ActionParser<Tree> p = JavaParser.createParser(StandardCharsets.UTF_8); @Test public void private_constructor() throws Exception { Constructor<JavaPropertiesHelper> constructor = JavaPropertiesHelper.class.getDeclaredConstructor(); assertThat(constructor.isAccessible()).isFalse(); constructor.setAccessible(true); constructor.newInstance(); } @Test public void null_if_not_get_property() throws Exception { ExpressionTree tree = firstExpression("void foo(java.util.Properties props){ props.setProperty(\"myKey\", \"myValue\"); }"); ExpressionTree defaultValue = JavaPropertiesHelper.retrievedPropertyDefaultValue(tree); assertThat(defaultValue).isNull(); tree = firstExpression("void foo(){ System.out.println(); }"); defaultValue = JavaPropertiesHelper.retrievedPropertyDefaultValue(tree); assertThat(defaultValue).isNull(); } @Test public void null_if_get_property_without_default_value() throws Exception { ExpressionTree tree = firstExpression("void foo(java.util.Properties props){ props.getProperty(\"myKey\"); }"); ExpressionTree defaultValue = JavaPropertiesHelper.retrievedPropertyDefaultValue(tree); assertThat(defaultValue).isNull(); } @Test public void null_if_not_identifier_or_method_invocation() throws Exception { ExpressionTree tree = firstExpression("void foo(int a){ a++; }"); ExpressionTree defaultValue = JavaPropertiesHelper.retrievedPropertyDefaultValue(tree); assertThat(defaultValue).isNull(); } @Test public void retrieve_default_value_on_method_invocation() throws Exception { ExpressionTree tree = firstExpression("void foo(java.util.Properties props){ props.getProperty(\"myKey\", \"defaultValue\"); }"); ExpressionTree defaultValue = JavaPropertiesHelper.retrievedPropertyDefaultValue(tree); assertThat(defaultValue).isNotNull(); assertThat(defaultValue.is(Tree.Kind.STRING_LITERAL)).isTrue(); } @Test public void retrieve_default_value_on_identifier() throws Exception { ExpressionTree tree = firstExpression( "void foo(String prop){ foo(myValue); } " + "java.util.Properties props = new java.util.Properties();" + "String myValue = props.getProperty(\"myKey\", \"defaultValue\");"); ExpressionTree defaultValue = JavaPropertiesHelper.retrievedPropertyDefaultValue(((MethodInvocationTree) tree).arguments().get(0)); assertThat(defaultValue).isNotNull(); assertThat(defaultValue.is(Tree.Kind.STRING_LITERAL)).isTrue(); } @Test public void null_if_variable_used_more_than_once() throws Exception { ExpressionTree tree = firstExpression( "void foo(String prop){ foo(myValue); myValue = 0; } " + "java.util.Properties props = new java.util.Properties();" + "String myValue = props.getProperty(\"myKey\", \"defaultValue\");"); ExpressionTree defaultValue = JavaPropertiesHelper.retrievedPropertyDefaultValue(((MethodInvocationTree) tree).arguments().get(0)); assertThat(defaultValue).isNull(); } @Test public void null_if_variable_not_initialized() throws Exception { ExpressionTree tree = firstExpression( "void foo(String prop){ foo(myValue);} " + "String myValue;"); ExpressionTree defaultValue = JavaPropertiesHelper.retrievedPropertyDefaultValue(((MethodInvocationTree) tree).arguments().get(0)); assertThat(defaultValue).isNull(); } @Test public void null_if_variable_not_initilialized_method_invocation() throws Exception { ExpressionTree tree = firstExpression( "void foo(String prop){ foo(myValue);} " + "java.util.Properties props = new java.util.Properties();" + "String myValue = \"hello\";"); ExpressionTree defaultValue = JavaPropertiesHelper.retrievedPropertyDefaultValue(((MethodInvocationTree) tree).arguments().get(0)); assertThat(defaultValue).isNull(); } private ExpressionTree firstExpression(String code) { CompilationUnitTree compilationUnitTree = (CompilationUnitTree) p.parse("class A { " + code + "}"); SemanticModel.createFor(compilationUnitTree, Lists.<File>newArrayList()); ClassTree firstType = (ClassTree) compilationUnitTree.types().get(0); StatementTree firstStatement = ((MethodTree) firstType.members().get(0)).block().body().get(0); return ((ExpressionStatementTree) firstStatement).expression(); } }