github.com/xiaoxu5271/can-go@v1.0.1/data_test.go (about) 1 package can 2 3 import ( 4 "fmt" 5 "testing" 6 "testing/quick" 7 8 "gotest.tools/v3/assert" 9 ) 10 11 func TestData_Bit(t *testing.T) { 12 for i, tt := range []struct { 13 data Data 14 bits []struct { 15 i uint8 16 bit bool 17 } 18 }{ 19 { 20 data: Data{0x01, 0x23}, 21 bits: []struct { 22 i uint8 23 bit bool 24 }{ 25 // nibble 1: 0x1 26 {bit: true, i: 0}, 27 {bit: false, i: 1}, 28 {bit: false, i: 2}, 29 {bit: false, i: 3}, 30 // nibble 2: 0x0 31 {bit: false, i: 4}, 32 {bit: false, i: 5}, 33 {bit: false, i: 6}, 34 {bit: false, i: 7}, 35 // nibble 3: 0x3 36 {bit: true, i: 8}, 37 {bit: true, i: 9}, 38 {bit: false, i: 10}, 39 {bit: false, i: 11}, 40 // nibble 4: 0x2 41 {bit: false, i: 12}, 42 {bit: true, i: 13}, 43 {bit: false, i: 14}, 44 {bit: false, i: 15}, 45 }, 46 }, 47 } { 48 i, tt := i, tt 49 t.Run("Get", func(t *testing.T) { 50 i, tt := i, tt 51 for j, ttBit := range tt.bits { 52 j, ttBit := j, ttBit 53 t.Run(fmt.Sprintf("tt=%v,bit=%v", i, j), func(t *testing.T) { 54 bit := tt.data.Bit(ttBit.i) 55 assert.Equal(t, ttBit.bit, bit) 56 }) 57 } 58 }) 59 t.Run("Set", func(t *testing.T) { 60 i, tt := i, tt 61 t.Run(fmt.Sprintf("data=%v", i), func(t *testing.T) { 62 var data Data 63 for _, tBit := range tt.bits { 64 data.SetBit(tBit.i, tBit.bit) 65 } 66 assert.DeepEqual(t, tt.data, data) 67 }) 68 }) 69 } 70 } 71 72 func TestData_Property_SetGetBit(t *testing.T) { 73 f := func(_ Data, _ uint8, bit bool) bool { 74 return bit 75 } 76 g := func(data Data, i uint8, bit bool) bool { 77 i %= 64 78 data.SetBit(i, bit) 79 return data.Bit(i) 80 } 81 assert.NilError(t, quick.CheckEqual(f, g, nil)) 82 } 83 84 func TestData_LittleEndian(t *testing.T) { 85 for i, tt := range []struct { 86 data Data 87 signals []struct { 88 start uint8 89 length uint8 90 unsigned uint64 91 signed int64 92 } 93 }{ 94 { 95 data: Data{0x80, 0x01}, 96 signals: []struct { 97 start uint8 98 length uint8 99 unsigned uint64 100 signed int64 101 }{ 102 {start: 7, length: 2, unsigned: 0x3, signed: -1}, 103 }, 104 }, 105 { 106 data: Data{0x01, 0x02, 0x03}, 107 signals: []struct { 108 start uint8 109 length uint8 110 unsigned uint64 111 signed int64 112 }{ 113 {start: 0, length: 24, unsigned: 0x030201, signed: 197121}, 114 }, 115 }, 116 { 117 data: Data{0x40, 0x23, 0x01, 0x12}, 118 signals: []struct { 119 start uint8 120 length uint8 121 unsigned uint64 122 signed int64 123 }{ 124 {start: 24, length: 8, unsigned: 0x12, signed: 18}, 125 {start: 8, length: 8, unsigned: 0x23, signed: 35}, 126 {start: 4, length: 16, unsigned: 0x1234, signed: 4660}, 127 }, 128 }, 129 } { 130 i, tt := i, tt 131 t.Run(fmt.Sprintf("UnsignedBits:%v", i), func(t *testing.T) { 132 for j, signal := range tt.signals { 133 j, signal := j, signal 134 t.Run(fmt.Sprintf("signal:%v", j), func(t *testing.T) { 135 actual := tt.data.UnsignedBitsLittleEndian(signal.start, signal.length) 136 assert.Equal(t, signal.unsigned, actual) 137 }) 138 } 139 }) 140 t.Run(fmt.Sprintf("SignedBits:%v", i), func(t *testing.T) { 141 for j, signal := range tt.signals { 142 j, signal := j, signal 143 t.Run(fmt.Sprintf("signal:%v", j), func(t *testing.T) { 144 actual := tt.data.SignedBitsLittleEndian(signal.start, signal.length) 145 assert.Equal(t, signal.signed, actual) 146 }) 147 } 148 }) 149 t.Run(fmt.Sprintf("SetUnsignedBits:%v", i), func(t *testing.T) { 150 var data Data 151 for j, signal := range tt.signals { 152 j, signal := j, signal 153 t.Run(fmt.Sprintf("data:%v", j), func(t *testing.T) { 154 data.SetUnsignedBitsLittleEndian(signal.start, signal.length, signal.unsigned) 155 }) 156 } 157 assert.DeepEqual(t, tt.data, data) 158 }) 159 t.Run(fmt.Sprintf("SetSignedBits:%v", i), func(t *testing.T) { 160 var data Data 161 for j, signal := range tt.signals { 162 j, signal := j, signal 163 t.Run(fmt.Sprintf("data:%v", j), func(t *testing.T) { 164 data.SetSignedBitsLittleEndian(signal.start, signal.length, signal.signed) 165 }) 166 } 167 assert.DeepEqual(t, tt.data, data) 168 }) 169 } 170 } 171 172 func TestData_BigEndian(t *testing.T) { 173 for i, tt := range []struct { 174 data Data 175 signals []struct { 176 start uint8 177 length uint8 178 unsigned uint64 179 signed int64 180 } 181 }{ 182 { 183 data: Data{0x3f, 0xf7, 0x0d, 0xc4, 0x0c, 0x93, 0xff, 0xff}, 184 signals: []struct { 185 start uint8 186 length uint8 187 unsigned uint64 188 signed int64 189 }{ 190 {start: 7, length: 3, unsigned: 0x1, signed: 1}, 191 {start: 4, length: 1, unsigned: 0x1, signed: -1}, 192 {start: 55, length: 16, unsigned: 0xffff, signed: -1}, 193 {start: 39, length: 16, unsigned: 0xc93, signed: 3219}, 194 {start: 23, length: 16, unsigned: 0xdc4, signed: 3524}, 195 {start: 3, length: 12, unsigned: 0xff7, signed: -9}, 196 }, 197 }, 198 { 199 data: Data{0x3f, 0xe4, 0x0e, 0xb6, 0x0c, 0xba, 0x00, 0x05}, 200 signals: []struct { 201 start uint8 202 length uint8 203 unsigned uint64 204 signed int64 205 }{ 206 {start: 7, length: 3, unsigned: 0x1, signed: 1}, 207 {start: 4, length: 1, unsigned: 0x1, signed: -1}, 208 {start: 55, length: 16, unsigned: 0x5, signed: 5}, 209 {start: 39, length: 16, unsigned: 0xcba, signed: 3258}, 210 {start: 23, length: 16, unsigned: 0xeb6, signed: 3766}, 211 {start: 3, length: 12, unsigned: 0xfe4, signed: -28}, 212 }, 213 }, 214 { 215 data: Data{0x30, 0x53, 0x23, 0xe5, 0x0e, 0x11, 0xff, 0xff}, 216 signals: []struct { 217 start uint8 218 length uint8 219 unsigned uint64 220 signed int64 221 }{ 222 {start: 7, length: 3, unsigned: 0x1, signed: 1}, 223 {start: 4, length: 1, unsigned: 0x1, signed: -1}, 224 {start: 55, length: 16, unsigned: 0xffff, signed: -1}, 225 {start: 39, length: 16, unsigned: 0xe11, signed: 3601}, 226 {start: 23, length: 16, unsigned: 0x23e5, signed: 9189}, 227 {start: 3, length: 12, unsigned: 0x53, signed: 83}, 228 }, 229 }, 230 } { 231 i, tt := i, tt 232 t.Run(fmt.Sprintf("UnsignedBits:%v", i), func(t *testing.T) { 233 for j, signal := range tt.signals { 234 j, signal := j, signal 235 t.Run(fmt.Sprintf("signal:%v", j), func(t *testing.T) { 236 actual := tt.data.UnsignedBitsBigEndian(signal.start, signal.length) 237 assert.Equal(t, signal.unsigned, actual) 238 }) 239 } 240 }) 241 t.Run(fmt.Sprintf("SignedBits:%v", i), func(t *testing.T) { 242 for j, signal := range tt.signals { 243 j, signal := j, signal 244 t.Run(fmt.Sprintf("signal:%v", j), func(t *testing.T) { 245 actual := tt.data.SignedBitsBigEndian(signal.start, signal.length) 246 assert.Equal(t, signal.signed, actual) 247 }) 248 } 249 }) 250 t.Run(fmt.Sprintf("SetUnsignedBits:%v", i), func(t *testing.T) { 251 var data Data 252 for j, signal := range tt.signals { 253 j, signal := j, signal 254 t.Run(fmt.Sprintf("data:%v", j), func(t *testing.T) { 255 data.SetUnsignedBitsBigEndian(signal.start, signal.length, signal.unsigned) 256 }) 257 } 258 assert.DeepEqual(t, tt.data, data) 259 }) 260 t.Run(fmt.Sprintf("SetSignedBits:%v", i), func(t *testing.T) { 261 var data Data 262 for j, signal := range tt.signals { 263 j, signal := j, signal 264 t.Run(fmt.Sprintf("data:%v", j), func(t *testing.T) { 265 data.SetSignedBitsBigEndian(signal.start, signal.length, signal.signed) 266 }) 267 } 268 assert.DeepEqual(t, tt.data, data) 269 }) 270 } 271 } 272 273 func TestInvertEndian_Property_Idempotent(t *testing.T) { 274 for i := uint8(0); i < 64; i++ { 275 assert.Equal(t, i, invertEndian(invertEndian(i))) 276 } 277 } 278 279 func TestPackUnpackBigEndian(t *testing.T) { 280 f := func(data Data) Data { 281 return data 282 } 283 g := func(data Data) Data { 284 data.UnpackBigEndian(data.PackBigEndian()) 285 return data 286 } 287 assert.NilError(t, quick.CheckEqual(f, g, nil)) 288 } 289 290 func TestPackUnpackLittleEndian(t *testing.T) { 291 f := func(data Data) Data { 292 return data 293 } 294 g := func(data Data) Data { 295 data.UnpackLittleEndian(data.PackLittleEndian()) 296 return data 297 } 298 assert.NilError(t, quick.CheckEqual(f, g, nil)) 299 } 300 301 func TestData_CheckBitRange(t *testing.T) { 302 // example case that big-endian signals and little-endian signals use different indexing 303 assert.NilError(t, CheckBitRangeBigEndian(8, 55, 16)) 304 assert.ErrorContains(t, CheckBitRangeLittleEndian(8, 55, 16), "bit range out of bounds") 305 } 306 307 func BenchmarkData_UnpackLittleEndian(b *testing.B) { 308 var data Data 309 for i := 0; i < b.N; i++ { 310 data.UnpackLittleEndian(0) 311 } 312 } 313 314 func BenchmarkData_UnpackBigEndian(b *testing.B) { 315 var data Data 316 for i := 0; i < b.N; i++ { 317 data.UnpackBigEndian(0) 318 } 319 } 320 321 func BenchmarkData_PackBigEndian(b *testing.B) { 322 var data Data 323 for i := 0; i < b.N; i++ { 324 _ = data.PackBigEndian() 325 } 326 } 327 328 func BenchmarkData_PackLittleEndian(b *testing.B) { 329 var data Data 330 for i := 0; i < b.N; i++ { 331 _ = data.PackLittleEndian() 332 } 333 }