/** * $Id$ * * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, * Santa Clara, California 95054, U.S.A. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package org.jdesktop.swingx.calendar; import java.util.Calendar; import java.util.Date; import java.util.SortedSet; import java.util.TreeSet; import java.util.logging.Logger; import org.jdesktop.swingx.event.DateSelectionEvent; import org.jdesktop.swingx.test.DateSelectionReport; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Tests for the DefaultDateSelectionModel. * * Moved from swingx to calendar package as of version 1.15 */ @RunWith(JUnit4.class) public class DefaultDateSelectionModelTest extends AbstractTestDateSelectionModel { @SuppressWarnings("unused") private static final Logger LOG = Logger .getLogger(DefaultDateSelectionModelTest.class.getName()); /** * DefaultDateSelectionModel impl doesn't normalize. */ @Test public void testNormalizedDateUnchanged() { Date date = calendar.getTime(); Date normalized = model.getNormalizedDate(date); assertEquals(date, normalized); } /** * setSelectionInterval must throw NPE if given date is null */ @Test public void testSetIntervalNulls() { try { model.setSelectionInterval(null, null); fail("normalizedDate must throw NPE if date is null"); } catch (NullPointerException e) { // expected } catch (Exception e) { fail("unexpected exception " + e); } } /** * setSelectionInterval must throw NPE if given date is null */ @Test public void testAddIntervalNulls() { try { model.addSelectionInterval(null, null); fail("normalizedDate must throw NPE if date is null"); } catch (NullPointerException e) { // expected } catch (Exception e) { fail("unexpected exception " + e); } } /** * removeSelectionInterval must throw NPE if given date is null */ @Test public void testRemoveIntervalNulls() { try { model.removeSelectionInterval(null, null); fail("normalizedDate must throw NPE if date is null"); } catch (NullPointerException e) { // expected } catch (Exception e) { fail("unexpected exception " + e); } } /** * Issue #625-swingx: DateSelectionModel must not fire if unchanged. * Here: test setSelection with single mode */ @Test public void testSelectionSetNotFireIfSameSingle() { final Date date = calendar.getTime(); model.setSelectionMode(DateSelectionModel.SelectionMode.SINGLE_SELECTION); model.setSelectionInterval(date, date); // sanity assertTrue(model.isSelected(date)); DateSelectionReport report = new DateSelectionReport(model); model.setSelectionInterval(date, date); assertEquals("selection must not fire on selecting already selected date", 0, report.getEventCount()); } /** * Issue #625-swingx: DateSelectionModel must not fire if unchanged. * Here: test addSelection with single mode */ @Test public void testSelectionAddNotFireIfSameSingle() { final Date date = calendar.getTime(); model.setSelectionMode(DateSelectionModel.SelectionMode.SINGLE_SELECTION); model.setSelectionInterval(date, date); // sanity assertTrue(model.isSelected(date)); DateSelectionReport report = new DateSelectionReport(model); model.addSelectionInterval(date, date); assertEquals("selection must not fire on selecting already selected date", 0, report.getEventCount()); } /** * Issue #625-swingx: DateSelectionModel must not fire if unchanged. * Here: test setSelection with single interval mode */ @Test public void testSelectionSetNotFireIfSameSingleInterval() { final Date date = calendar.getTime(); calendar.add(Calendar.DATE, 2); final Date end = calendar.getTime(); model.setSelectionMode(DateSelectionModel.SelectionMode.SINGLE_INTERVAL_SELECTION); model.setSelectionInterval(date, end); // sanity assertTrue(model.isSelected(date)); DateSelectionReport report = new DateSelectionReport(model); model.setSelectionInterval(date, end); assertEquals("selection must not fire on selecting already selected date", 0, report.getEventCount()); } /** * Issue #625-swingx: DateSelectionModel must not fire if unchanged. * Here: test addSelection with single interval mode */ @Test public void testSelectionAddNotFireIfSameSingleInterval() { final Date date = calendar.getTime(); calendar.add(Calendar.DATE, 2); final Date end = calendar.getTime(); model.setSelectionMode(DateSelectionModel.SelectionMode.SINGLE_INTERVAL_SELECTION); model.setSelectionInterval(date, end); // sanity assertTrue(model.isSelected(date)); DateSelectionReport report = new DateSelectionReport(model); model.addSelectionInterval(date, end); assertEquals("selection must not fire on selecting already selected date", 0, report.getEventCount()); } /** * Issue #625-swingx: DateSelectionModel must not fire if unchanged. * Here: test setSelection with multiple interval mode */ @Test public void testSelectionSetNotFireIfSameMultipleInterval() { final Date date = calendar.getTime(); calendar.add(Calendar.DATE, 2); final Date end = calendar.getTime(); model.setSelectionMode(DateSelectionModel.SelectionMode.MULTIPLE_INTERVAL_SELECTION); model.setSelectionInterval(date, end); // sanity assertTrue(model.isSelected(date)); DateSelectionReport report = new DateSelectionReport(model); model.setSelectionInterval(date, end); assertEquals("selection must not fire on selecting already selected date", 0, report.getEventCount()); } /** * Issue #625-swingx: DateSelectionModel must not fire if unchanged. * Here: test addSelection with multiple interval mode */ @Test public void testSelectionAddNotFireIfSameMultipeInterval() { final Date date = calendar.getTime(); calendar.add(Calendar.DATE, 2); final Date end = calendar.getTime(); model.setSelectionMode(DateSelectionModel.SelectionMode.MULTIPLE_INTERVAL_SELECTION); model.setSelectionInterval(date, end); // sanity assertTrue(model.isSelected(date)); DateSelectionReport report = new DateSelectionReport(model); model.addSelectionInterval(date, end); assertEquals("selection must not fire on selecting already selected date", 0, report.getEventCount()); } /** * related to #625-swingx: DateSelectionModel must not fire on clearing empty selection. */ @Test public void testDateSelectionClearSelectionNotFireIfUnselected() { // sanity assertTrue(model.isSelectionEmpty()); DateSelectionReport report = new DateSelectionReport(model); model.clearSelection(); assertEquals("selection must not fire on clearing empty selection", 0, report.getEventCount()); } /** * related to #625-swingx: DateSelectionModel must fire SELECTION_CLEARED if * had selection. * Testing here for sanity reasons ... be sure we didn't prevent the firing * altogether while changing. */ @Test public void testDateSelectionClearSelectionFireIfSelected() { Date date = new Date(); model.setSelectionInterval(date, date); // sanity assertFalse(model.isSelectionEmpty()); DateSelectionReport report = new DateSelectionReport(model); model.clearSelection(); assertEquals("selection must fire on clearing selection", 1, report.getEventCount()); assertEquals("event type must be SELECTION_CLEARED", DateSelectionEvent.EventType.SELECTION_CLEARED, report.getLastEventType()); } /** * related to #625-swingx: DateSelectionModel must not fire on clearing empty selection. */ @Test public void testDateSelectionSetSelectionNotFireIfSelected() { Date date = new Date(); model.setSelectionInterval(date, date); // sanity assertTrue(model.isSelected(date)); DateSelectionReport report = new DateSelectionReport(model); model.addDateSelectionListener(report); model.setSelectionInterval(date, date); assertEquals("selection must not fire on selecting already selected date", 0, report.getEventCount()); } /** * related to #625-swingx: DateSelectionModel must fire SELECTION_CLEARED if * had selection. * Testing here for sanity reasons ... be sure we didn't prevent the firing * altogether while changing. */ @Test public void testDateSelectionSetSelectionFire() { Date date = new Date(); model.setSelectionInterval(date, date); // sanity assertTrue(model.isSelected(date)); DateSelectionReport report = new DateSelectionReport(model); // modify the date calendar.setTime(date); calendar.add(Calendar.HOUR, 1); model.setSelectionInterval(calendar.getTime(), calendar.getTime()); assertEquals("selection must fire on selection", 1, report.getEventCount()); assertEquals("event type must be DATES_SET", DateSelectionEvent.EventType.DATES_SET, report.getLastEventType()); } /** * respect upper bound - the bound itself * a valid selection. * */ @Test public void testLowerBoundJustBelow() { model.setLowerBound(today); // the bound itself is allowed calendar.add(Calendar.HOUR_OF_DAY, -1); model.setSelectionInterval(calendar.getTime(), calendar.getTime()); assertEquals("future selection just above must be rejected", null, model.getFirstSelectionDate()); } /** * respect upper bound - the bound itself * a valid selection. * */ @Test public void testLowerBoundJustAbove() { model.setLowerBound(today); // the bound itself is allowed calendar.add(Calendar.HOUR_OF_DAY, +1); model.setSelectionInterval(calendar.getTime(), calendar.getTime()); assertEquals("selected just below upper bound", calendar.getTime(), model.getFirstSelectionDate()); } /** * respect upper bound - the bound itself * a valid selection. * */ @Test public void testUpperBoundJustAbove() { model.setUpperBound(today); // the bound itself is allowed calendar.add(Calendar.HOUR_OF_DAY, 1); model.setSelectionInterval(calendar.getTime(), calendar.getTime()); assertEquals("future selection just above must be rejected", null, model.getFirstSelectionDate()); } /** * respect upper bound - the bound itself * a valid selection. * */ @Test public void testUpperBoundJustBelow() { model.setUpperBound(today); // the bound itself is allowed calendar.add(Calendar.HOUR_OF_DAY, -1); model.setSelectionInterval(calendar.getTime(), calendar.getTime()); assertEquals("selected just below upper bound", calendar.getTime(), model.getFirstSelectionDate()); } @Test public void testSingleSelection() { model.setSelectionMode(DateSelectionModel.SelectionMode.SINGLE_SELECTION); Date today = new Date(); model.setSelectionInterval(today, today); SortedSet<Date> selection = model.getSelection(); assertTrue(!selection.isEmpty()); assertTrue(1 == selection.size()); assertTrue(today.equals(selection.first())); Calendar cal = Calendar.getInstance(); cal.setTime(today); cal.roll(Calendar.DAY_OF_MONTH, 1); Date tomorrow = cal.getTime(); model.setSelectionInterval(today, tomorrow); selection = model.getSelection(); assertTrue(!selection.isEmpty()); assertTrue(1 == selection.size()); assertTrue(today.equals(selection.first())); model.addSelectionInterval(tomorrow, tomorrow); selection = model.getSelection(); assertTrue(!selection.isEmpty()); assertTrue(1 == selection.size()); assertTrue(tomorrow.equals(selection.first())); } @Test public void testSingleIntervalSelection() { model.setSelectionMode(DateSelectionModel.SelectionMode.SINGLE_INTERVAL_SELECTION); Date startDate = new Date(); // PENDING JW: hit US DST switching again ... how to handle that? Calendar cal = Calendar.getInstance(); //TimeZone.getTimeZone("US/Eastern")); cal.setTime(startDate); // cal.set(2009, Calendar.MARCH, 5, 2, 0); // startDate = cal.getTime(); cal.add(Calendar.DAY_OF_MONTH, 5); Date endDate = cal.getTime(); model.setSelectionInterval(startDate, endDate); SortedSet<Date> selection = model.getSelection(); assertEquals(startDate, selection.first()); assertEquals(endDate, selection.last()); cal.setTime(startDate); cal.roll(Calendar.MONTH, 1); Date startDateNextMonth = cal.getTime(); model.addSelectionInterval(startDateNextMonth, startDateNextMonth); selection = model.getSelection(); assertEquals(startDateNextMonth, selection.first()); assertEquals(startDateNextMonth, selection.last()); } /** * characterize behaviour on setSelectionInterval depending on selection mode. * Here: compare singleInterval and multipleInterval - must be same. */ @Test public void testSetIntervalSameForSingleAndMultipleIntervalMode() { Date date = new Date(); // pre-select model.setSelectionMode(DateSelectionModel.SelectionMode.SINGLE_INTERVAL_SELECTION); model.setSelectionInterval(date, date); // get span in future Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.DAY_OF_MONTH, 5); Date startDate = cal.getTime(); cal.add(Calendar.DAY_OF_MONTH, 5); Date endDate = cal.getTime(); // set the interval model.setSelectionInterval(startDate, endDate); SortedSet<Date> selection = model.getSelection(); // sanity assertEquals(6, selection.size()); // prepare model for multiple interval selection model.clearSelection(); model.setSelectionMode(DateSelectionModel.SelectionMode.MULTIPLE_INTERVAL_SELECTION); model.setSelectionInterval(date, date); model.setSelectionInterval(startDate, endDate); assertEquals(selection.size(), model.getSelection().size()); assertEquals(selection.first(), model.getSelection().first()); assertEquals(selection.last(), model.getSelection().last()); } @Test public void testUnselectableDatesMultipleInterval() { // Make sure the unselectable dates returns an empty set if it hasn't been // used. SortedSet<Date> unselectableDates = model.getUnselectableDates(); assert(unselectableDates.isEmpty()); model.setSelectionMode(DateSelectionModel.SelectionMode.MULTIPLE_INTERVAL_SELECTION); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(System.currentTimeMillis()); Date today = cal.getTime(); cal.add(Calendar.DAY_OF_MONTH, 1); Date tPlus1 = cal.getTime(); cal.add(Calendar.DAY_OF_MONTH, 1); Date tPlus2 = cal.getTime(); cal.add(Calendar.DAY_OF_MONTH, 1); Date tPlus3 = cal.getTime(); cal.add(Calendar.DAY_OF_MONTH, 1); Date tPlus4 = cal.getTime(); model.setSelectionInterval(today, tPlus4); SortedSet<Date> selection = model.getSelection(); assertTrue(!selection.isEmpty()); assertTrue(5 == selection.size()); assertTrue(today.equals(selection.first())); assertTrue(tPlus4.equals(selection.last())); unselectableDates = new TreeSet<Date>(); unselectableDates.add(tPlus1); unselectableDates.add(tPlus3); model.setUnselectableDates(unselectableDates); // Make sure setting the unselectable dates to include a selected date removes // it from the selected set. selection = model.getSelection(); assertTrue(!selection.isEmpty()); assertTrue(3 == selection.size()); assertTrue(selection.contains(today)); assertTrue(selection.contains(tPlus2)); assertTrue(selection.contains(tPlus4)); // Make sure the unselectable dates is the same as what we set. SortedSet<Date> result = model.getUnselectableDates(); assertTrue(unselectableDates.equals(result)); } @Override @Before public void setUp() { setUpCalendar(); model = new DefaultDateSelectionModel(); } }