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