| /* |
| * Copyright (C) 2017 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 com.android.tools.idea.observable; |
| |
| import com.android.tools.idea.observable.core.BoolValueProperty; |
| import com.android.tools.idea.observable.core.IntValueProperty; |
| import com.android.tools.idea.observable.core.StringValueProperty; |
| import com.android.tools.idea.observable.expressions.list.MapExpression; |
| import com.android.tools.idea.observable.collections.ObservableList; |
| import org.jetbrains.annotations.NotNull; |
| import org.junit.Test; |
| |
| import java.util.Arrays; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| |
| public final class BindingsManagerTest { |
| |
| @Test |
| public void oneWayBindingAffectedByTarget() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| IntValueProperty property1 = new IntValueProperty(10); |
| IntValueProperty property2 = new IntValueProperty(20); |
| |
| bindings.bind(property1, property2); |
| assertThat(property1.get()).isEqualTo(20); |
| |
| property1.set(30); |
| assertThat(property1.get()).isEqualTo(30); |
| assertThat(property2.get()).isEqualTo(20); |
| |
| property2.set(40); |
| assertThat(property1.get()).isEqualTo(40); |
| } |
| |
| @Test |
| public void twoWayBindingsAffectEachOther() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| IntValueProperty property1 = new IntValueProperty(10); |
| IntValueProperty property2 = new IntValueProperty(20); |
| |
| bindings.bindTwoWay(property1, property2); |
| assertThat(property1.get()).isEqualTo(20); |
| |
| property1.set(30); |
| assertThat(property2.get()).isEqualTo(30); |
| |
| property2.set(40); |
| assertThat(property1.get()).isEqualTo(40); |
| } |
| |
| @Test |
| public void mapBindingsUpdateDestinationList() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| |
| ObservableList<Integer> numericList = new ObservableList<>(); |
| for (int i = 1; i <= 5; i++) { |
| numericList.add(i); |
| } |
| ObservableList<String> stringList = new ObservableList<>(); |
| CountListener listener = new CountListener(); |
| stringList.addListener(listener); |
| |
| bindings.bind(stringList, new MapExpression<Integer, String>(numericList) { |
| @NotNull |
| @Override |
| protected String transform(@NotNull Integer srcElement) { |
| return srcElement.toString(); |
| } |
| }); |
| |
| assertThat(stringList).containsExactly("1", "2", "3", "4", "5"); |
| assertThat(listener.getCount()).isEqualTo(1); |
| |
| numericList.addAll(Arrays.asList(6, 7)); |
| |
| assertThat(stringList).containsExactly("1", "2", "3", "4", "5", "6", "7"); |
| assertThat(listener.getCount()).isEqualTo(2); |
| |
| numericList.clear(); |
| |
| assertThat(stringList).isEmpty(); |
| assertThat(listener.getCount()).isEqualTo(3); |
| } |
| |
| @Test |
| public void releaseDisconnectsOneWayBindings() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| StringValueProperty property1 = new StringValueProperty("A"); |
| StringValueProperty property2 = new StringValueProperty("B"); |
| |
| bindings.bind(property1, property2); |
| assertThat(property1.get()).isEqualTo("B"); |
| |
| bindings.release(property1); |
| |
| property2.set("Property2"); |
| assertThat(property1.get()).isEqualTo("B"); |
| } |
| |
| @Test |
| public void releaseTwoWayDisconnectsTwoWayBindings() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| StringValueProperty property1 = new StringValueProperty("First"); |
| StringValueProperty property2 = new StringValueProperty("Second"); |
| |
| bindings.bindTwoWay(property1, property2); |
| assertThat(property1.get()).isEqualTo("Second"); |
| |
| bindings.releaseTwoWay(property1, property2); |
| |
| property1.set("Property1"); |
| assertThat(property2.get()).isEqualTo("Second"); |
| |
| property2.set("Property2"); |
| assertThat(property1.get()).isEqualTo("Property1"); |
| } |
| |
| @Test |
| public void releaseTwoWayWithOneArgDisconnectsAllMatchingBindings() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| StringValueProperty property1 = new StringValueProperty("First"); |
| StringValueProperty property2 = new StringValueProperty("Second"); |
| StringValueProperty property3 = new StringValueProperty("Third"); |
| |
| bindings.bindTwoWay(property1, property2); |
| bindings.bindTwoWay(property3, property2); |
| assertThat(property1.get()).isEqualTo("Second"); |
| assertThat(property3.get()).isEqualTo("Second"); |
| |
| bindings.releaseTwoWay(property2); |
| |
| property1.set("Property1"); |
| assertThat(property2.get()).isEqualTo("Second"); |
| |
| property3.set("Property3"); |
| assertThat(property2.get()).isEqualTo("Second"); |
| } |
| |
| @Test |
| public void releaseDisconnectsListBindings() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| ObservableList<String> dest = new ObservableList<>(); |
| ObservableList<Integer> src = new ObservableList<>(); |
| |
| bindings.bind(dest, new MapExpression<Integer, String>(src) { |
| @NotNull |
| @Override |
| protected String transform(@NotNull Integer srcElement) { |
| return srcElement.toString(); |
| } |
| }); |
| |
| src.add(5); |
| assertThat(dest).containsExactly("5"); |
| |
| bindings.release(dest); |
| |
| src.add(10); |
| assertThat(dest).containsExactly("5"); |
| } |
| |
| @Test |
| public void releaseAllDisconnectsOneWayBindings() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| StringValueProperty property1 = new StringValueProperty("A"); |
| StringValueProperty property2 = new StringValueProperty("B"); |
| |
| bindings.bind(property1, property2); |
| assertThat(property1.get()).isEqualTo("B"); |
| |
| bindings.releaseAll(); |
| |
| property2.set("Property2"); |
| assertThat(property1.get()).isEqualTo("B"); |
| } |
| |
| @Test |
| public void releaseAllDisconnectsTwoWayBindings() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| StringValueProperty property1 = new StringValueProperty("First"); |
| StringValueProperty property2 = new StringValueProperty("Second"); |
| |
| bindings.bindTwoWay(property1, property2); |
| assertThat(property1.get()).isEqualTo("Second"); |
| |
| bindings.releaseAll(); |
| |
| property1.set("Property1"); |
| assertThat(property2.get()).isEqualTo("Second"); |
| |
| property2.set("Property2"); |
| assertThat(property1.get()).isEqualTo("Property1"); |
| } |
| |
| @Test |
| public void releaseAllDisconnectsListBindings() throws Exception { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| ObservableList<String> dest = new ObservableList<>(); |
| ObservableList<Integer> src = new ObservableList<>(); |
| |
| bindings.bind(dest, new MapExpression<Integer, String>(src) { |
| @NotNull |
| @Override |
| protected String transform(@NotNull Integer srcElement) { |
| return srcElement.toString(); |
| } |
| }); |
| |
| src.add(5); |
| assertThat(dest).containsExactly("5"); |
| |
| bindings.releaseAll(); |
| |
| src.add(10); |
| assertThat(dest).containsExactly("5"); |
| } |
| |
| @Test |
| public void twoWayBindingsCanBeChained() { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| IntValueProperty a = new IntValueProperty(); |
| IntValueProperty b = new IntValueProperty(); |
| IntValueProperty c = new IntValueProperty(); |
| |
| bindings.bindTwoWay(a, b); |
| bindings.bindTwoWay(b, c); |
| |
| c.set(30); |
| assertThat(a.get()).isEqualTo(30); |
| assertThat(b.get()).isEqualTo(30); |
| assertThat(c.get()).isEqualTo(30); |
| |
| b.set(-100); |
| assertThat(a.get()).isEqualTo(-100); |
| assertThat(b.get()).isEqualTo(-100); |
| assertThat(c.get()).isEqualTo(-100); |
| |
| a.set(9); |
| assertThat(a.get()).isEqualTo(9); |
| assertThat(b.get()).isEqualTo(9); |
| assertThat(c.get()).isEqualTo(9); |
| } |
| |
| @Test |
| public void oneWayBindingsCanBeEnabledConditionally() { |
| BindingsManager bindings = new BindingsManager(BatchInvoker.INVOKE_IMMEDIATELY_STRATEGY); |
| IntValueProperty srcProperty = new IntValueProperty(10); |
| IntValueProperty destProperty = new IntValueProperty(-5); |
| BoolValueProperty bindingEnabled = new BoolValueProperty(true); |
| |
| bindings.bind(destProperty, srcProperty, bindingEnabled); |
| assertThat(destProperty.get()).isEqualTo(10); |
| |
| srcProperty.set(20); |
| assertThat(destProperty.get()).isEqualTo(20); |
| |
| bindingEnabled.set(false); |
| assertThat(destProperty.get()).isEqualTo(20); |
| |
| srcProperty.set(30); |
| assertThat(destProperty.get()).isEqualTo(20); |
| |
| srcProperty.set(40); |
| assertThat(destProperty.get()).isEqualTo(20); |
| |
| bindingEnabled.set(true); |
| assertThat(destProperty.get()).isEqualTo(40); |
| |
| srcProperty.set(50); |
| assertThat(destProperty.get()).isEqualTo(50); |
| } |
| } |