|
12 | 12 |
|
13 | 13 | import StdlibUnittest
|
14 | 14 |
|
| 15 | +// A minimal RRC conformance, to test default implementations with |
| 16 | +struct NaiveRRC : RangeReplaceableCollection, ExpressibleByArrayLiteral { |
| 17 | + |
| 18 | + // we're trying to move away from calling reserveCapacity inside most mutating |
| 19 | + // methods, this will let us verify that we don't |
| 20 | + internal var allowReserveCapacity = true |
| 21 | + var storage:[UInt8] = [] |
| 22 | + |
| 23 | + init() {} |
| 24 | + |
| 25 | + init(arrayLiteral elements: Element...) { |
| 26 | + storage.append(contentsOf: elements) |
| 27 | + } |
| 28 | + |
| 29 | + func index(after i: Int) -> Int { |
| 30 | + i + 1 |
| 31 | + } |
| 32 | + |
| 33 | + func index(before i: Int) -> Int { |
| 34 | + i - 1 |
| 35 | + } |
| 36 | + |
| 37 | + var startIndex: Int { |
| 38 | + 0 |
| 39 | + } |
| 40 | + |
| 41 | + var endIndex: Int { |
| 42 | + count |
| 43 | + } |
| 44 | + |
| 45 | + var count: Int { |
| 46 | + storage.count |
| 47 | + } |
| 48 | + |
| 49 | + subscript(position: Int) -> UInt8 { |
| 50 | + get { |
| 51 | + storage[position] |
| 52 | + } |
| 53 | + set(newValue) { |
| 54 | + storage[position] = newValue |
| 55 | + } |
| 56 | + } |
| 57 | + |
| 58 | + mutating func replaceSubrange(_ subrange: Range<Int>, with newElements: some Collection<UInt8>) { |
| 59 | + storage.replaceSubrange(subrange, with: newElements) |
| 60 | + } |
| 61 | + |
| 62 | + mutating func reserveCapacity(_ n: Int) { |
| 63 | + precondition(allowReserveCapacity) |
| 64 | + storage.reserveCapacity(n) |
| 65 | + } |
| 66 | +} |
| 67 | + |
15 | 68 | internal enum IndexSelection {
|
16 | 69 | case start
|
17 | 70 | case middle
|
@@ -264,6 +317,46 @@ let removeLastTests: [RemoveLastNTest] = [
|
264 | 317 | numberToRemove: 5,
|
265 | 318 | expectedCollection: []
|
266 | 319 | ),
|
| 320 | + RemoveLastNTest( |
| 321 | + collection: [1010] as NaiveRRC, |
| 322 | + numberToRemove: 0, |
| 323 | + expectedCollection: [1010] as NaiveRRC |
| 324 | + ), |
| 325 | + RemoveLastNTest( |
| 326 | + collection: [1010] as NaiveRRC, |
| 327 | + numberToRemove: 1, |
| 328 | + expectedCollection: [] as NaiveRRC |
| 329 | + ), |
| 330 | + RemoveLastNTest( |
| 331 | + collection: [1010, 2020, 3030, 4040, 5050] as NaiveRRC, |
| 332 | + numberToRemove: 0, |
| 333 | + expectedCollection: [1010, 2020, 3030, 4040, 5050] as NaiveRRC |
| 334 | + ), |
| 335 | + RemoveLastNTest( |
| 336 | + collection: [1010, 2020, 3030, 4040, 5050] as NaiveRRC, |
| 337 | + numberToRemove: 1, |
| 338 | + expectedCollection: [1010, 2020, 3030, 4040] as NaiveRRC |
| 339 | + ), |
| 340 | + RemoveLastNTest( |
| 341 | + collection: [1010, 2020, 3030, 4040, 5050] as NaiveRRC, |
| 342 | + numberToRemove: 2, |
| 343 | + expectedCollection: [1010, 2020, 3030] as NaiveRRC |
| 344 | + ), |
| 345 | + RemoveLastNTest( |
| 346 | + collection: [1010, 2020, 3030, 4040, 5050] as NaiveRRC, |
| 347 | + numberToRemove: 3, |
| 348 | + expectedCollection: [1010, 2020] as NaiveRRC |
| 349 | + ), |
| 350 | + RemoveLastNTest( |
| 351 | + collection: [1010, 2020, 3030, 4040, 5050] as NaiveRRC, |
| 352 | + numberToRemove: 4, |
| 353 | + expectedCollection: [1010] as NaiveRRC |
| 354 | + ), |
| 355 | + RemoveLastNTest( |
| 356 | + collection: [1010, 2020, 3030, 4040, 5050] as NaiveRRC, |
| 357 | + numberToRemove: 5, |
| 358 | + expectedCollection: [] as NaiveRRC |
| 359 | + ), |
267 | 360 | ]
|
268 | 361 |
|
269 | 362 | let appendContentsOfTests: [AppendContentsOfTest] = [
|
@@ -301,6 +394,78 @@ let appendContentsOfTests: [AppendContentsOfTest] = [
|
301 | 394 | collection: [1010, 2020, 3030, 4040],
|
302 | 395 | newElements: [5050, 6060, 7070, 8080],
|
303 | 396 | expected: [1010, 2020, 3030, 4040, 5050, 6060, 7070, 8080]),
|
| 397 | + |
| 398 | + // NaiveRRC doesn't implement withContiguousStorageIfAvailable, so this tests discontiguous appendees |
| 399 | + AppendContentsOfTest( |
| 400 | + collection: [] as NaiveRRC, |
| 401 | + newElements: [] as NaiveRRC, |
| 402 | + expected: [] as NaiveRRC), |
| 403 | + |
| 404 | + AppendContentsOfTest( |
| 405 | + collection: [1010] as NaiveRRC, |
| 406 | + newElements: [] as NaiveRRC, |
| 407 | + expected: [1010] as NaiveRRC), |
| 408 | + |
| 409 | + AppendContentsOfTest( |
| 410 | + collection: [1010, 2020, 3030, 4040] as NaiveRRC, |
| 411 | + newElements: [] as NaiveRRC, |
| 412 | + expected: [1010, 2020, 3030, 4040] as NaiveRRC), |
| 413 | + |
| 414 | + AppendContentsOfTest( |
| 415 | + collection: [] as NaiveRRC, |
| 416 | + newElements: [1010] as NaiveRRC, |
| 417 | + expected: [1010] as NaiveRRC), |
| 418 | + |
| 419 | + AppendContentsOfTest( |
| 420 | + collection: [1010] as NaiveRRC, |
| 421 | + newElements: [2020] as NaiveRRC, |
| 422 | + expected: [1010, 2020] as NaiveRRC), |
| 423 | + |
| 424 | + AppendContentsOfTest( |
| 425 | + collection: [1010] as NaiveRRC, |
| 426 | + newElements: [2020, 3030, 4040] as NaiveRRC, |
| 427 | + expected: [1010, 2020, 3030, 4040] as NaiveRRC), |
| 428 | + |
| 429 | + AppendContentsOfTest( |
| 430 | + collection: [1010, 2020, 3030, 4040] as NaiveRRC, |
| 431 | + newElements: [5050, 6060, 7070, 8080] as NaiveRRC, |
| 432 | + expected: [1010, 2020, 3030, 4040, 5050, 6060, 7070, 8080] as NaiveRRC), |
| 433 | + |
| 434 | + // Here we use Array to catch the contiguous cases |
| 435 | + AppendContentsOfTest( |
| 436 | + collection: [] as NaiveRRC, |
| 437 | + newElements: [], |
| 438 | + expected: [] as NaiveRRC), |
| 439 | + |
| 440 | + AppendContentsOfTest( |
| 441 | + collection: [1010] as NaiveRRC, |
| 442 | + newElements: [], |
| 443 | + expected: [1010] as NaiveRRC), |
| 444 | + |
| 445 | + AppendContentsOfTest( |
| 446 | + collection: [1010, 2020, 3030, 4040] as NaiveRRC, |
| 447 | + newElements: [], |
| 448 | + expected: [1010, 2020, 3030, 4040] as NaiveRRC), |
| 449 | + |
| 450 | + AppendContentsOfTest( |
| 451 | + collection: [] as NaiveRRC, |
| 452 | + newElements: [1010], |
| 453 | + expected: [1010] as NaiveRRC), |
| 454 | + |
| 455 | + AppendContentsOfTest( |
| 456 | + collection: [1010] as NaiveRRC, |
| 457 | + newElements: [2020], |
| 458 | + expected: [1010, 2020] as NaiveRRC), |
| 459 | + |
| 460 | + AppendContentsOfTest( |
| 461 | + collection: [1010] as NaiveRRC, |
| 462 | + newElements: [2020, 3030, 4040], |
| 463 | + expected: [1010, 2020, 3030, 4040] as NaiveRRC), |
| 464 | + |
| 465 | + AppendContentsOfTest( |
| 466 | + collection: [1010, 2020, 3030, 4040] as NaiveRRC, |
| 467 | + newElements: [5050, 6060, 7070, 8080], |
| 468 | + expected: [1010, 2020, 3030, 4040, 5050, 6060, 7070, 8080] as NaiveRRC), |
304 | 469 | ]
|
305 | 470 |
|
306 | 471 | // Also used in RangeReplaceable.swift.gyb to test `replaceSubrange()`
|
@@ -392,6 +557,8 @@ public let replaceRangeTests: [ReplaceSubrangeTest] = [
|
392 | 557 | rangeSelection: .offsets(1, 2),
|
393 | 558 | expected: [1010, 8080, 9090, 3030],
|
394 | 559 | closedExpected: [1010, 8080, 9090]),
|
| 560 | + |
| 561 | + //replaceSubrange is the protocol requirement, so we don't test NaiveRRC here |
395 | 562 | ]
|
396 | 563 |
|
397 | 564 | public let removeRangeTests: [RemoveSubrangeTest] = [
|
@@ -434,6 +601,46 @@ public let removeRangeTests: [RemoveSubrangeTest] = [
|
434 | 601 | collection: [1010, 2020, 3030, 4040, 5050, 6060],
|
435 | 602 | rangeSelection: .middle,
|
436 | 603 | expected: [1010, 6060]),
|
| 604 | + |
| 605 | + RemoveSubrangeTest( |
| 606 | + collection: [] as NaiveRRC), |
| 607 | + rangeSelection: .emptyRange, |
| 608 | + expected: []) as NaiveRRC), |
| 609 | + |
| 610 | + RemoveSubrangeTest( |
| 611 | + collection: [1010] as NaiveRRC), |
| 612 | + rangeSelection: .middle, |
| 613 | + expected: [] as NaiveRRC)), |
| 614 | + |
| 615 | + RemoveSubrangeTest( |
| 616 | + collection: [1010, 2020, 3030, 4040] as NaiveRRC), |
| 617 | + rangeSelection: .leftHalf, |
| 618 | + expected: [3030, 4040] as NaiveRRC)), |
| 619 | + |
| 620 | + RemoveSubrangeTest( |
| 621 | + collection: [1010, 2020, 3030, 4040] as NaiveRRC), |
| 622 | + rangeSelection: .rightHalf, |
| 623 | + expected: [1010, 2020] as NaiveRRC)), |
| 624 | + |
| 625 | + RemoveSubrangeTest( |
| 626 | + collection: [1010, 2020, 3030, 4040, 5050] as NaiveRRC), |
| 627 | + rangeSelection: .middle, |
| 628 | + expected: [1010, 5050] as NaiveRRC)), |
| 629 | + |
| 630 | + RemoveSubrangeTest( |
| 631 | + collection: [1010, 2020, 3030, 4040, 5050, 6060] as NaiveRRC), |
| 632 | + rangeSelection: .leftHalf, |
| 633 | + expected: [4040, 5050, 6060] as NaiveRRC)), |
| 634 | + |
| 635 | + RemoveSubrangeTest( |
| 636 | + collection: [1010, 2020, 3030, 4040, 5050, 6060] as NaiveRRC), |
| 637 | + rangeSelection: .rightHalf, |
| 638 | + expected: [1010, 2020, 3030] as NaiveRRC)), |
| 639 | + |
| 640 | + RemoveSubrangeTest( |
| 641 | + collection: [1010, 2020, 3030, 4040, 5050, 6060] as NaiveRRC), |
| 642 | + rangeSelection: .middle, |
| 643 | + expected: [1010, 6060] as NaiveRRC)), |
437 | 644 | ]
|
438 | 645 |
|
439 | 646 | extension TestSuite {
|
|
0 commit comments