1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.databinding.tool; 18 19 import org.junit.Before; 20 import org.junit.Test; 21 import org.junit.runner.RunWith; 22 import org.junit.runners.Parameterized; 23 24 import android.databinding.tool.expr.ComparisonExpr; 25 import android.databinding.tool.expr.Dependency; 26 import android.databinding.tool.expr.Expr; 27 import android.databinding.tool.expr.ExprModel; 28 import android.databinding.tool.expr.FieldAccessExpr; 29 import android.databinding.tool.expr.IdentifierExpr; 30 import android.databinding.tool.expr.MethodCallExpr; 31 import android.databinding.tool.expr.SymbolExpr; 32 import android.databinding.tool.expr.TernaryExpr; 33 import android.databinding.tool.reflection.Callable; 34 import android.databinding.tool.reflection.java.JavaAnalyzer; 35 import android.databinding.tool.reflection.java.JavaClass; 36 37 import java.util.Arrays; 38 import java.util.List; 39 40 import static org.junit.Assert.assertEquals; 41 import static org.junit.Assert.assertFalse; 42 import static org.junit.Assert.assertSame; 43 import static org.junit.Assert.assertTrue; 44 45 public class ExpressionVisitorTest { 46 ExpressionParser mParser = new ExpressionParser(new ExprModel()); 47 48 @Before 49 public void setUp() throws Exception { 50 JavaAnalyzer.initForTests(); 51 } 52 53 private <T extends Expr> T parse(String input, Class<T> klass) { 54 final Expr parsed = mParser.parse(input, null); 55 assertSame(klass, parsed.getClass()); 56 return (T) parsed; 57 } 58 59 @Test 60 public void testSymbol() { 61 final SymbolExpr res = parse("null", SymbolExpr.class); 62 assertEquals(1, mParser.getModel().size()); 63 assertEquals("null", res.getText()); 64 assertEquals(new JavaClass(Object.class),res.getResolvedType()); 65 assertEquals(0, res.getDependencies().size()); 66 } 67 68 69 @RunWith(Parameterized.class) 70 public static class ComparisonExprTests { 71 ExpressionParser mParser = new ExpressionParser(new ExprModel()); 72 private final String mOp; 73 74 @Before 75 public void setUp() throws Exception { 76 JavaAnalyzer.initForTests(); 77 } 78 79 @Parameterized.Parameters 80 public static List<Object[]> data() { 81 return Arrays.asList(new Object[][] { 82 {"=="}, {"<="}, {">="}, {">"}, {"<"} 83 }); 84 } 85 86 public ComparisonExprTests(String op) { 87 mOp = op; 88 } 89 90 @Test 91 public void testComparison() { 92 final Expr res = mParser.parse("3 " + mOp + " 5", null); 93 assertEquals(3, mParser.getModel().size()); 94 assertTrue(res instanceof ComparisonExpr); 95 // 0 because they are both static 96 assertEquals(0, res.getDependencies().size()); 97 } 98 } 99 100 101 102 @Test 103 public void testSimpleFieldAccess() { 104 final FieldAccessExpr expr = parse("a.b", FieldAccessExpr.class); 105 assertEquals(2, mParser.mModel.size()); 106 assertEquals("b", expr.getName()); 107 assertEquals(1, expr.getChildren().size()); 108 final Expr parent = expr.getChildren().get(0); 109 assertTrue(parent instanceof IdentifierExpr); 110 final IdentifierExpr id = (IdentifierExpr) parent; 111 assertEquals("a", id.getName()); 112 assertEquals(0, id.getDependencies().size()); 113 assertEquals(1, expr.getDependencies().size()); 114 } 115 116 @Test 117 public void testIdentifier() { 118 final IdentifierExpr id = parse("myStr", IdentifierExpr.class); 119 assertEquals(1, mParser.mModel.size()); 120 assertEquals("myStr", id.getName()); 121 id.setUserDefinedType("java.lang.String"); 122 assertEquals(new JavaClass(String.class), id.getResolvedType()); 123 } 124 125 @Test 126 public void testTernary() { 127 final TernaryExpr parsed = parse("a > b ? 5 : 4", TernaryExpr.class); 128 assertEquals(6, mParser.getModel().size()); 129 assertTrue(parsed.getPred() instanceof ComparisonExpr); 130 assertTrue(parsed.getIfTrue() instanceof SymbolExpr); 131 assertTrue(parsed.getIfFalse() instanceof SymbolExpr); 132 ComparisonExpr pred = (ComparisonExpr) parsed.getPred(); 133 SymbolExpr ifTrue = (SymbolExpr) parsed.getIfTrue(); 134 SymbolExpr ifFalse = (SymbolExpr) parsed.getIfFalse(); 135 assertEquals("5", ifTrue.getText()); 136 assertEquals("4", ifFalse.getText()); 137 assertEquals(1, parsed.getDependencies().size()); 138 for (Dependency dependency : parsed.getDependencies()) { 139 assertEquals(dependency.getOther() != pred, dependency.isConditional()); 140 } 141 } 142 143 @Test 144 public void testInheritedFieldResolution() { 145 final FieldAccessExpr parsed = parse("myStr.length", FieldAccessExpr.class); 146 assertTrue(parsed.getChild() instanceof IdentifierExpr); 147 final IdentifierExpr id = (IdentifierExpr) parsed.getChild(); 148 id.setUserDefinedType("java.lang.String"); 149 assertEquals(new JavaClass(int.class), parsed.getResolvedType()); 150 Callable getter = parsed.getGetter(); 151 assertEquals(Callable.Type.METHOD, getter.type); 152 assertEquals("length", getter.name); 153 assertEquals(1, parsed.getDependencies().size()); 154 final Dependency dep = parsed.getDependencies().get(0); 155 assertSame(id, dep.getOther()); 156 assertFalse(dep.isConditional()); 157 } 158 159 @Test 160 public void testGetterResolution() { 161 final FieldAccessExpr parsed = parse("myStr.bytes", FieldAccessExpr.class); 162 assertTrue(parsed.getChild() instanceof IdentifierExpr); 163 final IdentifierExpr id = (IdentifierExpr) parsed.getChild(); 164 id.setUserDefinedType("java.lang.String"); 165 assertEquals(new JavaClass(byte[].class), parsed.getResolvedType()); 166 Callable getter = parsed.getGetter(); 167 assertEquals(Callable.Type.METHOD, getter.type); 168 assertEquals("getBytes", getter.name); 169 assertEquals(1, parsed.getDependencies().size()); 170 final Dependency dep = parsed.getDependencies().get(0); 171 assertSame(id, dep.getOther()); 172 assertFalse(dep.isConditional()); 173 } 174 175 @Test 176 public void testMethodCall() { 177 final MethodCallExpr parsed = parse("user.getName()", MethodCallExpr.class); 178 assertTrue(parsed.getTarget() instanceof IdentifierExpr); 179 assertEquals("getName", parsed.getName()); 180 assertEquals(0, parsed.getArgs().size()); 181 assertEquals(1, parsed.getDependencies().size()); 182 final Dependency dep = parsed.getDependencies().get(0); 183 assertSame(mParser.parse("user", null), dep.getOther()); 184 assertFalse(dep.isConditional()); 185 } 186 187 @Test 188 public void testMethodCallWithArgs() { 189 final MethodCallExpr parsed = parse("str.substring(1, a)", MethodCallExpr.class); 190 assertTrue(parsed.getTarget() instanceof IdentifierExpr); 191 assertEquals("substring", parsed.getName()); 192 final List<Expr> args = parsed.getArgs(); 193 assertEquals(2, args.size()); 194 assertTrue(args.get(0) instanceof SymbolExpr); 195 assertTrue(args.get(1) instanceof IdentifierExpr); 196 final List<Dependency> deps = parsed.getDependencies(); 197 assertEquals(2, deps.size()); 198 } 199 200 } 201