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