1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package bigquery
16
17 import (
18 "testing"
19 "time"
20
21 "cloud.google.com/go/internal/testutil"
22 )
23
24 func TestParseInterval(t *testing.T) {
25 testcases := []struct {
26 inputStr string
27 wantInterval *IntervalValue
28 wantErr bool
29 }{
30 {
31 inputStr: "",
32 wantErr: true,
33 },
34 {
35 inputStr: "1-2 3",
36 wantErr: true,
37 },
38 {
39 inputStr: "1-2 3 4:5:6",
40 wantInterval: &IntervalValue{Years: 1, Months: 2, Days: 3, Hours: 4, Minutes: 5, Seconds: 6, SubSecondNanos: 0},
41 },
42 {
43 inputStr: "1-2 3 4:5:6.5",
44 wantInterval: &IntervalValue{Years: 1, Months: 2, Days: 3, Hours: 4, Minutes: 5, Seconds: 6, SubSecondNanos: 500000000},
45 },
46 {
47 inputStr: "-1-2 3 -4:5:6.123",
48 wantInterval: &IntervalValue{Years: -1, Months: -2, Days: 3, Hours: -4, Minutes: -5, Seconds: -6, SubSecondNanos: -123000000},
49 },
50 {
51 inputStr: "0-0 0 1:1:1.000000001",
52 wantInterval: &IntervalValue{Hours: 1, Minutes: 1, Seconds: 1, SubSecondNanos: 1},
53 },
54 }
55
56 for _, tc := range testcases {
57 gotInterval, err := ParseInterval(tc.inputStr)
58 if tc.wantErr {
59 if err != nil {
60 continue
61 }
62 t.Errorf("input %s: wanted err, got success", tc.inputStr)
63 }
64 if err != nil {
65 t.Errorf("input %s got err: %v", tc.inputStr, err)
66 }
67 if diff := testutil.Diff(gotInterval, tc.wantInterval); diff != "" {
68 t.Errorf("input %s: got=-, want=+:\n%s", tc.inputStr, diff)
69 }
70 }
71 }
72
73 func TestCanonicalInterval(t *testing.T) {
74 testcases := []struct {
75 description string
76 input *IntervalValue
77 wantCanonical *IntervalValue
78 wantString string
79 }{
80 {
81 description: "already canonical",
82 input: &IntervalValue{Years: 1, Months: 2, Days: 3, Hours: 4, Minutes: 5, Seconds: 6, SubSecondNanos: 0},
83 wantCanonical: &IntervalValue{Years: 1, Months: 2, Days: 3, Hours: 4, Minutes: 5, Seconds: 6, SubSecondNanos: 0},
84 wantString: "1-2 3 4:5:6",
85 },
86 {
87 description: "mixed Y-M",
88 input: &IntervalValue{Years: -1, Months: 28},
89 wantCanonical: &IntervalValue{Years: 1, Months: 4, Days: 0, Hours: 0, Minutes: 0, Seconds: 0, SubSecondNanos: 0},
90 wantString: "1-4 0 0:0:0",
91 },
92 {
93 description: "mixed Y-M",
94 input: &IntervalValue{Years: -1, Months: 28},
95 wantCanonical: &IntervalValue{Years: 1, Months: 4, Days: 0, Hours: 0, Minutes: 0, Seconds: 0, SubSecondNanos: 0},
96 wantString: "1-4 0 0:0:0",
97 },
98 {
99 description: "big month Y-M",
100 input: &IntervalValue{Years: 0, Months: -13},
101 wantCanonical: &IntervalValue{Years: -1, Months: -1, Days: 0, Hours: 0, Minutes: 0, Seconds: 0, SubSecondNanos: 0},
102 wantString: "-1-1 0 0:0:0",
103 },
104 {
105 description: "big days not normalized",
106 input: &IntervalValue{Days: 1000},
107 wantCanonical: &IntervalValue{Years: 0, Months: 0, Days: 1000, Hours: 0, Minutes: 0, Seconds: 0, SubSecondNanos: 0},
108 wantString: "0-0 1000 0:0:0",
109 },
110 {
111 description: "time reduced",
112 input: &IntervalValue{Minutes: 181, Seconds: 61, SubSecondNanos: 5},
113 wantCanonical: &IntervalValue{Hours: 3, Minutes: 2, Seconds: 1, SubSecondNanos: 5},
114 wantString: "0-0 0 3:2:1.000000005",
115 },
116 {
117 description: "subseconds oversized",
118 input: &IntervalValue{SubSecondNanos: 1900000000},
119 wantCanonical: &IntervalValue{Years: 0, Months: 0, Days: 0, Hours: 0, Minutes: 0, Seconds: 1, SubSecondNanos: 900000000},
120 wantString: "0-0 0 0:0:1.9",
121 },
122 }
123
124 for _, tc := range testcases {
125 gotCanonical := tc.input.Canonicalize()
126
127 if diff := testutil.Diff(gotCanonical, tc.wantCanonical); diff != "" {
128 t.Errorf("%s: got=-, want=+:\n%s", tc.description, diff)
129 }
130
131 gotStr := tc.input.String()
132 if gotStr != tc.wantString {
133 t.Errorf("%s mismatched strings. got %s want %s", tc.description, gotStr, tc.wantString)
134 }
135 }
136 }
137
138 func TestIntervalDuration(t *testing.T) {
139 testcases := []struct {
140 description string
141 inputInterval *IntervalValue
142 wantDuration time.Duration
143 wantInterval *IntervalValue
144 }{
145 {
146 description: "hour",
147 inputInterval: &IntervalValue{Hours: 1},
148 wantDuration: time.Duration(time.Hour),
149 wantInterval: &IntervalValue{Hours: 1},
150 },
151 {
152 description: "minute oversized",
153 inputInterval: &IntervalValue{Minutes: 62},
154 wantDuration: time.Duration(62 * time.Minute),
155 wantInterval: &IntervalValue{Hours: 1, Minutes: 2},
156 },
157 {
158 description: "other parts",
159 inputInterval: &IntervalValue{Months: 1, Days: 2},
160 wantDuration: time.Duration(32 * 24 * time.Hour),
161 wantInterval: &IntervalValue{Hours: 32 * 24},
162 },
163 }
164
165 for _, tc := range testcases {
166 gotDuration := tc.inputInterval.ToDuration()
167
168
169 if gotDuration != tc.wantDuration {
170 t.Errorf("%s: mismatched duration, got %v want %v", tc.description, gotDuration, tc.wantDuration)
171 }
172
173
174 gotInterval := IntervalValueFromDuration(gotDuration)
175 if diff := testutil.Diff(gotInterval, tc.wantInterval); diff != "" {
176 t.Errorf("%s: got=-, want=+:\n%s", tc.description, diff)
177 }
178 }
179 }
180
View as plain text