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