github.com/tunabay/go-bitarray@v1.3.1/bitarray_compare_test.go (about) 1 // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved. 2 // Use of this source code is governed by the MIT license that can be found in 3 // the LICENSE file. 4 5 package bitarray_test 6 7 import ( 8 "fmt" 9 "math/rand" 10 "sort" 11 "strings" 12 "testing" 13 "time" 14 15 "github.com/tunabay/go-bitarray" 16 ) 17 18 func TestBitArray_Equal(t *testing.T) { 19 const nillit = "<nil>" 20 fail := func(x, y *bitarray.BitArray) { 21 t.Helper() 22 if t.Failed() { 23 t.Logf("x: [%# b]", x) 24 t.Logf("y: [%# b]", y) 25 t.Logf("x: %s", x.D()) 26 t.Logf("y: %s", y.D()) 27 t.FailNow() 28 } 29 } 30 test := func(x, y *bitarray.BitArray, exp bool) { 31 t.Helper() 32 if x.Equal(y) != exp { 33 t.Errorf("unexpected x.Equal(y): got %t, want %t", !exp, exp) 34 } 35 fail(x, y) 36 if x == nil || y == nil { 37 return 38 } 39 xe, ye := x.ZExpand(), y.ZExpand() 40 xo, yo := x.ZOptimize(), y.ZOptimize() 41 switch { 42 case xe.Equal(ye) != exp: 43 t.Errorf("unexpected xe.Equal(ye): got %t, want %t", !exp, exp) 44 case xe.Equal(yo) != exp: 45 t.Errorf("unexpected xe.Equal(yo): got %t, want %t", !exp, exp) 46 case xo.Equal(yo) != exp: 47 t.Errorf("unexpected xo.Equal(yo): got %t, want %t", !exp, exp) 48 } 49 fail(x, y) 50 } 51 ptwo := func(xs, ys string) (x, y *bitarray.BitArray) { 52 t.Helper() 53 if xs != nillit { 54 x = bitarray.MustParse(xs) 55 } 56 if ys != nillit { 57 y = bitarray.MustParse(ys) 58 } 59 return 60 } 61 equal := func(xs, ys string) { 62 t.Helper() 63 x, y := ptwo(xs, ys) 64 test(x, y, true) 65 test(y, x, true) 66 } 67 differ := func(xs, ys string) { 68 t.Helper() 69 x, y := ptwo(xs, ys) 70 test(x, y, false) 71 test(y, x, false) 72 } 73 74 equal(nillit, nillit) 75 equal(nillit, "") 76 differ(nillit, "0") 77 equal("0", "0") 78 equal("00", "00") 79 equal("000", "000") 80 equal("0000", "0000") 81 equal("0000-0", "0000-0") 82 equal("0000-00", "0000-00") 83 equal("0000-000", "0000-000") 84 equal("0000-0000", "0000-0000") 85 equal("0000-0000 0", "0000-0000 0") 86 equal("0000-0000 0000-0000", "0000-0000 0000-0000") 87 equal("0000-0000 0000-0000 0000-000", "0000-0000 0000-0000 0000-000") 88 differ("0000-0000 0000-0000 0000-000", "0000-0000 0000-0000 0000-0000") 89 differ("0000-0000 0000-0000 0000-0000", "0000-0000 0000-0000 0000-0000 0") 90 differ("0", "00") 91 differ("0", "000") 92 differ("0", "0000") 93 differ("0", "0000-0") 94 differ("0", "0000-00") 95 differ("0", "0000-000") 96 differ("0", "0000-0000") 97 differ("0", "0000-0000 0") 98 differ("0", "0000-0000 00") 99 differ("0000-000", "0000-0000") 100 differ("0000-0000", "0000-0000 0") 101 differ("0000-001", "0000-0010") 102 differ("0000-0000 10", "0000-0000 100") 103 equal("1", "1") 104 differ("1", "0") 105 differ("1", "10") 106 differ("1", "100") 107 differ("1", "1000") 108 differ("1", "1000-0000") 109 differ("1", "0000-0001") 110 differ("1", "0000-0000 1") 111 differ("1", "1000-0000 00") 112 equal("0000-1111 1111-0000 0000-1111", "0000-1111 1111-0000 0000-1111") 113 differ("0000-1111 1111-0000 0000-1111", "0000-1111 1111-0000 0000-1111 0") 114 differ("0000-1111 1111-0000 0000-1111 1", "0000-1111 1111-0000 0000-1111 0") 115 differ("0000-1111 1111-0000 0000-1111 1", "0000-1111 1011-0000 0000-1111 1") 116 differ("0000-1110 1111-0000 0000-1111 1", "0000-1111 1111-0000 0000-1111 1") 117 } 118 119 func TestBitArray_Compare(t *testing.T) { 120 src := []string{ 121 "", 122 "0", 123 "00", 124 "000", 125 "0000", 126 "0000-0", 127 "0000-00", 128 "0000-000", 129 "0000-0000", 130 "0000-0000 0", 131 "0000-0000 00", 132 "0000-0000 000", 133 "0000-0000 0000", 134 "0000-0000 0000-0", 135 "0000-0000 0000-00", 136 "0000-0000 0000-000", 137 "0000-0000 0000-0000", 138 "0000-0000 0000-0000 0", 139 "0000-0000 0000-0000 00", 140 "0000-0001", 141 "0000-0001 00", 142 "0000-0001 0000-0000 0000-0000", 143 "0000-0001 0000-0000 0000-0000 0", 144 "0000-0001 0000-0000 0000-0000 1", 145 "0000-0001 0000-0000 0000-0001", 146 "0000-0001 0000-0000 0000-0001 0", 147 "0000-0001 0000-0000 0000-0001 1", 148 "0000-0001 0000-0001", 149 "0000-0001 01", 150 "0000-0001 1", 151 "0000-0001 11", 152 "0000-0010", 153 "0000-0100", 154 "0000-1000", 155 "0000-1100 0000-0000 0000-0000 0000-0000 0000-000", 156 "0000-1100 0000-0000 0000-0000 0000-0000 0000-0000", 157 "0000-1100 0000-0000 0000-0000 0000-0000 0000-0000 0", 158 "0000-1100 0000-0000 0000-0000 0000-0000 0000-0000 00", 159 "0000-1100 0000-0000 0000-0000 0000-0000 0000-0000 0000", 160 "0000-1100 0000-0000 0000-0000 0000-0000 0000-0000 0011", 161 "0000-1100 0000-0000 0000-0000 0000-0000 0000-0000 01", 162 "0000-1100 0000-0000 0000-0000 0100-0000 0000-000", 163 "0000-1100 0000-0000 0000-0000 1000-0000 0000-00", 164 "0000-1100 0000-0000 0000-0000 1000-0000 0000-000", 165 "0000-1101 1111-1110 0000-0000", 166 "0000-1101 1111-1110 0000-0000 0", 167 "0000-1101 1111-1110 0000-0001", 168 "0000-1101 1111-1110 0000-001", 169 "0000-1101 1111-1110 0000-01", 170 "0000-1101 1111-1110 0000-1", 171 "0000-1101 1111-1110 0000-10", 172 "0000-1101 1111-1110 0000-100", 173 "0000-1101 1111-1110 0000-1000", 174 "0000-1101 1111-1110 0000-11", 175 "0000-1101 1111-1110 0001", 176 "0000-1101 1111-1111 0", 177 "0000-1101 1111-1111 00", 178 "0000-1101 1111-1111 000", 179 "0000-1101 1111-1111 1", 180 "0000-1101 1111-1111 11", 181 "0000-1101 1111-1111 111", 182 "0000-1111", 183 "0000-1111 0", 184 "0000-1111 00", 185 "0000-1111 1", 186 "0000-1111 10", 187 "0000-1111 11", 188 "0000-1111 1100", 189 "0000-1111 1100-1100", 190 "0000-1111 1100-1100 0", 191 "0000-1111 1100-1100 00", 192 "0000-1111 1100-1100 01", 193 "0000-1111 1100-1100 1", 194 "0000-1111 1100-1100 10", 195 "0000-1111 1100-1100 11", 196 "01", 197 "010", 198 "0101", 199 "0101-0", 200 "0101-01", 201 "0101-010", 202 "0101-0101", 203 "0101-0101 0", 204 "0101-0101 01", 205 "0111", 206 "0111-0", 207 "0111-00", 208 "0111-01", 209 "0111-1", 210 "0111-10", 211 "0111-101", 212 "0111-11", 213 "0111-1100", 214 "0111-1100 0", 215 "0111-1101", 216 "1", 217 "10", 218 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0", 219 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-00", 220 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000", 221 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0", 222 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 00", 223 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 000", 224 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 1", 225 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 10", 226 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 100", 227 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0000 11", 228 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-0001", 229 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-001", 230 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-01", 231 "1000-0000 0000-0000 0000-0000 0000-0000 0000-0000 0000-1", 232 "11", 233 "111", 234 "1111", 235 "1111-1", 236 "1111-11", 237 "1111-111", 238 "1111-1111", 239 "1111-1111 1", 240 "1111-1111 11", 241 "1111-1111 111", 242 "1111-1111 1111", 243 "1111-1111 1111-1", 244 "1111-1111 1111-11", 245 "1111-1111 1111-110", 246 "1111-1111 1111-111", 247 "1111-1111 1111-1111", 248 "1111-1111 1111-1111 1", 249 "1111-1111 1111-1111 11", 250 } 251 dat := make([]*bitarray.BitArray, len(src)) 252 for i, s := range src { 253 if i+1 < len(src) { 254 next := src[i+1] 255 if next <= s { 256 t.Errorf("misordered data samples:") 257 t.Logf("#%3d: %q", i, s) 258 t.Logf("#%3d: %q", i+1, next) 259 t.FailNow() 260 } 261 } 262 dat[i] = bitarray.MustParse(s) 263 // t.Logf("data: %s", dat[i].D()) 264 } 265 for i := 0; i < len(dat); i++ { 266 x := dat[i] 267 xe := x.ZExpand() 268 xo := x.ZOptimize() 269 for j := 0; j < len(dat); j++ { 270 y := dat[j] 271 ye := y.ZExpand() 272 yo := y.ZOptimize() 273 c := bitarray.Compare(x, y) 274 switch { 275 case i == j && c != 0: 276 t.Errorf("unexpected result: got %d, want 0, x == y:", c) 277 case i < j && c != -1: 278 t.Errorf("unexpected result: got %d, want -1, x < y:", c) 279 case j < i && c != +1: 280 t.Errorf("unexpected result: got %d, want +1, y < x:", c) 281 } 282 if ca := bitarray.Compare(xe, ye); ca != c { 283 t.Errorf("unexpected result (e,e): got %d, want %d", ca, c) 284 } 285 if ca := bitarray.Compare(xe, yo); ca != c { 286 t.Errorf("unexpected result (e,o): got %d, want %d", ca, c) 287 } 288 if ca := bitarray.Compare(xo, yo); ca != c { 289 t.Errorf("unexpected result (o,o): got %d, want %d", ca, c) 290 } 291 if t.Failed() { 292 t.Logf("x: [%# b]", x) 293 t.Logf("y: [%# b]", y) 294 t.Logf("x: %s", x.D()) 295 t.Logf("y: %s", y.D()) 296 t.FailNow() 297 } 298 // t.Logf("passed: [%# b] %c [%# b]", x, "<=>"[c+1], y) 299 } 300 } 301 } 302 303 func TestBitArray_Compare_rand(t *testing.T) { 304 const testIterations = 256 305 const listSize = 256 306 rand.Seed(time.Now().UnixNano()) 307 mkdat := func() []*bitarray.BitArray { 308 t.Helper() 309 src := make([]string, listSize) 310 for i := range src { 311 n := rand.Intn(256) 312 if n == 0 || rand.Intn(64) == 0 { 313 continue 314 } 315 b := make([]byte, (n+7)>>3) 316 rand.Read(b) 317 s := fmt.Sprintf("%08b", b) 318 s = strings.Trim(s, "[]") 319 s = strings.ReplaceAll(s, " ", "") 320 src[i] = s[:n] 321 } 322 sort.Strings(src) 323 bas := make([]*bitarray.BitArray, 0, listSize) 324 for i, s := range src { 325 if 0 < i && s == src[i-1] { 326 continue 327 } 328 ba := bitarray.MustParse(s) 329 bas = append(bas, ba) 330 // t.Logf("dat: %# b", ba) 331 } 332 return bas 333 } 334 for i := 0; i < testIterations; i++ { 335 dat := mkdat() 336 for xi, x := range dat { 337 for yi, y := range dat { 338 c := bitarray.Compare(x, y) 339 switch { 340 case xi == yi && c != 0: 341 t.Errorf("unexpected result: got %d, want 0, x == y:", c) 342 case xi < yi && c != -1: 343 t.Errorf("unexpected result: got %d, want -1, x < y:", c) 344 case yi < xi && c != +1: 345 t.Errorf("unexpected result: got %d, want +1, y < x:", c) 346 } 347 if t.Failed() { 348 t.Logf("x: [%# b]", x) 349 t.Logf("y: [%# b]", y) 350 t.Logf("x: %s", x.D()) 351 t.Logf("y: %s", y.D()) 352 t.FailNow() 353 } 354 // t.Logf("passed: [%# b] %c [%# b]", x, "<=>"[c+1], y) 355 } 356 } 357 } 358 }