Java tutorial
/** * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work * for additional information regarding copyright ownership. * Jasig licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a * copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jasig.schedassist.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import org.apache.commons.lang.time.DateUtils; import org.junit.Assert; import org.junit.Test; /** * Test bench for {@link AvailableBlockBuilder}. * * @author Nicholas Blair, nblair@doit.wisc.edu * @version $Id: AvailableBlockBuilderTest.java 2516 2010-09-09 18:32:23Z npblair $ */ public class AvailableBlockBuilderTest { /** * Validate IllegalArgumentException thrown for all invalid arguments to createBlock. * @throws Exception */ @Test public void testCreateBlockInvalid() throws Exception { Date nullDate = null; try { AvailableBlockBuilder.createBlock(nullDate, nullDate, 1); fail("expected IllegalArgumentException not thrown for null startTime"); } catch (IllegalArgumentException e) { //success } try { AvailableBlockBuilder.createBlock(new Date(), nullDate, 1); fail("expected IllegalArgumentException not thrown for null endTime"); } catch (IllegalArgumentException e) { //success } Date now = new Date(); try { AvailableBlockBuilder.createBlock(now, now, 1); fail("expected IllegalArgumentException not thrown for equivalent start/endtime"); } catch (IllegalArgumentException e) { //success } try { AvailableBlockBuilder.createBlock(now, DateUtils.addMinutes(now, 1), 0); fail("expected IllegalArgumentException not thrown for visitorLimit less than 1"); } catch (IllegalArgumentException e) { //success } } /** * Every monday from June 1 2008 to July 1 2008. * * @throws Exception */ @Test public void testCreateBlocksExample1() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); Set<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("10:30 AM", "1:00 PM", "M", dateFormat.parse("20080601"), dateFormat.parse("20080701")); // there are 5 mondays in between June 1 2008 and July 1 2008 assertEquals(5, blocks.size()); for (AvailableBlock block : blocks) { Calendar cal = Calendar.getInstance(); cal.setTime(block.getStartTime()); assertEquals(10, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(30, cal.get(Calendar.MINUTE)); cal.setTime(block.getEndTime()); assertEquals(13, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(0, cal.get(Calendar.MINUTE)); assertEquals(Calendar.MONDAY, cal.get(Calendar.DAY_OF_WEEK)); assertEquals(1, block.getVisitorLimit()); } blocks = AvailableBlockBuilder.createBlocks("10:30 AM", "1:00 PM", "M", dateFormat.parse("20080601"), dateFormat.parse("20080701"), 5); // there are 5 mondays in between June 1 2008 and July 1 2008 assertEquals(5, blocks.size()); for (AvailableBlock block : blocks) { assertEquals(150, block.getDurationInMinutes()); Calendar cal = Calendar.getInstance(); cal.setTime(block.getStartTime()); assertEquals(10, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(30, cal.get(Calendar.MINUTE)); cal.setTime(block.getEndTime()); assertEquals(13, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(0, cal.get(Calendar.MINUTE)); assertEquals(Calendar.MONDAY, cal.get(Calendar.DAY_OF_WEEK)); assertEquals(5, block.getVisitorLimit()); } } /** * Every week day from June 24 2008 to August 6 2008. * * @throws Exception */ @Test public void testCreateBlocksExample2() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); Date startDate = dateFormat.parse("20080624"); Date endDate = dateFormat.parse("20080806"); Set<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("9:00 AM", "11:30 AM", "MTWRF", startDate, endDate); // 32 weekdays between June 24 2008 and August 6 2008 (including Aug 6 2008) assertEquals(32, blocks.size()); for (AvailableBlock block : blocks) { assertEquals(150, block.getDurationInMinutes()); Calendar cal = Calendar.getInstance(); cal.setTime(block.getStartTime()); assertEquals(9, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(0, cal.get(Calendar.MINUTE)); cal.setTime(block.getEndTime()); assertEquals(11, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(30, cal.get(Calendar.MINUTE)); assertNotSame(Calendar.SATURDAY, cal.get(Calendar.DAY_OF_WEEK)); assertNotSame(Calendar.SUNDAY, cal.get(Calendar.DAY_OF_WEEK)); assertEquals(1, block.getVisitorLimit()); } blocks = AvailableBlockBuilder.createBlocks("9:00 AM", "11:30 AM", "MTWRF", startDate, endDate, 64); // 32 weekdays between June 24 2008 and August 6 2008 (including Aug 6 2008) assertEquals(32, blocks.size()); for (AvailableBlock block : blocks) { assertEquals(150, block.getDurationInMinutes()); Calendar cal = Calendar.getInstance(); cal.setTime(block.getStartTime()); assertEquals(9, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(0, cal.get(Calendar.MINUTE)); cal.setTime(block.getEndTime()); assertEquals(11, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(30, cal.get(Calendar.MINUTE)); assertNotSame(Calendar.SATURDAY, cal.get(Calendar.DAY_OF_WEEK)); assertNotSame(Calendar.SUNDAY, cal.get(Calendar.DAY_OF_WEEK)); assertEquals(64, block.getVisitorLimit()); } } /** * Test times near midnight. * * @throws Exception */ @Test public void testCreateBlocksExample3() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); Date startDate = dateFormat.parse("20080624"); Date endDate = dateFormat.parse("20080630"); Set<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("12:00 AM", "12:59 AM", "MTWRF", startDate, endDate); assertEquals(5, blocks.size()); for (AvailableBlock block : blocks) { assertEquals(59, block.getDurationInMinutes()); Calendar cal = Calendar.getInstance(); cal.setTime(block.getStartTime()); assertEquals(0, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(0, cal.get(Calendar.MINUTE)); cal.setTime(block.getEndTime()); assertEquals(0, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(59, cal.get(Calendar.MINUTE)); assertNotSame(Calendar.SATURDAY, cal.get(Calendar.DAY_OF_WEEK)); assertNotSame(Calendar.SUNDAY, cal.get(Calendar.DAY_OF_WEEK)); assertEquals(1, block.getVisitorLimit()); } blocks = AvailableBlockBuilder.createBlocks("12:00 AM", "12:59 AM", "MTWRF", startDate, endDate, 27); assertEquals(5, blocks.size()); for (AvailableBlock block : blocks) { assertEquals(59, block.getDurationInMinutes()); Calendar cal = Calendar.getInstance(); cal.setTime(block.getStartTime()); assertEquals(0, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(0, cal.get(Calendar.MINUTE)); cal.setTime(block.getEndTime()); assertEquals(0, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(59, cal.get(Calendar.MINUTE)); assertNotSame(Calendar.SATURDAY, cal.get(Calendar.DAY_OF_WEEK)); assertNotSame(Calendar.SUNDAY, cal.get(Calendar.DAY_OF_WEEK)); assertEquals(27, block.getVisitorLimit()); } } /** * Create blocks that span noon. * * @throws Exception */ @Test public void testCreateBlocksExample4() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); Date startDate = dateFormat.parse("20080601"); Date endDate = dateFormat.parse("20080630"); Set<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("11:45 AM", "12:15 PM", "MTWRF", startDate, endDate); assertEquals(21, blocks.size()); for (AvailableBlock block : blocks) { assertEquals(30, block.getDurationInMinutes()); Calendar cal = Calendar.getInstance(); cal.setTime(block.getStartTime()); assertEquals(11, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(45, cal.get(Calendar.MINUTE)); cal.setTime(block.getEndTime()); assertEquals(12, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(15, cal.get(Calendar.MINUTE)); assertNotSame(Calendar.SATURDAY, cal.get(Calendar.DAY_OF_WEEK)); assertNotSame(Calendar.SUNDAY, cal.get(Calendar.DAY_OF_WEEK)); assertEquals(1, block.getVisitorLimit()); } blocks = AvailableBlockBuilder.createBlocks("11:45 AM", "12:15 PM", "MTWRF", startDate, endDate, 2); assertEquals(21, blocks.size()); for (AvailableBlock block : blocks) { assertEquals(30, block.getDurationInMinutes()); Calendar cal = Calendar.getInstance(); cal.setTime(block.getStartTime()); assertEquals(11, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(45, cal.get(Calendar.MINUTE)); cal.setTime(block.getEndTime()); assertEquals(12, cal.get(Calendar.HOUR_OF_DAY)); assertEquals(15, cal.get(Calendar.MINUTE)); assertNotSame(Calendar.SATURDAY, cal.get(Calendar.DAY_OF_WEEK)); assertNotSame(Calendar.SUNDAY, cal.get(Calendar.DAY_OF_WEEK)); assertEquals(2, block.getVisitorLimit()); } } /** * Create {@link AvailableBlock}s around daylight savings conversions, verify * expected behavior. * * @throws Exception */ @Test public void testCreateBlocksOverDaylightSavings() throws Exception { AvailableBlock block = AvailableBlockBuilder.createBlock("20091101-0130", "20091101-0200"); assertNotNull(block); assertEquals(30, block.getDurationInMinutes()); block = AvailableBlockBuilder.createBlock("20091101-0200", "20091101-0230"); assertNotNull(block); assertEquals(30, block.getDurationInMinutes()); block = AvailableBlockBuilder.createBlock("20091101-0145", "20091101-0215"); assertNotNull(block); assertEquals(30, block.getDurationInMinutes()); block = AvailableBlockBuilder.createBlock("20090308-0130", "20090308-0200"); assertNotNull(block); assertEquals(30, block.getDurationInMinutes()); block = AvailableBlockBuilder.createBlock("20090308-0200", "20090308-0230"); assertNotNull(block); assertEquals(30, block.getDurationInMinutes()); block = AvailableBlockBuilder.createBlock("20090308-0145", "20090308-0215"); assertNotNull(block); assertEquals(30, block.getDurationInMinutes()); } /** * Expand an {@link AvailableBlock} that was created with 9:00 AM and 3:00 PM as * start and end times, respectively. * * @throws Exception */ @Test public void testExpand() throws Exception { SimpleDateFormat dateTimeFormat = CommonDateOperations.getDateTimeFormat(); Date startTime = dateTimeFormat.parse("20080601-0900"); Date endTime = dateTimeFormat.parse("20080601-1500"); AvailableBlock original = AvailableBlockBuilder.createBlock(startTime, endTime); assertNotNull(original); Set<AvailableBlock> expanded = AvailableBlockBuilder.expand(original, 30); assertEquals(12, expanded.size()); Date currentStart = startTime; for (AvailableBlock block : expanded) { assertEquals(30, block.getDurationInMinutes()); assertEquals(currentStart, block.getStartTime()); currentStart = DateUtils.addMinutes(currentStart, 30); assertEquals(currentStart, block.getEndTime()); } } /** * Asserts expand called on an {@link AvailableBlock} from 9:00 AM to 9:30 AM returns * only 1 block, equivalent to the original. * * @throws Exception */ @Test public void testExpand2() throws Exception { SimpleDateFormat dateTimeFormat = CommonDateOperations.getDateTimeFormat(); Date startTime = dateTimeFormat.parse("20080601-0900"); Date endTime = dateTimeFormat.parse("20080601-0930"); AvailableBlock original = AvailableBlockBuilder.createBlock(startTime, endTime); assertNotNull(original); Set<AvailableBlock> expanded = AvailableBlockBuilder.expand(original, 30); assertEquals(1, expanded.size()); assertTrue(expanded.contains(original)); } /** * Assert expand function preserves original visitorLimit. * * @throws Exception */ @Test public void testExpandPreserveVisitorLimit() throws Exception { SimpleDateFormat dateTimeFormat = CommonDateOperations.getDateTimeFormat(); Date startTime = dateTimeFormat.parse("20080601-0900"); Date endTime = dateTimeFormat.parse("20080601-1500"); AvailableBlock toExpand = AvailableBlockBuilder.createBlock(startTime, endTime, 10); SortedSet<AvailableBlock> expanded20 = AvailableBlockBuilder.expand(toExpand, 20); assertEquals(18, expanded20.size()); Date currentStart = startTime; for (AvailableBlock block : expanded20) { assertEquals(20, block.getDurationInMinutes()); assertEquals(10, block.getVisitorLimit()); assertEquals(currentStart, block.getStartTime()); currentStart = DateUtils.addMinutes(currentStart, 20); assertEquals(currentStart, block.getEndTime()); } SortedSet<AvailableBlock> expanded40 = AvailableBlockBuilder.expand(toExpand, 40); assertEquals(9, expanded40.size()); currentStart = startTime; for (AvailableBlock block : expanded40) { assertEquals(40, block.getDurationInMinutes()); assertEquals(10, block.getVisitorLimit()); assertEquals(currentStart, block.getStartTime()); currentStart = DateUtils.addMinutes(currentStart, 40); assertEquals(currentStart, block.getEndTime()); } SortedSet<AvailableBlock> expanded60 = AvailableBlockBuilder.expand(toExpand, 60); assertEquals(6, expanded60.size()); currentStart = startTime; for (AvailableBlock block : expanded60) { assertEquals(60, block.getDurationInMinutes()); assertEquals(10, block.getVisitorLimit()); assertEquals(currentStart, block.getStartTime()); currentStart = DateUtils.addMinutes(currentStart, 60); assertEquals(currentStart, block.getEndTime()); } } /** * Create a series of (combined) blocks. * Expand that series, then re-combined. * Assert the re-combined set matches the original set. * * @throws Exception */ @Test public void testCombine() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); Date startDate = dateFormat.parse("20080624"); Date endDate = dateFormat.parse("20080806"); Set<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("9:00 AM", "11:30 AM", "MTWRF", startDate, endDate); // 32 weekdays between June 24 2008 and August 6 2008 assertEquals(32, blocks.size()); SortedSet<AvailableBlock> expandedBlocks = AvailableBlockBuilder.expand(blocks, 30); assertEquals(160, expandedBlocks.size()); Set<AvailableBlock> recombinedBlocks = AvailableBlockBuilder.combine(expandedBlocks); Iterator<AvailableBlock> originalIterator = blocks.iterator(); Iterator<AvailableBlock> recombinedIterator = recombinedBlocks.iterator(); for (int i = 0; i < 32; i++) { assertEquals(originalIterator.next(), recombinedIterator.next()); } assertEquals(32, recombinedBlocks.size()); } /** * Create 1 years worth of (combined) blocks. * Expand the set. * Re-combine the expanded set, assert matches original set. * * @throws Exception */ @Test public void testCombine2() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); Date startDate = dateFormat.parse("20080101"); Date endDate = dateFormat.parse("20081231"); Set<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("12:00 AM", "11:30 PM", "NMTWRFS", startDate, endDate); // 366 days in 2008 assertEquals(366, blocks.size()); SortedSet<AvailableBlock> expandedBlocks = AvailableBlockBuilder.expand(blocks, 30); assertEquals(17202, expandedBlocks.size()); Set<AvailableBlock> recombinedBlocks = AvailableBlockBuilder.combine(expandedBlocks); Iterator<AvailableBlock> originalIterator = blocks.iterator(); Iterator<AvailableBlock> recombinedIterator = recombinedBlocks.iterator(); for (int i = 0; i < 366; i++) { assertEquals(originalIterator.next(), recombinedIterator.next()); } assertEquals(366, recombinedBlocks.size()); } /** * Create 50 years worth of (combined) blocks. * Expand the set. * Re-combine the expanded set, assert matches original set. * * @throws Exception */ //@Test public void testCombine50Years() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); Date startDate = dateFormat.parse("20080101"); Date endDate = dateFormat.parse("20581231"); Set<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("12:00 AM", "11:30 PM", "NMTWRFS", startDate, endDate); assertEquals(18628, blocks.size()); SortedSet<AvailableBlock> expandedBlocks = AvailableBlockBuilder.expand(blocks, 30); assertEquals(875516, expandedBlocks.size()); Set<AvailableBlock> recombinedBlocks = AvailableBlockBuilder.combine(expandedBlocks); Iterator<AvailableBlock> originalIterator = blocks.iterator(); Iterator<AvailableBlock> recombinedIterator = recombinedBlocks.iterator(); for (int i = 0; i < 18628; i++) { assertEquals(originalIterator.next(), recombinedIterator.next()); } assertEquals(18628, recombinedBlocks.size()); } /** * Create a set of blocks with createBlocks. * expand, then remove some of the expanded elements. * call combine and verify blocks are created properly. * * @throws Exception */ @Test public void testCombine3() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); Date startDate = dateFormat.parse("20080720"); Date endDate = dateFormat.parse("20080726"); Set<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("8:00 AM", "4:00 PM", "MWF", startDate, endDate); // Mon/Wed/Fri from July 20 to July 26 // 3 days in this span assertEquals(3, blocks.size()); // 16 blocks per day (8 hours) SortedSet<AvailableBlock> expandedBlocks = AvailableBlockBuilder.expand(blocks, 30); assertEquals(48, expandedBlocks.size()); // remove 12:00 to 12:30 on Wednesday expandedBlocks.remove(AvailableBlockBuilder.createBlock("20080723-1200", "20080723-1230")); assertEquals(47, expandedBlocks.size()); SortedSet<AvailableBlock> recombinedBlocks = AvailableBlockBuilder.combine(expandedBlocks); assertEquals(4, recombinedBlocks.size()); SortedSet<AvailableBlock> reexpandedBlocks = AvailableBlockBuilder.expand(recombinedBlocks, 30); assertEquals(47, reexpandedBlocks.size()); // remove 3:30 to 4:00 on Friday reexpandedBlocks.remove(AvailableBlockBuilder.createBlock("20080725-1530", "20080725-1600")); assertEquals(46, reexpandedBlocks.size()); // recombining shouldn't change the size; we're just trimming the length of the last large block assertEquals(4, AvailableBlockBuilder.combine(reexpandedBlocks).size()); } /** * * @throws Exception */ @Test public void testCombine15s() throws Exception { SimpleDateFormat timeFormat = CommonDateOperations.getDateTimeFormat(); Date time1 = timeFormat.parse("20090211-1100"); Date time2 = timeFormat.parse("20090211-1105"); AvailableBlock block1 = AvailableBlockBuilder.createSmallestAllowedBlock(time1); assertEquals(time2, block1.getEndTime()); AvailableBlock block2 = AvailableBlockBuilder.createSmallestAllowedBlock(time2); SortedSet<AvailableBlock> smallBlocks = new TreeSet<AvailableBlock>(); smallBlocks.add(block1); smallBlocks.add(block2); Set<AvailableBlock> combined1 = AvailableBlockBuilder.combine(smallBlocks); assertEquals(1, combined1.size()); AvailableBlock expected = AvailableBlockBuilder.createBlock(block1.getStartTime(), block2.getEndTime()); assertTrue(combined1.contains(expected)); } /** * Create a regular schedule and add a single 15 minute outlier. * Combine and verify the outlier is not lost. * * @throws Exception */ @Test public void testCombinePreservesOutliersSmall() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); SimpleDateFormat timeFormat = CommonDateOperations.getDateTimeFormat(); Set<AvailableBlock> regularSchedule = AvailableBlockBuilder.createBlocks("9:00 AM", "3:00 PM", "MWF", dateFormat.parse("20090309"), dateFormat.parse("20090313")); assertEquals(3, regularSchedule.size()); SortedSet<AvailableBlock> regularScheduleExpanded = AvailableBlockBuilder.expand(regularSchedule, 15); assertEquals(72, regularScheduleExpanded.size()); Set<AvailableBlock> assertCombine = AvailableBlockBuilder.combine(regularScheduleExpanded); assertEquals(3, assertCombine.size()); AvailableBlock outlier = AvailableBlockBuilder.createBlock(timeFormat.parse("20090312-1200"), timeFormat.parse("20090312-1215")); regularScheduleExpanded.add(outlier); assertEquals(73, regularScheduleExpanded.size()); Set<AvailableBlock> recombined = AvailableBlockBuilder.combine(regularScheduleExpanded); assertEquals(4, recombined.size()); assertTrue(recombined.contains(outlier)); } /** * Create a regular schedule and add a single 15 minute outlier. * Combine and verify the outlier is not lost. * * @throws Exception */ @Test public void testCombinePreservesOutliersLarge() throws Exception { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); SimpleDateFormat timeFormat = CommonDateOperations.getDateTimeFormat(); Set<AvailableBlock> regularSchedule = AvailableBlockBuilder.createBlocks("9:00 AM", "3:00 PM", "MWF", dateFormat.parse("20090101"), dateFormat.parse("20090601")); assertEquals(65, regularSchedule.size()); SortedSet<AvailableBlock> regularScheduleExpanded = AvailableBlockBuilder.expand(regularSchedule, 15); assertEquals(1560, regularScheduleExpanded.size()); Set<AvailableBlock> assertCombine = AvailableBlockBuilder.combine(regularScheduleExpanded); assertEquals(65, assertCombine.size()); AvailableBlock outlier = AvailableBlockBuilder.createBlock(timeFormat.parse("20090312-1200"), timeFormat.parse("20090312-1215")); regularScheduleExpanded.add(outlier); assertEquals(1561, regularScheduleExpanded.size()); Set<AvailableBlock> recombined = AvailableBlockBuilder.combine(regularScheduleExpanded); assertEquals(66, recombined.size()); assertTrue(recombined.contains(outlier)); } /** * Create 2 adjacent blocks visitor limit set to 10. * Pass them into combine, assert they come out 1 combined block. * * @throws Exception */ @Test public void testCombineVisitorLimit10() throws Exception { AvailableBlock block1 = AvailableBlockBuilder.createBlock("20091007-1200", "20091007-1230", 10); assertEquals(30, block1.getDurationInMinutes()); AvailableBlock block2 = AvailableBlockBuilder.createBlock("20091007-1230", "20091007-1300", 10); assertEquals(30, block2.getDurationInMinutes()); SortedSet<AvailableBlock> smallBlocks = new TreeSet<AvailableBlock>(); smallBlocks.add(block1); smallBlocks.add(block2); SortedSet<AvailableBlock> resultCombined = AvailableBlockBuilder.combine(smallBlocks); assertEquals(resultCombined.size(), 1); AvailableBlock expectedCombined = AvailableBlockBuilder.createBlock("20091007-1200", "20091007-1300", 10); assertTrue(resultCombined.contains(expectedCombined)); assertEquals(60, expectedCombined.getDurationInMinutes()); } /** * Create 2 adjacent blocks with different visitor limits. * Pass them into combine, assert they come out as 2 separate blocks. * * @throws Exception */ @Test public void testCombineMismatchedVisitorLimit() throws Exception { AvailableBlock block1 = AvailableBlockBuilder.createBlock("20091007-1200", "20091007-1230", 10); AvailableBlock block2 = AvailableBlockBuilder.createBlock("20091007-1230", "20091007-1300", 9); SortedSet<AvailableBlock> smallBlocks = new TreeSet<AvailableBlock>(); smallBlocks.add(block1); smallBlocks.add(block2); SortedSet<AvailableBlock> resultCombined = AvailableBlockBuilder.combine(smallBlocks); assertEquals(resultCombined.size(), 2); assertTrue(resultCombined.contains(block1)); assertTrue(resultCombined.contains(block2)); } /** * Create 2 adjacent blocks with different meeting locations. * Pass them into combine, assert they come out as 2 separate blocks. * @throws Exception */ @Test public void testCombineMismatchedMeetingLocation() throws Exception { AvailableBlock block1 = AvailableBlockBuilder.createBlock("20091007-1200", "20091007-1230", 1, "alternate location"); AvailableBlock block2 = AvailableBlockBuilder.createBlock("20091007-1230", "20091007-1300", 1, null); SortedSet<AvailableBlock> smallBlocks = new TreeSet<AvailableBlock>(); smallBlocks.add(block1); smallBlocks.add(block2); SortedSet<AvailableBlock> resultCombined = AvailableBlockBuilder.combine(smallBlocks); assertEquals(resultCombined.size(), 2); assertTrue(resultCombined.contains(block1)); assertTrue(resultCombined.contains(block2)); } /** * Test the overloaded createSmallestAllowedBlock methods. * * @throws Exception */ @Test public void testCreateSmallestAllowedBlock() throws Exception { Date date = CommonDateOperations.parseDateTimePhrase("20091103-1500"); AvailableBlock block = AvailableBlockBuilder.createSmallestAllowedBlock(date); assertEquals(date, block.getStartTime()); assertEquals(DateUtils.addMinutes(date, AvailableBlockBuilder.MINIMUM_MINUTES), block.getEndTime()); assertEquals(1, block.getVisitorLimit()); block = AvailableBlockBuilder.createSmallestAllowedBlock(date, 10); assertEquals(date, block.getStartTime()); assertEquals(DateUtils.addMinutes(date, AvailableBlockBuilder.MINIMUM_MINUTES), block.getEndTime()); assertEquals(10, block.getVisitorLimit()); block = AvailableBlockBuilder.createSmallestAllowedBlock("20091103-1500"); assertEquals(date, block.getStartTime()); assertEquals(DateUtils.addMinutes(date, AvailableBlockBuilder.MINIMUM_MINUTES), block.getEndTime()); assertEquals(1, block.getVisitorLimit()); } /** * @throws ParseException * @throws InputFormatException * */ @Test public void testTwentyMinuteDuration() throws InputFormatException, ParseException { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); SortedSet<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("9:00 AM", "11:40 AM", "MW", dateFormat.parse("20100830"), dateFormat.parse("20100903")); Assert.assertEquals(2, blocks.size()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100830-0900"), blocks.first().getStartTime()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100830-1140"), blocks.first().getEndTime()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100901-0900"), blocks.last().getStartTime()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100901-1140"), blocks.last().getEndTime()); SortedSet<AvailableBlock> expanded = AvailableBlockBuilder.expand(blocks, 20); Assert.assertEquals(16, expanded.size()); Date originalStart = CommonDateOperations.getDateTimeFormat().parse("20100830-0900"); Date currentStart = originalStart; for (AvailableBlock e : expanded) { if (!DateUtils.isSameDay(e.getStartTime(), currentStart)) { currentStart = DateUtils.addDays(originalStart, 2); } Assert.assertEquals(currentStart, e.getStartTime()); currentStart = DateUtils.addMinutes(currentStart, 20); Assert.assertEquals(currentStart, e.getEndTime()); } } /** * Test that highlights the problem when a customer specifies a start/end range * for blocks and a meeting duration that leaves a remainder. * * @throws ParseException * @throws InputFormatException */ @Test public void testDurationLeavesRemainder() throws InputFormatException, ParseException { SimpleDateFormat dateFormat = CommonDateOperations.getDateFormat(); SortedSet<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("9:03 AM", "3:19 PM", "MWF", dateFormat.parse("20100830"), dateFormat.parse("20100903")); Assert.assertEquals(3, blocks.size()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100830-0903"), blocks.first().getStartTime()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100830-1519"), blocks.first().getEndTime()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100903-0903"), blocks.last().getStartTime()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100903-1519"), blocks.last().getEndTime()); SortedSet<AvailableBlock> expanded = AvailableBlockBuilder.expand(blocks, 17); AvailableBlock last = null; long millisIn17Minutes = 1020000L; for (AvailableBlock e : expanded) { if (last != null) { if (DateUtils.isSameDay(e.getStartTime(), last.getStartTime())) { Assert.assertEquals(last.getEndTime(), e.getStartTime()); Assert.assertEquals(e.getEndTime().getTime() - last.getEndTime().getTime(), millisIn17Minutes); } else { Calendar cal = Calendar.getInstance(); cal.setTime(e.getStartTime()); Assert.assertEquals(9, cal.get(Calendar.HOUR_OF_DAY)); Assert.assertEquals(3, cal.get(Calendar.MINUTE)); cal.setTime(e.getEndTime()); Assert.assertEquals(9, cal.get(Calendar.HOUR_OF_DAY)); Assert.assertEquals(20, cal.get(Calendar.MINUTE)); // double check yesterday's endpoint cal.setTime(last.getStartTime()); Assert.assertEquals(15, cal.get(Calendar.HOUR_OF_DAY)); Assert.assertEquals(0, cal.get(Calendar.MINUTE)); cal.setTime(last.getEndTime()); Assert.assertEquals(15, cal.get(Calendar.HOUR_OF_DAY)); Assert.assertEquals(17, cal.get(Calendar.MINUTE)); } } else { // first block in the series Calendar cal = Calendar.getInstance(); cal.setTime(e.getStartTime()); Assert.assertEquals(9, cal.get(Calendar.HOUR_OF_DAY)); Assert.assertEquals(3, cal.get(Calendar.MINUTE)); cal.setTime(e.getEndTime()); Assert.assertEquals(9, cal.get(Calendar.HOUR_OF_DAY)); Assert.assertEquals(20, cal.get(Calendar.MINUTE)); } last = e; } Assert.assertEquals(66, expanded.size()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100830-0903"), expanded.first().getStartTime()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100830-0920"), expanded.first().getEndTime()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100903-1500"), expanded.last().getStartTime()); Assert.assertEquals(CommonDateOperations.getDateTimeFormat().parse("20100903-1517"), expanded.last().getEndTime()); } @Test public void testMeetingLocationEffectHashCodeEquals() throws InputFormatException { AvailableBlock blockNoLocation = AvailableBlockBuilder.createBlock("20110810-0900", "20110810-0930"); AvailableBlock blockWithLocation = AvailableBlockBuilder.createBlock("20110810-0900", "20110810-0930", 1, "different location"); Assert.assertEquals(blockNoLocation, blockWithLocation); Assert.assertEquals(blockNoLocation.hashCode(), blockWithLocation.hashCode()); } @Test public void textExpandPreserveLocation() throws InputFormatException, ParseException { SortedSet<AvailableBlock> blocks = AvailableBlockBuilder.createBlocks("9:00 AM", "12:00 PM", "MWF", CommonDateOperations.getDateFormat().parse("20110801"), CommonDateOperations.getDateFormat().parse("20110831"), 1, "alternate location"); for (AvailableBlock block : blocks) { Assert.assertEquals("alternate location", block.getMeetingLocation()); } } /** * Create adjacent available blocks but set different meeting locations. * Confirm blocks not combined by combine method. * @throws InputFormatException * */ @Test public void testDifferentMeetingLocationNotCombined() throws InputFormatException { AvailableBlock blockNoLocation = AvailableBlockBuilder.createBlock("20110810-0900", "20110810-0930", 1, "some location"); AvailableBlock blockWithLocation = AvailableBlockBuilder.createBlock("20110810-0930", "20110810-1000", 1, "different location"); SortedSet<AvailableBlock> smallBlocks = new TreeSet<AvailableBlock>(); smallBlocks.add(blockNoLocation); smallBlocks.add(blockWithLocation); SortedSet<AvailableBlock> combined = AvailableBlockBuilder.combine(smallBlocks); Assert.assertEquals(2, combined.size()); Assert.assertEquals(blockNoLocation, combined.first()); Assert.assertEquals(blockWithLocation, combined.last()); } /** * * @throws InputFormatException */ @Test public void testSafeMeetingLocationEquals() throws InputFormatException { AvailableBlock blockNoLocation = AvailableBlockBuilder.createBlock("20110810-0900", "20110810-0930", 1); AvailableBlock blockNoLocation2 = AvailableBlockBuilder.createBlock("20110810-0900", "20110810-0930", 1); Assert.assertTrue(AvailableBlockBuilder.safeMeetingLocationEquals(blockNoLocation, blockNoLocation2)); AvailableBlock blockWithLocation = AvailableBlockBuilder.createBlock("20110810-0930", "20110810-1000", 1, "different location"); Assert.assertFalse(AvailableBlockBuilder.safeMeetingLocationEquals(blockNoLocation, blockWithLocation)); AvailableBlock blockWithLocation2 = AvailableBlockBuilder.createBlock("20110810-0930", "20110810-1000", 1, "different location"); Assert.assertTrue(AvailableBlockBuilder.safeMeetingLocationEquals(blockWithLocation, blockWithLocation2)); } }