@@ -482,13 +482,20 @@ internal func _product<C1 : Collection, C2 : Collection>(
482
482
checksAdded: Box<Set<String>> = Box([]),
483
483
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
484
484
outOfBoundsIndexOffset: Int = 1,
485
- outOfBoundsSubscriptOffset: Int = 1
485
+ outOfBoundsSubscriptOffset: Int = 1,
486
+ collectionIsBidirectional: Bool
486
487
'''
488
+
489
+ import re
490
+ forwardTestArgs = ',\n '.join(
491
+ [ x.group(1) + ': ' + x.group(1)
492
+ for x in re.finditer(r'([a-zA-Z0-9_]+):', testParams) ]
493
+ ).replace('testNamePrefix: ', '\n ')
487
494
}%
488
495
extension TestSuite {
489
496
public func addCollectionTests<
490
497
${testConstraints('Collection')}
491
- >(${testParams}) {
498
+ >(${testParams} = false ) {
492
499
var testNamePrefix = testNamePrefix
493
500
494
501
if checksAdded.value.contains(#function) {
@@ -1150,30 +1157,19 @@ extension TestSuite {
1150
1157
}
1151
1158
1152
1159
//===------------------------------------------------------------------===//
1153
-
1160
+ self.addCommonTests(${forwardTestArgs})
1154
1161
} // addCollectionTests
1155
1162
1156
1163
public func addBidirectionalCollectionTests<
1157
1164
${testConstraints('BidirectionalCollection')}
1158
- >(${testParams}) {
1165
+ >(${testParams} = true ) {
1159
1166
var testNamePrefix = testNamePrefix
1160
1167
if checksAdded.value.contains(#function) {
1161
1168
return
1162
1169
}
1163
1170
checksAdded.value.insert(#function)
1164
1171
1165
- addCollectionTests(
1166
- testNamePrefix,
1167
- makeCollection: makeCollection,
1168
- wrapValue: wrapValue,
1169
- extractValue: extractValue,
1170
- makeCollectionOfEquatable: makeCollectionOfEquatable,
1171
- wrapValueIntoEquatable: wrapValueIntoEquatable,
1172
- extractValueFromEquatable: extractValueFromEquatable,
1173
- checksAdded: checksAdded,
1174
- resiliencyChecks: resiliencyChecks,
1175
- outOfBoundsIndexOffset: outOfBoundsIndexOffset,
1176
- outOfBoundsSubscriptOffset: outOfBoundsSubscriptOffset)
1172
+ addCollectionTests(${forwardTestArgs})
1177
1173
1178
1174
func makeWrappedCollection(_ elements: [OpaqueValue<Int>]) -> C {
1179
1175
return makeCollection(elements.map(wrapValue))
@@ -1473,31 +1469,21 @@ extension TestSuite {
1473
1469
1474
1470
//===------------------------------------------------------------------===//
1475
1471
1472
+ self.addCommonTests(${forwardTestArgs})
1476
1473
} // addBidirectionalCollectionTests
1477
1474
1478
1475
public func addRandomAccessCollectionTests<
1479
1476
${testConstraints('RandomAccessCollection')}
1480
- >(${testParams}) {
1477
+ >(${testParams} = true ) {
1481
1478
var testNamePrefix = testNamePrefix
1482
1479
1483
1480
if checksAdded.value.contains(#function) {
1484
1481
return
1485
1482
}
1486
1483
checksAdded.value.insert(#function)
1487
1484
1488
- addBidirectionalCollectionTests(
1489
- testNamePrefix,
1490
- makeCollection: makeCollection,
1491
- wrapValue: wrapValue,
1492
- extractValue: extractValue,
1493
- makeCollectionOfEquatable: makeCollectionOfEquatable,
1494
- wrapValueIntoEquatable: wrapValueIntoEquatable,
1495
- extractValueFromEquatable: extractValueFromEquatable,
1496
- checksAdded: checksAdded,
1497
- resiliencyChecks: resiliencyChecks,
1498
- outOfBoundsIndexOffset: outOfBoundsIndexOffset,
1499
- outOfBoundsSubscriptOffset: outOfBoundsSubscriptOffset)
1500
-
1485
+ addBidirectionalCollectionTests(${forwardTestArgs})
1486
+
1501
1487
testNamePrefix += String(C.Type)
1502
1488
1503
1489
func makeWrappedCollection(_ elements: [OpaqueValue<Int>]) -> C {
@@ -1532,6 +1518,101 @@ extension TestSuite {
1532
1518
}
1533
1519
}
1534
1520
1535
- //===----------------------------------------------------------------------===//
1521
+ //===------------------------------------------------------------------===//
1522
+ self.addCommonTests(${forwardTestArgs})
1536
1523
} // addRandomAccessCollectionTests
1524
+
1525
+ % for Traversal in ['Forward', 'Bidirectional', 'RandomAccess']:
1526
+ func addCommonTests<
1527
+ ${testConstraints(collectionForTraversal(Traversal))}
1528
+ >(${testParams}) {
1529
+ if checksAdded.value.contains(#function) {
1530
+ return
1531
+ }
1532
+ checksAdded.value.insert(#function)
1533
+
1534
+ func toCollection(_ r: CountableRange<Int>) -> C {
1535
+ return makeCollection(r.map { wrapValue(OpaqueValue($0)) })
1536
+ }
1537
+
1538
+ self.test("\(testNamePrefix)/distance(from:to:)/semantics") {
1539
+ let c = toCollection(0..<20)
1540
+ for test in distanceFromToTests {
1541
+ let d = c.distance(
1542
+ from: c.nthIndex(test.startOffset), to: c.nthIndex(test.endOffset))
1543
+ expectEqual(
1544
+ numericCast(test.expectedDistance),
1545
+ d, stackTrace: SourceLocStack().with(test.loc))
1546
+ }
1547
+ }
1548
+
1549
+ self.test("\(testNamePrefix)/index(_:stepsFrom: n)/semantics") {
1550
+ for test in indexStepsFromTests.filter(
1551
+ {$0.limit == nil && $0.distance >= 0}
1552
+ ) {
1553
+ let c = toCollection(0..<10)
1554
+
1555
+ let new = c.index(
1556
+ c.nthIndex(test.startOffset),
1557
+ offsetBy: numericCast(test.distance))
1558
+
1559
+ // Since the `nthIndex(offset:)` method performs the same operation
1560
+ // (i.e. adavances `c.startIndex` by `test.distance`, it would be
1561
+ // silly to compare index values. Luckily the underlying collection
1562
+ // contains exactly index offsets.
1563
+ expectEqual(test.expectedOffset!, extractValue(c[new]).value,
1564
+ stackTrace: SourceLocStack().with(test.loc))
1565
+ }
1566
+ }
1567
+
1568
+ if !collectionIsBidirectional {
1569
+ self.test("\(testNamePrefix)/index(_:stepsFrom: -n)/semantics") {
1570
+ for test in indexStepsFromTests.filter(
1571
+ {$0.limit == nil && $0.distance < 0}
1572
+ ) {
1573
+ let c = toCollection(0..<10)
1574
+ let start = c.nthIndex(test.startOffset)
1575
+ expectCrashLater()
1576
+ _ = c.index(start, offsetBy: numericCast(test.distance))
1577
+ }
1578
+ }
1579
+ self.test("\(testNamePrefix)/advance(by: -n, limitedBy:)/semantics") {
1580
+ for test in indexStepsFromTests.filter(
1581
+ {$0.limit != nil && $0.distance < 0}
1582
+ ) {
1583
+ let c = toCollection(0..<10)
1584
+ let limit = c.nthIndex(test.limit.unsafelyUnwrapped)
1585
+ let start = c.nthIndex(test.startOffset)
1586
+ expectCrashLater()
1587
+ _ = c.index(
1588
+ start, offsetBy: numericCast(test.distance), limitedBy: limit)
1589
+ }
1590
+ }
1591
+ }
1592
+
1593
+ self.test("\(testNamePrefix)/advance(by: n, limitedBy:)/semantics") {
1594
+ for test in indexStepsFromTests.filter(
1595
+ {$0.limit != nil && $0.distance >= 0}
1596
+ ) {
1597
+ let c = toCollection(0..<20)
1598
+ let limit = c.nthIndex(test.limit.unsafelyUnwrapped)
1599
+
1600
+ if !collectionIsBidirectional && test.distance < 0 {
1601
+ expectCrashLater()
1602
+ }
1603
+
1604
+ let new = c.index(
1605
+ c.nthIndex(test.startOffset),
1606
+ offsetBy: numericCast(test.distance),
1607
+ limitedBy: limit)
1608
+ if test.expectedOffset == nil {
1609
+ expectEmpty(new)
1610
+ } else {
1611
+ expectEqual(c.nthIndex(test.expectedOffset!), new!,
1612
+ stackTrace: SourceLocStack().with(test.loc))
1613
+ }
1614
+ }
1615
+ }
1616
+ }
1617
+ % end
1537
1618
}
0 commit comments