Skip to content

Commit 698058b

Browse files
committed
Add tests for TimeDuration.
1 parent 00fed1c commit 698058b

File tree

2 files changed

+243
-2
lines changed

2 files changed

+243
-2
lines changed

authority/provisioner/timeduration.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import (
77
"github.com/pkg/errors"
88
)
99

10+
var now = func() time.Time {
11+
return time.Now().UTC()
12+
}
13+
1014
// TimeDuration is a type that represents a time but the JSON unmarshaling can
1115
// use a time using the RFC 3339 format or a time.Duration string. If a duration
1216
// is used, the time will be set on the first call to TimeDuration.Time.
@@ -25,7 +29,7 @@ func ParseTimeDuration(s string) (TimeDuration, error) {
2529
// Try to use the unquoted RFC 3339 format
2630
var t time.Time
2731
if err := t.UnmarshalText([]byte(s)); err == nil {
28-
return TimeDuration{t: t}, nil
32+
return TimeDuration{t: t.UTC()}, nil
2933
}
3034

3135
// Try to use the time.Duration string format
@@ -101,9 +105,17 @@ func (t *TimeDuration) Time() time.Time {
101105
case t == nil:
102106
return time.Time{}
103107
case t.t.IsZero():
104-
t.t = time.Now().UTC().Add(t.d)
108+
if t.d == 0 {
109+
return time.Time{}
110+
}
111+
t.t = now().Add(t.d)
105112
return t.t
106113
default:
107114
return t.t
108115
}
109116
}
117+
118+
// String implements the fmt.Stringer interface.
119+
func (t *TimeDuration) String() string {
120+
return t.Time().String()
121+
}
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
package provisioner
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
"time"
7+
)
8+
9+
func TestParseTimeDuration(t *testing.T) {
10+
type args struct {
11+
s string
12+
}
13+
tests := []struct {
14+
name string
15+
args args
16+
want TimeDuration
17+
wantErr bool
18+
}{
19+
{"timestamp", args{"2020-03-14T15:09:26.535897Z"}, TimeDuration{t: time.Unix(1584198566, 535897000).UTC()}, false},
20+
{"timestamp", args{"2020-03-14T15:09:26Z"}, TimeDuration{t: time.Unix(1584198566, 0).UTC()}, false},
21+
{"timestamp", args{"2020-03-14T15:09:26.535897-07:00"}, TimeDuration{t: time.Unix(1584223766, 535897000).UTC()}, false},
22+
{"timestamp", args{"2020-03-14T15:09:26-07:00"}, TimeDuration{t: time.Unix(1584223766, 0).UTC()}, false},
23+
{"timestamp", args{"2020-03-14T15:09:26.535897+07:00"}, TimeDuration{t: time.Unix(1584173366, 535897000).UTC()}, false},
24+
{"timestamp", args{"2020-03-14T15:09:26+07:00"}, TimeDuration{t: time.Unix(1584173366, 0).UTC()}, false},
25+
{"1h", args{"1h"}, TimeDuration{d: 1 * time.Hour}, false},
26+
{"-24h60m60s", args{"-24h60m60s"}, TimeDuration{d: -24*time.Hour - 60*time.Minute - 60*time.Second}, false},
27+
{"0", args{"0"}, TimeDuration{}, false},
28+
{"empty", args{""}, TimeDuration{}, false},
29+
{"fail", args{"2020-03-14T15:09:26Z07:00"}, TimeDuration{}, true},
30+
{"fail", args{"1d"}, TimeDuration{}, true},
31+
}
32+
for _, tt := range tests {
33+
t.Run(tt.name, func(t *testing.T) {
34+
got, err := ParseTimeDuration(tt.args.s)
35+
if (err != nil) != tt.wantErr {
36+
t.Errorf("ParseTimeDuration() error = %v, wantErr %v", err, tt.wantErr)
37+
return
38+
}
39+
if !reflect.DeepEqual(got, tt.want) {
40+
t.Errorf("ParseTimeDuration() = %v, want %v", got, tt.want)
41+
}
42+
})
43+
}
44+
}
45+
46+
func TestTimeDuration_SetDuration(t *testing.T) {
47+
type fields struct {
48+
t time.Time
49+
d time.Duration
50+
}
51+
type args struct {
52+
d time.Duration
53+
}
54+
tests := []struct {
55+
name string
56+
fields fields
57+
args args
58+
want *TimeDuration
59+
}{
60+
{"new", fields{}, args{2 * time.Hour}, &TimeDuration{d: 2 * time.Hour}},
61+
{"old", fields{time.Now(), 1 * time.Hour}, args{2 * time.Hour}, &TimeDuration{d: 2 * time.Hour}},
62+
}
63+
for _, tt := range tests {
64+
t.Run(tt.name, func(t *testing.T) {
65+
td := &TimeDuration{
66+
t: tt.fields.t,
67+
d: tt.fields.d,
68+
}
69+
td.SetDuration(tt.args.d)
70+
if !reflect.DeepEqual(td, tt.want) {
71+
t.Errorf("SetDuration() = %v, want %v", td, tt.want)
72+
}
73+
})
74+
}
75+
}
76+
77+
func TestTimeDuration_SetTime(t *testing.T) {
78+
tm := time.Unix(1584198566, 535897000).UTC()
79+
80+
type fields struct {
81+
t time.Time
82+
d time.Duration
83+
}
84+
type args struct {
85+
tt time.Time
86+
}
87+
tests := []struct {
88+
name string
89+
fields fields
90+
args args
91+
want *TimeDuration
92+
}{
93+
{"new", fields{}, args{tm}, &TimeDuration{t: tm}},
94+
{"old", fields{time.Now(), 1 * time.Hour}, args{tm}, &TimeDuration{t: tm}},
95+
}
96+
for _, tt := range tests {
97+
t.Run(tt.name, func(t *testing.T) {
98+
td := &TimeDuration{
99+
t: tt.fields.t,
100+
d: tt.fields.d,
101+
}
102+
td.SetTime(tt.args.tt)
103+
if !reflect.DeepEqual(td, tt.want) {
104+
t.Errorf("SetTime() = %v, want %v", td, tt.want)
105+
}
106+
})
107+
}
108+
}
109+
110+
func TestTimeDuration_MarshalJSON(t *testing.T) {
111+
tm := time.Unix(1584198566, 535897000).UTC()
112+
tests := []struct {
113+
name string
114+
timeDuration *TimeDuration
115+
want []byte
116+
wantErr bool
117+
}{
118+
{"null", nil, []byte("null"), false},
119+
{"null", &TimeDuration{}, []byte("null"), false},
120+
{"timestamp", &TimeDuration{t: tm}, []byte(`"2020-03-14T15:09:26.535897Z"`), false},
121+
{"duration", &TimeDuration{d: 1 * time.Hour}, []byte(`"1h0m0s"`), false},
122+
{"fail", &TimeDuration{t: time.Date(-1, 0, 0, 0, 0, 0, 0, time.UTC)}, nil, true},
123+
}
124+
for _, tt := range tests {
125+
t.Run(tt.name, func(t *testing.T) {
126+
got, err := tt.timeDuration.MarshalJSON()
127+
if (err != nil) != tt.wantErr {
128+
t.Errorf("TimeDuration.MarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
129+
return
130+
}
131+
if !reflect.DeepEqual(got, tt.want) {
132+
t.Errorf("TimeDuration.MarshalJSON() = %s, want %s", got, tt.want)
133+
}
134+
})
135+
}
136+
}
137+
138+
func TestTimeDuration_UnmarshalJSON(t *testing.T) {
139+
type args struct {
140+
data []byte
141+
}
142+
tests := []struct {
143+
name string
144+
args args
145+
want *TimeDuration
146+
wantErr bool
147+
}{
148+
{"null", args{[]byte("null")}, &TimeDuration{}, false},
149+
{"timestamp", args{[]byte(`"2020-03-14T15:09:26.535897Z"`)}, &TimeDuration{t: time.Unix(1584198566, 535897000).UTC()}, false},
150+
{"duration", args{[]byte(`"1h"`)}, &TimeDuration{d: time.Hour}, false},
151+
{"fail", args{[]byte("123")}, &TimeDuration{}, true},
152+
{"fail", args{[]byte(`"2020-03-14T15:09:26.535897Z07:00"`)}, &TimeDuration{}, true},
153+
}
154+
for _, tt := range tests {
155+
t.Run(tt.name, func(t *testing.T) {
156+
td := &TimeDuration{}
157+
if err := td.UnmarshalJSON(tt.args.data); (err != nil) != tt.wantErr {
158+
t.Errorf("TimeDuration.UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
159+
}
160+
if !reflect.DeepEqual(td, tt.want) {
161+
t.Errorf("TimeDuration.UnmarshalJSON() = %s, want %s", td, tt.want)
162+
}
163+
})
164+
}
165+
}
166+
167+
func TestTimeDuration_Time(t *testing.T) {
168+
nowFn := now
169+
defer func() {
170+
now = nowFn
171+
now()
172+
}()
173+
tm := time.Unix(1584198566, 535897000).UTC()
174+
now = func() time.Time {
175+
return tm
176+
}
177+
tests := []struct {
178+
name string
179+
timeDuration *TimeDuration
180+
want time.Time
181+
}{
182+
{"zero", nil, time.Time{}},
183+
{"zero", &TimeDuration{}, time.Time{}},
184+
{"timestamp", &TimeDuration{t: tm}, tm},
185+
{"duration", &TimeDuration{d: 1 * time.Hour}, tm.Add(1 * time.Hour)},
186+
}
187+
for _, tt := range tests {
188+
t.Run(tt.name, func(t *testing.T) {
189+
got := tt.timeDuration.Time()
190+
if !reflect.DeepEqual(got, tt.want) {
191+
t.Errorf("TimeDuration.Time() = %v, want %v", got, tt.want)
192+
193+
}
194+
})
195+
}
196+
}
197+
198+
func TestTimeDuration_String(t *testing.T) {
199+
nowFn := now
200+
defer func() {
201+
now = nowFn
202+
now()
203+
}()
204+
tm := time.Unix(1584198566, 535897000).UTC()
205+
now = func() time.Time {
206+
return tm
207+
}
208+
type fields struct {
209+
t time.Time
210+
d time.Duration
211+
}
212+
tests := []struct {
213+
name string
214+
timeDuration *TimeDuration
215+
want string
216+
}{
217+
{"zero", nil, "0001-01-01 00:00:00 +0000 UTC"},
218+
{"zero", &TimeDuration{}, "0001-01-01 00:00:00 +0000 UTC"},
219+
{"timestamp", &TimeDuration{t: tm}, "2020-03-14 15:09:26.535897 +0000 UTC"},
220+
{"duration", &TimeDuration{d: 1 * time.Hour}, "2020-03-14 16:09:26.535897 +0000 UTC"},
221+
}
222+
for _, tt := range tests {
223+
t.Run(tt.name, func(t *testing.T) {
224+
if got := tt.timeDuration.String(); got != tt.want {
225+
t.Errorf("TimeDuration.String() = %v, want %v", got, tt.want)
226+
}
227+
})
228+
}
229+
}

0 commit comments

Comments
 (0)