001: /*
002: * Copyright (C) 2004, 2005 Joe Walnes.
003: * Copyright (C) 2006, 2007 XStream Committers.
004: * All rights reserved.
005: *
006: * The software in this package is published under the terms of the BSD
007: * style license a copy of which has been included with this distribution in
008: * the LICENSE.txt file.
009: *
010: * Created on 22. February 2004 by Joe Walnes
011: */
012: package com.thoughtworks.xstream.converters.basic;
013:
014: import com.thoughtworks.xstream.converters.ConversionException;
015: import com.thoughtworks.xstream.testutil.TimeZoneChanger;
016:
017: import junit.framework.TestCase;
018:
019: import java.text.ParseException;
020: import java.text.SimpleDateFormat;
021: import java.util.ArrayList;
022: import java.util.Calendar;
023: import java.util.Collections;
024: import java.util.Date;
025: import java.util.List;
026: import java.util.TimeZone;
027:
028: public class DateConverterTest extends TestCase {
029:
030: private DateConverter converter = new DateConverter();
031:
032: protected void setUp() throws Exception {
033: super .setUp();
034:
035: // Ensure that this test always run as if it were in the IST timezone.
036: // This prevents failures when running the tests in different zones.
037: // Note: 'IST' has no relevance - it was just a randomly chosen zone
038: // without daylight saving.
039: TimeZoneChanger.change("IST");
040: }
041:
042: protected void tearDown() throws Exception {
043: TimeZoneChanger.reset();
044: super .tearDown();
045: }
046:
047: public void testRetainsDetailDownToMillisecondLevel() {
048: // setup
049: Date in = new Date();
050:
051: // execute
052: String text = converter.toString(in);
053: Date out = (Date) converter.fromString(text);
054:
055: // verify
056: assertEquals(in, out);
057: assertEquals(in.toString(), out.toString());
058: assertEquals(in.getTime(), out.getTime());
059: }
060:
061: public void testUnmarshalsOldXStreamDatesThatLackMillisecond() {
062: Date expected = (Date) converter
063: .fromString("2004-02-22 15:16:04.0 EST");
064:
065: assertEquals(expected, converter
066: .fromString("2004-02-22 15:16:04.0 EST"));
067: assertEquals(expected, converter
068: .fromString("2004-02-22 15:16:04 EST"));
069: assertEquals(expected, converter
070: .fromString("2004-02-22 15:16:04EST"));
071:
072: TimeZone.setDefault(TimeZone.getTimeZone("EST")); // Need correct local time, no TZ info in string
073: assertEquals(expected, converter
074: .fromString("2004-02-22 15:16:04.0 PM"));
075: assertEquals(expected, converter
076: .fromString("2004-02-22 15:16:04PM"));
077: }
078:
079: public void testUnmarshalsDatesWithDifferentTimeZones() {
080: converter = new DateConverter(true); // Needed by JDK 5 running on Codehaus' Bamboo installation
081: Date expected = (Date) converter
082: .fromString("2004-02-22 15:16:04.0 EST");
083:
084: assertEquals(expected, converter
085: .fromString("2004-02-22 15:16:04.0 EST"));
086: assertEquals(expected, converter
087: .fromString("2004-02-22 15:16:04.0 GMT-05:00"));
088: assertEquals(expected, converter
089: .fromString("2004-02-22 20:16:04.0 UTC"));
090: assertEquals(expected, converter
091: .fromString("2004-02-23 01:46:04.0 IST"));
092: assertEquals(expected, converter
093: .fromString("2004-02-23 01:46:04.0 GMT+05:30"));
094: }
095:
096: public void testUnmashalsDateWithDifferentDefaultTimeZones()
097: throws ParseException {
098: Calendar cal = Calendar.getInstance();
099: cal.clear();
100: cal.set(2004, Calendar.FEBRUARY, 23, 1, 46, 4);
101: Date date = cal.getTime();
102: String strIST = converter.toString(date);
103: assertEquals("2004-02-23 01:46:04.0 IST", strIST);
104: // select arbitrary TZ
105: TimeZone.setDefault(TimeZone.getTimeZone("EST"));
106: // compare parsed date with JDK implementation
107: Date dateRetrieved = (Date) converter.fromString(strIST);
108: SimpleDateFormat f = new SimpleDateFormat(
109: "yyyy-MM-dd HH:mm:ss.S z");
110: Date simpleDate = f.parse(strIST);
111: assertEquals(simpleDate, dateRetrieved);
112: // DateConverter does not get influenced by change of current TZ ...
113: TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
114: dateRetrieved = (Date) converter.fromString(strIST);
115: assertEquals(simpleDate, dateRetrieved);
116: // ... as well as the SimpleDateFormat
117: f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S z");
118: simpleDate = f.parse(strIST);
119: assertEquals(simpleDate, dateRetrieved);
120: assertEquals(date, f.parse("2004-02-22 20:16:04.0 UTC"));
121: // assertEquals(date, simpleDate); off by +03:30 ... but why ??
122: }
123:
124: public void testIsThreadSafe() throws InterruptedException {
125: final List results = Collections
126: .synchronizedList(new ArrayList());
127: final DateConverter converter = new DateConverter();
128: final Object monitor = new Object();
129: final int numberOfCallsPerThread = 20;
130: final int numberOfThreads = 20;
131:
132: // spawn some concurrent threads, that hammer the converter
133: Runnable runnable = new Runnable() {
134: public void run() {
135: for (int i = 0; i < numberOfCallsPerThread; i++) {
136: try {
137: converter
138: .fromString("2004-02-22 15:16:04.0 EST");
139: results.add("PASS");
140: } catch (ConversionException e) {
141: results.add("FAIL");
142: } finally {
143: synchronized (monitor) {
144: monitor.notifyAll();
145: }
146: }
147: }
148: }
149: };
150: for (int i = 0; i < numberOfThreads; i++) {
151: new Thread(runnable).start();
152: }
153:
154: // wait for all results
155: while (results.size() < numberOfThreads
156: * numberOfCallsPerThread) {
157: synchronized (monitor) {
158: monitor.wait(100);
159: }
160: }
161:
162: assertTrue("Nothing suceeded", results.contains("PASS"));
163: assertFalse("At least one attempt failed", results
164: .contains("FAIL"));
165: }
166:
167: public void testDatesInNonLenientMode() {
168: String[] dateFormats = new String[] { "yyyyMMdd",
169: "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd" };
170: converter = new DateConverter("yyyy-MM-dd'T'HH:mm:ss.S'Z'",
171: dateFormats);
172: Date expected = (Date) converter
173: .fromString("2004-02-22T15:16:04.0Z");
174: assertEquals(expected, converter
175: .fromString("2004-02-22T15:16:04Z"));
176: }
177:
178: public void testDatesInLenientMode() {
179: converter = new DateConverter("yyyy-MM-dd HH:mm:ss.S z",
180: new String[0], true);
181: Date expected = (Date) converter
182: .fromString("2004-02-22 15:16:04.0 IST");
183: assertEquals(expected, converter
184: .fromString("2004-02-21 39:16:04.0 IST"));
185: }
186: }
|