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
|
package xyz.driver.core
import java.util.TimeZone
import org.scalacheck.Arbitrary._
import org.scalacheck.Prop.BooleanOperators
import org.scalacheck.{Arbitrary, Gen}
import org.scalatest.prop.Checkers
import org.scalatest.{FlatSpec, Matchers}
import xyz.driver.core.time.{Time, _}
import scala.concurrent.duration._
class TimeTest extends FlatSpec with Matchers with Checkers {
implicit val arbitraryDuration = Arbitrary[Duration](Gen.chooseNum(0L, 9999999999L).map(_.milliseconds))
implicit val arbitraryTime = Arbitrary[Time](Gen.chooseNum(0L, 9999999999L).map(millis => Time(millis)))
"Time" should "have correct methods to compare" in {
Time(234L).isAfter(Time(123L)) should be(true)
Time(123L).isAfter(Time(123L)) should be(false)
Time(123L).isAfter(Time(234L)) should be(false)
check((a: Time, b: Time) => (a.millis > b.millis) ==> a.isAfter(b))
Time(234L).isBefore(Time(123L)) should be(false)
Time(123L).isBefore(Time(123L)) should be(false)
Time(123L).isBefore(Time(234L)) should be(true)
check { (a: Time, b: Time) =>
(a.millis < b.millis) ==> a.isBefore(b)
}
}
it should "not modify time" in {
Time(234L).millis should be(234L)
check { millis: Long =>
Time(millis).millis == millis
}
}
it should "support arithmetic with scala.concurrent.duration" in {
Time(123L).advanceBy(0 minutes).millis should be(123L)
Time(123L).advanceBy(1 second).millis should be(123L + Second)
Time(123L).advanceBy(4 days).millis should be(123L + 4 * Days)
check { (time: Time, duration: Duration) =>
time.advanceBy(duration).millis == (time.millis + duration.toMillis)
}
}
it should "have ordering defined correctly" in {
Seq(Time(321L), Time(123L), Time(231L)).sorted should
contain theSameElementsInOrderAs Seq(Time(123L), Time(231L), Time(321L))
check { times: List[Time] =>
times.sorted.sliding(2).filter(_.size == 2).forall {
case Seq(a, b) =>
a.millis <= b.millis
}
}
}
it should "reset to the start of the period, e.g. month" in {
startOfMonth(Time(1468937089834L)) should be(Time(1467381889834L))
startOfMonth(Time(1467381889834L)) should be(Time(1467381889834L)) // idempotent
}
it should "have correct textual representations" in {
textualDate(TimeZone.getTimeZone("EDT"))(Time(1468937089834L)) should be("July 19, 2016")
textualTime(TimeZone.getTimeZone("PDT"))(Time(1468937089834L)) should be("Jul 19, 2016 02:04:49 PM")
}
"TimeRange" should "have duration defined as a difference of start and end times" in {
TimeRange(Time(321L), Time(432L)).duration should be(111.milliseconds)
TimeRange(Time(432L), Time(321L)).duration should be((-111).milliseconds)
TimeRange(Time(333L), Time(333L)).duration should be(0.milliseconds)
}
"Time" should "use TimeZone correctly when converting to Date" in {
val EST = java.util.TimeZone.getTimeZone("EST")
val PST = java.util.TimeZone.getTimeZone("PST")
val timestamp = {
import java.util.Calendar
val cal = Calendar.getInstance(EST)
cal.set(Calendar.HOUR_OF_DAY, 1)
Time(cal.getTime().getTime())
}
textualDate(EST)(timestamp) should not be textualDate(PST)(timestamp)
timestamp.toDate(EST) should not be timestamp.toDate(PST)
}
}
|