Files
go-tyme/ts/ts_test.go

525 lines
12 KiB
Go

package ts
import (
"fmt"
"testing"
"time"
"github.com/jimeh/go-tyme/dur"
"github.com/stretchr/testify/assert"
)
func TestAdd(t *testing.T) {
testAdd[time.Time, time.Duration](t)
testAdd[time.Time, dur.Duration](t)
testAdd[Second, time.Duration](t)
testAdd[Second, dur.Duration](t)
testAdd[Millisecond, time.Duration](t)
testAdd[Millisecond, dur.Duration](t)
testAdd[Microsecond, time.Duration](t)
testAdd[Microsecond, dur.Duration](t)
testAdd[Nanosecond, time.Duration](t)
testAdd[Nanosecond, dur.Duration](t)
}
func testAdd[T Timestamp, D Duration](t *testing.T) {
t.Run(
fmt.Sprintf("[T %T, D %T]", T(time.Time{}), D(0)),
func(t *testing.T) {
tests := []struct {
name string
t T
d D
want T
}{
{
name: "add 1s",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC),
),
d: D(time.Second),
want: T(
time.Date(2020, 1, 1, 0, 0, 3, 0, time.UTC),
),
},
{
name: "remove 1s",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC),
),
d: D(-time.Second),
want: T(
time.Date(2020, 1, 1, 0, 0, 1, 0, time.UTC),
),
},
{
name: "add 250ms",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC),
),
d: D(250 * time.Millisecond),
want: T(
time.Date(2020, 1, 1, 0, 0, 2, 250000000, time.UTC),
),
},
{
name: "remove 250ms",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC),
),
d: D(-250 * time.Millisecond),
want: T(
time.Date(2020, 1, 1, 0, 0, 1, 750000000, time.UTC),
),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Add(tt.t, tt.d)
assert.Equal(t, tt.want, got)
})
}
},
)
}
func TestSub(t *testing.T) {
testSub[time.Time, time.Time](t)
testSub[time.Time, Second](t)
testSub[time.Time, Millisecond](t)
testSub[time.Time, Microsecond](t)
testSub[time.Time, Nanosecond](t)
testSub[Second, time.Time](t)
testSub[Second, Second](t)
testSub[Second, Millisecond](t)
testSub[Second, Microsecond](t)
testSub[Second, Nanosecond](t)
testSub[Millisecond, time.Time](t)
testSub[Millisecond, Millisecond](t)
testSub[Millisecond, Second](t)
testSub[Millisecond, Microsecond](t)
testSub[Millisecond, Nanosecond](t)
testSub[Microsecond, time.Time](t)
testSub[Microsecond, Second](t)
testSub[Microsecond, Millisecond](t)
testSub[Microsecond, Microsecond](t)
testSub[Microsecond, Nanosecond](t)
testSub[Nanosecond, time.Time](t)
testSub[Nanosecond, Second](t)
testSub[Nanosecond, Millisecond](t)
testSub[Nanosecond, Microsecond](t)
testSub[Nanosecond, Nanosecond](t)
}
func testSub[T, U Timestamp](t *testing.T) {
t.Run(
fmt.Sprintf("[T %T, U %T]", T(time.Time{}), U(time.Time{})),
func(t *testing.T) {
now := time.Now()
tests := []struct {
name string
t T
u U
want time.Duration
}{
{
name: "-1s",
t: T(now),
u: U(now.Add(time.Second)),
want: -time.Second,
},
{
name: "1s",
t: T(now),
u: U(now.Add(-time.Second)),
want: time.Second,
},
{
name: "-250ms",
t: T(now),
u: U(now.Add(250 * time.Millisecond)),
want: -250 * time.Millisecond,
},
{
name: "250ms",
t: T(now),
u: U(now.Add(-250 * time.Millisecond)),
want: 250 * time.Millisecond,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Sub(tt.t, tt.u)
assert.Equal(t, tt.want, time.Duration(got))
})
}
t1 := T(now)
u1 := U(now.Add(-time.Second))
got1 := Sub(t1, u1)
assert.Equal(t, time.Second, time.Duration(got1))
t2 := T(now)
u2 := U(now.Add(time.Second))
got2 := Sub(t2, u2)
assert.Equal(t, -time.Second, time.Duration(got2))
},
)
}
func TestAfter(t *testing.T) {
testAfter[time.Time, time.Time](t)
testAfter[time.Time, Second](t)
testAfter[time.Time, Millisecond](t)
testAfter[time.Time, Microsecond](t)
testAfter[time.Time, Nanosecond](t)
testAfter[Second, time.Time](t)
testAfter[Second, Second](t)
testAfter[Second, Millisecond](t)
testAfter[Second, Microsecond](t)
testAfter[Second, Nanosecond](t)
testAfter[Millisecond, time.Time](t)
testAfter[Millisecond, Millisecond](t)
testAfter[Millisecond, Second](t)
testAfter[Millisecond, Microsecond](t)
testAfter[Millisecond, Nanosecond](t)
testAfter[Microsecond, time.Time](t)
testAfter[Microsecond, Second](t)
testAfter[Microsecond, Millisecond](t)
testAfter[Microsecond, Microsecond](t)
testAfter[Microsecond, Nanosecond](t)
testAfter[Nanosecond, time.Time](t)
testAfter[Nanosecond, Second](t)
testAfter[Nanosecond, Millisecond](t)
testAfter[Nanosecond, Microsecond](t)
testAfter[Nanosecond, Nanosecond](t)
}
func testAfter[T, u Timestamp](t *testing.T) {
t.Run(
fmt.Sprintf("[T %T, U %T]", T(time.Time{}), u(time.Time{})),
func(t *testing.T) {
t1 := T(time.Now())
o1 := u(time.Now().Add(-time.Second))
got1 := After(t1, o1)
assert.True(t, got1)
t2 := T(time.Now())
o2 := u(time.Now().Add(time.Second))
got2 := After(t2, o2)
assert.False(t, got2)
},
)
}
func TestBefore(t *testing.T) {
testBefore[time.Time, time.Time](t)
testBefore[time.Time, Second](t)
testBefore[time.Time, Millisecond](t)
testBefore[time.Time, Microsecond](t)
testBefore[time.Time, Nanosecond](t)
testBefore[Second, time.Time](t)
testBefore[Second, Second](t)
testBefore[Second, Millisecond](t)
testBefore[Second, Microsecond](t)
testBefore[Second, Nanosecond](t)
testBefore[Millisecond, time.Time](t)
testBefore[Millisecond, Millisecond](t)
testBefore[Millisecond, Second](t)
testBefore[Millisecond, Microsecond](t)
testBefore[Millisecond, Nanosecond](t)
testBefore[Microsecond, time.Time](t)
testBefore[Microsecond, Second](t)
testBefore[Microsecond, Millisecond](t)
testBefore[Microsecond, Microsecond](t)
testBefore[Microsecond, Nanosecond](t)
testBefore[Nanosecond, time.Time](t)
testBefore[Nanosecond, Second](t)
testBefore[Nanosecond, Millisecond](t)
testBefore[Nanosecond, Microsecond](t)
testBefore[Nanosecond, Nanosecond](t)
}
func testBefore[T, U Timestamp](t *testing.T) {
t.Run(
fmt.Sprintf("[T %T, U %T]", T(time.Time{}), U(time.Time{})),
func(t *testing.T) {
t1 := T(time.Now())
o1 := U(time.Now().Add(-time.Second))
got1 := Before(t1, o1)
assert.False(t, got1)
t2 := T(time.Now())
o2 := U(time.Now().Add(time.Second))
got2 := Before(t2, o2)
assert.True(t, got2)
},
)
}
func TestEqual(t *testing.T) {
testEqual[time.Time, time.Time](t)
testEqual[time.Time, Second](t)
testEqual[time.Time, Millisecond](t)
testEqual[time.Time, Microsecond](t)
testEqual[time.Time, Nanosecond](t)
testEqual[Second, time.Time](t)
testEqual[Second, Second](t)
testEqual[Second, Millisecond](t)
testEqual[Second, Microsecond](t)
testEqual[Second, Nanosecond](t)
testEqual[Millisecond, time.Time](t)
testEqual[Millisecond, Millisecond](t)
testEqual[Millisecond, Second](t)
testEqual[Millisecond, Microsecond](t)
testEqual[Millisecond, Nanosecond](t)
testEqual[Microsecond, time.Time](t)
testEqual[Microsecond, Second](t)
testEqual[Microsecond, Millisecond](t)
testEqual[Microsecond, Microsecond](t)
testEqual[Microsecond, Nanosecond](t)
testEqual[Nanosecond, time.Time](t)
testEqual[Nanosecond, Second](t)
testEqual[Nanosecond, Millisecond](t)
testEqual[Nanosecond, Microsecond](t)
testEqual[Nanosecond, Nanosecond](t)
}
func testEqual[T, U Timestamp](t *testing.T) {
t.Run(
fmt.Sprintf("[T %T, U %T]", T(time.Time{}), U(time.Time{})),
func(t *testing.T) {
t1 := T(time.Now())
o1 := U(t1)
got1 := Equal(t1, o1)
assert.True(t, got1)
t2 := T(time.Now())
o2 := U(time.Now().Add(time.Second))
got2 := Equal(t2, o2)
assert.False(t, got2)
},
)
}
func TestRound(t *testing.T) {
testRound[time.Time, time.Duration](t)
testRound[time.Time, dur.Duration](t)
testRound[Second, time.Duration](t)
testRound[Second, dur.Duration](t)
testRound[Millisecond, time.Duration](t)
testRound[Millisecond, dur.Duration](t)
testRound[Microsecond, time.Duration](t)
testRound[Microsecond, dur.Duration](t)
testRound[Nanosecond, time.Duration](t)
testRound[Nanosecond, dur.Duration](t)
}
func testRound[T Timestamp, D Duration](t *testing.T) {
t.Run(
fmt.Sprintf("[T %T, D %T]", T(time.Time{}), D(0)),
func(t *testing.T) {
tests := []struct {
name string
t T
d D
want T
}{
{
name: "round up to nearest hour",
t: T(
time.Date(2020, 1, 1, 0, 30, 0, 0, time.UTC),
),
d: D(time.Hour),
want: T(time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC)),
},
{
name: "round down to nearest hour",
t: T(
time.Date(2020, 1, 1, 0, 29, 0, 0, time.UTC),
),
d: D(time.Hour),
want: T(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
},
{
name: "round up to nearest minute",
t: T(
time.Date(2020, 1, 1, 0, 0, 30, 0, time.UTC),
),
d: D(time.Minute),
want: T(time.Date(2020, 1, 1, 0, 1, 0, 0, time.UTC)),
},
{
name: "round down to nearest minute",
t: T(
time.Date(2020, 1, 1, 0, 0, 29, 0, time.UTC),
),
d: D(time.Minute),
want: T(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
},
{
name: "round up to nearest second",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 500000000, time.UTC),
),
d: D(time.Second),
want: T(time.Date(2020, 1, 1, 0, 0, 3, 0, time.UTC)),
},
{
name: "round down to nearest second",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 499999999, time.UTC),
),
d: D(time.Second),
want: T(time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC)),
},
{
name: "round up to nearest millisecond",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 500000, time.UTC),
),
d: D(time.Millisecond),
want: T(time.Date(2020, 1, 1, 0, 0, 2, 1000000, time.UTC)),
},
{
name: "round down to nearest millisecond",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 499999, time.UTC),
),
d: D(time.Millisecond),
want: T(time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC)),
},
{
name: "round up to nearest microsecond",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 500, time.UTC),
),
d: D(time.Microsecond),
want: T(time.Date(2020, 1, 1, 0, 0, 2, 1000, time.UTC)),
},
{
name: "round down to nearest microsecond",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 499, time.UTC),
),
d: D(time.Microsecond),
want: T(time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC)),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Round(tt.t, tt.d)
assert.Equal(t, tt.want, got)
})
}
},
)
}
func TestTruncate(t *testing.T) {
testTruncate[time.Time, time.Duration](t)
testTruncate[time.Time, dur.Duration](t)
testTruncate[Second, time.Duration](t)
testTruncate[Second, dur.Duration](t)
testTruncate[Millisecond, time.Duration](t)
testTruncate[Millisecond, dur.Duration](t)
testTruncate[Microsecond, time.Duration](t)
testTruncate[Microsecond, dur.Duration](t)
testTruncate[Nanosecond, time.Duration](t)
testTruncate[Nanosecond, dur.Duration](t)
}
func testTruncate[T Timestamp, D Duration](t *testing.T) {
t.Run(
fmt.Sprintf("[T %T, D %T]", T(time.Time{}), D(0)),
func(t *testing.T) {
tests := []struct {
name string
t T
d D
want T
}{
{
name: "truncate down to nearest hour",
t: T(
time.Date(2020, 1, 1, 0, 29, 0, 0, time.UTC),
),
d: D(time.Hour),
want: T(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
},
{
name: "truncate down to nearest minute",
t: T(
time.Date(2020, 1, 1, 0, 0, 29, 0, time.UTC),
),
d: D(time.Minute),
want: T(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
},
{
name: "truncate down to nearest second",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 499999999, time.UTC),
),
d: D(time.Second),
want: T(time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC)),
},
{
name: "truncate down to nearest millisecond",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 499999, time.UTC),
),
d: D(time.Millisecond),
want: T(time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC)),
},
{
name: "truncate down to nearest microsecond",
t: T(
time.Date(2020, 1, 1, 0, 0, 2, 499, time.UTC),
),
d: D(time.Microsecond),
want: T(time.Date(2020, 1, 1, 0, 0, 2, 0, time.UTC)),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Truncate(tt.t, tt.d)
assert.Equal(t, tt.want, got)
})
}
},
)
}