1d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/* 2d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Copyright (C) 2015 The Android Open Source Project 3d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 4d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 5d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * you may not use this file except in compliance with the License. 6d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * You may obtain a copy of the License at 7d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 8d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 9d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * 10d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Unless required by applicable law or agreed to in writing, software 11d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 12d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * See the License for the specific language governing permissions and 14d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * limitations under the License. 15d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */ 16d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.expr; 18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 19019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarimport android.databinding.tool.LayoutBinder; 20019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyarimport android.databinding.tool.MockLayoutBinder; 21fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelAnalyzer; 22fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.ModelClass; 23fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountimport android.databinding.tool.reflection.java.JavaAnalyzer; 24e52882df6130221462bf07f5f2b52de5c4b0f8deGeorge Mountimport android.databinding.tool.writer.KCode; 25fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount 26d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport org.junit.Before; 27d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mountimport org.junit.Test; 28d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 29d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.BitSet; 30d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.List; 31d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 32d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport static org.junit.Assert.assertEquals; 33d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport static org.junit.Assert.assertTrue; 34d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 35d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarpublic class ExprTest{ 36d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private static class DummyExpr extends Expr { 37d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar String mKey; 38d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public DummyExpr(String key, DummyExpr... children) { 39d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar super(children); 40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar mKey = key; 41d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 42d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 43d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 4497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { 4597d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return modelAnalyzer.findClass(Integer.class); 46d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 47d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar protected List<Dependency> constructDependencies() { 50d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return constructDynamicChildrenDependencies(); 51d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 52d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar protected String computeUniqueKey() { 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return mKey + super.computeUniqueKey(); 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 59d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount protected KCode generateCode(boolean full) { 60e52882df6130221462bf07f5f2b52de5c4b0f8deGeorge Mount return new KCode(); 61e52882df6130221462bf07f5f2b52de5c4b0f8deGeorge Mount } 62e52882df6130221462bf07f5f2b52de5c4b0f8deGeorge Mount 63e52882df6130221462bf07f5f2b52de5c4b0f8deGeorge Mount @Override 64d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount protected String getInvertibleError() { 65d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return null; 66d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 67d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 68d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public boolean isDynamic() { 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return true; 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 72d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 73d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Before 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void setUp() throws Exception { 7697d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar JavaAnalyzer.initForTests(); 77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 792611838bffef5a009ca71e3e9e59a93f29b098edYigit Boyar @Test(expected=Throwable.class) 80d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void testBadExpr() { 81d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar Expr expr = new Expr() { 82d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 8397d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar protected ModelClass resolveType(ModelAnalyzer modelAnalyzer) { 8497d6ddf47f4ff1abb3ed5201ce5232163f5325b1Yigit Boyar return modelAnalyzer.findClass(Integer.class); 85d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 87d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Override 88d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar protected List<Dependency> constructDependencies() { 89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return constructDynamicChildrenDependencies(); 90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 91e52882df6130221462bf07f5f2b52de5c4b0f8deGeorge Mount 92e52882df6130221462bf07f5f2b52de5c4b0f8deGeorge Mount @Override 93d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount protected KCode generateCode(boolean full) { 94e52882df6130221462bf07f5f2b52de5c4b0f8deGeorge Mount return new KCode(); 95e52882df6130221462bf07f5f2b52de5c4b0f8deGeorge Mount } 96d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount 97d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount @Override 98d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount protected String getInvertibleError() { 99d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount return null; 100d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount } 101d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar }; 102d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar expr.getUniqueKey(); 103d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 104d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 105d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Test 106d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void testBasicInvalidationFlag() { 107019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar LayoutBinder lb = new MockLayoutBinder(); 108019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar ExprModel model = lb.getModel(); 109019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar model.seal(); 110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr d = new DummyExpr("a"); 111019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar d.setModel(model); 112d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar d.setId(3); 113d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar d.enableDirectInvalidation(); 114d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar assertTrue(d.getInvalidFlags().get(3)); 115019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar BitSet clone = (BitSet) model.getInvalidateAnyBitSet().clone(); 116019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar clone.and(d.getInvalidFlags()); 117019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar assertEquals(1, clone.cardinality()); 118d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 119d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 120d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Test 121d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void testCannotBeInvalidated() { 122019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar LayoutBinder lb = new MockLayoutBinder(); 123019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar ExprModel model = lb.getModel(); 124019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar model.seal(); 125d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr d = new DummyExpr("a"); 126019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar d.setModel(model); 127d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar d.setId(3); 128019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar // +1 for invalidate all flag 129019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar assertEquals(1, d.getInvalidFlags().cardinality()); 130019c36b97c7c172ac03997f6bf170e65b2ed7fe4Yigit Boyar assertEquals(model.getInvalidateAnyBitSet(), d.getInvalidFlags()); 131d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 132d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 133d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Test 134d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void testInvalidationInheritance() { 135d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModel model = new ExprModel(); 136d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr a = model.register(new DummyExpr("a")); 137d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr b = model.register(new DummyExpr("b")); 138d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr c = model.register(new DummyExpr("c", a, b)); 139d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar a.enableDirectInvalidation(); 140d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar b.enableDirectInvalidation(); 141d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.setBindingExpression(true); 142d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.seal(); 143d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar assertFlags(c, a, b); 144d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 145d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 146d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Test 147d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void testInvalidationInheritance2() { 148d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModel model = new ExprModel(); 149d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr a = model.register(new DummyExpr("a")); 150d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr b = model.register(new DummyExpr("b", a)); 151d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr c = model.register(new DummyExpr("c", b)); 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar a.enableDirectInvalidation(); 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar b.enableDirectInvalidation(); 154d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.setBindingExpression(true); 155d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.seal(); 156d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar assertFlags(c, a, b); 157d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 158d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 159d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Test 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void testShouldReadFlags() { 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModel model = new ExprModel(); 162d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr a = model.register(new DummyExpr("a")); 163d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar a.enableDirectInvalidation(); 164d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar a.setBindingExpression(true); 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.seal(); 166d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar assertFlags(a, a); 167d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar @Test 170d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar public void testShouldReadDependencyFlags() { 171d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar ExprModel model = new ExprModel(); 172d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr a = model.register(new DummyExpr("a")); 173d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr b = model.register(new DummyExpr("b", a)); 174d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar DummyExpr c = model.register(new DummyExpr("c", b)); 175d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar a.enableDirectInvalidation(); 176d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar b.enableDirectInvalidation(); 177d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar b.setBindingExpression(true); 178d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.setBindingExpression(true); 179d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar model.seal(); 180d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar assertFlags(b, a, b); 181d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar assertFlags(c, a, b); 182d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 183d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 184d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private void assertFlags(Expr a, Expr... exprs) { 185d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar BitSet bitSet = a.getShouldReadFlags(); 186d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (Expr expr : exprs) { 187d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar BitSet clone = (BitSet) bitSet.clone(); 188d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar clone.and(expr.getInvalidFlags()); 189d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar assertEquals("should read flags of " + a.getUniqueKey() + " should include " + expr 190d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar .getUniqueKey(), expr.getInvalidFlags(), clone); 191d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 192d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 193d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar BitSet composite = new BitSet(); 194d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar for (Expr expr : exprs) { 195d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar composite.or(expr.getInvalidFlags()); 196d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 197d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar assertEquals("composite flags should match", composite, bitSet); 198d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 199d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 200