...

Source file src/github.com/gogo/protobuf/types/timestamp_test.go

Documentation: github.com/gogo/protobuf/types

     1  // Go support for Protocol Buffers - Google's data interchange format
     2  //
     3  // Copyright 2016 The Go Authors.  All rights reserved.
     4  // https://github.com/golang/protobuf
     5  //
     6  // Redistribution and use in source and binary forms, with or without
     7  // modification, are permitted provided that the following conditions are
     8  // met:
     9  //
    10  //     * Redistributions of source code must retain the above copyright
    11  // notice, this list of conditions and the following disclaimer.
    12  //     * Redistributions in binary form must reproduce the above
    13  // copyright notice, this list of conditions and the following disclaimer
    14  // in the documentation and/or other materials provided with the
    15  // distribution.
    16  //     * Neither the name of Google Inc. nor the names of its
    17  // contributors may be used to endorse or promote products derived from
    18  // this software without specific prior written permission.
    19  //
    20  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31  
    32  package types
    33  
    34  import (
    35  	"math"
    36  	"testing"
    37  	"time"
    38  
    39  	"github.com/gogo/protobuf/proto"
    40  )
    41  
    42  var tests = []struct {
    43  	ts    *Timestamp
    44  	valid bool
    45  	t     time.Time
    46  }{
    47  	// The timestamp representing the Unix epoch date.
    48  	{&Timestamp{Seconds: 0, Nanos: 0}, true, utcDate(1970, 1, 1)},
    49  	// The smallest representable timestamp.
    50  	{&Timestamp{Seconds: math.MinInt64, Nanos: math.MinInt32}, false,
    51  		time.Unix(math.MinInt64, math.MinInt32).UTC()},
    52  	// The smallest representable timestamp with non-negative nanos.
    53  	{&Timestamp{Seconds: math.MinInt64, Nanos: 0}, false, time.Unix(math.MinInt64, 0).UTC()},
    54  	// The earliest valid timestamp.
    55  	{&Timestamp{Seconds: minValidSeconds, Nanos: 0}, true, utcDate(1, 1, 1)},
    56  	//"0001-01-01T00:00:00Z"},
    57  	// The largest representable timestamp.
    58  	{&Timestamp{Seconds: math.MaxInt64, Nanos: math.MaxInt32}, false,
    59  		time.Unix(math.MaxInt64, math.MaxInt32).UTC()},
    60  	// The largest representable timestamp with nanos in range.
    61  	{&Timestamp{Seconds: math.MaxInt64, Nanos: 1e9 - 1}, false,
    62  		time.Unix(math.MaxInt64, 1e9-1).UTC()},
    63  	// The largest valid timestamp.
    64  	{&Timestamp{Seconds: maxValidSeconds - 1, Nanos: 1e9 - 1}, true,
    65  		time.Date(9999, 12, 31, 23, 59, 59, 1e9-1, time.UTC)},
    66  	// The smallest invalid timestamp that is larger than the valid range.
    67  	{&Timestamp{Seconds: maxValidSeconds, Nanos: 0}, false, time.Unix(maxValidSeconds, 0).UTC()},
    68  	// A date before the epoch.
    69  	{&Timestamp{Seconds: -281836800, Nanos: 0}, true, utcDate(1961, 1, 26)},
    70  	// A date after the epoch.
    71  	{&Timestamp{Seconds: 1296000000, Nanos: 0}, true, utcDate(2011, 1, 26)},
    72  	// A date after the epoch, in the middle of the day.
    73  	{&Timestamp{Seconds: 1296012345, Nanos: 940483}, true,
    74  		time.Date(2011, 1, 26, 3, 25, 45, 940483, time.UTC)},
    75  }
    76  
    77  func TestValidateTimestamp(t *testing.T) {
    78  	for _, s := range tests {
    79  		got := validateTimestamp(s.ts)
    80  		if (got == nil) != s.valid {
    81  			t.Errorf("validateTimestamp(%v) = %v, want %v", s.ts, got, s.valid)
    82  		}
    83  	}
    84  }
    85  
    86  func TestTimestampFromProto(t *testing.T) {
    87  	for _, s := range tests {
    88  		got, err := TimestampFromProto(s.ts)
    89  		if (err == nil) != s.valid {
    90  			t.Errorf("TimestampFromProto(%v) error = %v, but valid = %t", s.ts, err, s.valid)
    91  		} else if s.valid && got != s.t {
    92  			t.Errorf("TimestampFromProto(%v) = %v, want %v", s.ts, got, s.t)
    93  		}
    94  	}
    95  	// Special case: a nil TimestampFromProto is an error, but returns the 0 Unix time.
    96  	got, err := TimestampFromProto(nil)
    97  	want := time.Unix(0, 0).UTC()
    98  	if got != want {
    99  		t.Errorf("TimestampFromProto(nil) = %v, want %v", got, want)
   100  	}
   101  	if err == nil {
   102  		t.Errorf("TimestampFromProto(nil) error = nil, expected error")
   103  	}
   104  }
   105  
   106  func TestTimestampProto(t *testing.T) {
   107  	for _, s := range tests {
   108  		got, err := TimestampProto(s.t)
   109  		if (err == nil) != s.valid {
   110  			t.Errorf("TimestampProto(%v) error = %v, but valid = %t", s.t, err, s.valid)
   111  		} else if s.valid && !proto.Equal(got, s.ts) {
   112  			t.Errorf("TimestampProto(%v) = %v, want %v", s.t, got, s.ts)
   113  		}
   114  	}
   115  	// No corresponding special case here: no time.Time results in a nil Timestamp.
   116  }
   117  
   118  func TestTimestampString(t *testing.T) {
   119  	for _, test := range []struct {
   120  		ts   *Timestamp
   121  		want string
   122  	}{
   123  		// Not much testing needed because presumably time.Format is
   124  		// well-tested.
   125  		{&Timestamp{Seconds: 0, Nanos: 0}, "1970-01-01T00:00:00Z"},
   126  		{&Timestamp{Seconds: minValidSeconds - 1, Nanos: 0}, "(timestamp: &types.Timestamp{Seconds: -62135596801,\nNanos: 0,\n} before 0001-01-01)"},
   127  	} {
   128  		got := TimestampString(test.ts)
   129  		if got != test.want {
   130  			t.Errorf("TimestampString(%v) = %q, want %q", test.ts, got, test.want)
   131  		}
   132  	}
   133  }
   134  
   135  func utcDate(year, month, day int) time.Time {
   136  	return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
   137  }
   138  
   139  func TestTimestampNow(t *testing.T) {
   140  	// Bracket the expected time.
   141  	before := time.Now()
   142  	ts := TimestampNow()
   143  	after := time.Now()
   144  
   145  	tm, err := TimestampFromProto(ts)
   146  	if err != nil {
   147  		t.Errorf("between %v and %v\nTimestampNow() = %v\nwhich is invalid (%v)", before, after, ts, err)
   148  	}
   149  	if tm.Before(before) || tm.After(after) {
   150  		t.Errorf("between %v and %v\nTimestamp(TimestampNow()) = %v", before, after, tm)
   151  	}
   152  }
   153  

View as plain text