github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/goutils/iterate/impl_test.go (about) 1 /* 2 * Copyright (c) 2021-present Sigma-Soft, Ltd. 3 * @author: Nikolay Nikitin 4 */ 5 6 package iterate 7 8 import ( 9 "errors" 10 "fmt" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 ) 15 16 type ( 17 ITested1 interface { 18 Fields(enum func(name string)) 19 } 20 tested1 struct { 21 fields []string 22 } 23 ) 24 25 func (s *tested1) Fields(enum func(name string)) { 26 for _, name := range s.fields { 27 enum(name) 28 } 29 } 30 31 func Test_ForEach(t *testing.T) { 32 require := require.New(t) 33 34 t.Run("test ForEach with interface method", func(t *testing.T) { 35 var tested ITested1 = &tested1{fields: []string{"a", "b", "c"}} 36 37 line := "" 38 ForEach(tested.Fields, func(d string) { line += d }) 39 40 require.Equal("abc", line) 41 }) 42 43 t.Run("test ForEach with structure method", func(t *testing.T) { 44 tested := tested1{fields: []string{"a", "b", "c"}} 45 46 line := "" 47 ForEach(tested.Fields, func(d string) { line += d }) 48 49 require.Equal("abc", line) 50 }) 51 52 t.Run("test ForEach with naked slice", func(t *testing.T) { 53 fields := []string{"a", "b", "c"} 54 55 line := "" 56 ForEach(Slice(fields), func(d string) { line += d }) 57 58 require.Equal("abc", line) 59 }) 60 } 61 62 func Test_FindFirst(t *testing.T) { 63 require := require.New(t) 64 65 t.Run("test FindFirst with interface method", func(t *testing.T) { 66 var tested ITested1 = &tested1{fields: []string{"a", "b", "c"}} 67 68 ok, data := FindFirst(tested.Fields, func(data string) bool { return data == "b" }) 69 require.True(ok) 70 require.Equal("b", data) 71 72 ok, data = FindFirst(tested.Fields, func(data string) bool { return data == "impossible" }) 73 require.False(ok) 74 require.Empty(data) 75 }) 76 77 t.Run("test FindFirst with structure method", func(t *testing.T) { 78 tested := tested1{fields: []string{"a", "b", "c"}} 79 80 ok, data := FindFirst(tested.Fields, func(data string) bool { return data == "b" }) 81 require.True(ok) 82 require.Equal("b", data) 83 84 ok, data = FindFirst(tested.Fields, func(data string) bool { return data == "impossible" }) 85 require.False(ok) 86 require.Empty(data) 87 }) 88 89 t.Run("test FindFirst with naked slice", func(t *testing.T) { 90 fields := []string{"a", "b", "c"} 91 92 ok, data := FindFirst(Slice(fields), func(data string) bool { return data == "b" }) 93 require.True(ok) 94 require.Equal("b", data) 95 96 ok, data = FindFirst(Slice(fields), func(data string) bool { return data == "impossible" }) 97 require.False(ok) 98 require.Empty(data) 99 }) 100 } 101 102 func Test_FindData(t *testing.T) { 103 require := require.New(t) 104 105 t.Run("test FindFirstData with interface method", func(t *testing.T) { 106 var tested ITested1 = &tested1{fields: []string{"a", "b", "c"}} 107 108 ok, idx := FindFirstData(tested.Fields, "b") 109 require.True(ok) 110 require.Equal(1, idx) 111 112 ok, idx = FindFirstData(tested.Fields, "impossible") 113 require.False(ok) 114 require.Less(idx, 0) 115 }) 116 117 t.Run("test FindFirstData with structure method", func(t *testing.T) { 118 tested := tested1{fields: []string{"a", "b", "c"}} 119 120 ok, idx := FindFirstData(tested.Fields, "b") 121 require.True(ok) 122 require.Equal(1, idx) 123 124 ok, idx = FindFirstData(tested.Fields, "impossible") 125 require.False(ok) 126 require.Less(idx, 0) 127 }) 128 129 t.Run("test FindFirstData with naked slice", func(t *testing.T) { 130 fields := []string{"a", "b", "c"} 131 132 ok, idx := FindFirstData(Slice(fields), "b") 133 require.True(ok) 134 require.Equal(1, idx) 135 136 ok, idx = FindFirstData(Slice(fields), "impossible") 137 require.False(ok) 138 require.Less(idx, 0) 139 }) 140 } 141 142 func Test_FindFirstError(t *testing.T) { 143 require := require.New(t) 144 145 t.Run("test FindFirstError with interface method", func(t *testing.T) { 146 var tested ITested1 = &tested1{fields: []string{"a", "b", "c"}} 147 148 data, err := FindFirstError(tested.Fields, func(data string) error { 149 if data == "b" { 150 return fmt.Errorf("error at %v", data) 151 } 152 return nil 153 }) 154 require.Error(err) 155 require.Equal("b", data) 156 157 data, err = FindFirstError(tested.Fields, func(data string) error { 158 if data == "impossible" { 159 return fmt.Errorf("error at %v", data) 160 } 161 return nil 162 }) 163 require.NoError(err) 164 require.Empty(data) 165 }) 166 167 t.Run("test FindFirstError with structure method", func(t *testing.T) { 168 tested := tested1{fields: []string{"a", "b", "c"}} 169 170 data, err := FindFirstError(tested.Fields, func(data string) error { 171 if data == "b" { 172 return fmt.Errorf("error at %v", data) 173 } 174 return nil 175 }) 176 require.Error(err) 177 require.Equal("b", data) 178 179 data, err = FindFirstError(tested.Fields, func(data string) error { 180 if data == "impossible" { 181 return fmt.Errorf("error at %v", data) 182 } 183 return nil 184 }) 185 require.NoError(err) 186 require.Empty(data) 187 }) 188 189 t.Run("test FindFirstError with naked slice", func(t *testing.T) { 190 fields := []string{"a", "b", "c"} 191 192 data, err := FindFirstError(Slice(fields), func(data string) error { 193 if data == "b" { 194 return fmt.Errorf("error at %v", data) 195 } 196 return nil 197 }) 198 require.Error(err) 199 require.Equal("b", data) 200 201 data, err = FindFirstError(Slice(fields), func(data string) error { 202 if data == "impossible" { 203 return fmt.Errorf("error at %v", data) 204 } 205 return nil 206 }) 207 require.NoError(err) 208 require.Empty(data) 209 }) 210 } 211 212 type ( 213 ITested2 interface { 214 Fields(enum func(name string, data int)) 215 } 216 tested2 struct { 217 fields map[string]int 218 } 219 ) 220 221 func (s *tested2) Fields(enum func(name string, data int)) { 222 for name, data := range s.fields { 223 enum(name, data) 224 } 225 } 226 227 func Test_ForEachMap(t *testing.T) { 228 require := require.New(t) 229 230 t.Run("test ForEachMap with interface method", func(t *testing.T) { 231 var tested ITested2 = &tested2{fields: map[string]int{"a": 1, "b": 2, "c": 3}} 232 233 keys, values := "", 0 234 ForEachMap(tested.Fields, func(k string, v int) { keys += k; values += v }) 235 236 require.Len(keys, 3) 237 require.Contains(keys, "a") 238 require.Contains(keys, "b") 239 require.Contains(keys, "c") 240 241 require.Equal(1+2+3, values) 242 }) 243 244 t.Run("test ForEachMap with structure method", func(t *testing.T) { 245 tested := tested2{fields: map[string]int{"a": 1, "b": 2, "c": 3}} 246 247 keys, values := "", 0 248 ForEachMap(tested.Fields, func(k string, v int) { keys += k; values += v }) 249 250 require.Len(keys, 3) 251 require.Contains(keys, "a") 252 require.Contains(keys, "b") 253 require.Contains(keys, "c") 254 255 require.Equal(1+2+3, values) 256 }) 257 258 t.Run("test ForEachMap with naked map", func(t *testing.T) { 259 tested := map[string]int{"a": 1, "b": 2, "c": 3} 260 261 keys, values := "", 0 262 ForEachMap(Map(tested), func(k string, v int) { keys += k; values += v }) 263 264 require.Len(keys, 3) 265 require.Contains(keys, "a") 266 require.Contains(keys, "b") 267 require.Contains(keys, "c") 268 269 require.Equal(1+2+3, values) 270 }) 271 } 272 273 func Test_FindFirstMap(t *testing.T) { 274 require := require.New(t) 275 276 t.Run("test FindFirstMap with interface method", func(t *testing.T) { 277 var tested ITested2 = &tested2{fields: map[string]int{"a": 1, "b": 2, "c": 3}} 278 279 ok, key, value := FindFirstMap(tested.Fields, func(k string, _ int) bool { return k == "b" }) 280 require.True(ok) 281 require.Equal("b", key) 282 require.Equal(2, value) 283 284 ok, key, value = FindFirstMap(tested.Fields, func(k string, _ int) bool { return k == "impossible" }) 285 require.False(ok) 286 require.Empty(key) 287 require.Empty(value) 288 }) 289 290 t.Run("test FindFirstMap with structure method", func(t *testing.T) { 291 tested := tested2{fields: map[string]int{"a": 1, "b": 2, "c": 3}} 292 293 ok, key, value := FindFirstMap(tested.Fields, func(k string, _ int) bool { return k == "b" }) 294 require.True(ok) 295 require.Equal("b", key) 296 require.Equal(2, value) 297 298 ok, key, value = FindFirstMap(tested.Fields, func(k string, _ int) bool { return k == "impossible" }) 299 require.False(ok) 300 require.Empty(key) 301 require.Empty(value) 302 }) 303 304 t.Run("test FindFirstMap with naked map", func(t *testing.T) { 305 fields := map[string]int{"a": 1, "b": 2, "c": 3} 306 307 ok, key, value := FindFirstMap(Map(fields), func(k string, _ int) bool { return k == "b" }) 308 require.True(ok) 309 require.Equal("b", key) 310 require.Equal(2, value) 311 312 ok, key, value = FindFirstMap(Map(fields), func(k string, _ int) bool { return k == "impossible" }) 313 require.False(ok) 314 require.Empty(key) 315 require.Empty(value) 316 }) 317 } 318 319 func Test_FindFirstMapKey(t *testing.T) { 320 require := require.New(t) 321 322 t.Run("test FindFirstMapKey with interface method", func(t *testing.T) { 323 var tested ITested2 = &tested2{fields: map[string]int{"a": 1, "b": 2, "c": 3}} 324 325 ok, key, value := FindFirstMapKey(tested.Fields, "b") 326 require.True(ok) 327 require.Equal("b", key) 328 require.Equal(2, value) 329 330 ok, key, value = FindFirstMapKey(tested.Fields, "impossible") 331 require.False(ok) 332 require.Empty(key) 333 require.Empty(value) 334 }) 335 336 t.Run("test FindFirstMapKey with structure method", func(t *testing.T) { 337 tested := tested2{fields: map[string]int{"a": 1, "b": 2, "c": 3}} 338 339 ok, key, value := FindFirstMapKey(tested.Fields, "b") 340 require.True(ok) 341 require.Equal("b", key) 342 require.Equal(2, value) 343 344 ok, key, value = FindFirstMapKey(tested.Fields, "impossible") 345 require.False(ok) 346 require.Empty(key) 347 require.Empty(value) 348 }) 349 350 t.Run("test FindFirstMapKey with naked map", func(t *testing.T) { 351 fields := map[string]int{"a": 1, "b": 2, "c": 3} 352 353 ok, key, value := FindFirstMapKey(Map(fields), "b") 354 require.True(ok) 355 require.Equal("b", key) 356 require.Equal(2, value) 357 358 ok, key, value = FindFirstMapKey(Map(fields), "impossible") 359 require.False(ok) 360 require.Empty(key) 361 require.Empty(value) 362 }) 363 } 364 365 func Test_FindFirstMapError(t *testing.T) { 366 require := require.New(t) 367 368 t.Run("test FindFirstMapError with interface method", func(t *testing.T) { 369 var tested ITested2 = &tested2{fields: map[string]int{"a": 1, "b": 2, "c": 3}} 370 371 key, value, err := FindFirstMapError(tested.Fields, func(k string, v int) error { 372 if k == "b" { 373 return fmt.Errorf("error at %v: %v", k, v) 374 } 375 return nil 376 }) 377 require.Error(err) 378 require.Equal("b", key) 379 require.Equal(2, value) 380 381 key, value, err = FindFirstMapError(tested.Fields, func(k string, v int) error { 382 if k == "impossible" { 383 return fmt.Errorf("error at %v: %v", k, v) 384 } 385 return nil 386 }) 387 require.NoError(err) 388 require.Empty(key) 389 require.Empty(value) 390 }) 391 392 t.Run("test FindFirstMapError with structure method", func(t *testing.T) { 393 tested := tested2{fields: map[string]int{"a": 1, "b": 2, "c": 3}} 394 395 key, value, err := FindFirstMapError(tested.Fields, func(k string, v int) error { 396 if k == "b" { 397 return fmt.Errorf("error at %v: %v", k, v) 398 } 399 return nil 400 }) 401 require.Error(err) 402 require.Equal("b", key) 403 require.Equal(2, value) 404 405 key, value, err = FindFirstMapError(tested.Fields, func(k string, v int) error { 406 if k == "impossible" { 407 return fmt.Errorf("error at %v: %v", k, v) 408 } 409 return nil 410 }) 411 require.NoError(err) 412 require.Empty(key) 413 require.Empty(value) 414 }) 415 416 t.Run("test FindFirstMapError with naked map", func(t *testing.T) { 417 tested := map[string]int{"a": 1, "b": 2, "c": 3} 418 419 key, value, err := FindFirstMapError(Map(tested), func(k string, v int) error { 420 if k == "b" { 421 return fmt.Errorf("error at %v: %v", k, v) 422 } 423 return nil 424 }) 425 require.Error(err) 426 require.Equal("b", key) 427 require.Equal(2, value) 428 429 key, value, err = FindFirstMapError(Map(tested), func(k string, v int) error { 430 if k == "impossible" { 431 return fmt.Errorf("error at %v: %v", k, v) 432 } 433 return nil 434 }) 435 require.NoError(err) 436 require.Empty(key) 437 require.Empty(value) 438 }) 439 } 440 441 func TestForEachError(t *testing.T) { 442 require := require.New(t) 443 444 t.Run("no error", func(t *testing.T) { 445 err := ForEachError(func(enum func(str string)) { 446 enum("1") 447 }, func(s string) error { 448 require.Equal("1", s) 449 return nil 450 }) 451 require.NoError(err) 452 }) 453 454 t.Run("error", func(t *testing.T) { 455 testErr := errors.New("test error") 456 expected := "" 457 err := ForEachError(func(enum func(str string)) { 458 enum("1") 459 enum("2") 460 enum("3") 461 enum("4") 462 }, func(s string) error { 463 if s == "3" { 464 return testErr 465 } 466 expected += s 467 return nil 468 }) 469 require.ErrorIs(err, testErr) 470 require.Equal("12", expected) 471 }) 472 } 473 474 func TestForEachError1Arg(t *testing.T) { 475 require := require.New(t) 476 expectedArg1 := "expected str" 477 478 t.Run("no error", func(t *testing.T) { 479 err := ForEachError1Arg(func(arg1 string, enum func(str string)) { 480 enum("1") 481 require.Equal(expectedArg1, arg1) 482 }, expectedArg1, func(s string) error { 483 require.Equal("1", s) 484 return nil 485 }) 486 require.NoError(err) 487 }) 488 489 t.Run("error", func(t *testing.T) { 490 testErr := errors.New("test error") 491 expected := "" 492 err := ForEachError1Arg(func(arg1 string, enum func(str string)) { 493 enum("1") 494 enum("2") 495 enum("3") 496 enum("4") 497 require.Equal(expectedArg1, arg1) 498 }, expectedArg1, func(s string) error { 499 if s == "3" { 500 return testErr 501 } 502 expected += s 503 return nil 504 }) 505 require.ErrorIs(err, testErr) 506 require.Equal("12", expected) 507 }) 508 } 509 510 func TestForEachError2Values(t *testing.T) { 511 require := require.New(t) 512 513 t.Run("no error", func(t *testing.T) { 514 err := ForEachError2Values(func(enum func(v1 string, v2 int)) { 515 enum("str1", 42) 516 }, func(s string, i int) error { 517 require.Equal("str1", s) 518 require.Equal(42, i) 519 return nil 520 }) 521 require.NoError(err) 522 }) 523 524 t.Run("error", func(t *testing.T) { 525 testErr := errors.New("test error") 526 expectedSum := 0 527 err := ForEachError2Values(func(enum func(v1 string, v2 int)) { 528 enum("str1", 1) 529 enum("str2", 2) 530 enum("str3", 3) 531 enum("str4", 4) 532 }, func(s string, i int) error { 533 if i == 3 { 534 return testErr 535 } 536 require.Equal(fmt.Sprintf("str%d", i), s) 537 expectedSum += i 538 return nil 539 }) 540 require.ErrorIs(err, testErr) 541 require.Equal(3, expectedSum) 542 }) 543 }