github.com/wI2L/jettison@v0.7.5-0.20230106001914-c70014c6417a/time_test.go (about) 1 package jettison 2 3 import ( 4 "fmt" 5 "math/rand" 6 "strconv" 7 "testing" 8 "time" 9 ) 10 11 func TestDurationFmtString(t *testing.T) { 12 testdata := []struct { 13 fmt DurationFmt 14 str string 15 }{ 16 {DurationString, "str"}, 17 {DurationMinutes, "min"}, 18 {DurationSeconds, "s"}, 19 {DurationMilliseconds, "ms"}, 20 {DurationMicroseconds, "μs"}, 21 {DurationNanoseconds, "nanosecond"}, 22 {DurationFmt(-1), "unknown"}, 23 {DurationFmt(6), "unknown"}, 24 } 25 for _, tt := range testdata { 26 if s := tt.fmt.String(); s != tt.str { 27 t.Errorf("got %q, want %q", s, tt.str) 28 } 29 } 30 } 31 32 func TestIssue2(t *testing.T) { 33 type x struct { 34 F time.Duration `json:"foobar" yaml:"foobar"` 35 } 36 xx := &x{} 37 b, err := MarshalOpts(xx, DurationFormat(DurationString)) 38 if err != nil { 39 t.Error(err) 40 } 41 const want = `{"foobar":"0s"}` 42 43 if s := string(b); s != want { 44 t.Errorf("expected %q, got %q", want, s) 45 } 46 } 47 48 func TestAppendDuration(t *testing.T) { 49 // Taken from https://golang.org/src/time/time_test.go 50 var testdata = []struct { 51 str string 52 dur time.Duration 53 }{ 54 {"0s", 0}, 55 {"1ns", 1 * time.Nanosecond}, 56 {"1.1µs", 1100 * time.Nanosecond}, 57 {"2.2ms", 2200 * time.Microsecond}, 58 {"3.3s", 3300 * time.Millisecond}, 59 {"4m5s", 4*time.Minute + 5*time.Second}, 60 {"4m5.001s", 4*time.Minute + 5001*time.Millisecond}, 61 {"5h6m7.001s", 5*time.Hour + 6*time.Minute + 7001*time.Millisecond}, 62 {"8m0.000000001s", 8*time.Minute + 1*time.Nanosecond}, 63 {"2562047h47m16.854775807s", 1<<63 - 1}, 64 {"-2562047h47m16.854775808s", -1 << 63}, 65 } 66 for _, tt := range testdata { 67 buf := appendDuration(make([]byte, 0, 32), tt.dur) 68 69 if s := string(buf); s != tt.str { 70 t.Errorf("got %q, want %q", s, tt.str) 71 } 72 if tt.dur > 0 { 73 buf = make([]byte, 0, 32) 74 buf = appendDuration(buf, -tt.dur) 75 if s := string(buf); s != "-"+tt.str { 76 t.Errorf("got %q, want %q", s, "-"+tt.str) 77 } 78 } 79 } 80 } 81 82 func TestAppendRFC3339Time(t *testing.T) { 83 rand.Seed(time.Now().UnixNano()) 84 var ( 85 bat int 86 buf []byte 87 ) 88 for _, nano := range []bool{true, false} { 89 for i := 0; i < 1e3; i++ { 90 if testing.Short() && i > 1e2 { 91 break 92 } 93 // Generate a location with a random offset 94 // between 0 and 12 hours. 95 off := rand.Intn(12*60 + 1) 96 if rand.Intn(2) == 0 { // coin flip 97 off = -off 98 } 99 loc := time.FixedZone("", off) 100 101 // Generate a random time between now and the 102 // Unix epoch, with random fractional seconds. 103 ts := rand.Int63n(time.Now().Unix() + 1) 104 tm := time.Unix(ts, rand.Int63n(999999999+1)).In(loc) 105 106 layout := time.RFC3339 107 if nano { 108 layout = time.RFC3339Nano 109 } 110 bat = len(buf) 111 buf = appendRFC3339Time(tm, buf, nano) 112 113 // The time encodes with double-quotes. 114 want := strconv.Quote(tm.Format(layout)) 115 116 if s := string(buf[bat:]); s != want { 117 t.Errorf("got %s, want %s", s, want) 118 } 119 } 120 } 121 } 122 123 //nolint:scopelint 124 func BenchmarkRFC3339Time(b *testing.B) { 125 if testing.Short() { 126 b.SkipNow() 127 } 128 tm := time.Now() 129 130 for _, tt := range []struct { 131 name string 132 layout string 133 }{ 134 {"", time.RFC3339}, 135 {"-nano", time.RFC3339Nano}, 136 } { 137 b.Run(fmt.Sprintf("%s%s", "jettison", tt.name), func(b *testing.B) { 138 b.ReportAllocs() 139 for i := 0; i < b.N; i++ { 140 buf := make([]byte, 32) 141 appendRFC3339Time(tm, buf, tt.layout == time.RFC3339Nano) 142 } 143 }) 144 b.Run(fmt.Sprintf("%s%s", "standard", tt.name), func(b *testing.B) { 145 b.ReportAllocs() 146 for i := 0; i < b.N; i++ { 147 buf := make([]byte, 32) 148 tm.AppendFormat(buf, tt.layout) 149 } 150 }) 151 } 152 }