mirror of
https://github.com/jimeh/go-tyme.git
synced 2026-02-19 09:56:42 +00:00
feat(tyme/ts): add ts package
This commit is contained in:
524
ts/ts_test.go
Normal file
524
ts/ts_test.go
Normal file
@@ -0,0 +1,524 @@
|
||||
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)
|
||||
})
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user