v / vlib / strconv / atou_test.v
296 lines · 264 sloc · 7.67 KB · 701d7f3764f52f26ab864f8b0d422c19efdb4297
Raw
1// Copyright (c) 2019-2024 V language community. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4import strconv
5
6// Perform tests against basic check done on fn test_atou_common_check()
7// used from atou_common.
8fn test_atou_common_check() {
9 // Parsing of these strings should fail on all types.
10 ko := [
11 '', // Empty string
12 '+', // Only sign
13 '-10', // - sign
14 '_', // Only Underscore
15 '_10', // Start with underscore
16 '+_10', // Start with underscore after sign.
17 '-_16', // Start with underscore after sign.
18 '123_', // End with underscore
19 '+12_3_', // Sign with trailing underscore
20 ]
21
22 for v in ko {
23 if r := strconv.atou(v) {
24 // These conversions should fail so force assertion !
25 assert false, 'The string "${v}" should not succeed or be considered as valid ${r}).'
26 } else {
27 // println('Parsing fails as it should for : "${v}')
28 assert true
29 }
30 }
31}
32
33// Performs tests on possible errors from atou_common function.
34// Function called from atou_common are tested above.
35fn test_atou_common() {
36 struct StrUint {
37 str_value string
38 uint_value u64
39 }
40
41 ok := [
42 StrUint{'0', 0},
43 StrUint{'+0', 0},
44 StrUint{'1', 1},
45 StrUint{'+3_14159', 314159},
46 StrUint{'1_00_1', 1001},
47 StrUint{'+1_024', 1024},
48 StrUint{'123_456_789', 123456789},
49 StrUint{'00000006', 6},
50 StrUint{'+0_0_0_0_0_0_0_6', 6},
51 StrUint{'2147483647', 2147483647},
52 StrUint{'+4294967295', 4294967295}, // max u32 bits
53 StrUint{'+18446744073709551615', 18446744073709551615}, // max u64 bits
54 ]
55
56 // Check that extracted int value matches its string.
57 for v in ok {
58 // println('Parsing ${v.str_value} should equals ${v.int_value}')
59 assert strconv.atou_common(v.str_value, max_u64)! == v.uint_value
60 }
61
62 // Parsing of these values should fail !
63 ko := [
64 '+1_2A', // Non radix 10 character.
65 '++A', // double sign.
66 '1__0', // 2 consecutive underscore
67 '+18446744073709551616', // u64 overflow by 1.
68 ]
69
70 for v in ko {
71 if r := strconv.atou_common(v, max_u64) {
72 // These conversions should fail so force assertion !
73 assert false, 'The string ${v} integer extraction should not succeed or be considered as valid ${r}).'
74 } else {
75 // println('Parsing fails as it should for: "${v} -> ${err}')
76 assert true
77 }
78 }
79}
80
81// performs numeric (bounds) tests over u8 type.
82fn test_atou8() {
83 struct StrU8 {
84 str_value string
85 uint_value u8
86 }
87
88 ok := [
89 StrU8{'0', 0},
90 StrU8{'+0', 0},
91 StrU8{'1', 1},
92 StrU8{'+39', 39},
93 StrU8{'1_23', 123},
94 StrU8{'00000006', 6},
95 StrU8{'+0_0_0_0_0_0_0_6', 6},
96 StrU8{'255', 255}, // max u8
97 ]
98
99 // Check that extracted int value matches its string.
100 for v in ok {
101 // println('Parsing ${v.str_value} should equals ${v.int_value}')
102 assert strconv.atou8(v.str_value)! == v.uint_value
103 }
104
105 // Parsing of these values should fail !
106 ko := [
107 '256', // Overflow by one
108 '+65535', // overflow of superior type.
109 ]
110
111 for v in ko {
112 if r := strconv.atou8(v) {
113 // These conversions should fail so force assertion !
114 assert false, 'The string ${v} integer extraction should not succeed or be considered as valid ${r}).'
115 } else {
116 // println('Parsing fails as it should for: "${v} -> ${err}')
117 assert true
118 }
119 }
120}
121
122// performs numeric (bounds) tests over u16 type.
123fn test_atou16() {
124 struct StrU16 {
125 str_value string
126 uint_value u16
127 }
128
129 ok := [
130 StrU16{'0', 0},
131 StrU16{'+0', 0},
132 StrU16{'1', 1},
133 StrU16{'+16384', 16384},
134 StrU16{'1_23', 123},
135 StrU16{'00000006', 6},
136 StrU16{'+0_0_0_0_0_0_0_6', 6},
137 StrU16{'+3_2_7_6_8', 32768},
138 StrU16{'65535', 65535}, // max u16
139 ]
140
141 // Check that extracted int value matches its string.
142 for v in ok {
143 // println('Parsing ${v.str_value} should equals ${v.int_value}')
144 assert strconv.atou16(v.str_value)! == v.uint_value
145 }
146
147 // Parsing of these values should fail !
148 ko := [
149 '65536', // Overflow by one
150 '+4294967295', // overflow of superior type.
151 ]
152
153 for v in ko {
154 if r := strconv.atou16(v) {
155 // These conversions should fail so force assertion !
156 assert false, 'The string ${v} integer extraction should not succeed or be considered as valid ${r}).'
157 } else {
158 // println('Parsing fails as it should for: "${v} -> ${err}')
159 assert true
160 }
161 }
162}
163
164// atou method acts actually with u32 boundary. In the future int may be mapped on 32/64bits
165// depending on machine architecture. That's why we provide atou/atou32 code and tests.
166fn test_atou() {
167 struct StrU32 {
168 str_value string
169 uint_value u32
170 }
171
172 ok := [
173 StrU32{'0', 0},
174 StrU32{'+0', 0},
175 StrU32{'1', 1},
176 StrU32{'+3_14159', 314159},
177 StrU32{'1_00_1', 1001},
178 StrU32{'+1_024', 1024},
179 StrU32{'123_456_789', 123456789},
180 StrU32{'00000006', 6},
181 StrU32{'+0_0_0_0_0_0_0_6', 6},
182 StrU32{'2147483647', 2147483647},
183 StrU32{'+4294967295', 4294967295}, // max u32 bits
184 ]
185
186 // Check that extracted int value matches its string.
187 for v in ok {
188 // println('Parsing ${v.str_value} should equals ${v.int_value}')
189 assert strconv.atou(v.str_value)! == v.uint_value
190 }
191
192 // Parsing of these values should fail !
193 ko := [
194 '4294967296', // Overflow by one
195 '+18446744073709551615', // overflow of superior type.
196 ]
197
198 for v in ko {
199 if r := strconv.atou(v) {
200 // These conversions should fail so force assertion !
201 assert false, 'The string ${v} integer extraction should not succeed or be considered as valid ${r}).'
202 } else {
203 // println('Parsing fails as it should for: "${v} -> ${err}')
204 assert true
205 }
206 }
207}
208
209// performs numeric (bounds) tests over u64 type.
210fn test_atou32() {
211 struct StrU32 {
212 str_value string
213 uint_value u32
214 }
215
216 ok := [
217 StrU32{'0', 0},
218 StrU32{'+0', 0},
219 StrU32{'1', 1},
220 StrU32{'+3_14159', 314159},
221 StrU32{'1_00_1', 1001},
222 StrU32{'+1_024', 1024},
223 StrU32{'123_456_789', 123456789},
224 StrU32{'00000006', 6},
225 StrU32{'+0_0_0_0_0_0_0_6', 6},
226 StrU32{'2147483647', 2147483647},
227 StrU32{'+4294967295', 4294967295}, // max u32 bits
228 ]
229
230 // Check that extracted int value matches its string.
231 for v in ok {
232 // println('Parsing ${v.str_value} should equals ${v.int_value}')
233 assert strconv.atou32(v.str_value)! == v.uint_value
234 }
235
236 // Parsing of these values should fail !
237 ko := [
238 '4294967296', // Overflow by one
239 '+18446744073709551615', // overflow of superior type.
240 ]
241
242 for v in ko {
243 if r := strconv.atou32(v) {
244 // These conversions should fail so force assertion !
245 assert false, 'The string ${v} integer extraction should not succeed or be considered as valid ${r}).'
246 } else {
247 // println('Parsing fails as it should for: "${v} -> ${err}')
248 assert true
249 }
250 }
251}
252
253// performs numeric (bounds) tests over u64 type.
254fn test_atou64() {
255 struct StrU64 {
256 str_value string
257 uint_value u64
258 }
259
260 ok := [
261 StrU64{'0', 0},
262 StrU64{'+0', 0},
263 StrU64{'1', 1},
264 StrU64{'+3_14159', 314159},
265 StrU64{'1_00_1', 1001},
266 StrU64{'+1_024', 1024},
267 StrU64{'123_456_789', 123456789},
268 StrU64{'00000006', 6},
269 StrU64{'+0_0_0_0_0_0_0_6', 6},
270 StrU64{'2147483647', 2147483647},
271 StrU64{'+18446744073709551615', 18446744073709551615}, // max u64 bits
272 ]
273
274 // Check that extracted int value matches its string.
275 for v in ok {
276 // println('Parsing ${v.str_value} should equals ${v.int_value}')
277 assert strconv.atou64(v.str_value)! == v.uint_value
278 }
279
280 // Parsing of these values should fail !
281 ko := [
282 '18446744073709551616', // Overflow by one
283 '+184467440214748364773709551615', // Large overflow .
284 '430943843908439083411', // Overflow that wraps without falling under oldx (issue #27102).
285 ]
286
287 for v in ko {
288 if r := strconv.atou64(v) {
289 // These conversions should fail so force assertion !
290 assert false, 'The string ${v} integer extraction should not succeed or be considered as valid ${r}).'
291 } else {
292 // println('Parsing fails as it should for: "${v} -> ${err}')
293 assert true
294 }
295 }
296}
297