github.com/mailgun/holster/v4@v4.20.0/clock/rfc822_test.go (about)

     1  package clock
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"gopkg.in/yaml.v3"
    11  )
    12  
    13  type testStruct struct {
    14  	Time RFC822Time `json:"ts" yaml:"ts"`
    15  }
    16  
    17  func TestRFC822New(t *testing.T) {
    18  	stdTime, err := Parse(RFC3339, "2019-08-29T11:20:07.123456+03:00")
    19  	assert.NoError(t, err)
    20  
    21  	rfc822TimeFromTime := NewRFC822Time(stdTime)
    22  	rfc822TimeFromUnix := NewRFC822TimeFromUnix(stdTime.Unix())
    23  	assert.True(t, rfc822TimeFromTime.Equal(rfc822TimeFromUnix.Time),
    24  		"want=%s, got=%s", rfc822TimeFromTime.Time, rfc822TimeFromUnix.Time)
    25  
    26  	// Parsing from numerical offset to abbreviated offset is not always reliable. In this
    27  	// context Go will fallback to the known numerical offset.
    28  	assert.Equal(t, "Thu, 29 Aug 2019 11:20:07 +0300", rfc822TimeFromTime.String())
    29  	assert.Equal(t, "Thu, 29 Aug 2019 08:20:07 UTC", rfc822TimeFromUnix.String())
    30  }
    31  
    32  // NewRFC822Time truncates to second precision.
    33  func TestRFC822SecondPrecision(t *testing.T) {
    34  	stdTime1, err := Parse(RFC3339, "2019-08-29T11:20:07.111111+03:00")
    35  	assert.NoError(t, err)
    36  	stdTime2, err := Parse(RFC3339, "2019-08-29T11:20:07.999999+03:00")
    37  	assert.NoError(t, err)
    38  	assert.False(t, stdTime1.Equal(stdTime2))
    39  
    40  	rfc822Time1 := NewRFC822Time(stdTime1)
    41  	rfc822Time2 := NewRFC822Time(stdTime2)
    42  	assert.True(t, rfc822Time1.Equal(rfc822Time2.Time),
    43  		"want=%s, got=%s", rfc822Time1.Time, rfc822Time2.Time)
    44  }
    45  
    46  func TestRFC822YAMLMarshaler(t *testing.T) {
    47  	rfcTime := NewRFC822Time(Date(1955, November, 12, 6, 38, 0, 0, UTC))
    48  	ts := testStruct{Time: rfcTime}
    49  	encoded, err := yaml.Marshal(ts)
    50  	assert.NoError(t, err)
    51  	assert.Equal(t, "ts: Sat, 12 Nov 1955 06:38:00 UTC\n", string(encoded))
    52  
    53  	var decoded testStruct
    54  	err = yaml.Unmarshal(encoded, &decoded)
    55  	assert.NoError(t, err)
    56  	assert.Equal(t, rfcTime, decoded.Time)
    57  }
    58  
    59  // Marshaled representation is truncated down to second precision.
    60  func TestRFC822Marshaling(t *testing.T) {
    61  	stdTime, err := Parse(RFC3339Nano, "2019-08-29T11:20:07.123456789+03:30")
    62  	assert.NoError(t, err)
    63  
    64  	ts := testStruct{Time: NewRFC822Time(stdTime)}
    65  	encoded, err := json.Marshal(&ts)
    66  	assert.NoError(t, err)
    67  	assert.Equal(t, `{"ts":"Thu, 29 Aug 2019 11:20:07 +0330"}`, string(encoded))
    68  }
    69  
    70  func TestRFC822Unmarshaling(t *testing.T) {
    71  	for i, tc := range []struct {
    72  		inRFC822   string
    73  		outRFC3339 string
    74  		outRFC822  string
    75  	}{{
    76  		inRFC822:   "Thu, 29 Aug 2019 11:20:07 GMT",
    77  		outRFC3339: "2019-08-29T11:20:07Z",
    78  		outRFC822:  "Thu, 29 Aug 2019 11:20:07 GMT",
    79  	}, {
    80  		inRFC822: "Thu, 29 Aug 2019 11:20:07 MSK",
    81  		// Extrapolating the numerical offset from an abbreviated offset is unreliable. In
    82  		// this test case the RFC3339 will have the incorrect result due to limitation in
    83  		// Go's time parser.
    84  		outRFC3339: "2019-08-29T11:20:07Z",
    85  		outRFC822:  "Thu, 29 Aug 2019 11:20:07 MSK",
    86  	}, {
    87  		inRFC822:   "Thu, 29 Aug 2019 11:20:07 -0000",
    88  		outRFC3339: "2019-08-29T11:20:07Z",
    89  		outRFC822:  "Thu, 29 Aug 2019 11:20:07 -0000",
    90  	}, {
    91  		inRFC822:   "Thu, 29 Aug 2019 11:20:07 +0000",
    92  		outRFC3339: "2019-08-29T11:20:07Z",
    93  		outRFC822:  "Thu, 29 Aug 2019 11:20:07 +0000",
    94  	}, {
    95  		inRFC822:   "Thu, 29 Aug 2019 11:20:07 +0300",
    96  		outRFC3339: "2019-08-29T11:20:07+03:00",
    97  		outRFC822:  "Thu, 29 Aug 2019 11:20:07 +0300",
    98  	}, {
    99  		inRFC822:   "Thu, 29 Aug 2019 11:20:07 +0330",
   100  		outRFC3339: "2019-08-29T11:20:07+03:30",
   101  		outRFC822:  "Thu, 29 Aug 2019 11:20:07 +0330",
   102  	}, {
   103  		inRFC822:   "Sun, 01 Sep 2019 11:20:07 +0300",
   104  		outRFC3339: "2019-09-01T11:20:07+03:00",
   105  		outRFC822:  "Sun, 01 Sep 2019 11:20:07 +0300",
   106  	}, {
   107  		inRFC822:   "Sun,  1 Sep 2019 11:20:07 +0300",
   108  		outRFC3339: "2019-09-01T11:20:07+03:00",
   109  		outRFC822:  "Sun, 01 Sep 2019 11:20:07 +0300",
   110  	}, {
   111  		inRFC822:   "Sun, 1 Sep 2019 11:20:07 +0300",
   112  		outRFC3339: "2019-09-01T11:20:07+03:00",
   113  		outRFC822:  "Sun, 01 Sep 2019 11:20:07 +0300",
   114  	}, {
   115  		inRFC822:   "Sun, 1 Sep 2019 11:20:07 UTC",
   116  		outRFC3339: "2019-09-01T11:20:07Z",
   117  		outRFC822:  "Sun, 01 Sep 2019 11:20:07 UTC",
   118  	}, {
   119  		inRFC822:   "Sun, 1 Sep 2019 11:20:07 UTC",
   120  		outRFC3339: "2019-09-01T11:20:07Z",
   121  		outRFC822:  "Sun, 01 Sep 2019 11:20:07 UTC",
   122  	}, {
   123  		inRFC822:   "Sun, 1 Sep 2019 11:20:07 GMT",
   124  		outRFC3339: "2019-09-01T11:20:07Z",
   125  		outRFC822:  "Sun, 01 Sep 2019 11:20:07 GMT",
   126  	}, {
   127  		inRFC822:   "Fri, 21 Nov 1997 09:55:06 -0600 (MDT)",
   128  		outRFC3339: "1997-11-21T09:55:06-06:00",
   129  		outRFC822:  "Fri, 21 Nov 1997 09:55:06 MDT",
   130  	}} {
   131  		t.Run(tc.inRFC822, func(t *testing.T) {
   132  			tcDesc := fmt.Sprintf("Test case #%d: %v", i, tc)
   133  			var ts testStruct
   134  
   135  			inEncoded := []byte(fmt.Sprintf(`{"ts":%q}`, tc.inRFC822))
   136  			err := json.Unmarshal(inEncoded, &ts)
   137  			assert.NoError(t, err, tcDesc)
   138  			assert.Equal(t, tc.outRFC3339, ts.Time.Format(RFC3339), tcDesc)
   139  
   140  			actualEncoded, err := json.Marshal(&ts)
   141  			assert.NoError(t, err, tcDesc)
   142  			outEncoded := fmt.Sprintf(`{"ts":%q}`, tc.outRFC822)
   143  			assert.Equal(t, outEncoded, string(actualEncoded), tcDesc)
   144  		})
   145  	}
   146  }
   147  
   148  func TestRFC822UnmarshalingError(t *testing.T) {
   149  	for _, tc := range []struct {
   150  		inEncoded string
   151  		outError  string
   152  	}{{
   153  		inEncoded: `{"ts": "Thu, 29 Aug 2019 11:20:07"}`,
   154  		outError:  `parsing time "Thu, 29 Aug 2019 11:20:07" as "January 2 2006 15:04 -0700 (MST)": cannot parse "Thu, 29 Aug 2019 11:20:07" as "January"`,
   155  	}, {
   156  		inEncoded: `{"ts": "foo"}`,
   157  		outError:  `parsing time "foo" as "January 2 2006 15:04 -0700 (MST)": cannot parse "foo" as "January"`,
   158  	}, {
   159  		inEncoded: `{"ts": 42}`,
   160  		outError:  "invalid syntax",
   161  	}} {
   162  		t.Run(tc.inEncoded, func(t *testing.T) {
   163  			var ts testStruct
   164  			err := json.Unmarshal([]byte(tc.inEncoded), &ts)
   165  			assert.EqualError(t, err, tc.outError)
   166  		})
   167  	}
   168  }
   169  
   170  func TestParseRFC822Time(t *testing.T) {
   171  	for _, tt := range []struct {
   172  		rfc822Time string
   173  	}{
   174  		{"Thu, 3 Jun 2021 12:01:05 MST"},
   175  		{"Thu, 3 Jun 2021 12:01:05 -0700"},
   176  		{"Thu, 3 Jun 2021 12:01:05 -0700 (MST)"},
   177  		{"2 Jun 2021 17:06:41 GMT"},
   178  		{"2 Jun 2021 17:06:41 -0700"},
   179  		{"2 Jun 2021 17:06:41 -0700 (MST)"},
   180  		{"Mon, 30 August 2021 11:05:00 -0400"},
   181  		{"Thu, 3 June 2021 12:01:05 MST"},
   182  		{"Thu, 3 June 2021 12:01:05 -0700"},
   183  		{"Thu, 3 June 2021 12:01:05 -0700 (MST)"},
   184  		{"2 June 2021 17:06:41 GMT"},
   185  		{"2 June 2021 17:06:41 -0700"},
   186  		{"2 June 2021 17:06:41 -0700 (MST)"},
   187  		{"Wed, Nov 03 2021 17:48:06 CST"},
   188  		{"Wed, November 03 2021 17:48:06 CST"},
   189  
   190  		// Timestamps without seconds.
   191  		{"Sun, 31 Oct 2021 12:10 -5000"},
   192  		{"Thu, 3 Jun 2021 12:01 MST"},
   193  		{"Thu, 3 Jun 2021 12:01 -0700"},
   194  		{"Thu, 3 Jun 2021 12:01 -0700 (MST)"},
   195  		{"2 Jun 2021 17:06 GMT"},
   196  		{"2 Jun 2021 17:06 -0700"},
   197  		{"2 Jun 2021 17:06 -0700 (MST)"},
   198  		{"Mon, 30 August 2021 11:05 -0400"},
   199  		{"Thu, 3 June 2021 12:01 MST"},
   200  		{"Thu, 3 June 2021 12:01 -0700"},
   201  		{"Thu, 3 June 2021 12:01 -0700 (MST)"},
   202  		{"2 June 2021 17:06 GMT"},
   203  		{"2 June 2021 17:06 -0700"},
   204  		{"2 June 2021 17:06 -0700 (MST)"},
   205  		{"Wed, Nov 03 2021 17:48 CST"},
   206  		{"Wed, November 03 2021 17:48 CST"},
   207  	} {
   208  		t.Run(tt.rfc822Time, func(t *testing.T) {
   209  			_, err := ParseRFC822Time(tt.rfc822Time)
   210  			assert.NoError(t, err)
   211  		})
   212  	}
   213  }
   214  
   215  func TestStringWithOffset(t *testing.T) {
   216  	now := time.Now().UTC()
   217  	r := NewRFC822Time(now)
   218  	assert.Equal(t, now.Format(time.RFC1123Z), r.StringWithOffset())
   219  }