Package jfxtras.labs.util

Source Code of jfxtras.labs.util.HeterogeneousBidirectionalBinderTest

package jfxtras.labs.util;

import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.junit.Assert;
import org.junit.Test;

import java.util.function.Function;

import static org.mockito.Mockito.mock;

/**
* Few simple tests for heterogeneous binders:
* <ul>
*     <li>simpleBindingTest: Checks that the binding works and can be deactivated</li>
*     <li>conflictingBinding: Creates and unbinds multiple binders and make sure the results are correct</li>
*     <li>multipleConflictingBinders: Creates multiple binders and shows that the results are predictable but confusing</li>
* </ul>
* Created by carrknight on 4/26/14.
*/
public class HeterogeneousBidirectionalBinderTest {
    private static enum TestEnum{ NEGATIVE,POSITIVE}

    @Test
    public void simpleBindingTest() throws Exception {
        //binding an enum and a number
        Property<TestEnum> enumProperty = new SimpleObjectProperty<>(TestEnum.NEGATIVE);
        Property<Number> integerProperty = new SimpleIntegerProperty(10);
        Function<Number,TestEnum> toEnum = number -> number.intValue()>=0 ? TestEnum.POSITIVE : TestEnum.NEGATIVE;
        Function<TestEnum,Number> toNumber = testEnum -> testEnum.equals(TestEnum.POSITIVE) ? 1 : -1;
        //create the binding
        HeterogeneousBidirectionalBinder<TestEnum,Number> binder =
                new HeterogeneousBidirectionalBinder<>(enumProperty,integerProperty,toNumber,toEnum);
        //like the original double-binding, when binder is created the property1 is set to property 2
        Assert.assertEquals(TestEnum.POSITIVE, enumProperty.getValue());

        //if i change the integer property, i will see enum property change
        integerProperty.setValue(-5);
        Assert.assertEquals(TestEnum.NEGATIVE, enumProperty.getValue());
        integerProperty.setValue(5);
        Assert.assertEquals(TestEnum.POSITIVE, enumProperty.getValue());
        integerProperty.setValue(-5);
        Assert.assertEquals(TestEnum.NEGATIVE,enumProperty.getValue());

        //if I change the enum, i will change the integer
        enumProperty.setValue(TestEnum.POSITIVE);
        Assert.assertEquals(integerProperty.getValue().intValue(),1);
        enumProperty.setValue(TestEnum.NEGATIVE);
        Assert.assertEquals(integerProperty.getValue().intValue(),-1);

        //if i unbind, this stops being true
        binder.unbind(); //notice that it's not the static method that gets called
        integerProperty.setValue(5);
        Assert.assertEquals(TestEnum.NEGATIVE, enumProperty.getValue());
        enumProperty.setValue(TestEnum.POSITIVE);
        Assert.assertEquals(integerProperty.getValue().intValue(),5);


    }

    @Test
    public void conflictingBinding() throws Exception {
        //binding an enum and a number
        Property<TestEnum> enumProperty = new SimpleObjectProperty<>(TestEnum.NEGATIVE);
        Property<Number> integerProperty = new SimpleIntegerProperty(10);
        //the usual transfomers
        Function<Number, TestEnum> toEnum = number -> number.intValue() >= 0 ? TestEnum.POSITIVE : TestEnum.NEGATIVE;
        Function<TestEnum, Number> toNumber = testEnum -> testEnum.equals(TestEnum.POSITIVE) ? 1 : -1;
        //the inverse transformers: take a positive and call it negative
        Function<Number, TestEnum> toEnum2 = number -> number.intValue() < 0 ? TestEnum.POSITIVE : TestEnum.NEGATIVE;
        Function<TestEnum, Number> toNumber2 = testEnum -> testEnum.equals(TestEnum.NEGATIVE) ? 1 : -1;
        //create the binding
        HeterogeneousBidirectionalBinder<TestEnum, Number> binder =
                new HeterogeneousBidirectionalBinder<>(enumProperty, integerProperty, toNumber, toEnum);
        //like the original double-binding, when binder is created the property1 is set to property 2
        Assert.assertEquals(TestEnum.POSITIVE, enumProperty.getValue());

        //if i change the integer property, i will see enum property change
        integerProperty.setValue(-5);
        Assert.assertEquals(TestEnum.NEGATIVE, enumProperty.getValue());
        integerProperty.setValue(5);
        Assert.assertEquals(TestEnum.POSITIVE, enumProperty.getValue());
        integerProperty.setValue(-5);
        Assert.assertEquals(TestEnum.NEGATIVE, enumProperty.getValue());

        binder.unbind();
        HeterogeneousBidirectionalBinder<TestEnum, Number> binder2 =
                new HeterogeneousBidirectionalBinder<>(enumProperty, integerProperty, toNumber2, toEnum2);
        integerProperty.setValue(5);
        Assert.assertEquals(TestEnum.NEGATIVE, enumProperty.getValue());
        integerProperty.setValue(-5);
        Assert.assertEquals(TestEnum.POSITIVE, enumProperty.getValue());



        HeterogeneousBidirectionalBinder<TestEnum, Number> binder3 =
                new HeterogeneousBidirectionalBinder<>(enumProperty, integerProperty, toNumber, toEnum);
        binder2.unbind();
        binder.unbind(); //this is ignored. Notice that this is the big difference with the Bindings class since that uses
        //statics all over the place and is forced to use deep equals to unbind correctly.

        integerProperty.setValue(5);
        Assert.assertEquals(TestEnum.POSITIVE, enumProperty.getValue());
        integerProperty.setValue(-5);
        Assert.assertEquals(TestEnum.NEGATIVE, enumProperty.getValue());

        binder3.unbind();




    }

