github.com/whiteCcinn/protobuf-go@v1.0.9/types/known/durationpb/duration_test.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package durationpb_test
     6  
     7  import (
     8  	"math"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/google/go-cmp/cmp"
    14  	"github.com/google/go-cmp/cmp/cmpopts"
    15  	"github.com/whiteCcinn/protobuf-go/internal/detrand"
    16  	"github.com/whiteCcinn/protobuf-go/testing/protocmp"
    17  
    18  	durpb "github.com/whiteCcinn/protobuf-go/types/known/durationpb"
    19  )
    20  
    21  func init() {
    22  	detrand.Disable()
    23  }
    24  
    25  const (
    26  	minGoSeconds = math.MinInt64 / int64(1e9)
    27  	maxGoSeconds = math.MaxInt64 / int64(1e9)
    28  	absSeconds   = 315576000000 // 10000yr * 365.25day/yr * 24hr/day * 60min/hr * 60sec/min
    29  )
    30  
    31  func TestToDuration(t *testing.T) {
    32  	tests := []struct {
    33  		in   time.Duration
    34  		want *durpb.Duration
    35  	}{
    36  		{in: time.Duration(0), want: &durpb.Duration{Seconds: 0, Nanos: 0}},
    37  		{in: -time.Second, want: &durpb.Duration{Seconds: -1, Nanos: 0}},
    38  		{in: +time.Second, want: &durpb.Duration{Seconds: +1, Nanos: 0}},
    39  		{in: -time.Second - time.Millisecond, want: &durpb.Duration{Seconds: -1, Nanos: -1e6}},
    40  		{in: +time.Second + time.Millisecond, want: &durpb.Duration{Seconds: +1, Nanos: +1e6}},
    41  		{in: time.Duration(math.MinInt64), want: &durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}},
    42  		{in: time.Duration(math.MaxInt64), want: &durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}},
    43  	}
    44  
    45  	for _, tt := range tests {
    46  		got := durpb.New(tt.in)
    47  		if diff := cmp.Diff(tt.want, got, protocmp.Transform()); diff != "" {
    48  			t.Errorf("New(%v) mismatch (-want +got):\n%s", tt.in, diff)
    49  		}
    50  	}
    51  }
    52  
    53  func TestFromDuration(t *testing.T) {
    54  	tests := []struct {
    55  		in      *durpb.Duration
    56  		wantDur time.Duration
    57  		wantErr error
    58  	}{
    59  		{in: nil, wantDur: time.Duration(0), wantErr: textError("invalid nil Duration")},
    60  		{in: new(durpb.Duration), wantDur: time.Duration(0)},
    61  		{in: &durpb.Duration{Seconds: -1, Nanos: 0}, wantDur: -time.Second},
    62  		{in: &durpb.Duration{Seconds: +1, Nanos: 0}, wantDur: +time.Second},
    63  		{in: &durpb.Duration{Seconds: 0, Nanos: -1}, wantDur: -time.Nanosecond},
    64  		{in: &durpb.Duration{Seconds: 0, Nanos: +1}, wantDur: +time.Nanosecond},
    65  		{in: &durpb.Duration{Seconds: -100, Nanos: 0}, wantDur: -100 * time.Second},
    66  		{in: &durpb.Duration{Seconds: +100, Nanos: 0}, wantDur: +100 * time.Second},
    67  		{in: &durpb.Duration{Seconds: -100, Nanos: -987}, wantDur: -100*time.Second - 987*time.Nanosecond},
    68  		{in: &durpb.Duration{Seconds: +100, Nanos: +987}, wantDur: +100*time.Second + 987*time.Nanosecond},
    69  		{in: &durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, wantDur: time.Duration(math.MinInt64)},
    70  		{in: &durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, wantDur: time.Duration(math.MaxInt64)},
    71  		{in: &durpb.Duration{Seconds: minGoSeconds - 1, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, wantDur: time.Duration(math.MinInt64)},
    72  		{in: &durpb.Duration{Seconds: maxGoSeconds + 1, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, wantDur: time.Duration(math.MaxInt64)},
    73  		{in: &durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64-1e9*minGoSeconds) - 1}, wantDur: time.Duration(math.MinInt64)},
    74  		{in: &durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64-1e9*maxGoSeconds) + 1}, wantDur: time.Duration(math.MaxInt64)},
    75  		{in: &durpb.Duration{Seconds: -123, Nanos: +456}, wantDur: -123*time.Second + 456*time.Nanosecond, wantErr: textError("duration (seconds:-123 nanos:456) has seconds and nanos with different signs")},
    76  		{in: &durpb.Duration{Seconds: +123, Nanos: -456}, wantDur: +123*time.Second - 456*time.Nanosecond, wantErr: textError("duration (seconds:123 nanos:-456) has seconds and nanos with different signs")},
    77  		{in: &durpb.Duration{Seconds: math.MinInt64}, wantDur: time.Duration(math.MinInt64), wantErr: textError("duration (seconds:-9223372036854775808) exceeds -10000 years")},
    78  		{in: &durpb.Duration{Seconds: math.MaxInt64}, wantDur: time.Duration(math.MaxInt64), wantErr: textError("duration (seconds:9223372036854775807) exceeds +10000 years")},
    79  		{in: &durpb.Duration{Seconds: -absSeconds, Nanos: -(1e9 - 1)}, wantDur: time.Duration(math.MinInt64)},
    80  		{in: &durpb.Duration{Seconds: +absSeconds, Nanos: +(1e9 - 1)}, wantDur: time.Duration(math.MaxInt64)},
    81  		{in: &durpb.Duration{Seconds: -absSeconds - 1, Nanos: 0}, wantDur: time.Duration(math.MinInt64), wantErr: textError("duration (seconds:-315576000001) exceeds -10000 years")},
    82  		{in: &durpb.Duration{Seconds: +absSeconds + 1, Nanos: 0}, wantDur: time.Duration(math.MaxInt64), wantErr: textError("duration (seconds:315576000001) exceeds +10000 years")},
    83  	}
    84  
    85  	for _, tt := range tests {
    86  		gotDur := tt.in.AsDuration()
    87  		if diff := cmp.Diff(tt.wantDur, gotDur); diff != "" {
    88  			t.Errorf("AsDuration(%v) mismatch (-want +got):\n%s", tt.in, diff)
    89  		}
    90  		gotErr := tt.in.CheckValid()
    91  		if diff := cmp.Diff(tt.wantErr, gotErr, cmpopts.EquateErrors()); diff != "" {
    92  			t.Errorf("CheckValid(%v) mismatch (-want +got):\n%s", tt.in, diff)
    93  		}
    94  	}
    95  }
    96  
    97  type textError string
    98  
    99  func (e textError) Error() string     { return string(e) }
   100  func (e textError) Is(err error) bool { return err != nil && strings.Contains(err.Error(), e.Error()) }