001: /*
002: *******************************************************************************
003: * Copyright (C) 1996-2005, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: */
007: package com.ibm.icu.dev.test.calendar;
008:
009: import com.ibm.icu.dev.test.*;
010: import com.ibm.icu.util.Calendar;
011: import com.ibm.icu.util.GregorianCalendar;
012: import com.ibm.icu.util.SimpleTimeZone;
013: import java.util.Date;
014: import java.util.Locale;
015:
016: /**
017: * A pseudo <code>Calendar</code> that is useful for testing
018: * new calendars. A <code>TestCase</code> object is used to hold the
019: * field and millisecond values that the calendar should have at one
020: * particular instant in time. The applyFields and applyTime
021: * methods are used to apply these settings to the calendar object being
022: * tested, and the equals and fieldsEqual methods are used to ensure
023: * that the calendar has ended up in the right state.
024: */
025: public class TestCase {
026:
027: //------------------------------------------------------------------
028: // Pseudo-Calendar fields and methods
029: //------------------------------------------------------------------
030:
031: protected int[] fields = new int[32];
032: protected boolean[] isSet = new boolean[32];
033: protected long time;
034:
035: protected void set(int field, int value) {
036: fields[field] = value;
037: isSet[field] = true;
038: }
039:
040: protected int get(int field) {
041: return fields[field];
042: }
043:
044: protected boolean isSet(int field) {
045: return isSet[field];
046: }
047:
048: protected void setTime(Date d) {
049: time = d.getTime();
050: }
051:
052: public Date getTime() {
053: return new Date(time);
054: }
055:
056: /**
057: * Return a String representation of this test case's time.
058: */
059: public String toString() {
060: return dowToString(get(Calendar.DAY_OF_WEEK)) + " "
061: + get(Calendar.YEAR) + "/" + (get(Calendar.MONTH) + 1)
062: + "/" + get(Calendar.DATE);
063: }
064:
065: private static final String[] DOW_NAMES = { "Sun", "Mon", "Tue",
066: "Wed", "Thu", "Fri", "Sat" };
067:
068: public static String dowToString(int dow) {
069: --dow;
070: return (dow < 0 || dow > 6) ? ("<DOW " + dow + ">")
071: : DOW_NAMES[dow];
072: }
073:
074: /**
075: * Initialize a TestCase object using a julian day number and
076: * the corresponding fields for the calendar being tested.
077: *
078: * @param era The ERA field of tested calendar on the given julian day
079: * @param year The YEAR field of tested calendar on the given julian day
080: * @param month The MONTH (1-based) field of tested calendar on the given julian day
081: * @param day The DAY_OF_MONTH field of tested calendar on the given julian day
082: * @param dayOfWeek The DAY_OF_WEEK field of tested calendar on the given julian day
083: * @param hour The HOUR field of tested calendar on the given julian day
084: * @param min The MINUTE field of tested calendar on the given julian day
085: * @param sec The SECOND field of tested calendar on the given julian day
086: */
087: public TestCase(double julian, int era, int year, int month,
088: int day, int dayOfWeek, int hour, int min, int sec) {
089: setTime(new Date(JULIAN_EPOCH + (long) (ONE_DAY * julian)));
090:
091: set(Calendar.ERA, era);
092: set(Calendar.YEAR, year);
093: set(Calendar.MONTH, month - 1);
094: set(Calendar.DATE, day);
095: set(Calendar.DAY_OF_WEEK, dayOfWeek);
096: set(Calendar.HOUR, hour);
097: set(Calendar.MINUTE, min);
098: set(Calendar.SECOND, sec);
099: }
100:
101: /**
102: * Initialize a TestCase object using a Gregorian year/month/day and
103: * the corresponding fields for the calendar being tested.
104: *
105: * @param gregYear The Gregorian year of the date to be tested
106: * @param gregMonth The Gregorian month of the date to be tested
107: * @param gregDay The Gregorian day of the month of the date to be tested
108: *
109: * @param era The ERA field of tested calendar on the given gregorian date
110: * @param year The YEAR field of tested calendar on the given gregorian date
111: * @param month The MONTH (0-based) field of tested calendar on the given gregorian date
112: * @param day The DAY_OF_MONTH field of tested calendar on the given gregorian date
113: * @param dayOfWeek The DAY_OF_WEEK field of tested calendar on the given gregorian date
114: * @param hour The HOUR field of tested calendar on the given gregorian date
115: * @param min The MINUTE field of tested calendar on the given gregorian date
116: * @param sec The SECOND field of tested calendar on the given gregorian date
117: */
118: public TestCase(int gregYear, int gregMonth, int gregDay, int era,
119: int year, int month, int day, int dayOfWeek, int hour,
120: int min, int sec) {
121: GregorianCalendar greg = new GregorianCalendar(UTC, Locale
122: .getDefault());
123: greg.clear();
124: greg.set(gregYear, gregMonth - 1, gregDay);
125: setTime(greg.getTime());
126:
127: set(Calendar.ERA, era);
128: set(Calendar.YEAR, year);
129: set(Calendar.MONTH, month - 1);
130: set(Calendar.DATE, day);
131: set(Calendar.DAY_OF_WEEK, dayOfWeek);
132: set(Calendar.HOUR, hour);
133: set(Calendar.MINUTE, min);
134: set(Calendar.SECOND, sec);
135: }
136:
137: /**
138: * For subclasses.
139: */
140: protected TestCase() {
141: }
142:
143: /**
144: * Apply this test case's field values to another calendar
145: * by calling its set method for each field. This is useful in combination
146: * with the equal method.
147: *
148: * @see com.ibm.icu.util.Calendar#equals
149: */
150: public void applyFields(Calendar c) {
151: for (int i = 0; i < c.getFieldCount(); i++) {
152: if (isSet(i)) {
153: c.set(i, get(i));
154: }
155: }
156: }
157:
158: /**
159: * Apply this test case's time in milliseconds to another calendar
160: * by calling its setTime method. This is useful in combination
161: * with fieldsEqual
162: *
163: * @see #fieldsEqual
164: */
165: public void applyTime(Calendar c) {
166: c.setTime(new Date(time));
167: }
168:
169: /**
170: * Determine whether the fields of this calendar
171: * are the same as that of the other calendar. This method is useful
172: * for determining whether the other calendar's computeFields method
173: * works properly. For example:
174: * <pre>
175: * Calendar testCalendar = ...
176: * TestCase case = ...
177: * case.applyTime(testCalendar);
178: * if (!case.fieldsEqual(testCalendar)) {
179: * // Error!
180: * }
181: * </pre>
182: *
183: * @see #applyTime
184: */
185: public boolean fieldsEqual(Calendar c, TestLog log) {
186: for (int i = 0; i < c.getFieldCount(); i++) {
187: if (isSet(i) && get(i) != c.get(i)) {
188: StringBuffer buf = new StringBuffer();
189: buf.append("Fail: " + CalendarTest.fieldName(i) + " = "
190: + c.get(i) + ", expected " + get(i));
191: for (int j = 0; j < c.getFieldCount(); ++j) {
192: if (isSet(j)) {
193: if (get(j) == c.get(j)) {
194: buf.append("\n ok: "
195: + CalendarTest.fieldName(j) + " = "
196: + c.get(j));
197: } else {
198: buf
199: .append("\n fail: "
200: + CalendarTest.fieldName(j)
201: + " = " + c.get(j)
202: + ", expected " + get(j));
203: }
204: }
205: }
206: log.errln(buf.toString());
207: return false;
208: }
209: }
210:
211: return true;
212: }
213:
214: /**
215: * Determine whether time in milliseconds of this calendar
216: * is the same as that of the other calendar. This method is useful
217: * for determining whether the other calendar's computeTime method
218: * works properly. For example:
219: * <pre>
220: * Calendar testCalendar = ...
221: * TestCase case = ...
222: * case.applyFields(testCalendar);
223: * if (!case.equals(testCalendar)) {
224: * // Error!
225: * }
226: * </pre>
227: *
228: * @see #applyFields
229: */
230: public boolean equals(Object obj) {
231: return time == ((Calendar) obj).getTime().getTime();
232: }
233:
234: protected static final int ONE_SECOND = 1000;
235: protected static final int ONE_MINUTE = 60 * ONE_SECOND;
236: protected static final int ONE_HOUR = 60 * ONE_MINUTE;
237: protected static final long ONE_DAY = 24 * ONE_HOUR;
238: protected static final long JULIAN_EPOCH = -210866760000000L; // 1/1/4713 BC 12:00
239:
240: public final static SimpleTimeZone UTC = new SimpleTimeZone(0,
241: "GMT");
242: }
|