SegmentedTimelineTest.java 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  1. /* ===========================================================
  2. * JFreeChart : a free chart library for the Java(tm) platform
  3. * ===========================================================
  4. *
  5. * (C) Copyright 2000-2013, by Object Refinery Limited and Contributors.
  6. *
  7. * Project Info: http://www.jfree.org/jfreechart/index.html
  8. *
  9. * This library is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation; either version 2.1 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This library is distributed in the hope that it will be useful, but
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  17. * License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  22. * USA.
  23. *
  24. * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  25. * Other names may be trademarks of their respective owners.]
  26. *
  27. * ---------------------------
  28. * SegmentedTimelineTest.java
  29. * ---------------------------
  30. * (C) Copyright 2003-2013, by Bill Kelemen and Contributors.
  31. *
  32. * Original Author: Bill Kelemen;
  33. * Contributor(s): David Gilbert (for Object Refinery Limited);
  34. *
  35. * Changes
  36. * -------
  37. * 24-May-2003 : Version 1 (BK);
  38. * 07-Jan-2005 : Added test for hashCode() method (DG);
  39. * 02-Feb-2007 : Removed author tags all over JFreeChart sources (DG);
  40. *
  41. */
  42. package org.jfree.chart.axis;
  43. import static org.junit.Assert.assertEquals;
  44. import static org.junit.Assert.assertFalse;
  45. import static org.junit.Assert.assertTrue;
  46. import java.text.Format;
  47. import java.text.NumberFormat;
  48. import java.text.ParseException;
  49. import java.text.SimpleDateFormat;
  50. import java.util.ArrayList;
  51. import java.util.Calendar;
  52. import java.util.GregorianCalendar;
  53. import java.util.Iterator;
  54. import org.jfree.chart.TestUtilities;
  55. import org.junit.Before;
  56. import org.junit.Ignore;
  57. import org.junit.Test;
  58. /**
  59. * JUnit Tests for the {@link SegmentedTimeline} class.
  60. */
  61. public class SegmentedTimelineTest {
  62. /** These constants control test cycles in the validateXXXX methods. */
  63. private static final int TEST_CYCLE_START = 0;
  64. /** These constants control test cycles in the validateXXXX methods. */
  65. private static final int TEST_CYCLE_END = 1000;
  66. /** These constants control test cycles in the validateXXXX methods. */
  67. private static final int TEST_CYCLE_INC = 55;
  68. /** Number of ms in five years */
  69. private static final long FIVE_YEARS = 5 * 365
  70. * SegmentedTimeline.DAY_SEGMENT_SIZE;
  71. /** Number format object for ms tests. */
  72. private static final NumberFormat NUMBER_FORMAT
  73. = NumberFormat.getNumberInstance();
  74. /** Date format object for Monday through Friday tests. */
  75. private static final SimpleDateFormat DATE_FORMAT;
  76. /** Date format object 9:00 AM to 4:00 PM tests. */
  77. private static final SimpleDateFormat DATE_TIME_FORMAT;
  78. /** Some ms exceptions for ms testing. */
  79. private static final String[] MS_EXCEPTIONS = {"0", "2", "4", "10", "15",
  80. "16", "17", "18", "19", "20", "21", "22", "23", "24", "47", "58",
  81. "100", "101"};
  82. /** Some ms4 exceptions for ms testing. */
  83. private static final String[] MS2_BASE_TIMELINE_EXCEPTIONS = {"0", "8",
  84. "16", "24", "32", "40", "48", "56", "64", "72", "80", "88", "96",
  85. "104", "112", "120", "128", "136"};
  86. /** US non-trading dates in 2000 through 2002 to test exceptions. */
  87. private static final String[] US_HOLIDAYS = {"2000-01-17", "2000-02-21",
  88. "2000-04-21", "2000-05-29", "2000-07-04", "2000-09-04", "2000-11-23",
  89. "2000-12-25", "2001-01-01", "2001-01-15", "2001-02-19", "2001-04-13",
  90. "2001-05-28", "2001-07-04", "2001-09-03", "2001-09-11", "2001-09-12",
  91. "2001-09-13", "2001-09-14", "2001-11-22", "2001-12-25", "2002-01-01",
  92. "2002-01-21", "2002-02-18", "2002-03-29", "2002-05-27", "2002-07-04",
  93. "2002-09-02", "2002-11-28", "2002-12-25"};
  94. /** Some test exceptions for the fifteen min timeline. */
  95. private static final String[] FIFTEEN_MIN_EXCEPTIONS = {
  96. "2000-01-10 09:00:00", "2000-01-10 09:15:00", "2000-01-10 09:30:00",
  97. "2000-01-10 09:45:00", "2000-01-10 10:00:00", "2000-01-10 10:15:00",
  98. "2000-02-15 09:00:00", "2000-02-15 09:15:00", "2000-02-15 09:30:00",
  99. "2000-02-15 09:45:00", "2000-02-15 10:00:00", "2000-02-15 10:15:00",
  100. "2000-02-16 11:00:00", "2000-02-16 11:15:00", "2000-02-16 11:30:00",
  101. "2000-02-16 11:45:00", "2000-02-16 12:00:00", "2000-02-16 12:15:00",
  102. "2000-02-16 12:30:00", "2000-02-16 12:45:00", "2000-02-16 01:00:00",
  103. "2000-02-16 01:15:00", "2000-02-16 01:30:00", "2000-02-16 01:45:00",
  104. "2000-05-17 11:45:00", "2000-05-17 12:00:00", "2000-05-17 12:15:00",
  105. "2000-05-17 12:30:00", "2000-05-17 12:45:00", "2000-05-17 01:00:00",
  106. "2000-05-17 01:15:00", "2000-05-17 01:30:00", "2000-05-17 01:45:00",
  107. "2000-05-17 02:00:00", "2000-05-17 02:15:00", "2000-05-17 02:30:00",
  108. "2000-05-17 02:45:00", "2000-05-17 03:00:00", "2000-05-17 03:15:00",
  109. "2000-05-17 03:30:00", "2000-05-17 03:45:00", "2000-05-17 04:00:00"};
  110. /** Our 1-ms test timeline using 5 included and 2 excluded segments. */
  111. private SegmentedTimeline msTimeline;
  112. /**
  113. * Our 1-ms test timeline (with baseTimeline) using 2 included and 2
  114. * excluded segments.
  115. */
  116. private SegmentedTimeline ms2Timeline;
  117. /**
  118. * Our 4-ms test base timeline for ms2Timeline using 1 included and 1
  119. * excluded segments
  120. */
  121. private SegmentedTimeline ms2BaseTimeline;
  122. /** Our test Monday through Friday test timeline. */
  123. private SegmentedTimeline mondayFridayTimeline;
  124. /** Our 9:00 AM to 4:00 PM fifteen minute timeline. */
  125. private SegmentedTimeline fifteenMinTimeline;
  126. /** ms from 1970-01-01 to first monday after 2001-01-01. */
  127. private Calendar monday;
  128. /** ms from 1970-01-01 to 9 am first monday after 2001-01-01. */
  129. private Calendar monday9am;
  130. /** Static initialization block. */
  131. static {
  132. DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
  133. DATE_FORMAT.setTimeZone(SegmentedTimeline.NO_DST_TIME_ZONE);
  134. DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  135. DATE_TIME_FORMAT.setTimeZone(SegmentedTimeline.NO_DST_TIME_ZONE);
  136. }
  137. /**
  138. * Sets up the fixture, for example, open a network connection.
  139. * This method is called before a test is executed.
  140. *
  141. * @throws Exception if there is a problem.
  142. */
  143. @Before
  144. public void setUp() throws Exception {
  145. // setup our test timelines
  146. //
  147. // Legend for comments below:
  148. // <spaces> = Segments included in the final timeline
  149. // EE = Excluded segments via timeline rules
  150. // xx = Exception segments inherited from base timeline exclusions
  151. // 1-ms test timeline using 5 included and 2 excluded segments.
  152. //
  153. // timeline start time = 0
  154. // |
  155. // v
  156. // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ..
  157. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+..
  158. // | | | | | |EE|EE| | | | | |EE|EE| | | | | | |EE|EE| <-- msTimeline
  159. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+..
  160. // \_________ ________/ \_/
  161. // \/ |
  162. // segment group segment size = 1 ms
  163. //
  164. this.msTimeline = new SegmentedTimeline(1, 5, 2);
  165. this.msTimeline.setStartTime(0);
  166. // 4-ms test base timeline for ms2Timeline using 1 included and 1
  167. // excluded segments
  168. //
  169. // timeline start time = 0
  170. // |
  171. // v
  172. // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...
  173. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
  174. // | | | | |EE|EE|EE|EE| | | | |EE|EE|EE|EE| | | | | <-- ms2BaseTimeline
  175. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
  176. // \__________ _________/ \____ _____/
  177. // \/ \/
  178. // segment group segment size = 4 ms
  179. //
  180. this.ms2BaseTimeline = new SegmentedTimeline(4, 1, 1);
  181. this.ms2BaseTimeline.setStartTime(0);
  182. // 1-ms test timeline (with a baseTimeline) using 2 included and 2
  183. // excluded segments centered inside each base segment
  184. //
  185. // The ms2Timeline without a base would look like this:
  186. //
  187. // timeline start time = 1
  188. // |
  189. // v
  190. // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...
  191. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
  192. // |EE| | |EE|EE| | |EE|EE| | |EE|EE| | |EE|EE| | |EE| <-- ms2Timeline
  193. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
  194. // \____ _____/ \_/
  195. // \/ |
  196. // segment group segment size = 1 ms
  197. //
  198. // With the base timeline some originally included segments are now
  199. // removed (see "xx" below):
  200. //
  201. // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...
  202. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
  203. // |EE| | |EE|EE|xx|xx|EE|EE| | |EE|EE|xx|xx|EE|EE| | |EE| <-- ms2Timeline
  204. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
  205. // | | | | |EE|EE|EE|EE| | | | |EE|EE|EE|EE| | | | | <-- ms2BaseTimeline
  206. // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+...
  207. //
  208. this.ms2Timeline = new SegmentedTimeline(1, 2, 2);
  209. this.ms2Timeline.setStartTime(1);
  210. this.ms2Timeline.setBaseTimeline(this.ms2BaseTimeline);
  211. // test monday though friday timeline
  212. this.mondayFridayTimeline
  213. = SegmentedTimeline.newMondayThroughFridayTimeline();
  214. // test 9am-4pm Monday through Friday timeline
  215. this.fifteenMinTimeline
  216. = SegmentedTimeline.newFifteenMinuteTimeline();
  217. // find first Monday after 2001-01-01
  218. Calendar cal = new GregorianCalendar(
  219. SegmentedTimeline.NO_DST_TIME_ZONE);
  220. cal.set(2001, 0, 1, 0, 0, 0);
  221. cal.set(Calendar.MILLISECOND, 0);
  222. while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
  223. cal.add(Calendar.DATE, 1);
  224. }
  225. this.monday = (Calendar) cal.clone();
  226. // calculate 9am on the first Monday after 2001-01-01
  227. cal.add(Calendar.HOUR, 9);
  228. this.monday9am = (Calendar) cal.clone();
  229. }
  230. //////////////////////////////////////////////////////////////////////////
  231. // test construction process
  232. //////////////////////////////////////////////////////////////////////////
  233. /**
  234. * Tests that the new method that created the msTimeline segmented
  235. * timeline did so correctly.
  236. */
  237. @Test
  238. public void testMsSegmentedTimeline() {
  239. // verify attributes set during object construction
  240. assertEquals(1, this.msTimeline.getSegmentSize());
  241. assertEquals(0, this.msTimeline.getStartTime());
  242. assertEquals(5, this.msTimeline.getSegmentsIncluded());
  243. assertEquals(2, this.msTimeline.getSegmentsExcluded());
  244. }
  245. /**
  246. * Tests that the new method that created the ms2Timeline segmented
  247. * timeline did so correctly.
  248. */
  249. @Test
  250. public void testMs2SegmentedTimeline() {
  251. // verify attributes set during object construction
  252. assertEquals(1, this.ms2Timeline.getSegmentSize());
  253. assertEquals(1, this.ms2Timeline.getStartTime());
  254. assertEquals(2, this.ms2Timeline.getSegmentsIncluded());
  255. assertEquals(2, this.ms2Timeline.getSegmentsExcluded());
  256. assertEquals(this.ms2BaseTimeline, this.ms2Timeline.getBaseTimeline());
  257. }
  258. /**
  259. * Tests that the factory method that creates Monday through Friday
  260. * segmented timeline does so correctly.
  261. */
  262. @Test
  263. public void testMondayThroughFridaySegmentedTimeline() {
  264. // verify attributes set during object construction
  265. assertEquals(SegmentedTimeline.DAY_SEGMENT_SIZE,
  266. this.mondayFridayTimeline.getSegmentSize());
  267. assertEquals(SegmentedTimeline.FIRST_MONDAY_AFTER_1900,
  268. this.mondayFridayTimeline.getStartTime());
  269. assertEquals(5, this.mondayFridayTimeline.getSegmentsIncluded());
  270. assertEquals(2, this.mondayFridayTimeline.getSegmentsExcluded());
  271. }
  272. /**
  273. * Tests that the factory method that creates a 15-min 9:00 AM 4:00 PM
  274. * segmented axis does so correctly.
  275. */
  276. @Test
  277. public void testFifteenMinSegmentedTimeline() {
  278. assertEquals(SegmentedTimeline.FIFTEEN_MINUTE_SEGMENT_SIZE,
  279. this.fifteenMinTimeline.getSegmentSize());
  280. assertEquals(SegmentedTimeline.FIRST_MONDAY_AFTER_1900 + 36
  281. * this.fifteenMinTimeline.getSegmentSize(),
  282. this.fifteenMinTimeline.getStartTime());
  283. assertEquals(28, this.fifteenMinTimeline.getSegmentsIncluded());
  284. assertEquals(68, this.fifteenMinTimeline.getSegmentsExcluded());
  285. }
  286. //////////////////////////////////////////////////////////////////////////
  287. // test one-segment and adjacent segments
  288. //////////////////////////////////////////////////////////////////////////
  289. /**
  290. * Tests one segment of the ms timeline. Internal indices
  291. * inside one segment as well as adjacent segments are verified.
  292. */
  293. @Test
  294. public void testMsSegment() {
  295. verifyOneSegment(this.msTimeline);
  296. }
  297. /**
  298. * Tests one segment of the ms timeline. Internal indices
  299. * inside one segment as well as adjacent segments are verified.
  300. */
  301. @Test
  302. public void testMs2Segment() {
  303. verifyOneSegment(this.ms2Timeline);
  304. }
  305. /**
  306. * Tests one segment of the Monday through Friday timeline. Internal indices
  307. * inside one segment as well as adjacent segments are verified.
  308. */
  309. @Test
  310. public void testMondayThroughFridaySegment() {
  311. verifyOneSegment(this.mondayFridayTimeline);
  312. }
  313. /**
  314. * Tests one segment of the Fifteen timeline. Internal indices
  315. * inside one segment as well as adjacent segments are verified.
  316. */
  317. @Test
  318. public void testFifteenMinSegment() {
  319. verifyOneSegment(this.fifteenMinTimeline);
  320. }
  321. /**
  322. * Tests one segment of the Monday through Friday timeline. Internal indices
  323. * inside one segment as well as adjacent segments are verified.
  324. * @param timeline the timeline to use for verifications.
  325. */
  326. public void verifyOneSegment(SegmentedTimeline timeline) {
  327. for (long testCycle = TEST_CYCLE_START; testCycle < TEST_CYCLE_END;
  328. testCycle += TEST_CYCLE_INC) {
  329. // get two consecutive segments for various tests
  330. SegmentedTimeline.Segment segment1 = timeline.getSegment(
  331. this.monday.getTime().getTime() + testCycle);
  332. SegmentedTimeline.Segment segment2 = timeline.getSegment(
  333. segment1.getSegmentEnd() + 1);
  334. // verify segments are consecutive and correct
  335. assertEquals(segment1.getSegmentNumber() + 1,
  336. segment2.getSegmentNumber());
  337. assertEquals(segment1.getSegmentEnd() + 1,
  338. segment2.getSegmentStart());
  339. assertEquals(segment1.getSegmentStart()
  340. + timeline.getSegmentSize() - 1, segment1.getSegmentEnd());
  341. assertEquals(segment1.getSegmentStart() + timeline.getSegmentSize(),
  342. segment2.getSegmentStart());
  343. assertEquals(segment1.getSegmentEnd() + timeline.getSegmentSize(),
  344. segment2.getSegmentEnd());
  345. // verify various indices inside a segment are the same segment
  346. long delta;
  347. if (timeline.getSegmentSize() > 1000000) {
  348. delta = timeline.getSegmentSize() / 10000;
  349. }
  350. else if (timeline.getSegmentSize() > 100000) {
  351. delta = timeline.getSegmentSize() / 1000;
  352. }
  353. else if (timeline.getSegmentSize() > 10000) {
  354. delta = timeline.getSegmentSize() / 100;
  355. }
  356. else if (timeline.getSegmentSize() > 1000) {
  357. delta = timeline.getSegmentSize() / 10;
  358. }
  359. else if (timeline.getSegmentSize() > 100) {
  360. delta = timeline.getSegmentSize() / 5;
  361. }
  362. else {
  363. delta = 1;
  364. }
  365. long start = segment1.getSegmentStart() + delta;
  366. long end = segment1.getSegmentStart()
  367. + timeline.getSegmentSize() - 1;
  368. SegmentedTimeline.Segment lastSeg = timeline.getSegment(
  369. segment1.getSegmentStart());
  370. SegmentedTimeline.Segment seg;
  371. for (long i = start; i < end; i += delta) {
  372. seg = timeline.getSegment(i);
  373. assertEquals(lastSeg.getSegmentNumber(),
  374. seg.getSegmentNumber());
  375. assertEquals(lastSeg.getSegmentStart(), seg.getSegmentStart());
  376. assertEquals(lastSeg.getSegmentEnd(), seg.getSegmentEnd());
  377. assertTrue(lastSeg.getMillisecond() < seg.getMillisecond());
  378. lastSeg = seg;
  379. }
  380. // try next segment
  381. seg = timeline.getSegment(end + 1);
  382. assertEquals(segment2.getSegmentNumber(), seg.getSegmentNumber());
  383. assertEquals(segment2.getSegmentStart(), seg.getSegmentStart());
  384. assertEquals(segment2.getSegmentEnd(), seg.getSegmentEnd());
  385. }
  386. }
  387. //////////////////////////////////////////////////////////////////////////
  388. // test inc methods
  389. //////////////////////////////////////////////////////////////////////////
  390. /**
  391. * Tests the inc methods on the msTimeline.
  392. */
  393. @Test
  394. public void testMsInc() {
  395. verifyInc(this.msTimeline);
  396. }
  397. /**
  398. * Tests the inc methods on the msTimeline.
  399. */
  400. @Test
  401. public void testMs2Inc() {
  402. verifyInc(this.ms2Timeline);
  403. }
  404. /**
  405. * Tests the inc methods on the Monday through Friday timeline.
  406. */
  407. @Test
  408. public void testMondayThroughFridayInc() {
  409. verifyInc(this.mondayFridayTimeline);
  410. }
  411. /**
  412. * Tests the inc methods on the Fifteen minute timeline.
  413. */
  414. @Test
  415. public void testFifteenMinInc() {
  416. verifyInc(this.fifteenMinTimeline);
  417. }
  418. /**
  419. * Tests the inc methods.
  420. * @param timeline the timeline to use for verifications.
  421. */
  422. public void verifyInc(SegmentedTimeline timeline) {
  423. for (long testCycle = TEST_CYCLE_START; testCycle < TEST_CYCLE_END;
  424. testCycle += TEST_CYCLE_INC) {
  425. long m = timeline.getSegmentSize();
  426. SegmentedTimeline.Segment segment = timeline.getSegment(testCycle);
  427. SegmentedTimeline.Segment seg1 = segment.copy();
  428. for (int i = 0; i < 1000; i++) {
  429. // test inc() method
  430. SegmentedTimeline.Segment seg2 = seg1.copy();
  431. seg2.inc();
  432. if ((seg1.getSegmentEnd() + 1) != seg2.getSegmentStart()) {
  433. // logically consecutive segments non-physically consecutive
  434. // (with non-contained time in between)
  435. assertTrue(!timeline.containsDomainRange(
  436. seg1.getSegmentEnd() + 1,
  437. seg2.getSegmentStart() - 1));
  438. assertEquals(0, (seg2.getSegmentStart()
  439. - seg1.getSegmentStart()) % m);
  440. assertEquals(0, (seg2.getSegmentEnd()
  441. - seg1.getSegmentEnd()) % m);
  442. assertEquals(0, (seg2.getMillisecond()
  443. - seg1.getMillisecond()) % m);
  444. }
  445. else {
  446. // physically consecutive
  447. assertEquals(seg1.getSegmentStart() + m,
  448. seg2.getSegmentStart());
  449. assertEquals(seg1.getSegmentEnd() + m,
  450. seg2.getSegmentEnd());
  451. assertEquals(seg1.getMillisecond() + m,
  452. seg2.getMillisecond());
  453. }
  454. // test inc(n) method
  455. SegmentedTimeline.Segment seg3 = seg1.copy();
  456. SegmentedTimeline.Segment seg4 = seg1.copy();
  457. for (int j = 0; j < i; j++) {
  458. seg3.inc();
  459. }
  460. seg4.inc(i);
  461. assertEquals(seg3.getSegmentStart(), seg4.getSegmentStart());
  462. assertEquals(seg3.getSegmentEnd(), seg4.getSegmentEnd());
  463. assertEquals(seg3.getMillisecond(), seg4.getMillisecond());
  464. // go to another segment to continue test
  465. seg1.inc();
  466. }
  467. }
  468. }
  469. //////////////////////////////////////////////////////////////////////////
  470. // main include and excluded segments
  471. //////////////////////////////////////////////////////////////////////////
  472. /**
  473. * Tests that the msTimeline's included and excluded
  474. * segments are being calculated correctly.
  475. */
  476. @Test
  477. public void testMsIncludedAndExcludedSegments() {
  478. verifyIncludedAndExcludedSegments(this.msTimeline, 0);
  479. }
  480. /**
  481. * Tests that the ms2Timeline's included and excluded
  482. * segments are being calculated correctly.
  483. */
  484. @Test
  485. public void testMs2IncludedAndExcludedSegments() {
  486. verifyIncludedAndExcludedSegments(this.ms2Timeline, 1);
  487. }
  488. /**
  489. * Tests that the Monday through Friday timeline's included and excluded
  490. * segments are being calculated correctly. The test is performed starting
  491. * on the first monday after 1/1/2000 and for five years.
  492. */
  493. @Test
  494. public void testMondayThroughFridayIncludedAndExcludedSegments() {
  495. verifyIncludedAndExcludedSegments(this.mondayFridayTimeline,
  496. this.monday.getTime().getTime());
  497. }
  498. /**
  499. * Tests that the Fifteen-Min timeline's included and excluded
  500. * segments are being calculated correctly. The test is performed starting
  501. * on the first monday after 1/1/2000 and for five years.
  502. */
  503. @Test
  504. public void testFifteenMinIncludedAndExcludedSegments() {
  505. verifyIncludedAndExcludedSegments(this.fifteenMinTimeline,
  506. this.monday9am.getTime().getTime());
  507. }
  508. /**
  509. * Tests that a timeline's included and excluded segments are being
  510. * calculated correctly.
  511. *
  512. * @param timeline the timeline to verify
  513. * @param n the first segment number to start verifying
  514. */
  515. public void verifyIncludedAndExcludedSegments(SegmentedTimeline timeline,
  516. long n) {
  517. // clear any exceptions in this timeline
  518. timeline.setExceptionSegments(new java.util.ArrayList());
  519. // test some included and excluded segments
  520. SegmentedTimeline.Segment segment = timeline.getSegment(n);
  521. for (int i = 0; i < 1000; i++) {
  522. int d = (i % timeline.getGroupSegmentCount());
  523. if (d < timeline.getSegmentsIncluded()) {
  524. // should be an included segment
  525. assertTrue(segment.inIncludeSegments());
  526. assertTrue(!segment.inExcludeSegments());
  527. assertTrue(!segment.inExceptionSegments());
  528. }
  529. else {
  530. // should be an excluded segment
  531. assertTrue(!segment.inIncludeSegments());
  532. assertTrue(segment.inExcludeSegments());
  533. assertTrue(!segment.inExceptionSegments());
  534. }
  535. segment.inc();
  536. }
  537. }
  538. //////////////////////////////////////////////////////////////////////////
  539. // test exception segments
  540. //////////////////////////////////////////////////////////////////////////
  541. /**
  542. * Tests methods related to exceptions methods in the msTimeline.
  543. *
  544. * @throws ParseException if there is a parsing error.
  545. */
  546. @Test
  547. public void testMsExceptionSegments() throws ParseException {
  548. verifyExceptionSegments(this.msTimeline, MS_EXCEPTIONS, NUMBER_FORMAT);
  549. }
  550. /**
  551. * Tests methods related to exceptions methods in the ms2BaseTimeline.
  552. *
  553. * @throws ParseException if there is a parsing error.
  554. */
  555. @Test
  556. public void testMs2BaseTimelineExceptionSegments() throws ParseException {
  557. verifyExceptionSegments(this.ms2BaseTimeline,
  558. MS2_BASE_TIMELINE_EXCEPTIONS, NUMBER_FORMAT);
  559. }
  560. /**
  561. * Tests methods related to exceptions methods in the mondayFridayTimeline.
  562. *
  563. * @throws ParseException if there is a parsing error.
  564. */
  565. @Test
  566. public void testMondayThoughFridayExceptionSegments()
  567. throws ParseException {
  568. verifyExceptionSegments(this.mondayFridayTimeline,
  569. US_HOLIDAYS, DATE_FORMAT);
  570. }
  571. /**
  572. * Tests methods related to exceptions methods in the fifteenMinTimeline.
  573. *
  574. * @throws ParseException if there is a parsing error.
  575. */
  576. @Test
  577. public void testFifteenMinExceptionSegments() throws ParseException {
  578. verifyExceptionSegments(this.fifteenMinTimeline,
  579. FIFTEEN_MIN_EXCEPTIONS, DATE_TIME_FORMAT);
  580. }
  581. /**
  582. * Tests methods related to adding exceptions.
  583. *
  584. * @param timeline the timeline to verify
  585. * @param exceptionString array of Strings that represent the exceptions
  586. * @param fmt Format object that can parse the exceptionString strings
  587. *
  588. * @throws ParseException if there is a parsing error.
  589. */
  590. public void verifyExceptionSegments(SegmentedTimeline timeline,
  591. String[] exceptionString,
  592. Format fmt)
  593. throws ParseException {
  594. // fill in the exceptions
  595. long[] exception = verifyFillInExceptions(timeline, exceptionString,
  596. fmt);
  597. int m = exception.length;
  598. // verify list of exceptions
  599. assertEquals(exception.length, timeline.getExceptionSegments().size());
  600. SegmentedTimeline.Segment lastSegment = timeline.getSegment(
  601. exception[m - 1]);
  602. for (int i = 0; i < m; i++) {
  603. SegmentedTimeline.Segment segment = timeline.getSegment(
  604. exception[i]);
  605. assertTrue(segment.inExceptionSegments());
  606. // include current exception and last one
  607. assertEquals(m - i, timeline.getExceptionSegmentCount(
  608. segment.getSegmentStart(), lastSegment.getSegmentEnd()));
  609. // exclude current exception and last one
  610. assertEquals(Math.max(0, m - i - 2),
  611. timeline.getExceptionSegmentCount(exception[i] + 1,
  612. exception[m - 1] - 1));
  613. }
  614. }
  615. //////////////////////////////////////////////////////////////////////////
  616. // test timeline translations
  617. //////////////////////////////////////////////////////////////////////////
  618. /**
  619. * Tests translations for 1-ms timeline
  620. *
  621. * @throws ParseException if there is a parsing error.
  622. */
  623. @Test
  624. public void testMsTranslations() throws ParseException {
  625. verifyFillInExceptions(this.msTimeline, MS_EXCEPTIONS, NUMBER_FORMAT);
  626. verifyTranslations(this.msTimeline, 0);
  627. }
  628. /**
  629. * Tests translations for the base timeline used for the ms2Timeline
  630. *
  631. * @throws ParseException if there is a parsing error.
  632. */
  633. @Test
  634. public void testMs2BaseTimelineTranslations() throws ParseException {
  635. verifyFillInExceptions(this.ms2BaseTimeline,
  636. MS2_BASE_TIMELINE_EXCEPTIONS, NUMBER_FORMAT);
  637. verifyTranslations(this.ms2BaseTimeline, 0);
  638. }
  639. /**
  640. * Tests translations for the Monday through Friday timeline
  641. *
  642. * @throws ParseException if there is a parsing error.
  643. */
  644. @Test
  645. public void testMs2Translations() throws ParseException {
  646. fillInBaseTimelineExceptions(this.ms2Timeline,
  647. MS2_BASE_TIMELINE_EXCEPTIONS, NUMBER_FORMAT);
  648. fillInBaseTimelineExclusionsAsExceptions(this.ms2Timeline, 0, 5000);
  649. verifyTranslations(this.ms2Timeline, 1);
  650. }
  651. /**
  652. * Tests translations for the Monday through Friday timeline
  653. *
  654. * @throws ParseException if there is a parsing error.
  655. */
  656. @Ignore
  657. public void testMondayThroughFridayTranslations() throws ParseException {
  658. verifyFillInExceptions(this.mondayFridayTimeline, US_HOLIDAYS,
  659. DATE_FORMAT);
  660. verifyTranslations(this.mondayFridayTimeline,
  661. this.monday.getTime().getTime());
  662. }
  663. /**
  664. * Tests translations for the Fifteen Min timeline
  665. *
  666. * @throws ParseException if there is a parsing error.
  667. */
  668. @Test
  669. public void testFifteenMinTranslations() throws ParseException {
  670. verifyFillInExceptions(this.fifteenMinTimeline,
  671. FIFTEEN_MIN_EXCEPTIONS, DATE_TIME_FORMAT);
  672. fillInBaseTimelineExceptions(this.fifteenMinTimeline,
  673. US_HOLIDAYS, DATE_FORMAT);
  674. fillInBaseTimelineExclusionsAsExceptions(this.fifteenMinTimeline,
  675. this.monday9am.getTime().getTime(),
  676. this.monday9am.getTime().getTime() + FIVE_YEARS);
  677. verifyTranslations(this.fifteenMinTimeline,
  678. this.monday9am.getTime().getTime());
  679. }
  680. /**
  681. * Tests translations between timelines.
  682. *
  683. * @param timeline the timeline to use for verifications.
  684. * @param startTest ??.
  685. */
  686. public void verifyTranslations(SegmentedTimeline timeline, long startTest) {
  687. for (long testCycle = TEST_CYCLE_START; testCycle < TEST_CYCLE_END;
  688. testCycle += TEST_CYCLE_INC) {
  689. long millisecond = startTest + testCycle
  690. * timeline.getSegmentSize();
  691. SegmentedTimeline.Segment segment = timeline.getSegment(
  692. millisecond);
  693. for (int i = 0; i < 1000; i++) {
  694. long translatedValue = timeline.toTimelineValue(
  695. segment.getMillisecond());
  696. long newValue = timeline.toMillisecond(translatedValue);
  697. if (segment.inExcludeSegments()
  698. || segment.inExceptionSegments()) {
  699. // the reverse transformed value will be in the start of the
  700. // next non-excluded and non-exception segment
  701. SegmentedTimeline.Segment tempSegment = segment.copy();
  702. tempSegment.moveIndexToStart();
  703. do {
  704. tempSegment.inc();
  705. }
  706. while (!tempSegment.inIncludeSegments());
  707. assertEquals(tempSegment.getMillisecond(), newValue);
  708. }
  709. else {
  710. assertEquals(segment.getMillisecond(), newValue);
  711. }
  712. segment.inc();
  713. }
  714. }
  715. }
  716. //////////////////////////////////////////////////////////////////////////
  717. // test serialization
  718. //////////////////////////////////////////////////////////////////////////
  719. /**
  720. * Serialize an instance, restore it, and check for equality.
  721. */
  722. @Test
  723. public void testSerialization() {
  724. verifySerialization(this.msTimeline);
  725. verifySerialization(this.ms2Timeline);
  726. verifySerialization(this.ms2BaseTimeline);
  727. verifySerialization(SegmentedTimeline.newMondayThroughFridayTimeline());
  728. verifySerialization(SegmentedTimeline.newFifteenMinuteTimeline());
  729. }
  730. /**
  731. * Tests serialization of an instance.
  732. * @param a1 The timeline to verify the serialization
  733. */
  734. private void verifySerialization(SegmentedTimeline a1) {
  735. SegmentedTimeline a2 = (SegmentedTimeline) TestUtilities.serialised(a1);
  736. assertEquals(a1, a2);
  737. }
  738. /**
  739. * Adds an array of exceptions to the timeline. The timeline exception list
  740. * is first cleared.
  741. * @param timeline The timeline where the exceptions will be stored
  742. * @param exceptionString The exceptions to load
  743. * @param fmt The date formatter to use to parse each exceptions[i] value
  744. * @throws ParseException If there is any exception parsing each
  745. * exceptions[i] value.
  746. * @return An array of Dates[] containing each exception date.
  747. */
  748. private long[] verifyFillInExceptions(SegmentedTimeline timeline,
  749. String[] exceptionString,
  750. Format fmt) throws ParseException {
  751. // make sure there are no exceptions
  752. timeline.setExceptionSegments(new java.util.ArrayList());
  753. assertEquals(0, timeline.getExceptionSegments().size());
  754. // add our exceptions and store locally in ArrayList of Longs
  755. ArrayList exceptionList = new ArrayList();
  756. for (int i = 0; i < exceptionString.length; i++) {
  757. long e;
  758. if (fmt instanceof NumberFormat) {
  759. e = ((NumberFormat) fmt).parse(exceptionString[i]).longValue();
  760. }
  761. else {
  762. e = timeline.getTime(((SimpleDateFormat) fmt)
  763. .parse(exceptionString[i]));
  764. }
  765. // only add an exception if it is currently an included segment
  766. SegmentedTimeline.Segment segment = timeline.getSegment(e);
  767. if (segment.inIncludeSegments()) {
  768. timeline.addException(e);
  769. exceptionList.add(new Long(e));
  770. assertEquals(exceptionList.size(),
  771. timeline.getExceptionSegments().size());
  772. assertTrue(segment.inExceptionSegments());
  773. }
  774. }
  775. // make array of exceptions
  776. long[] exception = new long[exceptionList.size()];
  777. int i = 0;
  778. for (Iterator iter = exceptionList.iterator(); iter.hasNext();) {
  779. Long l = (Long) iter.next();
  780. exception[i++] = l.longValue();
  781. }
  782. return (exception);
  783. }
  784. /**
  785. * Adds an array of exceptions relative to the base timeline.
  786. *
  787. * @param timeline The timeline where the exceptions will be stored
  788. * @param exceptionString The exceptions to load
  789. * @param fmt The date formatter to use to parse each exceptions[i] value
  790. * @throws ParseException If there is any exception parsing each
  791. * exceptions[i] value.
  792. */
  793. private void fillInBaseTimelineExceptions(SegmentedTimeline timeline,
  794. String[] exceptionString,
  795. Format fmt) throws ParseException {
  796. SegmentedTimeline baseTimeline = timeline.getBaseTimeline();
  797. for (int i = 0; i < exceptionString.length; i++) {
  798. long e;
  799. if (fmt instanceof NumberFormat) {
  800. e = ((NumberFormat) fmt).parse(exceptionString[i]).longValue();
  801. }
  802. else {
  803. e = timeline.getTime(((SimpleDateFormat) fmt)
  804. .parse(exceptionString[i]));
  805. }
  806. timeline.addBaseTimelineException(e);
  807. // verify all timeline segments included in the
  808. // baseTimeline.segment are now exceptions
  809. SegmentedTimeline.Segment segment1 = baseTimeline.getSegment(e);
  810. for (SegmentedTimeline.Segment segment2
  811. = timeline.getSegment(segment1.getSegmentStart());
  812. segment2.getSegmentStart() <= segment1.getSegmentEnd();
  813. segment2.inc()) {
  814. if (!segment2.inExcludeSegments()) {
  815. assertTrue(segment2.inExceptionSegments());
  816. }
  817. }
  818. }
  819. }
  820. /**
  821. * Adds new exceptions to a timeline. The exceptions are the excluded
  822. * segments from its base timeline.
  823. *
  824. * @param timeline the timeline.
  825. * @param from the start.
  826. * @param to the end.
  827. */
  828. private void fillInBaseTimelineExclusionsAsExceptions(
  829. SegmentedTimeline timeline, long from, long to) {
  830. // add the base timeline exclusions as timeline's esceptions
  831. timeline.addBaseTimelineExclusions(from, to);
  832. // validate base timeline exclusions added as timeline's esceptions
  833. for (SegmentedTimeline.Segment segment1 = timeline.getBaseTimeline()
  834. .getSegment(from);
  835. segment1.getSegmentStart() <= to;
  836. segment1.inc()) {
  837. if (segment1.inExcludeSegments()) {
  838. // verify all timeline segments included in the
  839. // baseTimeline.segment are now exceptions
  840. for (SegmentedTimeline.Segment segment2 = timeline.getSegment(
  841. segment1.getSegmentStart());
  842. segment2.getSegmentStart() <= segment1.getSegmentEnd();
  843. segment2.inc()) {
  844. if (!segment2.inExcludeSegments()) {
  845. assertTrue(segment2.inExceptionSegments());
  846. }
  847. }
  848. }
  849. }
  850. }
  851. /**
  852. * Confirm that cloning works.
  853. */
  854. @Test
  855. public void testCloning() throws CloneNotSupportedException {
  856. SegmentedTimeline l1 = new SegmentedTimeline(1000, 5, 2);
  857. SegmentedTimeline l2 = (SegmentedTimeline) l1.clone();
  858. assertTrue(l1 != l2);
  859. assertTrue(l1.getClass() == l2.getClass());
  860. assertTrue(l1.equals(l2));
  861. }
  862. /**
  863. * Confirm that the equals method can distinguish all the required fields.
  864. */
  865. @Test
  866. public void testEquals() {
  867. SegmentedTimeline l1 = new SegmentedTimeline(1000, 5, 2);
  868. SegmentedTimeline l2 = new SegmentedTimeline(1000, 5, 2);
  869. assertTrue(l1.equals(l2));
  870. l1 = new SegmentedTimeline(1000, 5, 2);
  871. l2 = new SegmentedTimeline(1001, 5, 2);
  872. assertFalse(l1.equals(l2));
  873. l1 = new SegmentedTimeline(1000, 5, 2);
  874. l2 = new SegmentedTimeline(1000, 4, 2);
  875. assertFalse(l1.equals(l2));
  876. l1 = new SegmentedTimeline(1000, 5, 2);
  877. l2 = new SegmentedTimeline(1000, 5, 1);
  878. assertFalse(l1.equals(l2));
  879. l1 = new SegmentedTimeline(1000, 5, 2);
  880. l2 = new SegmentedTimeline(1000, 5, 2);
  881. // start time...
  882. l1.setStartTime(1234L);
  883. assertFalse(l1.equals(l2));
  884. l2.setStartTime(1234L);
  885. assertTrue(l1.equals(l2));
  886. }
  887. /**
  888. * Two objects that are equal are required to return the same hashCode.
  889. */
  890. @Test
  891. public void testHashCode() {
  892. SegmentedTimeline l1 = new SegmentedTimeline(1000, 5, 2);
  893. SegmentedTimeline l2 = new SegmentedTimeline(1000, 5, 2);
  894. assertTrue(l1.equals(l2));
  895. int h1 = l1.hashCode();
  896. int h2 = l2.hashCode();
  897. assertEquals(h1, h2);
  898. }
  899. /**
  900. * Serialize an instance, restore it, and check for equality.
  901. */
  902. @Test
  903. public void testSerialization2() {
  904. SegmentedTimeline l1 = new SegmentedTimeline(1000, 5, 2);
  905. SegmentedTimeline l2 = (SegmentedTimeline) TestUtilities.serialised(l1);
  906. assertEquals(l1, l2);
  907. }
  908. //////////////////////////////////////////////////////////////////////////
  909. // utility methods
  910. //////////////////////////////////////////////////////////////////////////
  911. /**
  912. * Tests a basic segmented timeline.
  913. */
  914. @Test
  915. public void testBasicSegmentedTimeline() {
  916. SegmentedTimeline stl = new SegmentedTimeline(10, 2, 3);
  917. stl.setStartTime(946684800000L); // 1-Jan-2000
  918. assertFalse(stl.containsDomainValue(946684799999L));
  919. assertTrue(stl.containsDomainValue(946684800000L));
  920. assertTrue(stl.containsDomainValue(946684800019L));
  921. assertFalse(stl.containsDomainValue(946684800020L));
  922. assertFalse(stl.containsDomainValue(946684800049L));
  923. assertTrue(stl.containsDomainValue(946684800050L));
  924. assertTrue(stl.containsDomainValue(946684800069L));
  925. assertFalse(stl.containsDomainValue(946684800070L));
  926. assertFalse(stl.containsDomainValue(946684800099L));
  927. assertTrue(stl.containsDomainValue(946684800100L));
  928. assertEquals(0, stl.toTimelineValue(946684800000L));
  929. assertEquals(19, stl.toTimelineValue(946684800019L));
  930. assertEquals(20, stl.toTimelineValue(946684800020L));
  931. assertEquals(20, stl.toTimelineValue(946684800049L));
  932. assertEquals(20, stl.toTimelineValue(946684800050L));
  933. assertEquals(39, stl.toTimelineValue(946684800069L));
  934. assertEquals(40, stl.toTimelineValue(946684800070L));
  935. assertEquals(40, stl.toTimelineValue(946684800099L));
  936. assertEquals(40, stl.toTimelineValue(946684800100L));
  937. assertEquals(946684800000L, stl.toMillisecond(0));
  938. assertEquals(946684800019L, stl.toMillisecond(19));
  939. assertEquals(946684800050L, stl.toMillisecond(20));
  940. assertEquals(946684800069L, stl.toMillisecond(39));
  941. assertEquals(946684800100L, stl.toMillisecond(40));
  942. }
  943. /**
  944. * Tests a basic time line with one exception.
  945. */
  946. @Test
  947. public void testSegmentedTimelineWithException1() {
  948. SegmentedTimeline stl = new SegmentedTimeline(10, 2, 3);
  949. stl.setStartTime(946684800000L); // 1-Jan-2000
  950. stl.addException(946684800050L);
  951. assertFalse(stl.containsDomainValue(946684799999L));
  952. assertTrue(stl.containsDomainValue(946684800000L));
  953. assertTrue(stl.containsDomainValue(946684800019L));
  954. assertFalse(stl.containsDomainValue(946684800020L));
  955. assertFalse(stl.containsDomainValue(946684800049L));
  956. assertFalse(stl.containsDomainValue(946684800050L));
  957. assertFalse(stl.containsDomainValue(946684800059L));
  958. assertTrue(stl.containsDomainValue(946684800060L));
  959. assertTrue(stl.containsDomainValue(946684800069L));
  960. assertFalse(stl.containsDomainValue(946684800070L));
  961. assertFalse(stl.containsDomainValue(946684800099L));
  962. assertTrue(stl.containsDomainValue(946684800100L));
  963. //long v = stl.toTimelineValue(946684800020L);
  964. assertEquals(0, stl.toTimelineValue(946684800000L));
  965. assertEquals(19, stl.toTimelineValue(946684800019L));
  966. assertEquals(20, stl.toTimelineValue(946684800020L));
  967. assertEquals(20, stl.toTimelineValue(946684800049L));
  968. assertEquals(20, stl.toTimelineValue(946684800050L));
  969. assertEquals(29, stl.toTimelineValue(946684800069L));
  970. assertEquals(30, stl.toTimelineValue(946684800070L));
  971. assertEquals(30, stl.toTimelineValue(946684800099L));
  972. assertEquals(30, stl.toTimelineValue(946684800100L));
  973. assertEquals(946684800000L, stl.toMillisecond(0));
  974. assertEquals(946684800019L, stl.toMillisecond(19));
  975. assertEquals(946684800060L, stl.toMillisecond(20));
  976. assertEquals(946684800069L, stl.toMillisecond(29));
  977. assertEquals(946684800100L, stl.toMillisecond(30));
  978. }
  979. }