1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.convert;
20
21 import java.util.Calendar;
22 import java.util.Date;
23 import java.util.GregorianCalendar;
24 import java.util.Locale;
25 import java.util.TimeZone;
26
27 import javax.faces.component.UIComponent;
28 import javax.faces.convert.ConverterException;
29
30 import org.apache.myfaces.trinidad.convert.ConverterTestCase;
31 import org.apache.myfaces.trinidadbuild.test.MockUIComponentWrapper;
32 import org.jmock.Mock;
33
34
35
36
37
38 public abstract class DateTimeConverterTestCase extends ConverterTestCase
39 {
40 public DateTimeConverterTestCase(String testName)
41 {
42 super(testName);
43 }
44
45
46
47
48 public void testCommonScenarios()
49 {
50
51
52
53
54
55
56
57 checkStateHolderSaveRestore();
58
59 checkEquals();
60
61 checkConversionOnLongPatternWithTimeZone();
62 checkDatesForPatternBasedChecks();
63 checkDateStyleValidity();
64 checkTimeStyleValidity();
65 doTestBlankValue(getDateTimeConverter());
66 }
67
68
69
70
71
72
73 protected void checkNullInputValue() throws ConverterException
74 {
75 Mock mock = mock(UIComponent.class);
76 UIComponent component = (UIComponent) mock.proxy();
77 MockUIComponentWrapper wrapper = new MockUIComponentWrapper(mock, component);
78
79 javax.faces.convert.DateTimeConverter converter = getDateTimeConverter();
80
81 doTestNull(facesContext, wrapper, converter);
82 }
83
84
85
86
87 protected void checkNullContext()
88 {
89 Mock mock = mock(UIComponent.class);
90 UIComponent component = (UIComponent) mock.proxy();
91 MockUIComponentWrapper wrapper = new MockUIComponentWrapper(mock, component);
92 javax.faces.convert.DateTimeConverter converter = getDateTimeConverter();
93
94 doTestNullContext(wrapper, converter);
95 }
96
97 protected void checkNullComponent()
98 {
99 javax.faces.convert.DateTimeConverter converter = getDateTimeConverter();
100
101 doTestNullComponent(facesContext, converter);
102 }
103
104
105
106
107 protected void checkEquals()
108 {
109
110 javax.faces.convert.DateTimeConverter converter = getDateTimeConverter();
111 javax.faces.convert.DateTimeConverter otherConverter = getDateTimeConverter();
112
113
114
115
116
117
118
119
120
121 for (int i = 0; i < _DATE_STYLES.length; i++)
122 {
123 converter.setDateStyle(_DATE_STYLES[i]);
124 otherConverter.setDateStyle(_DATE_STYLES[i]);
125
126
127
128
129
130
131
132
133 converter.setLocale(_LOCALES[i]);
134 otherConverter.setLocale(_LOCALES[i]);
135 doTestEquals(converter, otherConverter, true);
136
137 converter.setPattern(_PATTERNS[i]);
138 otherConverter.setPattern(_PATTERNS[i]);
139 doTestEquals(converter, otherConverter, true);
140
141 converter.setTimeStyle(_TIME_STYLES[i]);
142 otherConverter.setTimeStyle(_TIME_STYLES[i]);
143 doTestEquals(converter, otherConverter, true);
144
145 converter.setTimeZone(_TIME_ZONES[i]);
146 otherConverter.setTimeZone(_TIME_ZONES[i]);
147 doTestEquals(converter, otherConverter, true);
148
149 converter.setType(_TYPES[i]);
150 otherConverter.setType(_TYPES[i]);
151 doTestEquals(converter, otherConverter, true);
152
153 String secPattern = _SECONDARY_PATTERNS[i];
154 setSecondaryPattern(converter, secPattern);
155 setSecondaryPattern(otherConverter, secPattern);
156 doTestEquals(converter, otherConverter, true);
157
158
159 converter.setTransient(_TRANSIENT_VALUES[i]);
160 otherConverter.setTransient(_TRANSIENT_VALUES[i]);
161 doTestEquals(converter, otherConverter, true);
162 }
163 }
164
165
166
167
168 protected void checkStateHolderSaveRestore()
169 {
170
171 javax.faces.convert.DateTimeConverter converter = getDateTimeConverter();
172 Mock mock = mock(UIComponent.class);
173 UIComponent component = (UIComponent) mock.proxy();
174 MockUIComponentWrapper wrapper = new MockUIComponentWrapper(mock, component);
175
176 javax.faces.convert.DateTimeConverter restoreConverter = getDateTimeConverter();
177
178 for (int i = 0; i < _DATE_STYLES.length; i++)
179 {
180 converter.setDateStyle(_DATE_STYLES[i]);
181 restoreConverter.setDateStyle(_DATE_STYLES[i]);
182
183
184
185
186
187
188
189
190 converter.setLocale(_LOCALES[i]);
191 restoreConverter.setLocale(_LOCALES[i]);
192 doTestStateHolderSaveRestore(converter, restoreConverter,
193 facesContext, wrapper);
194
195 converter.setPattern(_PATTERNS[i]);
196 restoreConverter.setPattern(_PATTERNS[i]);
197 doTestStateHolderSaveRestore(converter, restoreConverter,
198 facesContext, wrapper);
199
200 converter.setTimeStyle(_TIME_STYLES[i]);
201 restoreConverter.setTimeStyle(_TIME_STYLES[i]);
202 doTestStateHolderSaveRestore(converter, restoreConverter,
203 facesContext, wrapper);
204
205 converter.setTimeZone(_TIME_ZONES[i]);
206 restoreConverter.setTimeZone(_TIME_ZONES[i]);
207 doTestStateHolderSaveRestore(converter, restoreConverter,
208 facesContext, wrapper);
209
210 converter.setType(_TYPES[i]);
211 restoreConverter.setType(_TYPES[i]);
212 doTestStateHolderSaveRestore(converter, restoreConverter,
213 facesContext, wrapper);
214
215 String secPattern = _SECONDARY_PATTERNS[i];
216 setSecondaryPattern(converter, secPattern);
217 setSecondaryPattern(restoreConverter, secPattern);
218
219 doTestStateHolderSaveRestore(converter, restoreConverter,
220 facesContext, wrapper);
221
222 converter.setTransient(_TRANSIENT_VALUES[i]);
223 restoreConverter.setTransient(_TRANSIENT_VALUES[i]);
224 doTestStateHolderSaveRestore(converter, restoreConverter,
225 facesContext, wrapper);
226 mock.verify();
227 }
228 }
229
230 protected void checkGetAsObject()
231 {
232 for (int i = 0; i < _SDATE_STYLES.length; ++i)
233 {
234 javax.faces.convert.DateTimeConverter dtConv = getDateTimeConverter();
235
236 dtConv.setDateStyle(_SDATE_STYLES[i]);
237 dtConv.setLocale(_SLOCALES[i]);
238 dtConv.setPattern(_SPATTERNS[i]);
239 setSecondaryPattern(dtConv, _SSECONDARY_PATTERNS[i]);
240 dtConv.setTimeStyle(_STIME_STYLES[i]);
241 dtConv.setTimeZone(_STIME_ZONES[i]);
242 dtConv.setType(_STYPES[i]);
243
244 Mock mock = mock(UIComponent.class);
245 UIComponent component = (UIComponent) mock.proxy();
246
247 setFacesContext(facesContext);
248 try
249 {
250 Date obj = (Date)dtConv.getAsObject(facesContext, component, _SINPUT_VALUES[i]);
251 assertEquals(true, isEqual(obj,_SEXPECTED_DATES[i]));
252 }
253 finally
254 {
255 setFacesContext(null);
256 }
257
258 mock.verify();
259 }
260 }
261
262 protected void checkConversionOnLongPatternWithTimeZone()
263 {
264 String pattern = "yyyy.MM.dd G 'at' HH:mm:ss z";
265 String inputValue = "2001.07.04 AD at 12:08:56 " + "UTC";
266
267 javax.faces.convert.DateTimeConverter dtConv = getDateTimeConverter();
268 dtConv.setTimeZone(null);
269 dtConv.setPattern(pattern);
270
271 Mock mock = mock(UIComponent.class);
272 UIComponent component = (UIComponent) mock.proxy();
273
274 facesContext.getViewRoot().setLocale(Locale.ENGLISH);
275
276 TimeZone.setDefault(getTzone("UTC"));
277
278 GregorianCalendar gcal = new GregorianCalendar(getTzone("UTC"));
279 gcal.set(2001,6,4,12,8,56);
280
281 setFacesContext(facesContext);
282 try
283 {
284 Date dt = (Date) dtConv.getAsObject(facesContext, component, inputValue);
285 Date expectedDt = gcal.getTime();
286 assertEquals(true, isEqual(dt, expectedDt));
287 }
288 finally
289 {
290 setFacesContext(null);
291 }
292 }
293
294 protected void checkDatesForPatternBasedChecks()
295 {
296
297
298
299
300
301
302
303 GregorianCalendar gcal = new GregorianCalendar();
304 gcal.set(2001,Calendar.JULY,4,12,8,56);
305
306 gcal.setTimeZone(getTzone("GMT"));
307
308 Date date = gcal.getTime();
309
310
311 Object[][] patternBasedValues
312 = {
313
314 {"yyyy.MM.dd G 'at' HH:mm:ss z",Locale.GERMAN, getTzone("GMT"),"2001.07.04 n. Chr. at 12:08:56 GMT"},
315 {"yyyy.MM.dd G 'at' HH:mm:ss z",Locale.ENGLISH, getTzone("GMT"),"2001.07.04 AD at 12:08:56 GMT"},
316
317 {"yyyy.MM.dd G 'at' HH:mm:ss z",null, getTzone("GMT"),"2001.07.04 n. Chr. at 12:08:56 GMT"},
318 };
319
320 for (int i = 0; i < patternBasedValues.length; i++)
321 {
322
323 Mock mock = mock(UIComponent.class);
324 UIComponent component = (UIComponent) mock.proxy();
325
326 javax.faces.convert.DateTimeConverter fdtConv
327 = getDateTimeConverter();
328
329 fdtConv.setPattern((String)patternBasedValues[i][0]);
330 fdtConv.setTimeZone((TimeZone)patternBasedValues[i][2]);
331
332 Locale loc = (Locale)patternBasedValues[i][1];
333 fdtConv.setLocale((Locale)patternBasedValues[i][1]);
334
335
336 if (loc == null)
337 {
338 facesContext.getViewRoot().setLocale(Locale.GERMAN);
339 }
340
341 setFacesContext(facesContext);
342 try
343 {
344 String fobtPattern = fdtConv.getAsString(facesContext, component, date);
345
346 assertEquals(patternBasedValues[i][3], fobtPattern);
347
348 Date fdt = (Date)fdtConv.getAsObject(facesContext, component, fobtPattern);
349
350
351
352
353 assertEquals(true, isEqual(date, fdt));
354 }
355 finally
356 {
357 setFacesContext(null);
358 }
359 mock.verify();
360 }
361 }
362
363 protected void checkDateStyleValidity()
364 {
365 String[] dateStyles = {"short", "medium", "default", "long", "full",};
366 doTestStyleValidity(_DATE_STYLE, dateStyles);
367 }
368
369 protected void checkTimeStyleValidity()
370 {
371 String[] timeStyles = {"short", "medium", "default", "long", "full",};
372 doTestStyleValidity(_TIME_STYLE, timeStyles);
373 }
374
375 protected void doTestStyleValidity(int styleType, String[] styles)
376 {
377 Date dt = new Date(0);
378 for (int i = 0; i < styles.length; i++)
379 {
380
381
382 javax.faces.convert.DateTimeConverter dtConv = getDateTimeConverter();
383 Mock mock = mock(UIComponent.class);
384 UIComponent component = (UIComponent) mock.proxy();
385
386 _setStyleOnConverter(dtConv, styleType, styles[i]);
387
388 dtConv.setLocale(Locale.ENGLISH);
389 setFacesContext(facesContext);
390 try
391 {
392 String out = dtConv.getAsString(facesContext, component, dt);
393 assertEquals(true, (out != null));
394 }
395 finally
396 {
397 setFacesContext(null);
398 }
399
400 mock.verify();
401
402 Mock mok = mock(UIComponent.class);
403 UIComponent cmp = (UIComponent) mok.proxy();
404
405 setFacesContext(facesContext);
406 try
407 {
408 try
409 {
410 javax.faces.convert.DateTimeConverter extDtConv = getDateTimeConverter();
411 extDtConv.setLocale(Locale.ENGLISH);
412 _setStyleOnConverter(extDtConv, styleType, styles[i].toUpperCase());
413 extDtConv.getAsString(facesContext, cmp, dt);
414 fail("Upper case not accepted for styles");
415 }
416 catch (RuntimeException ce)
417 {
418
419 }
420 }
421 finally
422 {
423 setFacesContext(null);
424 }
425
426 mok.verify();
427 }
428 }
429
430 protected abstract javax.faces.convert.DateTimeConverter getDateTimeConverter();
431
432 protected abstract void setSecondaryPattern(
433 javax.faces.convert.DateTimeConverter converter,
434 String secondaryPattern );
435
436 protected static TimeZone getTzone(String timeZoneId)
437 {
438 return TimeZone.getTimeZone(timeZoneId);
439 }
440
441
442
443
444
445
446
447 @SuppressWarnings("deprecation")
448 protected static boolean isEqual(Date convDate, Date expectedDate)
449 {
450 GregorianCalendar convGcal = new GregorianCalendar();
451 convGcal.setTime(convDate);
452
453 GregorianCalendar expGcal = new GregorianCalendar();
454 expGcal.setTime(expectedDate);
455
456
457
458 return
459 (convDate.getSeconds() == expectedDate.getSeconds()) &&
460 (convDate.getYear() == expectedDate.getYear()) &&
461 (convDate.getMonth() == expectedDate.getMonth()) &&
462 (convDate.getDate() == expectedDate.getDate()) &&
463 (convDate.getHours() == expectedDate.getHours()) &&
464 (convDate.getMinutes() == expectedDate.getMinutes()) ;
465 }
466
467
468 private static void _setStyleOnConverter(
469 javax.faces.convert.DateTimeConverter dtConv,
470 int styleType,
471 String style
472 )
473 {
474 if (_DATE_STYLE == styleType)
475 {
476 dtConv.setDateStyle(style);
477 }
478 else if (_TIME_STYLE == styleType)
479 {
480 dtConv.setTimeStyle(style);
481 dtConv.setType("time");
482 }
483 else
484 {
485 throw new IllegalArgumentException("Invalid style id");
486 }
487 }
488
489 private static Date[] _getDates(
490 Locale[] locales,
491 TimeZone[] timeZones,
492 int[] day,
493 int[] month,
494 int[] year,
495 int[] hours,
496 int[] mins,
497 int[] secs
498 )
499 {
500 Date[] dates = new Date[timeZones.length];
501 for (int i = 0; i < timeZones.length; ++i)
502 {
503 GregorianCalendar gcal = new GregorianCalendar();
504 gcal.set(year[i],month[i],day[i],hours[i],mins[i],secs[i]);
505 gcal.setTimeZone(timeZones[i]);
506 dates[i] = gcal.getTime();
507 }
508 return dates;
509 }
510
511 protected static final int _TIME_STYLE = 0;
512
513 protected static final int _DATE_STYLE = 1;
514
515
516
517 private static String[] _DATE_STYLES = {
518 "short",
519 "shortish",
520 "default",
521 "medium",
522 "full",
523 "long",
524 "shortish",
525 "long",
526 null
527 };
528
529 private static Locale[] _LOCALES = {
530 Locale.US,
531 Locale.CANADA,
532 Locale.CANADA_FRENCH,
533 Locale.TRADITIONAL_CHINESE,
534 Locale.GERMAN,
535 Locale.ENGLISH,
536 Locale.KOREAN,
537 new Locale("en","","ORACLE10G"),
538 new Locale("en","us","ORACLE10G")
539 };
540
541 private static String[] _PATTERNS = {
542 null,
543 "yyyy.MM.dd G 'at' HH:mm:ss z",
544 "EEE, MMM d, ''yy",
545 "h:mm a",
546 "hh 'o''clock' a, zzzz",
547 "K:mm a, z",
548 "yyyyy.MMMMM.dd GGG hh:mm aaa",
549 "EEE, d MMM yyyy HH:mm:ss Z",
550 "yyMMddHHmmssZ",
551 };
552
553 private String[] _TIME_STYLES = {
554 "short",
555 "default",
556 "default",
557 "medium",
558 "fullx",
559 "long",
560 null,
561 "long",
562 null
563 };
564
565 private static TimeZone[] _TIME_ZONES = {
566 getTzone("GMT"),
567 getTzone("GMT-8:00"),
568 getTzone("GMT+8:00"),
569 getTzone("GMT-23:59"),
570 getTzone("GMT-23:00"),
571 getTzone("GMT-9:00"),
572 getTzone("GMT-5:30"),
573 getTzone("GMT+23:59"),
574 getTzone("GMT-01:05"),
575 };
576
577 private static String[] _TYPES = {
578 "date",
579 "both",
580 "null",
581 null,
582 "invalid",
583 "time",
584 "date",
585 "both",
586 "date"
587 };
588
589 private String[] _SECONDARY_PATTERNS = {
590 null,
591 "yyyy/MM/dd G 'at' HH:mm:ss z",
592 "YYYY/EEE/dd HH:mm:ss Z",
593 "yyyy-mm-dd G",
594 "HH:mm:ss",
595 "MMM/dd/yy",
596 "EEE MMM dd YYYY",
597 "dd-MMM-yy",
598 null
599 };
600
601 private boolean[] _TRANSIENT_VALUES = {
602 true,
603 false,
604 false,
605 true,
606 true,
607 false,
608 true,
609 true,
610 true
611 };
612
613
614
615
616 private static String[] _SDATE_STYLES = {
617 "medium",
618 "long",
619 "long",
620
621 };
622
623 private static Locale[] _SLOCALES = {
624 Locale.US,
625 Locale.ENGLISH,
626 Locale.ENGLISH,
627 Locale.ENGLISH,
628 };
629
630 private static String[] _SPATTERNS = {
631 "d/M/yyyy",
632 null,
633 null,
634 null,
635 };
636
637 private static String[] _STIME_STYLES = {
638 "long",
639 null,
640 "long",
641 "ADD TEST !",
642 };
643
644 private static TimeZone[] _STIME_ZONES = {
645 getTzone("GMT-8:00"),
646 getTzone("GMT-4:00"),
647 getTzone("GMT"),
648 getTzone("GMT-4:00")
649 };
650
651 private static String[] _STYPES = {
652 "date",
653 "date",
654 "both",
655 "date"
656 };
657
658 private static String[] _SSECONDARY_PATTERNS = {
659 "dd/M/yy",
660 null,
661 "dd-M-yyyy",
662 "ADD TEST !"
663 };
664
665
666 private static String[] _SINPUT_VALUES = {
667 "9/1/2001",
668 "February 12, 1952",
669 "July 7, 2001 1:08:56 AM GMT",
670 "Sep 06, 1972"
671 };
672
673 private static int[] _DAYS = {
674 9,
675 12,
676 7,
677 6,
678 };
679
680
681 private static int[] _MONTHS = {
682 Calendar.JANUARY,
683 Calendar.FEBRUARY,
684 Calendar.JULY,
685 Calendar.SEPTEMBER,
686 };
687
688
689 private static int[] _YEARS = {
690 2001,
691 1952,
692 2001,
693 1972,
694 };
695
696 private static int[] _HOURS = {
697 0,
698 0,
699 1,
700 0,
701 };
702
703 private static int[] _MINS = {
704 0,
705 0,
706 8,
707 0,
708 };
709
710 private static int[] _SECS = {
711 0,
712 0,
713 56,
714 0,
715 };
716
717 private static Date[] _SEXPECTED_DATES
718 = _getDates(_SLOCALES,_STIME_ZONES, _DAYS,_MONTHS, _YEARS, _HOURS, _MINS, _SECS);
719
720 }