1 /* 2 ******************************************************************************* 3 * Copyright (C) 1996-2010, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 package com.ibm.icu.dev.test.calendar; 8 9 import java.util.Date; 10 import java.util.Locale; 11 12 import com.ibm.icu.dev.test.TestLog; 13 import com.ibm.icu.util.Calendar; 14 import com.ibm.icu.util.GregorianCalendar; 15 import com.ibm.icu.util.SimpleTimeZone; 16 17 /** 18 * A pseudo <code>Calendar</code> that is useful for testing 19 * new calendars. A <code>TestCase</code> object is used to hold the 20 * field and millisecond values that the calendar should have at one 21 * particular instant in time. The applyFields and applyTime 22 * methods are used to apply these settings to the calendar object being 23 * tested, and the equals and fieldsEqual methods are used to ensure 24 * that the calendar has ended up in the right state. 25 */ 26 public class TestCase { 27 28 //------------------------------------------------------------------ 29 // Pseudo-Calendar fields and methods 30 //------------------------------------------------------------------ 31 32 protected int[] fields = new int[32]; 33 protected boolean[] isSet = new boolean[32]; 34 protected long time; 35 set(int field, int value)36 protected void set(int field, int value) { 37 fields[field] = value; 38 isSet[field] = true; 39 } 40 get(int field)41 protected int get(int field) { 42 return fields[field]; 43 } 44 isSet(int field)45 protected boolean isSet(int field) { 46 return isSet[field]; 47 } 48 setTime(Date d)49 protected void setTime(Date d) { 50 time = d.getTime(); 51 } 52 getTime()53 public Date getTime() { 54 return new Date(time); 55 } 56 57 /** 58 * Return a String representation of this test case's time. 59 */ toString()60 public String toString() { 61 return dowToString(get(Calendar.DAY_OF_WEEK)) + " " + 62 get(Calendar.YEAR) + "/" + (get(Calendar.MONTH)+1) + "/" + 63 get(Calendar.DATE); 64 } 65 66 private static final String[] DOW_NAMES = { 67 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 68 }; 69 dowToString(int dow)70 public static String dowToString(int dow) { 71 --dow; 72 return (dow < 0 || dow > 6) ? 73 ("<DOW " + dow + ">") : DOW_NAMES[dow]; 74 } 75 76 /** 77 * Initialize a TestCase object using a julian day number and 78 * the corresponding fields for the calendar being tested. 79 * 80 * @param era The ERA field of tested calendar on the given julian day 81 * @param year The YEAR field of tested calendar on the given julian day 82 * @param month The MONTH (1-based) field of tested calendar on the given julian day 83 * @param day The DAY_OF_MONTH field of tested calendar on the given julian day 84 * @param dayOfWeek The DAY_OF_WEEK field of tested calendar on the given julian day 85 * @param hour The HOUR field of tested calendar on the given julian day 86 * @param min The MINUTE field of tested calendar on the given julian day 87 * @param sec The SECOND field of tested calendar on the given julian day 88 */ TestCase(double julian, int era, int year, int month, int day, int dayOfWeek, int hour, int min, int sec)89 public TestCase(double julian, 90 int era, int year, int month, int day, 91 int dayOfWeek, 92 int hour, int min, int sec) 93 { 94 setTime(new Date(JULIAN_EPOCH + (long)(ONE_DAY * julian))); 95 96 set(Calendar.ERA, era); 97 set(Calendar.YEAR, year); 98 set(Calendar.MONTH, month - 1); 99 set(Calendar.DATE, day); 100 set(Calendar.DAY_OF_WEEK, dayOfWeek); 101 set(Calendar.HOUR, hour); 102 set(Calendar.MINUTE, min); 103 set(Calendar.SECOND, sec); 104 } 105 106 /** 107 * Initialize a TestCase object using a Gregorian year/month/day and 108 * the corresponding fields for the calendar being tested. 109 * 110 * @param gregYear The Gregorian year of the date to be tested 111 * @param gregMonth The Gregorian month of the date to be tested 112 * @param gregDay The Gregorian day of the month of the date to be tested 113 * 114 * @param era The ERA field of tested calendar on the given gregorian date 115 * @param year The YEAR field of tested calendar on the given gregorian date 116 * @param month The MONTH (0-based) field of tested calendar on the given gregorian date 117 * @param day The DAY_OF_MONTH field of tested calendar on the given gregorian date 118 * @param dayOfWeek The DAY_OF_WEEK field of tested calendar on the given gregorian date 119 * @param hour The HOUR field of tested calendar on the given gregorian date 120 * @param min The MINUTE field of tested calendar on the given gregorian date 121 * @param sec The SECOND field of tested calendar on the given gregorian date 122 */ TestCase(int gregYear, int gregMonth, int gregDay, int era, int year, int month, int day, int dayOfWeek, int hour, int min, int sec)123 public TestCase(int gregYear, int gregMonth, int gregDay, 124 int era, int year, int month, int day, 125 int dayOfWeek, 126 int hour, int min, int sec) 127 { 128 GregorianCalendar greg = new GregorianCalendar(UTC, Locale.getDefault()); 129 greg.clear(); 130 greg.set(gregYear, gregMonth-1, gregDay); 131 setTime(greg.getTime()); 132 133 set(Calendar.ERA, era); 134 set(Calendar.YEAR, year); 135 set(Calendar.MONTH, month - 1); 136 set(Calendar.DATE, day); 137 set(Calendar.DAY_OF_WEEK, dayOfWeek); 138 set(Calendar.HOUR, hour); 139 set(Calendar.MINUTE, min); 140 set(Calendar.SECOND, sec); 141 } 142 143 /** 144 * For subclasses. 145 */ TestCase()146 protected TestCase() {} 147 148 /** 149 * Apply this test case's field values to another calendar 150 * by calling its set method for each field. This is useful in combination 151 * with the equal method. 152 * 153 * @see com.ibm.icu.util.Calendar#equals 154 */ applyFields(Calendar c)155 public void applyFields(Calendar c) { 156 for (int i=0; i < c.getFieldCount(); i++) { 157 if (isSet(i)) { 158 c.set(i, get(i)); 159 } 160 } 161 } 162 163 /** 164 * Apply this test case's time in milliseconds to another calendar 165 * by calling its setTime method. This is useful in combination 166 * with fieldsEqual 167 * 168 * @see #fieldsEqual 169 */ applyTime(Calendar c)170 public void applyTime(Calendar c) { 171 c.setTime(new Date(time)); 172 } 173 174 /** 175 * Determine whether the fields of this calendar 176 * are the same as that of the other calendar. This method is useful 177 * for determining whether the other calendar's computeFields method 178 * works properly. For example: 179 * <pre> 180 * Calendar testCalendar = ... 181 * TestCase case = ... 182 * case.applyTime(testCalendar); 183 * if (!case.fieldsEqual(testCalendar)) { 184 * // Error! 185 * } 186 * </pre> 187 * 188 * @see #applyTime 189 */ fieldsEqual(Calendar c, TestLog log)190 public boolean fieldsEqual(Calendar c, TestLog log) { 191 for (int i=0; i < c.getFieldCount(); i++) { 192 if (isSet(i) && get(i) != c.get(i)) { 193 StringBuffer buf = new StringBuffer(); 194 buf.append("Fail: " + CalendarTest.fieldName(i) + " = " + c.get(i) + 195 ", expected " + get(i)); 196 for (int j=0; j<c.getFieldCount(); ++j) { 197 if (isSet(j)) { 198 if (get(j) == c.get(j)) { 199 buf.append("\n ok: " + CalendarTest.fieldName(j) + " = " + 200 c.get(j)); 201 } else { 202 buf.append("\n fail: " + CalendarTest.fieldName(j) + " = " + 203 c.get(j) + ", expected " + get(j)); 204 } 205 } 206 } 207 log.errln(buf.toString()); 208 return false; 209 } 210 } 211 212 return true; 213 } 214 215 /** 216 * Determine whether time in milliseconds of this calendar 217 * is the same as that of the other calendar. This method is useful 218 * for determining whether the other calendar's computeTime method 219 * works properly. For example: 220 * <pre> 221 * Calendar testCalendar = ... 222 * TestCase case = ... 223 * case.applyFields(testCalendar); 224 * if (!case.equals(testCalendar)) { 225 * // Error! 226 * } 227 * </pre> 228 * 229 * @see #applyFields 230 */ equals(Object obj)231 public boolean equals(Object obj) { 232 return time == ((Calendar)obj).getTime().getTime(); 233 } 234 235 protected static final int ONE_SECOND = 1000; 236 protected static final int ONE_MINUTE = 60*ONE_SECOND; 237 protected static final int ONE_HOUR = 60*ONE_MINUTE; 238 protected static final long ONE_DAY = 24*ONE_HOUR; 239 protected static final long JULIAN_EPOCH = -210866760000000L; // 1/1/4713 BC 12:00 240 241 public final static SimpleTimeZone UTC = new SimpleTimeZone(0, "GMT"); 242 } 243