github.com/datastax/go-cassandra-native-protocol@v0.0.0-20220706104457-5e8aad05cf90/primitive/string_multimap_test.go (about) 1 // Copyright 2020 DataStax 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 package primitive 16 17 import ( 18 "bytes" 19 "errors" 20 "fmt" 21 "io/ioutil" 22 "testing" 23 24 "github.com/stretchr/testify/assert" 25 ) 26 27 func TestReadStringMultiMap(t *testing.T) { 28 tests := []struct { 29 name string 30 source []byte 31 expected map[string][]string 32 remaining []byte 33 err error 34 }{ 35 {"empty string multimap", []byte{0, 0}, map[string][]string{}, []byte{}, nil}, 36 {"multimap 1 key 1 value", []byte{ 37 0, 1, // map length 38 0, 5, h, e, l, l, o, // key: hello 39 0, 1, // list length 40 0, 5, w, o, r, l, d, // value1: world 41 }, map[string][]string{"hello": {"world"}}, []byte{}, nil}, 42 {"multimap 1 key 2 values", []byte{ 43 0, 1, // map length 44 0, 5, h, e, l, l, o, // key: hello 45 0, 2, // list length 46 0, 5, w, o, r, l, d, // value1: world 47 0, 5, m, u, n, d, o, // value2: mundo 48 }, map[string][]string{"hello": {"world", "mundo"}}, []byte{}, nil}, 49 // FIXME map iteration order 50 //{"multimap 2 keys 2 values", []byte{ 51 // 0, 2, // map length 52 // 0, 5, h, e, l, l, o, // key1: hello 53 // 0, 2, // list length 54 // 0, 5, w, o, r, l, d, // value1: world 55 // 0, 5, m, u, n, d, o, // value2: mundo 56 // 0, 6, h, o, l, 0xc3, 0xa0, 0x21, // key2: holà! 57 // 0, 2, // list length 58 // 0, 5, w, o, r, l, d, // value1: world 59 // 0, 5, m, u, n, d, o, // value2: mundo 60 //}, map[string][]string{ 61 // "hello": {"world", "mundo"}, 62 // "holà!": {"world", "mundo"}, 63 //}, []byte{}, nil}, 64 { 65 "cannot read map length", 66 []byte{0}, 67 nil, 68 []byte{}, 69 fmt.Errorf( 70 "cannot read [string multimap] length: %w", 71 fmt.Errorf("cannot read [short]: %w", errors.New("unexpected EOF")), 72 ), 73 }, 74 { 75 "cannot read key length", 76 []byte{0, 1, 0}, 77 nil, 78 []byte{}, 79 fmt.Errorf( 80 "cannot read [string multimap] entry 0 key: %w", 81 fmt.Errorf("cannot read [string] length: %w", 82 fmt.Errorf("cannot read [short]: %w", errors.New("unexpected EOF"))), 83 ), 84 }, 85 { 86 "cannot read list length", 87 []byte{0, 1, 0, 1, k, 0}, 88 nil, 89 []byte{}, 90 fmt.Errorf( 91 "cannot read [string multimap] entry 0 value: %w", 92 fmt.Errorf("cannot read [string list] length: %w", 93 fmt.Errorf("cannot read [short]: %w", errors.New("unexpected EOF"))), 94 ), 95 }, 96 { 97 "cannot read element length", 98 []byte{0, 1, 0, 1, k, 0, 1, 0}, 99 nil, 100 []byte{}, 101 fmt.Errorf( 102 "cannot read [string multimap] entry 0 value: %w", 103 fmt.Errorf("cannot read [string list] element 0: %w", 104 fmt.Errorf("cannot read [string] length: %w", 105 fmt.Errorf("cannot read [short]: %w", errors.New("unexpected EOF")))), 106 ), 107 }, 108 { 109 "cannot read list", 110 []byte{0, 1, 0, 1, k, 0, 1, 0, 5, h, e, l, l}, 111 nil, 112 []byte{}, 113 fmt.Errorf("cannot read [string multimap] entry 0 value: %w", 114 fmt.Errorf("cannot read [string list] element 0: %w", 115 fmt.Errorf("cannot read [string] content: %w", errors.New("unexpected EOF")))), 116 }, 117 } 118 for _, tt := range tests { 119 t.Run(tt.name, func(t *testing.T) { 120 buf := bytes.NewReader(tt.source) 121 actual, err := ReadStringMultiMap(buf) 122 assert.Equal(t, tt.expected, actual) 123 assert.Equal(t, tt.err, err) 124 remaining, _ := ioutil.ReadAll(buf) 125 assert.Equal(t, tt.remaining, remaining) 126 }) 127 } 128 } 129 130 func TestWriteStringMultiMap(t *testing.T) { 131 tests := []struct { 132 name string 133 input map[string][]string 134 expected []byte 135 err error 136 }{ 137 { 138 "empty string multimap", 139 map[string][]string{}, 140 []byte{0, 0}, 141 nil, 142 }, 143 // not officially allowed by the specs, but better safe than sorry 144 { 145 "nil string multimap", 146 nil, 147 []byte{0, 0}, 148 nil, 149 }, 150 { 151 "multimap 1 key 1 value", 152 map[string][]string{"hello": {"world"}}, 153 []byte{ 154 0, 1, // map length 155 0, 5, h, e, l, l, o, // key: hello 156 0, 1, // list length 157 0, 5, w, o, r, l, d, // value1: world 158 }, 159 nil, 160 }, 161 { 162 "multimap 1 key 2 values", 163 map[string][]string{"hello": {"world", "mundo"}}, 164 []byte{ 165 0, 1, // map length 166 0, 5, h, e, l, l, o, // key: hello 167 0, 2, // list length 168 0, 5, w, o, r, l, d, // value1: world 169 0, 5, m, u, n, d, o, // value2: mundo 170 }, 171 nil, 172 }, 173 // FIXME map iteration order 174 //{"multimap 2 keys 2 values", 175 // map[string][]string{ 176 // "hello": {"world", "mundo"}, 177 // "holà!": {"world", "mundo"}, 178 // }, 179 // []byte{ 180 // 0, 2, // map length 181 // 0, 5, h, e, l, l, o, // key1: hello 182 // 0, 2, // list length 183 // 0, 5, w, o, r, l, d, // value1: world 184 // 0, 5, m, u, n, d, o, // value2: mundo 185 // 0, 6, h, o, l, 0xc3, 0xa0, 0x21, // key2: holà! 186 // 0, 2, // list length 187 // 0, 5, w, o, r, l, d, // value1: world 188 // 0, 5, m, u, n, d, o, // value2: mundo 189 // }, 190 // nil}, 191 } 192 for _, tt := range tests { 193 t.Run(tt.name, func(t *testing.T) { 194 buf := &bytes.Buffer{} 195 err := WriteStringMultiMap(tt.input, buf) 196 assert.Equal(t, tt.expected, buf.Bytes()) 197 assert.Equal(t, tt.err, err) 198 }) 199 } 200 }