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

omitempty behavior on serializing objectid.ObjectID value type in structs

    XMLWordPrintableJSON

Details

    • Icon: Task Task
    • Resolution: Fixed
    • Icon: Major - P3 Major - P3
    • 0.0.15
    • 0.0.14
    • BSON
    • None
    • linux
      go1.11

    Description

      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))
      	}
      }
      
      

      Attachments

        Activity

          People

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

            Dates

              Created:
              Updated:
              Resolved: