Browse Source

codec: test: expand to include maps with struct keys

    Ensure those maps with struct keys are set to nil if decoding into a nil interface.
Ugorji Nwoke 6 years ago
parent
commit
dfc37c8976
3 changed files with 55 additions and 12 deletions
  1. 16 0
      codec/codec_test.go
  2. 27 3
      codec/values_flex_test.go
  3. 12 9
      codec/values_test.go

+ 16 - 0
codec/codec_test.go

@@ -751,6 +751,18 @@ func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
 	for i, v0 := range vs {
 		logTv(t, "..............................................")
 		logTv(t, "         Testing: #%d:, %T, %#v\n", i, v0, v0)
+		// if a TestStrucFlex and we are doing a testNil,
+		// ensure the fields which are not encodeable are set to nil appropriately
+		// i.e. MstrUi64TSelf
+		var mapMstrUi64TSelf map[stringUint64T]*stringUint64T
+		var mapMsu2wss map[stringUint64T]wrapStringSlice
+		tsflex, _ := v0.(*TestStrucFlex)
+		if testNil && tsflex != nil {
+			mapMstrUi64TSelf = tsflex.MstrUi64TSelf
+			mapMsu2wss = tsflex.Msu2wss
+			tsflex.MstrUi64TSelf = nil
+			tsflex.Msu2wss = nil
+		}
 		b0 := testMarshalErr(v0, h, t, "v0")
 		var b1 = b0
 		if len(b1) > 256 {
@@ -766,6 +778,10 @@ func doTestCodecTableOne(t *testing.T, testNil bool, h Handle,
 		var err error
 		if testNil {
 			err = testUnmarshal(&v1, b0, h)
+			if tsflex != nil {
+				tsflex.MstrUi64TSelf = mapMstrUi64TSelf
+				tsflex.Msu2wss = mapMsu2wss
+			}
 		} else {
 			if v0 != nil {
 				v0rt := reflect.TypeOf(v0) // ptr

+ 27 - 3
codec/values_flex_test.go

@@ -6,6 +6,7 @@
 package codec
 
 import (
+	"strconv"
 	"strings"
 	"time"
 )
@@ -168,6 +169,10 @@ type TestStrucFlex struct {
 	Mfwss   map[float64]wrapStringSlice
 	Mf32wss map[float32]wrapStringSlice
 	Mui2wss map[uint64]wrapStringSlice
+
+	// DecodeNaked bombs because stringUint64T is decoded as a map,
+	// and a map cannot be the key type of a map.
+	// Ensure this is set to nil if decoding into a nil interface{}.
 	Msu2wss map[stringUint64T]wrapStringSlice
 
 	Ci64       wrapInt64
@@ -181,6 +186,9 @@ type TestStrucFlex struct {
 
 	SintfAarray []interface{}
 
+	// Ensure this is set to nil if decoding into a nil interface{}.
+	MstrUi64TSelf map[stringUint64T]*stringUint64T
+
 	// make this a ptr, so that it could be set or not.
 	// for comparison (e.g. with msgp), give it a struct tag (so it is not inlined),
 	// make this one omitempty (so it is excluded if nil).
@@ -227,6 +235,15 @@ func newTestStrucFlex(depth, n int, bench, useInterface, useStringKeyOnly bool)
 			5.0: []wrapString{"1.0", "2.0", "3.0", "4.0", "5.0"},
 			3.0: []wrapString{"1.0", "2.0", "3.0"},
 		},
+
+		// DecodeNaked bombs here, because the stringUint64T is decoded as a map,
+		// and a map cannot be the key type of a map.
+		// Ensure this is set to nil if decoding into a nil interface{}.
+		Msu2wss: map[stringUint64T]wrapStringSlice{
+			{"5", 5}: []wrapString{"1", "2", "3", "4", "5"},
+			{"3", 3}: []wrapString{"1", "2", "3"},
+		},
+
 		Mis: map[int]string{
 			1:   "one",
 			22:  "twenty two",
@@ -250,9 +267,16 @@ func newTestStrucFlex(depth, n int, bench, useInterface, useStringKeyOnly bool)
 		Swrapuint8: []wrapUint8{
 			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
 		},
-		Ui64array:   [4]uint64{4, 16, 64, 256},
-		ArrStrUi64T: [4]stringUint64T{{"4", 4}, {"3", 3}, {"2", 2}, {"1", 1}},
-		SintfAarray: []interface{}{Aarray{"s"}},
+		Ui64array:     [4]uint64{4, 16, 64, 256},
+		ArrStrUi64T:   [4]stringUint64T{{"4", 4}, {"3", 3}, {"2", 2}, {"1", 1}},
+		SintfAarray:   []interface{}{Aarray{"s"}},
+		MstrUi64TSelf: make(map[stringUint64T]*stringUint64T, numStrUi64T),
+	}
+
+	for i := uint64(0); i < numStrUi64T; i++ {
+		ss := stringUint64T{S: strings.Repeat(strconv.FormatUint(i, 10), 4), U: i}
+		// Ensure this is set to nil if decoding into a nil interface{}.
+		ts.MstrUi64TSelf[ss] = &ss
 	}
 
 	numChanSend := cap(ts.Chstr) / 4 // 8

+ 12 - 9
codec/values_test.go

@@ -18,6 +18,7 @@ package codec
 
 import (
 	"math"
+	"strconv"
 	"strings"
 )
 
@@ -26,6 +27,8 @@ import (
 // 	defTypeInfos.get(rt2id(rt), rt)
 // }
 
+const numStrUi64T = 4 // TODO: prefer 32
+
 type wrapSliceUint64 []uint64
 type wrapSliceString []string
 type wrapUint64 uint64
@@ -138,6 +141,7 @@ type TestStrucCommon struct {
 	Simplef testSimpleFields
 
 	SstrUi64T []stringUint64T
+	MstrUi64T map[string]*stringUint64T
 
 	AnonInTestStruc
 
@@ -302,14 +306,6 @@ func populateTestStrucCommon(ts *TestStrucCommon, n int, bench, useInterface, us
 		// R: Raw([]byte("goodbye")),
 		// Rext: RawExt{ 120, []byte("hello"), }, // TODO: don't set this - it's hard to test
 
-		// DecodeNaked bombs here, because the stringUint64T is decoded as a map,
-		// and a map cannot be the key type of a map.
-		// Thus, don't initialize this here.
-		// Msu2wss: map[stringUint64T]wrapStringSlice{
-		// 	{"5", 5}: []wrapString{"1", "2", "3", "4", "5"},
-		// 	{"3", 3}: []wrapString{"1", "2", "3"},
-		// },
-
 		// make Simplef same as top-level
 		// TODO: should this have slightly different values???
 		Simplef: testSimpleFields{
@@ -343,11 +339,18 @@ func populateTestStrucCommon(ts *TestStrucCommon, n int, bench, useInterface, us
 			WrapSliceString: []string{strRpt(n, "4"), strRpt(n, "16"), strRpt(n, "64"), strRpt(n, "256")},
 		},
 
-		SstrUi64T:       []stringUint64T{{"1", 1}, {"2", 2}, {"3", 3}, {"4", 4}},
+		SstrUi64T:       make([]stringUint64T, numStrUi64T), // {{"1", 1}, {"2", 2}, {"3", 3}, {"4", 4}},
+		MstrUi64T:       make(map[string]*stringUint64T, numStrUi64T),
 		AnonInTestStruc: a,
 		NotAnon:         a,
 	}
 
+	for i := uint64(0); i < numStrUi64T; i++ {
+		ss := strings.Repeat(strconv.FormatUint(i, 10), 4)
+		ts.SstrUi64T[i] = stringUint64T{S: ss, U: i}
+		ts.MstrUi64T[ss] = &ts.SstrUi64T[i]
+	}
+
 	if bench {
 		ts.Ui64 = math.MaxInt64 * 2 / 3
 		ts.Simplef.Ui64 = ts.Ui64