ics - types_test.go
1 package ics
2
3 import (
4 "bytes"
5 "reflect"
6 "testing"
7 "time"
8 )
9
10 type typeTest struct {
11 Params map[string]string
12 Data string
13 Input interface {
14 decode(map[string]string, string) error
15 }
16 Match interface {
17 encode(writer)
18 valid() error
19 }
20 Output string
21 Error error
22 }
23
24 var emptyMap = make(map[string]string)
25
26 func testType(t *testing.T, tests []typeTest) {
27 var buf bytes.Buffer
28 for n, test := range tests {
29 if test.Params == nil {
30 test.Params = emptyMap
31 }
32 err := test.Input.decode(test.Params, test.Data)
33 if err != test.Error {
34 if !reflect.DeepEqual(err, test.Error) {
35 t.Errorf("test %d: expecting error %s, got %s", n+1, test.Error, err)
36 continue
37 }
38 }
39 if test.Error == nil {
40 if !reflect.DeepEqual(test.Input, test.Match) {
41 t.Errorf("test %d: input does not match expected", n+1)
42 continue
43 }
44 if err := test.Match.valid(); err != nil {
45 t.Errorf("test %d: unexpected validation error: %s", n+1, err)
46 continue
47 }
48 test.Match.encode(&buf)
49 if str := buf.String(); str != test.Output {
50 t.Errorf("test %d: expecting output string %q, got %q", n+1, test.Output, str)
51 }
52 buf.Reset()
53 }
54 }
55 }
56
57 func TestBinary(t *testing.T) {
58 testType(t, []typeTest{
59 {
60 Input: &Binary{},
61 Match: &Binary{},
62 Error: ErrInvalidEncoding,
63 },
64 {
65 Params: map[string]string{"ENCODING": "BASE64"},
66 Data: "MTIzNDU=",
67 Input: &Binary{},
68 Match: &Binary{'1', '2', '3', '4', '5'},
69 Output: "MTIzNDU=",
70 },
71 })
72 }
73
74 func TestBoolean(t *testing.T) {
75 tr := new(Boolean)
76 fa := new(Boolean)
77 *tr = true
78 testType(t, []typeTest{
79 {
80 Data: "False",
81 Input: fa,
82 Match: fa,
83 Output: "FALSE",
84 },
85 {
86 Data: "true",
87 Input: tr,
88 Match: tr,
89 Output: "TRUE",
90 },
91 {
92 Data: "HotDog",
93 Input: fa,
94 Error: ErrInvalidBoolean,
95 },
96 })
97 }
98
99 func TestDate(t *testing.T) {
100 testType(t, []typeTest{
101 {
102 Data: "20011225",
103 Input: &Date{},
104 Match: &Date{time.Date(2001, 12, 25, 0, 0, 0, 0, time.UTC)},
105 Output: "20011225",
106 },
107 {
108 Data: "20081111",
109 Input: &Date{},
110 Match: &Date{time.Date(2008, 11, 11, 0, 0, 0, 0, time.UTC)},
111 Output: "20081111",
112 },
113 })
114 }
115
116 func TestDateTime(t *testing.T) {
117 l, err := time.LoadLocation("America/New_York")
118 if err != nil {
119 t.Errorf("unexpected error: %s", err)
120 return
121 }
122 testType(t, []typeTest{
123 {
124 Data: "20011225T131415",
125 Input: &DateTime{},
126 Match: &DateTime{time.Date(2001, 12, 25, 13, 14, 15, 0, time.Local)},
127 Output: "20011225T131415",
128 },
129 {
130 Data: "20011225T131415Z",
131 Input: &DateTime{},
132 Match: &DateTime{time.Date(2001, 12, 25, 13, 14, 15, 0, time.UTC)},
133 Output: "20011225T131415Z",
134 },
135 {
136 Params: map[string]string{"TZID": "America/New_York"},
137 Data: "20011225T131415",
138 Input: &DateTime{},
139 Match: &DateTime{time.Date(2001, 12, 25, 13, 14, 15, 0, l)},
140 Output: "20011225T131415",
141 },
142 })
143 }
144
145 func TestDuration(t *testing.T) {
146 testType(t, []typeTest{
147 {
148 Data: "P1W",
149 Input: &Duration{},
150 Match: &Duration{Weeks: 1},
151 Output: "P1W",
152 },
153 {
154 Data: "P1D",
155 Input: &Duration{},
156 Match: &Duration{Days: 1},
157 Output: "P1D",
158 },
159 {
160 Data: "PT1H",
161 Input: &Duration{},
162 Match: &Duration{Hours: 1},
163 Output: "PT1H",
164 },
165 {
166 Data: "PT1M",
167 Input: &Duration{},
168 Match: &Duration{Minutes: 1},
169 Output: "PT1M",
170 },
171 {
172 Data: "PT1S",
173 Input: &Duration{},
174 Match: &Duration{Seconds: 1},
175 Output: "PT1S",
176 },
177 {
178 Data: "P25W",
179 Input: &Duration{},
180 Match: &Duration{Weeks: 25},
181 Output: "P25W",
182 },
183 {
184 Data: "P25W1D",
185 Input: &Duration{},
186 Error: ErrInvalidDuration,
187 },
188 {
189 Data: "P25G",
190 Input: &Duration{},
191 Error: ErrInvalidDuration,
192 },
193 {
194 Data: "P1DT2H3M4S",
195 Input: &Duration{},
196 Match: &Duration{Days: 1, Hours: 2, Minutes: 3, Seconds: 4},
197 Output: "P1DT2H3M4S",
198 },
199 {
200 Data: "PT0S",
201 Input: &Duration{},
202 Match: &Duration{},
203 Output: "PT0S",
204 },
205 {
206 Data: "+P1DT2H3M4S",
207 Input: &Duration{},
208 Match: &Duration{Days: 1, Hours: 2, Minutes: 3, Seconds: 4},
209 Output: "P1DT2H3M4S",
210 },
211 {
212 Data: "-P1DT2H3M4S",
213 Input: &Duration{},
214 Match: &Duration{Negative: true, Days: 1, Hours: 2, Minutes: 3, Seconds: 4},
215 Output: "-P1DT2H3M4S",
216 },
217 })
218 }
219
220 func TestPeriod(t *testing.T) {
221 testType(t, []typeTest{
222 {
223 Data: "19970101T180000Z/19970102T070000Z",
224 Input: &Period{},
225 Match: &Period{
226 Start: DateTime{Time: time.Date(1997, 1, 1, 18, 0, 0, 0, time.UTC)},
227 End: DateTime{Time: time.Date(1997, 1, 2, 7, 0, 0, 0, time.UTC)},
228 },
229 Output: "19970101T180000Z/19970102T070000Z",
230 },
231 {
232 Data: "19970101T180000Z/PT5H30M",
233 Input: &Period{},
234 Match: &Period{
235 Start: DateTime{Time: time.Date(1997, 1, 1, 18, 0, 0, 0, time.UTC)},
236 Duration: Duration{Hours: 5, Minutes: 30},
237 },
238 Output: "19970101T180000Z/PT5H30M",
239 },
240 })
241 }
242
243 func TestRecur(t *testing.T) {
244 testType(t, []typeTest{
245 { // 1
246 Data: "FREQ=SECONDLY",
247 Input: &Recur{},
248 Match: &Recur{},
249 Output: "FREQ=SECONDLY",
250 },
251 { // 2
252 Data: "FREQ=MINUTELY",
253 Input: &Recur{},
254 Match: &Recur{
255 Frequency: Minutely,
256 },
257 Output: "FREQ=MINUTELY",
258 },
259 { // 3
260 Data: "FREQ=HOURLY;COUNT=10",
261 Input: &Recur{},
262 Match: &Recur{
263 Frequency: Hourly,
264 Count: 10,
265 },
266 Output: "FREQ=HOURLY;COUNT=10",
267 },
268 { // 4
269 Data: "FREQ=DAILY;UNTIL=20011125",
270 Input: &Recur{},
271 Match: &Recur{
272 Frequency: Daily,
273 Until: time.Date(2001, 11, 25, 0, 0, 0, 0, time.UTC),
274 },
275 Output: "FREQ=DAILY;UNTIL=20011125",
276 },
277 { // 5
278 Data: "FREQ=WEEKLY;UNTIL=20011125T131415",
279 Input: &Recur{},
280 Match: &Recur{
281 Frequency: Weekly,
282 Until: time.Date(2001, 11, 25, 13, 14, 15, 0, time.Local),
283 UntilTime: true,
284 },
285 Output: "FREQ=WEEKLY;UNTIL=20011125T131415",
286 },
287 { // 6
288 Data: "UNTIL=20011125;FREQ=MONTHLY",
289 Input: &Recur{},
290 Match: &Recur{
291 Frequency: Monthly,
292 Until: time.Date(2001, 11, 25, 0, 0, 0, 0, time.UTC),
293 },
294 Output: "FREQ=MONTHLY;UNTIL=20011125",
295 },
296 { // 7
297 Data: "FREQ=YEARLY;UNTIL=20011125T131415Z",
298 Input: &Recur{},
299 Match: &Recur{
300 Frequency: Yearly,
301 Until: time.Date(2001, 11, 25, 13, 14, 15, 0, time.UTC),
302 UntilTime: true,
303 },
304 Output: "FREQ=YEARLY;UNTIL=20011125T131415Z",
305 },
306 { // 8
307 Data: "FREQ=UNKNOWN",
308 Input: &Recur{},
309 Error: ErrInvalidRecur,
310 },
311 { // 9
312 Data: "FREQ=SECONDLY;COUNT=-1",
313 Input: &Recur{},
314 Error: ErrInvalidRecur,
315 },
316 { // 10
317 Data: "FREQ=SECONDLY;UNTIL=ABC",
318 Input: &Recur{},
319 Error: ErrInvalidRecur,
320 },
321 { // 11
322 Data: "FREQ=SECONDLY;INTERVAL=10",
323 Input: &Recur{},
324 Match: &Recur{
325 Interval: 10,
326 },
327 Output: "FREQ=SECONDLY;INTERVAL=10",
328 },
329 { // 12
330 Data: "FREQ=SECONDLY;BYSECOND=1,2,60",
331 Input: &Recur{},
332 Match: &Recur{
333 BySecond: []uint8{1, 2, 60},
334 },
335 Output: "FREQ=SECONDLY;BYSECOND=1,2,60",
336 },
337 { // 13
338 Data: "FREQ=SECONDLY;BYSECOND=1,2,61",
339 Input: &Recur{},
340 Error: ErrInvalidRecur,
341 },
342 { // 14
343 Data: "FREQ=SECONDLY;BYSECOND=1,2,-1",
344 Input: &Recur{},
345 Error: ErrInvalidRecur,
346 },
347 { // 15
348 Data: "FREQ=SECONDLY;BYSECOND=1,2,A",
349 Input: &Recur{},
350 Error: ErrInvalidRecur,
351 },
352 { // 16
353 Data: "FREQ=SECONDLY;BYMINUTE=1,2,59",
354 Input: &Recur{},
355 Match: &Recur{
356 ByMinute: []uint8{1, 2, 59},
357 },
358 Output: "FREQ=SECONDLY;BYMINUTE=1,2,59",
359 },
360 { // 17
361 Data: "FREQ=SECONDLY;BYMINUTE=1,2,60",
362 Input: &Recur{},
363 Error: ErrInvalidRecur,
364 },
365 { // 18
366 Data: "FREQ=SECONDLY;BYMINUTE=1,2,-1",
367 Input: &Recur{},
368 Error: ErrInvalidRecur,
369 },
370 { // 19
371 Data: "FREQ=SECONDLY;BYMINUTE=1,2,A",
372 Input: &Recur{},
373 Error: ErrInvalidRecur,
374 },
375 { // 20
376 Data: "FREQ=SECONDLY;BYHOUR=1,2,23",
377 Input: &Recur{},
378 Match: &Recur{
379 ByHour: []uint8{1, 2, 23},
380 },
381 Output: "FREQ=SECONDLY;BYHOUR=1,2,23",
382 },
383 { // 21
384 Data: "FREQ=SECONDLY;BYHOUR=1,2,24",
385 Input: &Recur{},
386 Error: ErrInvalidRecur,
387 },
388 { // 22
389 Data: "FREQ=SECONDLY;BYHOUR=1,2,-1",
390 Input: &Recur{},
391 Error: ErrInvalidRecur,
392 },
393 { // 23
394 Data: "FREQ=SECONDLY;BYHOUR=1,2,A",
395 Input: &Recur{},
396 Error: ErrInvalidRecur,
397 },
398 { // 24
399 Data: "FREQ=SECONDLY;BYDAY=WE,+2FR,53MO,-53SU,-9TU",
400 Input: &Recur{},
401 Match: &Recur{
402 ByDay: []DayRecur{
403 {Day: Wednesday},
404 {Day: Friday, Occurrence: 2},
405 {Day: Monday, Occurrence: 53},
406 {Day: Sunday, Occurrence: -53},
407 {Day: Tuesday, Occurrence: -9},
408 },
409 },
410 Output: "FREQ=SECONDLY;BYDAY=WE,2FR,53MO,-53SU,-9TU",
411 },
412 { // 25
413 Data: "FREQ=SECONDLY;BYDAY=UN",
414 Input: &Recur{},
415 Error: ErrInvalidRecur,
416 },
417 { // 26
418 Data: "FREQ=SECONDLY;BYDAY=-54MO",
419 Input: &Recur{},
420 Error: ErrInvalidRecur,
421 },
422 { // 27
423 Data: "FREQ=SECONDLY;BYDAY=54MO",
424 Input: &Recur{},
425 Error: ErrInvalidRecur,
426 },
427 { // 28
428 Data: "FREQ=SECONDLY;BYDAY=MON",
429 Input: &Recur{},
430 Error: ErrInvalidRecur,
431 },
432 { // 29
433 Data: "FREQ=SECONDLY;BYDAY=MO,",
434 Input: &Recur{},
435 Error: ErrInvalidRecur,
436 },
437 { // 30
438 Data: "FREQ=SECONDLY;BYMONTHDAY=1,31,-1,-31",
439 Input: &Recur{},
440 Match: &Recur{
441 ByMonthDay: []int8{1, 31, -1, -31},
442 },
443 Output: "FREQ=SECONDLY;BYMONTHDAY=1,31,-1,-31",
444 },
445 { // 31
446 Data: "FREQ=SECONDLY;BYMONTHDAY=32",
447 Input: &Recur{},
448 Error: ErrInvalidRecur,
449 },
450 { // 32
451 Data: "FREQ=SECONDLY;BYMONTHDAY=-32",
452 Input: &Recur{},
453 Error: ErrInvalidRecur,
454 },
455 { // 33
456 Data: "FREQ=SECONDLY;BYMONTHDAY=0",
457 Input: &Recur{},
458 Error: ErrInvalidRecur,
459 },
460 { // 34
461 Data: "FREQ=SECONDLY;BYMONTHDAY=A",
462 Input: &Recur{},
463 Error: ErrInvalidRecur,
464 },
465 { // 35
466 Data: "FREQ=SECONDLY;BYMONTHDAY=1,",
467 Input: &Recur{},
468 Error: ErrInvalidRecur,
469 },
470 { // 36
471 Data: "FREQ=SECONDLY;BYYEARDAY=1,366,-1,-366",
472 Input: &Recur{},
473 Match: &Recur{
474 ByYearDay: []int16{1, 366, -1, -366},
475 },
476 Output: "FREQ=SECONDLY;BYYEARDAY=1,366,-1,-366",
477 },
478 { // 37
479 Data: "FREQ=SECONDLY;BYYEARDAY=0",
480 Input: &Recur{},
481 Error: ErrInvalidRecur,
482 },
483 { // 38
484 Data: "FREQ=SECONDLY;BYYEARDAY=367",
485 Input: &Recur{},
486 Error: ErrInvalidRecur,
487 },
488 { // 39
489 Data: "FREQ=SECONDLY;BYYEARDAY=-367",
490 Input: &Recur{},
491 Error: ErrInvalidRecur,
492 },
493 { // 40
494 Data: "FREQ=SECONDLY;BYYEARDAY=1,",
495 Input: &Recur{},
496 Error: ErrInvalidRecur,
497 },
498 { // 41
499 Data: "FREQ=SECONDLY;BYYEARDAY=A",
500 Input: &Recur{},
501 Error: ErrInvalidRecur,
502 },
503 { // 42
504 Data: "FREQ=SECONDLY;BYWEEKNO=1,52,-1,-52",
505 Input: &Recur{},
506 Match: &Recur{
507 ByWeekNum: []int8{1, 52, -1, -52},
508 },
509 Output: "FREQ=SECONDLY;BYWEEKNO=1,52,-1,-52",
510 },
511 { // 43
512 Data: "FREQ=SECONDLY;BYYWEEKNO=1,0",
513 Input: &Recur{},
514 Error: ErrInvalidRecur,
515 },
516 { // 44
517 Data: "FREQ=SECONDLY;BYYWEEKNO=54",
518 Input: &Recur{},
519 Error: ErrInvalidRecur,
520 },
521 { // 45
522 Data: "FREQ=SECONDLY;BYYWEEKNO=-54",
523 Input: &Recur{},
524 Error: ErrInvalidRecur,
525 },
526 { // 46
527 Data: "FREQ=SECONDLY;BYYWEEKNO=A",
528 Input: &Recur{},
529 Error: ErrInvalidRecur,
530 },
531 { // 47
532 Data: "FREQ=SECONDLY;BYMONTH=1,2,12",
533 Input: &Recur{},
534 Match: &Recur{
535 ByMonth: []Month{January, February, December},
536 },
537 Output: "FREQ=SECONDLY;BYMONTH=1,2,12",
538 },
539 { // 48
540 Data: "FREQ=SECONDLY;BYMONTH=1,2,13",
541 Input: &Recur{},
542 Error: ErrInvalidRecur,
543 },
544 { // 49
545 Data: "FREQ=SECONDLY;BYMONTH=1,2,-1",
546 Input: &Recur{},
547 Error: ErrInvalidRecur,
548 },
549 { // 50
550 Data: "FREQ=SECONDLY;BYMONTH=1,2,A",
551 Input: &Recur{},
552 Error: ErrInvalidRecur,
553 },
554 { // 51
555 Data: "FREQ=SECONDLY;BYSETPOS=1,366,-1,-366",
556 Input: &Recur{},
557 Match: &Recur{
558 BySetPos: []int16{1, 366, -1, -366},
559 },
560 Output: "FREQ=SECONDLY;BYSETPOS=1,366,-1,-366",
561 },
562 { // 52
563 Data: "FREQ=SECONDLY;BYSETPOS=0",
564 Input: &Recur{},
565 Error: ErrInvalidRecur,
566 },
567 { // 53
568 Data: "FREQ=SECONDLY;BYSETPOS=367",
569 Input: &Recur{},
570 Error: ErrInvalidRecur,
571 },
572 { // 54
573 Data: "FREQ=SECONDLY;BYSETPOS=-367",
574 Input: &Recur{},
575 Error: ErrInvalidRecur,
576 },
577 { // 55
578 Data: "FREQ=SECONDLY;BYSETPOS=1,",
579 Input: &Recur{},
580 Error: ErrInvalidRecur,
581 },
582 { // 56
583 Data: "FREQ=SECONDLY;BYSETPOS=A",
584 Input: &Recur{},
585 Error: ErrInvalidRecur,
586 },
587 { // 57
588 Data: "FREQ=SECONDLY;WKST=SU",
589 Input: &Recur{},
590 Match: &Recur{
591 WeekStart: Sunday,
592 },
593 Output: "FREQ=SECONDLY;WKST=SU",
594 },
595 { // 58
596 Data: "FREQ=SECONDLY;WKST=MO",
597 Input: &Recur{},
598 Match: &Recur{
599 WeekStart: Monday,
600 },
601 Output: "FREQ=SECONDLY;WKST=MO",
602 },
603 { // 59
604 Data: "FREQ=SECONDLY;WKST=TU",
605 Input: &Recur{},
606 Match: &Recur{
607 WeekStart: Tuesday,
608 },
609 Output: "FREQ=SECONDLY;WKST=TU",
610 },
611 { // 60
612 Data: "FREQ=SECONDLY;WKST=WE",
613 Input: &Recur{},
614 Match: &Recur{
615 WeekStart: Wednesday,
616 },
617 Output: "FREQ=SECONDLY;WKST=WE",
618 },
619 { // 61
620 Data: "FREQ=SECONDLY;WKST=TH",
621 Input: &Recur{},
622 Match: &Recur{
623 WeekStart: Thursday,
624 },
625 Output: "FREQ=SECONDLY;WKST=TH",
626 },
627 { // 62
628 Data: "FREQ=SECONDLY;WKST=FR",
629 Input: &Recur{},
630 Match: &Recur{
631 WeekStart: Friday,
632 },
633 Output: "FREQ=SECONDLY;WKST=FR",
634 },
635 { // 63
636 Data: "FREQ=SECONDLY;WKST=SA",
637 Input: &Recur{},
638 Match: &Recur{
639 WeekStart: Saturday,
640 },
641 Output: "FREQ=SECONDLY;WKST=SA",
642 },
643 { // 64
644 Data: "FREQ=SECONDLY;WKST=UN",
645 Input: &Recur{},
646 Error: ErrInvalidRecur,
647 },
648 { // 65
649 Data: "FREQ=SECONDLY;",
650 Input: &Recur{},
651 Error: ErrInvalidRecur,
652 },
653 { // 66
654 Data: "FREQ=SECONDLY;UNKNOWN=1",
655 Input: &Recur{},
656 Error: ErrInvalidRecur,
657 },
658 { // 67
659 Data: "FREQ=SECONDLY;UNKNOWN",
660 Input: &Recur{},
661 Error: ErrInvalidRecur,
662 },
663 })
664 }
665
666 func TestText(t *testing.T) {
667 newText := func(s string) *Text {
668 nt := Text(s)
669 return &nt
670 }
671 testType(t, []typeTest{
672 {
673 Data: "",
674 Input: new(Text),
675 Match: newText(""),
676 Output: "",
677 },
678 {
679 Data: "Jackdaws love my big Sphinx of quartz",
680 Input: new(Text),
681 Match: newText("Jackdaws love my big Sphinx of quartz"),
682 Output: "Jackdaws love my big Sphinx of quartz",
683 },
684 {
685 Data: "Project XYZ Final Review\\nConference Room - 3B\\nCome Prepared.",
686 Input: new(Text),
687 Match: newText("Project XYZ Final Review\nConference Room - 3B\nCome Prepared."),
688 Output: "Project XYZ Final Review\\nConference Room - 3B\\nCome Prepared.",
689 },
690 {
691 Data: "\\\\\\;\\,\\N\\n",
692 Input: new(Text),
693 Match: newText("\\;,\n\n"),
694 Output: "\\\\\\;\\,\\n\\n",
695 },
696 {
697 Data: ";",
698 Input: new(Text),
699 Error: ErrInvalidText,
700 },
701 {
702 Data: ",",
703 Input: new(Text),
704 Error: ErrInvalidText,
705 },
706 })
707 }
708
709 func TestTime(t *testing.T) {
710 l, err := time.LoadLocation("America/New_York")
711 if err != nil {
712 t.Errorf("unexpected error: %s", err)
713 return
714 }
715 testType(t, []typeTest{
716 {
717 Data: "010203",
718 Input: &Time{},
719 Match: &Time{Time: time.Date(0, 1, 1, 1, 2, 3, 0, time.Local)},
720 Output: "010203",
721 },
722 {
723 Data: "010203Z",
724 Input: &Time{},
725 Match: &Time{Time: time.Date(0, 1, 1, 1, 2, 3, 0, time.UTC)},
726 Output: "010203Z",
727 },
728 {
729 Params: map[string]string{"TZID": "America/New_York"},
730 Data: "010203",
731 Input: &Time{},
732 Match: &Time{Time: time.Date(0, 1, 1, 1, 2, 3, 0, l)},
733 Output: "010203",
734 },
735 })
736 }
737
738 func TestUTCOffset(t *testing.T) {
739 newUTC := func(i int) *UTCOffset {
740 u := UTCOffset(i)
741 return &u
742 }
743 testType(t, []typeTest{
744 {
745 Data: "0100",
746 Input: new(UTCOffset),
747 Match: newUTC(3600),
748 Output: "0100",
749 },
750 {
751 Data: "0230",
752 Input: new(UTCOffset),
753 Match: newUTC(9000),
754 Output: "0230",
755 },
756 {
757 Data: "023045",
758 Input: new(UTCOffset),
759 Match: newUTC(9045),
760 Output: "023045",
761 },
762 {
763 Data: "+0230",
764 Input: new(UTCOffset),
765 Match: newUTC(9000),
766 Output: "0230",
767 },
768 {
769 Data: "-0230",
770 Input: new(UTCOffset),
771 Match: newUTC(-9000),
772 Output: "-0230",
773 },
774 {
775 Data: "0260",
776 Input: new(UTCOffset),
777 Error: ErrInvalidOffset,
778 },
779 {
780 Data: "020060",
781 Input: new(UTCOffset),
782 Error: ErrInvalidOffset,
783 },
784 {
785 Data: "0261",
786 Input: new(UTCOffset),
787 Error: ErrInvalidOffset,
788 },
789 {
790 Data: "020061",
791 Input: new(UTCOffset),
792 Error: ErrInvalidOffset,
793 },
794 {
795 Data: "0",
796 Input: new(UTCOffset),
797 Error: ErrInvalidOffset,
798 },
799 {
800 Data: "00",
801 Input: new(UTCOffset),
802 Error: ErrInvalidOffset,
803 },
804 {
805 Data: "000",
806 Input: new(UTCOffset),
807 Error: ErrInvalidOffset,
808 },
809 {
810 Data: "00000",
811 Input: new(UTCOffset),
812 Error: ErrInvalidOffset,
813 },
814 {
815 Data: "T",
816 Input: new(UTCOffset),
817 Error: ErrInvalidOffset,
818 },
819 {
820 Data: "0000T",
821 Input: new(UTCOffset),
822 Error: ErrInvalidOffset,
823 },
824 {
825 Data: "000000T",
826 Input: new(UTCOffset),
827 Error: ErrInvalidOffset,
828 },
829 {
830 Data: "-0000",
831 Input: new(UTCOffset),
832 Error: ErrInvalidOffset,
833 },
834 {
835 Data: "-000000",
836 Input: new(UTCOffset),
837 Error: ErrInvalidOffset,
838 },
839 })
840 }