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.ObservableBooleanValueStub;
  36 import javafx.beans.value.ObservableObjectValueStub;
  37 
  38 import org.junit.Before;
  39 import org.junit.Test;
  40 
  41 public class ReadOnlyBooleanWrapperTest {
  42 
  43         private static final Boolean UNDEFINED = null;
  44     private static final boolean DEFAULT = false;
  45     private static final boolean VALUE_1 = true;
  46     private static final boolean VALUE_2 = false;
  47         
  48         private ReadOnlyBooleanWrapperMock property;
  49         private ReadOnlyBooleanProperty readOnlyProperty;
  50         private InvalidationListenerMock internalInvalidationListener;
  51         private InvalidationListenerMock publicInvalidationListener;
  52         private ChangeListenerMock<Boolean> internalChangeListener;
  53         private ChangeListenerMock<Boolean> publicChangeListener;
  54         
  55         @Before
  56         public void setUp() throws Exception {
  57                 property = new ReadOnlyBooleanWrapperMock();
  58                 readOnlyProperty = property.getReadOnlyProperty();
  59                 internalInvalidationListener = new InvalidationListenerMock();
  60                 publicInvalidationListener = new InvalidationListenerMock();
  61                 internalChangeListener = new ChangeListenerMock<Boolean>(UNDEFINED);
  62                 publicChangeListener = new ChangeListenerMock<Boolean>(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 ReadOnlyBooleanWrapper p1 = new ReadOnlyBooleanWrapper();
  89                 assertEquals(DEFAULT, p1.get());
  90                 assertEquals((Boolean)DEFAULT, p1.getValue());
  91                 assertFalse(property.isBound());
  92                 assertEquals(null, p1.getBean());
  93                 assertEquals("", p1.getName());
  94                 final ReadOnlyBooleanProperty r1 = p1.getReadOnlyProperty();
  95                 assertEquals(DEFAULT, r1.get());
  96                 assertEquals((Boolean)DEFAULT, r1.getValue());
  97                 assertEquals(null, r1.getBean());
  98                 assertEquals("", r1.getName());
  99         }
 100         
 101         @Test
 102         public void testConstructor_InitialValue() {
 103                 final ReadOnlyBooleanWrapper p1 = new ReadOnlyBooleanWrapper(VALUE_1);
 104                 assertEquals(VALUE_1, p1.get());
 105                 assertEquals((Boolean)VALUE_1, p1.getValue());
 106                 assertFalse(property.isBound());
 107                 assertEquals(null, p1.getBean());
 108                 assertEquals("", p1.getName());
 109                 final ReadOnlyBooleanProperty r1 = p1.getReadOnlyProperty();
 110                 assertEquals(VALUE_1, r1.get());
 111                 assertEquals((Boolean)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 ReadOnlyBooleanWrapper p1 = new ReadOnlyBooleanWrapper(bean, name);
 121                 assertEquals(DEFAULT, p1.get());
 122                 assertEquals((Boolean)DEFAULT, p1.getValue());
 123                 assertFalse(property.isBound());
 124                 assertEquals(bean, p1.getBean());
 125                 assertEquals(name, p1.getName());
 126                 final ReadOnlyBooleanProperty r1 = p1.getReadOnlyProperty();
 127                 assertEquals(DEFAULT, r1.get());
 128                 assertEquals((Boolean)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 ReadOnlyBooleanWrapper p1 = new ReadOnlyBooleanWrapper(bean, name, VALUE_1);
 138                 assertEquals(VALUE_1, p1.get());
 139                 assertEquals((Boolean)VALUE_1, p1.getValue());
 140                 assertFalse(property.isBound());
 141                 assertEquals(bean, p1.getBean());
 142                 assertEquals(name, p1.getName());
 143                 final ReadOnlyBooleanProperty r1 = p1.getReadOnlyProperty();
 144                 assertEquals(VALUE_1, r1.get());
 145                 assertEquals((Boolean)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, VALUE_2, 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, VALUE_2, 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, VALUE_2, 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 BooleanProperty v = new SimpleBooleanProperty(VALUE_1);
 321                 property.bind(v);
 322                 property.set(VALUE_1);
 323         }
 324 
 325         @Test
 326         public void testLazyBind_primitive() {
 327                 attachInvalidationListeners();
 328                 final ObservableBooleanValueStub v = new ObservableBooleanValueStub(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 ObservableBooleanValueStub v = new ObservableBooleanValueStub(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, VALUE_2, 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 ObservableBooleanValueStub v = new ObservableBooleanValueStub(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, VALUE_2, 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<Boolean> v = new ObservableObjectValueStub<Boolean>(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<Boolean> v = new ObservableObjectValueStub<Boolean>(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, VALUE_2, 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<Boolean> v = new ObservableObjectValueStub<Boolean>(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, VALUE_2, 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 BooleanProperty v1 = new SimpleBooleanProperty(VALUE_1);
 558                 final BooleanProperty v2 = new SimpleBooleanProperty(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 BooleanProperty v = new SimpleBooleanProperty(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 BooleanProperty v = new SimpleBooleanProperty(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 ReadOnlyBooleanWrapper v1 = new ReadOnlyBooleanWrapper();
 688                 v1.removeListener(internalInvalidationListener);
 689                 v1.removeListener(internalChangeListener);
 690         }
 691         
 692         @Test
 693         public void testNoReadOnlyPropertyCreated() {
 694                 final BooleanProperty v1 = new SimpleBooleanProperty(VALUE_1);
 695                 final ReadOnlyBooleanWrapper p1 = new ReadOnlyBooleanWrapper();
 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 BooleanProperty v1 = new SimpleBooleanProperty(VALUE_1);
 707                 
 708                 property.set(VALUE_1);
 709                 assertEquals("BooleanProperty [value: " + VALUE_1 + "]", property.toString());
 710                 assertEquals("ReadOnlyBooleanProperty [value: " + VALUE_1 + "]", readOnlyProperty.toString());
 711                 
 712                 property.bind(v1);
 713                 assertEquals("BooleanProperty [bound, invalid]", property.toString());
 714                 assertEquals("ReadOnlyBooleanProperty [value: " + VALUE_1 + "]", readOnlyProperty.toString());
 715                 property.get();
 716                 assertEquals("BooleanProperty [bound, value: " + VALUE_1 + "]", property.toString());
 717                 assertEquals("ReadOnlyBooleanProperty [value: " + VALUE_1 + "]", readOnlyProperty.toString());
 718                 v1.set(VALUE_2);
 719                 assertEquals("BooleanProperty [bound, invalid]", property.toString());
 720                 assertEquals("ReadOnlyBooleanProperty [value: " + VALUE_2 + "]", readOnlyProperty.toString());
 721                 property.get();
 722                 assertEquals("BooleanProperty [bound, value: " + VALUE_2 + "]", property.toString());
 723                 assertEquals("ReadOnlyBooleanProperty [value: " + VALUE_2 + "]", readOnlyProperty.toString());
 724                 
 725                 final Object bean = new Object();
 726                 final String name = "My name";
 727                 final ReadOnlyBooleanWrapper v2 = new ReadOnlyBooleanWrapper(bean, name);
 728                 assertEquals("BooleanProperty [bean: " + bean.toString() + ", name: My name, value: " + DEFAULT + "]", v2.toString());
 729                 assertEquals("ReadOnlyBooleanProperty [bean: " + bean.toString() + ", name: My name, value: " + DEFAULT + "]", v2.getReadOnlyProperty().toString());
 730                 
 731                 final ReadOnlyBooleanWrapper v3 = new ReadOnlyBooleanWrapper(bean, "");
 732                 assertEquals("BooleanProperty [bean: " + bean.toString() + ", value: " + DEFAULT + "]", v3.toString());
 733                 assertEquals("ReadOnlyBooleanProperty [bean: " + bean.toString() + ", value: " + DEFAULT + "]", v3.getReadOnlyProperty().toString());
 734 
 735                 final ReadOnlyBooleanWrapper v4 = new ReadOnlyBooleanWrapper(null, name);
 736                 assertEquals("BooleanProperty [name: My name, value: " + DEFAULT + "]", v4.toString());
 737                 assertEquals("ReadOnlyBooleanProperty [name: My name, value: " + DEFAULT + "]", v4.getReadOnlyProperty().toString());
 738         }
 739         
 740         private static class ReadOnlyBooleanWrapperMock extends ReadOnlyBooleanWrapper {
 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 }