1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.beans.property;
  27 
  28 import javafx.beans.property.LongProperty;
  29 import javafx.beans.property.LongPropertyBase;
  30 import javafx.beans.property.SimpleLongProperty;
  31 import static org.junit.Assert.assertEquals;
  32 import static org.junit.Assert.assertFalse;
  33 import static org.junit.Assert.assertTrue;
  34 
  35 import test.javafx.beans.InvalidationListenerMock;
  36 import test.javafx.beans.value.ChangeListenerMock;
  37 import javafx.beans.value.ObservableLongValueStub;
  38 import javafx.beans.value.ObservableValueStub;
  39 
  40 import org.junit.Before;
  41 import org.junit.Test;
  42 
  43 public class LongPropertyBaseTest {
  44 
  45     private static final Object NO_BEAN = null;
  46     private static final String NO_NAME_1 = null;
  47     private static final String NO_NAME_2 = "";
  48     private static final Long UNDEFINED = Long.MAX_VALUE;
  49         private static final long VALUE_1 = 42;
  50         private static final long VALUE_2 = 12345;
  51         
  52         private LongPropertyMock property;
  53         private InvalidationListenerMock invalidationListener;
  54         private ChangeListenerMock<Number> changeListener;
  55 
  56         @Before
  57         public void setUp() throws Exception {
  58                 property = new LongPropertyMock();
  59                 invalidationListener = new InvalidationListenerMock();
  60         changeListener = new ChangeListenerMock<Number>(UNDEFINED);
  61         }
  62 
  63         private void attachInvalidationListener() {
  64                 property.addListener(invalidationListener);
  65                 property.get();
  66                 invalidationListener.reset();
  67         }
  68 
  69         private void attachChangeListener() {
  70                 property.addListener(changeListener);
  71                 property.get();
  72                 changeListener.reset();
  73         }
  74 
  75         @Test
  76         public void testConstructor() {
  77                 final LongProperty p1 = new SimpleLongProperty();
  78                 assertEquals(0, p1.get());
  79                 assertEquals(Long.valueOf(0), p1.getValue());
  80                 assertFalse(property.isBound());
  81                 
  82                 final LongProperty p2 = new SimpleLongProperty(-VALUE_1);
  83                 assertEquals(-VALUE_1, p2.get());
  84                 assertEquals(Long.valueOf(-VALUE_1), p2.getValue());
  85                 assertFalse(property.isBound());
  86         }
  87 
  88     @Test
  89     public void testInvalidationListener() {
  90         attachInvalidationListener();
  91         property.set(VALUE_2);
  92         invalidationListener.check(property, 1);
  93         property.removeListener(invalidationListener);
  94         invalidationListener.reset();
  95         property.set(VALUE_1);
  96         invalidationListener.check(null, 0);
  97     }
  98 
  99     @Test
 100     public void testChangeListener() {
 101         attachChangeListener();
 102         property.set(VALUE_2);
 103         changeListener.check(property, 0L, VALUE_2, 1);
 104         property.removeListener(changeListener);
 105         changeListener.reset();
 106         property.set(VALUE_1);
 107         changeListener.check(null, UNDEFINED, UNDEFINED, 0);
 108     }
 109 
 110         @Test
 111         public void testLazySet() {
 112                 attachInvalidationListener();
 113 
 114                 // set value once
 115                 property.set(VALUE_2);
 116                 assertEquals(VALUE_2, property.get());
 117                 property.check(1);
 118                 invalidationListener.check(property, 1);
 119 
 120                 // set same value again
 121                 property.set(VALUE_2);
 122                 assertEquals(VALUE_2, property.get());
 123                 property.check(0);
 124                 invalidationListener.check(null, 0);
 125 
 126                 // set value twice without reading
 127                 property.set(VALUE_1);
 128                 property.set(-VALUE_1);
 129                 assertEquals(-VALUE_1, property.get());
 130                 property.check(1);
 131                 invalidationListener.check(property, 1);
 132         }
 133 
 134         @Test
 135         public void testEagerSet() {
 136                 attachChangeListener();
 137 
 138                 // set value once
 139                 property.set(VALUE_2);
 140                 assertEquals(VALUE_2, property.get());
 141                 property.check(1);
 142                 changeListener.check(property, 0L, VALUE_2, 1);
 143 
 144                 // set same value again
 145                 property.set(VALUE_2);
 146                 assertEquals(VALUE_2, property.get());
 147                 property.check(0);
 148                 changeListener.check(null, UNDEFINED, UNDEFINED, 0);
 149 
 150                 // set value twice without reading
 151                 property.set(VALUE_1);
 152                 property.set(-VALUE_1);
 153                 assertEquals(-VALUE_1, property.get());
 154                 property.check(2);
 155                 changeListener.check(property, VALUE_1, -VALUE_1, 2);
 156         }
 157 
 158         @Test
 159         public void testLazySetValue() {
 160                 attachInvalidationListener();
 161 
 162                 // set value once
 163                 property.setValue(VALUE_2);
 164                 assertEquals(VALUE_2, property.get());
 165                 property.check(1);
 166                 invalidationListener.check(property, 1);
 167 
 168                 // set same value again
 169                 property.setValue(VALUE_2);
 170                 assertEquals(VALUE_2, property.get());
 171                 property.check(0);
 172                 invalidationListener.check(null, 0);
 173 
 174                 // set value twice without reading
 175                 property.setValue(VALUE_1);
 176                 property.setValue(-VALUE_1);
 177                 assertEquals(-VALUE_1, property.get());
 178                 property.check(1);
 179                 invalidationListener.check(property, 1);
 180         }
 181 
 182         @Test
 183         public void testEagerSetValue() {
 184                 attachChangeListener();
 185 
 186                 // set value once
 187                 property.setValue(VALUE_2);
 188                 assertEquals(VALUE_2, property.get());
 189                 property.check(1);
 190                 changeListener.check(property, 0L, VALUE_2, 1);
 191 
 192                 // set same value again
 193                 property.setValue(VALUE_2);
 194                 assertEquals(VALUE_2, property.get());
 195                 property.check(0);
 196                 changeListener.check(null, UNDEFINED, UNDEFINED, 0);
 197 
 198                 // set value twice without reading
 199                 property.setValue(VALUE_1);
 200                 property.setValue(-VALUE_1);
 201                 assertEquals(-VALUE_1, property.get());
 202                 property.check(2);
 203                 changeListener.check(property, VALUE_1, -VALUE_1, 2);
 204         }
 205 
 206         @Test(expected=RuntimeException.class)
 207         public void testSetBoundValue() {
 208                 final LongProperty v = new SimpleLongProperty(VALUE_1);
 209                 property.bind(v);
 210                 property.set(VALUE_1);
 211         }
 212 
 213         @Test
 214         public void testLazyBind() {
 215                 attachInvalidationListener();
 216                 final ObservableLongValueStub v = new ObservableLongValueStub(VALUE_1);
 217 
 218                 property.bind(v);
 219                 assertEquals(VALUE_1, property.get());
 220                 assertTrue(property.isBound());
 221                 property.check(1);
 222                 invalidationListener.check(property, 1);
 223 
 224                 // change binding once
 225                 v.set(VALUE_2);
 226                 assertEquals(VALUE_2, property.get());
 227                 property.check(1);
 228                 invalidationListener.check(property, 1);
 229 
 230                 // change binding twice without reading
 231                 v.set(VALUE_1);
 232                 v.set(-VALUE_1);
 233                 assertEquals(-VALUE_1, property.get());
 234                 property.check(1);
 235                 invalidationListener.check(property, 1);
 236 
 237                 // change binding twice to same value
 238                 v.set(VALUE_1);
 239                 v.set(VALUE_1);
 240                 assertEquals(VALUE_1, property.get());
 241                 property.check(1);
 242                 invalidationListener.check(property, 1);
 243         }
 244 
 245         @Test
 246         public void testEagerBind() {
 247                 attachChangeListener();
 248                 final ObservableLongValueStub v = new ObservableLongValueStub(VALUE_1);
 249 
 250                 property.bind(v);
 251                 assertEquals(VALUE_1, property.get());
 252                 assertTrue(property.isBound());
 253                 property.check(1);
 254                 changeListener.check(property, 0L, VALUE_1, 1);
 255 
 256                 // change binding once
 257                 v.set(VALUE_2);
 258                 assertEquals(VALUE_2, property.get());
 259                 property.check(1);
 260                 changeListener.check(property, VALUE_1, VALUE_2, 1);
 261 
 262                 // change binding twice without reading
 263                 v.set(VALUE_1);
 264                 v.set(-VALUE_1);
 265                 assertEquals(-VALUE_1, property.get());
 266                 property.check(2);
 267                 changeListener.check(property, VALUE_1, -VALUE_1, 2);
 268 
 269                 // change binding twice to same value
 270                 v.set(VALUE_1);
 271                 v.set(VALUE_1);
 272                 assertEquals(VALUE_1, property.get());
 273                 property.check(2);
 274                 changeListener.check(property, -VALUE_1, VALUE_1, 1);
 275         }
 276 
 277     @Test
 278     public void testLazyBindObservableValue() {
 279         final long value1 = 9876543212345L;
 280         final long value2 = -123456789098765L;
 281         attachInvalidationListener();
 282         final ObservableValueStub<Number> v = new ObservableValueStub<Number>(value1);
 283 
 284         property.bind(v);
 285         assertEquals(value1, property.get());
 286         assertTrue(property.isBound());
 287         property.check(1);
 288         invalidationListener.check(property, 1);
 289 
 290         // change binding once
 291         v.set(value2);
 292         assertEquals(value2, property.get());
 293         property.check(1);
 294         invalidationListener.check(property, 1);
 295 
 296         // change binding twice without reading
 297         v.set(value1);
 298         v.set(value2);
 299         assertEquals(value2, property.get());
 300         property.check(1);
 301         invalidationListener.check(property, 1);
 302 
 303         // change binding twice to same value
 304         v.set(value1);
 305         v.set(value1);
 306         assertEquals(value1, property.get());
 307         property.check(1);
 308         invalidationListener.check(property, 1);
 309 
 310         // set binding to null
 311         v.set(null);
 312         assertEquals(0L, property.get());
 313         property.check(1);
 314         invalidationListener.check(property, 1);
 315     }
 316 
 317     @Test
 318     public void testEagerBindObservableValue() {
 319         final long value1 = 9876543212345L;
 320         final long value2 = -123456789098765L;
 321         attachChangeListener();
 322         final ObservableValueStub<Number> v = new ObservableValueStub<Number>(value1);
 323 
 324         property.bind(v);
 325         assertEquals(value1, property.get());
 326         assertTrue(property.isBound());
 327         property.check(1);
 328         changeListener.check(property, 0L, value1, 1);
 329 
 330         // change binding once
 331         v.set(value2);
 332         assertEquals(value2, property.get());
 333         property.check(1);
 334         changeListener.check(property, value1, value2, 1);
 335 
 336         // change binding twice without reading
 337         v.set(value1);
 338         v.set(value2);
 339         assertEquals(value2, property.get());
 340         property.check(2);
 341         changeListener.check(property, value1, value2, 2);
 342 
 343         // change binding twice to same value
 344         v.set(value1);
 345         v.set(value1);
 346         assertEquals(value1, property.get());
 347         property.check(2);
 348         changeListener.check(property, value2, value1, 1);
 349     }
 350 
 351         @Test(expected=NullPointerException.class)
 352         public void testBindToNull() {
 353                 property.bind(null);
 354         }
 355 
 356         @Test
 357         public void testRebind() {
 358                 attachInvalidationListener();
 359                 final LongProperty v1 = new SimpleLongProperty(VALUE_1);
 360                 final LongProperty v2 = new SimpleLongProperty(VALUE_2);
 361                 property.bind(v1);
 362                 property.get();
 363                 property.reset();
 364                 invalidationListener.reset();
 365                 
 366                 // rebind causes invalidation event
 367                 property.bind(v2);
 368                 assertEquals(VALUE_2, property.get());
 369                 assertTrue(property.isBound());
 370                 assertEquals(1, property.counter);
 371                 invalidationListener.check(property, 1);
 372                 property.reset();
 373                 
 374                 // change old binding
 375                 v1.set(-VALUE_1);
 376                 assertEquals(VALUE_2, property.get());
 377                 assertEquals(0, property.counter);
 378                 invalidationListener.check(null, 0);
 379                 property.reset();
 380                 
 381                 // change new binding
 382                 v2.set(-VALUE_2);
 383                 assertEquals(-VALUE_2, property.get());
 384                 assertEquals(1, property.counter);
 385                 invalidationListener.check(property, 1);
 386                 property.reset();
 387                 
 388                 // rebind to same observable should have no effect
 389                 property.bind(v2);
 390                 assertEquals(-VALUE_2, property.get());
 391                 assertTrue(property.isBound());
 392                 assertEquals(0, property.counter);
 393                 invalidationListener.check(null, 0);
 394         }
 395 
 396         @Test
 397         public void testUnbind() {
 398                 attachInvalidationListener();
 399                 final LongProperty v = new SimpleLongProperty(VALUE_1);
 400                 property.bind(v);
 401                 property.unbind();
 402                 assertEquals(VALUE_1, property.get());
 403                 assertFalse(property.isBound());
 404         property.reset();
 405         invalidationListener.reset();
 406                 
 407                 // change binding
 408                 v.set(VALUE_2);
 409                 assertEquals(VALUE_1, property.get());
 410                 assertEquals(0, property.counter);
 411                 invalidationListener.check(null, 0);
 412                 property.reset();
 413                 
 414                 // set value
 415                 property.set(-VALUE_1);
 416                 assertEquals(-VALUE_1, property.get());
 417                 assertEquals(1, property.counter);
 418                 invalidationListener.check(property, 1);
 419         }
 420     
 421     @Test
 422     public void testUnbindObservableValue() {
 423         final long value1 = 9876543212345L;
 424         final long value2 = -123456789098765L;
 425         
 426         attachInvalidationListener();
 427         final ObservableValueStub<Number> v = new ObservableValueStub<Number>(value1);
 428         property.bind(v);
 429         property.unbind();
 430         assertEquals(value1, property.get());
 431         assertFalse(property.isBound());
 432         property.reset();
 433         invalidationListener.reset();
 434         
 435         // change binding
 436         v.set(value2);
 437         assertEquals(value1, property.get());
 438         assertEquals(0, property.counter);
 439         invalidationListener.check(null, 0);
 440         property.reset();
 441         
 442         // set value
 443         property.set(value2);
 444         assertEquals(value2, property.get());
 445         assertEquals(1, property.counter);
 446         invalidationListener.check(property, 1);
 447     }
 448         
 449         @Test
 450         public void testAddingListenerWillAlwaysReceiveInvalidationEvent() {
 451                 final LongProperty v = new SimpleLongProperty(VALUE_1);
 452                 final InvalidationListenerMock listener2 = new InvalidationListenerMock();
 453                 final InvalidationListenerMock listener3 = new InvalidationListenerMock();
 454 
 455                 // setting the property
 456                 property.set(VALUE_1);
 457                 property.addListener(listener2);
 458                 listener2.reset();
 459                 property.set(-VALUE_1);
 460                 listener2.check(property, 1);
 461                 
 462                 // binding the property
 463                 property.bind(v);
 464                 v.set(VALUE_2);
 465                 property.addListener(listener3);
 466                 v.get();
 467                 listener3.reset();
 468                 v.set(-VALUE_2);
 469                 listener3.check(property, 1);
 470         }
 471         
 472         @Test
 473         public void testToString() {
 474                 final long value1 = 1234567890987654321L;
 475                 final long value2 = -987654321012345678L;
 476                 final LongProperty v = new SimpleLongProperty(value2);
 477                 
 478                 property.set(value1);
 479                 assertEquals("LongProperty [value: " + value1 + "]", property.toString());
 480                 
 481                 property.bind(v);
 482                 assertEquals("LongProperty [bound, invalid]", property.toString());
 483                 property.get();
 484                 assertEquals("LongProperty [bound, value: " + value2 + "]", property.toString());
 485                 v.set(value1);
 486                 assertEquals("LongProperty [bound, invalid]", property.toString());
 487                 property.get();
 488                 assertEquals("LongProperty [bound, value: " + value1 + "]", property.toString());
 489         
 490         final Object bean = new Object();
 491         final String name = "My name";
 492         final LongProperty v1 = new LongPropertyMock(bean, name);
 493         assertEquals("LongProperty [bean: " + bean.toString() + ", name: My name, value: " + 0L + "]", v1.toString());
 494         v1.set(value1);
 495         assertEquals("LongProperty [bean: " + bean.toString() + ", name: My name, value: " + value1 + "]", v1.toString());
 496         
 497         final LongProperty v2 = new LongPropertyMock(bean, NO_NAME_1);
 498         assertEquals("LongProperty [bean: " + bean.toString() + ", value: " + 0L + "]", v2.toString());
 499         v2.set(value1);
 500         assertEquals("LongProperty [bean: " + bean.toString() + ", value: " + value1 + "]", v2.toString());
 501 
 502         final LongProperty v3 = new LongPropertyMock(bean, NO_NAME_2);
 503         assertEquals("LongProperty [bean: " + bean.toString() + ", value: " + 0L + "]", v3.toString());
 504         v3.set(value1);
 505         assertEquals("LongProperty [bean: " + bean.toString() + ", value: " + value1 + "]", v3.toString());
 506 
 507         final LongProperty v4 = new LongPropertyMock(NO_BEAN, name);
 508         assertEquals("LongProperty [name: My name, value: " + 0L + "]", v4.toString());
 509         v4.set(value1);
 510         assertEquals("LongProperty [name: My name, value: " + value1 + "]", v4.toString());
 511         }
 512         
 513         private static class LongPropertyMock extends LongPropertyBase {
 514         
 515         private final Object bean;
 516         private final String name;
 517                 private int counter;
 518                 
 519         private LongPropertyMock() {
 520             this.bean = NO_BEAN;
 521             this.name = NO_NAME_1;
 522         }
 523         
 524         private LongPropertyMock(Object bean, String name) {
 525             this.bean = bean;
 526             this.name = name;
 527         }
 528         
 529                 @Override
 530                 protected void invalidated() {
 531                         counter++;
 532                 }
 533                 
 534                 private void check(int expected) {
 535                         assertEquals(expected, counter);
 536                         reset();
 537                 }
 538 
 539                 private void reset() {
 540                         counter = 0;
 541                 }
 542 
 543         @Override public Object getBean() { return bean; }
 544 
 545         @Override public String getName() { return name; }
 546         }
 547 
 548 }