@@ -294,43 +294,144 @@ func TestIsolationLevelMapping(t *testing.T) {
294294}
295295
296296func TestParseDateTime (t * testing.T ) {
297- // UTC loc
298- {
299- str := "2020-05-13 21:30:45"
300- t1 , err := parseDateTime (str , time .UTC )
301- if err != nil {
302- t .Error (err )
303- return
304- }
305- t2 := time .Date (2020 , 5 , 13 ,
306- 21 , 30 , 45 , 0 , time .UTC )
307- if ! t1 .Equal (t2 ) {
308- t .Errorf ("want equal, have: %v, want: %v" , t1 , t2 )
309- return
310- }
297+ cases := []struct {
298+ name string
299+ str string
300+ }{
301+ {
302+ name : "parse date" ,
303+ str : "2020-05-13" ,
304+ },
305+ {
306+ name : "parse null date" ,
307+ str : sDate0 ,
308+ },
309+ {
310+ name : "parse datetime" ,
311+ str : "2020-05-13 21:30:45" ,
312+ },
313+ {
314+ name : "parse null datetime" ,
315+ str : sDateTime0 ,
316+ },
317+ {
318+ name : "parse datetime nanosec 1-digit" ,
319+ str : "2020-05-25 23:22:01.1" ,
320+ },
321+ {
322+ name : "parse datetime nanosec 2-digits" ,
323+ str : "2020-05-25 23:22:01.15" ,
324+ },
325+ {
326+ name : "parse datetime nanosec 3-digits" ,
327+ str : "2020-05-25 23:22:01.159" ,
328+ },
329+ {
330+ name : "parse datetime nanosec 4-digits" ,
331+ str : "2020-05-25 23:22:01.1594" ,
332+ },
333+ {
334+ name : "parse datetime nanosec 5-digits" ,
335+ str : "2020-05-25 23:22:01.15949" ,
336+ },
337+ {
338+ name : "parse datetime nanosec 6-digits" ,
339+ str : "2020-05-25 23:22:01.159491" ,
340+ },
311341 }
312- // non-UTC loc
313- {
314- str := "2020-05-13 21:30:45"
315- loc := time .FixedZone ("test" , 8 * 60 * 60 )
316- t1 , err := parseDateTime (str , loc )
317- if err != nil {
318- t .Error (err )
319- return
320- }
321- t2 := time .Date (2020 , 5 , 13 ,
322- 21 , 30 , 45 , 0 , loc )
323- if ! t1 .Equal (t2 ) {
324- t .Errorf ("want equal, have: %v, want: %v" , t1 , t2 )
325- return
342+
343+ for _ , loc := range []* time.Location {
344+ time .UTC ,
345+ time .FixedZone ("test" , 8 * 60 * 60 ),
346+ } {
347+ for _ , cc := range cases {
348+ t .Run (cc .name + "-" + loc .String (), func (t * testing.T ) {
349+ var want time.Time
350+ if cc .str != sDate0 && cc .str != sDateTime0 {
351+ var err error
352+ want , err = time .ParseInLocation (timeFormat [:len (cc .str )], cc .str , loc )
353+ if err != nil {
354+ t .Fatal (err )
355+ }
356+ }
357+ got , err := parseDateTime ([]byte (cc .str ), loc )
358+ if err != nil {
359+ t .Fatal (err )
360+ }
361+
362+ if ! want .Equal (got ) {
363+ t .Fatalf ("want: %v, but got %v" , want , got )
364+ }
365+ })
326366 }
327367 }
328368}
329369
330- func BenchmarkParseDateTime (b * testing.B ) {
331- str := "2020-05-13 21:30:45"
332- loc := time .FixedZone ("test" , 8 * 60 * 60 )
333- for i := 0 ; i < b .N ; i ++ {
334- _ , _ = parseDateTime (str , loc )
370+ func TestParseDateTimeFail (t * testing.T ) {
371+ cases := []struct {
372+ name string
373+ str string
374+ wantErr string
375+ }{
376+ {
377+ name : "parse invalid time" ,
378+ str : "hello" ,
379+ wantErr : "invalid time bytes: hello" ,
380+ },
381+ {
382+ name : "parse year" ,
383+ str : "000!-00-00 00:00:00.000000" ,
384+ wantErr : "not [0-9]" ,
385+ },
386+ {
387+ name : "parse month" ,
388+ str : "0000-!0-00 00:00:00.000000" ,
389+ wantErr : "not [0-9]" ,
390+ },
391+ {
392+ name : `parse "-" after parsed year` ,
393+ str : "0000:00-00 00:00:00.000000" ,
394+ wantErr : "bad value for field: `:`" ,
395+ },
396+ {
397+ name : `parse "-" after parsed month` ,
398+ str : "0000-00:00 00:00:00.000000" ,
399+ wantErr : "bad value for field: `:`" ,
400+ },
401+ {
402+ name : `parse " " after parsed date` ,
403+ str : "0000-00-00+00:00:00.000000" ,
404+ wantErr : "bad value for field: `+`" ,
405+ },
406+ {
407+ name : `parse ":" after parsed date` ,
408+ str : "0000-00-00 00-00:00.000000" ,
409+ wantErr : "bad value for field: `-`" ,
410+ },
411+ {
412+ name : `parse ":" after parsed hour` ,
413+ str : "0000-00-00 00:00-00.000000" ,
414+ wantErr : "bad value for field: `-`" ,
415+ },
416+ {
417+ name : `parse "." after parsed sec` ,
418+ str : "0000-00-00 00:00:00?000000" ,
419+ wantErr : "bad value for field: `?`" ,
420+ },
421+ }
422+
423+ for _ , cc := range cases {
424+ t .Run (cc .name , func (t * testing.T ) {
425+ got , err := parseDateTime ([]byte (cc .str ), time .UTC )
426+ if err == nil {
427+ t .Fatal ("want error" )
428+ }
429+ if cc .wantErr != err .Error () {
430+ t .Fatalf ("want `%s`, but got `%s`" , cc .wantErr , err )
431+ }
432+ if ! got .IsZero () {
433+ t .Fatal ("want zero time" )
434+ }
435+ })
335436 }
336437}
0 commit comments