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 
  29 import javafx.beans.property.LongProperty;
  30 import javafx.beans.property.ReadOnlyLongProperty;
  31 import javafx.beans.property.ReadOnlyLongWrapper;
  32 import javafx.beans.property.SimpleLongProperty;
  33 import static org.junit.Assert.assertEquals;
  34 import static org.junit.Assert.assertFalse;
  35 import static org.junit.Assert.assertTrue;
  36 
  37 import test.javafx.beans.InvalidationListenerMock;
  38 import test.javafx.beans.value.ChangeListenerMock;
  39 import javafx.beans.value.ObservableLongValueStub;
  40 import javafx.beans.value.ObservableObjectValueStub;
  41 
  42 import org.junit.Before;
  43 import org.junit.Test;
  44 
  45 public class ReadOnlyLongWrapperTest {
  46 
  47     private static final Long UNDEFINED = null;
  48     private static final long DEFAULT = 0L;
  49     private static final long VALUE_1 = 890987654321L;
  50     private static final long VALUE_2 = 2123456789098L;
  51     
  52     private ReadOnlyLongWrapperMock property;
  53     private ReadOnlyLongProperty readOnlyProperty;
  54     private InvalidationListenerMock internalInvalidationListener;
  55     private InvalidationListenerMock publicInvalidationListener;
  56     private ChangeListenerMock<Number> internalChangeListener;
  57     private ChangeListenerMock<Number> publicChangeListener;
  58     
  59     @Before
  60     public void setUp() throws Exception {
  61         property = new ReadOnlyLongWrapperMock();
  62         readOnlyProperty = property.getReadOnlyProperty();
  63         internalInvalidationListener = new InvalidationListenerMock();
  64         publicInvalidationListener = new InvalidationListenerMock();
  65         internalChangeListener = new ChangeListenerMock<Number>(UNDEFINED);
  66         publicChangeListener = new ChangeListenerMock<Number>(UNDEFINED);
  67     }
  68     
  69     private void attachInvalidationListeners() {
  70         property.addListener(internalInvalidationListener);
  71         readOnlyProperty.addListener(publicInvalidationListener);
  72         property.get();
  73         readOnlyProperty.get();
  74         internalInvalidationListener.reset();
  75         publicInvalidationListener.reset();
  76     }
  77 
  78     private void attachInternalChangeListener() {
  79         property.addListener(internalChangeListener);
  80         property.get();
  81         internalChangeListener.reset();
  82     }
  83 
  84     private void attachPublicChangeListener() {
  85         readOnlyProperty.addListener(publicChangeListener);
  86         readOnlyProperty.get();
  87         publicChangeListener.reset();
  88     }
  89 
  90     @Test
  91     public void testConstructor_NoArguments() {
  92         final ReadOnlyLongWrapper p1 = new ReadOnlyLongWrapper();
  93         assertEquals(DEFAULT, p1.get());
  94         assertEquals((Long)DEFAULT, p1.getValue());
  95         assertFalse(property.isBound());
  96         assertEquals(null, p1.getBean());
  97         assertEquals("", p1.getName());
  98         final ReadOnlyLongProperty r1 = p1.getReadOnlyProperty();
  99         assertEquals(DEFAULT, r1.get());
 100         assertEquals((Long)DEFAULT, r1.getValue());
 101         assertEquals(null, r1.getBean());
 102         assertEquals("", r1.getName());
 103     }
 104     
 105     @Test
 106     public void testConstructor_InitialValue() {
 107         final ReadOnlyLongWrapper p1 = new ReadOnlyLongWrapper(VALUE_1);
 108         assertEquals(VALUE_1, p1.get());
 109         assertEquals((Long)VALUE_1, p1.getValue());
 110         assertFalse(property.isBound());
 111         assertEquals(null, p1.getBean());
 112         assertEquals("", p1.getName());
 113         final ReadOnlyLongProperty r1 = p1.getReadOnlyProperty();
 114         assertEquals(VALUE_1, r1.get());
 115         assertEquals((Long)VALUE_1, r1.getValue());
 116         assertEquals(null, r1.getBean());
 117         assertEquals("", r1.getName());
 118     }
 119     
 120     @Test
 121     public void testConstructor_Bean_Name() {
 122         final Object bean = new Object();
 123         final String name = "My name";
 124         final ReadOnlyLongWrapper p1 = new ReadOnlyLongWrapper(bean, name);
 125         assertEquals(DEFAULT, p1.get());
 126         assertEquals((Long)DEFAULT, p1.getValue());
 127         assertFalse(property.isBound());
 128         assertEquals(bean, p1.getBean());
 129         assertEquals(name, p1.getName());
 130         final ReadOnlyLongProperty r1 = p1.getReadOnlyProperty();
 131         assertEquals(DEFAULT, r1.get());
 132         assertEquals((Long)DEFAULT, r1.getValue());
 133         assertEquals(bean, r1.getBean());
 134         assertEquals(name, r1.getName());
 135     }
 136     
 137     @Test
 138     public void testConstructor_Bean_Name_InitialValue() {
 139         final Object bean = new Object();
 140         final String name = "My name";
 141         final ReadOnlyLongWrapper p1 = new ReadOnlyLongWrapper(bean, name, VALUE_1);
 142         assertEquals(VALUE_1, p1.get());
 143         assertEquals((Long)VALUE_1, p1.getValue());
 144         assertFalse(property.isBound());
 145         assertEquals(bean, p1.getBean());
 146         assertEquals(name, p1.getName());
 147         final ReadOnlyLongProperty r1 = p1.getReadOnlyProperty();
 148         assertEquals(VALUE_1, r1.get());
 149         assertEquals((Long)VALUE_1, r1.getValue());
 150         assertEquals(bean, r1.getBean());
 151         assertEquals(name, r1.getName());
 152     }
 153 
 154     @Test
 155     public void testLazySet() {
 156         attachInvalidationListeners();
 157         
 158         // set value once
 159         property.set(VALUE_1);
 160         assertEquals(VALUE_1, property.get());
 161         property.check(1);
 162         internalInvalidationListener.check(property, 1);
 163         assertEquals(VALUE_1, readOnlyProperty.get());
 164         publicInvalidationListener.check(readOnlyProperty, 1);
 165         
 166         // set same value again
 167         property.set(VALUE_1);
 168         assertEquals(VALUE_1, property.get());
 169         property.check(0);
 170         internalInvalidationListener.check(null, 0);
 171         assertEquals(VALUE_1, readOnlyProperty.get());
 172         publicInvalidationListener.check(null, 0);
 173         
 174         // set value twice without reading
 175         property.set(VALUE_2);
 176         property.set(VALUE_1);
 177         assertEquals(VALUE_1, property.get());
 178         property.check(1);
 179         internalInvalidationListener.check(property, 1);
 180         assertEquals(VALUE_1, readOnlyProperty.get());
 181         publicInvalidationListener.check(readOnlyProperty, 1);
 182     }
 183     
 184     @Test
 185     public void testInternalEagerSet() {
 186         attachInternalChangeListener();
 187         
 188         // set value once
 189         property.set(VALUE_1);
 190         assertEquals(VALUE_1, property.get());
 191         property.check(1);
 192         internalChangeListener.check(property, DEFAULT, VALUE_1, 1);
 193         assertEquals(VALUE_1, readOnlyProperty.get());
 194         
 195         // set same value again
 196         property.set(VALUE_1);
 197         assertEquals(VALUE_1, property.get());
 198         property.check(0);
 199         internalChangeListener.check(null, UNDEFINED, UNDEFINED, 0);
 200         assertEquals(VALUE_1, readOnlyProperty.get());
 201         
 202         // set value twice without reading
 203         property.set(VALUE_2);
 204         property.set(VALUE_1);
 205         assertEquals(VALUE_1, property.get());
 206         property.check(2);
 207         internalChangeListener.check(property, VALUE_2, VALUE_1, 2);
 208         assertEquals(VALUE_1, readOnlyProperty.get());
 209     }
 210     
 211     @Test
 212     public void testPublicEagerSet() {
 213         attachPublicChangeListener();
 214         
 215         // set value once
 216         property.set(VALUE_1);
 217         assertEquals(VALUE_1, property.get());
 218         property.check(1);
 219         assertEquals(VALUE_1, readOnlyProperty.get());
 220         publicChangeListener.check(readOnlyProperty, DEFAULT, VALUE_1, 1);
 221         
 222         // set same value again
 223         property.set(VALUE_1);
 224         assertEquals(VALUE_1, property.get());
 225         property.check(0);
 226         assertEquals(VALUE_1, readOnlyProperty.get());
 227         publicChangeListener.check(null, UNDEFINED, UNDEFINED, 0);
 228         
 229         // set value twice without reading
 230         property.set(VALUE_2);
 231         property.set(VALUE_1);
 232         assertEquals(VALUE_1, property.get());
 233         property.check(2);
 234         assertEquals(VALUE_1, readOnlyProperty.get());
 235         publicChangeListener.check(readOnlyProperty, VALUE_2, VALUE_1, 2);
 236     }
 237 
 238     @Test
 239     public void testLazySetValue() {
 240         attachInvalidationListeners();
 241         
 242         // set value once
 243         property.setValue(VALUE_1);
 244         assertEquals(VALUE_1, property.get());
 245         property.check(1);
 246         internalInvalidationListener.check(property, 1);
 247         assertEquals(VALUE_1, readOnlyProperty.get());
 248         publicInvalidationListener.check(readOnlyProperty, 1);
 249         
 250         // set same value again
 251         property.setValue(VALUE_1);
 252         assertEquals(VALUE_1, property.get());
 253         property.check(0);
 254         internalInvalidationListener.check(null, 0);
 255         assertEquals(VALUE_1, readOnlyProperty.get());
 256         publicInvalidationListener.check(null, 0);
 257         
 258         // set value twice without reading
 259         property.setValue(VALUE_2);
 260         property.setValue(VALUE_1);
 261         assertEquals(VALUE_1, property.get());
 262         property.check(1);
 263         internalInvalidationListener.check(property, 1);
 264         assertEquals(VALUE_1, readOnlyProperty.get());
 265         publicInvalidationListener.check(readOnlyProperty, 1);
 266     }
 267     
 268     @Test
 269     public void testInternalEagerSetValue() {
 270         attachInternalChangeListener();
 271         
 272         // set value once
 273         property.setValue(VALUE_1);
 274         assertEquals(VALUE_1, property.get());
 275         property.check(1);
 276         internalChangeListener.check(property, DEFAULT, VALUE_1, 1);
 277         assertEquals(VALUE_1, readOnlyProperty.get());
 278         
 279         // set same value again
 280         property.setValue(VALUE_1);
 281         assertEquals(VALUE_1, property.get());
 282         property.check(0);
 283         internalChangeListener.check(null, UNDEFINED, UNDEFINED, 0);
 284         assertEquals(VALUE_1, readOnlyProperty.get());
 285         
 286         // set value twice without reading
 287         property.setValue(VALUE_2);
 288         property.setValue(VALUE_1);
 289         assertEquals(VALUE_1, property.get());
 290         property.check(2);
 291         internalChangeListener.check(property, VALUE_2, VALUE_1, 2);
 292         assertEquals(VALUE_1, readOnlyProperty.get());
 293     }
 294     
 295     @Test
 296     public void testPublicEagerSetValue() {
 297         attachPublicChangeListener();
 298         
 299         // set value once
 300         property.setValue(VALUE_1);
 301         assertEquals(VALUE_1, property.get());
 302         property.check(1);
 303         assertEquals(VALUE_1, readOnlyProperty.get());
 304         publicChangeListener.check(readOnlyProperty, DEFAULT, VALUE_1, 1);
 305         
 306         // set same value again
 307         property.setValue(VALUE_1);
 308         assertEquals(VALUE_1, property.get());
 309         property.check(0);
 310         assertEquals(VALUE_1, readOnlyProperty.get());
 311         publicChangeListener.check(null, UNDEFINED, UNDEFINED, 0);
 312         
 313         // set value twice without reading
 314         property.setValue(VALUE_2);
 315         property.setValue(VALUE_1);
 316         assertEquals(VALUE_1, property.get());
 317         property.check(2);
 318         assertEquals(VALUE_1, readOnlyProperty.get());
 319         publicChangeListener.check(readOnlyProperty, VALUE_2, VALUE_1, 2);
 320     }
 321     
 322     @Test(expected=RuntimeException.class)
 323     public void testSetBoundValue() {
 324         final LongProperty v = new SimpleLongProperty(VALUE_1);
 325         property.bind(v);
 326         property.set(VALUE_1);
 327     }
 328 
 329     @Test
 330     public void testLazyBind_primitive() {
 331         attachInvalidationListeners();
 332         final ObservableLongValueStub v = new ObservableLongValueStub(VALUE_1);
 333 
 334         property.bind(v);
 335         assertEquals(VALUE_1, property.get());
 336         assertTrue(property.isBound());
 337         property.check(1);
 338         internalInvalidationListener.check(property, 1);
 339         assertEquals(VALUE_1, readOnlyProperty.get());
 340         publicInvalidationListener.check(readOnlyProperty, 1);
 341 
 342         // change binding once
 343         v.set(VALUE_2);
 344         assertEquals(VALUE_2, property.get());
 345         property.check(1);
 346         internalInvalidationListener.check(property, 1);
 347         assertEquals(VALUE_2, readOnlyProperty.get());
 348         publicInvalidationListener.check(readOnlyProperty, 1);
 349 
 350         // change binding twice without reading
 351         v.set(VALUE_1);
 352         v.set(VALUE_2);
 353         assertEquals(VALUE_2, property.get());
 354         property.check(1);
 355         internalInvalidationListener.check(property, 1);
 356         assertEquals(VALUE_2, readOnlyProperty.get());
 357         publicInvalidationListener.check(readOnlyProperty, 1);
 358 
 359         // change binding twice to same value
 360         v.set(VALUE_1);
 361         v.set(VALUE_1);
 362         assertEquals(VALUE_1, property.get());
 363         property.check(1);
 364         internalInvalidationListener.check(property, 1);
 365         assertEquals(VALUE_1, readOnlyProperty.get());
 366         publicInvalidationListener.check(readOnlyProperty, 1);
 367     }
 368 
 369     @Test
 370     public void testInternalEagerBind_primitive() {
 371         attachInternalChangeListener();
 372         final ObservableLongValueStub v = new ObservableLongValueStub(VALUE_1);
 373 
 374         property.bind(v);
 375         assertEquals(VALUE_1, property.get());
 376         assertTrue(property.isBound());
 377         property.check(1);
 378         internalChangeListener.check(property, DEFAULT, VALUE_1, 1);
 379         assertEquals(VALUE_1, readOnlyProperty.get());
 380 
 381         // change binding once
 382         v.set(VALUE_2);
 383         assertEquals(VALUE_2, property.get());
 384         property.check(1);
 385         internalChangeListener.check(property, VALUE_1, VALUE_2, 1);
 386         assertEquals(VALUE_2, readOnlyProperty.get());
 387 
 388         // change binding twice without reading
 389         v.set(VALUE_1);
 390         v.set(VALUE_2);
 391         assertEquals(VALUE_2, property.get());
 392         property.check(2);
 393         internalChangeListener.check(property, VALUE_1, VALUE_2, 2);
 394         assertEquals(VALUE_2, readOnlyProperty.get());
 395 
 396         // change binding twice to same value
 397         v.set(VALUE_1);
 398         v.set(VALUE_1);
 399         assertEquals(VALUE_1, property.get());
 400         property.check(2);
 401         internalChangeListener.check(property, VALUE_2, VALUE_1, 1);
 402         assertEquals(VALUE_1, readOnlyProperty.get());
 403     }
 404     
 405     @Test
 406     public void testPublicEagerBind_primitive() {
 407         attachPublicChangeListener();
 408         final ObservableLongValueStub v = new ObservableLongValueStub(VALUE_1);
 409 
 410         property.bind(v);
 411         assertEquals(VALUE_1, property.get());
 412         assertTrue(property.isBound());
 413         property.check(1);
 414         assertEquals(VALUE_1, readOnlyProperty.get());
 415         publicChangeListener.check(readOnlyProperty, DEFAULT, VALUE_1, 1);
 416 
 417         // change binding once
 418         v.set(VALUE_2);
 419         assertEquals(VALUE_2, property.get());
 420         property.check(1);
 421         assertEquals(VALUE_2, readOnlyProperty.get());
 422         publicChangeListener.check(readOnlyProperty, VALUE_1, VALUE_2, 1);
 423 
 424         // change binding twice without reading
 425         v.set(VALUE_1);
 426         v.set(VALUE_2);
 427         assertEquals(VALUE_2, property.get());
 428         property.check(2);
 429         assertEquals(VALUE_2, readOnlyProperty.get());
 430         publicChangeListener.check(readOnlyProperty, VALUE_1, VALUE_2, 2);
 431 
 432         // change binding twice to same value
 433         v.set(VALUE_1);
 434         v.set(VALUE_1);
 435         assertEquals(VALUE_1, property.get());
 436         property.check(2);
 437         assertEquals(VALUE_1, readOnlyProperty.get());
 438         publicChangeListener.check(readOnlyProperty, VALUE_2, VALUE_1, 1);
 439     }
 440     
 441     @Test
 442     public void testLazyBind_generic() {
 443         attachInvalidationListeners();
 444         final ObservableObjectValueStub<Long> v = new ObservableObjectValueStub<Long>(VALUE_1);
 445 
 446         property.bind(v);
 447         assertEquals(VALUE_1, property.get());
 448         assertTrue(property.isBound());
 449         property.check(1);
 450         internalInvalidationListener.check(property, 1);
 451         assertEquals(VALUE_1, readOnlyProperty.get());
 452         publicInvalidationListener.check(readOnlyProperty, 1);
 453 
 454         // change binding once
 455         v.set(VALUE_2);
 456         assertEquals(VALUE_2, property.get());
 457         property.check(1);
 458         internalInvalidationListener.check(property, 1);
 459         assertEquals(VALUE_2, readOnlyProperty.get());
 460         publicInvalidationListener.check(readOnlyProperty, 1);
 461 
 462         // change binding twice without reading
 463         v.set(VALUE_1);
 464         v.set(VALUE_2);
 465         assertEquals(VALUE_2, property.get());
 466         property.check(1);
 467         internalInvalidationListener.check(property, 1);
 468         assertEquals(VALUE_2, readOnlyProperty.get());
 469         publicInvalidationListener.check(readOnlyProperty, 1);
 470 
 471         // change binding twice to same value
 472         v.set(VALUE_1);
 473         v.set(VALUE_1);
 474         assertEquals(VALUE_1, property.get());
 475         property.check(1);
 476         internalInvalidationListener.check(property, 1);
 477         assertEquals(VALUE_1, readOnlyProperty.get());
 478         publicInvalidationListener.check(readOnlyProperty, 1);
 479     }
 480 
 481     @Test
 482     public void testInternalEagerBind_generic() {
 483         attachInternalChangeListener();
 484         final ObservableObjectValueStub<Long> v = new ObservableObjectValueStub<Long>(VALUE_1);
 485 
 486         property.bind(v);
 487         assertEquals(VALUE_1, property.get());
 488         assertTrue(property.isBound());
 489         property.check(1);
 490         internalChangeListener.check(property, DEFAULT, VALUE_1, 1);
 491         assertEquals(VALUE_1, readOnlyProperty.get());
 492 
 493         // change binding once
 494         v.set(VALUE_2);
 495         assertEquals(VALUE_2, property.get());
 496         property.check(1);
 497         internalChangeListener.check(property, VALUE_1, VALUE_2, 1);
 498         assertEquals(VALUE_2, readOnlyProperty.get());
 499 
 500         // change binding twice without reading
 501         v.set(VALUE_1);
 502         v.set(VALUE_2);
 503         assertEquals(VALUE_2, property.get());
 504         property.check(2);
 505         internalChangeListener.check(property, VALUE_1, VALUE_2, 2);
 506         assertEquals(VALUE_2, readOnlyProperty.get());
 507 
 508         // change binding twice to same value
 509         v.set(VALUE_1);
 510         v.set(VALUE_1);
 511         assertEquals(VALUE_1, property.get());
 512         property.check(2);
 513         internalChangeListener.check(property, VALUE_2, VALUE_1, 1);
 514         assertEquals(VALUE_1, readOnlyProperty.get());
 515     }
 516 
 517     @Test
 518     public void testPublicEagerBind_generic() {
 519         attachPublicChangeListener();
 520         final ObservableObjectValueStub<Long> v = new ObservableObjectValueStub<Long>(VALUE_1);
 521 
 522         property.bind(v);
 523         assertEquals(VALUE_1, property.get());
 524         assertTrue(property.isBound());
 525         property.check(1);
 526         assertEquals(VALUE_1, readOnlyProperty.get());
 527         publicChangeListener.check(readOnlyProperty, DEFAULT, VALUE_1, 1);
 528 
 529         // change binding once
 530         v.set(VALUE_2);
 531         assertEquals(VALUE_2, property.get());
 532         property.check(1);
 533         assertEquals(VALUE_2, readOnlyProperty.get());
 534         publicChangeListener.check(readOnlyProperty, VALUE_1, VALUE_2, 1);
 535 
 536         // change binding twice without reading
 537         v.set(VALUE_1);
 538         v.set(VALUE_2);
 539         assertEquals(VALUE_2, property.get());
 540         property.check(2);
 541         assertEquals(VALUE_2, readOnlyProperty.get());
 542         publicChangeListener.check(readOnlyProperty, VALUE_1, VALUE_2, 2);
 543 
 544         // change binding twice to same value
 545         v.set(VALUE_1);
 546         v.set(VALUE_1);
 547         assertEquals(VALUE_1, property.get());
 548         property.check(2);
 549         assertEquals(VALUE_1, readOnlyProperty.get());
 550         publicChangeListener.check(readOnlyProperty, VALUE_2, VALUE_1, 1);
 551     }
 552     
 553     @Test(expected=NullPointerException.class)
 554     public void testBindToNull() {
 555         property.bind(null);
 556     }
 557 
 558     @Test
 559     public void testRebind() {
 560         attachInvalidationListeners();
 561         final LongProperty v1 = new SimpleLongProperty(VALUE_1);
 562         final LongProperty v2 = new SimpleLongProperty(VALUE_2);
 563         property.bind(v1);
 564         property.get();
 565         readOnlyProperty.get();
 566         property.reset();
 567         internalInvalidationListener.reset();
 568         publicInvalidationListener.reset();
 569         
 570         // rebind causes invalidation event
 571         property.bind(v2);
 572         assertEquals(VALUE_2, property.get());
 573         assertTrue(property.isBound());
 574         property.check(1);
 575         internalInvalidationListener.check(property, 1);
 576         assertEquals(VALUE_2, readOnlyProperty.get());
 577         publicInvalidationListener.check(readOnlyProperty, 1);
 578         
 579         // change new binding
 580         v2.set(VALUE_1);
 581         assertEquals(VALUE_1, property.get());
 582         property.check(1);
 583         internalInvalidationListener.check(property, 1);
 584         assertEquals(VALUE_1, readOnlyProperty.get());
 585         publicInvalidationListener.check(readOnlyProperty, 1);
 586         
 587         // change old binding
 588         v1.set(VALUE_2);
 589         assertEquals(VALUE_1, property.get());
 590         property.check(0);
 591         internalInvalidationListener.check(null, 0);
 592         assertEquals(VALUE_1, readOnlyProperty.get());
 593         publicInvalidationListener.check(null, 0);
 594         
 595         // rebind to same observable should have no effect
 596         property.bind(v2);
 597         assertEquals(VALUE_1, property.get());
 598         assertTrue(property.isBound());
 599         property.check(0);
 600         internalInvalidationListener.check(null, 0);
 601         assertEquals(VALUE_1, readOnlyProperty.get());
 602         publicInvalidationListener.check(null, 0);
 603     }
 604 
 605     @Test
 606     public void testUnbind() {
 607         attachInvalidationListeners();
 608         final LongProperty v = new SimpleLongProperty(VALUE_1);
 609         property.bind(v);
 610         property.unbind();
 611         assertEquals(VALUE_1, property.get());
 612         assertFalse(property.isBound());
 613         assertEquals(VALUE_1, readOnlyProperty.get());
 614         property.reset();
 615         internalInvalidationListener.reset();
 616         publicInvalidationListener.reset();
 617         
 618         // change binding
 619         v.set(VALUE_2);
 620         assertEquals(VALUE_1, property.get());
 621         property.check(0);
 622         internalInvalidationListener.check(null, 0);
 623         assertEquals(VALUE_1, readOnlyProperty.get());
 624         publicInvalidationListener.check(null, 0);
 625         
 626         // set value
 627         property.set(VALUE_2);
 628         assertEquals(VALUE_2, property.get());
 629         property.check(1);
 630         internalInvalidationListener.check(property, 1);
 631         assertEquals(VALUE_2, readOnlyProperty.get());
 632         publicInvalidationListener.check(readOnlyProperty, 1);
 633     }
 634     
 635     @Test
 636     public void testAddingListenerWillAlwaysReceiveInvalidationEvent() {
 637         final LongProperty v = new SimpleLongProperty(VALUE_1);
 638         final InvalidationListenerMock internalListener2 = new InvalidationListenerMock();
 639         final InvalidationListenerMock internalListener3 = new InvalidationListenerMock();
 640         final InvalidationListenerMock publicListener2 = new InvalidationListenerMock();
 641         final InvalidationListenerMock publicListener3 = new InvalidationListenerMock();
 642 
 643         // setting the property,checking internal
 644         property.set(VALUE_1);
 645         property.addListener(internalListener2);
 646         internalListener2.reset();
 647         property.set(VALUE_2);
 648         internalListener2.check(property, 1);
 649         
 650         // setting the property, checking public
 651         property.set(VALUE_1);
 652         readOnlyProperty.addListener(publicListener2);
 653         publicListener2.reset();
 654         property.set(VALUE_2);
 655         publicListener2.check(readOnlyProperty, 1);
 656         
 657         // binding the property, checking internal
 658         property.bind(v);
 659         v.set(VALUE_2);
 660         property.addListener(internalListener3);
 661         v.get();
 662         internalListener3.reset();
 663         v.set(VALUE_1);
 664         internalListener3.check(property, 1);
 665         
 666         // binding the property, checking public
 667         property.bind(v);
 668         v.set(VALUE_2);
 669         readOnlyProperty.addListener(publicListener3);
 670         v.get();
 671         publicListener3.reset();
 672         v.set(VALUE_1);
 673         publicListener3.check(readOnlyProperty, 1);
 674     }
 675     
 676     @Test
 677     public void testRemoveListeners() {
 678         attachInvalidationListeners();
 679         attachInternalChangeListener();
 680         property.removeListener(internalInvalidationListener);
 681         property.removeListener(internalChangeListener);
 682         property.get();
 683         internalInvalidationListener.reset();
 684         internalChangeListener.reset();
 685         
 686         property.set(VALUE_1);
 687         internalInvalidationListener.check(null, 0);
 688         internalChangeListener.check(null, UNDEFINED, UNDEFINED, 0);
 689         
 690         // no read only property created => no-op
 691         final ReadOnlyLongWrapper v1 = new ReadOnlyLongWrapper();
 692         v1.removeListener(internalInvalidationListener);
 693         v1.removeListener(internalChangeListener);
 694     }
 695     
 696     @Test
 697     public void testNoReadOnlyPropertyCreated() {
 698         final LongProperty v1 = new SimpleLongProperty(VALUE_1);
 699         final ReadOnlyLongWrapper p1 = new ReadOnlyLongWrapper();
 700         
 701         p1.set(VALUE_1);
 702         p1.bind(v1);
 703         assertEquals(VALUE_1, p1.get());
 704         v1.set(VALUE_2);
 705         assertEquals(VALUE_2, p1.get());
 706     }
 707     
 708     @Test
 709     public void testToString() {
 710         final LongProperty v1 = new SimpleLongProperty(VALUE_1);
 711         
 712         property.set(VALUE_1);
 713         assertEquals("LongProperty [value: " + VALUE_1 + "]", property.toString());
 714         assertEquals("ReadOnlyLongProperty [value: " + VALUE_1 + "]", readOnlyProperty.toString());
 715         
 716         property.bind(v1);
 717         assertEquals("LongProperty [bound, invalid]", property.toString());
 718         assertEquals("ReadOnlyLongProperty [value: " + VALUE_1 + "]", readOnlyProperty.toString());
 719         property.get();
 720         assertEquals("LongProperty [bound, value: " + VALUE_1 + "]", property.toString());
 721         assertEquals("ReadOnlyLongProperty [value: " + VALUE_1 + "]", readOnlyProperty.toString());
 722         v1.set(VALUE_2);
 723         assertEquals("LongProperty [bound, invalid]", property.toString());
 724         assertEquals("ReadOnlyLongProperty [value: " + VALUE_2 + "]", readOnlyProperty.toString());
 725         property.get();
 726         assertEquals("LongProperty [bound, value: " + VALUE_2 + "]", property.toString());
 727         assertEquals("ReadOnlyLongProperty [value: " + VALUE_2 + "]", readOnlyProperty.toString());
 728         
 729         final Object bean = new Object();
 730         final String name = "My name";
 731         final ReadOnlyLongWrapper v2 = new ReadOnlyLongWrapper(bean, name);
 732         assertEquals("LongProperty [bean: " + bean.toString() + ", name: My name, value: " + DEFAULT + "]", v2.toString());
 733         assertEquals("ReadOnlyLongProperty [bean: " + bean.toString() + ", name: My name, value: " + DEFAULT + "]", v2.getReadOnlyProperty().toString());
 734         
 735         final ReadOnlyLongWrapper v3 = new ReadOnlyLongWrapper(bean, "");
 736         assertEquals("LongProperty [bean: " + bean.toString() + ", value: " + DEFAULT + "]", v3.toString());
 737         assertEquals("ReadOnlyLongProperty [bean: " + bean.toString() + ", value: " + DEFAULT + "]", v3.getReadOnlyProperty().toString());
 738 
 739         final ReadOnlyLongWrapper v4 = new ReadOnlyLongWrapper(null, name);
 740         assertEquals("LongProperty [name: My name, value: " + DEFAULT + "]", v4.toString());
 741         assertEquals("ReadOnlyLongProperty [name: My name, value: " + DEFAULT + "]", v4.getReadOnlyProperty().toString());
 742     }
 743     
 744     private static class ReadOnlyLongWrapperMock extends ReadOnlyLongWrapper {
 745         
 746         private int counter;
 747         
 748         @Override
 749         protected void invalidated() {
 750             counter++;
 751         }
 752         
 753         private void check(int expected) {
 754             assertEquals(expected, counter);
 755             reset();
 756         }
 757         
 758         private void reset() {
 759             counter = 0;
 760         }
 761     }
 762 }