github.com/google/go-github/v66@v66.0.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  	t.Parallel()
    30  	testCases := []struct {
    31  		desc    string
    32  		data    Timestamp
    33  		want    string
    34  		wantErr bool
    35  		equal   bool
    36  	}{
    37  		{"Reference", Timestamp{referenceTime}, referenceTimeStr, false, true},
    38  		{"Empty", Timestamp{}, emptyTimeStr, false, true},
    39  		{"Mismatch", Timestamp{}, referenceTimeStr, false, false},
    40  	}
    41  	for _, tc := range testCases {
    42  		out, err := json.Marshal(tc.data)
    43  		if gotErr := err != nil; gotErr != tc.wantErr {
    44  			t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err)
    45  		}
    46  		got := string(out)
    47  		equal := got == tc.want
    48  		if (got == tc.want) != tc.equal {
    49  			t.Errorf("%s: got=%s, want=%s, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal)
    50  		}
    51  	}
    52  }
    53  
    54  func TestTimestamp_Unmarshal(t *testing.T) {
    55  	t.Parallel()
    56  	testCases := []struct {
    57  		desc    string
    58  		data    string
    59  		want    Timestamp
    60  		wantErr bool
    61  		equal   bool
    62  	}{
    63  		{"Reference", referenceTimeStr, Timestamp{referenceTime}, false, true},
    64  		{"ReferenceUnix", referenceUnixTimeStr, Timestamp{referenceTime}, false, true},
    65  		{"ReferenceUnixMillisecond", referenceUnixTimeStrMilliSeconds, Timestamp{referenceTime}, false, true},
    66  		{"ReferenceFractional", referenceTimeStrFractional, Timestamp{referenceTime}, false, true},
    67  		{"Empty", emptyTimeStr, Timestamp{}, false, true},
    68  		{"UnixStart", `0`, Timestamp{unixOrigin}, false, true},
    69  		{"Mismatch", referenceTimeStr, Timestamp{}, false, false},
    70  		{"MismatchUnix", `0`, Timestamp{}, false, false},
    71  		{"Invalid", `"asdf"`, Timestamp{referenceTime}, true, false},
    72  		{"OffByMillisecond", `1136214245001`, Timestamp{referenceTime}, false, false},
    73  	}
    74  	for _, tc := range testCases {
    75  		var got Timestamp
    76  		err := json.Unmarshal([]byte(tc.data), &got)
    77  		if gotErr := err != nil; gotErr != tc.wantErr {
    78  			t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err)
    79  			continue
    80  		}
    81  		equal := got.Equal(tc.want)
    82  		if equal != tc.equal {
    83  			t.Errorf("%s: got=%#v, want=%#v, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal)
    84  		}
    85  	}
    86  }
    87  
    88  func TestTimestamp_MarshalReflexivity(t *testing.T) {
    89  	t.Parallel()
    90  	testCases := []struct {
    91  		desc string
    92  		data Timestamp
    93  	}{
    94  		{"Reference", Timestamp{referenceTime}},
    95  		{"Empty", Timestamp{}},
    96  	}
    97  	for _, tc := range testCases {
    98  		data, err := json.Marshal(tc.data)
    99  		if err != nil {
   100  			t.Errorf("%s: Marshal err=%v", tc.desc, err)
   101  		}
   102  		var got Timestamp
   103  		err = json.Unmarshal(data, &got)
   104  		if err != nil {
   105  			t.Errorf("%s: Unmarshal err=%v", tc.desc, err)
   106  		}
   107  		if !got.Equal(tc.data) {
   108  			t.Errorf("%s: %+v != %+v", tc.desc, got, data)
   109  		}
   110  	}
   111  }
   112  
   113  type WrappedTimestamp struct {
   114  	A    int
   115  	Time Timestamp
   116  }
   117  
   118  func TestWrappedTimestamp_Marshal(t *testing.T) {
   119  	t.Parallel()
   120  	testCases := []struct {
   121  		desc    string
   122  		data    WrappedTimestamp
   123  		want    string
   124  		wantErr bool
   125  		equal   bool
   126  	}{
   127  		{"Reference", WrappedTimestamp{0, Timestamp{referenceTime}}, fmt.Sprintf(`{"A":0,"Time":%s}`, referenceTimeStr), false, true},
   128  		{"Empty", WrappedTimestamp{}, fmt.Sprintf(`{"A":0,"Time":%s}`, emptyTimeStr), false, true},
   129  		{"Mismatch", WrappedTimestamp{}, fmt.Sprintf(`{"A":0,"Time":%s}`, referenceTimeStr), false, false},
   130  	}
   131  	for _, tc := range testCases {
   132  		out, err := json.Marshal(tc.data)
   133  		if gotErr := err != nil; gotErr != tc.wantErr {
   134  			t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err)
   135  		}
   136  		got := string(out)
   137  		equal := got == tc.want
   138  		if equal != tc.equal {
   139  			t.Errorf("%s: got=%s, want=%s, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal)
   140  		}
   141  	}
   142  }
   143  
   144  func TestWrappedTimestamp_Unmarshal(t *testing.T) {
   145  	t.Parallel()
   146  	testCases := []struct {
   147  		desc    string
   148  		data    string
   149  		want    WrappedTimestamp
   150  		wantErr bool
   151  		equal   bool
   152  	}{
   153  		{"Reference", referenceTimeStr, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true},
   154  		{"ReferenceUnix", referenceUnixTimeStr, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true},
   155  		{"ReferenceUnixMillisecond", referenceUnixTimeStrMilliSeconds, WrappedTimestamp{0, Timestamp{referenceTime}}, false, true},
   156  		{"Empty", emptyTimeStr, WrappedTimestamp{0, Timestamp{}}, false, true},
   157  		{"UnixStart", `0`, WrappedTimestamp{0, Timestamp{unixOrigin}}, false, true},
   158  		{"Mismatch", referenceTimeStr, WrappedTimestamp{0, Timestamp{}}, false, false},
   159  		{"MismatchUnix", `0`, WrappedTimestamp{0, Timestamp{}}, false, false},
   160  		{"Invalid", `"asdf"`, WrappedTimestamp{0, Timestamp{referenceTime}}, true, false},
   161  		{"OffByMillisecond", `1136214245001`, WrappedTimestamp{0, Timestamp{referenceTime}}, false, false},
   162  	}
   163  	for _, tc := range testCases {
   164  		var got Timestamp
   165  		err := json.Unmarshal([]byte(tc.data), &got)
   166  		if gotErr := err != nil; gotErr != tc.wantErr {
   167  			t.Errorf("%s: gotErr=%v, wantErr=%v, err=%v", tc.desc, gotErr, tc.wantErr, err)
   168  			continue
   169  		}
   170  		equal := got.Time.Equal(tc.want.Time.Time)
   171  		if equal != tc.equal {
   172  			t.Errorf("%s: got=%#v, want=%#v, equal=%v, want=%v", tc.desc, got, tc.want, equal, tc.equal)
   173  		}
   174  	}
   175  }
   176  
   177  func TestTimestamp_GetTime(t *testing.T) {
   178  	t.Parallel()
   179  	var t1 *Timestamp
   180  	if t1.GetTime() != nil {
   181  		t.Errorf("nil timestamp should return nil, got: %v", t1.GetTime())
   182  	}
   183  	t1 = &Timestamp{referenceTime}
   184  	if !t1.GetTime().Equal(referenceTime) {
   185  		t.Errorf("want reference time, got: %s", t1.GetTime().String())
   186  	}
   187  }
   188  
   189  func TestWrappedTimestamp_MarshalReflexivity(t *testing.T) {
   190  	t.Parallel()
   191  	testCases := []struct {
   192  		desc string
   193  		data WrappedTimestamp
   194  	}{
   195  		{"Reference", WrappedTimestamp{0, Timestamp{referenceTime}}},
   196  		{"Empty", WrappedTimestamp{0, Timestamp{}}},
   197  	}
   198  	for _, tc := range testCases {
   199  		bytes, err := json.Marshal(tc.data)
   200  		if err != nil {
   201  			t.Errorf("%s: Marshal err=%v", tc.desc, err)
   202  		}
   203  		var got WrappedTimestamp
   204  		err = json.Unmarshal(bytes, &got)
   205  		if err != nil {
   206  			t.Errorf("%s: Unmarshal err=%v", tc.desc, err)
   207  		}
   208  		if !got.Time.Equal(tc.data.Time) {
   209  			t.Errorf("%s: %+v != %+v", tc.desc, got, tc.data)
   210  		}
   211  	}
   212  }