Skip to content

Commit

Permalink
Test Array type-specific adders
Browse files Browse the repository at this point in the history
  • Loading branch information
xdg committed Jan 4, 2021
1 parent b379db4 commit 7a185c9
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 7 deletions.
11 changes: 11 additions & 0 deletions array.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ func (a *Array) AddBinary(v *primitive.Binary) *Array {
return a
}

// AddUndefined
func (a *Array) AddUndefined() *Array {
if a.d.immutable || !a.d.valid {
a.d.err = errImmutableInvalid
return a
}
a.d.AddUndefined(strconv.Itoa(a.n))
a.n++
return a
}

// AddOID ...
func (a *Array) AddOID(v primitive.ObjectID) *Array {
if a.d.immutable || !a.d.valid {
Expand Down
158 changes: 158 additions & 0 deletions array_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package bsony

import (
"fmt"
"testing"
"time"

"go.mongodb.org/mongo-driver/bson/primitive"
)

func testArrayAdd(t *testing.T, addCases []AddTestCase) {
// Array.Add is a wrapper around Doc.Add, so we can use the same input data.
t.Run("Array.Add", func(t *testing.T) {
for _, c := range addCases {
// replace key in document with "0" (ASCII 0x30)
aHex := c.D[0:10] + "30" + c.D[12:]

a := fct.NewArray()
a.Add(c.V)
compareArrayHex(t, a, aHex, c.L)
a.Release()
}
})

// Test adding to array with type-specific functions. This is needed
// because Doc.Add delegates to the type-specific adders, but Array.Add
// delegates to Doc.Add. Therefore, we have to do our own type-specific
// test for arrays.
t.Run("Array.AddType", func(t *testing.T) {
for _, c := range addCases {
// replace key in document with "0" (ASCII 0x30)
aHex := c.D[0:10] + "30" + c.D[12:]

a := fct.NewArray()
if addByType(a, c.V) {
compareArrayHex(t, a, aHex, c.L)
}
a.Release()
}
})

}

// Switch adapted from Doc.Add and will need to be kept in sync if new types
// are added.
func addByType(a *Array, v interface{}) bool {
switch x := v.(type) {
// Type 01 - double
case float32:
a.AddDouble(float64(x))
case float64:
a.AddDouble(x)

// Type 02 - string
case string:
a.AddString(x)

// Type 03 - document
case Doc:
a.AddDoc(&x)
case *Doc:
a.AddDoc(x)

// Type 04 - array
case Array:
a.AddArray(&x)
case *Array:
a.AddArray(x)

// Type 05 - binary
case primitive.Binary:
a.AddBinary(&x)
case *primitive.Binary:
a.AddBinary(x)

// Type 06 - undefined (deprecated)
case primitive.Undefined:
a.AddUndefined()

// Type 07 - ObjectID
case primitive.ObjectID:
a.AddOID(x)

// Type 08 - boolean
case bool:
a.AddBool(x)

// Type 09 - UTC DateTime
case primitive.DateTime:
a.AddDateTime(x)
case time.Time:
a.AddDateTimeFromTime(x)
case *time.Time:
a.AddDateTimeFromTime(*x)

// Type 0A - null
case nil:
a.AddNull()

// Type 0B - regular expression
case primitive.Regex:
a.AddRegex(x)
case *primitive.Regex:
a.AddRegex(*x)

// Type 0C - DBPointer (deprecated)
case primitive.DBPointer:
a.AddDBPointer(x)
case *primitive.DBPointer:
a.AddDBPointer(*x)

// Type 0D - JavaScript code
case primitive.JavaScript:
a.AddJavaScript(x)

// Type 0E - Symbol (deprecated)
case primitive.Symbol:
a.AddSymbol(x)

// Type 0F - JavaScript code with scope
case CodeWithScope:
a.AddCodeScope(x)
case primitive.CodeWithScope:
// AddCodeScope doesn't convert this, only Add, so skip test
return false

// Type 10 - 32-bit integer
case int32:
a.AddInt32(x)

// Type 11 - timestamp
case primitive.Timestamp:
a.AddTimestamp(x)

// Type 12 - 64-bit integer
case int64:
a.AddInt64(x)

// Type 13 - 128-bit decimal floating point
case primitive.Decimal128:
a.AddDecimal128(x)
case *primitive.Decimal128:
a.AddDecimal128(*x)

// Type FF - Min key
case primitive.MinKey:
a.AddMinKey()

// Type 7F - Max key
case primitive.MaxKey:
a.AddMaxKey()

default:
panic(fmt.Sprintf("unsupported type: %T", v))
}

return true
}
18 changes: 12 additions & 6 deletions document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const (
rfc3339Milli = "2006-01-02T15:04:05.999Z07:00"
)

// This function calls into array_test.go so as to use the same input data.
func TestAdd(t *testing.T) {
fct := New()
testArray := fct.NewArray()
Expand Down Expand Up @@ -94,10 +95,15 @@ func TestAdd(t *testing.T) {
{"maxkey", "a", primitive.MaxKey{}, "080000007F610000"},
}

for _, c := range addCases {
d := fct.NewDoc()
d.Add(c.K, c.V)
compareDocHex(t, d, c.D, c.L)
d.Release()
}
t.Run("Doc.Add", func(t *testing.T) {
for _, c := range addCases {
d := fct.NewDoc()
d.Add(c.K, c.V)
compareDocHex(t, d, c.D, c.L)
d.Release()
}
})

// Delegate array testing with same data
testArrayAdd(t, addCases)
}
2 changes: 1 addition & 1 deletion util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func compareArrayHex(t *testing.T, a *Array, want string, label string) {
got := strings.ToLower(hex.EncodeToString(a.d.buf))
want = strings.ToLower(want)
if got != want {
t.Errorf("%s: encoded doc incorrect.\nGot: %s\nWant: %s", label, got, want)
t.Errorf("%s: encoded array incorrect.\nGot: %s\nWant: %s", label, got, want)
}
return
}
Expand Down

0 comments on commit 7a185c9

Please sign in to comment.