forked from apognu/gocal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gocal_test.go
278 lines (237 loc) · 7.61 KB
/
gocal_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
package gocal
import (
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
const ics = `BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;VALUE=DATE:20141217
DTEND;VALUE=DATE:20141219
DTSTAMP:20151116T133227Z
CREATED:20141110T150010Z
DESCRIPTION:Amazing description on t
wo lines
LAST-MODIFIED:20141110T150010Z
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Antoin
e Popineau;X-NUM-GUESTS=0:mailto:[email protected]
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=John
Connor;X-NUM-GUESTS=0:mailto:[email protected]
LOCATION:My Place
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Lorem Ipsum Dolor Sit Amet
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART:20141203T130000Z
DTEND:20141203T163000Z
DTSTAMP:20151116T133227Z
CREATED:20141110T145426Z
DESCRIPTION:
LAST-MODIFIED:20141110T150016Z
LOCATION:Over there
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:The quick brown fox jumps over the lazy dog
TRANSP:TRANSPARENT
X-COLOR:#abc123
X-ADDRESS:432 Main St., San Francisco
END:VEVENT`
func Test_Parse(t *testing.T) {
start, end := time.Date(2010, 1, 1, 0, 0, 0, 0, time.Local), time.Date(2017, 1, 1, 0, 0, 0, 0, time.Local)
gc := NewParser(strings.NewReader(ics))
gc.Start, gc.End = &start, &end
gc.Parse()
assert.Equal(t, 2, len(gc.Events))
assert.Equal(t, "Lorem Ipsum Dolor Sit Amet", gc.Events[0].Summary)
assert.Equal(t, "[email protected]", gc.Events[0].Uid)
assert.Equal(t, "Amazing description on two lines", gc.Events[0].Description)
assert.Equal(t, 2, len(gc.Events[0].Attendees))
assert.Equal(t, "John Connor", gc.Events[0].Attendees[1].Cn)
assert.Equal(t, 0, len(gc.Events[0].CustomAttributes))
assert.Equal(t, 2, len(gc.Events[1].CustomAttributes))
assert.Equal(t, "#abc123", gc.Events[1].CustomAttributes["X-COLOR"])
}
func Test_ParseLine(t *testing.T) {
gc := NewParser(strings.NewReader("HELLO;KEY1=value1;KEY2=value2: world"))
gc.scanner.Scan()
l, err, done := gc.parseLine()
assert.Equal(t, nil, err)
assert.Equal(t, true, done)
assert.Equal(t, "HELLO", l.Key)
assert.Equal(t, "world", l.Value)
assert.Equal(t, map[string]string{"KEY1": "value1", "KEY2": "value2"}, l.Params)
}
// Event repeats every second monday and tuesday
// Instance of January, 29th is excluded
// Instance of January, 1st is changed
// Event repeats every month on the second day
const recuringICS = `BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20180102
DTEND:20180103
DTSTAMP:20151116T133227Z
SUMMARY:Every month on the second
RRULE:FREQ=MONTHLY;BYMONTHDAY=2
END:VEVENT
BEGIN:VEVENT
DTSTART:20180101T090000Z
DTEND:20180101T110000Z
DTSTAMP:20151116T133227Z
SUMMARY:Every two weeks on mondays and tuesdays forever
RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,TU
EXDATE;VALUE=DATE:20180129T090000Z
END:VEVENT
BEGIN:VEVENT
DTSTART:20180101T110000Z
DTEND:20180101T130000Z
DTSTAMP:20151116T133227Z
RECURRENCE-ID:20180101T090000Z
SUMMARY:This changed!
END:VEVENT
END:VCALENDAR`
func Test_ReccuringRule(t *testing.T) {
start, end := time.Date(2018, 1, 1, 0, 0, 0, 0, time.Local), time.Date(2018, 2, 5, 23, 59, 59, 0, time.Local)
gc := NewParser(strings.NewReader(recuringICS))
gc.Start, gc.End = &start, &end
gc.Parse()
assert.Equal(t, 7, len(gc.Events))
assert.Equal(t, "This changed!", gc.Events[0].Summary)
assert.Equal(t, "Every month on the second", gc.Events[2].Summary)
assert.Equal(t, "Every two weeks on mondays and tuesdays forever", gc.Events[4].Summary)
}
const recurringICSWithExdate = `BEGIN:VCALENDAR
BEGIN:VEVENT
UID:plop
SUMMARY:Lorem ipsum dolor sit amet
DTSTAMP:20151116T133227Z
DTSTART:20190101T130000Z
DTEND:20190101T140000Z
RRULE:FREQ=MONTHLY;COUNT=5
EXDATE:20190201T130000Z
END:VEVENT
END:VCALENDAR`
func Test_ReccuringRuleWithExdate(t *testing.T) {
start, end := time.Date(2019, 1, 1, 0, 0, 0, 0, time.Local), time.Date(2019, 12, 31, 23, 59, 59, 0, time.Local)
gc := NewParser(strings.NewReader(recurringICSWithExdate))
gc.Start, gc.End = &start, &end
gc.Parse()
assert.Equal(t, 4, len(gc.Events))
d := time.Date(2019, 2, 1, 13, 0, 0, 0, time.Local).Format("2006-02-01")
for _, e := range gc.Events {
assert.NotEqual(t, d, e.Start.Format("2016-02-01"))
}
}
const unknownICS = `BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;VALUE=DATE:20180117
DTEND;VALUE=DATE:20180119
DTSTAMP:20151116T133227Z
CREATED:20141110T150010Z
DESCRIPTION:Amazing description on t
wo lines
LAST-MODIFIED:20141110T150010Z
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Antoin
e Popineau;X-NUM-GUESTS=0:mailto:[email protected]
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=John
Connor;X-NUM-GUESTS=0:mailto:[email protected]
BEGIN:SOMETHING
BEGIN:NESTED
BEGIN:AGAINNESTED
END:AGAINNESTED
END:NESTED
END:SOMETHING
LOCATION:My Place
SEQUENCE:0
STATUS:CONFIRMED
BEGIN:HELLOWORLD
END:HELLOWORLD
SUMMARY:Lorem Ipsum Dolor Sit Amet
TRANSP:TRANSPARENT
END:VEVENT`
func Test_UnknownBlocks(t *testing.T) {
start, end := time.Date(2018, 1, 1, 0, 0, 0, 0, time.Local), time.Date(2018, 2, 5, 23, 59, 59, 0, time.Local)
gc := NewParser(strings.NewReader(unknownICS))
gc.Start, gc.End = &start, &end
err := gc.Parse()
assert.Nil(t, err)
assert.Equal(t, 1, len(gc.Events))
assert.Equal(t, "Amazing description on two lines", gc.Events[0].Description)
assert.Equal(t, "My Place", gc.Events[0].Location)
}
const invalidICS = `BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;TZID=Europe/Paris:20190101T090000
DTEND;TZID=Europe/Paris:20190101T110000
UID:one@gocal
SUMMARY:Event with custom labels
END:VEVENT
BEGIN:VEVENT
DTSTAMP:20151116T133227Z
DTSTART;TZID=Europe/Paris:20190201T090000
DTEND;TZID=Europe/Paris:20190201T110000
UID:two@gocal
SUMMARY:Second event with custom labels
END:VEVENT
END:VCALENDAR`
func Test_InvalidEventFailFeed(t *testing.T) {
start, end := time.Date(2018, 1, 1, 0, 0, 0, 0, time.Local), time.Date(2020, 2, 5, 23, 59, 59, 0, time.Local)
gc := NewParser(strings.NewReader(invalidICS))
gc.Start, gc.End = &start, &end
err := gc.Parse()
assert.NotNil(t, err)
assert.Equal(t, 0, len(gc.Events))
}
func Test_InvalidEventFailEvent(t *testing.T) {
start, end := time.Date(2018, 1, 1, 0, 0, 0, 0, time.Local), time.Date(2020, 2, 5, 23, 59, 59, 0, time.Local)
gc := NewParser(strings.NewReader(invalidICS))
gc.Start, gc.End = &start, &end
gc.StrictMode = StrictModeFailEvent
err := gc.Parse()
assert.Nil(t, err)
assert.Equal(t, 1, len(gc.Events))
}
func Test_InvalidEventFailAttribute(t *testing.T) {
start, end := time.Date(2018, 1, 1, 0, 0, 0, 0, time.Local), time.Date(2020, 2, 5, 23, 59, 59, 0, time.Local)
gc := NewParser(strings.NewReader(invalidICS))
gc.Start, gc.End = &start, &end
gc.StrictMode = StrictModeFailAttribute
err := gc.Parse()
assert.Nil(t, err)
assert.Equal(t, 2, len(gc.Events))
assert.False(t, gc.Events[0].Valid)
assert.True(t, gc.Events[1].Valid)
}
const durationICS = `BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTAMP:20151116T133227Z
DURATION:P1Y5DT1H10M30S
DTSTART;TZID=Europe/Paris:20190101T090000
UID:one@gocal
SUMMARY:Event with custom labels
END:VEVENT`
func Test_DurationEvent(t *testing.T) {
start, end := time.Date(2018, 1, 1, 0, 0, 0, 0, time.Local), time.Date(2025, 2, 5, 23, 59, 59, 0, time.Local)
gc := NewParser(strings.NewReader(durationICS))
gc.Start, gc.End = &start, &end
err := gc.Parse()
assert.Nil(t, err)
assert.Equal(t, 1, len(gc.Events))
if len(gc.Events) == 1 {
assert.Equal(t, gc.Events[0].End.Year(), 2020)
assert.Equal(t, gc.Events[0].End.Day(), 6)
assert.Equal(t, gc.Events[0].End.Hour(), 10)
assert.Equal(t, gc.Events[0].End.Minute(), 10)
assert.Equal(t, gc.Events[0].End.Second(), 30)
}
}