Uploaded image for project: 'Go Driver'
  1. Go Driver
  2. GODRIVER-585

omitempty behavior on serializing objectid.ObjectID value type in structs

    • Type: Icon: Task Task
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 0.0.15
    • Affects Version/s: 0.0.14
    • Component/s: BSON
    • None
    • Environment:
      linux
      go1.11

      omitempty behavior differs from how value types are expected to work. Especially objectid.NilObjectID can be quite misleading in such scenarios. Kindly go test the following or use the attached file.

      package main
      
      import (
      	"testing"
      
      	"github.com/mongodb/mongo-go-driver/bson"
      	"github.com/mongodb/mongo-go-driver/bson/objectid"
      )
      
      type ThingOmitID struct {
      	ID    objectid.ObjectID `bson:"_id,omitempty"`
      	Field string            `bson:"field"`
      }
      
      type ThingOmitIDPtr struct {
      	ID    *objectid.ObjectID `bson:"_id,omitempty"`
      	Field string             `bson:"field"`
      }
      
      type ThingOmitStringField struct {
      	ID    objectid.ObjectID `bson:"_id"`
      	Field string            `bson:"field,omitempty"`
      }
      
      func TestOmitEmptyID_NilObjectID(t *testing.T) {
      	thing := &ThingOmitID{
      		ID:    objectid.NilObjectID,
      		Field: "content",
      	}
      	validateNumKeys(t, 1, thing)
      }
      
      func TestOmitEmptyID_Omit(t *testing.T) {
      	thing := &ThingOmitID{
      		Field: "content",
      	}
      	validateNumKeys(t, 1, thing)
      }
      
      func TestOmitEmptyIDPtr_Nil(t *testing.T) {
      	thing := &ThingOmitIDPtr{
      		ID:    nil,
      		Field: "content",
      	}
      	validateNumKeys(t, 1, thing)
      }
      
      func TestOmitEmptyIDPtr_NilObjectID(t *testing.T) {
      	thing := &ThingOmitIDPtr{
      		ID:    &objectid.NilObjectID,
      		Field: "content",
      	}
      	validateNumKeys(t, 2, thing)
      }
      
      func TestOmitEmptyStringField_Empty(t *testing.T) {
      	thing := &ThingOmitStringField{
      		ID:    objectid.NilObjectID,
      		Field: "",
      	}
      	validateNumKeys(t, 1, thing)
      }
      
      func TestOmitEmptyStringField_Omit(t *testing.T) {
      	thing := &ThingOmitStringField{
      		ID: objectid.NilObjectID,
      	}
      	validateNumKeys(t, 1, thing)
      }
      
      func validateNumKeys(t *testing.T, numKeys int, obj interface{}) {
      	encodedObj, err := bson.NewDocumentEncoder().EncodeDocument(obj)
      	if err != nil {
      		t.Error(err.Error())
      	}
      
      	keys, err := encodedObj.Keys(false)
      	if err != nil {
      		t.Error(err.Error())
      	}
      	if numKeys != len(keys) {
      		for _, key := range keys {
      			t.Log(key.Prefix, key.Name)
      		}
      		t.Errorf("Expected number of keys: %d, actual: %d", numKeys, len(keys))
      	}
      }
      
      

        1. omitempty_test.go
          2 kB
          Mohammad Nasirifar

            Assignee:
            Unassigned Unassigned
            Reporter:
            farnasirim Mohammad Nasirifar
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: