123 lines
3.9 KiB
Go
123 lines
3.9 KiB
Go
|
// Copyright (C) MongoDB, Inc. 2017-present.
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||
|
// not use this file except in compliance with the License. You may obtain
|
||
|
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
||
|
package primitive
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/stretchr/testify/require"
|
||
|
"go.mongodb.org/mongo-driver/internal/testutil/assert"
|
||
|
)
|
||
|
|
||
|
// The same interface as bsoncodec.Zeroer implemented for tests.
|
||
|
type zeroer interface {
|
||
|
IsZero() bool
|
||
|
}
|
||
|
|
||
|
func TestTimestampCompare(t *testing.T) {
|
||
|
testcases := []struct {
|
||
|
name string
|
||
|
tp Timestamp
|
||
|
tp2 Timestamp
|
||
|
expected int
|
||
|
}{
|
||
|
{"equal", Timestamp{T: 12345, I: 67890}, Timestamp{T: 12345, I: 67890}, 0},
|
||
|
{"T greater than", Timestamp{T: 12345, I: 67890}, Timestamp{T: 2345, I: 67890}, 1},
|
||
|
{"I greater than", Timestamp{T: 12345, I: 67890}, Timestamp{T: 12345, I: 7890}, 1},
|
||
|
{"T less than", Timestamp{T: 12345, I: 67890}, Timestamp{T: 112345, I: 67890}, -1},
|
||
|
{"I less than", Timestamp{T: 12345, I: 67890}, Timestamp{T: 12345, I: 167890}, -1},
|
||
|
}
|
||
|
|
||
|
for _, tc := range testcases {
|
||
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
result := CompareTimestamp(tc.tp, tc.tp2)
|
||
|
require.Equal(t, tc.expected, result)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestPrimitiveIsZero(t *testing.T) {
|
||
|
testcases := []struct {
|
||
|
name string
|
||
|
zero zeroer
|
||
|
nonzero zeroer
|
||
|
}{
|
||
|
{"binary", Binary{}, Binary{Data: []byte{0x01, 0x02, 0x03}, Subtype: 0xFF}},
|
||
|
{"decimal128", Decimal128{}, NewDecimal128(1, 2)},
|
||
|
{"objectID", ObjectID{}, NewObjectID()},
|
||
|
{"regex", Regex{}, Regex{Pattern: "foo", Options: "bar"}},
|
||
|
{"dbPointer", DBPointer{}, DBPointer{DB: "foobar", Pointer: ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}}},
|
||
|
{"timestamp", Timestamp{}, Timestamp{T: 12345, I: 67890}},
|
||
|
}
|
||
|
|
||
|
for _, tc := range testcases {
|
||
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
require.True(t, tc.zero.IsZero())
|
||
|
require.False(t, tc.nonzero.IsZero())
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestRegexCompare(t *testing.T) {
|
||
|
testcases := []struct {
|
||
|
name string
|
||
|
r1 Regex
|
||
|
r2 Regex
|
||
|
eq bool
|
||
|
}{
|
||
|
{"equal", Regex{Pattern: "foo1", Options: "bar1"}, Regex{Pattern: "foo1", Options: "bar1"}, true},
|
||
|
{"not equal", Regex{Pattern: "foo1", Options: "bar1"}, Regex{Pattern: "foo2", Options: "bar2"}, false},
|
||
|
{"not equal", Regex{Pattern: "foo1", Options: "bar1"}, Regex{Pattern: "foo1", Options: "bar2"}, false},
|
||
|
{"not equal", Regex{Pattern: "foo1", Options: "bar1"}, Regex{Pattern: "foo2", Options: "bar1"}, false},
|
||
|
}
|
||
|
|
||
|
for _, tc := range testcases {
|
||
|
t.Run(tc.name, func(t *testing.T) {
|
||
|
require.True(t, tc.r1.Equal(tc.r2) == tc.eq)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestDateTime(t *testing.T) {
|
||
|
t.Run("json", func(t *testing.T) {
|
||
|
t.Run("round trip", func(t *testing.T) {
|
||
|
original := DateTime(1000)
|
||
|
jsonBytes, err := json.Marshal(original)
|
||
|
assert.Nil(t, err, "Marshal error: %v", err)
|
||
|
|
||
|
var unmarshalled DateTime
|
||
|
err = json.Unmarshal(jsonBytes, &unmarshalled)
|
||
|
assert.Nil(t, err, "Unmarshal error: %v", err)
|
||
|
|
||
|
assert.Equal(t, original, unmarshalled, "expected DateTime %v, got %v", original, unmarshalled)
|
||
|
})
|
||
|
t.Run("decode null", func(t *testing.T) {
|
||
|
jsonBytes := []byte("null")
|
||
|
var dt DateTime
|
||
|
err := json.Unmarshal(jsonBytes, &dt)
|
||
|
assert.Nil(t, err, "Unmarshal error: %v", err)
|
||
|
assert.Equal(t, DateTime(0), dt, "expected DateTime value to be 0, got %v", dt)
|
||
|
})
|
||
|
})
|
||
|
t.Run("NewDateTimeFromTime", func(t *testing.T) {
|
||
|
t.Run("range is not limited", func(t *testing.T) {
|
||
|
// If the implementation internally calls time.Time.UnixNano(), the constructor cannot handle times after
|
||
|
// the year 2262.
|
||
|
|
||
|
timeFormat := "2006-01-02T15:04:05.999Z07:00"
|
||
|
timeString := "3001-01-01T00:00:00Z"
|
||
|
tt, err := time.Parse(timeFormat, timeString)
|
||
|
assert.Nil(t, err, "Parse error: %v", err)
|
||
|
|
||
|
dt := NewDateTimeFromTime(tt)
|
||
|
assert.True(t, dt > 0, "expected a valid DateTime greater than 0, got %v", dt)
|
||
|
})
|
||
|
})
|
||
|
}
|