1
0
mirror of https://github.com/rs/zerolog synced 2026-06-08 17:13:30 +00:00
Files
rs-zerolog/internal/cbor/time_test.go
T
Marc Brooks 8148645974 Chore improve test coverage (#735)
* Add array handling of IPAddr and IPPrefix

Updated documentation, benchmark, and tests including catching up some missing.
Cleaned up couple lint messages

* Added cbor encoding for []net.IP and []net.IPNet

* Fix binary_test

Typos galore, thanks CI

* Remove feral x character

* Added IPAddrs and IPPrefixes tests for json encoder

* Increase code coverage and test cleanup

Added Type to the BenchmarkLogFieldType and BenchmarkContexdtFieldType test cases, also to log_test.go
Moved the test-fixture data for them and also shared them with new event test for nil events.
Added a couple strings for encodeByteTest for FF, CR, LF
Added complete cbor testing for AppendInt*, AppendInts*, AppendUint*, and AppendUints* methods.
Added test for float IsNaN and Inf(0) and Inf(-1).
Added all min/max/smallest value tests for ints and floats
Extended the Array test to include IPPrefix, MACAddr, Interface, and object marshaled.
Better test of MarshalZerologObject.
Added test for encoder AppendStrings and AppendStringers.

* Remove merge detritus.

* Remove code duplication when appending objects

* Add missing Stringers support to Context

* Add test cases for Err and Object in Array

* Add missing benchmark for Events and Contexts

Events: Any, Bytes, Hex, Float32, Floats32, Stringer, Stringers, Timestamp
Context: Any, Bytes, Hex, Float32, Floats32, Stringers
(also renamed Float,Floats to Float64,Floats64)

* Add test of MarshalZeroLogObject of error

* Build out Event test cases

Test of nil Event
- write
- Array, Dict
- Fields
- Int8, Ints8, Int16, Ints16, Int32, Ints32, Int64, Ints64
- Uint8, Uints8, Uint16, Uints16, Uint32, Uints32, Uint64, Uints64
- RawCBOR, RawJSON, EmbedObject
- Stringers
- Caller, CallerSkip, Stack
- Send, Msg, Msgf, MsgFunc
- (renamed tests of Float, Floats to Float64, Floats64)

Added test of MsgFunc

* Add more tests

- Dur (With)
- Any (With, Fields, Fields map, Disabled)
- Interface
- Stack (Fields)

Fix issue with testing a nil loggableError

* Split out the With tests again type arrays

Simplifies the "want" maintenance

* Add missing test fixture data

Bytes, Floats32, Ints8, Ints16, Ints32, Ints64, Uints8, Uints16, Uints32, Uints64, RawJSON, RawCBOR
Stringers is now an array (not a single Stringer)
(also renamed Float, Floats to Float64, Floats64)

* Add examples for IPAddrs, IPPrefixes, Times

Missing examples that increase coverage

* Build out the complete ErrorMarshalFunc tests

* Add AppendStrings to CBOR tests

* Add CBOR AppendTimes, AppendDuration, AppendDurations tests

* Add CBOR tests

- BeginMarker, EndMarker, AppendArrayDim, AppendLineBreak
- AppendObjectData
- AppendIterface
- AppendType
- AppendHex
- Empty arrays for
  - Bools
  - Floats32, Floats64
- Large arrays for
  - Bools,
  - Uints8, Uints16, Uints32, Uints64
  - Floats32, Floats64
  - IPAddrs, IPPrefixes
- Small arrays for
  - Ints, Ints8, Ints16, Ints32, Ints64
  - Uints, Uints32, Uints64
  - Floats32, Floats64

* Add CBOR test for AppendKey

* Added more string encoding tests

Test escape character handling.

* Fix test import cycle

* Rename hex to hexCharacters to avoid namespace.

* Remove leftover comment

* Add test cases to share between CBOR and JSON tests

* Switched CBOR to shared test cases

* Add JSON test for AppendKey

* Switch to shared test cases

Added test for AppendStringer

* Added JSON test

- AppendNil
- AppendBeginMarker, AppendEndMarker
- AppendArrayStart, AppendArrayEnd
- AppendArrayDelim
- AppendLineBreak
- AppendObjectData
- AppendInterface
- AppendBool, AppendBools

* Add JSON time tests

- AppendTime, AppendTimes
- AppendTime (past/present) (integer/float)
- AppendDuration, AppendDurations

* Added JSON tests for plurals

Split out the Int and Float tests into distinct files.
Add
 - AppendInt
 - AppendInts8, AppendInts16, AppendInts32, AppendInts64, AppendInts
 - AppendUints8, AppendUints16, AppendUints32, AppendUints64, AppendUints
- AppendFloats32, AppendFloats64
2025-12-15 20:55:37 +01:00

210 lines
6.0 KiB
Go

package cbor
import (
"bytes"
"encoding/hex"
"fmt"
"math"
"testing"
"time"
"github.com/rs/zerolog/internal"
)
func TestAppendTimeNow(t *testing.T) {
tm := time.Now()
s := enc.AppendTime([]byte{}, tm, "unused")
got := string(s)
tm1 := float64(tm.Unix()) + float64(tm.Nanosecond())*1e-9
tm2 := math.Float64bits(tm1)
var tm3 [8]byte
for i := uint(0); i < 8; i++ {
tm3[i] = byte(tm2 >> ((8 - i - 1) * 8))
}
want := append([]byte{0xc1, 0xfb}, tm3[:]...)
if got != string(want) {
t.Errorf("Appendtime(%s)=0x%s, want: 0x%s",
"time.Now()", hex.EncodeToString(s),
hex.EncodeToString(want))
}
}
func TestAppendTimePastPresentInteger(t *testing.T) {
for _, tt := range internal.TimeIntegerTestcases {
tin, err := time.Parse(time.RFC3339, tt.Txt)
if err != nil {
fmt.Println("Cannot parse input", tt.Txt, ".. Skipping!", err)
continue
}
b := enc.AppendTime([]byte{}, tin, "unused")
if got, want := string(b), tt.Binary; got != want {
t.Errorf("appendString(%s) = 0x%s, want 0x%s", tt.Txt,
hex.EncodeToString(b),
hex.EncodeToString([]byte(want)))
}
}
}
func TestAppendTimePastPresentFloat(t *testing.T) {
const timeFloatFmt = "2006-01-02T15:04:05.999999-07:00"
for _, tt := range internal.TimeFloatTestcases {
tin, err := time.Parse(timeFloatFmt, tt.RfcStr)
if err != nil {
fmt.Println("Cannot parse input", tt.RfcStr, ".. Skipping!")
continue
}
b := enc.AppendTime([]byte{}, tin, "unused")
if got, want := string(b), tt.Out; got != want {
t.Errorf("appendString(%s) = 0x%s, want 0x%s", tt.RfcStr,
hex.EncodeToString(b),
hex.EncodeToString([]byte(want)))
}
}
}
func TestAppendTimes(t *testing.T) {
const timeFloatFmt = "2006-01-02T15:04:05.999999-07:00"
array := make([]time.Time, len(internal.TimeFloatTestcases))
want := make([]byte, 0)
want = append(want, 0x82) // start small array
for i, tt := range internal.TimeFloatTestcases {
array[i], _ = time.Parse(timeFloatFmt, tt.RfcStr)
want = append(want, []byte(tt.Out)...)
}
got := enc.AppendTimes([]byte{}, array, "unused")
if !bytes.Equal(got, want) {
t.Errorf("AppendTimes(%v)\ngot: 0x%s\nwant: 0x%s",
array, hex.EncodeToString(got),
hex.EncodeToString(want))
}
// now empty array case
array = make([]time.Time, 0)
want = make([]byte, 0)
want = append(want, 0x9f) // start and end array
want = append(want, 0xff) // for empty array
got = enc.AppendTimes([]byte{}, array, "unused")
if !bytes.Equal(got, want) {
t.Errorf("AppendTimes(%v)\ngot: 0x%s\nwant: 0x%s",
array, hex.EncodeToString(got),
hex.EncodeToString(want))
}
// now large array case
testtime, _ := time.Parse(timeFloatFmt, internal.TimeFloatTestcases[0].RfcStr)
outbytes := internal.TimeFloatTestcases[0].Out
array = make([]time.Time, 24)
want = make([]byte, 0)
want = append(want, 0x98) // start a large array
want = append(want, 0x18) // of length 24
for i := 0; i < len(array); i++ {
array[i] = testtime
want = append(want, []byte(outbytes)...)
}
got = enc.AppendTimes([]byte{}, array, "unused")
if !bytes.Equal(got, want) {
t.Errorf("AppendTimes(%v)\ngot: 0x%s\nwant: 0x%s",
array,
hex.EncodeToString(got),
hex.EncodeToString(want))
}
}
func TestAppendDurationFloat(t *testing.T) {
for _, tt := range internal.DurTestcases {
dur := tt.Duration
want := []byte{}
want = append(want, []byte(tt.FloatOut)...)
got := enc.AppendDuration([]byte{}, dur, time.Microsecond, false, -1)
if !bytes.Equal(got, want) {
t.Errorf("AppendDuration(%v)=\ngot: 0x%s\nwant: 0x%s",
dur,
hex.EncodeToString(got),
hex.EncodeToString(want))
}
}
}
func TestAppendDurationInteger(t *testing.T) {
for _, tt := range internal.DurTestcases {
dur := tt.Duration
want := []byte{}
want = append(want, []byte(tt.IntegerOut)...)
got := enc.AppendDuration([]byte{}, dur, time.Microsecond, true, -1)
if !bytes.Equal(got, want) {
t.Errorf("AppendDuration(%v)=\ngot: 0x%s\nwant: 0x%s",
dur,
hex.EncodeToString(got),
hex.EncodeToString(want))
}
}
}
func TestAppendDurations(t *testing.T) {
array := make([]time.Duration, len(internal.DurTestcases))
want := make([]byte, 0)
want = append(want, 0x83) // start 3 element array
for i, tt := range internal.DurTestcases {
array[i] = tt.Duration
want = append(want, []byte(tt.FloatOut)...)
}
got := enc.AppendDurations([]byte{}, array, time.Microsecond, false, -1)
if !bytes.Equal(got, want) {
t.Errorf("AppendDurations(%v)\ngot: 0x%s\nwant: 0x%s",
array, hex.EncodeToString(got),
hex.EncodeToString(want))
}
// now empty array case
array = make([]time.Duration, 0)
want = make([]byte, 0)
want = append(want, 0x9f) // start and end array
want = append(want, 0xff) // for empty array
got = enc.AppendDurations([]byte{}, array, time.Microsecond, false, -1)
if !bytes.Equal(got, want) {
t.Errorf("AppendDurations(%v)\ngot: 0x%s\nwant: 0x%s",
array, hex.EncodeToString(got),
hex.EncodeToString(want))
}
// now large array case
testtime := internal.DurTestcases[0].Duration
outbytes := internal.DurTestcases[0].FloatOut
array = make([]time.Duration, 24)
want = make([]byte, 0)
want = append(want, 0x98) // start a large array
want = append(want, 0x18) // of length 24
for i := 0; i < len(array); i++ {
array[i] = testtime
want = append(want, []byte(outbytes)...)
}
got = enc.AppendDurations([]byte{}, array, time.Microsecond, false, -1)
if !bytes.Equal(got, want) {
t.Errorf("AppendDurations(%v)\ngot: 0x%s\nwant: 0x%s",
array,
hex.EncodeToString(got),
hex.EncodeToString(want))
}
}
func BenchmarkAppendTime(b *testing.B) {
tests := map[string]string{
"Integer": "Feb 3, 2013 at 7:54pm (PST)",
"Float": "2006-01-02T15:04:05.999999-08:00",
}
const timeFloatFmt = "2006-01-02T15:04:05.999999-07:00"
for name, str := range tests {
t, err := time.Parse(time.RFC3339, str)
if err != nil {
t, _ = time.Parse(timeFloatFmt, str)
}
b.Run(name, func(b *testing.B) {
buf := make([]byte, 0, 100)
for i := 0; i < b.N; i++ {
_ = enc.AppendTime(buf, t, "unused")
}
})
}
}