/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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 android.databinding.tool;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import android.databinding.tool.expr.ComparisonExpr;
import android.databinding.tool.expr.Dependency;
import android.databinding.tool.expr.Expr;
import android.databinding.tool.expr.ExprModel;
import android.databinding.tool.expr.FieldAccessExpr;
import android.databinding.tool.expr.IdentifierExpr;
import android.databinding.tool.expr.MethodCallExpr;
import android.databinding.tool.expr.SymbolExpr;
import android.databinding.tool.expr.TernaryExpr;
import android.databinding.tool.reflection.Callable;
import android.databinding.tool.reflection.java.JavaAnalyzer;
import android.databinding.tool.reflection.java.JavaClass;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class ExpressionVisitorTest {
ExpressionParser mParser = new ExpressionParser(new ExprModel());
@Before
public void setUp() throws Exception {
JavaAnalyzer.initForTests();
}
private <T extends Expr> T parse(String input, Class<T> klass) {
final Expr parsed = mParser.parse(input, null);
assertSame(klass, parsed.getClass());
return (T) parsed;
}
@Test
public void testSymbol() {
final SymbolExpr res = parse("null", SymbolExpr.class);
assertEquals(1, mParser.getModel().size());
assertEquals("null", res.getText());
assertEquals(new JavaClass(Object.class),res.getResolvedType());
assertEquals(0, res.getDependencies().size());
}
@RunWith(Parameterized.class)
public static class ComparisonExprTests {
ExpressionParser mParser = new ExpressionParser(new ExprModel());
private final String mOp;
@Before
public void setUp() throws Exception {
JavaAnalyzer.initForTests();
}
@Parameterized.Parameters
public static List<Object[]> data() {
return Arrays.asList(new Object[][] {
{"=="}, {"<="}, {">="}, {">"}, {"<"}
});
}
public ComparisonExprTests(String op) {
mOp = op;
}
@Test
public void testComparison() {
final Expr res = mParser.parse("3 " + mOp + " 5", null);
assertEquals(3, mParser.getModel().size());
assertTrue(res instanceof ComparisonExpr);
// 0 because they are both static
assertEquals(0, res.getDependencies().size());
}
}
@Test
public void testSimpleFieldAccess() {
final FieldAccessExpr expr = parse("a.b", FieldAccessExpr.class);
assertEquals(2, mParser.mModel.size());
assertEquals("b", expr.getName());
assertEquals(1, expr.getChildren().size());
final Expr parent = expr.getChildren().get(0);
assertTrue(parent instanceof IdentifierExpr);
final IdentifierExpr id = (IdentifierExpr) parent;
assertEquals("a", id.getName());
assertEquals(0, id.getDependencies().size());
assertEquals(1, expr.getDependencies().size());
}
@Test
public void testIdentifier() {
final IdentifierExpr id = parse("myStr", IdentifierExpr.class);
assertEquals(1, mParser.mModel.size());
assertEquals("myStr", id.getName());
id.setUserDefinedType("java.lang.String");
assertEquals(new JavaClass(String.class), id.getResolvedType());
}
@Test
public void testTernary() {
final TernaryExpr parsed = parse("a > b ? 5 : 4", TernaryExpr.class);
assertEquals(6, mParser.getModel().size());
assertTrue(parsed.getPred() instanceof ComparisonExpr);
assertTrue(parsed.getIfTrue() instanceof SymbolExpr);
assertTrue(parsed.getIfFalse() instanceof SymbolExpr);
ComparisonExpr pred = (ComparisonExpr) parsed.getPred();
SymbolExpr ifTrue = (SymbolExpr) parsed.getIfTrue();
SymbolExpr ifFalse = (SymbolExpr) parsed.getIfFalse();
assertEquals("5", ifTrue.getText());
assertEquals("4", ifFalse.getText());
assertEquals(1, parsed.getDependencies().size());
for (Dependency dependency : parsed.getDependencies()) {
assertEquals(dependency.getOther() != pred, dependency.isConditional());
}
}
@Test
public void testInheritedFieldResolution() {
final FieldAccessExpr parsed = parse("myStr.length", FieldAccessExpr.class);
assertTrue(parsed.getChild() instanceof IdentifierExpr);
final IdentifierExpr id = (IdentifierExpr) parsed.getChild();
id.setUserDefinedType("java.lang.String");
assertEquals(new JavaClass(int.class), parsed.getResolvedType());
Callable getter = parsed.getGetter();
assertEquals(Callable.Type.METHOD, getter.type);
assertEquals("length", getter.name);
assertEquals(1, parsed.getDependencies().size());
final Dependency dep = parsed.getDependencies().get(0);
assertSame(id, dep.getOther());
assertFalse(dep.isConditional());
}
@Test
public void testGetterResolution() {
final FieldAccessExpr parsed = parse("myStr.bytes", FieldAccessExpr.class);
assertTrue(parsed.getChild() instanceof IdentifierExpr);
final IdentifierExpr id = (IdentifierExpr) parsed.getChild();
id.setUserDefinedType("java.lang.String");
assertEquals(new JavaClass(byte[].class), parsed.getResolvedType());
Callable getter = parsed.getGetter();
assertEquals(Callable.Type.METHOD, getter.type);
assertEquals("getBytes", getter.name);
assertEquals(1, parsed.getDependencies().size());
final Dependency dep = parsed.getDependencies().get(0);
assertSame(id, dep.getOther());
assertFalse(dep.isConditional());
}
@Test
public void testMethodCall() {
final MethodCallExpr parsed = parse("user.getName()", MethodCallExpr.class);
assertTrue(parsed.getTarget() instanceof IdentifierExpr);
assertEquals("getName", parsed.getName());
assertEquals(0, parsed.getArgs().size());
assertEquals(1, parsed.getDependencies().size());
final Dependency dep = parsed.getDependencies().get(0);
assertSame(mParser.parse("user", null), dep.getOther());
assertFalse(dep.isConditional());
}
@Test
public void testMethodCallWithArgs() {
final MethodCallExpr parsed = parse("str.substring(1, a)", MethodCallExpr.class);
assertTrue(parsed.getTarget() instanceof IdentifierExpr);
assertEquals("substring", parsed.getName());
final List<Expr> args = parsed.getArgs();
assertEquals(2, args.size());
assertTrue(args.get(0) instanceof SymbolExpr);
assertTrue(args.get(1) instanceof IdentifierExpr);
final List<Dependency> deps = parsed.getDependencies();
assertEquals(2, deps.size());
}
}