github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/marshal/encode_test.go (about)

     1  // Copyright 2019 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // This file incorporates work covered by the following copyright and
    16  // permission notice:
    17  //
    18  // Copyright 2016 Attic Labs, Inc. All rights reserved.
    19  // Licensed under the Apache License, version 2.0:
    20  // http://www.apache.org/licenses/LICENSE-2.0
    21  
    22  package marshal
    23  
    24  import (
    25  	"bytes"
    26  	"context"
    27  	"errors"
    28  	"fmt"
    29  	"math"
    30  	"regexp"
    31  	"strings"
    32  	"testing"
    33  
    34  	"github.com/stretchr/testify/assert"
    35  	"github.com/stretchr/testify/require"
    36  
    37  	"github.com/dolthub/dolt/go/store/types"
    38  )
    39  
    40  func TestEncode(tt *testing.T) {
    41  	vs := newTestValueStore()
    42  	defer vs.Close()
    43  
    44  	t := func(exp types.Value, v interface{}) {
    45  		actual, err := Marshal(context.Background(), vs, v)
    46  		assert.NoError(tt, err)
    47  		assert.True(tt, exp.Equals(actual))
    48  
    49  		// Encode again for fallthrough
    50  		actual2, err := Marshal(context.Background(), vs, actual)
    51  		assert.NoError(tt, err)
    52  		assert.True(tt, exp.Equals(actual2))
    53  	}
    54  
    55  	for _, n := range []float32{0, 42, 3.14159265359, math.MaxFloat32} {
    56  		t(types.Float(n), n)
    57  		t(types.Float(-n), -n)
    58  	}
    59  
    60  	for _, n := range []float64{0, 42, 3.14159265359, 9007199254740991, math.MaxFloat64} {
    61  		t(types.Float(n), n)
    62  		t(types.Float(-n), -n)
    63  	}
    64  
    65  	for _, n := range []int8{0, 42, math.MaxInt8} {
    66  		t(types.Float(n), n)
    67  		t(types.Float(-n), -n)
    68  	}
    69  
    70  	for _, n := range []int16{0, 42, math.MaxInt16} {
    71  		t(types.Float(n), n)
    72  		t(types.Float(-n), -n)
    73  	}
    74  
    75  	for _, n := range []int32{0, 42, math.MaxInt32} {
    76  		t(types.Float(n), n)
    77  		t(types.Float(-n), -n)
    78  	}
    79  
    80  	// int is at least int32
    81  	for _, n := range []int{0, 42, math.MaxInt32} {
    82  		t(types.Float(n), n)
    83  		t(types.Float(-n), -n)
    84  	}
    85  
    86  	for _, n := range []int64{0, 42, math.MaxInt64} {
    87  		t(types.Float(n), n)
    88  		t(types.Float(-n), -n)
    89  	}
    90  
    91  	for _, n := range []uint8{0, 42, math.MaxUint8} {
    92  		t(types.Float(n), n)
    93  	}
    94  
    95  	for _, n := range []uint16{0, 42, math.MaxUint16} {
    96  		t(types.Float(n), n)
    97  	}
    98  
    99  	for _, n := range []uint32{0, 42, math.MaxUint32} {
   100  		t(types.Float(n), n)
   101  	}
   102  
   103  	// uint is at least uint32
   104  	for _, n := range []uint{0, 42, math.MaxUint32} {
   105  		t(types.Float(n), n)
   106  	}
   107  
   108  	for _, n := range []uint64{0, 42, math.MaxUint64} {
   109  		t(types.Float(n), n)
   110  	}
   111  
   112  	t(types.Bool(true), true)
   113  	t(types.Bool(false), false)
   114  
   115  	for _, s := range []string{"", "s", "hello", "💩"} {
   116  		t(types.String(s), s)
   117  	}
   118  
   119  	t(mustValue(types.NewList(context.Background(), vs, types.Float(42))), mustValue(types.NewList(context.Background(), vs, types.Float(42))))
   120  	t(mustValue(types.NewMap(context.Background(), vs, types.Float(42), types.String("hi"))), mustValue(types.NewMap(context.Background(), vs, types.Float(42), types.String("hi"))))
   121  	t(mustValue(types.NewSet(context.Background(), vs, types.String("bye"))), mustValue(types.NewSet(context.Background(), vs, types.String("bye"))))
   122  	t(mustValue(types.NewBlob(context.Background(), vs, bytes.NewBufferString("hello"))), mustValue(types.NewBlob(context.Background(), vs, bytes.NewBufferString("hello"))))
   123  
   124  	type TestStruct struct {
   125  		Str string
   126  		Num float64
   127  	}
   128  	t(mustValue(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{
   129  		"num": types.Float(42),
   130  		"str": types.String("Hello"),
   131  	})), TestStruct{Str: "Hello", Num: 42})
   132  	// Same again to test caching
   133  	t(mustValue(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{
   134  		"num": types.Float(1),
   135  		"str": types.String("Bye"),
   136  	})), TestStruct{Str: "Bye", Num: 1})
   137  
   138  	anonStruct := struct {
   139  		B bool
   140  	}{
   141  		true,
   142  	}
   143  	t(mustValue(types.NewStruct(types.Format_7_18, "", types.StructData{
   144  		"b": types.Bool(true),
   145  	})), anonStruct)
   146  
   147  	type TestNestedStruct struct {
   148  		A types.List
   149  		B TestStruct
   150  		C float64
   151  	}
   152  	t(mustValue(types.NewStruct(types.Format_7_18, "TestNestedStruct", types.StructData{
   153  		"a": mustValue(types.NewList(context.Background(), vs, types.String("hi"))),
   154  		"b": mustValue(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{
   155  			"str": types.String("bye"),
   156  			"num": types.Float(5678),
   157  		})),
   158  		"c": types.Float(1234),
   159  	})), TestNestedStruct{
   160  		A: mustList(types.NewList(context.Background(), vs, types.String("hi"))),
   161  		B: TestStruct{
   162  			Str: "bye",
   163  			Num: 5678,
   164  		},
   165  		C: 1234,
   166  	})
   167  
   168  	type testStruct struct {
   169  		Str string
   170  		Num float64
   171  	}
   172  	t(mustValue(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{
   173  		"num": types.Float(42),
   174  		"str": types.String("Hello"),
   175  	})), testStruct{Str: "Hello", Num: 42})
   176  }
   177  
   178  func assertEncodeErrorMessage(t *testing.T, v interface{}, expectedMessage string) {
   179  	vs := newTestValueStore()
   180  	defer vs.Close()
   181  
   182  	_, err := Marshal(context.Background(), vs, v)
   183  	assert.Error(t, err)
   184  	assert.Equal(t, expectedMessage, err.Error())
   185  }
   186  
   187  func TestInvalidTypes(t *testing.T) {
   188  	assertEncodeErrorMessage(t, make(chan int), "Type is not supported, type: chan int")
   189  	x := 42
   190  	assertEncodeErrorMessage(t, &x, "Type is not supported, type: *int")
   191  }
   192  
   193  func TestEncodeEmbeddedStructSkip(t *testing.T) {
   194  	assert := assert.New(t)
   195  
   196  	vs := newTestValueStore()
   197  	defer vs.Close()
   198  
   199  	type EmbeddedStruct struct {
   200  		X int
   201  	}
   202  	type TestStruct struct {
   203  		EmbeddedStruct `noms:"-"`
   204  		Y              int
   205  	}
   206  	s := TestStruct{EmbeddedStruct{1}, 2}
   207  	v, err := Marshal(context.Background(), vs, s)
   208  	require.NoError(t, err)
   209  	assert.True(mustValue(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{
   210  		"y": types.Float(2),
   211  	})).Equals(v))
   212  }
   213  
   214  func TestEncodeEmbeddedStructWithName(t *testing.T) {
   215  	assert := assert.New(t)
   216  
   217  	vs := newTestValueStore()
   218  	defer vs.Close()
   219  
   220  	type EmbeddedStruct struct {
   221  		X int
   222  	}
   223  	type TestStruct struct {
   224  		EmbeddedStruct `noms:"em"`
   225  		Y              int
   226  	}
   227  	s := TestStruct{EmbeddedStruct{1}, 2}
   228  	v, err := Marshal(context.Background(), vs, s)
   229  	require.NoError(t, err)
   230  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{
   231  		"em": mustStruct(types.NewStruct(types.Format_7_18, "EmbeddedStruct", types.StructData{
   232  			"x": types.Float(1),
   233  		})),
   234  		"y": types.Float(2),
   235  	})).Equals(v))
   236  }
   237  
   238  func TestEncodeEmbeddedStruct(t *testing.T) {
   239  	assert := assert.New(t)
   240  
   241  	vs := newTestValueStore()
   242  	defer vs.Close()
   243  
   244  	type EmbeddedStruct struct {
   245  		X int
   246  	}
   247  	type TestStruct struct {
   248  		EmbeddedStruct
   249  	}
   250  	s := TestStruct{EmbeddedStruct{1}}
   251  	v, err := Marshal(context.Background(), vs, s)
   252  	require.NoError(t, err)
   253  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{
   254  		"x": types.Float(1),
   255  	})).Equals(v))
   256  
   257  	type TestOuter struct {
   258  		A int
   259  		TestStruct
   260  		B int
   261  	}
   262  	s2 := TestOuter{0, TestStruct{EmbeddedStruct{1}}, 2}
   263  	v2, err := Marshal(context.Background(), vs, s2)
   264  	require.NoError(t, err)
   265  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "TestOuter", types.StructData{
   266  		"a": types.Float(0),
   267  		"b": types.Float(2),
   268  		"x": types.Float(1),
   269  	})).Equals(v2))
   270  }
   271  
   272  func TestEncodeEmbeddedStructOriginal(t *testing.T) {
   273  	assert := assert.New(t)
   274  
   275  	vs := newTestValueStore()
   276  	defer vs.Close()
   277  
   278  	type EmbeddedStruct struct {
   279  		X int
   280  		O types.Struct `noms:",original"`
   281  		B bool
   282  	}
   283  	type TestStruct struct {
   284  		EmbeddedStruct
   285  	}
   286  	s := TestStruct{
   287  		EmbeddedStruct: EmbeddedStruct{
   288  			X: 1,
   289  			B: true,
   290  		},
   291  	}
   292  	v, err := Marshal(context.Background(), vs, s)
   293  	require.NoError(t, err)
   294  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "TestStruct", types.StructData{
   295  		"b": types.Bool(true),
   296  		"x": types.Float(1),
   297  	})).Equals(v))
   298  }
   299  
   300  func TestEncodeNonExportedField(t *testing.T) {
   301  	type TestStruct struct {
   302  		x int
   303  	}
   304  	assertEncodeErrorMessage(t, TestStruct{1}, "Non exported fields are not supported, type: marshal.TestStruct")
   305  }
   306  
   307  func TestEncodeTaggingSkip(t *testing.T) {
   308  	assert := assert.New(t)
   309  
   310  	vs := newTestValueStore()
   311  	defer vs.Close()
   312  
   313  	type S struct {
   314  		Abc int `noms:"-"`
   315  		Def bool
   316  	}
   317  	s := S{42, true}
   318  	v, err := Marshal(context.Background(), vs, s)
   319  	require.NoError(t, err)
   320  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{
   321  		"def": types.Bool(true),
   322  	})).Equals(v))
   323  }
   324  
   325  func TestEncodeNamedFields(t *testing.T) {
   326  	assert := assert.New(t)
   327  
   328  	vs := newTestValueStore()
   329  	defer vs.Close()
   330  
   331  	type S struct {
   332  		Aaa int  `noms:"a"`
   333  		Bbb bool `noms:"B"`
   334  		Ccc string
   335  	}
   336  	s := S{42, true, "Hi"}
   337  	v, err := Marshal(context.Background(), vs, s)
   338  	require.NoError(t, err)
   339  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{
   340  		"a":   types.Float(42),
   341  		"B":   types.Bool(true),
   342  		"ccc": types.String("Hi"),
   343  	})).Equals(v))
   344  }
   345  
   346  func TestEncodeInvalidNamedFields(t *testing.T) {
   347  	type S struct {
   348  		A int `noms:"1a"`
   349  	}
   350  	assertEncodeErrorMessage(t, S{42}, "Invalid struct field name: 1a")
   351  }
   352  
   353  func TestEncodeOmitEmpty(t *testing.T) {
   354  	assert := assert.New(t)
   355  
   356  	vs := newTestValueStore()
   357  	defer vs.Close()
   358  
   359  	type S struct {
   360  		String  string  `noms:",omitempty"`
   361  		Bool    bool    `noms:",omitempty"`
   362  		Int     int     `noms:",omitempty"`
   363  		Int8    int8    `noms:",omitempty"`
   364  		Int16   int16   `noms:",omitempty"`
   365  		Int32   int32   `noms:",omitempty"`
   366  		Int64   int64   `noms:",omitempty"`
   367  		Uint    uint    `noms:",omitempty"`
   368  		Uint8   uint8   `noms:",omitempty"`
   369  		Uint16  uint16  `noms:",omitempty"`
   370  		Uint32  uint32  `noms:",omitempty"`
   371  		Uint64  uint64  `noms:",omitempty"`
   372  		Float32 float32 `noms:",omitempty"`
   373  		Float64 float64 `noms:",omitempty"`
   374  	}
   375  	s := S{
   376  		String:  "s",
   377  		Bool:    true,
   378  		Int:     1,
   379  		Int8:    1,
   380  		Int16:   1,
   381  		Int32:   1,
   382  		Int64:   1,
   383  		Uint:    1,
   384  		Uint8:   1,
   385  		Uint16:  1,
   386  		Uint32:  1,
   387  		Uint64:  1,
   388  		Float32: 1,
   389  		Float64: 1,
   390  	}
   391  	v, err := Marshal(context.Background(), vs, s)
   392  	require.NoError(t, err)
   393  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{
   394  		"string":  types.String("s"),
   395  		"bool":    types.Bool(true),
   396  		"int":     types.Float(1),
   397  		"int8":    types.Float(1),
   398  		"int16":   types.Float(1),
   399  		"int32":   types.Float(1),
   400  		"int64":   types.Float(1),
   401  		"uint":    types.Float(1),
   402  		"uint8":   types.Float(1),
   403  		"uint16":  types.Float(1),
   404  		"uint32":  types.Float(1),
   405  		"uint64":  types.Float(1),
   406  		"float32": types.Float(1),
   407  		"float64": types.Float(1),
   408  	})).Equals(v))
   409  
   410  	s2 := S{
   411  		String:  "",
   412  		Bool:    false,
   413  		Int:     0,
   414  		Int8:    0,
   415  		Int16:   0,
   416  		Int32:   0,
   417  		Int64:   0,
   418  		Uint:    0,
   419  		Uint8:   0,
   420  		Uint16:  0,
   421  		Uint32:  0,
   422  		Uint64:  0,
   423  		Float32: 0,
   424  		Float64: 0,
   425  	}
   426  	v2, err := Marshal(context.Background(), vs, s2)
   427  	require.NoError(t, err)
   428  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{})).Equals(v2))
   429  
   430  	type S2 struct {
   431  		Slice []int       `noms:",omitempty"`
   432  		Map   map[int]int `noms:",omitempty"`
   433  	}
   434  
   435  	s3 := S2{
   436  		Slice: []int{0},
   437  		Map:   map[int]int{0: 0},
   438  	}
   439  	v3, err := Marshal(context.Background(), vs, s3)
   440  	require.NoError(t, err)
   441  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S2", types.StructData{
   442  		"slice": mustList(types.NewList(context.Background(), vs, types.Float(0))),
   443  		"map":   mustValue(types.NewMap(context.Background(), vs, types.Float(0), types.Float(0))),
   444  	})).Equals(v3))
   445  
   446  	s4 := S2{
   447  		Slice: []int{},
   448  		Map:   map[int]int{},
   449  	}
   450  	v4, err := Marshal(context.Background(), vs, s4)
   451  	require.NoError(t, err)
   452  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S2", types.StructData{})).Equals(v4))
   453  
   454  	s5 := S2{
   455  		Slice: nil,
   456  		Map:   nil,
   457  	}
   458  	v5, err := Marshal(context.Background(), vs, s5)
   459  	require.NoError(t, err)
   460  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S2", types.StructData{})).Equals(v5))
   461  
   462  	type S3 struct {
   463  		List  types.List  `noms:",omitempty"`
   464  		Value types.Value `noms:",omitempty"`
   465  	}
   466  	s6 := S3{
   467  		List:  mustList(types.NewList(context.Background(), vs)),
   468  		Value: types.Float(0),
   469  	}
   470  	v6, err := Marshal(context.Background(), vs, s6)
   471  	require.NoError(t, err)
   472  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S3", types.StructData{
   473  		"list":  mustList(types.NewList(context.Background(), vs)),
   474  		"value": types.Float(0),
   475  	})).Equals(v6))
   476  
   477  	s7 := S3{
   478  		List:  types.List{},
   479  		Value: nil,
   480  	}
   481  	v7, err := Marshal(context.Background(), vs, s7)
   482  	require.NoError(t, err)
   483  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S3", types.StructData{})).Equals(v7))
   484  
   485  	// Both name and omitempty
   486  	type S4 struct {
   487  		X int `noms:"y,omitempty"`
   488  	}
   489  	s8 := S4{
   490  		X: 1,
   491  	}
   492  	v8, err := Marshal(context.Background(), vs, s8)
   493  	require.NoError(t, err)
   494  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S4", types.StructData{
   495  		"y": types.Float(1),
   496  	})).Equals(v8))
   497  
   498  	s9 := S4{
   499  		X: 0,
   500  	}
   501  	v9, err := Marshal(context.Background(), vs, s9)
   502  	require.NoError(t, err)
   503  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S4", types.StructData{})).Equals(v9))
   504  }
   505  
   506  func ExampleMarshal() {
   507  	vs := newTestValueStore()
   508  	defer vs.Close()
   509  
   510  	type Person struct {
   511  		Given string
   512  		Male  bool
   513  	}
   514  	arya, err := Marshal(context.Background(), vs, Person{"Arya", false})
   515  	if err != nil {
   516  		fmt.Println(err)
   517  		return
   518  	}
   519  
   520  	fmt.Printf("Given: %s, Male: %t\n", mustGetValue(arya.(types.Struct).MaybeGet("given")).(types.String), mustGetValue(arya.(types.Struct).MaybeGet("male")).(types.Bool))
   521  	// Output: Given: Arya, Male: false
   522  }
   523  
   524  func TestEncodeSlice(t *testing.T) {
   525  	assert := assert.New(t)
   526  
   527  	vs := newTestValueStore()
   528  	defer vs.Close()
   529  
   530  	v, err := Marshal(context.Background(), vs, []string{"a", "b", "c"})
   531  	require.NoError(t, err)
   532  	assert.True(mustList(types.NewList(context.Background(), vs, types.String("a"), types.String("b"), types.String("c"))).Equals(v))
   533  }
   534  
   535  func TestEncodeArray(t *testing.T) {
   536  	assert := assert.New(t)
   537  
   538  	vs := newTestValueStore()
   539  	defer vs.Close()
   540  
   541  	v, err := Marshal(context.Background(), vs, [3]int{1, 2, 3})
   542  	require.NoError(t, err)
   543  	assert.True(mustList(types.NewList(context.Background(), vs, types.Float(1), types.Float(2), types.Float(3))).Equals(v))
   544  }
   545  
   546  func TestEncodeStructWithSlice(t *testing.T) {
   547  	assert := assert.New(t)
   548  
   549  	vs := newTestValueStore()
   550  	defer vs.Close()
   551  
   552  	type S struct {
   553  		List []int
   554  	}
   555  	v, err := Marshal(context.Background(), vs, S{[]int{1, 2, 3}})
   556  	require.NoError(t, err)
   557  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{
   558  		"list": mustList(types.NewList(context.Background(), vs, types.Float(1), types.Float(2), types.Float(3))),
   559  	})).Equals(v))
   560  }
   561  
   562  func TestEncodeStructWithArrayOfNomsValue(t *testing.T) {
   563  	assert := assert.New(t)
   564  
   565  	vs := newTestValueStore()
   566  	defer vs.Close()
   567  
   568  	type S struct {
   569  		List [1]types.Set
   570  	}
   571  	v, err := Marshal(context.Background(), vs, S{[1]types.Set{mustSet(types.NewSet(context.Background(), vs, types.Bool(true)))}})
   572  	require.NoError(t, err)
   573  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{
   574  		"list": mustList(types.NewList(context.Background(), vs, mustSet(types.NewSet(context.Background(), vs, types.Bool(true))))),
   575  	})).Equals(v))
   576  }
   577  
   578  func TestEncodeNomsTypePtr(t *testing.T) {
   579  	assert := assert.New(t)
   580  
   581  	vs := newTestValueStore()
   582  	defer vs.Close()
   583  
   584  	testMarshal := func(g interface{}, expected types.Value) {
   585  		v, err := Marshal(context.Background(), vs, g)
   586  		require.NoError(t, err)
   587  		assert.Equal(expected, v)
   588  	}
   589  
   590  	type S struct {
   591  		Type *types.Type
   592  	}
   593  
   594  	primitive := types.PrimitiveTypeMap[types.StringKind]
   595  	testMarshal(S{primitive}, mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{"type": primitive})))
   596  
   597  	complex := mustType(types.MakeStructType("Complex",
   598  		types.StructField{
   599  			Name: "stuff",
   600  			Type: types.PrimitiveTypeMap[types.StringKind],
   601  		},
   602  	))
   603  	testMarshal(S{complex}, mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{"type": complex})))
   604  }
   605  
   606  func TestEncodeRecursive(t *testing.T) {
   607  	assert := assert.New(t)
   608  
   609  	vs := newTestValueStore()
   610  	defer vs.Close()
   611  
   612  	type Node struct {
   613  		Value    int
   614  		Children []Node
   615  	}
   616  	v, err := Marshal(context.Background(), vs, Node{
   617  		1, []Node{
   618  			{2, []Node{}},
   619  			{3, []Node(nil)},
   620  		},
   621  	})
   622  	require.NoError(t, err)
   623  
   624  	typ, err := types.MakeStructType("Node",
   625  		types.StructField{
   626  			Name: "children",
   627  			Type: mustType(types.MakeListType(types.MakeCycleType("Node"))),
   628  		},
   629  		types.StructField{
   630  			Name: "value",
   631  			Type: types.PrimitiveTypeMap[types.FloatKind],
   632  		},
   633  	)
   634  	require.NoError(t, err)
   635  	tp, err := types.TypeOf(v)
   636  	require.NoError(t, err)
   637  	assert.True(typ.Equals(tp))
   638  
   639  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "Node", types.StructData{
   640  		"children": mustValue(types.NewList(context.Background(),
   641  			vs,
   642  			mustStruct(types.NewStruct(types.Format_7_18, "Node", types.StructData{
   643  				"children": mustValue(types.NewList(context.Background(), vs)),
   644  				"value":    types.Float(2),
   645  			})),
   646  			mustStruct(types.NewStruct(types.Format_7_18, "Node", types.StructData{
   647  				"children": mustValue(types.NewList(context.Background(), vs)),
   648  				"value":    types.Float(3),
   649  			})),
   650  		)),
   651  		"value": types.Float(1),
   652  	})).Equals(v))
   653  }
   654  
   655  func TestEncodeMap(t *testing.T) {
   656  	assert := assert.New(t)
   657  
   658  	vs := newTestValueStore()
   659  	defer vs.Close()
   660  
   661  	v, err := Marshal(context.Background(), vs, map[string]int{"a": 1, "b": 2, "c": 3})
   662  	require.NoError(t, err)
   663  	assert.True(mustValue(types.NewMap(context.Background(),
   664  		vs,
   665  		types.String("a"), types.Float(1),
   666  		types.String("b"), types.Float(2),
   667  		types.String("c"), types.Float(3))).Equals(v))
   668  
   669  	type S struct {
   670  		N string
   671  	}
   672  	v, err = Marshal(context.Background(), vs, map[S]bool{S{"Yes"}: true, S{"No"}: false})
   673  	require.NoError(t, err)
   674  	assert.True(mustValue(types.NewMap(context.Background(),
   675  		vs,
   676  		mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{"n": types.String("Yes")})), types.Bool(true),
   677  		mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{"n": types.String("No")})), types.Bool(false))).Equals(v))
   678  
   679  	v, err = Marshal(context.Background(), vs, map[string]int(nil))
   680  	require.NoError(t, err)
   681  	assert.True(mustValue(types.NewMap(context.Background(), vs)).Equals(v))
   682  
   683  	v, err = Marshal(context.Background(), vs, map[string]int{})
   684  	require.NoError(t, err)
   685  	assert.True(mustValue(types.NewMap(context.Background(), vs)).Equals(v))
   686  }
   687  
   688  func TestEncodeInterface(t *testing.T) {
   689  	assert := assert.New(t)
   690  
   691  	vs := newTestValueStore()
   692  	defer vs.Close()
   693  
   694  	var i interface{} = []string{"a", "b"}
   695  	v, err := Marshal(context.Background(), vs, i)
   696  	require.NoError(t, err)
   697  	assert.True(mustValue(types.NewList(context.Background(), vs, types.String("a"), types.String("b"))).Equals(v))
   698  
   699  	i = map[interface{}]interface{}{"a": true, struct{ Name string }{"b"}: 42}
   700  	v, err = Marshal(context.Background(), vs, i)
   701  	require.NoError(t, err)
   702  	assert.True(mustValue(types.NewMap(context.Background(),
   703  		vs,
   704  		types.String("a"), types.Bool(true),
   705  		mustStruct(types.NewStruct(types.Format_7_18, "", types.StructData{"name": types.String("b")})), types.Float(42),
   706  	)).Equals(v))
   707  }
   708  
   709  func TestEncodeSet(t *testing.T) {
   710  	assert := assert.New(t)
   711  
   712  	vs := newTestValueStore()
   713  	defer vs.Close()
   714  
   715  	v, err := Marshal(context.Background(), vs, struct {
   716  		A map[int]struct{} `noms:",set"`
   717  		B map[int]struct{}
   718  		C map[int]string      `noms:",set"`
   719  		D map[string]struct{} `noms:",set"`
   720  		E map[string]struct{}
   721  		F map[string]int `noms:",set"`
   722  		G []int          `noms:",set"`
   723  		H string         `noms:",set"`
   724  	}{
   725  		map[int]struct{}{0: {}, 1: {}, 2: {}},
   726  		map[int]struct{}{3: {}, 4: {}, 5: {}},
   727  		map[int]string{},
   728  		map[string]struct{}{"A": {}, "B": {}, "C": {}},
   729  		map[string]struct{}{"D": {}, "E": {}, "F": {}},
   730  		map[string]int{},
   731  		[]int{1, 2, 3},
   732  		"",
   733  	})
   734  	require.NoError(t, err)
   735  	s, ok := v.(types.Struct)
   736  	assert.True(ok)
   737  
   738  	expect := map[string]types.NomsKind{
   739  		"a": types.SetKind,
   740  		"b": types.MapKind,
   741  		"c": types.MapKind,
   742  		"d": types.SetKind,
   743  		"e": types.MapKind,
   744  		"f": types.MapKind,
   745  		"g": types.SetKind,
   746  		"h": types.StringKind,
   747  	}
   748  	for fieldName, kind := range expect {
   749  		assert.Equal(kind, mustGetValue(s.MaybeGet(fieldName)).Kind())
   750  	}
   751  
   752  	// Test both the Set values are correct, and that the equivalent typed Map
   753  	// are correct in case the Set marshaling interferes with it.
   754  
   755  	val, ok, err := s.MaybeGet("a")
   756  	require.NoError(t, err)
   757  	assert.True(ok)
   758  	a := val.(types.Set)
   759  	assert.True(a.Has(context.Background(), types.Float(0)))
   760  	assert.True(a.Has(context.Background(), types.Float(1)))
   761  	assert.True(a.Has(context.Background(), types.Float(2)))
   762  
   763  	val, ok, err = s.MaybeGet("b")
   764  	require.NoError(t, err)
   765  	assert.True(ok)
   766  	b := val.(types.Map)
   767  	assert.True(b.Has(context.Background(), types.Float(3)))
   768  	assert.True(b.Has(context.Background(), types.Float(4)))
   769  	assert.True(b.Has(context.Background(), types.Float(5)))
   770  
   771  	val, ok, err = s.MaybeGet("d")
   772  	require.NoError(t, err)
   773  	assert.True(ok)
   774  	d := val.(types.Set)
   775  	assert.True(d.Has(context.Background(), types.String("A")))
   776  	assert.True(d.Has(context.Background(), types.String("B")))
   777  	assert.True(d.Has(context.Background(), types.String("C")))
   778  
   779  	val, ok, err = s.MaybeGet("e")
   780  	require.NoError(t, err)
   781  	assert.True(ok)
   782  	e := val.(types.Map)
   783  	assert.True(e.Has(context.Background(), types.String("D")))
   784  	assert.True(e.Has(context.Background(), types.String("E")))
   785  	assert.True(e.Has(context.Background(), types.String("F")))
   786  
   787  	val, ok, err = s.MaybeGet("g")
   788  	require.NoError(t, err)
   789  	assert.True(ok)
   790  	g := val.(types.Set)
   791  	assert.True(g.Has(context.Background(), types.Float(1)))
   792  	assert.True(g.Has(context.Background(), types.Float(2)))
   793  	assert.True(g.Has(context.Background(), types.Float(3)))
   794  }
   795  
   796  func TestEncodeOpt(t *testing.T) {
   797  	assert := assert.New(t)
   798  
   799  	vs := newTestValueStore()
   800  	defer vs.Close()
   801  
   802  	tc := []struct {
   803  		in        interface{}
   804  		opt       Opt
   805  		wantValue types.Value
   806  	}{
   807  		{
   808  			[]string{"a", "b"},
   809  			Opt{},
   810  			mustValue(types.NewList(context.Background(), vs, types.String("a"), types.String("b"))),
   811  		},
   812  		{
   813  			[]string{"a", "b"},
   814  			Opt{Set: true},
   815  			mustValue(types.NewSet(context.Background(), vs, types.String("a"), types.String("b"))),
   816  		},
   817  		{
   818  			map[string]struct{}{"a": {}, "b": {}},
   819  			Opt{},
   820  			mustValue(types.NewMap(context.Background(), vs,
   821  				types.String("a"), mustStruct(types.NewStruct(types.Format_7_18, "", nil)),
   822  				types.String("b"), mustStruct(types.NewStruct(types.Format_7_18, "", nil)),
   823  			)),
   824  		},
   825  		{
   826  			map[string]struct{}{"a": {}, "b": {}},
   827  			Opt{Set: true},
   828  			mustSet(types.NewSet(context.Background(), vs, types.String("a"), types.String("b"))),
   829  		},
   830  	}
   831  
   832  	for _, t := range tc {
   833  		r, err := MarshalOpt(context.Background(), vs, t.in, t.opt)
   834  		assert.True(t.wantValue.Equals(r))
   835  		assert.Nil(err)
   836  	}
   837  }
   838  
   839  func TestEncodeSetWithTags(t *testing.T) {
   840  	assert := assert.New(t)
   841  
   842  	vs := newTestValueStore()
   843  	defer vs.Close()
   844  
   845  	v, err := Marshal(context.Background(), vs, struct {
   846  		A map[int]struct{} `noms:"foo,set"`
   847  		B map[int]struct{} `noms:",omitempty,set"`
   848  		C map[int]struct{} `noms:"bar,omitempty,set"`
   849  	}{
   850  		A: map[int]struct{}{0: {}, 1: {}},
   851  		C: map[int]struct{}{2: {}, 3: {}},
   852  	})
   853  	require.NoError(t, err)
   854  	s, ok := v.(types.Struct)
   855  	assert.True(ok)
   856  
   857  	_, ok, err = s.MaybeGet("a")
   858  	require.NoError(t, err)
   859  	assert.False(ok)
   860  	_, ok, err = s.MaybeGet("b")
   861  	require.NoError(t, err)
   862  	assert.False(ok)
   863  	_, ok, err = s.MaybeGet("c")
   864  	require.NoError(t, err)
   865  	assert.False(ok)
   866  
   867  	val, ok, err := s.MaybeGet("foo")
   868  	require.NoError(t, err)
   869  	foo := val.(types.Set)
   870  	require.NoError(t, err)
   871  	assert.True(ok)
   872  	assert.True(mustSet(types.NewSet(context.Background(), vs, types.Float(0), types.Float(1))).Equals(foo))
   873  
   874  	val, ok, err = s.MaybeGet("bar")
   875  	require.NoError(t, err)
   876  	bar := val.(types.Set)
   877  	require.NoError(t, err)
   878  	assert.True(ok)
   879  	assert.True(mustSet(types.NewSet(context.Background(), vs, types.Float(2), types.Float(3))).Equals(bar))
   880  }
   881  
   882  func TestInvalidTag(t *testing.T) {
   883  	vs := newTestValueStore()
   884  	defer vs.Close()
   885  
   886  	_, err := Marshal(context.Background(), vs, struct {
   887  		F string `noms:",omitEmpty"`
   888  	}{"F"})
   889  	assert.Error(t, err)
   890  	assert.Equal(t, `Unrecognized tag: omitEmpty`, err.Error())
   891  }
   892  
   893  func TestEncodeCanSkipUnexportedField(t *testing.T) {
   894  	assert := assert.New(t)
   895  
   896  	vs := newTestValueStore()
   897  	defer vs.Close()
   898  
   899  	type S struct {
   900  		Abc         int
   901  		notExported bool `noms:"-"`
   902  	}
   903  	s := S{42, true}
   904  	v, err := Marshal(context.Background(), vs, s)
   905  	require.NoError(t, err)
   906  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{
   907  		"abc": types.Float(42),
   908  	})).Equals(v))
   909  }
   910  
   911  func TestEncodeOriginal(t *testing.T) {
   912  	assert := assert.New(t)
   913  
   914  	vs := newTestValueStore()
   915  	defer vs.Close()
   916  
   917  	type S struct {
   918  		Foo int          `noms:",omitempty"`
   919  		Bar types.Struct `noms:",original"`
   920  	}
   921  
   922  	var s S
   923  	var err error
   924  
   925  	// New field value clobbers old field value
   926  	orig := mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{
   927  		"foo": types.Float(42),
   928  	}))
   929  	err = Unmarshal(context.Background(), types.Format_7_18, orig, &s)
   930  	require.NoError(t, err)
   931  	s.Foo = 43
   932  	assert.True(mustValue(Marshal(context.Background(), vs, s)).Equals(mustStruct(orig.Set("foo", types.Float(43)))))
   933  
   934  	// New field extends old struct
   935  	orig, err = types.NewStruct(types.Format_7_18, "S", types.StructData{})
   936  	require.NoError(t, err)
   937  	err = Unmarshal(context.Background(), types.Format_7_18, orig, &s)
   938  	require.NoError(t, err)
   939  	s.Foo = 43
   940  	assert.True(mustValue(Marshal(context.Background(), vs, s)).Equals(mustStruct(orig.Set("foo", types.Float(43)))))
   941  
   942  	// Old struct name always used
   943  	orig = mustStruct(types.NewStruct(types.Format_7_18, "Q", types.StructData{}))
   944  	err = Unmarshal(context.Background(), types.Format_7_18, orig, &s)
   945  	require.NoError(t, err)
   946  	s.Foo = 43
   947  	assert.True(mustValue(Marshal(context.Background(), vs, s)).Equals(mustStruct(orig.Set("foo", types.Float(43)))))
   948  
   949  	// Field type of base are preserved
   950  	orig = mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{
   951  		"foo": types.Float(42),
   952  	}))
   953  	err = Unmarshal(context.Background(), types.Format_7_18, orig, &s)
   954  	require.NoError(t, err)
   955  	s.Foo = 43
   956  	out, err := Marshal(context.Background(), vs, s)
   957  	require.NoError(t, err)
   958  	assert.True(out.Equals(mustStruct(orig.Set("foo", types.Float(43)))))
   959  
   960  	st2 := mustType(types.MakeStructTypeFromFields("S", types.FieldMap{
   961  		"foo": types.PrimitiveTypeMap[types.FloatKind],
   962  	}))
   963  	assert.True(mustType(types.TypeOf(out)).Equals(st2))
   964  
   965  	// It's OK to have an empty original field
   966  	s = S{
   967  		Foo: 42,
   968  	}
   969  	assert.True(mustValue(Marshal(context.Background(), vs, s)).Equals(
   970  		mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{"foo": types.Float(float64(42))}))))
   971  }
   972  
   973  func TestNomsTypes(t *testing.T) {
   974  	assert := assert.New(t)
   975  
   976  	vs := newTestValueStore()
   977  	defer vs.Close()
   978  
   979  	type S struct {
   980  		Blob   types.Blob
   981  		Bool   types.Bool
   982  		Number types.Float
   983  		String types.String
   984  		Type   *types.Type
   985  	}
   986  	s := S{
   987  		Blob:   mustBlob(types.NewBlob(context.Background(), vs)),
   988  		Bool:   types.Bool(true),
   989  		Number: types.Float(42),
   990  		String: types.String("hi"),
   991  		Type:   types.PrimitiveTypeMap[types.FloatKind],
   992  	}
   993  	assert.True(mustValue(Marshal(context.Background(), vs, s)).Equals(
   994  		mustStruct(types.NewStruct(types.Format_7_18, "S", types.StructData{
   995  			"blob":   mustBlob(types.NewBlob(context.Background(), vs)),
   996  			"bool":   types.Bool(true),
   997  			"number": types.Float(42),
   998  			"string": types.String("hi"),
   999  			"type":   types.PrimitiveTypeMap[types.FloatKind],
  1000  		})),
  1001  	))
  1002  }
  1003  
  1004  type primitiveType int
  1005  
  1006  func (t primitiveType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) {
  1007  	return types.Float(int(t) + 1), nil
  1008  }
  1009  
  1010  func TestMarshalerPrimitiveType(t *testing.T) {
  1011  	assert := assert.New(t)
  1012  
  1013  	vs := newTestValueStore()
  1014  	defer vs.Close()
  1015  
  1016  	u := primitiveType(42)
  1017  	v, err := Marshal(context.Background(), vs, u)
  1018  	require.NoError(t, err)
  1019  	assert.Equal(types.Float(43), v)
  1020  }
  1021  
  1022  type primitiveSliceType []string
  1023  
  1024  func (u primitiveSliceType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) {
  1025  	return types.String(strings.Join(u, ",")), nil
  1026  }
  1027  
  1028  func TestMarshalerPrimitiveSliceType(t *testing.T) {
  1029  	assert := assert.New(t)
  1030  
  1031  	vs := newTestValueStore()
  1032  	defer vs.Close()
  1033  
  1034  	u := primitiveSliceType([]string{"a", "b", "c"})
  1035  	v, err := Marshal(context.Background(), vs, u)
  1036  	require.NoError(t, err)
  1037  	assert.Equal(types.String("a,b,c"), v)
  1038  }
  1039  
  1040  type primitiveMapType map[string]string
  1041  
  1042  func (u primitiveMapType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) {
  1043  	var vals types.ValueSlice
  1044  	for k, v := range u {
  1045  		vals = append(vals, types.String(k+","+v))
  1046  	}
  1047  	return types.NewSet(context.Background(), vrw, vals...)
  1048  }
  1049  
  1050  func TestMarshalerPrimitiveMapType(t *testing.T) {
  1051  	assert := assert.New(t)
  1052  
  1053  	vs := newTestValueStore()
  1054  	defer vs.Close()
  1055  
  1056  	u := primitiveMapType(map[string]string{
  1057  		"a": "foo",
  1058  		"b": "bar",
  1059  	})
  1060  	v, err := Marshal(context.Background(), vs, u)
  1061  	require.NoError(t, err)
  1062  	assert.True(mustSet(types.NewSet(context.Background(), vs, types.String("a,foo"), types.String("b,bar"))).Equals(v))
  1063  }
  1064  
  1065  type primitiveStructType struct {
  1066  	x, y int
  1067  }
  1068  
  1069  func (u primitiveStructType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) {
  1070  	return types.Float(u.x + u.y), nil
  1071  }
  1072  
  1073  func TestMarshalerPrimitiveStructType(t *testing.T) {
  1074  	assert := assert.New(t)
  1075  
  1076  	vs := newTestValueStore()
  1077  	defer vs.Close()
  1078  
  1079  	u := primitiveStructType{1, 2}
  1080  	v, err := Marshal(context.Background(), vs, u)
  1081  	require.NoError(t, err)
  1082  	assert.Equal(types.Float(3), v)
  1083  }
  1084  
  1085  type builtinType regexp.Regexp
  1086  
  1087  func (u builtinType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) {
  1088  	r := regexp.Regexp(u)
  1089  	return types.String(r.String()), nil
  1090  }
  1091  
  1092  func TestMarshalerBuiltinType(t *testing.T) {
  1093  	assert := assert.New(t)
  1094  
  1095  	vs := newTestValueStore()
  1096  	defer vs.Close()
  1097  
  1098  	s := "[a-z]+$"
  1099  	r := regexp.MustCompile(s)
  1100  	u := builtinType(*r)
  1101  	v, err := Marshal(context.Background(), vs, u)
  1102  	require.NoError(t, err)
  1103  	assert.Equal(types.String(s), v)
  1104  }
  1105  
  1106  type wrappedMarshalerType primitiveType
  1107  
  1108  func (u wrappedMarshalerType) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) {
  1109  	return types.Float(int(u) + 2), nil
  1110  }
  1111  
  1112  func TestMarshalerWrapperMarshalerType(t *testing.T) {
  1113  	assert := assert.New(t)
  1114  
  1115  	vs := newTestValueStore()
  1116  	defer vs.Close()
  1117  
  1118  	u := wrappedMarshalerType(primitiveType(42))
  1119  	v, err := Marshal(context.Background(), vs, u)
  1120  	require.NoError(t, err)
  1121  	assert.Equal(types.Float(44), v)
  1122  }
  1123  
  1124  type TestComplexStructType struct {
  1125  	P       primitiveType
  1126  	Ps      []primitiveType
  1127  	Pm      map[string]primitiveType
  1128  	Pslice  primitiveSliceType
  1129  	Pmap    primitiveMapType
  1130  	Pstruct primitiveStructType
  1131  	B       builtinType
  1132  }
  1133  
  1134  func TestMarshalerComplexStructType(t *testing.T) {
  1135  	assert := assert.New(t)
  1136  
  1137  	vs := newTestValueStore()
  1138  	defer vs.Close()
  1139  
  1140  	s := "foo|bar"
  1141  	r := regexp.MustCompile(s)
  1142  	u := TestComplexStructType{
  1143  		P:  42,
  1144  		Ps: []primitiveType{1, 2},
  1145  		Pm: map[string]primitiveType{
  1146  			"x": 100,
  1147  			"y": 101,
  1148  		},
  1149  		Pslice: primitiveSliceType{"a", "b", "c"},
  1150  		Pmap: primitiveMapType{
  1151  			"c": "123",
  1152  			"d": "456",
  1153  		},
  1154  		Pstruct: primitiveStructType{10, 20},
  1155  		B:       builtinType(*r),
  1156  	}
  1157  
  1158  	v, err := Marshal(context.Background(), vs, u)
  1159  	require.NoError(t, err)
  1160  
  1161  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "TestComplexStructType", types.StructData{
  1162  		"p":       types.Float(43),
  1163  		"ps":      mustValue(types.NewList(context.Background(), vs, types.Float(2), types.Float(3))),
  1164  		"pm":      mustValue(types.NewMap(context.Background(), vs, types.String("x"), types.Float(101), types.String("y"), types.Float(102))),
  1165  		"pslice":  types.String("a,b,c"),
  1166  		"pmap":    mustValue(types.NewSet(context.Background(), vs, types.String("c,123"), types.String("d,456"))),
  1167  		"pstruct": types.Float(30),
  1168  		"b":       types.String(s),
  1169  	})).Equals(v))
  1170  }
  1171  
  1172  type returnsMarshalerError struct {
  1173  	err error
  1174  }
  1175  
  1176  func (u returnsMarshalerError) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) {
  1177  	return nil, u.err
  1178  }
  1179  
  1180  type returnsMarshalerNil struct{}
  1181  
  1182  func (u returnsMarshalerNil) MarshalNoms(vrw types.ValueReadWriter) (types.Value, error) {
  1183  	return nil, nil
  1184  }
  1185  
  1186  func TestMarshalerErrors(t *testing.T) {
  1187  	assert := assert.New(t)
  1188  
  1189  	vs := newTestValueStore()
  1190  	defer vs.Close()
  1191  
  1192  	expErr := errors.New("expected error")
  1193  	m1 := returnsMarshalerError{expErr}
  1194  	_, actErr := Marshal(context.Background(), vs, m1)
  1195  	assert.Equal(&marshalNomsError{expErr}, actErr)
  1196  
  1197  	m2 := returnsMarshalerNil{}
  1198  	_, err := Marshal(context.Background(), vs, m2)
  1199  	assert.Error(err)
  1200  }
  1201  
  1202  type TestStructWithNameImpl struct {
  1203  	X int
  1204  }
  1205  
  1206  func (ts TestStructWithNameImpl) MarshalNomsStructName() string {
  1207  	return "A"
  1208  }
  1209  func TestMarshalStructName(t *testing.T) {
  1210  	assert := assert.New(t)
  1211  
  1212  	vs := newTestValueStore()
  1213  	defer vs.Close()
  1214  
  1215  	ts := TestStructWithNameImpl{
  1216  		X: 1,
  1217  	}
  1218  	v, err := Marshal(context.Background(), vs, ts)
  1219  	require.NoError(t, err)
  1220  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "A", types.StructData{
  1221  		"x": types.Float(1),
  1222  	})).Equals(v), mustString(types.EncodedValue(context.Background(), v)))
  1223  }
  1224  
  1225  type TestStructWithNameImpl2 struct {
  1226  	X int
  1227  }
  1228  
  1229  func (ts TestStructWithNameImpl2) MarshalNomsStructName() string {
  1230  	return ""
  1231  }
  1232  func TestMarshalStructName2(t *testing.T) {
  1233  	assert := assert.New(t)
  1234  
  1235  	vs := newTestValueStore()
  1236  	defer vs.Close()
  1237  
  1238  	ts := TestStructWithNameImpl2{
  1239  		X: 1,
  1240  	}
  1241  	v, err := Marshal(context.Background(), vs, ts)
  1242  	require.NoError(t, err)
  1243  	assert.True(mustStruct(types.NewStruct(types.Format_7_18, "", types.StructData{
  1244  		"x": types.Float(1),
  1245  	})).Equals(v), mustString(types.EncodedValue(context.Background(), v)))
  1246  }