1 /* 2 * Copyright (c) 2010, 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.binding; 27 28 import static org.junit.Assert.*; 29 import javafx.beans.InvalidationListener; 30 import test.javafx.beans.InvalidationListenerMock; 31 import javafx.beans.binding.Bindings; 32 import javafx.beans.binding.BooleanBinding; 33 import javafx.beans.property.BooleanProperty; 34 import javafx.beans.property.SimpleBooleanProperty; 35 import javafx.beans.value.ChangeListener; 36 import javafx.beans.value.ObservableBooleanValue; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 41 public class BindingsBooleanTest { 42 43 private BooleanProperty op1; 44 private BooleanProperty op2; 45 private InvalidationListenerMock observer; 46 47 @Before 48 public void setUp() { 49 op1 = new SimpleBooleanProperty(true); 50 op2 = new SimpleBooleanProperty(false); 51 observer = new InvalidationListenerMock(); 52 } 53 54 @SuppressWarnings("unused") 55 @Test 56 public void testAnd() { 57 final BooleanBinding binding = Bindings.and(op1, op2); 58 binding.addListener(observer); 59 60 // check initial value 61 assertEquals(true && false, binding.get()); 62 DependencyUtils.checkDependencies(binding.getDependencies(), op1, op2); 63 64 // change first operand 65 observer.reset(); 66 op1.set(false); 67 assertEquals(false && false, binding.get()); 68 observer.check(binding, 1); 69 70 // change second operand 71 op1.set(true); // avoid short-circuit invalidation 72 binding.get(); 73 observer.reset(); 74 op2.set(true); 75 assertEquals(true && true, binding.get()); 76 observer.check(binding, 1); 77 78 // last possibility 79 op1.set(false); 80 assertEquals(false && true, binding.get()); 81 observer.check(binding, 1); 82 } 83 84 @Test 85 public void testAnd_Efficiency() { 86 final BooleanBinding binding = Bindings.and(op1, op2); 87 binding.addListener(observer); 88 binding.get(); 89 90 // change both values 91 op1.set(false); 92 op2.set(true); 93 observer.check(binding, 1); 94 95 // check short circuit invalidation 96 op2.set(false); 97 observer.check(null, 0); 98 } 99 100 @SuppressWarnings("unused") 101 @Test 102 public void testAnd_Self() { 103 final BooleanBinding binding = Bindings.and(op1, op1); 104 binding.addListener(observer); 105 106 // check initial value 107 assertEquals(true && true, binding.get()); 108 DependencyUtils.checkDependencies(binding.getDependencies(), op1); 109 110 // change value 111 observer.reset(); 112 op1.set(false); 113 assertEquals(false && false, binding.get()); 114 observer.check(binding, 1); 115 116 // change value again 117 op1.set(true); 118 assertEquals(true && true, binding.get()); 119 observer.check(binding, 1); 120 } 121 122 @Test 123 public void testAnd_WeakReference() { 124 final ObservableBooleanValueMock op1 = new ObservableBooleanValueMock(); 125 final ObservableBooleanValueMock op2 = new ObservableBooleanValueMock(); 126 BooleanBinding binding = Bindings.and(op1, op2); 127 assertNotNull(op1.listener); 128 assertNotNull(op2.listener); 129 binding = null; 130 System.gc(); 131 op1.fireInvalidationEvent(); 132 assertNull(op1.listener); 133 assertNotNull(op2.listener); 134 op2.fireInvalidationEvent(); 135 assertNull(op1.listener); 136 assertNull(op2.listener); 137 } 138 139 @Test(expected=NullPointerException.class) 140 public void testAnd_null_x() { 141 Bindings.and(null, op1); 142 } 143 144 @Test(expected=NullPointerException.class) 145 public void testAnd_x_null() { 146 Bindings.and(op1, null); 147 } 148 149 @SuppressWarnings("unused") 150 @Test 151 public void testOr() { 152 final BooleanBinding binding = Bindings.or(op1, op2); 153 binding.addListener(observer); 154 155 // check initial value 156 assertEquals(true || false, binding.get()); 157 DependencyUtils.checkDependencies(binding.getDependencies(), op1, op2); 158 159 // change first operand 160 observer.reset(); 161 op1.set(false); 162 assertEquals(false || false, binding.get()); 163 observer.check(binding, 1); 164 165 // change second operand 166 op2.set(true); 167 assertEquals(false || true, binding.get()); 168 observer.check(binding, 1); 169 170 // last possibility 171 op1.set(true); 172 assertEquals(true || true, binding.get()); 173 observer.check(binding, 1); 174 } 175 176 @Test 177 public void testOr_Efficiency() { 178 final BooleanBinding binding = Bindings.or(op1, op2); 179 binding.addListener(observer); 180 binding.get(); 181 182 // change both values 183 op1.set(false); 184 op2.set(true); 185 observer.check(binding, 1); 186 187 // check short circuit invalidation 188 op1.set(true); // force short-circuit invalidation 189 binding.get(); 190 observer.reset(); 191 op2.set(false); 192 observer.check(null, 0); 193 } 194 195 @SuppressWarnings("unused") 196 @Test 197 public void testOr_Self() { 198 final BooleanBinding binding = Bindings.or(op1, op1); 199 binding.addListener(observer); 200 201 // check initial value 202 assertEquals(true || true, binding.get()); 203 DependencyUtils.checkDependencies(binding.getDependencies(), op1); 204 205 // change value 206 observer.reset(); 207 op1.set(false); 208 assertEquals(false || false, binding.get()); 209 observer.check(binding, 1); 210 211 // change value again 212 op1.set(true); 213 assertEquals(true || true, binding.get()); 214 observer.check(binding, 1); 215 } 216 217 @Test 218 public void testOr_WeakReference() { 219 final ObservableBooleanValueMock op1 = new ObservableBooleanValueMock(); 220 final ObservableBooleanValueMock op2 = new ObservableBooleanValueMock(); 221 BooleanBinding binding = Bindings.or(op1, op2); 222 assertNotNull(op1.listener); 223 assertNotNull(op2.listener); 224 binding = null; 225 System.gc(); 226 op1.fireInvalidationEvent(); 227 assertNull(op1.listener); 228 assertNotNull(op2.listener); 229 op2.fireInvalidationEvent(); 230 assertNull(op1.listener); 231 assertNull(op2.listener); 232 } 233 234 @Test(expected=NullPointerException.class) 235 public void testOr_null_x() { 236 Bindings.or(null, op1); 237 } 238 239 @Test(expected=NullPointerException.class) 240 public void testOr_x_null() { 241 Bindings.or(op1, null); 242 } 243 244 @Test 245 public void testNot() { 246 final BooleanBinding binding = Bindings.not(op1); 247 binding.addListener(observer); 248 249 // check initial value 250 assertEquals(!true, binding.get()); 251 DependencyUtils.checkDependencies(binding.getDependencies(), op1); 252 253 // change first operand 254 observer.reset(); 255 op1.set(false); 256 assertEquals(!false, binding.get()); 257 observer.check(binding, 1); 258 259 // change again 260 op1.set(true); 261 assertEquals(!true, binding.get()); 262 observer.check(binding, 1); 263 } 264 265 @Test 266 public void testNot_Efficiency() { 267 final BooleanBinding binding = Bindings.not(op1); 268 binding.addListener(observer); 269 binding.get(); 270 271 // change value twice 272 op1.set(false); 273 op1.set(true); 274 observer.check(binding, 1); 275 } 276 277 @Test(expected=NullPointerException.class) 278 public void testNot_null() { 279 Bindings.not(null); 280 } 281 282 @Test 283 public void testEqual() { 284 final BooleanBinding binding = Bindings.equal(op1, op2); 285 binding.addListener(observer); 286 287 // check initial value 288 assertEquals(true == false, binding.get()); 289 DependencyUtils.checkDependencies(binding.getDependencies(), op1, op2); 290 291 // change first operand 292 observer.reset(); 293 op1.set(false); 294 assertEquals(false == false, binding.get()); 295 observer.check(binding, 1); 296 297 // change second operand 298 op2.set(true); 299 assertEquals(false == true, binding.get()); 300 observer.check(binding, 1); 301 302 // last possibility 303 op1.set(true); 304 assertEquals(true == true, binding.get()); 305 observer.check(binding, 1); 306 } 307 308 @Test 309 public void testEqual_Efficiency() { 310 final BooleanBinding binding = Bindings.equal(op1, op2); 311 binding.addListener(observer); 312 binding.get(); 313 314 // change both values 315 op1.set(false); 316 op2.set(true); 317 observer.check(binding, 1); 318 } 319 320 @Test 321 public void testEqual_Self() { 322 final BooleanBinding binding = Bindings.equal(op1, op1); 323 binding.addListener(observer); 324 325 // check initial value 326 assertEquals(true == true, binding.get()); 327 DependencyUtils.checkDependencies(binding.getDependencies(), op1); 328 329 // change value 330 observer.reset(); 331 op1.set(false); 332 assertEquals(false == false, binding.get()); 333 observer.check(binding, 1); 334 335 // change value again 336 op1.set(true); 337 assertEquals(true == true, binding.get()); 338 observer.check(binding, 1); 339 } 340 341 @Test(expected=NullPointerException.class) 342 public void testEqual_null_x() { 343 Bindings.equal((ObservableBooleanValue)null, op1); 344 } 345 346 @Test(expected=NullPointerException.class) 347 public void testEqual_x_null() { 348 Bindings.equal(op1, (ObservableBooleanValue)null); 349 } 350 351 @Test 352 public void testNotEqual() { 353 final BooleanBinding binding = Bindings.notEqual(op1, op2); 354 binding.addListener(observer); 355 356 // check initial value 357 assertEquals(true != false, binding.get()); 358 DependencyUtils.checkDependencies(binding.getDependencies(), op1, op2); 359 360 // change first operand 361 observer.reset(); 362 op1.set(false); 363 assertEquals(false != false, binding.get()); 364 observer.check(binding, 1); 365 366 // change second operand 367 op2.set(true); 368 assertEquals(false != true, binding.get()); 369 observer.check(binding, 1); 370 371 // last possibility 372 op1.set(true); 373 assertEquals(true != true, binding.get()); 374 observer.check(binding, 1); 375 } 376 377 private static class ObservableBooleanValueMock implements ObservableBooleanValue { 378 private InvalidationListener listener; 379 380 @Override 381 public boolean get() { 382 return false; 383 } 384 385 @Override 386 public Boolean getValue() { 387 return Boolean.FALSE; 388 } 389 390 private void fireInvalidationEvent() { 391 if (listener == null) { 392 fail("Attempt to fire an event with no listener attached"); 393 } 394 this.listener.invalidated(this); 395 } 396 397 @Override 398 public void addListener(ChangeListener<? super Boolean> listener) { 399 // not used 400 } 401 402 @Override 403 public void removeListener(ChangeListener<? super Boolean> listener) { 404 // not used 405 } 406 407 @Override 408 public void addListener(InvalidationListener listener) { 409 if ((this.listener != null) && !this.listener.equals(listener)) { 410 fail("More than one listener set in mock."); 411 } 412 this.listener = listener; 413 } 414 415 @Override 416 public void removeListener(InvalidationListener listener) { 417 if (this.listener != listener) { 418 fail("Attempt to remove unknown listener"); 419 } 420 this.listener = null; 421 } 422 423 } 424 }