1package pgtype_test 2 3import ( 4 "reflect" 5 "testing" 6 "time" 7 8 "github.com/jackc/pgtype" 9 "github.com/jackc/pgtype/testutil" 10) 11 12func TestTimeTranscode(t *testing.T) { 13 testutil.TestSuccessfulTranscode(t, "time", []interface{}{ 14 &pgtype.Time{Microseconds: 0, Status: pgtype.Present}, 15 &pgtype.Time{Microseconds: 1, Status: pgtype.Present}, 16 &pgtype.Time{Microseconds: 86399999999, Status: pgtype.Present}, 17 &pgtype.Time{Status: pgtype.Null}, 18 }) 19} 20 21// Test for transcoding 24:00:00 separately as github.com/lib/pq doesn't seem to support it. 22func TestTimeTranscode24HH(t *testing.T) { 23 pgTypeName := "time" 24 values := []interface{}{ 25 &pgtype.Time{Microseconds: 86400000000, Status: pgtype.Present}, 26 } 27 28 eqFunc := func(a, b interface{}) bool { 29 return reflect.DeepEqual(a, b) 30 } 31 32 testutil.TestPgxSuccessfulTranscodeEqFunc(t, pgTypeName, values, eqFunc) 33 testutil.TestDatabaseSQLSuccessfulTranscodeEqFunc(t, "github.com/jackc/pgx/stdlib", pgTypeName, values, eqFunc) 34} 35 36func TestTimeSet(t *testing.T) { 37 type _time time.Time 38 39 successfulTests := []struct { 40 source interface{} 41 result pgtype.Time 42 }{ 43 {source: time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC), result: pgtype.Time{Microseconds: 0, Status: pgtype.Present}}, 44 {source: time.Date(1900, 1, 1, 1, 0, 0, 0, time.UTC), result: pgtype.Time{Microseconds: 3600000000, Status: pgtype.Present}}, 45 {source: time.Date(1900, 1, 1, 0, 1, 0, 0, time.UTC), result: pgtype.Time{Microseconds: 60000000, Status: pgtype.Present}}, 46 {source: time.Date(1900, 1, 1, 0, 0, 1, 0, time.UTC), result: pgtype.Time{Microseconds: 1000000, Status: pgtype.Present}}, 47 {source: time.Date(1970, 1, 1, 0, 0, 0, 1, time.UTC), result: pgtype.Time{Microseconds: 0, Status: pgtype.Present}}, 48 {source: time.Date(1970, 1, 1, 0, 0, 0, 1000, time.UTC), result: pgtype.Time{Microseconds: 1, Status: pgtype.Present}}, 49 {source: time.Date(1999, 12, 31, 23, 59, 59, 999999999, time.UTC), result: pgtype.Time{Microseconds: 86399999999, Status: pgtype.Present}}, 50 {source: time.Date(2015, 1, 1, 0, 0, 0, 2000, time.Local), result: pgtype.Time{Microseconds: 2, Status: pgtype.Present}}, 51 {source: func(t time.Time) *time.Time { return &t }(time.Date(2015, 1, 1, 0, 0, 0, 2000, time.Local)), result: pgtype.Time{Microseconds: 2, Status: pgtype.Present}}, 52 {source: nil, result: pgtype.Time{Status: pgtype.Null}}, 53 {source: (*time.Time)(nil), result: pgtype.Time{Status: pgtype.Null}}, 54 {source: _time(time.Date(1970, 1, 1, 0, 0, 0, 3000, time.UTC)), result: pgtype.Time{Microseconds: 3, Status: pgtype.Present}}, 55 } 56 57 for i, tt := range successfulTests { 58 var r pgtype.Time 59 err := r.Set(tt.source) 60 if err != nil { 61 t.Errorf("%d: %v", i, err) 62 } 63 64 if r != tt.result { 65 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r) 66 } 67 } 68} 69 70func TestTimeAssignTo(t *testing.T) { 71 var tim time.Time 72 var ptim *time.Time 73 74 simpleTests := []struct { 75 src pgtype.Time 76 dst interface{} 77 expected interface{} 78 }{ 79 {src: pgtype.Time{Microseconds: 0, Status: pgtype.Present}, dst: &tim, expected: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)}, 80 {src: pgtype.Time{Microseconds: 3600000000, Status: pgtype.Present}, dst: &tim, expected: time.Date(2000, 1, 1, 1, 0, 0, 0, time.UTC)}, 81 {src: pgtype.Time{Microseconds: 60000000, Status: pgtype.Present}, dst: &tim, expected: time.Date(2000, 1, 1, 0, 1, 0, 0, time.UTC)}, 82 {src: pgtype.Time{Microseconds: 1000000, Status: pgtype.Present}, dst: &tim, expected: time.Date(2000, 1, 1, 0, 0, 1, 0, time.UTC)}, 83 {src: pgtype.Time{Microseconds: 1, Status: pgtype.Present}, dst: &tim, expected: time.Date(2000, 1, 1, 0, 0, 0, 1000, time.UTC)}, 84 {src: pgtype.Time{Microseconds: 86399999999, Status: pgtype.Present}, dst: &tim, expected: time.Date(2000, 1, 1, 23, 59, 59, 999999000, time.UTC)}, 85 {src: pgtype.Time{Microseconds: 0, Status: pgtype.Null}, dst: &ptim, expected: ((*time.Time)(nil))}, 86 } 87 88 for i, tt := range simpleTests { 89 err := tt.src.AssignTo(tt.dst) 90 if err != nil { 91 t.Errorf("%d: %v", i, err) 92 } 93 94 if dst := reflect.ValueOf(tt.dst).Elem().Interface(); dst != tt.expected { 95 t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst) 96 } 97 } 98 99 pointerAllocTests := []struct { 100 src pgtype.Time 101 dst interface{} 102 expected interface{} 103 }{ 104 {src: pgtype.Time{Microseconds: 0, Status: pgtype.Present}, dst: &ptim, expected: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)}, 105 } 106 107 for i, tt := range pointerAllocTests { 108 err := tt.src.AssignTo(tt.dst) 109 if err != nil { 110 t.Errorf("%d: %v", i, err) 111 } 112 113 if dst := reflect.ValueOf(tt.dst).Elem().Elem().Interface(); dst != tt.expected { 114 t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, dst) 115 } 116 } 117 118 errorTests := []struct { 119 src pgtype.Time 120 dst interface{} 121 }{ 122 {src: pgtype.Time{Microseconds: 86400000000, Status: pgtype.Present}, dst: &tim}, 123 } 124 125 for i, tt := range errorTests { 126 err := tt.src.AssignTo(tt.dst) 127 if err == nil { 128 t.Errorf("%d: expected error but none was returned (%v -> %v)", i, tt.src, tt.dst) 129 } 130 } 131} 132