-
-
Notifications
You must be signed in to change notification settings - Fork 771
/
Copy pathTestDateInRegion+Create.swift
324 lines (285 loc) · 11.6 KB
/
TestDateInRegion+Create.swift
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
//
// SwiftDate
// Parse, validate, manipulate, and display dates, time and timezones in Swift
//
// Created by Daniele Margutti
// - Web: https://www.danielemargutti.com
// - Twitter: https://twitter.com/danielemargutti
// - Mail: hello@danielemargutti.com
//
// Copyright © 2019 Daniele Margutti. Licensed under MIT License.
//
import SwiftDate
import XCTest
public func randomNumber<T: SignedInteger>(inRange range: ClosedRange<T> = 1...6) -> T {
let length = Int64(range.upperBound - range.lowerBound + 1)
let value = Int64.random(in: 0..<Int64.max) % length + Int64(range.lowerBound)
return T(value)
}
class TestDateInRegion_Create: XCTestCase {
func testDateInRegion_DateBySetTime() {
let regionRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
let date1 = DateInRegion("2010-01-01 00:00:00", format: "yyyy-MM-dd HH:mm:ss", region: regionRome)!
guard let date1a = date1.dateBySet(hour: 20, min: 13, secs: 15) else {
XCTFail("Failed to alter date's time")
return
}
XCTAssert( (date1a.hour == 20 && date1a.minute == 13 && date1a.second == 15 ), "Failed to alter date's time")
// altering only one component
guard let date2a = date1.dateBySet(hour: 20, min: nil, secs: nil) else {
XCTFail("Failed to alter date's time")
return
}
XCTAssert( (date2a.hour == 20 && date2a.minute == 00 && date2a.second == 00 ), "Failed to alter date's time")
}
func testDateInRegion_DateBySet() {
// swiftlint:disable nesting
struct ExpectDateBySet {
var components: [Calendar.Component: Int?] = [:]
init() {
let allCmps: [Calendar.Component] = [.second, .minute, .hour, .day, .month, .year]
for i in 0..<allCmps.count {
let componentToAlter = allCmps[i]
let range: ClosedRange<Int>?
switch componentToAlter {
case .second, .minute: range = 0...50
case .hour: range = 0...20
case .day: range = 1...28
case .month: range = 1...12
case .year: range = 2000...2050
default: range = nil
}
if let range = range {
let value = randomNumber(inRange: range)
components[componentToAlter] = value
}
}
}
func verify(date: DateInRegion) {
components.keys.forEach {
if let value = date.dateComponents.value(for: $0), let expected = components[$0] as? Int {
if value != expected {
XCTFail("Failed to set value of component \($0). Got \(value), expected \(expected)")
return
}
}
}
}
}
for _ in 0..<50 {
let randomDate = "2041-05-18T18:00:25Z".toISODate()! //DateInRegion.randomDate(region: regionRome)
let alterComponents = ExpectDateBySet()
if let alteredDate = randomDate.dateBySet(alterComponents.components) {
alterComponents.verify(date: alteredDate)
}
}
}
func testDateInRegion_RandomDatesInRange() {
// Random dates
let regionNorw = Region(calendar: Calendars.gregorian, zone: Zones.europeOslo, locale: Locales.norwegianBokmlSvalbardJanMayen)
let randomDateAny = DateInRegion.randomDate(region: regionNorw)
guard randomDateAny.region == regionNorw else {
XCTFail("Failed to generate a random date in region")
return
}
// Random dates in range
let regionRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
let upperLimit = DateInRegion("2015-01-01 00:00:00", format: "yyyy-MM-dd HH:mm:ss", region: regionRome)!
let lowerLimit = DateInRegion("2010-01-01 00:00:00", format: "yyyy-MM-dd HH:mm:ss", region: regionRome)!
let randomDates = DateInRegion.randomDates(count: 50, between: lowerLimit, and: upperLimit, region: regionRome)
randomDates.forEach {
guard $0.isInRange(date: lowerLimit, and: upperLimit) else {
XCTFail("Random date '\($0.description)' is not in given range")
return
}
}
}
func testDateInRegion_RandomDatesBackToDays() {
for _ in 0..<50 {
let daysBack = (Int.random(in: 0..<365) + 1)
let randomDate = DateInRegion.randomDate(withinDaysBeforeToday: daysBack)
guard randomDate.getInterval(toDate: DateInRegion(), component: .day) <= daysBack else {
XCTFail("Failed to generate a random back date back to max \(daysBack) days")
return
}
}
}
func testDateInRegion_EnumerateDates() {
let regionRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
// TEST DATE #1
// +1 days
let fromDate1 = DateInRegion("2015-01-01 00:00:00", format: "yyyy-MM-dd HH:mm:ss", region: regionRome)!
let toDate1 = DateInRegion("2015-01-02 03:00:00", format: "yyyy-MM-dd HH:mm:ss", region: regionRome)!
let increment1 = DateComponents.create {
$0.hour = 1
}
let enumeratedDates1 = DateInRegion.enumerateDates(from: fromDate1, to: toDate1, increment: increment1)
let expectedDates1 = [
"2015-01-01 00:00:00",
"2015-01-01 01:00:00",
"2015-01-01 02:00:00",
"2015-01-01 03:00:00",
"2015-01-01 04:00:00",
"2015-01-01 05:00:00",
"2015-01-01 06:00:00",
"2015-01-01 07:00:00",
"2015-01-01 08:00:00",
"2015-01-01 09:00:00",
"2015-01-01 10:00:00",
"2015-01-01 11:00:00",
"2015-01-01 12:00:00",
"2015-01-01 13:00:00",
"2015-01-01 14:00:00",
"2015-01-01 15:00:00",
"2015-01-01 16:00:00",
"2015-01-01 17:00:00",
"2015-01-01 18:00:00",
"2015-01-01 19:00:00",
"2015-01-01 20:00:00",
"2015-01-01 21:00:00",
"2015-01-01 22:00:00",
"2015-01-01 23:00:00",
"2015-01-02 00:00:00",
"2015-01-02 01:00:00",
"2015-01-02 02:00:00",
"2015-01-02 03:00:00"]
XCTExpectedFormattedDates(enumeratedDates1, expected: expectedDates1)
// TEST DATE #2
// +1 hour, +30 minutes, +10 seconds
let increment2 = DateComponents.create {
$0.hour = 1
$0.minute = 30
$0.second = 10
}
let fromDate2 = DateInRegion("2015-01-01 10:00:00", format: "yyyy-MM-dd HH:mm:ss", region: regionRome)!
let toDate2 = DateInRegion("2015-01-02 03:00:00", format: "yyyy-MM-dd HH:mm:ss", region: regionRome)!
let enumeratedDates2 = DateInRegion.enumerateDates(from: fromDate2, to: toDate2, increment: increment2)
let expectedDates2 = [
"2015-01-01 10:00:00",
"2015-01-01 11:30:10",
"2015-01-01 13:00:20",
"2015-01-01 14:30:30",
"2015-01-01 16:00:40",
"2015-01-01 17:30:50",
"2015-01-01 19:01:00",
"2015-01-01 20:31:10",
"2015-01-01 22:01:20",
"2015-01-01 23:31:30",
"2015-01-02 01:01:40",
"2015-01-02 02:31:50"
]
XCTExpectedFormattedDates(enumeratedDates2, expected: expectedDates2)
// TEST DATE #3
// +1 month
let increment3 = DateComponents.create {
$0.month = 1
}
let fromDate3 = DateInRegion("2015-01-01 01:00:00", format: "yyyy-MM-dd HH:mm:ss", region: regionRome)!
let toDate3 = DateInRegion("2016-02-05 02:00:00", format: "yyyy-MM-dd HH:mm:ss", region: regionRome)!
let enumeratedDates3 = DateInRegion.enumerateDates(from: fromDate3, to: toDate3, increment: increment3)
let expectedDates3 = [
"2015-01-01 01:00:00",
"2015-02-01 01:00:00",
"2015-03-01 01:00:00",
"2015-04-01 01:00:00",
"2015-05-01 01:00:00",
"2015-06-01 01:00:00",
"2015-07-01 01:00:00",
"2015-08-01 01:00:00",
"2015-09-01 01:00:00",
"2015-10-01 01:00:00",
"2015-11-01 01:00:00",
"2015-12-01 01:00:00",
"2016-01-01 01:00:00",
"2016-02-01 01:00:00"
]
XCTExpectedFormattedDates(enumeratedDates3, expected: expectedDates3)
}
func XCTExpectedFormattedDates(_ list: [DateInRegion], expected expectedDates: [String]) {
list.enumerated().forEach {
let formatted = $0.element.toFormat("yyyy-MM-dd HH:mm:ss")
let expected = expectedDates[$0.offset]
guard expected == formatted else {
XCTFail("Failed to enumerate dates. Got '\(formatted)' expected '\(expected)")
return
}
}
}
func testDateInRegion_oldestAndNewestAndSortsIn() {
let regionRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
let regionLondon = Region(calendar: Calendars.gregorian, zone: Zones.europeLondon, locale: Locales.english)
let regionNY = Region(calendar: Calendars.gregorian, zone: Zones.americaNewYork, locale: Locales.english)
let datesArrayFormat = "yyyy-MM-dd HH:mm:ss"
let date1 = DateInRegion("2015-09-24 13:20:55", format: datesArrayFormat, region: regionRome)!
let date2 = DateInRegion("2015-11-14 14:44:00", format: datesArrayFormat, region: regionRome)!
let date3 = DateInRegion("2017-01-01 00:00:00", format: datesArrayFormat, region: regionRome)!
let date4 = DateInRegion("2015-09-24 13:00:55", format: datesArrayFormat, region: regionNY)!
let date5 = DateInRegion("2017-11-30 20:00:40", format: datesArrayFormat, region: regionNY)!
let date6 = DateInRegion("2017-11-29 23:59:59", format: datesArrayFormat, region: regionLondon)!
let datesArray = [date1, date2, date3, date4, date5, date6]
// Oldest and Newest
XCTAssert( (DateInRegion.oldestIn(list: datesArray) == date1), "Failed to get the oldest date in list")
XCTAssert( (DateInRegion.newestIn(list: datesArray) == date5), "Failed to get the newest date in list")
// Order by newest
let orderedByNewest = DateInRegion.sortedByNewest(list: datesArray)
XCTSameDateArray([date5, date6, date3, date2, date4, date1], orderedByNewest)
// Order by oldest
let orderedByOldest = DateInRegion.sortedByOldest(list: datesArray)
XCTSameDateArray([date1, date4, date2, date3, date6, date5], orderedByOldest)
}
@discardableResult
func XCTSameDateArray(_ left: [DateInRegion], _ right: [DateInRegion]) -> Bool {
guard left.count == right.count else { return false }
// swiftlint:disable for_where
for idx in 0..<left.count {
if left[idx] != right[idx] {
XCTFail("At index \(idx). Expected date = {\(left[idx].date)}, got = {\(right[idx].date)}")
return false
}
}
return true
}
func testDateInRegion_DateForWeekdays() {
func validateArrayOfISODates(_ found: [String], _ expected: [String]) {
guard found.count == expected.count else {
XCTFail("Failed to validate array of dates. Different in number.")
return
}
for i in 0..<expected.count {
guard found[i] == expected[i] else {
XCTFail("Failed to validate item '\(i)'. Found '\(found[i])', expecting '\(expected[i])'")
return
}
}
}
let mondaysInJan2019 = DateInRegion.datesForWeekday(.monday, inMonth: 1, ofYear: 2019, region: Region.UTC).map { $0.toISO() }
validateArrayOfISODates(mondaysInJan2019, [
"2019-01-07T00:00:00Z",
"2019-01-14T00:00:00Z",
"2019-01-21T00:00:00Z",
"2019-01-28T00:00:00Z"
])
let fromDate = DateInRegion(year: 2019, month: 5, day: 27, hour: 0, minute: 0)
let toDate = DateInRegion(year: 2019, month: 6, day: 8, hour: 0, minute: 0)
let fridaysInJunePartial = DateInRegion.datesForWeekday(.friday, from: fromDate, to: toDate, region: Region.UTC).map {
$0.toISO()
}
validateArrayOfISODates(fridaysInJunePartial, [
"2019-05-31T00:00:00Z",
"2019-06-07T00:00:00Z"
])
}
func testDateInRegion_DateAtStartOf() {
let regionRome = Region(calendar: Calendars.gregorian, zone: Zones.europeRome, locale: Locales.italian)
let currentDate = DateInRegion(Date(), region: regionRome)
let startOfDay1 = currentDate.dateAt(.startOfDay).date
let startOfDay2 = currentDate.dateAtStartOf(.day).date
XCTAssert( startOfDay1 == startOfDay2, "dateAt(.startOfDay), dateAtStartOf(.day) are not same.")
let startOfWeek1 = currentDate.dateAt(.startOfWeek).date
let startOfWeek2 = currentDate.dateAtStartOf(.weekOfYear).date
XCTAssert( startOfWeek1 == startOfWeek2, "dateAt(.startOfWeek), dateAtStartOf(.weekday) are not same.")
let startOfMonth1 = currentDate.dateAt(.startOfMonth).date
let startOfMonth2 = currentDate.dateAtStartOf(.month).date
XCTAssert( startOfMonth1 == startOfMonth2, "dateAt(.startOfMonth), dateAtStartOf(.month) are not same.")
}
}