1// Copyright 2015 go-swagger maintainers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package strfmt
16
17import (
18	"testing"
19	"time"
20
21	"github.com/stretchr/testify/assert"
22	"go.mongodb.org/mongo-driver/bson"
23)
24
25func TestDuration(t *testing.T) {
26	pp := Duration(0)
27
28	err := pp.UnmarshalText([]byte("0ms"))
29	assert.NoError(t, err)
30	err = pp.UnmarshalText([]byte("yada"))
31	assert.Error(t, err)
32
33	orig := "2ms"
34	b := []byte(orig)
35	bj := []byte("\"" + orig + "\"")
36
37	err = pp.UnmarshalText(b)
38	assert.NoError(t, err)
39
40	err = pp.UnmarshalText([]byte("three week"))
41	assert.Error(t, err)
42
43	err = pp.UnmarshalText([]byte("9999999999999999999999999999999999999999999999999999999 weeks"))
44	assert.Error(t, err)
45
46	txt, err := pp.MarshalText()
47	assert.NoError(t, err)
48	assert.Equal(t, orig, string(txt))
49
50	err = pp.UnmarshalJSON(bj)
51	assert.NoError(t, err)
52	assert.EqualValues(t, orig, pp.String())
53
54	err = pp.UnmarshalJSON([]byte("yada"))
55	assert.Error(t, err)
56
57	err = pp.UnmarshalJSON([]byte(`"12 parsecs"`))
58	assert.Error(t, err)
59
60	err = pp.UnmarshalJSON([]byte(`"12 y"`))
61	assert.Error(t, err)
62
63	b, err = pp.MarshalJSON()
64	assert.NoError(t, err)
65	assert.Equal(t, bj, b)
66
67	dur := Duration(42)
68	bsonData, err := bson.Marshal(&dur)
69	assert.NoError(t, err)
70
71	var durCopy Duration
72	err = bson.Unmarshal(bsonData, &durCopy)
73	assert.NoError(t, err)
74	assert.Equal(t, dur, durCopy)
75}
76
77func testDurationParser(t *testing.T, toParse string, expected time.Duration) {
78	r, e := ParseDuration(toParse)
79	assert.NoError(t, e)
80	assert.Equal(t, expected, r)
81}
82
83func TestDurationParser_Failed(t *testing.T) {
84	_, e := ParseDuration("45 wekk")
85	assert.Error(t, e)
86}
87
88func TestIsDuration_Failed(t *testing.T) {
89	e := IsDuration("45 weeekks")
90	assert.False(t, e)
91}
92
93func testDurationSQLScanner(t *testing.T, dur time.Duration) {
94	values := []interface{}{int64(dur), float64(dur)}
95	for _, value := range values {
96		var result Duration
97		err := result.Scan(value)
98		assert.NoError(t, err)
99		assert.Equal(t, dur, time.Duration(result))
100
101		// And the other way around
102		resv, erv := result.Value()
103		assert.NoError(t, erv)
104		assert.EqualValues(t, value, resv)
105
106	}
107}
108
109func TestDurationScanner_Nil(t *testing.T) {
110	var result Duration
111	err := result.Scan(nil)
112	assert.NoError(t, err)
113	assert.EqualValues(t, 0, time.Duration(result))
114
115	err = result.Scan("1 ms")
116	assert.Error(t, err)
117}
118
119func TestDurationParser(t *testing.T) {
120	testcases := map[string]time.Duration{
121
122		// parse the short forms without spaces
123		"1ns": 1 * time.Nanosecond,
124		"1us": 1 * time.Microsecond,
125		"1µs": 1 * time.Microsecond,
126		"1ms": 1 * time.Millisecond,
127		"1s":  1 * time.Second,
128		"1m":  1 * time.Minute,
129		"1h":  1 * time.Hour,
130		"1hr": 1 * time.Hour,
131		"1d":  24 * time.Hour,
132		"1w":  7 * 24 * time.Hour,
133		"1wk": 7 * 24 * time.Hour,
134
135		// parse the long forms without spaces
136		"1nanoseconds":  1 * time.Nanosecond,
137		"1nanos":        1 * time.Nanosecond,
138		"1microseconds": 1 * time.Microsecond,
139		"1micros":       1 * time.Microsecond,
140		"1millis":       1 * time.Millisecond,
141		"1milliseconds": 1 * time.Millisecond,
142		"1second":       1 * time.Second,
143		"1sec":          1 * time.Second,
144		"1min":          1 * time.Minute,
145		"1minute":       1 * time.Minute,
146		"1hour":         1 * time.Hour,
147		"1day":          24 * time.Hour,
148		"1week":         7 * 24 * time.Hour,
149
150		// parse the short forms with spaces
151		"1  ns": 1 * time.Nanosecond,
152		"1  us": 1 * time.Microsecond,
153		"1  µs": 1 * time.Microsecond,
154		"1  ms": 1 * time.Millisecond,
155		"1  s":  1 * time.Second,
156		"1  m":  1 * time.Minute,
157		"1  h":  1 * time.Hour,
158		"1  hr": 1 * time.Hour,
159		"1  d":  24 * time.Hour,
160		"1  w":  7 * 24 * time.Hour,
161		"1  wk": 7 * 24 * time.Hour,
162
163		// parse the long forms without spaces
164		"1  nanoseconds":  1 * time.Nanosecond,
165		"1  nanos":        1 * time.Nanosecond,
166		"1  microseconds": 1 * time.Microsecond,
167		"1  micros":       1 * time.Microsecond,
168		"1  millis":       1 * time.Millisecond,
169		"1  milliseconds": 1 * time.Millisecond,
170		"1  second":       1 * time.Second,
171		"1  sec":          1 * time.Second,
172		"1  min":          1 * time.Minute,
173		"1  minute":       1 * time.Minute,
174		"1  hour":         1 * time.Hour,
175		"1  day":          24 * time.Hour,
176		"1  week":         7 * 24 * time.Hour,
177	}
178
179	for str, dur := range testcases {
180		testDurationParser(t, str, dur)
181		testDurationSQLScanner(t, dur)
182	}
183}
184func TestIsDuration_Caveats(t *testing.T) {
185	// This works too
186	e := IsDuration("45 weeks")
187	assert.True(t, e)
188
189	// This works too
190	e = IsDuration("45 weekz")
191	assert.True(t, e)
192
193	// This works too
194	e = IsDuration("12 hours")
195	assert.True(t, e)
196
197	// This works too
198	e = IsDuration("12 minutes")
199	assert.True(t, e)
200
201	// This does not work
202	e = IsDuration("12 phours")
203	assert.False(t, e)
204
205}
206
207func TestDeepCopyDuration(t *testing.T) {
208	dur := Duration(42)
209	in := &dur
210
211	out := new(Duration)
212	in.DeepCopyInto(out)
213	assert.Equal(t, in, out)
214
215	out2 := in.DeepCopy()
216	assert.Equal(t, in, out2)
217
218	var inNil *Duration
219	out3 := inNil.DeepCopy()
220	assert.Nil(t, out3)
221}
222