github.com/lianghucheng/zrddz@v0.0.0-20200923083010-c71f680932e2/src/gopkg.in/mgo.v2/bson/bson_test.go (about)

     1  // BSON library for Go
     2  //
     3  // Copyright (c) 2010-2012 - Gustavo Niemeyer <gustavo@niemeyer.net>
     4  //
     5  // All rights reserved.
     6  //
     7  // Redistribution and use in source and binary forms, with or without
     8  // modification, are permitted provided that the following conditions are met:
     9  //
    10  // 1. Redistributions of source code must retain the above copyright notice, this
    11  //    list of conditions and the following disclaimer.
    12  // 2. Redistributions in binary form must reproduce the above copyright notice,
    13  //    this list of conditions and the following disclaimer in the documentation
    14  //    and/or other materials provided with the distribution.
    15  //
    16  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    17  // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    18  // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    19  // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
    20  // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    21  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    22  // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    23  // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    24  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    25  // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    26  // gobson - BSON library for Go.
    27  
    28  package bson_test
    29  
    30  import (
    31  	"encoding/binary"
    32  	"encoding/hex"
    33  	"encoding/json"
    34  	"encoding/xml"
    35  	"errors"
    36  	"net/url"
    37  	"reflect"
    38  	"strings"
    39  	"testing"
    40  	"time"
    41  
    42  	. "gopkg.in/check.v1"
    43  	"gopkg.in/mgo.v2/bson"
    44  	"gopkg.in/yaml.v2"
    45  )
    46  
    47  func TestAll(t *testing.T) {
    48  	TestingT(t)
    49  }
    50  
    51  type S struct{}
    52  
    53  var _ = Suite(&S{})
    54  
    55  // Wrap up the document elements contained in data, prepending the int32
    56  // length of the data, and appending the '\x00' value closing the document.
    57  func wrapInDoc(data string) string {
    58  	result := make([]byte, len(data)+5)
    59  	binary.LittleEndian.PutUint32(result, uint32(len(result)))
    60  	copy(result[4:], []byte(data))
    61  	return string(result)
    62  }
    63  
    64  func makeZeroDoc(value interface{}) (zero interface{}) {
    65  	v := reflect.ValueOf(value)
    66  	t := v.Type()
    67  	switch t.Kind() {
    68  	case reflect.Map:
    69  		mv := reflect.MakeMap(t)
    70  		zero = mv.Interface()
    71  	case reflect.Ptr:
    72  		pv := reflect.New(v.Type().Elem())
    73  		zero = pv.Interface()
    74  	case reflect.Slice, reflect.Int, reflect.Int64, reflect.Struct:
    75  		zero = reflect.New(t).Interface()
    76  	default:
    77  		panic("unsupported doc type: " + t.Name())
    78  	}
    79  	return zero
    80  }
    81  
    82  func testUnmarshal(c *C, data string, obj interface{}) {
    83  	zero := makeZeroDoc(obj)
    84  	err := bson.Unmarshal([]byte(data), zero)
    85  	c.Assert(err, IsNil)
    86  	c.Assert(zero, DeepEquals, obj)
    87  }
    88  
    89  type testItemType struct {
    90  	obj  interface{}
    91  	data string
    92  }
    93  
    94  // --------------------------------------------------------------------------
    95  // Samples from bsonspec.org:
    96  
    97  var sampleItems = []testItemType{
    98  	{bson.M{"hello": "world"},
    99  		"\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00"},
   100  	{bson.M{"BSON": []interface{}{"awesome", float64(5.05), 1986}},
   101  		"1\x00\x00\x00\x04BSON\x00&\x00\x00\x00\x020\x00\x08\x00\x00\x00" +
   102  			"awesome\x00\x011\x00333333\x14@\x102\x00\xc2\x07\x00\x00\x00\x00"},
   103  }
   104  
   105  func (s *S) TestMarshalSampleItems(c *C) {
   106  	for i, item := range sampleItems {
   107  		data, err := bson.Marshal(item.obj)
   108  		c.Assert(err, IsNil)
   109  		c.Assert(string(data), Equals, item.data, Commentf("Failed on item %d", i))
   110  	}
   111  }
   112  
   113  func (s *S) TestUnmarshalSampleItems(c *C) {
   114  	for i, item := range sampleItems {
   115  		value := bson.M{}
   116  		err := bson.Unmarshal([]byte(item.data), value)
   117  		c.Assert(err, IsNil)
   118  		c.Assert(value, DeepEquals, item.obj, Commentf("Failed on item %d", i))
   119  	}
   120  }
   121  
   122  // --------------------------------------------------------------------------
   123  // Every type, ordered by the type flag. These are not wrapped with the
   124  // length and last \x00 from the document. wrapInDoc() computes them.
   125  // Note that all of them should be supported as two-way conversions.
   126  
   127  var allItems = []testItemType{
   128  	{bson.M{},
   129  		""},
   130  	{bson.M{"_": float64(5.05)},
   131  		"\x01_\x00333333\x14@"},
   132  	{bson.M{"_": "yo"},
   133  		"\x02_\x00\x03\x00\x00\x00yo\x00"},
   134  	{bson.M{"_": bson.M{"a": true}},
   135  		"\x03_\x00\x09\x00\x00\x00\x08a\x00\x01\x00"},
   136  	{bson.M{"_": []interface{}{true, false}},
   137  		"\x04_\x00\r\x00\x00\x00\x080\x00\x01\x081\x00\x00\x00"},
   138  	{bson.M{"_": []byte("yo")},
   139  		"\x05_\x00\x02\x00\x00\x00\x00yo"},
   140  	{bson.M{"_": bson.Binary{0x80, []byte("udef")}},
   141  		"\x05_\x00\x04\x00\x00\x00\x80udef"},
   142  	{bson.M{"_": bson.Undefined}, // Obsolete, but still seen in the wild.
   143  		"\x06_\x00"},
   144  	{bson.M{"_": bson.ObjectId("0123456789ab")},
   145  		"\x07_\x000123456789ab"},
   146  	{bson.M{"_": bson.DBPointer{"testnamespace", bson.ObjectId("0123456789ab")}},
   147  		"\x0C_\x00\x0e\x00\x00\x00testnamespace\x000123456789ab"},
   148  	{bson.M{"_": false},
   149  		"\x08_\x00\x00"},
   150  	{bson.M{"_": true},
   151  		"\x08_\x00\x01"},
   152  	{bson.M{"_": time.Unix(0, 258e6)}, // Note the NS <=> MS conversion.
   153  		"\x09_\x00\x02\x01\x00\x00\x00\x00\x00\x00"},
   154  	{bson.M{"_": nil},
   155  		"\x0A_\x00"},
   156  	{bson.M{"_": bson.RegEx{"ab", "cd"}},
   157  		"\x0B_\x00ab\x00cd\x00"},
   158  	{bson.M{"_": bson.JavaScript{"code", nil}},
   159  		"\x0D_\x00\x05\x00\x00\x00code\x00"},
   160  	{bson.M{"_": bson.Symbol("sym")},
   161  		"\x0E_\x00\x04\x00\x00\x00sym\x00"},
   162  	{bson.M{"_": bson.JavaScript{"code", bson.M{"": nil}}},
   163  		"\x0F_\x00\x14\x00\x00\x00\x05\x00\x00\x00code\x00" +
   164  			"\x07\x00\x00\x00\x0A\x00\x00"},
   165  	{bson.M{"_": 258},
   166  		"\x10_\x00\x02\x01\x00\x00"},
   167  	{bson.M{"_": bson.MongoTimestamp(258)},
   168  		"\x11_\x00\x02\x01\x00\x00\x00\x00\x00\x00"},
   169  	{bson.M{"_": int64(258)},
   170  		"\x12_\x00\x02\x01\x00\x00\x00\x00\x00\x00"},
   171  	{bson.M{"_": int64(258 << 32)},
   172  		"\x12_\x00\x00\x00\x00\x00\x02\x01\x00\x00"},
   173  	{bson.M{"_": bson.MaxKey},
   174  		"\x7F_\x00"},
   175  	{bson.M{"_": bson.MinKey},
   176  		"\xFF_\x00"},
   177  }
   178  
   179  func (s *S) TestMarshalAllItems(c *C) {
   180  	for i, item := range allItems {
   181  		data, err := bson.Marshal(item.obj)
   182  		c.Assert(err, IsNil)
   183  		c.Assert(string(data), Equals, wrapInDoc(item.data), Commentf("Failed on item %d: %#v", i, item))
   184  	}
   185  }
   186  
   187  func (s *S) TestUnmarshalAllItems(c *C) {
   188  	for i, item := range allItems {
   189  		value := bson.M{}
   190  		err := bson.Unmarshal([]byte(wrapInDoc(item.data)), value)
   191  		c.Assert(err, IsNil)
   192  		c.Assert(value, DeepEquals, item.obj, Commentf("Failed on item %d: %#v", i, item))
   193  	}
   194  }
   195  
   196  func (s *S) TestUnmarshalRawAllItems(c *C) {
   197  	for i, item := range allItems {
   198  		if len(item.data) == 0 {
   199  			continue
   200  		}
   201  		value := item.obj.(bson.M)["_"]
   202  		if value == nil {
   203  			continue
   204  		}
   205  		pv := reflect.New(reflect.ValueOf(value).Type())
   206  		raw := bson.Raw{item.data[0], []byte(item.data[3:])}
   207  		c.Logf("Unmarshal raw: %#v, %#v", raw, pv.Interface())
   208  		err := raw.Unmarshal(pv.Interface())
   209  		c.Assert(err, IsNil)
   210  		c.Assert(pv.Elem().Interface(), DeepEquals, value, Commentf("Failed on item %d: %#v", i, item))
   211  	}
   212  }
   213  
   214  func (s *S) TestUnmarshalRawIncompatible(c *C) {
   215  	raw := bson.Raw{0x08, []byte{0x01}} // true
   216  	err := raw.Unmarshal(&struct{}{})
   217  	c.Assert(err, ErrorMatches, "BSON kind 0x08 isn't compatible with type struct \\{\\}")
   218  }
   219  
   220  func (s *S) TestUnmarshalZeroesStruct(c *C) {
   221  	data, err := bson.Marshal(bson.M{"b": 2})
   222  	c.Assert(err, IsNil)
   223  	type T struct{ A, B int }
   224  	v := T{A: 1}
   225  	err = bson.Unmarshal(data, &v)
   226  	c.Assert(err, IsNil)
   227  	c.Assert(v.A, Equals, 0)
   228  	c.Assert(v.B, Equals, 2)
   229  }
   230  
   231  func (s *S) TestUnmarshalZeroesMap(c *C) {
   232  	data, err := bson.Marshal(bson.M{"b": 2})
   233  	c.Assert(err, IsNil)
   234  	m := bson.M{"a": 1}
   235  	err = bson.Unmarshal(data, &m)
   236  	c.Assert(err, IsNil)
   237  	c.Assert(m, DeepEquals, bson.M{"b": 2})
   238  }
   239  
   240  func (s *S) TestUnmarshalNonNilInterface(c *C) {
   241  	data, err := bson.Marshal(bson.M{"b": 2})
   242  	c.Assert(err, IsNil)
   243  	m := bson.M{"a": 1}
   244  	var i interface{}
   245  	i = m
   246  	err = bson.Unmarshal(data, &i)
   247  	c.Assert(err, IsNil)
   248  	c.Assert(i, DeepEquals, bson.M{"b": 2})
   249  	c.Assert(m, DeepEquals, bson.M{"a": 1})
   250  }
   251  
   252  // --------------------------------------------------------------------------
   253  // Some one way marshaling operations which would unmarshal differently.
   254  
   255  var oneWayMarshalItems = []testItemType{
   256  	// These are being passed as pointers, and will unmarshal as values.
   257  	{bson.M{"": &bson.Binary{0x02, []byte("old")}},
   258  		"\x05\x00\x07\x00\x00\x00\x02\x03\x00\x00\x00old"},
   259  	{bson.M{"": &bson.Binary{0x80, []byte("udef")}},
   260  		"\x05\x00\x04\x00\x00\x00\x80udef"},
   261  	{bson.M{"": &bson.RegEx{"ab", "cd"}},
   262  		"\x0B\x00ab\x00cd\x00"},
   263  	{bson.M{"": &bson.JavaScript{"code", nil}},
   264  		"\x0D\x00\x05\x00\x00\x00code\x00"},
   265  	{bson.M{"": &bson.JavaScript{"code", bson.M{"": nil}}},
   266  		"\x0F\x00\x14\x00\x00\x00\x05\x00\x00\x00code\x00" +
   267  			"\x07\x00\x00\x00\x0A\x00\x00"},
   268  
   269  	// There's no float32 type in BSON.  Will encode as a float64.
   270  	{bson.M{"": float32(5.05)},
   271  		"\x01\x00\x00\x00\x00@33\x14@"},
   272  
   273  	// The array will be unmarshaled as a slice instead.
   274  	{bson.M{"": [2]bool{true, false}},
   275  		"\x04\x00\r\x00\x00\x00\x080\x00\x01\x081\x00\x00\x00"},
   276  
   277  	// The typed slice will be unmarshaled as []interface{}.
   278  	{bson.M{"": []bool{true, false}},
   279  		"\x04\x00\r\x00\x00\x00\x080\x00\x01\x081\x00\x00\x00"},
   280  
   281  	// Will unmarshal as a []byte.
   282  	{bson.M{"": bson.Binary{0x00, []byte("yo")}},
   283  		"\x05\x00\x02\x00\x00\x00\x00yo"},
   284  	{bson.M{"": bson.Binary{0x02, []byte("old")}},
   285  		"\x05\x00\x07\x00\x00\x00\x02\x03\x00\x00\x00old"},
   286  
   287  	// No way to preserve the type information here. We might encode as a zero
   288  	// value, but this would mean that pointer values in structs wouldn't be
   289  	// able to correctly distinguish between unset and set to the zero value.
   290  	{bson.M{"": (*byte)(nil)},
   291  		"\x0A\x00"},
   292  
   293  	// No int types smaller than int32 in BSON. Could encode this as a char,
   294  	// but it would still be ambiguous, take more, and be awkward in Go when
   295  	// loaded without typing information.
   296  	{bson.M{"": byte(8)},
   297  		"\x10\x00\x08\x00\x00\x00"},
   298  
   299  	// There are no unsigned types in BSON.  Will unmarshal as int32 or int64.
   300  	{bson.M{"": uint32(258)},
   301  		"\x10\x00\x02\x01\x00\x00"},
   302  	{bson.M{"": uint64(258)},
   303  		"\x12\x00\x02\x01\x00\x00\x00\x00\x00\x00"},
   304  	{bson.M{"": uint64(258 << 32)},
   305  		"\x12\x00\x00\x00\x00\x00\x02\x01\x00\x00"},
   306  
   307  	// This will unmarshal as int.
   308  	{bson.M{"": int32(258)},
   309  		"\x10\x00\x02\x01\x00\x00"},
   310  
   311  	// That's a special case. The unsigned value is too large for an int32,
   312  	// so an int64 is used instead.
   313  	{bson.M{"": uint32(1<<32 - 1)},
   314  		"\x12\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00"},
   315  	{bson.M{"": uint(1<<32 - 1)},
   316  		"\x12\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00"},
   317  }
   318  
   319  func (s *S) TestOneWayMarshalItems(c *C) {
   320  	for i, item := range oneWayMarshalItems {
   321  		data, err := bson.Marshal(item.obj)
   322  		c.Assert(err, IsNil)
   323  		c.Assert(string(data), Equals, wrapInDoc(item.data),
   324  			Commentf("Failed on item %d", i))
   325  	}
   326  }
   327  
   328  // --------------------------------------------------------------------------
   329  // Two-way tests for user-defined structures using the samples
   330  // from bsonspec.org.
   331  
   332  type specSample1 struct {
   333  	Hello string
   334  }
   335  
   336  type specSample2 struct {
   337  	BSON []interface{} "BSON"
   338  }
   339  
   340  var structSampleItems = []testItemType{
   341  	{&specSample1{"world"},
   342  		"\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00"},
   343  	{&specSample2{[]interface{}{"awesome", float64(5.05), 1986}},
   344  		"1\x00\x00\x00\x04BSON\x00&\x00\x00\x00\x020\x00\x08\x00\x00\x00" +
   345  			"awesome\x00\x011\x00333333\x14@\x102\x00\xc2\x07\x00\x00\x00\x00"},
   346  }
   347  
   348  func (s *S) TestMarshalStructSampleItems(c *C) {
   349  	for i, item := range structSampleItems {
   350  		data, err := bson.Marshal(item.obj)
   351  		c.Assert(err, IsNil)
   352  		c.Assert(string(data), Equals, item.data,
   353  			Commentf("Failed on item %d", i))
   354  	}
   355  }
   356  
   357  func (s *S) TestUnmarshalStructSampleItems(c *C) {
   358  	for _, item := range structSampleItems {
   359  		testUnmarshal(c, item.data, item.obj)
   360  	}
   361  }
   362  
   363  func (s *S) Test64bitInt(c *C) {
   364  	var i int64 = (1 << 31)
   365  	if int(i) > 0 {
   366  		data, err := bson.Marshal(bson.M{"i": int(i)})
   367  		c.Assert(err, IsNil)
   368  		c.Assert(string(data), Equals, wrapInDoc("\x12i\x00\x00\x00\x00\x80\x00\x00\x00\x00"))
   369  
   370  		var result struct{ I int }
   371  		err = bson.Unmarshal(data, &result)
   372  		c.Assert(err, IsNil)
   373  		c.Assert(int64(result.I), Equals, i)
   374  	}
   375  }
   376  
   377  // --------------------------------------------------------------------------
   378  // Generic two-way struct marshaling tests.
   379  
   380  var bytevar = byte(8)
   381  var byteptr = &bytevar
   382  
   383  var structItems = []testItemType{
   384  	{&struct{ Ptr *byte }{nil},
   385  		"\x0Aptr\x00"},
   386  	{&struct{ Ptr *byte }{&bytevar},
   387  		"\x10ptr\x00\x08\x00\x00\x00"},
   388  	{&struct{ Ptr **byte }{&byteptr},
   389  		"\x10ptr\x00\x08\x00\x00\x00"},
   390  	{&struct{ Byte byte }{8},
   391  		"\x10byte\x00\x08\x00\x00\x00"},
   392  	{&struct{ Byte byte }{0},
   393  		"\x10byte\x00\x00\x00\x00\x00"},
   394  	{&struct {
   395  		V byte "Tag"
   396  	}{8},
   397  		"\x10Tag\x00\x08\x00\x00\x00"},
   398  	{&struct {
   399  		V *struct {
   400  			Byte byte
   401  		}
   402  	}{&struct{ Byte byte }{8}},
   403  		"\x03v\x00" + "\x0f\x00\x00\x00\x10byte\x00\b\x00\x00\x00\x00"},
   404  	{&struct{ priv byte }{}, ""},
   405  
   406  	// The order of the dumped fields should be the same in the struct.
   407  	{&struct{ A, C, B, D, F, E *byte }{},
   408  		"\x0Aa\x00\x0Ac\x00\x0Ab\x00\x0Ad\x00\x0Af\x00\x0Ae\x00"},
   409  
   410  	{&struct{ V bson.Raw }{bson.Raw{0x03, []byte("\x0f\x00\x00\x00\x10byte\x00\b\x00\x00\x00\x00")}},
   411  		"\x03v\x00" + "\x0f\x00\x00\x00\x10byte\x00\b\x00\x00\x00\x00"},
   412  	{&struct{ V bson.Raw }{bson.Raw{0x10, []byte("\x00\x00\x00\x00")}},
   413  		"\x10v\x00" + "\x00\x00\x00\x00"},
   414  
   415  	// Byte arrays.
   416  	{&struct{ V [2]byte }{[2]byte{'y', 'o'}},
   417  		"\x05v\x00\x02\x00\x00\x00\x00yo"},
   418  }
   419  
   420  func (s *S) TestMarshalStructItems(c *C) {
   421  	for i, item := range structItems {
   422  		data, err := bson.Marshal(item.obj)
   423  		c.Assert(err, IsNil)
   424  		c.Assert(string(data), Equals, wrapInDoc(item.data),
   425  			Commentf("Failed on item %d", i))
   426  	}
   427  }
   428  
   429  func (s *S) TestUnmarshalStructItems(c *C) {
   430  	for _, item := range structItems {
   431  		testUnmarshal(c, wrapInDoc(item.data), item.obj)
   432  	}
   433  }
   434  
   435  func (s *S) TestUnmarshalRawStructItems(c *C) {
   436  	for i, item := range structItems {
   437  		raw := bson.Raw{0x03, []byte(wrapInDoc(item.data))}
   438  		zero := makeZeroDoc(item.obj)
   439  		err := raw.Unmarshal(zero)
   440  		c.Assert(err, IsNil)
   441  		c.Assert(zero, DeepEquals, item.obj, Commentf("Failed on item %d: %#v", i, item))
   442  	}
   443  }
   444  
   445  func (s *S) TestUnmarshalRawNil(c *C) {
   446  	// Regression test: shouldn't try to nil out the pointer itself,
   447  	// as it's not settable.
   448  	raw := bson.Raw{0x0A, []byte{}}
   449  	err := raw.Unmarshal(&struct{}{})
   450  	c.Assert(err, IsNil)
   451  }
   452  
   453  // --------------------------------------------------------------------------
   454  // One-way marshaling tests.
   455  
   456  type dOnIface struct {
   457  	D interface{}
   458  }
   459  
   460  type ignoreField struct {
   461  	Before string
   462  	Ignore string `bson:"-"`
   463  	After  string
   464  }
   465  
   466  var marshalItems = []testItemType{
   467  	// Ordered document dump.  Will unmarshal as a dictionary by default.
   468  	{bson.D{{"a", nil}, {"c", nil}, {"b", nil}, {"d", nil}, {"f", nil}, {"e", true}},
   469  		"\x0Aa\x00\x0Ac\x00\x0Ab\x00\x0Ad\x00\x0Af\x00\x08e\x00\x01"},
   470  	{MyD{{"a", nil}, {"c", nil}, {"b", nil}, {"d", nil}, {"f", nil}, {"e", true}},
   471  		"\x0Aa\x00\x0Ac\x00\x0Ab\x00\x0Ad\x00\x0Af\x00\x08e\x00\x01"},
   472  	{&dOnIface{bson.D{{"a", nil}, {"c", nil}, {"b", nil}, {"d", true}}},
   473  		"\x03d\x00" + wrapInDoc("\x0Aa\x00\x0Ac\x00\x0Ab\x00\x08d\x00\x01")},
   474  
   475  	{bson.RawD{{"a", bson.Raw{0x0A, nil}}, {"c", bson.Raw{0x0A, nil}}, {"b", bson.Raw{0x08, []byte{0x01}}}},
   476  		"\x0Aa\x00" + "\x0Ac\x00" + "\x08b\x00\x01"},
   477  	{MyRawD{{"a", bson.Raw{0x0A, nil}}, {"c", bson.Raw{0x0A, nil}}, {"b", bson.Raw{0x08, []byte{0x01}}}},
   478  		"\x0Aa\x00" + "\x0Ac\x00" + "\x08b\x00\x01"},
   479  	{&dOnIface{bson.RawD{{"a", bson.Raw{0x0A, nil}}, {"c", bson.Raw{0x0A, nil}}, {"b", bson.Raw{0x08, []byte{0x01}}}}},
   480  		"\x03d\x00" + wrapInDoc("\x0Aa\x00"+"\x0Ac\x00"+"\x08b\x00\x01")},
   481  
   482  	{&ignoreField{"before", "ignore", "after"},
   483  		"\x02before\x00\a\x00\x00\x00before\x00\x02after\x00\x06\x00\x00\x00after\x00"},
   484  
   485  	// Marshalling a Raw document does nothing.
   486  	{bson.Raw{0x03, []byte(wrapInDoc("anything"))},
   487  		"anything"},
   488  	{bson.Raw{Data: []byte(wrapInDoc("anything"))},
   489  		"anything"},
   490  }
   491  
   492  func (s *S) TestMarshalOneWayItems(c *C) {
   493  	for _, item := range marshalItems {
   494  		data, err := bson.Marshal(item.obj)
   495  		c.Assert(err, IsNil)
   496  		c.Assert(string(data), Equals, wrapInDoc(item.data))
   497  	}
   498  }
   499  
   500  // --------------------------------------------------------------------------
   501  // One-way unmarshaling tests.
   502  
   503  var unmarshalItems = []testItemType{
   504  	// Field is private.  Should not attempt to unmarshal it.
   505  	{&struct{ priv byte }{},
   506  		"\x10priv\x00\x08\x00\x00\x00"},
   507  
   508  	// Wrong casing. Field names are lowercased.
   509  	{&struct{ Byte byte }{},
   510  		"\x10Byte\x00\x08\x00\x00\x00"},
   511  
   512  	// Ignore non-existing field.
   513  	{&struct{ Byte byte }{9},
   514  		"\x10boot\x00\x08\x00\x00\x00" + "\x10byte\x00\x09\x00\x00\x00"},
   515  
   516  	// Do not unmarshal on ignored field.
   517  	{&ignoreField{"before", "", "after"},
   518  		"\x02before\x00\a\x00\x00\x00before\x00" +
   519  			"\x02-\x00\a\x00\x00\x00ignore\x00" +
   520  			"\x02after\x00\x06\x00\x00\x00after\x00"},
   521  
   522  	// Ignore unsuitable types silently.
   523  	{map[string]string{"str": "s"},
   524  		"\x02str\x00\x02\x00\x00\x00s\x00" + "\x10int\x00\x01\x00\x00\x00"},
   525  	{map[string][]int{"array": []int{5, 9}},
   526  		"\x04array\x00" + wrapInDoc("\x100\x00\x05\x00\x00\x00"+"\x021\x00\x02\x00\x00\x00s\x00"+"\x102\x00\x09\x00\x00\x00")},
   527  
   528  	// Wrong type. Shouldn't init pointer.
   529  	{&struct{ Str *byte }{},
   530  		"\x02str\x00\x02\x00\x00\x00s\x00"},
   531  	{&struct{ Str *struct{ Str string } }{},
   532  		"\x02str\x00\x02\x00\x00\x00s\x00"},
   533  
   534  	// Ordered document.
   535  	{&struct{ bson.D }{bson.D{{"a", nil}, {"c", nil}, {"b", nil}, {"d", true}}},
   536  		"\x03d\x00" + wrapInDoc("\x0Aa\x00\x0Ac\x00\x0Ab\x00\x08d\x00\x01")},
   537  
   538  	// Raw document.
   539  	{&bson.Raw{0x03, []byte(wrapInDoc("\x10byte\x00\x08\x00\x00\x00"))},
   540  		"\x10byte\x00\x08\x00\x00\x00"},
   541  
   542  	// RawD document.
   543  	{&struct{ bson.RawD }{bson.RawD{{"a", bson.Raw{0x0A, []byte{}}}, {"c", bson.Raw{0x0A, []byte{}}}, {"b", bson.Raw{0x08, []byte{0x01}}}}},
   544  		"\x03rawd\x00" + wrapInDoc("\x0Aa\x00\x0Ac\x00\x08b\x00\x01")},
   545  
   546  	// Decode old binary.
   547  	{bson.M{"_": []byte("old")},
   548  		"\x05_\x00\x07\x00\x00\x00\x02\x03\x00\x00\x00old"},
   549  
   550  	// Decode old binary without length. According to the spec, this shouldn't happen.
   551  	{bson.M{"_": []byte("old")},
   552  		"\x05_\x00\x03\x00\x00\x00\x02old"},
   553  
   554  	// Decode a doc within a doc in to a slice within a doc; shouldn't error
   555  	{&struct{ Foo []string }{},
   556  		"\x03\x66\x6f\x6f\x00\x05\x00\x00\x00\x00"},
   557  }
   558  
   559  func (s *S) TestUnmarshalOneWayItems(c *C) {
   560  	for _, item := range unmarshalItems {
   561  		testUnmarshal(c, wrapInDoc(item.data), item.obj)
   562  	}
   563  }
   564  
   565  func (s *S) TestUnmarshalNilInStruct(c *C) {
   566  	// Nil is the default value, so we need to ensure it's indeed being set.
   567  	b := byte(1)
   568  	v := &struct{ Ptr *byte }{&b}
   569  	err := bson.Unmarshal([]byte(wrapInDoc("\x0Aptr\x00")), v)
   570  	c.Assert(err, IsNil)
   571  	c.Assert(v, DeepEquals, &struct{ Ptr *byte }{nil})
   572  }
   573  
   574  // --------------------------------------------------------------------------
   575  // Marshalling error cases.
   576  
   577  type structWithDupKeys struct {
   578  	Name  byte
   579  	Other byte "name" // Tag should precede.
   580  }
   581  
   582  var marshalErrorItems = []testItemType{
   583  	{bson.M{"": uint64(1 << 63)},
   584  		"BSON has no uint64 type, and value is too large to fit correctly in an int64"},
   585  	{bson.M{"": bson.ObjectId("tooshort")},
   586  		"ObjectIDs must be exactly 12 bytes long \\(got 8\\)"},
   587  	{int64(123),
   588  		"Can't marshal int64 as a BSON document"},
   589  	{bson.M{"": 1i},
   590  		"Can't marshal complex128 in a BSON document"},
   591  	{&structWithDupKeys{},
   592  		"Duplicated key 'name' in struct bson_test.structWithDupKeys"},
   593  	{bson.Raw{0xA, []byte{}},
   594  		"Attempted to marshal Raw kind 10 as a document"},
   595  	{bson.Raw{0x3, []byte{}},
   596  		"Attempted to marshal empty Raw document"},
   597  	{bson.M{"w": bson.Raw{0x3, []byte{}}},
   598  		"Attempted to marshal empty Raw document"},
   599  	{&inlineCantPtr{&struct{ A, B int }{1, 2}},
   600  		"Option ,inline needs a struct value or map field"},
   601  	{&inlineDupName{1, struct{ A, B int }{2, 3}},
   602  		"Duplicated key 'a' in struct bson_test.inlineDupName"},
   603  	{&inlineDupMap{},
   604  		"Multiple ,inline maps in struct bson_test.inlineDupMap"},
   605  	{&inlineBadKeyMap{},
   606  		"Option ,inline needs a map with string keys in struct bson_test.inlineBadKeyMap"},
   607  	{&inlineMap{A: 1, M: map[string]interface{}{"a": 1}},
   608  		`Can't have key "a" in inlined map; conflicts with struct field`},
   609  }
   610  
   611  func (s *S) TestMarshalErrorItems(c *C) {
   612  	for _, item := range marshalErrorItems {
   613  		data, err := bson.Marshal(item.obj)
   614  		c.Assert(err, ErrorMatches, item.data)
   615  		c.Assert(data, IsNil)
   616  	}
   617  }
   618  
   619  // --------------------------------------------------------------------------
   620  // Unmarshalling error cases.
   621  
   622  type unmarshalErrorType struct {
   623  	obj   interface{}
   624  	data  string
   625  	error string
   626  }
   627  
   628  var unmarshalErrorItems = []unmarshalErrorType{
   629  	// Tag name conflicts with existing parameter.
   630  	{&structWithDupKeys{},
   631  		"\x10name\x00\x08\x00\x00\x00",
   632  		"Duplicated key 'name' in struct bson_test.structWithDupKeys"},
   633  
   634  	// Non-string map key.
   635  	{map[int]interface{}{},
   636  		"\x10name\x00\x08\x00\x00\x00",
   637  		"BSON map must have string keys. Got: map\\[int\\]interface \\{\\}"},
   638  
   639  	{nil,
   640  		"\xEEname\x00",
   641  		"Unknown element kind \\(0xEE\\)"},
   642  
   643  	{struct{ Name bool }{},
   644  		"\x10name\x00\x08\x00\x00\x00",
   645  		"Unmarshal can't deal with struct values. Use a pointer."},
   646  
   647  	{123,
   648  		"\x10name\x00\x08\x00\x00\x00",
   649  		"Unmarshal needs a map or a pointer to a struct."},
   650  
   651  	{nil,
   652  		"\x08\x62\x00\x02",
   653  		"encoded boolean must be 1 or 0, found 2"},
   654  }
   655  
   656  func (s *S) TestUnmarshalErrorItems(c *C) {
   657  	for _, item := range unmarshalErrorItems {
   658  		data := []byte(wrapInDoc(item.data))
   659  		var value interface{}
   660  		switch reflect.ValueOf(item.obj).Kind() {
   661  		case reflect.Map, reflect.Ptr:
   662  			value = makeZeroDoc(item.obj)
   663  		case reflect.Invalid:
   664  			value = bson.M{}
   665  		default:
   666  			value = item.obj
   667  		}
   668  		err := bson.Unmarshal(data, value)
   669  		c.Assert(err, ErrorMatches, item.error)
   670  	}
   671  }
   672  
   673  type unmarshalRawErrorType struct {
   674  	obj   interface{}
   675  	raw   bson.Raw
   676  	error string
   677  }
   678  
   679  var unmarshalRawErrorItems = []unmarshalRawErrorType{
   680  	// Tag name conflicts with existing parameter.
   681  	{&structWithDupKeys{},
   682  		bson.Raw{0x03, []byte("\x10byte\x00\x08\x00\x00\x00")},
   683  		"Duplicated key 'name' in struct bson_test.structWithDupKeys"},
   684  
   685  	{&struct{}{},
   686  		bson.Raw{0xEE, []byte{}},
   687  		"Unknown element kind \\(0xEE\\)"},
   688  
   689  	{struct{ Name bool }{},
   690  		bson.Raw{0x10, []byte("\x08\x00\x00\x00")},
   691  		"Raw Unmarshal can't deal with struct values. Use a pointer."},
   692  
   693  	{123,
   694  		bson.Raw{0x10, []byte("\x08\x00\x00\x00")},
   695  		"Raw Unmarshal needs a map or a valid pointer."},
   696  }
   697  
   698  func (s *S) TestUnmarshalRawErrorItems(c *C) {
   699  	for i, item := range unmarshalRawErrorItems {
   700  		err := item.raw.Unmarshal(item.obj)
   701  		c.Assert(err, ErrorMatches, item.error, Commentf("Failed on item %d: %#v\n", i, item))
   702  	}
   703  }
   704  
   705  var corruptedData = []string{
   706  	"\x04\x00\x00\x00\x00",         // Document shorter than minimum
   707  	"\x06\x00\x00\x00\x00",         // Not enough data
   708  	"\x05\x00\x00",                 // Broken length
   709  	"\x05\x00\x00\x00\xff",         // Corrupted termination
   710  	"\x0A\x00\x00\x00\x0Aooop\x00", // Unfinished C string
   711  
   712  	// Array end past end of string (s[2]=0x07 is correct)
   713  	wrapInDoc("\x04\x00\x09\x00\x00\x00\x0A\x00\x00"),
   714  
   715  	// Array end within string, but past acceptable.
   716  	wrapInDoc("\x04\x00\x08\x00\x00\x00\x0A\x00\x00"),
   717  
   718  	// Document end within string, but past acceptable.
   719  	wrapInDoc("\x03\x00\x08\x00\x00\x00\x0A\x00\x00"),
   720  
   721  	// String with corrupted end.
   722  	wrapInDoc("\x02\x00\x03\x00\x00\x00yo\xFF"),
   723  
   724  	// String with negative length (issue #116).
   725  	"\x0c\x00\x00\x00\x02x\x00\xff\xff\xff\xff\x00",
   726  
   727  	// String with zero length (must include trailing '\x00')
   728  	"\x0c\x00\x00\x00\x02x\x00\x00\x00\x00\x00\x00",
   729  
   730  	// Binary with negative length.
   731  	"\r\x00\x00\x00\x05x\x00\xff\xff\xff\xff\x00\x00",
   732  }
   733  
   734  func (s *S) TestUnmarshalMapDocumentTooShort(c *C) {
   735  	for _, data := range corruptedData {
   736  		err := bson.Unmarshal([]byte(data), bson.M{})
   737  		c.Assert(err, ErrorMatches, "Document is corrupted")
   738  
   739  		err = bson.Unmarshal([]byte(data), &struct{}{})
   740  		c.Assert(err, ErrorMatches, "Document is corrupted")
   741  	}
   742  }
   743  
   744  // --------------------------------------------------------------------------
   745  // Setter test cases.
   746  
   747  var setterResult = map[string]error{}
   748  
   749  type setterType struct {
   750  	received interface{}
   751  }
   752  
   753  func (o *setterType) SetBSON(raw bson.Raw) error {
   754  	err := raw.Unmarshal(&o.received)
   755  	if err != nil {
   756  		panic("The panic:" + err.Error())
   757  	}
   758  	if s, ok := o.received.(string); ok {
   759  		if result, ok := setterResult[s]; ok {
   760  			return result
   761  		}
   762  	}
   763  	return nil
   764  }
   765  
   766  type ptrSetterDoc struct {
   767  	Field *setterType "_"
   768  }
   769  
   770  type valSetterDoc struct {
   771  	Field setterType "_"
   772  }
   773  
   774  func (s *S) TestUnmarshalAllItemsWithPtrSetter(c *C) {
   775  	for _, item := range allItems {
   776  		for i := 0; i != 2; i++ {
   777  			var field *setterType
   778  			if i == 0 {
   779  				obj := &ptrSetterDoc{}
   780  				err := bson.Unmarshal([]byte(wrapInDoc(item.data)), obj)
   781  				c.Assert(err, IsNil)
   782  				field = obj.Field
   783  			} else {
   784  				obj := &valSetterDoc{}
   785  				err := bson.Unmarshal([]byte(wrapInDoc(item.data)), obj)
   786  				c.Assert(err, IsNil)
   787  				field = &obj.Field
   788  			}
   789  			if item.data == "" {
   790  				// Nothing to unmarshal. Should be untouched.
   791  				if i == 0 {
   792  					c.Assert(field, IsNil)
   793  				} else {
   794  					c.Assert(field.received, IsNil)
   795  				}
   796  			} else {
   797  				expected := item.obj.(bson.M)["_"]
   798  				c.Assert(field, NotNil, Commentf("Pointer not initialized (%#v)", expected))
   799  				c.Assert(field.received, DeepEquals, expected)
   800  			}
   801  		}
   802  	}
   803  }
   804  
   805  func (s *S) TestUnmarshalWholeDocumentWithSetter(c *C) {
   806  	obj := &setterType{}
   807  	err := bson.Unmarshal([]byte(sampleItems[0].data), obj)
   808  	c.Assert(err, IsNil)
   809  	c.Assert(obj.received, DeepEquals, bson.M{"hello": "world"})
   810  }
   811  
   812  func (s *S) TestUnmarshalSetterOmits(c *C) {
   813  	setterResult["2"] = &bson.TypeError{}
   814  	setterResult["4"] = &bson.TypeError{}
   815  	defer func() {
   816  		delete(setterResult, "2")
   817  		delete(setterResult, "4")
   818  	}()
   819  
   820  	m := map[string]*setterType{}
   821  	data := wrapInDoc("\x02abc\x00\x02\x00\x00\x001\x00" +
   822  		"\x02def\x00\x02\x00\x00\x002\x00" +
   823  		"\x02ghi\x00\x02\x00\x00\x003\x00" +
   824  		"\x02jkl\x00\x02\x00\x00\x004\x00")
   825  	err := bson.Unmarshal([]byte(data), m)
   826  	c.Assert(err, IsNil)
   827  	c.Assert(m["abc"], NotNil)
   828  	c.Assert(m["def"], IsNil)
   829  	c.Assert(m["ghi"], NotNil)
   830  	c.Assert(m["jkl"], IsNil)
   831  
   832  	c.Assert(m["abc"].received, Equals, "1")
   833  	c.Assert(m["ghi"].received, Equals, "3")
   834  }
   835  
   836  func (s *S) TestUnmarshalSetterErrors(c *C) {
   837  	boom := errors.New("BOOM")
   838  	setterResult["2"] = boom
   839  	defer delete(setterResult, "2")
   840  
   841  	m := map[string]*setterType{}
   842  	data := wrapInDoc("\x02abc\x00\x02\x00\x00\x001\x00" +
   843  		"\x02def\x00\x02\x00\x00\x002\x00" +
   844  		"\x02ghi\x00\x02\x00\x00\x003\x00")
   845  	err := bson.Unmarshal([]byte(data), m)
   846  	c.Assert(err, Equals, boom)
   847  	c.Assert(m["abc"], NotNil)
   848  	c.Assert(m["def"], IsNil)
   849  	c.Assert(m["ghi"], IsNil)
   850  
   851  	c.Assert(m["abc"].received, Equals, "1")
   852  }
   853  
   854  func (s *S) TestDMap(c *C) {
   855  	d := bson.D{{"a", 1}, {"b", 2}}
   856  	c.Assert(d.Map(), DeepEquals, bson.M{"a": 1, "b": 2})
   857  }
   858  
   859  func (s *S) TestUnmarshalSetterSetZero(c *C) {
   860  	setterResult["foo"] = bson.SetZero
   861  	defer delete(setterResult, "field")
   862  
   863  	data, err := bson.Marshal(bson.M{"field": "foo"})
   864  	c.Assert(err, IsNil)
   865  
   866  	m := map[string]*setterType{}
   867  	err = bson.Unmarshal([]byte(data), m)
   868  	c.Assert(err, IsNil)
   869  
   870  	value, ok := m["field"]
   871  	c.Assert(ok, Equals, true)
   872  	c.Assert(value, IsNil)
   873  }
   874  
   875  // --------------------------------------------------------------------------
   876  // Getter test cases.
   877  
   878  type typeWithGetter struct {
   879  	result interface{}
   880  	err    error
   881  }
   882  
   883  func (t *typeWithGetter) GetBSON() (interface{}, error) {
   884  	if t == nil {
   885  		return "<value is nil>", nil
   886  	}
   887  	return t.result, t.err
   888  }
   889  
   890  type docWithGetterField struct {
   891  	Field *typeWithGetter "_"
   892  }
   893  
   894  func (s *S) TestMarshalAllItemsWithGetter(c *C) {
   895  	for i, item := range allItems {
   896  		if item.data == "" {
   897  			continue
   898  		}
   899  		obj := &docWithGetterField{}
   900  		obj.Field = &typeWithGetter{result: item.obj.(bson.M)["_"]}
   901  		data, err := bson.Marshal(obj)
   902  		c.Assert(err, IsNil)
   903  		c.Assert(string(data), Equals, wrapInDoc(item.data),
   904  			Commentf("Failed on item #%d", i))
   905  	}
   906  }
   907  
   908  func (s *S) TestMarshalWholeDocumentWithGetter(c *C) {
   909  	obj := &typeWithGetter{result: sampleItems[0].obj}
   910  	data, err := bson.Marshal(obj)
   911  	c.Assert(err, IsNil)
   912  	c.Assert(string(data), Equals, sampleItems[0].data)
   913  }
   914  
   915  func (s *S) TestGetterErrors(c *C) {
   916  	e := errors.New("oops")
   917  
   918  	obj1 := &docWithGetterField{}
   919  	obj1.Field = &typeWithGetter{sampleItems[0].obj, e}
   920  	data, err := bson.Marshal(obj1)
   921  	c.Assert(err, ErrorMatches, "oops")
   922  	c.Assert(data, IsNil)
   923  
   924  	obj2 := &typeWithGetter{sampleItems[0].obj, e}
   925  	data, err = bson.Marshal(obj2)
   926  	c.Assert(err, ErrorMatches, "oops")
   927  	c.Assert(data, IsNil)
   928  }
   929  
   930  type intGetter int64
   931  
   932  func (t intGetter) GetBSON() (interface{}, error) {
   933  	return int64(t), nil
   934  }
   935  
   936  type typeWithIntGetter struct {
   937  	V intGetter ",minsize"
   938  }
   939  
   940  func (s *S) TestMarshalShortWithGetter(c *C) {
   941  	obj := typeWithIntGetter{42}
   942  	data, err := bson.Marshal(obj)
   943  	c.Assert(err, IsNil)
   944  	m := bson.M{}
   945  	err = bson.Unmarshal(data, m)
   946  	c.Assert(err, IsNil)
   947  	c.Assert(m["v"], Equals, 42)
   948  }
   949  
   950  func (s *S) TestMarshalWithGetterNil(c *C) {
   951  	obj := docWithGetterField{}
   952  	data, err := bson.Marshal(obj)
   953  	c.Assert(err, IsNil)
   954  	m := bson.M{}
   955  	err = bson.Unmarshal(data, m)
   956  	c.Assert(err, IsNil)
   957  	c.Assert(m, DeepEquals, bson.M{"_": "<value is nil>"})
   958  }
   959  
   960  // --------------------------------------------------------------------------
   961  // Cross-type conversion tests.
   962  
   963  type crossTypeItem struct {
   964  	obj1 interface{}
   965  	obj2 interface{}
   966  }
   967  
   968  type condStr struct {
   969  	V string ",omitempty"
   970  }
   971  type condStrNS struct {
   972  	V string `a:"A" bson:",omitempty" b:"B"`
   973  }
   974  type condBool struct {
   975  	V bool ",omitempty"
   976  }
   977  type condInt struct {
   978  	V int ",omitempty"
   979  }
   980  type condUInt struct {
   981  	V uint ",omitempty"
   982  }
   983  type condFloat struct {
   984  	V float64 ",omitempty"
   985  }
   986  type condIface struct {
   987  	V interface{} ",omitempty"
   988  }
   989  type condPtr struct {
   990  	V *bool ",omitempty"
   991  }
   992  type condSlice struct {
   993  	V []string ",omitempty"
   994  }
   995  type condMap struct {
   996  	V map[string]int ",omitempty"
   997  }
   998  type namedCondStr struct {
   999  	V string "myv,omitempty"
  1000  }
  1001  type condTime struct {
  1002  	V time.Time ",omitempty"
  1003  }
  1004  type condStruct struct {
  1005  	V struct{ A []int } ",omitempty"
  1006  }
  1007  type condRaw struct {
  1008  	V bson.Raw ",omitempty"
  1009  }
  1010  
  1011  type shortInt struct {
  1012  	V int64 ",minsize"
  1013  }
  1014  type shortUint struct {
  1015  	V uint64 ",minsize"
  1016  }
  1017  type shortIface struct {
  1018  	V interface{} ",minsize"
  1019  }
  1020  type shortPtr struct {
  1021  	V *int64 ",minsize"
  1022  }
  1023  type shortNonEmptyInt struct {
  1024  	V int64 ",minsize,omitempty"
  1025  }
  1026  
  1027  type inlineInt struct {
  1028  	V struct{ A, B int } ",inline"
  1029  }
  1030  type inlineCantPtr struct {
  1031  	V *struct{ A, B int } ",inline"
  1032  }
  1033  type inlineDupName struct {
  1034  	A int
  1035  	V struct{ A, B int } ",inline"
  1036  }
  1037  type inlineMap struct {
  1038  	A int
  1039  	M map[string]interface{} ",inline"
  1040  }
  1041  type inlineMapInt struct {
  1042  	A int
  1043  	M map[string]int ",inline"
  1044  }
  1045  type inlineMapMyM struct {
  1046  	A int
  1047  	M MyM ",inline"
  1048  }
  1049  type inlineDupMap struct {
  1050  	M1 map[string]interface{} ",inline"
  1051  	M2 map[string]interface{} ",inline"
  1052  }
  1053  type inlineBadKeyMap struct {
  1054  	M map[int]int ",inline"
  1055  }
  1056  type inlineUnexported struct {
  1057  	M          map[string]interface{} ",inline"
  1058  	unexported ",inline"
  1059  }
  1060  type unexported struct {
  1061  	A int
  1062  }
  1063  
  1064  type getterSetterD bson.D
  1065  
  1066  func (s getterSetterD) GetBSON() (interface{}, error) {
  1067  	if len(s) == 0 {
  1068  		return bson.D{}, nil
  1069  	}
  1070  	return bson.D(s[:len(s)-1]), nil
  1071  }
  1072  
  1073  func (s *getterSetterD) SetBSON(raw bson.Raw) error {
  1074  	var doc bson.D
  1075  	err := raw.Unmarshal(&doc)
  1076  	doc = append(doc, bson.DocElem{"suffix", true})
  1077  	*s = getterSetterD(doc)
  1078  	return err
  1079  }
  1080  
  1081  type getterSetterInt int
  1082  
  1083  func (i getterSetterInt) GetBSON() (interface{}, error) {
  1084  	return bson.D{{"a", int(i)}}, nil
  1085  }
  1086  
  1087  func (i *getterSetterInt) SetBSON(raw bson.Raw) error {
  1088  	var doc struct{ A int }
  1089  	err := raw.Unmarshal(&doc)
  1090  	*i = getterSetterInt(doc.A)
  1091  	return err
  1092  }
  1093  
  1094  type ifaceType interface {
  1095  	Hello()
  1096  }
  1097  
  1098  type ifaceSlice []ifaceType
  1099  
  1100  func (s *ifaceSlice) SetBSON(raw bson.Raw) error {
  1101  	var ns []int
  1102  	if err := raw.Unmarshal(&ns); err != nil {
  1103  		return err
  1104  	}
  1105  	*s = make(ifaceSlice, ns[0])
  1106  	return nil
  1107  }
  1108  
  1109  func (s ifaceSlice) GetBSON() (interface{}, error) {
  1110  	return []int{len(s)}, nil
  1111  }
  1112  
  1113  type (
  1114  	MyString string
  1115  	MyBytes  []byte
  1116  	MyBool   bool
  1117  	MyD      []bson.DocElem
  1118  	MyRawD   []bson.RawDocElem
  1119  	MyM      map[string]interface{}
  1120  )
  1121  
  1122  var (
  1123  	truevar  = true
  1124  	falsevar = false
  1125  
  1126  	int64var = int64(42)
  1127  	int64ptr = &int64var
  1128  	intvar   = int(42)
  1129  	intptr   = &intvar
  1130  
  1131  	gsintvar = getterSetterInt(42)
  1132  )
  1133  
  1134  func parseURL(s string) *url.URL {
  1135  	u, err := url.Parse(s)
  1136  	if err != nil {
  1137  		panic(err)
  1138  	}
  1139  	return u
  1140  }
  1141  
  1142  // That's a pretty fun test.  It will dump the first item, generate a zero
  1143  // value equivalent to the second one, load the dumped data onto it, and then
  1144  // verify that the resulting value is deep-equal to the untouched second value.
  1145  // Then, it will do the same in the *opposite* direction!
  1146  var twoWayCrossItems = []crossTypeItem{
  1147  	// int<=>int
  1148  	{&struct{ I int }{42}, &struct{ I int8 }{42}},
  1149  	{&struct{ I int }{42}, &struct{ I int32 }{42}},
  1150  	{&struct{ I int }{42}, &struct{ I int64 }{42}},
  1151  	{&struct{ I int8 }{42}, &struct{ I int32 }{42}},
  1152  	{&struct{ I int8 }{42}, &struct{ I int64 }{42}},
  1153  	{&struct{ I int32 }{42}, &struct{ I int64 }{42}},
  1154  
  1155  	// uint<=>uint
  1156  	{&struct{ I uint }{42}, &struct{ I uint8 }{42}},
  1157  	{&struct{ I uint }{42}, &struct{ I uint32 }{42}},
  1158  	{&struct{ I uint }{42}, &struct{ I uint64 }{42}},
  1159  	{&struct{ I uint8 }{42}, &struct{ I uint32 }{42}},
  1160  	{&struct{ I uint8 }{42}, &struct{ I uint64 }{42}},
  1161  	{&struct{ I uint32 }{42}, &struct{ I uint64 }{42}},
  1162  
  1163  	// float32<=>float64
  1164  	{&struct{ I float32 }{42}, &struct{ I float64 }{42}},
  1165  
  1166  	// int<=>uint
  1167  	{&struct{ I uint }{42}, &struct{ I int }{42}},
  1168  	{&struct{ I uint }{42}, &struct{ I int8 }{42}},
  1169  	{&struct{ I uint }{42}, &struct{ I int32 }{42}},
  1170  	{&struct{ I uint }{42}, &struct{ I int64 }{42}},
  1171  	{&struct{ I uint8 }{42}, &struct{ I int }{42}},
  1172  	{&struct{ I uint8 }{42}, &struct{ I int8 }{42}},
  1173  	{&struct{ I uint8 }{42}, &struct{ I int32 }{42}},
  1174  	{&struct{ I uint8 }{42}, &struct{ I int64 }{42}},
  1175  	{&struct{ I uint32 }{42}, &struct{ I int }{42}},
  1176  	{&struct{ I uint32 }{42}, &struct{ I int8 }{42}},
  1177  	{&struct{ I uint32 }{42}, &struct{ I int32 }{42}},
  1178  	{&struct{ I uint32 }{42}, &struct{ I int64 }{42}},
  1179  	{&struct{ I uint64 }{42}, &struct{ I int }{42}},
  1180  	{&struct{ I uint64 }{42}, &struct{ I int8 }{42}},
  1181  	{&struct{ I uint64 }{42}, &struct{ I int32 }{42}},
  1182  	{&struct{ I uint64 }{42}, &struct{ I int64 }{42}},
  1183  
  1184  	// int <=> float
  1185  	{&struct{ I int }{42}, &struct{ I float64 }{42}},
  1186  
  1187  	// int <=> bool
  1188  	{&struct{ I int }{1}, &struct{ I bool }{true}},
  1189  	{&struct{ I int }{0}, &struct{ I bool }{false}},
  1190  
  1191  	// uint <=> float64
  1192  	{&struct{ I uint }{42}, &struct{ I float64 }{42}},
  1193  
  1194  	// uint <=> bool
  1195  	{&struct{ I uint }{1}, &struct{ I bool }{true}},
  1196  	{&struct{ I uint }{0}, &struct{ I bool }{false}},
  1197  
  1198  	// float64 <=> bool
  1199  	{&struct{ I float64 }{1}, &struct{ I bool }{true}},
  1200  	{&struct{ I float64 }{0}, &struct{ I bool }{false}},
  1201  
  1202  	// string <=> string and string <=> []byte
  1203  	{&struct{ S []byte }{[]byte("abc")}, &struct{ S string }{"abc"}},
  1204  	{&struct{ S []byte }{[]byte("def")}, &struct{ S bson.Symbol }{"def"}},
  1205  	{&struct{ S string }{"ghi"}, &struct{ S bson.Symbol }{"ghi"}},
  1206  
  1207  	// map <=> struct
  1208  	{&struct {
  1209  		A struct {
  1210  			B, C int
  1211  		}
  1212  	}{struct{ B, C int }{1, 2}},
  1213  		map[string]map[string]int{"a": map[string]int{"b": 1, "c": 2}}},
  1214  
  1215  	{&struct{ A bson.Symbol }{"abc"}, map[string]string{"a": "abc"}},
  1216  	{&struct{ A bson.Symbol }{"abc"}, map[string][]byte{"a": []byte("abc")}},
  1217  	{&struct{ A []byte }{[]byte("abc")}, map[string]string{"a": "abc"}},
  1218  	{&struct{ A uint }{42}, map[string]int{"a": 42}},
  1219  	{&struct{ A uint }{42}, map[string]float64{"a": 42}},
  1220  	{&struct{ A uint }{1}, map[string]bool{"a": true}},
  1221  	{&struct{ A int }{42}, map[string]uint{"a": 42}},
  1222  	{&struct{ A int }{42}, map[string]float64{"a": 42}},
  1223  	{&struct{ A int }{1}, map[string]bool{"a": true}},
  1224  	{&struct{ A float64 }{42}, map[string]float32{"a": 42}},
  1225  	{&struct{ A float64 }{42}, map[string]int{"a": 42}},
  1226  	{&struct{ A float64 }{42}, map[string]uint{"a": 42}},
  1227  	{&struct{ A float64 }{1}, map[string]bool{"a": true}},
  1228  	{&struct{ A bool }{true}, map[string]int{"a": 1}},
  1229  	{&struct{ A bool }{true}, map[string]uint{"a": 1}},
  1230  	{&struct{ A bool }{true}, map[string]float64{"a": 1}},
  1231  	{&struct{ A **byte }{&byteptr}, map[string]byte{"a": 8}},
  1232  
  1233  	// url.URL <=> string
  1234  	{&struct{ URL *url.URL }{parseURL("h://e.c/p")}, map[string]string{"url": "h://e.c/p"}},
  1235  	{&struct{ URL url.URL }{*parseURL("h://e.c/p")}, map[string]string{"url": "h://e.c/p"}},
  1236  
  1237  	// Slices
  1238  	{&struct{ S []int }{[]int{1, 2, 3}}, map[string][]int{"s": []int{1, 2, 3}}},
  1239  	{&struct{ S *[]int }{&[]int{1, 2, 3}}, map[string][]int{"s": []int{1, 2, 3}}},
  1240  
  1241  	// Conditionals
  1242  	{&condBool{true}, map[string]bool{"v": true}},
  1243  	{&condBool{}, map[string]bool{}},
  1244  	{&condInt{1}, map[string]int{"v": 1}},
  1245  	{&condInt{}, map[string]int{}},
  1246  	{&condUInt{1}, map[string]uint{"v": 1}},
  1247  	{&condUInt{}, map[string]uint{}},
  1248  	{&condFloat{}, map[string]int{}},
  1249  	{&condStr{"yo"}, map[string]string{"v": "yo"}},
  1250  	{&condStr{}, map[string]string{}},
  1251  	{&condStrNS{"yo"}, map[string]string{"v": "yo"}},
  1252  	{&condStrNS{}, map[string]string{}},
  1253  	{&condSlice{[]string{"yo"}}, map[string][]string{"v": []string{"yo"}}},
  1254  	{&condSlice{}, map[string][]string{}},
  1255  	{&condMap{map[string]int{"k": 1}}, bson.M{"v": bson.M{"k": 1}}},
  1256  	{&condMap{}, map[string][]string{}},
  1257  	{&condIface{"yo"}, map[string]string{"v": "yo"}},
  1258  	{&condIface{""}, map[string]string{"v": ""}},
  1259  	{&condIface{}, map[string]string{}},
  1260  	{&condPtr{&truevar}, map[string]bool{"v": true}},
  1261  	{&condPtr{&falsevar}, map[string]bool{"v": false}},
  1262  	{&condPtr{}, map[string]string{}},
  1263  
  1264  	{&condTime{time.Unix(123456789, 123e6)}, map[string]time.Time{"v": time.Unix(123456789, 123e6)}},
  1265  	{&condTime{}, map[string]string{}},
  1266  
  1267  	{&condStruct{struct{ A []int }{[]int{1}}}, bson.M{"v": bson.M{"a": []interface{}{1}}}},
  1268  	{&condStruct{struct{ A []int }{}}, bson.M{}},
  1269  
  1270  	{&condRaw{bson.Raw{Kind: 0x0A, Data: []byte{}}}, bson.M{"v": nil}},
  1271  	{&condRaw{bson.Raw{Kind: 0x00}}, bson.M{}},
  1272  
  1273  	{&namedCondStr{"yo"}, map[string]string{"myv": "yo"}},
  1274  	{&namedCondStr{}, map[string]string{}},
  1275  
  1276  	{&shortInt{1}, map[string]interface{}{"v": 1}},
  1277  	{&shortInt{1 << 30}, map[string]interface{}{"v": 1 << 30}},
  1278  	{&shortInt{1 << 31}, map[string]interface{}{"v": int64(1 << 31)}},
  1279  	{&shortUint{1 << 30}, map[string]interface{}{"v": 1 << 30}},
  1280  	{&shortUint{1 << 31}, map[string]interface{}{"v": int64(1 << 31)}},
  1281  	{&shortIface{int64(1) << 31}, map[string]interface{}{"v": int64(1 << 31)}},
  1282  	{&shortPtr{int64ptr}, map[string]interface{}{"v": intvar}},
  1283  
  1284  	{&shortNonEmptyInt{1}, map[string]interface{}{"v": 1}},
  1285  	{&shortNonEmptyInt{1 << 31}, map[string]interface{}{"v": int64(1 << 31)}},
  1286  	{&shortNonEmptyInt{}, map[string]interface{}{}},
  1287  
  1288  	{&inlineInt{struct{ A, B int }{1, 2}}, map[string]interface{}{"a": 1, "b": 2}},
  1289  	{&inlineMap{A: 1, M: map[string]interface{}{"b": 2}}, map[string]interface{}{"a": 1, "b": 2}},
  1290  	{&inlineMap{A: 1, M: nil}, map[string]interface{}{"a": 1}},
  1291  	{&inlineMapInt{A: 1, M: map[string]int{"b": 2}}, map[string]int{"a": 1, "b": 2}},
  1292  	{&inlineMapInt{A: 1, M: nil}, map[string]int{"a": 1}},
  1293  	{&inlineMapMyM{A: 1, M: MyM{"b": MyM{"c": 3}}}, map[string]interface{}{"a": 1, "b": map[string]interface{}{"c": 3}}},
  1294  	{&inlineUnexported{M: map[string]interface{}{"b": 1}, unexported: unexported{A: 2}}, map[string]interface{}{"b": 1, "a": 2}},
  1295  
  1296  	// []byte <=> Binary
  1297  	{&struct{ B []byte }{[]byte("abc")}, map[string]bson.Binary{"b": bson.Binary{Data: []byte("abc")}}},
  1298  
  1299  	// []byte <=> MyBytes
  1300  	{&struct{ B MyBytes }{[]byte("abc")}, map[string]string{"b": "abc"}},
  1301  	{&struct{ B MyBytes }{[]byte{}}, map[string]string{"b": ""}},
  1302  	{&struct{ B MyBytes }{}, map[string]bool{}},
  1303  	{&struct{ B []byte }{[]byte("abc")}, map[string]MyBytes{"b": []byte("abc")}},
  1304  
  1305  	// bool <=> MyBool
  1306  	{&struct{ B MyBool }{true}, map[string]bool{"b": true}},
  1307  	{&struct{ B MyBool }{}, map[string]bool{"b": false}},
  1308  	{&struct{ B MyBool }{}, map[string]string{}},
  1309  	{&struct{ B bool }{}, map[string]MyBool{"b": false}},
  1310  
  1311  	// arrays
  1312  	{&struct{ V [2]int }{[...]int{1, 2}}, map[string][2]int{"v": [2]int{1, 2}}},
  1313  	{&struct{ V [2]byte }{[...]byte{1, 2}}, map[string][2]byte{"v": [2]byte{1, 2}}},
  1314  
  1315  	// zero time
  1316  	{&struct{ V time.Time }{}, map[string]interface{}{"v": time.Time{}}},
  1317  
  1318  	// zero time + 1 second + 1 millisecond; overflows int64 as nanoseconds
  1319  	{&struct{ V time.Time }{time.Unix(-62135596799, 1e6).Local()},
  1320  		map[string]interface{}{"v": time.Unix(-62135596799, 1e6).Local()}},
  1321  
  1322  	// bson.D <=> []DocElem
  1323  	{&bson.D{{"a", bson.D{{"b", 1}, {"c", 2}}}}, &bson.D{{"a", bson.D{{"b", 1}, {"c", 2}}}}},
  1324  	{&bson.D{{"a", bson.D{{"b", 1}, {"c", 2}}}}, &MyD{{"a", MyD{{"b", 1}, {"c", 2}}}}},
  1325  	{&struct{ V MyD }{MyD{{"a", 1}}}, &bson.D{{"v", bson.D{{"a", 1}}}}},
  1326  
  1327  	// bson.RawD <=> []RawDocElem
  1328  	{&bson.RawD{{"a", bson.Raw{0x08, []byte{0x01}}}}, &bson.RawD{{"a", bson.Raw{0x08, []byte{0x01}}}}},
  1329  	{&bson.RawD{{"a", bson.Raw{0x08, []byte{0x01}}}}, &MyRawD{{"a", bson.Raw{0x08, []byte{0x01}}}}},
  1330  
  1331  	// bson.M <=> map
  1332  	{bson.M{"a": bson.M{"b": 1, "c": 2}}, MyM{"a": MyM{"b": 1, "c": 2}}},
  1333  	{bson.M{"a": bson.M{"b": 1, "c": 2}}, map[string]interface{}{"a": map[string]interface{}{"b": 1, "c": 2}}},
  1334  
  1335  	// bson.M <=> map[MyString]
  1336  	{bson.M{"a": bson.M{"b": 1, "c": 2}}, map[MyString]interface{}{"a": map[MyString]interface{}{"b": 1, "c": 2}}},
  1337  
  1338  	// json.Number <=> int64, float64
  1339  	{&struct{ N json.Number }{"5"}, map[string]interface{}{"n": int64(5)}},
  1340  	{&struct{ N json.Number }{"5.05"}, map[string]interface{}{"n": 5.05}},
  1341  	{&struct{ N json.Number }{"9223372036854776000"}, map[string]interface{}{"n": float64(1 << 63)}},
  1342  
  1343  	// bson.D <=> non-struct getter/setter
  1344  	{&bson.D{{"a", 1}}, &getterSetterD{{"a", 1}, {"suffix", true}}},
  1345  	{&bson.D{{"a", 42}}, &gsintvar},
  1346  
  1347  	// Interface slice setter.
  1348  	{&struct{ V ifaceSlice }{ifaceSlice{nil, nil, nil}}, bson.M{"v": []interface{}{3}}},
  1349  }
  1350  
  1351  // Same thing, but only one way (obj1 => obj2).
  1352  var oneWayCrossItems = []crossTypeItem{
  1353  	// map <=> struct
  1354  	{map[string]interface{}{"a": 1, "b": "2", "c": 3}, map[string]int{"a": 1, "c": 3}},
  1355  
  1356  	// inline map elides badly typed values
  1357  	{map[string]interface{}{"a": 1, "b": "2", "c": 3}, &inlineMapInt{A: 1, M: map[string]int{"c": 3}}},
  1358  
  1359  	// Can't decode int into struct.
  1360  	{bson.M{"a": bson.M{"b": 2}}, &struct{ A bool }{}},
  1361  
  1362  	// Would get decoded into a int32 too in the opposite direction.
  1363  	{&shortIface{int64(1) << 30}, map[string]interface{}{"v": 1 << 30}},
  1364  
  1365  	// Ensure omitempty on struct with private fields works properly.
  1366  	{&struct {
  1367  		V struct{ v time.Time } ",omitempty"
  1368  	}{}, map[string]interface{}{}},
  1369  
  1370  	// Attempt to marshal slice into RawD (issue #120).
  1371  	{bson.M{"x": []int{1, 2, 3}}, &struct{ X bson.RawD }{}},
  1372  }
  1373  
  1374  func testCrossPair(c *C, dump interface{}, load interface{}) {
  1375  	c.Logf("Dump: %#v", dump)
  1376  	c.Logf("Load: %#v", load)
  1377  	zero := makeZeroDoc(load)
  1378  	data, err := bson.Marshal(dump)
  1379  	c.Assert(err, IsNil)
  1380  	c.Logf("Dumped: %#v", string(data))
  1381  	err = bson.Unmarshal(data, zero)
  1382  	c.Assert(err, IsNil)
  1383  	c.Logf("Loaded: %#v", zero)
  1384  	c.Assert(zero, DeepEquals, load)
  1385  }
  1386  
  1387  func (s *S) TestTwoWayCrossPairs(c *C) {
  1388  	for _, item := range twoWayCrossItems {
  1389  		testCrossPair(c, item.obj1, item.obj2)
  1390  		testCrossPair(c, item.obj2, item.obj1)
  1391  	}
  1392  }
  1393  
  1394  func (s *S) TestOneWayCrossPairs(c *C) {
  1395  	for _, item := range oneWayCrossItems {
  1396  		testCrossPair(c, item.obj1, item.obj2)
  1397  	}
  1398  }
  1399  
  1400  // --------------------------------------------------------------------------
  1401  // ObjectId hex representation test.
  1402  
  1403  func (s *S) TestObjectIdHex(c *C) {
  1404  	id := bson.ObjectIdHex("4d88e15b60f486e428412dc9")
  1405  	c.Assert(id.String(), Equals, `ObjectIdHex("4d88e15b60f486e428412dc9")`)
  1406  	c.Assert(id.Hex(), Equals, "4d88e15b60f486e428412dc9")
  1407  }
  1408  
  1409  func (s *S) TestIsObjectIdHex(c *C) {
  1410  	test := []struct {
  1411  		id    string
  1412  		valid bool
  1413  	}{
  1414  		{"4d88e15b60f486e428412dc9", true},
  1415  		{"4d88e15b60f486e428412dc", false},
  1416  		{"4d88e15b60f486e428412dc9e", false},
  1417  		{"4d88e15b60f486e428412dcx", false},
  1418  	}
  1419  	for _, t := range test {
  1420  		c.Assert(bson.IsObjectIdHex(t.id), Equals, t.valid)
  1421  	}
  1422  }
  1423  
  1424  // --------------------------------------------------------------------------
  1425  // ObjectId parts extraction tests.
  1426  
  1427  type objectIdParts struct {
  1428  	id        bson.ObjectId
  1429  	timestamp int64
  1430  	machine   []byte
  1431  	pid       uint16
  1432  	counter   int32
  1433  }
  1434  
  1435  var objectIds = []objectIdParts{
  1436  	objectIdParts{
  1437  		bson.ObjectIdHex("4d88e15b60f486e428412dc9"),
  1438  		1300816219,
  1439  		[]byte{0x60, 0xf4, 0x86},
  1440  		0xe428,
  1441  		4271561,
  1442  	},
  1443  	objectIdParts{
  1444  		bson.ObjectIdHex("000000000000000000000000"),
  1445  		0,
  1446  		[]byte{0x00, 0x00, 0x00},
  1447  		0x0000,
  1448  		0,
  1449  	},
  1450  	objectIdParts{
  1451  		bson.ObjectIdHex("00000000aabbccddee000001"),
  1452  		0,
  1453  		[]byte{0xaa, 0xbb, 0xcc},
  1454  		0xddee,
  1455  		1,
  1456  	},
  1457  }
  1458  
  1459  func (s *S) TestObjectIdPartsExtraction(c *C) {
  1460  	for i, v := range objectIds {
  1461  		t := time.Unix(v.timestamp, 0)
  1462  		c.Assert(v.id.Time(), Equals, t, Commentf("#%d Wrong timestamp value", i))
  1463  		c.Assert(v.id.Machine(), DeepEquals, v.machine, Commentf("#%d Wrong machine id value", i))
  1464  		c.Assert(v.id.Pid(), Equals, v.pid, Commentf("#%d Wrong pid value", i))
  1465  		c.Assert(v.id.Counter(), Equals, v.counter, Commentf("#%d Wrong counter value", i))
  1466  	}
  1467  }
  1468  
  1469  func (s *S) TestNow(c *C) {
  1470  	before := time.Now()
  1471  	time.Sleep(1e6)
  1472  	now := bson.Now()
  1473  	time.Sleep(1e6)
  1474  	after := time.Now()
  1475  	c.Assert(now.After(before) && now.Before(after), Equals, true, Commentf("now=%s, before=%s, after=%s", now, before, after))
  1476  }
  1477  
  1478  // --------------------------------------------------------------------------
  1479  // ObjectId generation tests.
  1480  
  1481  func (s *S) TestNewObjectId(c *C) {
  1482  	// Generate 10 ids
  1483  	ids := make([]bson.ObjectId, 10)
  1484  	for i := 0; i < 10; i++ {
  1485  		ids[i] = bson.NewObjectId()
  1486  	}
  1487  	for i := 1; i < 10; i++ {
  1488  		prevId := ids[i-1]
  1489  		id := ids[i]
  1490  		// Test for uniqueness among all other 9 generated ids
  1491  		for j, tid := range ids {
  1492  			if j != i {
  1493  				c.Assert(id, Not(Equals), tid, Commentf("Generated ObjectId is not unique"))
  1494  			}
  1495  		}
  1496  		// Check that timestamp was incremented and is within 30 seconds of the previous one
  1497  		secs := id.Time().Sub(prevId.Time()).Seconds()
  1498  		c.Assert((secs >= 0 && secs <= 30), Equals, true, Commentf("Wrong timestamp in generated ObjectId"))
  1499  		// Check that machine ids are the same
  1500  		c.Assert(id.Machine(), DeepEquals, prevId.Machine())
  1501  		// Check that pids are the same
  1502  		c.Assert(id.Pid(), Equals, prevId.Pid())
  1503  		// Test for proper increment
  1504  		delta := int(id.Counter() - prevId.Counter())
  1505  		c.Assert(delta, Equals, 1, Commentf("Wrong increment in generated ObjectId"))
  1506  	}
  1507  }
  1508  
  1509  func (s *S) TestNewObjectIdWithTime(c *C) {
  1510  	t := time.Unix(12345678, 0)
  1511  	id := bson.NewObjectIdWithTime(t)
  1512  	c.Assert(id.Time(), Equals, t)
  1513  	c.Assert(id.Machine(), DeepEquals, []byte{0x00, 0x00, 0x00})
  1514  	c.Assert(int(id.Pid()), Equals, 0)
  1515  	c.Assert(int(id.Counter()), Equals, 0)
  1516  }
  1517  
  1518  // --------------------------------------------------------------------------
  1519  // ObjectId JSON marshalling.
  1520  
  1521  type jsonType struct {
  1522  	Id bson.ObjectId
  1523  }
  1524  
  1525  var jsonIdTests = []struct {
  1526  	value     jsonType
  1527  	json      string
  1528  	marshal   bool
  1529  	unmarshal bool
  1530  	error     string
  1531  }{{
  1532  	value:     jsonType{Id: bson.ObjectIdHex("4d88e15b60f486e428412dc9")},
  1533  	json:      `{"Id":"4d88e15b60f486e428412dc9"}`,
  1534  	marshal:   true,
  1535  	unmarshal: true,
  1536  }, {
  1537  	value:     jsonType{},
  1538  	json:      `{"Id":""}`,
  1539  	marshal:   true,
  1540  	unmarshal: true,
  1541  }, {
  1542  	value:     jsonType{},
  1543  	json:      `{"Id":null}`,
  1544  	marshal:   false,
  1545  	unmarshal: true,
  1546  }, {
  1547  	json:      `{"Id":"4d88e15b60f486e428412dc9A"}`,
  1548  	error:     `invalid ObjectId in JSON: "4d88e15b60f486e428412dc9A"`,
  1549  	marshal:   false,
  1550  	unmarshal: true,
  1551  }, {
  1552  	json:      `{"Id":"4d88e15b60f486e428412dcZ"}`,
  1553  	error:     `invalid ObjectId in JSON: "4d88e15b60f486e428412dcZ" .*`,
  1554  	marshal:   false,
  1555  	unmarshal: true,
  1556  }}
  1557  
  1558  func (s *S) TestObjectIdJSONMarshaling(c *C) {
  1559  	for _, test := range jsonIdTests {
  1560  		if test.marshal {
  1561  			data, err := json.Marshal(&test.value)
  1562  			if test.error == "" {
  1563  				c.Assert(err, IsNil)
  1564  				c.Assert(string(data), Equals, test.json)
  1565  			} else {
  1566  				c.Assert(err, ErrorMatches, test.error)
  1567  			}
  1568  		}
  1569  
  1570  		if test.unmarshal {
  1571  			var value jsonType
  1572  			err := json.Unmarshal([]byte(test.json), &value)
  1573  			if test.error == "" {
  1574  				c.Assert(err, IsNil)
  1575  				c.Assert(value, DeepEquals, test.value)
  1576  			} else {
  1577  				c.Assert(err, ErrorMatches, test.error)
  1578  			}
  1579  		}
  1580  	}
  1581  }
  1582  
  1583  // --------------------------------------------------------------------------
  1584  // Spec tests
  1585  
  1586  type specTest struct {
  1587  	Description string
  1588  	Documents   []struct {
  1589  		Decoded    map[string]interface{}
  1590  		Encoded    string
  1591  		DecodeOnly bool `yaml:"decodeOnly"`
  1592  		Error      interface{}
  1593  	}
  1594  }
  1595  
  1596  func (s *S) TestSpecTests(c *C) {
  1597  	for _, data := range specTests {
  1598  		var test specTest
  1599  		err := yaml.Unmarshal([]byte(data), &test)
  1600  		c.Assert(err, IsNil)
  1601  
  1602  		c.Logf("Running spec test set %q", test.Description)
  1603  
  1604  		for _, doc := range test.Documents {
  1605  			if doc.Error != nil {
  1606  				continue
  1607  			}
  1608  			c.Logf("Ensuring %q decodes as %v", doc.Encoded, doc.Decoded)
  1609  			var decoded map[string]interface{}
  1610  			encoded, err := hex.DecodeString(doc.Encoded)
  1611  			c.Assert(err, IsNil)
  1612  			err = bson.Unmarshal(encoded, &decoded)
  1613  			c.Assert(err, IsNil)
  1614  			c.Assert(decoded, DeepEquals, doc.Decoded)
  1615  		}
  1616  
  1617  		for _, doc := range test.Documents {
  1618  			if doc.DecodeOnly || doc.Error != nil {
  1619  				continue
  1620  			}
  1621  			c.Logf("Ensuring %v encodes as %q", doc.Decoded, doc.Encoded)
  1622  			encoded, err := bson.Marshal(doc.Decoded)
  1623  			c.Assert(err, IsNil)
  1624  			c.Assert(strings.ToUpper(hex.EncodeToString(encoded)), Equals, doc.Encoded)
  1625  		}
  1626  
  1627  		for _, doc := range test.Documents {
  1628  			if doc.Error == nil {
  1629  				continue
  1630  			}
  1631  			c.Logf("Ensuring %q errors when decoded: %s", doc.Encoded, doc.Error)
  1632  			var decoded map[string]interface{}
  1633  			encoded, err := hex.DecodeString(doc.Encoded)
  1634  			c.Assert(err, IsNil)
  1635  			err = bson.Unmarshal(encoded, &decoded)
  1636  			c.Assert(err, NotNil)
  1637  			c.Logf("Failed with: %v", err)
  1638  		}
  1639  	}
  1640  }
  1641  
  1642  // --------------------------------------------------------------------------
  1643  // ObjectId Text encoding.TextUnmarshaler.
  1644  
  1645  var textIdTests = []struct {
  1646  	value     bson.ObjectId
  1647  	text      string
  1648  	marshal   bool
  1649  	unmarshal bool
  1650  	error     string
  1651  }{{
  1652  	value:     bson.ObjectIdHex("4d88e15b60f486e428412dc9"),
  1653  	text:      "4d88e15b60f486e428412dc9",
  1654  	marshal:   true,
  1655  	unmarshal: true,
  1656  }, {
  1657  	text:      "",
  1658  	marshal:   true,
  1659  	unmarshal: true,
  1660  }, {
  1661  	text:      "4d88e15b60f486e428412dc9A",
  1662  	marshal:   false,
  1663  	unmarshal: true,
  1664  	error:     `invalid ObjectId: 4d88e15b60f486e428412dc9A`,
  1665  }, {
  1666  	text:      "4d88e15b60f486e428412dcZ",
  1667  	marshal:   false,
  1668  	unmarshal: true,
  1669  	error:     `invalid ObjectId: 4d88e15b60f486e428412dcZ .*`,
  1670  }}
  1671  
  1672  func (s *S) TestObjectIdTextMarshaling(c *C) {
  1673  	for _, test := range textIdTests {
  1674  		if test.marshal {
  1675  			data, err := test.value.MarshalText()
  1676  			if test.error == "" {
  1677  				c.Assert(err, IsNil)
  1678  				c.Assert(string(data), Equals, test.text)
  1679  			} else {
  1680  				c.Assert(err, ErrorMatches, test.error)
  1681  			}
  1682  		}
  1683  
  1684  		if test.unmarshal {
  1685  			err := test.value.UnmarshalText([]byte(test.text))
  1686  			if test.error == "" {
  1687  				c.Assert(err, IsNil)
  1688  				if test.value != "" {
  1689  					value := bson.ObjectIdHex(test.text)
  1690  					c.Assert(value, DeepEquals, test.value)
  1691  				}
  1692  			} else {
  1693  				c.Assert(err, ErrorMatches, test.error)
  1694  			}
  1695  		}
  1696  	}
  1697  }
  1698  
  1699  // --------------------------------------------------------------------------
  1700  // ObjectId XML marshalling.
  1701  
  1702  type xmlType struct {
  1703  	Id bson.ObjectId
  1704  }
  1705  
  1706  var xmlIdTests = []struct {
  1707  	value     xmlType
  1708  	xml       string
  1709  	marshal   bool
  1710  	unmarshal bool
  1711  	error     string
  1712  }{{
  1713  	value:     xmlType{Id: bson.ObjectIdHex("4d88e15b60f486e428412dc9")},
  1714  	xml:       "<xmlType><Id>4d88e15b60f486e428412dc9</Id></xmlType>",
  1715  	marshal:   true,
  1716  	unmarshal: true,
  1717  }, {
  1718  	value:     xmlType{},
  1719  	xml:       "<xmlType><Id></Id></xmlType>",
  1720  	marshal:   true,
  1721  	unmarshal: true,
  1722  }, {
  1723  	xml:       "<xmlType><Id>4d88e15b60f486e428412dc9A</Id></xmlType>",
  1724  	marshal:   false,
  1725  	unmarshal: true,
  1726  	error:     `invalid ObjectId: 4d88e15b60f486e428412dc9A`,
  1727  }, {
  1728  	xml:       "<xmlType><Id>4d88e15b60f486e428412dcZ</Id></xmlType>",
  1729  	marshal:   false,
  1730  	unmarshal: true,
  1731  	error:     `invalid ObjectId: 4d88e15b60f486e428412dcZ .*`,
  1732  }}
  1733  
  1734  func (s *S) TestObjectIdXMLMarshaling(c *C) {
  1735  	for _, test := range xmlIdTests {
  1736  		if test.marshal {
  1737  			data, err := xml.Marshal(&test.value)
  1738  			if test.error == "" {
  1739  				c.Assert(err, IsNil)
  1740  				c.Assert(string(data), Equals, test.xml)
  1741  			} else {
  1742  				c.Assert(err, ErrorMatches, test.error)
  1743  			}
  1744  		}
  1745  
  1746  		if test.unmarshal {
  1747  			var value xmlType
  1748  			err := xml.Unmarshal([]byte(test.xml), &value)
  1749  			if test.error == "" {
  1750  				c.Assert(err, IsNil)
  1751  				c.Assert(value, DeepEquals, test.value)
  1752  			} else {
  1753  				c.Assert(err, ErrorMatches, test.error)
  1754  			}
  1755  		}
  1756  	}
  1757  }
  1758  
  1759  // --------------------------------------------------------------------------
  1760  // Some simple benchmarks.
  1761  
  1762  type BenchT struct {
  1763  	A, B, C, D, E, F string
  1764  }
  1765  
  1766  type BenchRawT struct {
  1767  	A string
  1768  	B int
  1769  	C bson.M
  1770  	D []float64
  1771  }
  1772  
  1773  func (s *S) BenchmarkUnmarhsalStruct(c *C) {
  1774  	v := BenchT{A: "A", D: "D", E: "E"}
  1775  	data, err := bson.Marshal(&v)
  1776  	if err != nil {
  1777  		panic(err)
  1778  	}
  1779  	c.ResetTimer()
  1780  	for i := 0; i < c.N; i++ {
  1781  		err = bson.Unmarshal(data, &v)
  1782  	}
  1783  	if err != nil {
  1784  		panic(err)
  1785  	}
  1786  }
  1787  
  1788  func (s *S) BenchmarkUnmarhsalMap(c *C) {
  1789  	m := bson.M{"a": "a", "d": "d", "e": "e"}
  1790  	data, err := bson.Marshal(&m)
  1791  	if err != nil {
  1792  		panic(err)
  1793  	}
  1794  	c.ResetTimer()
  1795  	for i := 0; i < c.N; i++ {
  1796  		err = bson.Unmarshal(data, &m)
  1797  	}
  1798  	if err != nil {
  1799  		panic(err)
  1800  	}
  1801  }
  1802  
  1803  func (s *S) BenchmarkUnmarshalRaw(c *C) {
  1804  	var err error
  1805  	m := BenchRawT{
  1806  		A: "test_string",
  1807  		B: 123,
  1808  		C: bson.M{
  1809  			"subdoc_int": 12312,
  1810  			"subdoc_doc": bson.M{"1": 1},
  1811  		},
  1812  		D: []float64{0.0, 1.3333, -99.9997, 3.1415},
  1813  	}
  1814  	data, err := bson.Marshal(&m)
  1815  	if err != nil {
  1816  		panic(err)
  1817  	}
  1818  	raw := bson.Raw{}
  1819  	c.ResetTimer()
  1820  	for i := 0; i < c.N; i++ {
  1821  		err = bson.Unmarshal(data, &raw)
  1822  	}
  1823  	if err != nil {
  1824  		panic(err)
  1825  	}
  1826  }
  1827  
  1828  func (s *S) BenchmarkNewObjectId(c *C) {
  1829  	for i := 0; i < c.N; i++ {
  1830  		bson.NewObjectId()
  1831  	}
  1832  }