    /**
     * 3 binders all on at the same time is a recipe for weirdness!
     * @throws Exception
     */
    @Test
    public void multipleConflictingBinders() throws Exception {
        //binding an enum and a number
        Property<TestEnum> enumProperty = new SimpleObjectProperty<>(TestEnum.NEGATIVE);
        Property<Number> integerProperty = new SimpleIntegerProperty(10);
        //the usual transfomers
        Function<Number, TestEnum> toEnum = number -> number.intValue() >= 0 ? TestEnum.POSITIVE : TestEnum.NEGATIVE;
        Function<TestEnum, Number> toNumber = testEnum -> testEnum.equals(TestEnum.POSITIVE) ? 1 : -1;
        //the inverse transformers: take a positive and call it negative
        Function<Number, TestEnum> toEnum2 = number -> number.intValue() < 0 ? TestEnum.POSITIVE : TestEnum.NEGATIVE;
        Function<TestEnum, Number> toNumber2 = testEnum -> testEnum.equals(TestEnum.NEGATIVE) ? 1 : -1;
        //create 3 binders: one of them uses normal transformers the other two invert
        HeterogeneousBidirectionalBinder binder1 =
                new HeterogeneousBidirectionalBinder<>(enumProperty, integerProperty, toNumber, toEnum);
        HeterogeneousBidirectionalBinder binder2 =
                new HeterogeneousBidirectionalBinder<>(enumProperty, integerProperty, toNumber2, toEnum2);
        HeterogeneousBidirectionalBinder binder3 =
                new HeterogeneousBidirectionalBinder<>(enumProperty, integerProperty, toNumber2, toEnum2);
        //like the original double-binding, when binder is created the property1 is set to property 2
        integerProperty.setValue(-5); //set the value to -5
        //the second and third binder both flip the enum twice, correctly but confusingly
        Assert.assertEquals(TestEnum.NEGATIVE, enumProperty.getValue());
        enumProperty.setValue(TestEnum.POSITIVE);
        //you get +1 by flipping 1 into -1 and then again into 1
        Assert.assertEquals(1, integerProperty.getValue());

        //now remove binder2
        binder2.unbind();
        //binder 3 is still there flipping values:
        integerProperty.setValue(-5);
        Assert.assertEquals(TestEnum.POSITIVE, enumProperty.getValue()); //only one flip.


        binder1.unbind();
        binder3.unbind();
    }


    @Test
    public void blockWrongInstantiations() throws Exception {
        Property<Number> integer1 = mock(SimpleIntegerProperty.class);
        Property<Number> integer2 = mock(SimpleIntegerProperty.class);
        Function<Number,Number> fakeTransformer = mock(Function.class);
        //expect runtime exceptions

        //can't have two equal properties
        try{
            new HeterogeneousBidirectionalBinder<>(integer1,integer1,fakeTransformer,fakeTransformer);
            Assert.assertTrue(false); //can't be here!
        }
        catch (IllegalArgumentException ignored){}

        //can't have nulls!
        try{
            new HeterogeneousBidirectionalBinder<>(integer1,null,fakeTransformer,fakeTransformer);
            Assert.assertTrue(false); //can't be here!
        }
        catch (IllegalArgumentException ignored){}
        try{
            new HeterogeneousBidirectionalBinder<>(null,null,fakeTransformer,fakeTransformer);
            Assert.assertTrue(false); //can't be here!
        }
        catch (IllegalArgumentException ignored){}
        try{
            new HeterogeneousBidirectionalBinder<>(null,integer1,fakeTransformer,fakeTransformer);
            Assert.assertTrue(false); //can't be here!
        }
        catch (IllegalArgumentException ignored){}

        //can't have null transformers!
        try{
            new HeterogeneousBidirectionalBinder<>(integer1,integer2,fakeTransformer,null);
            Assert.assertTrue(false); //can't be here!
        }
        catch (IllegalArgumentException ignored){}
        try{
            new HeterogeneousBidirectionalBinder<>(integer1,integer2,null,fakeTransformer);
            Assert.assertTrue(false); //can't be here!
        }
        catch (IllegalArgumentException ignored){}
        try{
            new HeterogeneousBidirectionalBinder<>(integer1,integer2,null,null);
            Assert.assertTrue(false); //can't be here!
        }
        catch (IllegalArgumentException ignored){}

    }
}
TOP

Related Classes of jfxtras.labs.util.HeterogeneousBidirectionalBinderTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.