public void testSelectionReflectsIndexAfterClear() {
    ValueModel selectionHolder = new ValueHolder();
    SelectionInList<String> sil =
        new SelectionInList<String>(new ValueHolder(listModel, true), selectionHolder);
    sil.setSelectionIndex(1);
    PropertyChangeReport changeReport = new PropertyChangeReport();
    sil.addPropertyChangeListener(SelectionInList.PROPERTYNAME_SELECTION, changeReport);

    assertEquals(
        "SelectionHolder holds the second list element.",
        listModel.get(1),
        selectionHolder.getValue());

    listModel.clear();
    assertEquals("The selection index is -1.", -1, sil.getSelectionIndex());
    assertEquals("The selection is null.", null, sil.getSelection());
    assertEquals("The selection holder value is null.", null, sil.getSelectionHolder().getValue());
    assertEquals("A selection change event has been fired.", 1, changeReport.eventCount());

    // If this event provides an old value, it should be the old value.
    if (changeReport.lastOldValue() != null) {
      assertEquals(
          "The selection change's old value is 'two'.", "two", changeReport.lastOldValue());
    }
    assertEquals("The selection change new value is null.", null, changeReport.lastNewValue());
  }
  public void testSelectionForDirectSelectionChanges() {
    SelectionInList<String> sil = new SelectionInList<String>(listModel);
    PropertyChangeReport selectionEmptyReport = new PropertyChangeReport();
    sil.addPropertyChangeListener(
        SelectionInList.PROPERTYNAME_SELECTION_EMPTY, selectionEmptyReport);

    sil.setSelection((String) listModel.getElementAt(0));
    assertFalse("The selection index is 0 and not empty.", sil.isSelectionEmpty());

    assertEquals(
        "selectionEmpty changed from true to false.", 1, selectionEmptyReport.eventCount());
    assertTrue(
        "1) selectionEmpty change event oldValue == true.",
        selectionEmptyReport.lastOldBooleanValue());
    assertFalse(
        "1) selectionEmpty change event newValue == false.",
        selectionEmptyReport.lastNewBooleanValue());

    sil.setSelection((String) listModel.getElementAt(1));
    assertFalse("The selection index is 1 and not empty.", sil.isSelectionEmpty());

    assertEquals("No selectionEmpty change event fired", 1, selectionEmptyReport.eventCount());

    sil.setSelection(null);
    assertTrue("The selection index is empty.", sil.isSelectionEmpty());

    assertEquals(
        "selectionEmpty changed from false to true.", 2, selectionEmptyReport.eventCount());
    assertFalse(
        "2) selectionEmpty change event oldValue == false.",
        selectionEmptyReport.lastOldBooleanValue());
    assertTrue(
        "2) selectionEmpty change event newValue == true.",
        selectionEmptyReport.lastNewBooleanValue());
  }
  public void testFiresSelectionChangeOnlyForSelectionChanges() {
    int selectionIndex = 0;
    ValueHolder indexHolder = new ValueHolder(selectionIndex);
    SelectionInList<String> sil = new SelectionInList<String>(listModel);
    sil.setSelectionIndexHolder(indexHolder);

    // Create change reports.
    PropertyChangeReport valueReport = new PropertyChangeReport();
    PropertyChangeReport selectionReport = new PropertyChangeReport();
    PropertyChangeReport selectionEmptyReport = new PropertyChangeReport();
    PropertyChangeReport selectionIndexReport = new PropertyChangeReport();

    // Register change reports for value, selection, selection index,
    // and selectionEmpty
    sil.addValueChangeListener(valueReport);
    sil.addPropertyChangeListener(SelectionInList.PROPERTYNAME_SELECTION, selectionReport);
    sil.addPropertyChangeListener(
        SelectionInList.PROPERTYNAME_SELECTION_EMPTY, selectionEmptyReport);
    sil.addPropertyChangeListener(
        SelectionInList.PROPERTYNAME_SELECTION_INDEX, selectionIndexReport);

    indexHolder.fireValueChange(null, new Integer(selectionIndex));
    indexHolder.fireValueChange(new Integer(selectionIndex), null);
    indexHolder.fireValueChange(null, null);
    assertEquals("No value change event fired", 0, valueReport.eventCount());
    assertEquals("No selection change event fired", 0, selectionReport.eventCount());
    assertEquals("No selectionEmpty change event fired", 0, selectionEmptyReport.eventCount());
    assertEquals("No selectionIndex change event fired", 0, selectionIndexReport.eventCount());
  }
  public void testSelectionForDirectSelectionIndexChanges() {
    SelectionInList<String> sil = new SelectionInList<String>(listModel);

    // Create change reports.
    PropertyChangeReport valueReport = new PropertyChangeReport();
    PropertyChangeReport selectionReport = new PropertyChangeReport();
    PropertyChangeReport selectionEmptyReport = new PropertyChangeReport();
    PropertyChangeReport selectionIndexReport = new PropertyChangeReport();

    // Register change reports for value, selection, selection index,
    // and selectionEmpty
    sil.addValueChangeListener(valueReport);
    sil.addPropertyChangeListener(SelectionInList.PROPERTYNAME_SELECTION, selectionReport);
    sil.addPropertyChangeListener(
        SelectionInList.PROPERTYNAME_SELECTION_EMPTY, selectionEmptyReport);
    sil.addPropertyChangeListener(
        SelectionInList.PROPERTYNAME_SELECTION_INDEX, selectionIndexReport);

    assertEquals("The initial value is null.", null, sil.getValue());
    assertEquals("The initial selection is null.", null, sil.getSelection());
    assertTrue("The initial selection is empty.", sil.isSelectionEmpty());
    assertEquals("The initial selection index is -1.", -1, sil.getSelectionIndex());

    sil.setSelectionIndex(0);
    assertEquals(
        "The new value is the first list element.", listModel.getElementAt(0), sil.getValue());
    assertEquals(
        "The new selection is the first list element.",
        listModel.getElementAt(0),
        sil.getSelection());
    assertFalse("The selection is not empty.", sil.isSelectionEmpty());
    assertEquals("The new selection index is 0.", 0, sil.getSelectionIndex());

    assertEquals(
        "selectionEmpty changed from true to false.", 1, selectionEmptyReport.eventCount());
    assertTrue(
        "1) selectionEmpty change event oldValue == true.",
        selectionEmptyReport.lastOldBooleanValue());
    assertFalse(
        "1) selectionEmpty change event newValue == false.",
        selectionEmptyReport.lastNewBooleanValue());

    sil.setSelectionIndex(1);
    assertFalse("The selection index is 1 and not empty.", sil.isSelectionEmpty());

    assertEquals("No selectionEmpty change event fired", 1, selectionEmptyReport.eventCount());

    sil.clearSelection();
    assertTrue("The selection index is empty.", sil.isSelectionEmpty());

    assertEquals(
        "selectionEmpty changed from false to true.", 2, selectionEmptyReport.eventCount());
    assertFalse(
        "2) selectionEmpty change event oldValue == false.",
        selectionEmptyReport.lastOldBooleanValue());
    assertTrue(
        "2) selectionEmpty change event newValue == true.",
        selectionEmptyReport.lastNewBooleanValue());
  }
  /** Checks that list data events from an underlying are reported by the SelectionInList. */
  public static void testFiresListModelListDataEvents() {
    PropertyChangeReport changeReport = new PropertyChangeReport();
    ListDataReport listDataReport1 = new ListDataReport();
    ListDataReport listDataReport2 = new ListDataReport();

    ArrayListModel<String> arrayListModel = new ArrayListModel<String>();
    SelectionInList<String> sil = new SelectionInList<String>((ListModel) arrayListModel);

    arrayListModel.addListDataListener(listDataReport1);
    sil.addListDataListener(listDataReport2);
    sil.addValueChangeListener(changeReport);

    arrayListModel.add("One");
    assertEquals("No list change.", changeReport.eventCount(), 0);
    assertEquals("An element has been added.", listDataReport2.eventCount(), 1);
    assertEquals("An element has been added.", listDataReport2.eventCountAdd(), 1);

    arrayListModel.addAll(Arrays.asList(new String[] {"two", "three", "four"}));
    assertEquals("No list change.", changeReport.eventCount(), 0);
    assertEquals("An element block has been added.", listDataReport2.eventCount(), 2);
    assertEquals("An element block has been added.", listDataReport2.eventCountAdd(), 2);

    arrayListModel.remove(0);
    assertEquals("An element has been removed.", listDataReport2.eventCount(), 3);
    assertEquals("No element has been added.", listDataReport2.eventCountAdd(), 2);
    assertEquals("An element has been removed.", listDataReport2.eventCountRemove(), 1);

    arrayListModel.set(1, "newTwo");
    assertEquals("An element has been replaced.", listDataReport2.eventCount(), 4);
    assertEquals("No element has been added.", listDataReport2.eventCountAdd(), 2);
    assertEquals("No element has been removed.", listDataReport2.eventCountRemove(), 1);
    assertEquals("An element has been changed.", listDataReport2.eventCountChange(), 1);

    // Compare the event counts of the list models listener
    // with the SelectionInList listener.
    assertEquals(
        "Add event counts are equal.",
        listDataReport1.eventCountAdd(),
        listDataReport2.eventCountAdd());
    assertEquals(
        "Remove event counts are equal.",
        listDataReport1.eventCountRemove(),
        listDataReport2.eventCountRemove());
    assertEquals(
        "Change event counts are equal.",
        listDataReport1.eventCountChange(),
        listDataReport2.eventCountChange());
  }
  public void testIndexChangeFiresChangesWithNonNullOldValue() {
    int initialSelectionIndex = 0;
    int newSelectionIndex = 1;
    AbstractValueModel indexHolder = new ValueHolderWithOldValueNull(initialSelectionIndex);
    SelectionInList<String> sil = new SelectionInList<String>(listModel);
    sil.setSelectionIndexHolder(indexHolder);

    // Create change reports.
    PropertyChangeReport valueReport = new PropertyChangeReport();
    PropertyChangeReport selectionReport = new PropertyChangeReport();
    PropertyChangeReport selectionIndexReport = new PropertyChangeReport();

    // Register change reports for value, selection, selection index,
    // and selectionEmpty
    sil.addValueChangeListener(valueReport);
    sil.addPropertyChangeListener(SelectionInList.PROPERTYNAME_SELECTION, selectionReport);
    sil.addPropertyChangeListener(
        SelectionInList.PROPERTYNAME_SELECTION_INDEX, selectionIndexReport);

    // We change the selection index holder's value to the new index.
    // The ValueModel used for the selectionIndexHolder fires no old value.
    indexHolder.setValue(newSelectionIndex);
    Object oldValue = valueReport.lastOldValue();
    Object oldSelection = selectionReport.lastOldValue();
    Object oldSelectionIndex = selectionIndexReport.lastOldValue();
    assertTrue("Non-null old value in value change event", oldValue != null);
    assertTrue("Non-null old value in selection change event", oldSelection != null);
    assertTrue("Non-null old value in selectionIndex change event", oldSelectionIndex != null);
  }
  public void testSelectionReflectsIndexAfterIndexMoveForward() {
    ValueModel selectionHolder = new ValueHolder();
    SelectionInList<String> sil =
        new SelectionInList<String>(new ValueHolder(listModel, true), selectionHolder);
    sil.setSelectionIndex(1);
    PropertyChangeReport changeReport = new PropertyChangeReport();
    sil.addPropertyChangeListener(SelectionInList.PROPERTYNAME_SELECTION, changeReport);

    Object initialSelection = listModel.get(1);
    assertEquals(
        "SelectionHolder holds the second list element.",
        initialSelection,
        selectionHolder.getValue());

    listModel.add(0, "zero");
    Object expectedSelection = listModel.get(2);
    assertEquals("The selection index has been increased by 1.", 2, sil.getSelectionIndex());
    assertEquals("The selection remains unchanged.", expectedSelection, sil.getSelection());
    assertEquals(
        "The selection holder value remains unchanged.",
        expectedSelection,
        sil.getSelectionHolder().getValue());
    assertEquals("No selection change event has been fired.", 0, changeReport.eventCount());
  }