github.com/google/go-github/v49@v49.1.0/github/timestamp_test.go (about) 1 // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "encoding/json" 10 "fmt" 11 "testing" 12 "time" 13 ) 14 15 const ( 16 emptyTimeStr = `"0001-01-01T00:00:00Z"` 17 referenceTimeStr = `"2006-01-02T15:04:05Z"` 18 referenceTimeStrFractional = `"2006-01-02T15:04:05.000Z"` // This format was returned by the Projects API before October 1, 2017. 19 referenceUnixTimeStr = `1136214245` 20 referenceUnixTimeStrMilliSeconds = `1136214245000` // Millisecond-granular timestamps were introduced in the Audit log API. 21 ) 22 23 var ( 24 referenceTime = time.Date(2006, time.January, 02, 15, 04, 05, 0, time.UTC) 25 unixOrigin = time.Unix(0, 0).In(time.UTC) 26 ) 27 28 func TestTimestamp_Marshal(t *testing.T) { 29 testCases := []struct { 30 desc string 31 data Timestamp 32 want string 33 wantErr bool 34 equal bool 35 }{ 36 {"Reference", Timestamp{referenceTime}, referenceTimeStr, false, true}, 37 {"Empty", Timestamp{}, emptyTimeStr, false, true}, 38 {"Mismatch", Timestamp{}, referenceTimeStr, false, false}, 39 } 40 for _, tc := range testCases { 41 out, err := json.Marshal(tc.data) 42 if gotErr := err != nil; gotErr != tc.wantErr { 43 t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err) 44 } 45 got := string(out) 46 equal := got == tc.want 47 if (got == tc.want) != tc.equal { 48 t.Errorf("%s: got=%s, want=%s, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal) 49 } 50 } 51 } 52 53 func TestTimestamp_Unmarshal(t *testing.T) { 54 testCases := []struct { 55 desc string 56 data string 57 want Timestamp 58 wantErr bool 59 equal bool 60 }{ 61 {"Reference", referenceTimeStr, Timestamp{referenceTime}, false, true}, 62 {"ReferenceUnix", referenceUnixTimeStr, Timestamp{referenceTime}, false, true}, 63 {"ReferenceUnixMillisecond", referenceUnixTimeStrMilliSeconds, Timestamp{referenceTime}, false, true}, 64 {"ReferenceFractional", referenceTimeStrFractional, Timestamp{referenceTime}, false, true}, 65 {"Empty", emptyTimeStr, Timestamp{}, false, true}, 66 {"UnixStart", `0`, Timestamp{unixOrigin}, false, true}, 67 {"Mismatch", referenceTimeStr, Timestamp{}, false, false}, 68 {"MismatchUnix", `0`, Timestamp{}, false, false}, 69 {"Invalid", `"asdf"`, Timestamp{referenceTime}, true, false}, 70 {"OffByMillisecond", `1136214245001`, Timestamp{referenceTime}, false, false}, 71 } 72 for _, tc := range testCases { 73 var got Timestamp 74 err := json.Unmarshal([]byte(tc.data), &got) 75 if gotErr := err != nil; gotErr != tc.wantErr { 76 t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err) 77 continue 78 } 79 equal := got.Equal(tc.want) 80 if equal != tc.equal { 81 t.Errorf("%s: got=%#v, want=%#v, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal) 82 } 83 } 84 } 85 86 func TestTimestamp_MarshalReflexivity(t *testing.T) { 87 testCases := []struct { 88 desc string 89 data Timestamp 90 }{ 91 {"Reference", Timestamp{referenceTime}}, 92 {"Empty", Timestamp{}}, 93 } 94 for _, tc := range testCases { 95 data, err := json.Marshal(tc.data) 96 if err != nil { 97 t.Errorf("%s: Marshal err=%v", tc.desc, err) 98 } 99 var got Timestamp 100 err = json.Unmarshal(data, &got) 101 if err != nil { 102 t.Errorf("%s: Unmarshal err=%v", tc.desc, err) 103 } 104 if !got.Equal(tc.data) { 105 t.Errorf("%s: %+v != %+v", tc.desc, got, data) 106 } 107 } 108 } 109 110 type WrappedTimestamp struct { 111 A int 112 Time Timestamp 113 } 114 115 func TestWrappedTimestamp_Marshal(t *testing.T) { 116 testCases := []struct { 117 desc string 118 data WrappedTimestamp 119 want string 120 wantErr bool 121 equal bool 122 }{ 123 {"Reference", WrappedTimestamp{0, Timestamp{referenceTime}}, fmt.Sprintf(`{"A":0,"Time":%s}`, referenceTimeStr), false, true}, 124 {"Empty", WrappedTimestamp{}, fmt.Sprintf(`{"A":0,"Time":%s}`, emptyTimeStr), false, true}, 125 {"Mismatch", WrappedTimestamp{}, fmt.Sprintf(`{"A":0,"Time":%s}`, referenceTimeStr), false, false}, 126 } 127 for _, tc := range testCases { 128 out, err := json.Marshal(tc.data) 129 if gotErr := err != nil; gotErr != tc.wantErr { 130 t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err) 131 } 132 got := string(out) 133 equal := got == tc.want 134 if equal != tc.equal { 135 t.Errorf("%s: got=%s, want=%s, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal) 136 } 137 } 138 } 139 140 func TestWrappedTimestamp_Unmarshal(t *testing.T) { 141 testCases := []struct { 142 desc string 143 data string 144 want WrappedTimestamp 145 wantErr bool 146 equal bool 147 }{ 148 {"Reference", referenceTimeStr, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true}, 149 {"ReferenceUnix", referenceUnixTimeStr, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true}, 150 {"ReferenceUnixMillisecond", referenceUnixTimeStrMilliSeconds, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true}, 151 {"Empty", emptyTimeStr, WrappedTimestamp{0, Timestamp{}}, false, true}, 152 {"UnixStart", `0`, WrappedTimestamp{0, Timestamp{unixOrigin}}, false, true}, 153 {"Mismatch", referenceTimeStr, WrappedTimestamp{0, Timestamp{}}, false, false}, 154 {"MismatchUnix", `0`, WrappedTimestamp{0, Timestamp{}}, false, false}, 155 {"Invalid", `"asdf"`, WrappedTimestamp{0, Timestamp{referenceTime}}, true, false}, 156 {"OffByMillisecond", `1136214245001`, WrappedTimestamp{0, Timestamp{referenceTime}}, false, false}, 157 } 158 for _, tc := range testCases { 159 var got Timestamp 160 err := json.Unmarshal([]byte(tc.data), &got) 161 if gotErr := err != nil; gotErr != tc.wantErr { 162 t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err) 163 continue 164 } 165 equal := got.Time.Equal(tc.want.Time.Time) 166 if equal != tc.equal { 167 t.Errorf("%s: got=%#v, want=%#v, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal) 168 } 169 } 170 } 171 172 func TestWrappedTimestamp_MarshalReflexivity(t *testing.T) { 173 testCases := []struct { 174 desc string 175 data WrappedTimestamp 176 }{ 177 {"Reference", WrappedTimestamp{0, Timestamp{referenceTime}}}, 178 {"Empty", WrappedTimestamp{0, Timestamp{}}}, 179 } 180 for _, tc := range testCases { 181 bytes, err := json.Marshal(tc.data) 182 if err != nil { 183 t.Errorf("%s: Marshal err=%v", tc.desc, err) 184 } 185 var got WrappedTimestamp 186 err = json.Unmarshal(bytes, &got) 187 if err != nil { 188 t.Errorf("%s: Unmarshal err=%v", tc.desc, err) 189 } 190 if !got.Time.Equal(tc.data.Time) { 191 t.Errorf("%s: %+v != %+v", tc.desc, got, tc.data) 192 } 193 } 194 }