marshal_test.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // Copyright (C) MongoDB, Inc. 2017-present.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  6. package bson
  7. import (
  8. "bytes"
  9. "testing"
  10. "github.com/google/go-cmp/cmp"
  11. "github.com/stretchr/testify/require"
  12. "go.mongodb.org/mongo-driver/bson/bsoncodec"
  13. "go.mongodb.org/mongo-driver/bson/primitive"
  14. )
  15. func TestMarshalAppendWithRegistry(t *testing.T) {
  16. for _, tc := range marshalingTestCases {
  17. t.Run(tc.name, func(t *testing.T) {
  18. dst := make([]byte, 0, 1024)
  19. var reg *bsoncodec.Registry
  20. if tc.reg != nil {
  21. reg = tc.reg
  22. } else {
  23. reg = DefaultRegistry
  24. }
  25. got, err := MarshalAppendWithRegistry(reg, dst, tc.val)
  26. noerr(t, err)
  27. if !bytes.Equal(got, tc.want) {
  28. t.Errorf("Bytes are not equal. got %v; want %v", got, tc.want)
  29. t.Errorf("Bytes:\n%v\n%v", got, tc.want)
  30. }
  31. })
  32. }
  33. }
  34. func TestMarshalAppendWithContext(t *testing.T) {
  35. for _, tc := range marshalingTestCases {
  36. t.Run(tc.name, func(t *testing.T) {
  37. dst := make([]byte, 0, 1024)
  38. var reg *bsoncodec.Registry
  39. if tc.reg != nil {
  40. reg = tc.reg
  41. } else {
  42. reg = DefaultRegistry
  43. }
  44. ec := bsoncodec.EncodeContext{Registry: reg}
  45. got, err := MarshalAppendWithContext(ec, dst, tc.val)
  46. noerr(t, err)
  47. if !bytes.Equal(got, tc.want) {
  48. t.Errorf("Bytes are not equal. got %v; want %v", got, tc.want)
  49. t.Errorf("Bytes:\n%v\n%v", got, tc.want)
  50. }
  51. })
  52. }
  53. }
  54. func TestMarshalWithRegistry(t *testing.T) {
  55. for _, tc := range marshalingTestCases {
  56. t.Run(tc.name, func(t *testing.T) {
  57. var reg *bsoncodec.Registry
  58. if tc.reg != nil {
  59. reg = tc.reg
  60. } else {
  61. reg = DefaultRegistry
  62. }
  63. got, err := MarshalWithRegistry(reg, tc.val)
  64. noerr(t, err)
  65. if !bytes.Equal(got, tc.want) {
  66. t.Errorf("Bytes are not equal. got %v; want %v", got, tc.want)
  67. t.Errorf("Bytes:\n%v\n%v", got, tc.want)
  68. }
  69. })
  70. }
  71. }
  72. func TestMarshalWithContext(t *testing.T) {
  73. for _, tc := range marshalingTestCases {
  74. t.Run(tc.name, func(t *testing.T) {
  75. var reg *bsoncodec.Registry
  76. if tc.reg != nil {
  77. reg = tc.reg
  78. } else {
  79. reg = DefaultRegistry
  80. }
  81. ec := bsoncodec.EncodeContext{Registry: reg}
  82. got, err := MarshalWithContext(ec, tc.val)
  83. noerr(t, err)
  84. if !bytes.Equal(got, tc.want) {
  85. t.Errorf("Bytes are not equal. got %v; want %v", got, tc.want)
  86. t.Errorf("Bytes:\n%v\n%v", got, tc.want)
  87. }
  88. })
  89. }
  90. }
  91. func TestMarshalAppend(t *testing.T) {
  92. for _, tc := range marshalingTestCases {
  93. t.Run(tc.name, func(t *testing.T) {
  94. if tc.reg != nil {
  95. t.Skip() // test requires custom registry
  96. }
  97. dst := make([]byte, 0, 1024)
  98. got, err := MarshalAppend(dst, tc.val)
  99. noerr(t, err)
  100. if !bytes.Equal(got, tc.want) {
  101. t.Errorf("Bytes are not equal. got %v; want %v", got, tc.want)
  102. t.Errorf("Bytes:\n%v\n%v", got, tc.want)
  103. }
  104. })
  105. }
  106. }
  107. func TestMarshalExtJSONAppendWithContext(t *testing.T) {
  108. t.Run("MarshalExtJSONAppendWithContext", func(t *testing.T) {
  109. dst := make([]byte, 0, 1024)
  110. type teststruct struct{ Foo int }
  111. val := teststruct{1}
  112. ec := bsoncodec.EncodeContext{Registry: DefaultRegistry}
  113. got, err := MarshalExtJSONAppendWithContext(ec, dst, val, true, false)
  114. noerr(t, err)
  115. want := []byte(`{"foo":{"$numberInt":"1"}}`)
  116. if !bytes.Equal(got, want) {
  117. t.Errorf("Bytes are not equal. got %v; want %v", got, want)
  118. t.Errorf("Bytes:\n%s\n%s", got, want)
  119. }
  120. })
  121. }
  122. func TestMarshalExtJSONWithContext(t *testing.T) {
  123. t.Run("MarshalExtJSONWithContext", func(t *testing.T) {
  124. type teststruct struct{ Foo int }
  125. val := teststruct{1}
  126. ec := bsoncodec.EncodeContext{Registry: DefaultRegistry}
  127. got, err := MarshalExtJSONWithContext(ec, val, true, false)
  128. noerr(t, err)
  129. want := []byte(`{"foo":{"$numberInt":"1"}}`)
  130. if !bytes.Equal(got, want) {
  131. t.Errorf("Bytes are not equal. got %v; want %v", got, want)
  132. t.Errorf("Bytes:\n%s\n%s", got, want)
  133. }
  134. })
  135. }
  136. func TestMarshal_roundtripFromBytes(t *testing.T) {
  137. before := []byte{
  138. // length
  139. 0x1c, 0x0, 0x0, 0x0,
  140. // --- begin array ---
  141. // type - document
  142. 0x3,
  143. // key - "foo"
  144. 0x66, 0x6f, 0x6f, 0x0,
  145. // length
  146. 0x12, 0x0, 0x0, 0x0,
  147. // type - string
  148. 0x2,
  149. // key - "bar"
  150. 0x62, 0x61, 0x72, 0x0,
  151. // value - string length
  152. 0x4, 0x0, 0x0, 0x0,
  153. // value - "baz"
  154. 0x62, 0x61, 0x7a, 0x0,
  155. // null terminator
  156. 0x0,
  157. // --- end array ---
  158. // null terminator
  159. 0x0,
  160. }
  161. var doc D
  162. require.NoError(t, Unmarshal(before, &doc))
  163. after, err := Marshal(doc)
  164. require.NoError(t, err)
  165. require.True(t, bytes.Equal(before, after))
  166. }
  167. func TestMarshal_roundtripFromDoc(t *testing.T) {
  168. before := D{
  169. {"foo", "bar"},
  170. {"baz", int64(-27)},
  171. {"bing", A{nil, primitive.Regex{Pattern: "word", Options: "i"}}},
  172. }
  173. b, err := Marshal(before)
  174. require.NoError(t, err)
  175. var after D
  176. require.NoError(t, Unmarshal(b, &after))
  177. if !cmp.Equal(after, before) {
  178. t.Errorf("Documents to not match. got %v; want %v", after, before)
  179. }
  180. }