1 package duration
2
3 import (
4 "encoding/json"
5 "reflect"
6 "testing"
7 "time"
8 )
9
10 func TestParse(t *testing.T) {
11 type args struct {
12 d string
13 }
14 tests := []struct {
15 name string
16 args args
17 want *Duration
18 wantErr bool
19 }{
20 {
21 name: "period-only",
22 args: args{d: "P4Y"},
23 want: &Duration{
24 Years: 4,
25 },
26 wantErr: false,
27 },
28 {
29 name: "time-only-decimal",
30 args: args{d: "T2.5S"},
31 want: &Duration{
32 Seconds: 2.5,
33 },
34 wantErr: false,
35 },
36 {
37 name: "full",
38 args: args{d: "P3Y6M4DT12H30M5.5S"},
39 want: &Duration{
40 Years: 3,
41 Months: 6,
42 Days: 4,
43 Hours: 12,
44 Minutes: 30,
45 Seconds: 5.5,
46 },
47 wantErr: false,
48 },
49 {
50 name: "negative",
51 args: args{d: "-PT5M"},
52 want: &Duration{
53 Minutes: 5,
54 Negative: true,
55 },
56 wantErr: false,
57 },
58 }
59 for _, tt := range tests {
60 t.Run(tt.name, func(t *testing.T) {
61 got, err := Parse(tt.args.d)
62 if (err != nil) != tt.wantErr {
63 t.Errorf("Parse() error = %v, wantErr %v", err, tt.wantErr)
64 return
65 }
66 if !reflect.DeepEqual(got, tt.want) {
67 t.Errorf("Parse() got = %v, want %v", got, tt.want)
68 }
69 })
70 }
71 }
72
73 func TestFromTimeDuration(t *testing.T) {
74 tests := []struct {
75 give time.Duration
76 want *Duration
77 }{
78 {
79 give: 0,
80 want: &Duration{},
81 },
82 {
83 give: time.Minute * 94,
84 want: &Duration{
85 Hours: 1,
86 Minutes: 34,
87 },
88 },
89 {
90 give: -time.Second * 10,
91 want: &Duration{
92 Seconds: 10,
93 Negative: true,
94 },
95 },
96 }
97 for _, tt := range tests {
98 t.Run(tt.give.String(), func(t *testing.T) {
99 got := FromTimeDuration(tt.give)
100 if !reflect.DeepEqual(got, tt.want) {
101 t.Errorf("Format() got = %s, want %s", got, tt.want)
102 }
103 })
104 }
105 }
106
107 func TestFormat(t *testing.T) {
108 tests := []struct {
109 give time.Duration
110 want string
111 }{
112 {
113 give: 0,
114 want: "PT0S",
115 },
116 {
117 give: time.Minute * 94,
118 want: "PT1H34M",
119 },
120 {
121 give: time.Hour * 72,
122 want: "P3D",
123 },
124 {
125 give: time.Hour * 26,
126 want: "P1DT2H",
127 },
128 {
129 give: time.Second * 465461651,
130 want: "P14Y9M3DT12H54M11S",
131 },
132 {
133 give: -time.Hour * 99544,
134 want: "-P11Y4M1W4D",
135 },
136 {
137 give: -time.Second * 10,
138 want: "-PT10S",
139 },
140 }
141 for _, tt := range tests {
142 t.Run(tt.want, func(t *testing.T) {
143 got := Format(tt.give)
144 if !reflect.DeepEqual(got, tt.want) {
145 t.Errorf("Format() got = %s, want %s", got, tt.want)
146 }
147 })
148 }
149 }
150
151 func TestDuration_ToTimeDuration(t *testing.T) {
152 type fields struct {
153 Years float64
154 Months float64
155 Weeks float64
156 Days float64
157 Hours float64
158 Minutes float64
159 Seconds float64
160 Negative bool
161 }
162 tests := []struct {
163 name string
164 fields fields
165 want time.Duration
166 }{
167 {
168 name: "seconds",
169 fields: fields{
170 Seconds: 33.3,
171 },
172 want: time.Second*33 + time.Millisecond*300,
173 },
174 {
175 name: "hours, minutes, and seconds",
176 fields: fields{
177 Hours: 2,
178 Minutes: 33,
179 Seconds: 17,
180 },
181 want: time.Hour*2 + time.Minute*33 + time.Second*17,
182 },
183 {
184 name: "days",
185 fields: fields{
186 Days: 2,
187 },
188 want: time.Hour * 24 * 2,
189 },
190 {
191 name: "weeks",
192 fields: fields{
193 Weeks: 1,
194 },
195 want: time.Hour * 24 * 7,
196 },
197 {
198 name: "fractional weeks",
199 fields: fields{
200 Weeks: 12.5,
201 },
202 want: time.Hour*24*7*12 + time.Hour*84,
203 },
204 {
205 name: "negative",
206 fields: fields{
207 Hours: 2,
208 Negative: true,
209 },
210 want: -time.Hour * 2,
211 },
212 }
213 for _, tt := range tests {
214 t.Run(tt.name, func(t *testing.T) {
215 duration := &Duration{
216 Years: tt.fields.Years,
217 Months: tt.fields.Months,
218 Weeks: tt.fields.Weeks,
219 Days: tt.fields.Days,
220 Hours: tt.fields.Hours,
221 Minutes: tt.fields.Minutes,
222 Seconds: tt.fields.Seconds,
223 Negative: tt.fields.Negative,
224 }
225 if got := duration.ToTimeDuration(); got != tt.want {
226 t.Errorf("ToTimeDuration() = %v, want %v", got, tt.want)
227 }
228 })
229 }
230 }
231
232 func TestDuration_String(t *testing.T) {
233 duration, err := Parse("P3Y6M4DT12H30M5.5S")
234 if err != nil {
235 t.Fatal(err)
236 }
237
238 if duration.String() != "P3Y6M4DT12H30M5.5S" {
239 t.Errorf("expected: %s, got: %s", "P3Y6M4DT12H30M5.5S", duration.String())
240 }
241
242 duration.Seconds = 33.3333
243
244 if duration.String() != "P3Y6M4DT12H30M33.3333S" {
245 t.Errorf("expected: %s, got: %s", "P3Y6M4DT12H30M33.3333S", duration.String())
246 }
247
248 smallDuration, err := Parse("T0.0000000000001S")
249 if err != nil {
250 t.Fatal(err)
251 }
252
253 if smallDuration.String() != "PT0.0000000000001S" {
254 t.Errorf("expected: %s, got: %s", "PT0.0000000000001S", smallDuration.String())
255 }
256
257 negativeDuration, err := Parse("-PT2H5M")
258 if err != nil {
259 t.Fatal(err)
260 }
261
262 if negativeDuration.String() != "-PT2H5M" {
263 t.Errorf("expected: %s, got: %s", "-PT2H5M", negativeDuration.String())
264 }
265 }
266
267 func TestDuration_MarshalJSON(t *testing.T) {
268 td, err := Parse("P3Y6M4DT12H30M5.5S")
269 if err != nil {
270 t.Fatal(err)
271 }
272
273 jsonVal, err := json.Marshal(struct {
274 Dur *Duration `json:"d"`
275 }{Dur: td})
276 if err != nil {
277 t.Errorf("did not expect error: %s", err.Error())
278 }
279 if string(jsonVal) != `{"d":"P3Y6M4DT12H30M5.5S"}` {
280 t.Errorf("expected: %s, got: %s", `{"d":"P3Y6M4DT12H30M5.5S"}`, string(jsonVal))
281 }
282
283 jsonVal, err = json.Marshal(struct {
284 Dur Duration `json:"d"`
285 }{Dur: *td})
286 if err != nil {
287 t.Errorf("did not expect error: %s", err.Error())
288 }
289 if string(jsonVal) != `{"d":"P3Y6M4DT12H30M5.5S"}` {
290 t.Errorf("expected: %s, got: %s", `{"d":"P3Y6M4DT12H30M5.5S"}`, string(jsonVal))
291 }
292 }
293
294 func TestDuration_UnmarshalJSON(t *testing.T) {
295 jsonStr := `
296 {
297 "d": "P3Y6M4DT12H30M5.5S"
298 }
299 `
300 expected, err := Parse("P3Y6M4DT12H30M5.5S")
301 if err != nil {
302 t.Fatal(err)
303 }
304
305 var durStructPtr struct {
306 Dur *Duration `json:"d"`
307 }
308 err = json.Unmarshal([]byte(jsonStr), &durStructPtr)
309 if err != nil {
310 t.Errorf("did not expect error: %s", err.Error())
311 }
312 if !reflect.DeepEqual(durStructPtr.Dur, expected) {
313 t.Errorf("JSON Unmarshal ptr got = %s, want %s", durStructPtr.Dur, expected)
314 }
315
316 var durStruct struct {
317 Dur Duration `json:"d"`
318 }
319 err = json.Unmarshal([]byte(jsonStr), &durStruct)
320 if err != nil {
321 t.Errorf("did not expect error: %s", err.Error())
322 }
323 if !reflect.DeepEqual(durStruct.Dur, *expected) {
324 t.Errorf("JSON Unmarshal ptr got = %s, want %s", &(durStruct.Dur), expected)
325 }
326 }
327
View as plain text