1 /*
   2  * Copyright (c) 2014, 2016, 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 package test.javafx.scene.control;
  26 
  27 import static junit.framework.Assert.*;
  28 
  29 import javafx.scene.control.skin.SpinnerSkin;
  30 import javafx.collections.FXCollections;
  31 import javafx.collections.ObservableList;
  32 import org.junit.Before;
  33 import org.junit.Ignore;
  34 import org.junit.Test;
  35 
  36 import java.time.LocalDate;
  37 import java.time.LocalTime;
  38 import java.time.temporal.ChronoUnit;
  39 import javafx.scene.control.Spinner;
  40 import javafx.scene.control.SpinnerShim;
  41 import javafx.scene.control.SpinnerValueFactory;
  42 import javafx.scene.control.SpinnerValueFactoryShim;
  43 
  44 import static javafx.scene.control.SpinnerValueFactoryShim.*;
  45 
  46 public class SpinnerTest {
  47 
  48     private Spinner<?> spinner;
  49 
  50     // --- int spinner
  51     private Spinner<Integer> intSpinner;
  52     private IntegerSpinnerValueFactory intValueFactory;
  53 
  54     // --- double spinner
  55     private Spinner<Double> dblSpinner;
  56     private DoubleSpinnerValueFactory dblValueFactory;
  57 
  58     // --- list spinner
  59     private ObservableList<String> strings;
  60     private Spinner<String> listSpinner;
  61     private ListSpinnerValueFactory listValueFactory;
  62 
  63     // --- LocalDate spinner
  64     private Spinner<LocalDate> localDateSpinner;
  65     private SpinnerValueFactory<LocalDate> localDateValueFactory;
  66 
  67     // --- LocalTime spinner
  68     private Spinner<LocalTime> localTimeSpinner;
  69     private SpinnerValueFactory<LocalTime>localTimeValueFactory;
  70 
  71     // used in tests for counting events, reset to zero in setup()
  72     private int eventCount;
  73 
  74 
  75     @Before public void setup() {
  76         eventCount = 0;
  77         spinner = new Spinner();
  78 
  79         intSpinner = new Spinner<>(0, 10, 5, 1);
  80         intValueFactory = (IntegerSpinnerValueFactory) intSpinner.getValueFactory();
  81 
  82         dblSpinner = new Spinner<>(0.0, 1.0, 0.5, 0.05);
  83         dblValueFactory = (DoubleSpinnerValueFactory) dblSpinner.getValueFactory();
  84 
  85         strings = FXCollections.observableArrayList("string1", "string2", "string3");
  86         listSpinner = new Spinner<>(strings);
  87         listValueFactory = (ListSpinnerValueFactory<String>) listSpinner.getValueFactory();
  88 
  89         // minimum is today minus 10 days, maximum is today plus 10 days
  90         localDateSpinner = SpinnerShim.getSpinnerLocalDate(
  91                 nowPlusDays(-10), nowPlusDays(10),
  92                 LocalDate.now(), 1, ChronoUnit.DAYS);
  93         localDateValueFactory = localDateSpinner.getValueFactory();
  94 
  95         localTimeSpinner = SpinnerShim.getSpinnerLocalTime(
  96                 LocalTime.MIN, LocalTime.MAX,
  97                 LocalTime.now(), 1, ChronoUnit.HOURS);
  98         localTimeValueFactory = localTimeSpinner.getValueFactory();
  99     }
 100 
 101 
 102     /***************************************************************************
 103      *                                                                         *
 104      * Basic tests                                                             *
 105      *                                                                         *
 106      **************************************************************************/
 107 
 108     @Test public void createDefaultSpinner_hasSpinnerStyleClass() {
 109         assertEquals(1, spinner.getStyleClass().size());
 110         assertTrue(spinner.getStyleClass().contains("spinner"));
 111     }
 112 
 113     @Test public void createDefaultSpinner_editorIsNotNull() {
 114         assertNotNull(spinner.getEditor());
 115     }
 116 
 117     @Test public void createDefaultSpinner_valueFactoryIsNull() {
 118         assertNull(spinner.getValueFactory());
 119     }
 120 
 121     @Test public void createDefaultSpinner_valueIsNull() {
 122         assertNull(spinner.getValue());
 123     }
 124 
 125     @Test public void createDefaultSpinner_editableIsFalse() {
 126         assertFalse(spinner.isEditable());
 127     }
 128 
 129     @Ignore("Waiting for StageLoader")
 130     @Test public void createDefaultSpinner_defaultSkinIsInstalled() {
 131         assertTrue(spinner.getSkin() instanceof SpinnerSkin);
 132     }
 133 
 134 
 135     /***************************************************************************
 136      *                                                                         *
 137      * Alternative constructor tests                                           *
 138      *                                                                         *
 139      **************************************************************************/
 140 
 141     @Test public void createIntSpinner_createValidValueFactory() {
 142         Spinner<Integer> intSpinner = new Spinner<Integer>(0, 10, 5, 1);
 143         assertTrue(intSpinner.getValueFactory() instanceof IntegerSpinnerValueFactory);
 144         IntegerSpinnerValueFactory valueFactory = (IntegerSpinnerValueFactory) intSpinner.getValueFactory();
 145         assertEquals(5, (int) valueFactory.getValue());
 146     }
 147 
 148     @Test public void createIntSpinner_setInitialValueOutsideMaxBounds() {
 149         Spinner<Integer> intSpinner = new Spinner<Integer>(0, 10, 100, 1);
 150         assertTrue(intSpinner.getValueFactory() instanceof IntegerSpinnerValueFactory);
 151         IntegerSpinnerValueFactory valueFactory = (IntegerSpinnerValueFactory) intSpinner.getValueFactory();
 152         assertEquals(0, (int) valueFactory.getValue());
 153     }
 154 
 155     @Test public void createIntSpinner_setInitialValueOutsideMinBounds() {
 156         Spinner<Integer> intSpinner = new Spinner<Integer>(0, 10, -100, 1);
 157         assertTrue(intSpinner.getValueFactory() instanceof IntegerSpinnerValueFactory);
 158         IntegerSpinnerValueFactory valueFactory = (IntegerSpinnerValueFactory) intSpinner.getValueFactory();
 159         assertEquals(0, (int) valueFactory.getValue());
 160     }
 161 
 162     @Test public void createListSpinner_createValidValueFactory() {
 163         Spinner<String> stringSpinner = new Spinner<>(FXCollections.observableArrayList("item 1", "item 2"));
 164         assertTrue(stringSpinner.getValueFactory() instanceof ListSpinnerValueFactory);
 165         ListSpinnerValueFactory valueFactory = (ListSpinnerValueFactory) stringSpinner.getValueFactory();
 166         assertEquals("item 1", valueFactory.getValue());
 167     }
 168 
 169     @Test public void createListSpinner_emptyListResultsInNullValue() {
 170         Spinner<String> stringSpinner = new Spinner<String>(FXCollections.observableArrayList());
 171         assertTrue(stringSpinner.getValueFactory() instanceof ListSpinnerValueFactory);
 172         ListSpinnerValueFactory valueFactory = (ListSpinnerValueFactory) stringSpinner.getValueFactory();
 173         assertNull(valueFactory.getValue());
 174     }
 175 
 176     @Test public void createListSpinner_nullListResultsInNullValue() {
 177         Spinner<String> stringSpinner = new Spinner<>((ObservableList<String>)null);
 178         assertTrue(stringSpinner.getValueFactory() instanceof ListSpinnerValueFactory);
 179         ListSpinnerValueFactory valueFactory = (ListSpinnerValueFactory) stringSpinner.getValueFactory();
 180         assertNull(valueFactory.getValue());
 181     }
 182 
 183     @Test public void createSpinner_customSpinnerValueFactory() {
 184         SpinnerValueFactory<String> valueFactory = new ListSpinnerValueFactory<>(FXCollections.observableArrayList("item 1", "item 2"));
 185         Spinner<String> stringSpinner = new Spinner<>(valueFactory);
 186         assertEquals(valueFactory, stringSpinner.getValueFactory());
 187         ListSpinnerValueFactory valueFactory1 = (ListSpinnerValueFactory) stringSpinner.getValueFactory();
 188         assertEquals("item 1", valueFactory.getValue());
 189         assertEquals("item 1", valueFactory1.getValue());
 190     }
 191 
 192 
 193 
 194     /***************************************************************************
 195      *                                                                         *
 196      * increment / decrement tests                                             *
 197      * (we test the actual inc / dec in the value factory impl tests)          *
 198      *                                                                         *
 199      **************************************************************************/
 200 
 201     @Test(expected = IllegalStateException.class)
 202     public void expectExceptionWhenNoArgsIncrementCalled_noValueFactory() {
 203         spinner.increment();
 204     }
 205 
 206     @Test(expected = IllegalStateException.class)
 207     public void expectExceptionWhenOneArgsIncrementCalled_noValueFactory() {
 208         spinner.increment(2);
 209     }
 210 
 211     @Test(expected = IllegalStateException.class)
 212     public void expectExceptionWhenNoArgsDecrementCalled_noValueFactory() {
 213         spinner.decrement();
 214     }
 215 
 216     @Test(expected = IllegalStateException.class)
 217     public void expectExceptionWhenOneArgsDecrementCalled_noValueFactory() {
 218         spinner.decrement(2);
 219     }
 220 
 221 
 222     /***************************************************************************
 223      *                                                                         *
 224      * changing value factory tests                                            *
 225      *                                                                         *
 226      **************************************************************************/
 227 
 228     @Test public void valueFactory_valueIsNulledWhenValueFactoryisNull() {
 229         assertEquals(5, (int) intSpinner.getValue());
 230         intSpinner.setValueFactory(null);
 231         assertNull(spinner.getValue());
 232     }
 233 
 234     @Test public void valueFactory_valueIsUpdatedWhenValueFactoryChanged() {
 235         assertEquals(5, (int) intSpinner.getValue());
 236         intSpinner.setValueFactory(new IntegerSpinnerValueFactory(0, 10, 8));
 237         assertEquals(8, (int) intSpinner.getValue());
 238     }
 239 
 240 //    @Test public void valueFactory_spinnerPropertyIsNullWhenRemovedFromSpinner() {
 241 //        SpinnerValueFactory initialValueFactory = intSpinner.getValueFactory();
 242 //        assertEquals(intSpinner, initialValueFactory.getSpinner());
 243 //
 244 //        intSpinner.setValueFactory(null);
 245 //        assertNull(intSpinner.getValueFactory());
 246 //    }
 247 //
 248 //    @Test public void valueFactory_spinnerPropertyIsSetOnNewSpinner() {
 249 //        SpinnerValueFactory initialValueFactory = intSpinner.getValueFactory();
 250 //        assertEquals(intSpinner, initialValueFactory.getSpinner());
 251 //
 252 //        SpinnerValueFactory newValueFactory = new IntSpinnerValueFactory(0, 10, 8);
 253 //        intSpinner.setValueFactory(newValueFactory);
 254 //
 255 //        assertNull(initialValueFactory.getSpinner());
 256 //        assertEquals(intSpinner, newValueFactory.getSpinner());
 257 //    }
 258 
 259 
 260     /***************************************************************************
 261      *                                                                         *
 262      * value property events                                                   *
 263      *                                                                         *                                                                         *
 264      **************************************************************************/
 265 
 266     @Test public void value_notifyWhenChanged_validValue() {
 267         assertEquals(5, (int) intSpinner.getValue());
 268         intSpinner.valueProperty().addListener(o -> eventCount++);
 269         intSpinner.getValueFactory().setValue(3);
 270         assertEquals(1, eventCount);
 271     }
 272 
 273     @Test public void value_notifyWhenChanged_invalidValue() {
 274         assertEquals(5, (int) intSpinner.getValue());
 275         intSpinner.valueProperty().addListener(o -> eventCount++);
 276         intSpinner.getValueFactory().setValue(1000);
 277 
 278         // we expect two events: firstly, one for the invalid value, and another
 279         // for the valid value
 280         assertEquals(2, eventCount);
 281     }
 282 
 283     @Test public void value_notifyWhenChanged_existingValue() {
 284         assertEquals(5, (int) intSpinner.getValue());
 285         intSpinner.valueProperty().addListener(o -> eventCount++);
 286         intSpinner.getValueFactory().setValue(5);
 287         assertEquals(0, eventCount);
 288     }
 289 
 290 
 291     /***************************************************************************
 292      *                                                                         *
 293      * editing tests                                                           *
 294      *                                                                         *
 295      **************************************************************************/
 296 
 297     @Ignore("Need KeyboardEventFirer")
 298     @Test public void editing_commitValidInput() {
 299         intSpinner.valueProperty().addListener(o -> eventCount++);
 300         intSpinner.getEditor().setText("3");
 301         // TODO press enter
 302 
 303         assertEquals(1, eventCount);
 304         assertEquals(3, (int) intSpinner.getValue());
 305         assertEquals("3", intSpinner.getEditor().getText());
 306     }
 307 
 308     @Ignore("Need KeyboardEventFirer")
 309     @Test public void editing_commitInvalidInput() {
 310         intSpinner.valueProperty().addListener(o -> eventCount++);
 311         intSpinner.getEditor().setText("300");
 312         // TODO press enter
 313 
 314         assertEquals(2, eventCount);
 315         assertEquals(5, (int) intSpinner.getValue());
 316         assertEquals("5", intSpinner.getEditor().getText());
 317     }
 318 
 319 
 320     /***************************************************************************
 321      *                                                                         *
 322      * IntegerSpinnerValueFactory tests                                        *
 323      *                                                                         *
 324      **************************************************************************/
 325 
 326     @Test public void intSpinner_testIncrement_oneStep() {
 327         intValueFactory.increment(1);
 328         assertEquals(6, (int) intValueFactory.getValue());
 329     }
 330 
 331     @Test public void intSpinner_testIncrement_twoSteps() {
 332         intValueFactory.increment(2);
 333         assertEquals(7, (int) intValueFactory.getValue());
 334     }
 335 
 336     @Test public void intSpinner_testIncrement_manyCalls() {
 337         for (int i = 0; i < 100; i++) {
 338             intValueFactory.increment(1);
 339         }
 340         assertEquals(10, (int) intValueFactory.getValue());
 341     }
 342 
 343     @Test public void intSpinner_testIncrement_bigStepPastMaximum() {
 344         intValueFactory.increment(1000);
 345         assertEquals(10, (int) intValueFactory.getValue());
 346     }
 347 
 348     @Test public void intSpinner_testDecrement_oneStep() {
 349         intValueFactory.decrement(1);
 350         assertEquals(4, (int) intValueFactory.getValue());
 351     }
 352 
 353     @Test public void intSpinner_testDecrement_twoSteps() {
 354         intValueFactory.decrement(2);
 355         assertEquals(3, (int) intValueFactory.getValue());
 356     }
 357 
 358     @Test public void intSpinner_testDecrement_manyCalls() {
 359         for (int i = 0; i < 100; i++) {
 360             intValueFactory.decrement(1);
 361         }
 362         assertEquals(0, (int) intValueFactory.getValue());
 363     }
 364 
 365     @Test public void intSpinner_testDecrement_bigStepPastMinimum() {
 366         intValueFactory.decrement(1000);
 367         assertEquals(0, (int) intValueFactory.getValue());
 368     }
 369 
 370     @Test public void intSpinner_testWrapAround_increment_oneStep() {
 371         intValueFactory.setWrapAround(true);
 372         intValueFactory.increment(1); // 6
 373         intValueFactory.increment(1); // 7
 374         intValueFactory.increment(1); // 8
 375         intValueFactory.increment(1); // 9
 376         intValueFactory.increment(1); // 10
 377         intValueFactory.increment(1); // 0
 378         intValueFactory.increment(1); // 1
 379         assertEquals(1, (int) intValueFactory.getValue());
 380     }
 381 
 382     @Test public void intSpinner_testWrapAround_increment_twoSteps() {
 383         intValueFactory.setWrapAround(true);
 384         intValueFactory.increment(2); // 7
 385         intValueFactory.increment(2); // 9
 386         intValueFactory.increment(2); // 0
 387         intValueFactory.increment(2); // 2
 388         assertEquals(2, (int) intValueFactory.getValue());
 389     }
 390 
 391     @Test public void intSpinner_testWrapAround_decrement_oneStep() {
 392         intValueFactory.setWrapAround(true);
 393         intValueFactory.decrement(1); // 4
 394         intValueFactory.decrement(1); // 3
 395         intValueFactory.decrement(1); // 2
 396         intValueFactory.decrement(1); // 1
 397         intValueFactory.decrement(1); // 0
 398         intValueFactory.decrement(1); // 10
 399         intValueFactory.decrement(1); // 9
 400         assertEquals(9, (int) intValueFactory.getValue());
 401     }
 402 
 403     @Test public void intSpinner_testWrapAround_decrement_twoSteps() {
 404         intValueFactory.setWrapAround(true);
 405         intValueFactory.decrement(2); // 3
 406         intValueFactory.decrement(2); // 1
 407         intValueFactory.decrement(2); // 10
 408         intValueFactory.decrement(2); // 8
 409         assertEquals(8, (int) intValueFactory.getValue());
 410     }
 411 
 412     @Test public void intSpinner_assertDefaultConverterIsNonNull() {
 413         assertNotNull(intValueFactory.getConverter());
 414     }
 415 
 416     @Test public void intSpinner_testToString_valueInRange() {
 417         assertEquals("3", intValueFactory.getConverter().toString(3));
 418     }
 419 
 420     @Test public void intSpinner_testToString_valueOutOfRange() {
 421         assertEquals("300", intValueFactory.getConverter().toString(300));
 422     }
 423 
 424     @Test public void intSpinner_testFromString_valueInRange() {
 425         assertEquals(3, (int) intValueFactory.getConverter().fromString("3"));
 426     }
 427 
 428     @Test public void intSpinner_testFromString_valueOutOfRange() {
 429         assertEquals(300, (int) intValueFactory.getConverter().fromString("300"));
 430     }
 431 
 432     @Test public void intSpinner_testSetMin_doesNotChangeSpinnerValueWhenMinIsLessThanCurrentValue() {
 433         intValueFactory.setValue(5);
 434         assertEquals(5, (int) intSpinner.getValue());
 435         intValueFactory.setMin(3);
 436         assertEquals(5, (int) intSpinner.getValue());
 437     }
 438 
 439     @Test public void intSpinner_testSetMin_changesSpinnerValueWhenMinIsGreaterThanCurrentValue() {
 440         intValueFactory.setValue(0);
 441         assertEquals(0, (int) intSpinner.getValue());
 442         intValueFactory.setMin(5);
 443         assertEquals(5, (int) intSpinner.getValue());
 444     }
 445 
 446     @Test public void intSpinner_testSetMin_ensureThatMinCanNotExceedMax() {
 447         assertEquals(0, intValueFactory.getMin());
 448         assertEquals(10, intValueFactory.getMax());
 449         intValueFactory.setMin(20);
 450         assertEquals(10, intValueFactory.getMin());
 451     }
 452 
 453     @Test public void intSpinner_testSetMin_ensureThatMinCanEqualMax() {
 454         assertEquals(0, intValueFactory.getMin());
 455         assertEquals(10, intValueFactory.getMax());
 456         intValueFactory.setMin(10);
 457         assertEquals(10, intValueFactory.getMin());
 458     }
 459 
 460     @Test public void intSpinner_testSetMax_doesNotChangeSpinnerValueWhenMaxIsGreaterThanCurrentValue() {
 461         intValueFactory.setValue(5);
 462         assertEquals(5, (int) intSpinner.getValue());
 463         intValueFactory.setMax(8);
 464         assertEquals(5, (int) intSpinner.getValue());
 465     }
 466 
 467     @Test public void intSpinner_testSetMax_changesSpinnerValueWhenMaxIsGreaterThanCurrentValue() {
 468         intValueFactory.setValue(5);
 469         assertEquals(5, (int) intSpinner.getValue());
 470         intValueFactory.setMax(3);
 471         assertEquals(3, (int) intSpinner.getValue());
 472     }
 473 
 474     @Test public void intSpinner_testSetMax_ensureThatMaxCanNotGoLessThanMin() {
 475         intValueFactory.setMin(5);
 476         assertEquals(5, intValueFactory.getMin());
 477         assertEquals(10, intValueFactory.getMax());
 478         intValueFactory.setMax(3);
 479         assertEquals(5, intValueFactory.getMin());
 480     }
 481 
 482     @Test public void intSpinner_testSetMax_ensureThatMaxCanEqualMin() {
 483         intValueFactory.setMin(5);
 484         assertEquals(5, intValueFactory.getMin());
 485         assertEquals(10, intValueFactory.getMax());
 486         intValueFactory.setMax(5);
 487         assertEquals(5, intValueFactory.getMin());
 488     }
 489 
 490     @Test public void intSpinner_testSetValue_canNotExceedMax() {
 491         assertEquals(0, intValueFactory.getMin());
 492         assertEquals(10, intValueFactory.getMax());
 493         intValueFactory.setValue(50);
 494         assertEquals(10, (int) intSpinner.getValue());
 495     }
 496 
 497     @Test public void intSpinner_testSetValue_canNotExceedMin() {
 498         assertEquals(0, intValueFactory.getMin());
 499         assertEquals(10, intValueFactory.getMax());
 500         intValueFactory.setValue(-50);
 501         assertEquals(0, (int) intSpinner.getValue());
 502     }
 503 
 504 
 505 
 506     /***************************************************************************
 507      *                                                                         *
 508      * DoubleSpinnerValueFactory tests                                         *
 509      *                                                                         *                                                                         *
 510      **************************************************************************/
 511 
 512     @Test public void dblSpinner_testIncrement_oneStep() {
 513         dblValueFactory.increment(1);
 514         assertEquals(0.55, dblValueFactory.getValue(), 0);
 515     }
 516 
 517     @Test public void dblSpinner_testIncrement_twoSteps() {
 518         dblValueFactory.increment(2);
 519         assertEquals(0.6, dblValueFactory.getValue(), 0);
 520     }
 521 
 522     @Test public void dblSpinner_testIncrement_manyCalls() {
 523         for (int i = 0; i < 100; i++) {
 524             dblValueFactory.increment(1);
 525         }
 526         assertEquals(1.0, dblValueFactory.getValue(), 0);
 527     }
 528 
 529     @Test public void dblSpinner_testIncrement_bigStepPastMaximum() {
 530         dblValueFactory.increment(1000);
 531         assertEquals(1.0, dblValueFactory.getValue(), 0);
 532     }
 533 
 534     @Test public void dblSpinner_testDecrement_oneStep() {
 535         dblValueFactory.decrement(1);
 536         assertEquals(0.45, dblValueFactory.getValue());
 537     }
 538 
 539     @Test public void dblSpinner_testDecrement_twoSteps() {
 540         dblValueFactory.decrement(2);
 541         assertEquals(0.4, dblValueFactory.getValue());
 542     }
 543 
 544     @Test public void dblSpinner_testDecrement_manyCalls() {
 545         for (int i = 0; i < 100; i++) {
 546             dblValueFactory.decrement(1);
 547         }
 548         assertEquals(0, dblValueFactory.getValue(), 0);
 549     }
 550 
 551     @Test public void dblSpinner_testDecrement_bigStepPastMinimum() {
 552         dblValueFactory.decrement(1000);
 553         assertEquals(0, dblValueFactory.getValue(), 0);
 554     }
 555 
 556     @Test public void dblSpinner_testWrapAround_increment_oneStep() {
 557         dblValueFactory.setWrapAround(true);
 558         dblValueFactory.setValue(0.80);
 559         dblValueFactory.increment(1); // 0.85
 560         dblValueFactory.increment(1); // 0.90
 561         dblValueFactory.increment(1); // 0.95
 562         dblValueFactory.increment(1); // 1.00
 563         dblValueFactory.increment(1); // 0.00
 564         dblValueFactory.increment(1); // 0.05
 565         dblValueFactory.increment(1); // 0.10
 566         assertEquals(0.10, dblValueFactory.getValue(), 0);
 567     }
 568 
 569     @Test public void dblSpinner_testWrapAround_increment_twoSteps() {
 570         dblValueFactory.setWrapAround(true);
 571         dblValueFactory.setValue(0.80);
 572         dblValueFactory.increment(2); // 0.90
 573         dblValueFactory.increment(2); // 1.00
 574         dblValueFactory.increment(2); // 0.00
 575         dblValueFactory.increment(2); // 0.10
 576         assertEquals(0.10, dblValueFactory.getValue(), 0);
 577     }
 578 
 579     @Test public void dblSpinner_testWrapAround_decrement_oneStep() {
 580         dblValueFactory.setWrapAround(true);
 581         dblValueFactory.setValue(0.20);
 582         dblValueFactory.decrement(1); // 0.15
 583         dblValueFactory.decrement(1); // 0.10
 584         dblValueFactory.decrement(1); // 0.05
 585         dblValueFactory.decrement(1); // 0.00
 586         dblValueFactory.decrement(1); // 1.00
 587         dblValueFactory.decrement(1); // 0.95
 588         dblValueFactory.decrement(1); // 0.90
 589         assertEquals(0.90, dblValueFactory.getValue(), 0);
 590     }
 591 
 592     @Test public void dblSpinner_testWrapAround_decrement_twoSteps() {
 593         dblValueFactory.setWrapAround(true);
 594         dblValueFactory.setValue(0.20);
 595         dblValueFactory.decrement(2); // 0.10
 596         dblValueFactory.decrement(2); // 0.00
 597         dblValueFactory.decrement(2); // 1.00
 598         dblValueFactory.decrement(2); // 0.90
 599         assertEquals(0.90, dblValueFactory.getValue());
 600     }
 601 
 602     @Test public void dblSpinner_assertDefaultConverterIsNonNull() {
 603         assertNotNull(dblValueFactory.getConverter());
 604     }
 605 
 606     @Test public void dblSpinner_testToString_valueInRange() {
 607         assertEquals("0.3", dblValueFactory.getConverter().toString(0.3));
 608     }
 609 
 610     @Test public void dblSpinner_testToString_valueOutOfRange() {
 611         assertEquals("300", dblValueFactory.getConverter().toString(300D));
 612     }
 613 
 614     @Test public void dblSpinner_testFromString_valueInRange() {
 615         assertEquals(0.3, dblValueFactory.getConverter().fromString("0.3"));
 616     }
 617 
 618     @Test public void dblSpinner_testFromString_valueOutOfRange() {
 619         assertEquals(300.0, dblValueFactory.getConverter().fromString("300"), 0);
 620     }
 621 
 622     @Test public void dblSpinner_testSetMin_doesNotChangeSpinnerValueWhenMinIsLessThanCurrentValue() {
 623         dblValueFactory.setValue(0.5);
 624         assertEquals(0.5, dblSpinner.getValue());
 625         dblValueFactory.setMin(0.3);
 626         assertEquals(0.5, dblSpinner.getValue());
 627     }
 628 
 629     @Test public void dblSpinner_testSetMin_changesSpinnerValueWhenMinIsGreaterThanCurrentValue() {
 630         dblValueFactory.setValue(0.0);
 631         assertEquals(0.0, dblSpinner.getValue());
 632         dblValueFactory.setMin(0.5);
 633         assertEquals(0.5, dblSpinner.getValue());
 634     }
 635 
 636     @Test public void dblSpinner_testSetMin_ensureThatMinCanNotExceedMax() {
 637         assertEquals(0, dblValueFactory.getMin(), 0);
 638         assertEquals(1.0, dblValueFactory.getMax());
 639         dblValueFactory.setMin(20);
 640         assertEquals(1.0, dblValueFactory.getMin());
 641     }
 642 
 643     @Test public void dblSpinner_testSetMin_ensureThatMinCanEqualMax() {
 644         assertEquals(0, dblValueFactory.getMin(), 0);
 645         assertEquals(1.0, dblValueFactory.getMax());
 646         dblValueFactory.setMin(1.0);
 647         assertEquals(1.0, dblValueFactory.getMin());
 648     }
 649 
 650     @Test public void dblSpinner_testSetMax_doesNotChangeSpinnerValueWhenMaxIsGreaterThanCurrentValue() {
 651         dblValueFactory.setValue(0.5);
 652         assertEquals(0.5, dblSpinner.getValue());
 653         dblValueFactory.setMax(0.8);
 654         assertEquals(0.5, dblSpinner.getValue());
 655     }
 656 
 657     @Test public void dblSpinner_testSetMax_changesSpinnerValueWhenMaxIsGreaterThanCurrentValue() {
 658         dblValueFactory.setValue(0.5);
 659         assertEquals(0.5, dblSpinner.getValue());
 660         dblValueFactory.setMax(0.3);
 661         assertEquals(0.3, dblSpinner.getValue());
 662     }
 663 
 664     @Test public void dblSpinner_testSetMax_ensureThatMaxCanNotGoLessThanMin() {
 665         dblValueFactory.setMin(0.5);
 666         assertEquals(0.5, dblValueFactory.getMin());
 667         assertEquals(1.0, dblValueFactory.getMax());
 668         dblValueFactory.setMax(0.3);
 669         assertEquals(0.5, dblValueFactory.getMin());
 670     }
 671 
 672     @Test public void dblSpinner_testSetMax_ensureThatMaxCanEqualMin() {
 673         dblValueFactory.setMin(0.5);
 674         assertEquals(0.5, dblValueFactory.getMin());
 675         assertEquals(1.0, dblValueFactory.getMax());
 676         dblValueFactory.setMax(0.5);
 677         assertEquals(0.5, dblValueFactory.getMin());
 678     }
 679 
 680     @Test public void dblSpinner_testSetValue_canNotExceedMax() {
 681         assertEquals(0, dblValueFactory.getMin(), 0);
 682         assertEquals(1.0, dblValueFactory.getMax());
 683         dblValueFactory.setValue(5.0);
 684         assertEquals(1.0, dblSpinner.getValue());
 685     }
 686 
 687     @Test public void dblSpinner_testSetValue_canNotExceedMin() {
 688         assertEquals(0, dblValueFactory.getMin(), 0);
 689         assertEquals(1.0, dblValueFactory.getMax(), 0);
 690         dblValueFactory.setValue(-5.0);
 691         assertEquals(0, dblSpinner.getValue(), 0);
 692     }
 693 
 694 
 695     /***************************************************************************
 696      *                                                                         *
 697      * ListSpinnerValueFactory tests                                           *
 698      *                                                                         *
 699      **************************************************************************/
 700 
 701     @Test public void listSpinner_testIncrement_oneStep() {
 702         listValueFactory.increment(1);
 703         assertEquals("string2", listValueFactory.getValue());
 704     }
 705 
 706     @Test public void listSpinner_testIncrement_twoSteps() {
 707         listValueFactory.increment(2);
 708         assertEquals("string3", listValueFactory.getValue());
 709     }
 710 
 711     @Test public void listSpinner_testIncrement_manyCalls() {
 712         for (int i = 0; i < 100; i++) {
 713             listValueFactory.increment(1);
 714         }
 715         assertEquals("string3", listValueFactory.getValue());
 716     }
 717 
 718     @Test public void listSpinner_testIncrement_bigStepPastMaximum() {
 719         listValueFactory.increment(1000);
 720         assertEquals("string3", listValueFactory.getValue());
 721     }
 722 
 723     @Test public void listSpinner_testDecrement_oneStep() {
 724         listValueFactory.decrement(1);
 725         assertEquals("string1", listValueFactory.getValue());
 726     }
 727 
 728     @Test public void listSpinner_testDecrement_twoSteps() {
 729         listValueFactory.decrement(2);
 730         assertEquals("string1", listValueFactory.getValue());
 731     }
 732 
 733     @Test public void listSpinner_testDecrement_manyCalls() {
 734         for (int i = 0; i < 100; i++) {
 735             listValueFactory.decrement(1);
 736         }
 737         assertEquals("string1", listValueFactory.getValue());
 738     }
 739 
 740     @Test public void listSpinner_testDecrement_bigStepPastMinimum() {
 741         listValueFactory.decrement(1000);
 742         assertEquals("string1", listValueFactory.getValue());
 743     }
 744 
 745     @Test public void listSpinner_testWrapAround_increment_oneStep() {
 746         listValueFactory.setWrapAround(true);
 747         listValueFactory.increment(1); // string2
 748         listValueFactory.increment(1); // string3
 749         listValueFactory.increment(1); // string1
 750         listValueFactory.increment(1); // string2
 751         listValueFactory.increment(1); // string3
 752         listValueFactory.increment(1); // string1
 753         listValueFactory.increment(1); // string2
 754         assertEquals("string2", listValueFactory.getValue());
 755     }
 756 
 757     @Test public void listSpinner_testWrapAround_increment_twoSteps() {
 758         listValueFactory.setWrapAround(true);
 759         listValueFactory.increment(2); // string1 -> string3
 760         listValueFactory.increment(2); // string3 -> string2
 761         listValueFactory.increment(2); // string2 -> string1
 762         listValueFactory.increment(2); // string1 -> string3
 763         assertEquals("string3", listValueFactory.getValue());
 764     }
 765 
 766     @Test public void listSpinner_testWrapAround_decrement_oneStep() {
 767         listValueFactory.setWrapAround(true);
 768         listValueFactory.decrement(1); // string3
 769         listValueFactory.decrement(1); // string2
 770         listValueFactory.decrement(1); // string1
 771         listValueFactory.decrement(1); // string3
 772         listValueFactory.decrement(1); // string2
 773         listValueFactory.decrement(1); // string1
 774         listValueFactory.decrement(1); // string3
 775         assertEquals("string3", listValueFactory.getValue());
 776     }
 777 
 778     @Test public void listSpinner_testWrapAround_decrement_twoSteps() {
 779         listValueFactory.setWrapAround(true);
 780         listValueFactory.decrement(2); // string1 -> string2
 781         listValueFactory.decrement(2); // string2 -> string3
 782         listValueFactory.decrement(2); // string3 -> string1
 783         listValueFactory.decrement(2); // string1 -> string2
 784         assertEquals("string2", listValueFactory.getValue());
 785     }
 786 
 787     @Test public void listSpinner_assertDefaultConverterIsNonNull() {
 788         assertNotNull(listValueFactory.getConverter());
 789     }
 790 
 791     @Test public void listSpinner_testToString_valueInRange() {
 792         assertEquals("string2", listValueFactory.getConverter().toString("string2"));
 793     }
 794 
 795     @Test public void listSpinner_testToString_valueOutOfRange() {
 796         assertEquals("string300", listValueFactory.getConverter().toString("string300"));
 797     }
 798 
 799     @Test public void listSpinner_testFromString_valueInRange() {
 800         assertEquals("string3", listValueFactory.getConverter().fromString("string3"));
 801     }
 802 
 803     @Test public void listSpinner_testFromString_valueOutOfRange() {
 804         assertEquals("string300", listValueFactory.getConverter().fromString("string300"));
 805     }
 806 
 807     @Test public void listSpinner_testListChange_changeNonSelectedItem() {
 808         assertEquals("string1", listSpinner.getValue());
 809 
 810         strings.set(1, "string200"); // change 'string2' to 'string200'
 811 
 812         // there should be no change
 813         assertEquals("string1", listSpinner.getValue());
 814     }
 815 
 816     @Test public void listSpinner_testListChange_changeSelectedItem() {
 817         assertEquals("string1", listSpinner.getValue());
 818 
 819         strings.set(0, "string100"); // change 'string1' to 'string100'
 820 
 821         // the selected value should change
 822         assertEquals("string100", listSpinner.getValue());
 823     }
 824 
 825     @Test public void listSpinner_testListChange_changeEntireList_directly() {
 826         assertEquals("string1", listSpinner.getValue());
 827 
 828         listValueFactory.getItems().setAll("newString1", "newString2", "newString3");
 829 
 830         // the selected value should change
 831         assertEquals("newString1", listSpinner.getValue());
 832     }
 833 
 834     @Test public void listSpinner_testListChange_changeEntireList_usingSetter() {
 835         assertEquals("string1", listSpinner.getValue());
 836 
 837         listValueFactory.setItems(FXCollections.observableArrayList("newString1", "newString2", "newString3"));
 838         assertEquals("newString1", listSpinner.getValue());
 839     }
 840 
 841     @Test public void listSpinner_testListChange_setItemsToNull() {
 842         assertEquals("string1", listSpinner.getValue());
 843         listValueFactory.setItems(null);
 844         assertNull(listSpinner.getValue());
 845     }
 846 
 847     @Test public void listSpinner_testListChange_setItemsToNonNull() {
 848         assertEquals("string1", listSpinner.getValue());
 849         listValueFactory.setItems(null);
 850         assertNull(listSpinner.getValue());
 851 
 852         listValueFactory.setItems(FXCollections.observableArrayList("newString1", "newString2", "newString3"));
 853         assertEquals("newString1", listSpinner.getValue());
 854     }
 855 
 856     @Test public void listSpinner_testListChange_setNewEmptyListOverOldEmptyList() {
 857         // this tests the issue where we replace an empty list with another. As
 858         // both empty lists are equal, we are ensuring that the listeners update
 859         // to the new list.
 860         ObservableList<String> firstEmptyList = FXCollections.observableArrayList();
 861         ObservableList<String> newEmptyList = FXCollections.observableArrayList();
 862 
 863         ListSpinnerValueFactory valueFactory = new ListSpinnerValueFactory(firstEmptyList);
 864         Spinner listSpinner = new Spinner(valueFactory);
 865 
 866         valueFactory.setItems(newEmptyList);
 867         assertNull(listSpinner.getValue());
 868 
 869         newEmptyList.addAll("newString1", "newString2", "newString3");
 870         assertEquals("newString1", listSpinner.getValue());
 871     }
 872 
 873 
 874 
 875     /***************************************************************************
 876      *                                                                         *
 877      * LocalDateSpinnerValueFactory tests                                      *
 878      *                                                                         *
 879      **************************************************************************/
 880 
 881     private LocalDate nowPlusDays(int days) {
 882         return LocalDate.now().plus(days, ChronoUnit.DAYS);
 883     }
 884 
 885     @Test public void localDateSpinner_testIncrement_oneStep() {
 886         localDateValueFactory.increment(1);
 887         assertEquals(nowPlusDays(1), localDateValueFactory.getValue());
 888     }
 889 
 890     @Test public void localDateSpinner_testIncrement_twoSteps() {
 891         localDateValueFactory.increment(2);
 892         assertEquals(nowPlusDays(2), localDateValueFactory.getValue());
 893     }
 894 
 895     @Test public void localDateSpinner_testIncrement_manyCalls() {
 896         for (int i = 0; i < 100; i++) {
 897             localDateValueFactory.increment(1);
 898         }
 899         assertEquals(nowPlusDays(10), localDateValueFactory.getValue());
 900     }
 901 
 902     @Test public void localDateSpinner_testIncrement_bigStepPastMaximum() {
 903         localDateValueFactory.increment(1000);
 904         assertEquals(nowPlusDays(10), localDateValueFactory.getValue());
 905     }
 906 
 907     @Test public void localDateSpinner_testDecrement_oneStep() {
 908         localDateValueFactory.decrement(1);
 909         assertEquals(nowPlusDays(-1), localDateValueFactory.getValue());
 910     }
 911 
 912     @Test public void localDateSpinner_testDecrement_twoSteps() {
 913         localDateValueFactory.decrement(2);
 914         assertEquals(nowPlusDays(-2), localDateValueFactory.getValue());
 915     }
 916 
 917     @Test public void localDateSpinner_testDecrement_manyCalls() {
 918         for (int i = 0; i < 100; i++) {
 919             localDateValueFactory.decrement(1);
 920         }
 921         assertEquals(nowPlusDays(-10), localDateValueFactory.getValue());
 922     }
 923 
 924     @Test public void localDateSpinner_testDecrement_bigStepPastMinimum() {
 925         localDateValueFactory.decrement(1000);
 926         assertEquals(nowPlusDays(-10), localDateValueFactory.getValue());
 927     }
 928 
 929     @Test public void localDateSpinner_testWrapAround_increment_oneStep() {
 930         localDateValueFactory.setWrapAround(true);
 931         localDateValueFactory.setValue(nowPlusDays(7));
 932         localDateValueFactory.increment(1); // nowPlusDays(8)
 933         localDateValueFactory.increment(1); // nowPlusDays(9)
 934         localDateValueFactory.increment(1); // nowPlusDays(10)
 935         localDateValueFactory.increment(1); // nowPlusDays(-10)
 936         localDateValueFactory.increment(1); // nowPlusDays(-9)
 937         localDateValueFactory.increment(1); // nowPlusDays(-8)
 938         localDateValueFactory.increment(1); // nowPlusDays(-7)
 939         assertEquals(nowPlusDays(-7), localDateValueFactory.getValue());
 940     }
 941 
 942     @Test public void localDateSpinner_testWrapAround_increment_twoSteps() {
 943         localDateValueFactory.setWrapAround(true);
 944         localDateValueFactory.setValue(nowPlusDays(7));
 945         localDateValueFactory.increment(2); // nowPlusDays(9)
 946         localDateValueFactory.increment(2); // nowPlusDays(-10)
 947         localDateValueFactory.increment(2); // nowPlusDays(-8)
 948         localDateValueFactory.increment(2); // nowPlusDays(-6)
 949         assertEquals(nowPlusDays(-6), localDateValueFactory.getValue());
 950     }
 951 
 952     @Test public void localDateSpinner_testWrapAround_decrement_oneStep() {
 953         localDateValueFactory.setWrapAround(true);
 954         localDateValueFactory.setValue(nowPlusDays(-8));
 955         localDateValueFactory.decrement(1); // nowPlusDays(-9)
 956         localDateValueFactory.decrement(1); // nowPlusDays(-10)
 957         localDateValueFactory.decrement(1); // nowPlusDays(10)
 958         localDateValueFactory.decrement(1); // nowPlusDays(9)
 959         localDateValueFactory.decrement(1); // nowPlusDays(8)
 960         localDateValueFactory.decrement(1); // nowPlusDays(7)
 961         localDateValueFactory.decrement(1); // nowPlusDays(6)
 962         assertEquals(nowPlusDays(6), localDateValueFactory.getValue());
 963     }
 964 
 965     @Test public void localDateSpinner_testWrapAround_decrement_twoSteps() {
 966         localDateValueFactory.setWrapAround(true);
 967         localDateValueFactory.setValue(nowPlusDays(-8));
 968         localDateValueFactory.decrement(2); // nowPlusDays(-10)
 969         localDateValueFactory.decrement(2); // nowPlusDays(9)
 970         localDateValueFactory.decrement(2); // nowPlusDays(7)
 971         localDateValueFactory.decrement(2); // nowPlusDays(6)
 972         assertEquals(nowPlusDays(6), localDateValueFactory.getValue());
 973     }
 974 
 975     @Test public void localDateSpinner_assertDefaultConverterIsNonNull() {
 976         assertNotNull(localDateValueFactory.getConverter());
 977     }
 978 
 979     @Test public void localDateSpinner_testToString_valueInRange() {
 980         assertEquals("2014-06-27", localDateValueFactory.getConverter().toString(LocalDate.of(2014, 6, 27)));
 981     }
 982 
 983     @Test public void localDateSpinner_testToString_valueOutOfRange() {
 984         assertEquals("2024-06-27", localDateValueFactory.getConverter().toString(LocalDate.of(2024, 6, 27)));
 985     }
 986 
 987     @Test public void localDateSpinner_testFromString_valueInRange() {
 988         assertEquals(LocalDate.of(2014, 6, 27), localDateValueFactory.getConverter().fromString("2014-06-27"));
 989     }
 990 
 991     @Test public void localDateSpinner_testFromString_valueOutOfRange() {
 992         assertEquals(LocalDate.of(2024, 6, 27), localDateValueFactory.getConverter().fromString("2024-06-27"));
 993     }
 994 
 995     @Test public void localDateSpinner_testSetMin_doesNotChangeSpinnerValueWhenMinIsLessThanCurrentValue() {
 996         LocalDate newValue = LocalDate.now();
 997         localDateValueFactory.setValue(newValue);
 998         assertEquals(newValue, localDateSpinner.getValue());
 999         SpinnerValueFactoryShim.LocalDate_setMin(localDateValueFactory, nowPlusDays(-3));
1000         assertEquals(newValue, localDateSpinner.getValue());
1001     }
1002 
1003     @Test public void localDateSpinner_testSetMin_changesSpinnerValueWhenMinIsGreaterThanCurrentValue() {
1004         LocalDate newValue = LocalDate.now();
1005         localDateValueFactory.setValue(newValue);
1006         assertEquals(newValue, localDateSpinner.getValue());
1007 
1008         LocalDate twoDaysFromNow = nowPlusDays(2);
1009         SpinnerValueFactoryShim.LocalDate_setMin(localDateValueFactory, twoDaysFromNow);
1010         assertEquals(twoDaysFromNow, localDateSpinner.getValue());
1011     }
1012 
1013     @Test public void localDateSpinner_testSetMin_ensureThatMinCanNotExceedMax() {
1014         assertEquals(nowPlusDays(-10), SpinnerValueFactoryShim.LocalDate_getMin(localDateValueFactory));
1015         assertEquals(nowPlusDays(10), SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1016         SpinnerValueFactoryShim.LocalDate_setMin(localDateValueFactory, nowPlusDays(20));
1017         assertEquals(nowPlusDays(10), SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1018     }
1019 
1020     @Test public void localDateSpinner_testSetMin_ensureThatMinCanEqualMax() {
1021         assertEquals(nowPlusDays(-10), SpinnerValueFactoryShim.LocalDate_getMin(localDateValueFactory));
1022         assertEquals(nowPlusDays(10), SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1023         SpinnerValueFactoryShim.LocalDate_setMin(localDateValueFactory, nowPlusDays(10));
1024         assertEquals(nowPlusDays(10), SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1025     }
1026 
1027     @Test public void localDateSpinner_testSetMax_doesNotChangeSpinnerValueWhenMaxIsGreaterThanCurrentValue() {
1028         LocalDate newValue = LocalDate.now();
1029         localDateValueFactory.setValue(newValue);
1030         assertEquals(newValue, localDateSpinner.getValue());
1031         SpinnerValueFactoryShim.LocalDate_setMax(localDateValueFactory, nowPlusDays(2));
1032         assertEquals(newValue, localDateSpinner.getValue());
1033     }
1034 
1035     @Test public void localDateSpinner_testSetMax_changesSpinnerValueWhenMaxIsLessThanCurrentValue() {
1036         LocalDate newValue = nowPlusDays(4);
1037         localDateValueFactory.setValue(newValue);
1038         assertEquals(newValue, localDateSpinner.getValue());
1039 
1040         LocalDate twoDays = nowPlusDays(2);
1041         SpinnerValueFactoryShim.LocalDate_setMax(localDateValueFactory, twoDays);
1042         assertEquals(twoDays, localDateSpinner.getValue());
1043     }
1044 
1045     @Test public void localDateSpinner_testSetMax_ensureThatMaxCanNotGoLessThanMin() {
1046         SpinnerValueFactoryShim.LocalDate_setMin(localDateValueFactory, nowPlusDays(5));
1047         assertEquals(nowPlusDays(5), SpinnerValueFactoryShim.LocalDate_getMin(localDateValueFactory));
1048         assertEquals(nowPlusDays(10), SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1049         SpinnerValueFactoryShim.LocalDate_setMax(localDateValueFactory, nowPlusDays(2));
1050         assertEquals(nowPlusDays(5), SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1051     }
1052 
1053     @Test public void localDateSpinner_testSetMax_ensureThatMaxCanEqualMin() {
1054         LocalDate twoDays = nowPlusDays(2);
1055         SpinnerValueFactoryShim.LocalDate_setMin(localDateValueFactory, twoDays);
1056         assertEquals(twoDays, SpinnerValueFactoryShim.LocalDate_getMin(localDateValueFactory));
1057         assertEquals(nowPlusDays(10), SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1058         SpinnerValueFactoryShim.LocalDate_setMax(localDateValueFactory, twoDays);
1059         assertEquals(twoDays, SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1060     }
1061 
1062     @Test public void localDateSpinner_testSetValue_canNotExceedMax() {
1063         assertEquals(nowPlusDays(-10), SpinnerValueFactoryShim.LocalDate_getMin(localDateValueFactory));
1064         assertEquals(nowPlusDays(10), SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1065         localDateValueFactory.setValue(nowPlusDays(50));
1066         assertEquals(nowPlusDays(10), localDateSpinner.getValue());
1067     }
1068 
1069     @Test public void localDateSpinner_testSetValue_canNotExceedMin() {
1070         assertEquals(nowPlusDays(-10), SpinnerValueFactoryShim.LocalDate_getMin(localDateValueFactory));
1071         assertEquals(nowPlusDays(10), SpinnerValueFactoryShim.LocalDate_getMax(localDateValueFactory));
1072         localDateValueFactory.setValue(nowPlusDays(-50));
1073         assertEquals(nowPlusDays(-10), localDateSpinner.getValue());
1074     }
1075 
1076 
1077 
1078     /***************************************************************************
1079      *                                                                         *
1080      * LocalTimeSpinnerValueFactory tests                                      *
1081      *                                                                         *
1082      **************************************************************************/
1083 
1084     private LocalTime nowPlusHours(int hours) {
1085         return LocalTime.now().plus(hours, ChronoUnit.HOURS);
1086     }
1087 
1088     private void assertTimeEquals(LocalTime expected, LocalTime actual) {
1089         // just compare hours, minutes and seconds
1090         assertEquals(expected.truncatedTo(ChronoUnit.MINUTES), actual.truncatedTo(ChronoUnit.MINUTES));
1091     }
1092 
1093     @Ignore
1094     @Test public void localTimeSpinner_testIncrement_oneStep() {
1095         localTimeValueFactory.increment(1);
1096         assertTimeEquals(nowPlusHours(1), localTimeValueFactory.getValue());
1097     }
1098 
1099     @Ignore
1100     @Test public void localTimeSpinner_testIncrement_twoSteps() {
1101         localTimeValueFactory.increment(2);
1102         assertTimeEquals(nowPlusHours(2), localTimeValueFactory.getValue());
1103     }
1104 
1105     @Ignore
1106     @Test public void localTimeSpinner_testIncrement_manyCalls() {
1107         for (int i = 0; i < 100; i++) {
1108             localTimeValueFactory.increment(1);
1109         }
1110         assertTimeEquals(LocalTime.MAX, localTimeValueFactory.getValue());
1111     }
1112 
1113     @Ignore
1114     @Test public void localTimeSpinner_testIncrement_bigStepPastMaximum() {
1115         localTimeValueFactory.increment(100000);
1116         assertTimeEquals(LocalTime.MAX, localTimeValueFactory.getValue());
1117     }
1118 
1119     @Ignore
1120     @Test public void localTimeSpinner_testDecrement_oneStep() {
1121         localTimeValueFactory.decrement(1);
1122         assertTimeEquals(nowPlusHours(-1), localTimeValueFactory.getValue());
1123     }
1124 
1125     @Ignore
1126     @Test public void localTimeSpinner_testDecrement_twoSteps() {
1127         localTimeValueFactory.decrement(2);
1128         assertTimeEquals(nowPlusHours(-2), localTimeValueFactory.getValue());
1129     }
1130 
1131     @Ignore
1132     @Test public void localTimeSpinner_testDecrement_manyCalls() {
1133         for (int i = 0; i < 100; i++) {
1134             localTimeValueFactory.decrement(1);
1135         }
1136         assertTimeEquals(LocalTime.MIN, localTimeValueFactory.getValue());
1137     }
1138 
1139     @Ignore
1140     @Test public void localTimeSpinner_testDecrement_bigStepPastMinimum() {
1141         localTimeValueFactory.decrement(100000);
1142         assertTimeEquals(LocalTime.MIN, localTimeValueFactory.getValue());
1143     }
1144 
1145     @Ignore
1146     @Test public void localTimeSpinner_testWrapAround_increment_oneStep() {
1147         localTimeValueFactory.setWrapAround(true);
1148 
1149         LocalTime six_pm = LocalTime.of(18,32);
1150         localTimeValueFactory.setValue(six_pm);
1151         localTimeValueFactory.increment(1); // 19:32
1152         localTimeValueFactory.increment(1); // 20:32
1153         localTimeValueFactory.increment(1); // 21:32
1154         localTimeValueFactory.increment(1); // 22:32
1155         localTimeValueFactory.increment(1); // 23:32
1156         localTimeValueFactory.increment(1); // 00:32
1157         localTimeValueFactory.increment(1); // 01:32
1158         assertTimeEquals(LocalTime.of(01,32), localTimeValueFactory.getValue());
1159     }
1160 
1161     @Ignore
1162     @Test public void localTimeSpinner_testWrapAround_increment_twoSteps() {
1163         localTimeValueFactory.setWrapAround(true);
1164 
1165         LocalTime six_pm = LocalTime.of(18,32);
1166         localTimeValueFactory.setValue(six_pm);
1167         localTimeValueFactory.increment(2); // 20:32
1168         localTimeValueFactory.increment(2); // 22:32
1169         localTimeValueFactory.increment(2); // 00:32
1170         localTimeValueFactory.increment(2); // 02:32
1171         assertTimeEquals(LocalTime.of(02,32), localTimeValueFactory.getValue());
1172     }
1173 
1174     @Test public void localTimeSpinner_testWrapAround_decrement_oneStep() {
1175         localTimeValueFactory.setWrapAround(true);
1176 
1177         LocalTime six_am = LocalTime.of(06,32);
1178         localTimeValueFactory.setValue(six_am);
1179         localTimeValueFactory.decrement(1); // 05:32
1180         localTimeValueFactory.decrement(1); // 04:32
1181         localTimeValueFactory.decrement(1); // 03:32
1182         localTimeValueFactory.decrement(1); // 02:32
1183         localTimeValueFactory.decrement(1); // 01:32
1184         localTimeValueFactory.decrement(1); // 00:32
1185         localTimeValueFactory.decrement(1); // 23:32
1186         assertTimeEquals(LocalTime.of(23,32), localTimeValueFactory.getValue());
1187     }
1188 
1189     @Ignore
1190     @Test public void localTimeSpinner_testWrapAround_decrement_twoSteps() {
1191         localTimeValueFactory.setWrapAround(true);
1192 
1193         LocalTime six_am = LocalTime.of(06,32);
1194         localTimeValueFactory.setValue(six_am);
1195         localTimeValueFactory.decrement(2); // 04:32
1196         localTimeValueFactory.decrement(2); // 02:32
1197         localTimeValueFactory.decrement(2); // 00:32
1198         localTimeValueFactory.decrement(2); // 22:32
1199         assertTimeEquals(LocalTime.of(22,32), localTimeValueFactory.getValue());
1200     }
1201 
1202     @Ignore
1203     @Test public void localTimeSpinner_assertDefaultConverterIsNonNull() {
1204         assertNotNull(localTimeValueFactory.getConverter());
1205     }
1206 
1207     @Ignore("Not safe when run early in the morning - needs refining when time permits")
1208     @Test public void localTimeSpinner_testSetMin_doesNotChangeSpinnerValueWhenMinIsLessThanCurrentValue() {
1209         LocalTime newValue = LocalTime.now();
1210         localTimeValueFactory.setValue(newValue);
1211         assertTimeEquals(newValue, localTimeSpinner.getValue());
1212         SpinnerValueFactoryShim.LocalTime_setMin(localTimeValueFactory, nowPlusHours(-3));
1213         assertTimeEquals(newValue, localTimeSpinner.getValue());
1214     }
1215 
1216     @Ignore("Not safe when late at night - needs refining when time permits")
1217     @Test public void localTimeSpinner_testSetMin_changesSpinnerValueWhenMinIsGreaterThanCurrentValue() {
1218         LocalTime newValue = LocalTime.now();
1219         localTimeValueFactory.setValue(newValue);
1220         assertTimeEquals(newValue, localTimeSpinner.getValue());
1221 
1222         LocalTime twoDaysFromNow = nowPlusHours(2);
1223         SpinnerValueFactoryShim.LocalTime_setMin(localTimeValueFactory, twoDaysFromNow);
1224         assertTimeEquals(twoDaysFromNow, localTimeSpinner.getValue());
1225     }
1226 
1227     @Test public void localTimeSpinner_testSetMin_ensureThatMinCanEqualMax() {
1228         assertTimeEquals(LocalTime.MIN, SpinnerValueFactoryShim.LocalTime_getMin(localTimeValueFactory));
1229         assertTimeEquals(LocalTime.MAX, SpinnerValueFactoryShim.LocalTime_getMax(localTimeValueFactory));
1230         SpinnerValueFactoryShim.LocalTime_setMin(localTimeValueFactory, LocalTime.MAX);
1231         assertTimeEquals(LocalTime.MAX, SpinnerValueFactoryShim.LocalTime_getMax(localTimeValueFactory));
1232     }
1233 
1234     @Ignore
1235     @Test public void localTimeSpinner_testSetMax_doesNotChangeSpinnerValueWhenMaxIsGreaterThanCurrentValue() {
1236         LocalTime newValue = LocalTime.now();
1237         localTimeValueFactory.setValue(newValue);
1238         assertTimeEquals(newValue, localTimeSpinner.getValue());
1239         SpinnerValueFactoryShim.LocalTime_setMax(localTimeValueFactory, nowPlusHours(2));
1240         assertTimeEquals(newValue, localTimeSpinner.getValue());
1241     }
1242 
1243     @Ignore
1244     @Test public void localTimeSpinner_testSetMax_changesSpinnerValueWhenMaxIsLessThanCurrentValue() {
1245         LocalTime newValue = nowPlusHours(4);
1246         localTimeValueFactory.setValue(newValue);
1247         assertTimeEquals(newValue, localTimeSpinner.getValue());
1248 
1249         LocalTime twoDays = nowPlusHours(2);
1250         SpinnerValueFactoryShim.LocalTime_setMax(localTimeValueFactory, twoDays);
1251         assertTimeEquals(twoDays, localTimeSpinner.getValue());
1252     }
1253 
1254     @Ignore
1255     @Test public void localTimeSpinner_testSetMax_ensureThatMaxCanNotGoLessThanMin() {
1256         SpinnerValueFactoryShim.LocalTime_setMin(localTimeValueFactory, nowPlusHours(5));
1257         assertTimeEquals(nowPlusHours(5), SpinnerValueFactoryShim.LocalTime_getMax(localTimeValueFactory));
1258         assertTimeEquals(LocalTime.MAX, SpinnerValueFactoryShim.LocalTime_getMax(localTimeValueFactory));
1259         SpinnerValueFactoryShim.LocalTime_setMax(localTimeValueFactory, nowPlusHours(2));
1260         assertTimeEquals(nowPlusHours(5), SpinnerValueFactoryShim.LocalTime_getMax(localTimeValueFactory));
1261     }
1262 
1263     @Ignore
1264     @Test public void localTimeSpinner_testSetMax_ensureThatMaxCanEqualMin() {
1265         LocalTime twoDays = nowPlusHours(2);
1266         SpinnerValueFactoryShim.LocalTime_setMin(localTimeValueFactory, twoDays);
1267         assertTimeEquals(twoDays, SpinnerValueFactoryShim.LocalTime_getMax(localTimeValueFactory));
1268         assertTimeEquals(LocalTime.MAX, SpinnerValueFactoryShim.LocalTime_getMax(localTimeValueFactory));
1269         SpinnerValueFactoryShim.LocalTime_setMax(localTimeValueFactory, twoDays);
1270         assertTimeEquals(twoDays, SpinnerValueFactoryShim.LocalTime_getMax(localTimeValueFactory));
1271     }
1272 
1273 
1274     /***************************************************************************
1275      *                                                                         *
1276      * Tests for bugs                                                          *
1277      *                                                                         *
1278      **************************************************************************/
1279 
1280     @Test public void test_rt_39655_decrement() {
1281         assertEquals(5, (int) intSpinner.getValue());
1282         intSpinner.setEditable(true);
1283         intSpinner.getEditor().setText("7");
1284         intSpinner.decrement();
1285         assertEquals(6, (int) intSpinner.getValue());
1286     }
1287 
1288     @Test public void test_rt_39655_increment() {
1289         assertEquals(5, (int) intSpinner.getValue());
1290         intSpinner.setEditable(true);
1291         intSpinner.getEditor().setText("7");
1292         intSpinner.increment();
1293         assertEquals(8, (int) intSpinner.getValue());
1294     }
1295 
1296     @Test public void test_jdk_8150962() {
1297         Spinner<Double> spinner = new Spinner<>(-100, 100, 0, 0.5);
1298         spinner.getValueFactory().setValue(null);
1299         assertNull(spinner.getValue());
1300     }
1301 
1302     @Test public void test_jdk_8150946_testCommit_valid() {
1303         Spinner<Double> spinner = new Spinner<>(-100, 100, 0, 0.5);
1304         spinner.setEditable(true);
1305         assertEquals(0.0, spinner.getValue());
1306         spinner.getEditor().setText("2.5");
1307         spinner.commitValue();
1308         assertEquals(2.5, spinner.getValue());
1309     }
1310 
1311     @Test public void test_jdk_8150946_testCommit_invalid_outOfRange() {
1312         Spinner<Double> spinner = new Spinner<>(-100, 100, 0, 0.5);
1313         spinner.setEditable(true);
1314         assertEquals(0.0, spinner.getValue());
1315         spinner.getEditor().setText("2500");
1316         spinner.commitValue();
1317         assertEquals(100.0, spinner.getValue());
1318     }
1319 
1320     @Test(expected = RuntimeException.class)
1321     public void test_jdk_8150946_testCommit_invalid_wrongType() {
1322         Spinner<Double> spinner = new Spinner<>(-100, 100, 0, 0.5);
1323         spinner.setEditable(true);
1324         assertEquals(0.0, spinner.getValue());
1325         spinner.getEditor().setText("Hello, World!");
1326         spinner.commitValue();
1327         assertEquals(0.0, spinner.getValue());
1328     }
1329 
1330     @Test public void test_jdk_8150946_testCancel() {
1331         Spinner<Double> spinner = new Spinner<>(-100, 100, 2.5, 0.5);
1332         spinner.setEditable(true);
1333         assertEquals(2.5, spinner.getValue());
1334         assertEquals("2.5", spinner.getEditor().getText());
1335         spinner.getEditor().setText("3.5");
1336         assertEquals(2.5, spinner.getValue());
1337         spinner.cancelEdit();
1338         assertEquals(2.5, spinner.getValue());
1339         assertEquals("2.5", spinner.getEditor().getText());
1340     }
1341 }