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.FloatProperty; 29 import javafx.beans.property.FloatPropertyBase; 30 import javafx.beans.property.SimpleFloatProperty; 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.ObservableFloatValueStub; 38 import javafx.beans.value.ObservableValueStub; 39 40 import org.junit.Before; 41 import org.junit.Test; 42 43 public class FloatPropertyBaseTest { 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 Float UNDEFINED = Float.MAX_VALUE; 49 private static final float EPSILON = 1e-6f; 50 private static final float PI = (float)Math.PI; 51 private static final float E = (float)Math.E; 52 53 private FloatPropertyMock property; 54 private InvalidationListenerMock invalidationListener; 55 private ChangeListenerMock<Number> changeListener; 56 57 @Before 58 public void setUp() throws Exception { 59 property = new FloatPropertyMock(); 60 invalidationListener = new InvalidationListenerMock(); 61 changeListener = new ChangeListenerMock<Number>(UNDEFINED); 62 } 63 64 private void attachInvalidationListener() { 65 property.addListener(invalidationListener); 66 property.get(); 67 invalidationListener.reset(); 68 } 69 70 private void attachChangeListener() { 71 property.addListener(changeListener); 72 property.get(); 73 changeListener.reset(); 74 } 75 76 @Test 77 public void testConstructor() { 78 final FloatProperty p1 = new SimpleFloatProperty(); 79 assertEquals(0.0f, p1.get(), EPSILON); 80 assertEquals(Float.valueOf(0.0f), p1.getValue(), EPSILON); 81 assertFalse(property.isBound()); 82 83 final FloatProperty p2 = new SimpleFloatProperty(-PI); 84 assertEquals(-PI, p2.get(), EPSILON); 85 assertEquals(Float.valueOf(-PI), p2.getValue(), EPSILON); 86 assertFalse(property.isBound()); 87 } 88 89 @Test 90 public void testInvalidationListener() { 91 attachInvalidationListener(); 92 property.set(E); 93 invalidationListener.check(property, 1); 94 property.removeListener(invalidationListener); 95 invalidationListener.reset(); 96 property.set(PI); 97 invalidationListener.check(null, 0); 98 } 99 100 @Test 101 public void testChangeListener() { 102 attachChangeListener(); 103 property.set(E); 104 changeListener.check(property, 0.0f, E, 1); 105 property.removeListener(changeListener); 106 changeListener.reset(); 107 property.set(PI); 108 changeListener.check(null, UNDEFINED, UNDEFINED, 0); 109 } 110 111 @Test 112 public void testLazySet() { 113 attachInvalidationListener(); 114 115 // set value once 116 property.set(E); 117 assertEquals(E, property.get(), EPSILON); 118 property.check(1); 119 invalidationListener.check(property, 1); 120 121 // set same value again 122 property.set(E); 123 assertEquals(E, property.get(), EPSILON); 124 property.check(0); 125 invalidationListener.check(null, 0); 126 127 // set value twice without reading 128 property.set(PI); 129 property.set(-PI); 130 assertEquals(-PI, property.get(), EPSILON); 131 property.check(1); 132 invalidationListener.check(property, 1); 133 } 134 135 @Test 136 public void testEagerSet() { 137 attachChangeListener(); 138 139 // set value once 140 property.set(E); 141 assertEquals(E, property.get(), EPSILON); 142 property.check(1); 143 changeListener.check(property, 0.0f, E, 1); 144 145 // set same value again 146 property.set(E); 147 assertEquals(E, property.get(), EPSILON); 148 property.check(0); 149 changeListener.check(null, UNDEFINED, UNDEFINED, 0); 150 151 // set value twice without reading 152 property.set(PI); 153 property.set(-PI); 154 assertEquals(-PI, property.get(), EPSILON); 155 property.check(2); 156 changeListener.check(property, PI, -PI, 2); 157 } 158 159 @Test 160 public void testLazySetValue() { 161 attachInvalidationListener(); 162 163 // set value once 164 property.setValue(E); 165 assertEquals(E, property.get(), EPSILON); 166 property.check(1); 167 invalidationListener.check(property, 1); 168 169 // set same value again 170 property.setValue(E); 171 assertEquals(E, property.get(), EPSILON); 172 property.check(0); 173 invalidationListener.check(null, 0); 174 175 // set value twice without reading 176 property.setValue(PI); 177 property.setValue(-PI); 178 assertEquals(-PI, property.get(), EPSILON); 179 property.check(1); 180 invalidationListener.check(property, 1); 181 } 182 183 @Test 184 public void testEagerSetValue() { 185 attachChangeListener(); 186 187 // set value once 188 property.setValue(E); 189 assertEquals(E, property.get(), EPSILON); 190 property.check(1); 191 changeListener.check(property, 0.0f, E, 1); 192 193 // set same value again 194 property.setValue(E); 195 assertEquals(E, property.get(), EPSILON); 196 property.check(0); 197 changeListener.check(null, UNDEFINED, UNDEFINED, 0); 198 199 // set value twice without reading 200 property.setValue(PI); 201 property.setValue(-PI); 202 assertEquals(-PI, property.get(), EPSILON); 203 property.check(2); 204 changeListener.check(property, PI, -PI, 2); 205 } 206 207 @Test(expected=RuntimeException.class) 208 public void testSetBoundValue() { 209 final FloatProperty v = new SimpleFloatProperty(PI); 210 property.bind(v); 211 property.set(PI); 212 } 213 214 @Test 215 public void testLazyBind() { 216 attachInvalidationListener(); 217 final FloatProperty v = new SimpleFloatProperty(PI); 218 property.reset(); 219 220 property.bind(v); 221 assertEquals(PI, property.get(), EPSILON); 222 assertTrue(property.isBound()); 223 property.check(1); 224 invalidationListener.check(property, 1); 225 226 // change binding once 227 v.set(E); 228 assertEquals(E, property.get(), EPSILON); 229 property.check(1); 230 invalidationListener.check(property, 1); 231 232 // change binding twice without reading 233 v.set(PI); 234 v.set(-PI); 235 assertEquals(-PI, property.get(), EPSILON); 236 property.check(1); 237 invalidationListener.check(property, 1); 238 239 // change binding twice to same value 240 v.set(PI); 241 v.set(PI); 242 assertEquals(PI, property.get(), EPSILON); 243 property.check(1); 244 invalidationListener.check(property, 1); 245 } 246 247 @Test 248 public void testEagerBind() { 249 attachChangeListener(); 250 final ObservableFloatValueStub v = new ObservableFloatValueStub(PI); 251 property.reset(); 252 253 property.bind(v); 254 assertEquals(PI, property.get(), EPSILON); 255 assertTrue(property.isBound()); 256 property.check(1); 257 changeListener.check(property, 0.0f, PI, 1); 258 259 // change binding once 260 v.set(E); 261 assertEquals(E, property.get(), EPSILON); 262 property.check(1); 263 changeListener.check(property, PI, E, 1); 264 265 // change binding twice without reading 266 v.set(PI); 267 v.set(-PI); 268 assertEquals(-PI, property.get(), EPSILON); 269 property.check(2); 270 changeListener.check(property, PI, -PI, 2); 271 272 // change binding twice to same value 273 v.set(PI); 274 v.set(PI); 275 assertEquals(PI, property.get(), EPSILON); 276 property.check(2); 277 changeListener.check(property, -PI, PI, 1); 278 } 279 280 @Test 281 public void testLazyBindObservableValue() { 282 final float value1 = (float)Math.PI; 283 final float value2 = (float)Math.E; 284 attachInvalidationListener(); 285 final ObservableValueStub<Number> v = new ObservableValueStub<Number>(value1); 286 287 property.bind(v); 288 assertEquals(value1, property.get(), EPSILON); 289 assertTrue(property.isBound()); 290 property.check(1); 291 invalidationListener.check(property, 1); 292 293 // change binding once 294 v.set(value2); 295 assertEquals(value2, property.get(), EPSILON); 296 property.check(1); 297 invalidationListener.check(property, 1); 298 299 // change binding twice without reading 300 v.set(value1); 301 v.set(value2); 302 assertEquals(value2, property.get(), EPSILON); 303 property.check(1); 304 invalidationListener.check(property, 1); 305 306 // change binding twice to same value 307 v.set(value1); 308 v.set(value1); 309 assertEquals(value1, property.get(), EPSILON); 310 property.check(1); 311 invalidationListener.check(property, 1); 312 313 // set binding to null 314 v.set(null); 315 assertEquals(0.0f, property.get(), EPSILON); 316 property.check(1); 317 invalidationListener.check(property, 1); 318 } 319 320 @Test 321 public void testEagerBindObservableValue() { 322 final float value1 = (float)Math.PI; 323 final float value2 = (float)Math.E; 324 attachChangeListener(); 325 final ObservableValueStub<Number> v = new ObservableValueStub<Number>(value1); 326 327 property.bind(v); 328 assertEquals(value1, property.get(), EPSILON); 329 assertTrue(property.isBound()); 330 property.check(1); 331 changeListener.check(property, 0.0f, value1, 1); 332 333 // change binding once 334 v.set(value2); 335 assertEquals(value2, property.get(), EPSILON); 336 property.check(1); 337 changeListener.check(property, value1, value2, 1); 338 339 // change binding twice without reading 340 v.set(value1); 341 v.set(value2); 342 assertEquals(value2, property.get(), EPSILON); 343 property.check(2); 344 changeListener.check(property, value1, value2, 2); 345 346 // change binding twice to same value 347 v.set(value1); 348 v.set(value1); 349 assertEquals(value1, property.get(), EPSILON); 350 property.check(2); 351 changeListener.check(property, value2, value1, 1); 352 353 // set binding to null 354 v.set(null); 355 assertEquals(0.0f, property.get(), EPSILON); 356 property.check(1); 357 changeListener.check(property, value1, 0.0f, 1); 358 } 359 360 @Test(expected=NullPointerException.class) 361 public void testBindToNull() { 362 property.bind(null); 363 } 364 365 @Test 366 public void testRebind() { 367 attachInvalidationListener(); 368 final FloatProperty v1 = new SimpleFloatProperty(PI); 369 final FloatProperty v2 = new SimpleFloatProperty(E); 370 property.bind(v1); 371 property.get(); 372 property.reset(); 373 invalidationListener.reset(); 374 375 // rebind causes invalidation event 376 property.bind(v2); 377 assertEquals(E, property.get(), EPSILON); 378 assertTrue(property.isBound()); 379 assertEquals(1, property.counter); 380 invalidationListener.check(property, 1); 381 property.reset(); 382 383 // change old binding 384 v1.set(-PI); 385 assertEquals(E, property.get(), EPSILON); 386 assertEquals(0, property.counter); 387 invalidationListener.check(null, 0); 388 property.reset(); 389 390 // change new binding 391 v2.set(-E); 392 assertEquals(-E, property.get(), EPSILON); 393 assertEquals(1, property.counter); 394 invalidationListener.check(property, 1); 395 property.reset(); 396 397 // rebind to same observable should have no effect 398 property.bind(v2); 399 assertEquals(-E, property.get(), EPSILON); 400 assertTrue(property.isBound()); 401 assertEquals(0, property.counter); 402 invalidationListener.check(null, 0); 403 } 404 405 @Test 406 public void testUnbind() { 407 attachInvalidationListener(); 408 final FloatProperty v = new SimpleFloatProperty(PI); 409 property.bind(v); 410 property.unbind(); 411 assertEquals(PI, property.get(), EPSILON); 412 assertFalse(property.isBound()); 413 property.reset(); 414 invalidationListener.reset(); 415 416 // change binding 417 v.set(E); 418 assertEquals(PI, property.get(), EPSILON); 419 assertEquals(0, property.counter); 420 invalidationListener.check(null, 0); 421 property.reset(); 422 423 // set value 424 property.set(-PI); 425 assertEquals(-PI, property.get(), EPSILON); 426 assertEquals(1, property.counter); 427 invalidationListener.check(property, 1); 428 } 429 430 @Test 431 public void testUnbindObservableValue() { 432 final float value1 = (float)Math.PI; 433 final float value2 = (float)Math.E; 434 435 attachInvalidationListener(); 436 final ObservableValueStub<Number> v = new ObservableValueStub<Number>(value1); 437 property.bind(v); 438 property.unbind(); 439 assertEquals(value1, property.get(), EPSILON); 440 assertFalse(property.isBound()); 441 property.reset(); 442 invalidationListener.reset(); 443 444 // change binding 445 v.set(value2); 446 assertEquals(value1, property.get(), EPSILON); 447 assertEquals(0, property.counter); 448 invalidationListener.check(null, 0); 449 property.reset(); 450 451 // set value 452 property.set(value2); 453 assertEquals(value2, property.get(), EPSILON); 454 assertEquals(1, property.counter); 455 invalidationListener.check(property, 1); 456 } 457 458 @Test 459 public void testAddingListenerWillAlwaysReceiveInvalidationEvent() { 460 final FloatProperty v = new SimpleFloatProperty(PI); 461 final InvalidationListenerMock listener2 = new InvalidationListenerMock(); 462 final InvalidationListenerMock listener3 = new InvalidationListenerMock(); 463 464 // setting the property 465 property.set(PI); 466 property.addListener(listener2); 467 listener2.reset(); 468 property.set(-PI); 469 listener2.check(property, 1); 470 471 // binding the property 472 property.bind(v); 473 v.set(E); 474 property.addListener(listener3); 475 v.get(); 476 listener3.reset(); 477 v.set(-E); 478 listener3.check(property, 1); 479 } 480 481 @Test 482 public void testToString() { 483 final float value1 = (float)Math.E; 484 final float value2 = (float)-Math.PI; 485 final FloatProperty v = new SimpleFloatProperty(value2); 486 487 property.set(value1); 488 assertEquals("FloatProperty [value: " + value1 + "]", property.toString()); 489 490 property.bind(v); 491 assertEquals("FloatProperty [bound, invalid]", property.toString()); 492 property.get(); 493 assertEquals("FloatProperty [bound, value: " + value2 + "]", property.toString()); 494 v.set(value1); 495 assertEquals("FloatProperty [bound, invalid]", property.toString()); 496 property.get(); 497 assertEquals("FloatProperty [bound, value: " + value1 + "]", property.toString()); 498 499 final Object bean = new Object(); 500 final String name = "My name"; 501 final FloatProperty v1 = new FloatPropertyMock(bean, name); 502 assertEquals("FloatProperty [bean: " + bean.toString() + ", name: My name, value: " + 0.0f + "]", v1.toString()); 503 v1.set(value1); 504 assertEquals("FloatProperty [bean: " + bean.toString() + ", name: My name, value: " + value1 + "]", v1.toString()); 505 506 final FloatProperty v2 = new FloatPropertyMock(bean, NO_NAME_1); 507 assertEquals("FloatProperty [bean: " + bean.toString() + ", value: " + 0.0f + "]", v2.toString()); 508 v2.set(value1); 509 assertEquals("FloatProperty [bean: " + bean.toString() + ", value: " + value1 + "]", v2.toString()); 510 511 final FloatProperty v3 = new FloatPropertyMock(bean, NO_NAME_2); 512 assertEquals("FloatProperty [bean: " + bean.toString() + ", value: " + 0.0f + "]", v3.toString()); 513 v3.set(value1); 514 assertEquals("FloatProperty [bean: " + bean.toString() + ", value: " + value1 + "]", v3.toString()); 515 516 final FloatProperty v4 = new FloatPropertyMock(NO_BEAN, name); 517 assertEquals("FloatProperty [name: My name, value: " + 0.0f + "]", v4.toString()); 518 v4.set(value1); 519 assertEquals("FloatProperty [name: My name, value: " + value1 + "]", v4.toString()); 520 } 521 522 private static class FloatPropertyMock extends FloatPropertyBase { 523 524 private final Object bean; 525 private final String name; 526 private int counter; 527 528 private FloatPropertyMock() { 529 this.bean = NO_BEAN; 530 this.name = NO_NAME_1; 531 } 532 533 private FloatPropertyMock(Object bean, String name) { 534 this.bean = bean; 535 this.name = name; 536 } 537 538 @Override 539 protected void invalidated() { 540 counter++; 541 } 542 543 private void check(int expected) { 544 assertEquals(expected, counter); 545 reset(); 546 } 547 548 private void reset() { 549 counter = 0; 550 } 551 552 @Override public Object getBean() { return bean; } 553 554 @Override public String getName() { return name; } 555 } 556 557 }