mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Fix and enable testing stdlib Collection instances.
Top-level entry points fully testing a collection instance:
check${Traversal}Collection
One level of recursion into all slices of the collection instance
O(n^2). (Not combinatorial).
Previously, checkCollection() did nothing. So much of the testing infrastructure was inactive. Now it runs all forward collection tests.
Fixes a bug in subscriptRangeTests.
The UnsafeRawBufferPointer and Data collection testing is disabled and
will be fixed in the following commit.
This commit is contained in:
@@ -269,9 +269,57 @@ public func checkAdvancesAndDistances<Instances, Distances, BaseCollection>(
|
|||||||
% ('Expected: Collection', 'Expected.Iterator.Element', 'Expected'),
|
% ('Expected: Collection', 'Expected.Iterator.Element', 'Expected'),
|
||||||
% ('Element' , 'Element' , 'Array<Element>')]:
|
% ('Element' , 'Element' , 'Array<Element>')]:
|
||||||
|
|
||||||
|
// Top-level check for Collection instances. Alias for checkForwardCollection.
|
||||||
|
// Checks all slices: O(n^2).
|
||||||
|
public func checkCollection<${genericParam}, C : Collection>(
|
||||||
|
_ expected: ${Expected},
|
||||||
|
_ collection: C,
|
||||||
|
${TRACE},
|
||||||
|
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
|
||||||
|
sameValue: (${Element}, ${Element}) -> Bool
|
||||||
|
) where C.Iterator.Element == ${Element},
|
||||||
|
// FIXME(ABI) (Associated Types with where clauses): these constraints should be applied to
|
||||||
|
// associated types of Collection.
|
||||||
|
C.Indices.Iterator.Element == C.Index,
|
||||||
|
C.SubSequence : Collection,
|
||||||
|
C.SubSequence.Iterator.Element == ${Element},
|
||||||
|
C.SubSequence.Indices.Iterator.Element == C.Index,
|
||||||
|
C.SubSequence.Index == C.Index {
|
||||||
|
|
||||||
|
checkForwardCollection(expected, collection, message(),
|
||||||
|
stackTrace: stackTrace, showFrame: showFrame, file: file, line: line,
|
||||||
|
resiliencyChecks: resiliencyChecks,
|
||||||
|
sameValue: sameValue)
|
||||||
|
}
|
||||||
|
|
||||||
% for Traversal in TRAVERSALS:
|
% for Traversal in TRAVERSALS:
|
||||||
% TraversalCollection = collectionForTraversal(Traversal)
|
% TraversalCollection = collectionForTraversal(Traversal)
|
||||||
|
|
||||||
|
// Calls check${Traversal}Collection with default `sameValue`.
|
||||||
|
public func check${Traversal}Collection<
|
||||||
|
${genericParam}, C : ${TraversalCollection}
|
||||||
|
>(
|
||||||
|
_ expected: ${Expected}, _ collection: C,
|
||||||
|
${TRACE},
|
||||||
|
resiliencyChecks: CollectionMisuseResiliencyChecks = .all
|
||||||
|
) where
|
||||||
|
C.Iterator.Element == ${Element},
|
||||||
|
C.Indices.Iterator.Element == C.Index,
|
||||||
|
C.SubSequence : ${TraversalCollection},
|
||||||
|
C.SubSequence.Iterator.Element == ${Element},
|
||||||
|
C.SubSequence.Indices.Iterator.Element == C.Index,
|
||||||
|
C.SubSequence.Index == C.Index,
|
||||||
|
${Element} : Equatable {
|
||||||
|
|
||||||
|
check${Traversal}Collection(
|
||||||
|
expected, collection, ${trace},
|
||||||
|
resiliencyChecks: resiliencyChecks) { $0 == $1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top-Level check for all ${TraversalCollection} semantics on a single
|
||||||
|
// instance. This constrains SubSequence associated types in order to check
|
||||||
|
// slice semantics.
|
||||||
|
// Checks all slices: O(n^2).
|
||||||
public func check${Traversal}Collection<
|
public func check${Traversal}Collection<
|
||||||
${genericParam}, C : ${TraversalCollection}
|
${genericParam}, C : ${TraversalCollection}
|
||||||
>(
|
>(
|
||||||
@@ -281,6 +329,40 @@ public func check${Traversal}Collection<
|
|||||||
sameValue: (${Element}, ${Element}) -> Bool
|
sameValue: (${Element}, ${Element}) -> Bool
|
||||||
) where
|
) where
|
||||||
C.Iterator.Element == ${Element},
|
C.Iterator.Element == ${Element},
|
||||||
|
// FIXME(ABI) (Associated Types with where clauses): these constraints should be applied to
|
||||||
|
// associated types of Collection.
|
||||||
|
C.Indices.Iterator.Element == C.Index,
|
||||||
|
C.SubSequence : ${TraversalCollection},
|
||||||
|
C.SubSequence.Iterator.Element == ${Element},
|
||||||
|
C.SubSequence.Index == C.Index,
|
||||||
|
C.SubSequence.Indices.Iterator.Element == C.Index {
|
||||||
|
|
||||||
|
_checkOneLevelOf${Traversal}Collection(expected, collection, ${trace},
|
||||||
|
resiliencyChecks: resiliencyChecks, sameValue: sameValue)
|
||||||
|
|
||||||
|
_checkSliceableWith${Traversal}Index(expected, collection, ${trace},
|
||||||
|
resiliencyChecks: resiliencyChecks, sameValue: sameValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper for check${Traversal}Collection. Check that instance of `C`,
|
||||||
|
// `collection`, upholds the semantics of `${TraversalCollection}`,
|
||||||
|
// non-recursively. This does not check subsequences. It may be called for each
|
||||||
|
// subsequence without combinatorial explosion. Also, since recursive protocol
|
||||||
|
// contraints are not supported, our second level of checks cannot depend on the
|
||||||
|
// associated type properties of SubSequence.
|
||||||
|
//
|
||||||
|
// Checks all slices: O(n^2).
|
||||||
|
internal func _checkOneLevelOf${Traversal}Collection<
|
||||||
|
${genericParam}, C : ${TraversalCollection}
|
||||||
|
>(
|
||||||
|
_ expected: ${Expected}, _ collection: C,
|
||||||
|
${TRACE},
|
||||||
|
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
|
||||||
|
sameValue: (${Element}, ${Element}) -> Bool
|
||||||
|
) where
|
||||||
|
C.Iterator.Element == ${Element},
|
||||||
|
// FIXME(ABI) (Associated Types with where clauses): these constraints should be applied to
|
||||||
|
// associated types of Collection.
|
||||||
C.Indices.Iterator.Element == C.Index {
|
C.Indices.Iterator.Element == C.Index {
|
||||||
|
|
||||||
// A `Collection` is a multi-pass `Sequence`.
|
// A `Collection` is a multi-pass `Sequence`.
|
||||||
@@ -290,6 +372,10 @@ public func check${Traversal}Collection<
|
|||||||
resiliencyChecks: resiliencyChecks, sameValue: sameValue)
|
resiliencyChecks: resiliencyChecks, sameValue: sameValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===------------------------------------------------------------------===//
|
||||||
|
// Check Index semantics
|
||||||
|
//===------------------------------------------------------------------===//
|
||||||
|
|
||||||
let succ = { collection.index(after: $0) }
|
let succ = { collection.index(after: $0) }
|
||||||
% if Traversal != 'Forward':
|
% if Traversal != 'Forward':
|
||||||
let pred = { collection.index(before: $0) }
|
let pred = { collection.index(before: $0) }
|
||||||
@@ -356,9 +442,14 @@ public func check${Traversal}Collection<
|
|||||||
|
|
||||||
let expectedArray = Array(expected)
|
let expectedArray = Array(expected)
|
||||||
|
|
||||||
|
// Check `count`.
|
||||||
expectEqual(
|
expectEqual(
|
||||||
expectedArray.count.toIntMax(), collection.count.toIntMax(), ${trace})
|
expectedArray.count.toIntMax(), collection.count.toIntMax(), ${trace})
|
||||||
|
|
||||||
|
//===------------------------------------------------------------------===//
|
||||||
|
// Check Iteration behavior.
|
||||||
|
//===------------------------------------------------------------------===//
|
||||||
|
|
||||||
for _ in 0..<3 {
|
for _ in 0..<3 {
|
||||||
do {
|
do {
|
||||||
let startIndex = collection.startIndex
|
let startIndex = collection.startIndex
|
||||||
@@ -414,7 +505,7 @@ public func check${Traversal}Collection<
|
|||||||
expectedArray[i], collection[index], ${trace}, sameValue: sameValue)
|
expectedArray[i], collection[index], ${trace}, sameValue: sameValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
% end
|
% end # Traversal == "Bidirectional"
|
||||||
|
|
||||||
} // end of `if expectedArray.count >= 2`
|
} // end of `if expectedArray.count >= 2`
|
||||||
|
|
||||||
@@ -440,65 +531,57 @@ public func check${Traversal}Collection<
|
|||||||
// FIXME: more checks for bidirectional and random access collections.
|
// FIXME: more checks for bidirectional and random access collections.
|
||||||
}
|
}
|
||||||
|
|
||||||
public func check${Traversal}Collection<
|
// Helper for check${Traversal}Collection to check Slices.
|
||||||
${genericParam}, C : ${TraversalCollection}
|
//
|
||||||
|
// Checks all slices: O(n^2).
|
||||||
|
internal func _checkSliceableWith${Traversal}Index<
|
||||||
|
${genericParam}, S : ${TraversalCollection}
|
||||||
>(
|
>(
|
||||||
_ expected: ${Expected}, _ collection: C,
|
_ expected: ${Expected}, _ sliceable: S, ${TRACE},
|
||||||
${TRACE},
|
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
|
||||||
resiliencyChecks: CollectionMisuseResiliencyChecks = .all
|
sameValue: (${Element}, ${Element}) -> Bool
|
||||||
) where
|
|
||||||
C.Iterator.Element == ${Element},
|
|
||||||
C.Indices.Iterator.Element == C.Index,
|
|
||||||
${Element} : Equatable {
|
|
||||||
|
|
||||||
check${Traversal}Collection(
|
|
||||||
expected, collection, ${trace},
|
|
||||||
resiliencyChecks: resiliencyChecks) { $0 == $1 }
|
|
||||||
}
|
|
||||||
|
|
||||||
% end
|
|
||||||
|
|
||||||
// FIXME: merge into checkCollection()
|
|
||||||
public func checkSliceableWithBidirectionalIndex<
|
|
||||||
${genericParam}, S : BidirectionalCollection
|
|
||||||
>(
|
|
||||||
_ expected: ${Expected}, _ sliceable: S, ${TRACE}
|
|
||||||
) where
|
) where
|
||||||
S.Iterator.Element == ${Element},
|
S.Iterator.Element == ${Element},
|
||||||
S.Indices.Iterator.Element == S.Index,
|
S.SubSequence : ${TraversalCollection},
|
||||||
S.SubSequence : BidirectionalCollection,
|
|
||||||
S.SubSequence.Iterator.Element == ${Element},
|
S.SubSequence.Iterator.Element == ${Element},
|
||||||
S.SubSequence.Indices.Iterator.Element == S.SubSequence.Index,
|
S.SubSequence.Index == S.Index,
|
||||||
${Element} : Equatable {
|
S.SubSequence.Indices.Iterator.Element == S.Index {
|
||||||
|
|
||||||
// A `Sliceable` is a `Collection`.
|
|
||||||
checkBidirectionalCollection(expected, sliceable, ${trace})
|
|
||||||
|
|
||||||
let expectedArray = Array(expected)
|
let expectedArray = Array(expected)
|
||||||
|
|
||||||
let succ = { sliceable.index(after: $0) }
|
let succ = { sliceable.index(after: $0) }
|
||||||
|
% if Traversal != "Forward":
|
||||||
let pred = { sliceable.index(before: $0) }
|
let pred = { sliceable.index(before: $0) }
|
||||||
|
% end
|
||||||
|
|
||||||
var start = sliceable.startIndex
|
var start = sliceable.startIndex
|
||||||
for startNumericIndex in 0...expectedArray.count {
|
for startNumericIndex in 0...expectedArray.count {
|
||||||
|
% if Traversal != "Forward":
|
||||||
if start != sliceable.endIndex {
|
if start != sliceable.endIndex {
|
||||||
start = succ(start)
|
start = succ(start)
|
||||||
start = pred(start)
|
start = pred(start)
|
||||||
start = succ(start)
|
start = succ(start)
|
||||||
start = pred(start)
|
start = pred(start)
|
||||||
}
|
}
|
||||||
|
% end
|
||||||
var end = start
|
var end = start
|
||||||
for endNumericIndex in startNumericIndex...expectedArray.count {
|
for endNumericIndex in startNumericIndex...expectedArray.count {
|
||||||
|
% if Traversal != "Forward":
|
||||||
if end != sliceable.endIndex {
|
if end != sliceable.endIndex {
|
||||||
end = succ(end)
|
end = succ(end)
|
||||||
end = pred(end)
|
end = pred(end)
|
||||||
end = succ(end)
|
end = succ(end)
|
||||||
end = pred(end)
|
end = pred(end)
|
||||||
}
|
}
|
||||||
|
% end
|
||||||
let expectedSlice = expectedArray[startNumericIndex..<endNumericIndex]
|
let expectedSlice = expectedArray[startNumericIndex..<endNumericIndex]
|
||||||
let slice = sliceable[start..<end]
|
let slice = sliceable[start..<end]
|
||||||
|
//FIXME!!!: expectEqual(start, slice.startIndex)
|
||||||
|
//FIXME!!!: expectEqual(end, slice.endIndex)
|
||||||
|
|
||||||
checkBidirectionalCollection(expectedSlice, slice, ${trace})
|
_checkOneLevelOf${Traversal}Collection(expectedSlice, slice, ${trace},
|
||||||
|
resiliencyChecks: resiliencyChecks,
|
||||||
|
sameValue: sameValue)
|
||||||
|
|
||||||
if end != sliceable.endIndex {
|
if end != sliceable.endIndex {
|
||||||
end = succ(end)
|
end = succ(end)
|
||||||
@@ -510,9 +593,13 @@ public func checkSliceableWithBidirectionalIndex<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
% end
|
% end # Traversal
|
||||||
|
|
||||||
|
% end # genericParam, Elements, Expected
|
||||||
|
|
||||||
|
// Check RangeReplaceableCollection using a factory.
|
||||||
|
//
|
||||||
|
// Note: This does not invoke other collection tests.
|
||||||
public func checkRangeReplaceable<C, N>(
|
public func checkRangeReplaceable<C, N>(
|
||||||
_ makeCollection: @escaping () -> C,
|
_ makeCollection: @escaping () -> C,
|
||||||
_ makeNewValues: (Int) -> N
|
_ makeNewValues: (Int) -> N
|
||||||
@@ -574,13 +661,3 @@ public func checkRangeReplaceable<C, N>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func checkCollection<C : Collection, Expected : Collection>(
|
|
||||||
_ subject: C,
|
|
||||||
expected: Expected,
|
|
||||||
${TRACE},
|
|
||||||
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
|
|
||||||
sameValue: (Expected.Iterator.Element, Expected.Iterator.Element) -> Bool
|
|
||||||
) where C.Iterator.Element == Expected.Iterator.Element {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -120,85 +120,85 @@ public let subscriptRangeTests = [
|
|||||||
|
|
||||||
// Slice to the full extent.
|
// Slice to the full extent.
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 1010 ],
|
expected: [1010],
|
||||||
collection: [ 1010 ],
|
collection: [1010],
|
||||||
bounds: 0..<1,
|
bounds: 0..<1,
|
||||||
count: 1),
|
count: 1),
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 1010, 2020, 3030 ],
|
expected: [1010, 2020, 3030],
|
||||||
collection: [ 1010, 2020, 3030 ],
|
collection: [1010, 2020, 3030],
|
||||||
bounds: 0..<3,
|
bounds: 0..<3,
|
||||||
count: 3),
|
count: 3),
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 1010, 2020, 3030, 4040, 5050 ],
|
expected: [1010, 2020, 3030, 4040, 5050],
|
||||||
collection: [ 1010, 2020, 3030, 4040, 5050 ],
|
collection: [1010, 2020, 3030, 4040, 5050],
|
||||||
bounds: 0..<5,
|
bounds: 0..<5,
|
||||||
count: 5),
|
count: 5),
|
||||||
|
|
||||||
// Slice an empty prefix.
|
// Slice an empty prefix.
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [],
|
expected: [],
|
||||||
collection: [ 1010, 2020, 3030 ],
|
collection: [1010, 2020, 3030],
|
||||||
bounds: 0..<0,
|
bounds: 0..<0,
|
||||||
count: 3),
|
count: 3),
|
||||||
|
|
||||||
// Slice a prefix.
|
// Slice a prefix.
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 1010, 2020 ],
|
expected: [1010, 2020],
|
||||||
collection: [ 1010, 2020, 3030 ],
|
collection: [1010, 2020, 3030],
|
||||||
bounds: 0..<2,
|
bounds: 0..<2,
|
||||||
count: 3),
|
count: 3),
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 1010, 2020 ],
|
expected: [1010, 2020],
|
||||||
collection: [ 1010, 2020, 3030, 4040, 5050 ],
|
collection: [1010, 2020, 3030, 4040, 5050],
|
||||||
bounds: 0..<2,
|
bounds: 0..<2,
|
||||||
count: 5),
|
count: 5),
|
||||||
|
|
||||||
// Slice an empty suffix.
|
// Slice an empty suffix.
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [],
|
expected: [],
|
||||||
collection: [ 1010, 2020, 3030 ],
|
collection: [1010, 2020, 3030],
|
||||||
bounds: 3..<3,
|
bounds: 3..<3,
|
||||||
count: 3),
|
count: 3),
|
||||||
|
|
||||||
// Slice a suffix.
|
// Slice a suffix.
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 2020, 3030 ],
|
expected: [2020, 3030],
|
||||||
collection: [ 1010, 2020, 3030 ],
|
collection: [1010, 2020, 3030],
|
||||||
bounds: 1..<3,
|
bounds: 1..<3,
|
||||||
count: 3),
|
count: 3),
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 4040, 5050 ],
|
expected: [4040, 5050],
|
||||||
collection: [ 1010, 2020, 3030, 4040, 5050 ],
|
collection: [1010, 2020, 3030, 4040, 5050],
|
||||||
bounds: 3..<5,
|
bounds: 3..<5,
|
||||||
count: 5),
|
count: 5),
|
||||||
|
|
||||||
// Slice an empty range in the middle.
|
// Slice an empty range in the middle.
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [],
|
expected: [],
|
||||||
collection: [ 1010, 2020, 3030 ],
|
collection: [1010, 2020, 3030],
|
||||||
bounds: 1..<1,
|
bounds: 1..<1,
|
||||||
count: 3),
|
count: 3),
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [],
|
expected: [],
|
||||||
collection: [ 1010, 2020, 3030 ],
|
collection: [1010, 2020, 3030],
|
||||||
bounds: 2..<2,
|
bounds: 2..<2,
|
||||||
count: 3),
|
count: 3),
|
||||||
|
|
||||||
// Slice the middle part.
|
// Slice the middle part.
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 2020 ],
|
expected: [2020],
|
||||||
collection: [ 1010, 2020, 3030 ],
|
collection: [1010, 2020, 3030],
|
||||||
bounds: 1..<2,
|
bounds: 1..<2,
|
||||||
count: 3),
|
count: 3),
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 3030 ],
|
expected: [3030],
|
||||||
collection: [ 1010, 2020, 3030, 4040 ],
|
collection: [1010, 2020, 3030, 4040],
|
||||||
bounds: 3..<4,
|
bounds: 2..<3,
|
||||||
count: 4),
|
count: 4),
|
||||||
SubscriptRangeTest(
|
SubscriptRangeTest(
|
||||||
expected: [ 2020, 3030, 4040 ],
|
expected: [2020, 3030, 4040],
|
||||||
collection: [ 1010, 2020, 3030, 4040, 5050, 6060 ],
|
collection: [1010, 2020, 3030, 4040, 5050, 6060],
|
||||||
bounds: 1..<4,
|
bounds: 1..<4,
|
||||||
count: 6),
|
count: 6),
|
||||||
]
|
]
|
||||||
@@ -690,8 +690,8 @@ extension TestSuite {
|
|||||||
// TODO: swift-3-indexing-model: uncomment the following.
|
// TODO: swift-3-indexing-model: uncomment the following.
|
||||||
// FIXME: improve checkForwardCollection to check the SubSequence type.
|
// FIXME: improve checkForwardCollection to check the SubSequence type.
|
||||||
checkCollection(
|
checkCollection(
|
||||||
slice,
|
|
||||||
expected: test.expected.map(wrapValue),
|
expected: test.expected.map(wrapValue),
|
||||||
|
slice,
|
||||||
resiliencyChecks: .none) {
|
resiliencyChecks: .none) {
|
||||||
extractValue($0).value == extractValue($1).value
|
extractValue($0).value == extractValue($1).value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ ${Suite}.test("${ArrayType}/Sliceable/Enums") {
|
|||||||
do {
|
do {
|
||||||
let expected = [E.A, E.B, E.C, E.D]
|
let expected = [E.A, E.B, E.C, E.D]
|
||||||
let sliceable = ${ArrayType}(expected)
|
let sliceable = ${ArrayType}(expected)
|
||||||
checkSliceableWithBidirectionalIndex(expected, sliceable)
|
checkBidirectionalCollection(expected, sliceable)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -95,7 +95,7 @@ ${Suite}.test("${ArrayType}/Sliceable/Enums") {
|
|||||||
do {
|
do {
|
||||||
let expected = [[E.A, E.B], [E.B, E.C], [E.D], [E.A, E.B, E.D]]
|
let expected = [[E.A, E.B], [E.B, E.C], [E.D], [E.A, E.B, E.D]]
|
||||||
let sliceable = ${ArrayType}(expected)
|
let sliceable = ${ArrayType}(expected)
|
||||||
checkSliceableWithBidirectionalIndex(
|
checkBidirectionalCollection(
|
||||||
expected, sliceable, SourceLocStack().withCurrentLoc())
|
expected, sliceable, SourceLocStack().withCurrentLoc())
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -474,8 +474,8 @@ CollectionTypeTests.test("Collection.makeIterator()/DefaultImplementation") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkCollection(
|
checkCollection(
|
||||||
collection,
|
Array(1..<count+1).map(OpaqueValue.init) as [OpaqueValue<Int>],
|
||||||
expected: Array(1..<count+1).map(OpaqueValue.init) as [OpaqueValue<Int>]
|
collection
|
||||||
) { $0.value == $1.value }
|
) { $0.value == $1.value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -547,8 +547,8 @@ CollectionTypeTests.test("Collection.makeIterator()/CustomImplementation") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkCollection(
|
checkCollection(
|
||||||
|
Array(1..<count+1).map(OpaqueValue.init) as [OpaqueValue<Int>],
|
||||||
collection,
|
collection,
|
||||||
expected: Array(1..<count+1).map(OpaqueValue.init) as [OpaqueValue<Int>],
|
|
||||||
resiliencyChecks: .none) { $0.value == $1.value }
|
resiliencyChecks: .none) { $0.value == $1.value }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import StdlibCollectionUnittest
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
var DataTestSuite = TestSuite("Data")
|
var DataTestSuite = TestSuite("Data")
|
||||||
|
|
||||||
DataTestSuite.test("Data.Iterator semantics") {
|
DataTestSuite.test("Data.Iterator semantics") {
|
||||||
// Empty data
|
// Empty data
|
||||||
checkSequence([], Data())
|
checkSequence([], Data())
|
||||||
@@ -45,7 +46,10 @@ DataTestSuite.test("Data SubSequence") {
|
|||||||
let array: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7]
|
let array: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7]
|
||||||
var data = Data(bytes: array)
|
var data = Data(bytes: array)
|
||||||
|
|
||||||
checkRandomAccessCollection(array, data)
|
// FIXME: Iteration over Data slices is currently broken:
|
||||||
|
// [SR-4292] Foundation.Data.copyBytes is zero-based.
|
||||||
|
// Data.Iterator assumes it is not.
|
||||||
|
// checkRandomAccessCollection(array, data)
|
||||||
|
|
||||||
for i in 0..<data.count {
|
for i in 0..<data.count {
|
||||||
for j in i..<data.count {
|
for j in i..<data.count {
|
||||||
|
|||||||
@@ -83,8 +83,8 @@ SliceTests.test("${Slice}/init(base:bounds:)") {
|
|||||||
expectType(${Slice}<${Collection}<OpaqueValue<Int>>>.self, &slice)
|
expectType(${Slice}<${Collection}<OpaqueValue<Int>>>.self, &slice)
|
||||||
|
|
||||||
checkCollection(
|
checkCollection(
|
||||||
|
test.expected,
|
||||||
slice,
|
slice,
|
||||||
expected: test.expected,
|
|
||||||
stackTrace: SourceLocStack().with(test.loc))
|
stackTrace: SourceLocStack().with(test.loc))
|
||||||
{ $0.value == $1.value }
|
{ $0.value == $1.value }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1607,7 +1607,7 @@ func checkUTF8View(_ expected: [UInt8], _ subject: String,
|
|||||||
|
|
||||||
func checkUTF16View(_ expected: [UInt16], _ subject: String,
|
func checkUTF16View(_ expected: [UInt16], _ subject: String,
|
||||||
_ stackTrace: SourceLocStack) {
|
_ stackTrace: SourceLocStack) {
|
||||||
checkSliceableWithBidirectionalIndex(expected, subject.utf16)
|
checkBidirectionalCollection(expected, subject.utf16)
|
||||||
}
|
}
|
||||||
|
|
||||||
func forStringsWithUnpairedSurrogates(_ checkClosure: (UTF16Test, String) -> Void) {
|
func forStringsWithUnpairedSurrogates(_ checkClosure: (UTF16Test, String) -> Void) {
|
||||||
@@ -1848,7 +1848,7 @@ StringCookedViews.test("UnicodeScalars").forEach(in: utfTests) {
|
|||||||
test in
|
test in
|
||||||
|
|
||||||
let subject = NonContiguousNSString(test.utf32) as String
|
let subject = NonContiguousNSString(test.utf32) as String
|
||||||
checkSliceableWithBidirectionalIndex(
|
checkBidirectionalCollection(
|
||||||
test.unicodeScalars, subject.unicodeScalars)
|
test.unicodeScalars, subject.unicodeScalars)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1858,7 +1858,7 @@ StringCookedViews.test("UnicodeScalars/StringsWithUnpairedSurrogates") {
|
|||||||
let expectedScalars = (test.scalarsHead + test.scalarsRepairedTail).map {
|
let expectedScalars = (test.scalarsHead + test.scalarsRepairedTail).map {
|
||||||
UnicodeScalar($0)!
|
UnicodeScalar($0)!
|
||||||
}
|
}
|
||||||
checkSliceableWithBidirectionalIndex(
|
checkBidirectionalCollection(
|
||||||
expectedScalars, subject.unicodeScalars)
|
expectedScalars, subject.unicodeScalars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ func checkGraphemeClusterSegmentation(
|
|||||||
)
|
)
|
||||||
|
|
||||||
let expectedCharacters: [Character] = Array(subject.characters)
|
let expectedCharacters: [Character] = Array(subject.characters)
|
||||||
checkSliceableWithBidirectionalIndex(expectedCharacters, subject.characters)
|
checkBidirectionalCollection(expectedCharacters, subject.characters)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkGraphemeClusterSegmentation(
|
func checkGraphemeClusterSegmentation(
|
||||||
|
|||||||
@@ -475,15 +475,15 @@ ${SelfName}TestSuite.test("RandomAccessCollection") {
|
|||||||
defer { SubscriptGetTest.deallocateFor${'Raw' if IsRaw else ''}Buffer(
|
defer { SubscriptGetTest.deallocateFor${'Raw' if IsRaw else ''}Buffer(
|
||||||
memoryCopy, count: elementCount) }
|
memoryCopy, count: elementCount) }
|
||||||
|
|
||||||
var buffer = SubscriptGetTest.create${SelfName}(from: memory)
|
let buffer = SubscriptGetTest.create${SelfName}(from: memory)
|
||||||
var expected = UnsafeMutable${'Raw' if IsRaw else ''}BufferPointer(
|
let expected = UnsafeMutable${'Raw' if IsRaw else ''}BufferPointer(
|
||||||
start: memoryCopy, count: buffer.count)
|
start: memoryCopy, count: buffer.count)
|
||||||
|
|
||||||
% if IsRaw:
|
% if IsRaw:
|
||||||
expected.copyBytes(from: buffer)
|
expected.copyBytes(from: buffer)
|
||||||
checkRandomAccessCollection(expected, buffer) { $0 == $1 }
|
checkRandomAccessCollection(expected, buffer) { $0 == $1 }
|
||||||
% else:
|
% else:
|
||||||
expected.baseAddress!.initialize(from: buffer)
|
_ = expected.initialize(from: buffer)
|
||||||
checkRandomAccessCollection(expected, buffer) { $0.value == $1.value }
|
checkRandomAccessCollection(expected, buffer) { $0.value == $1.value }
|
||||||
% end
|
% end
|
||||||
}
|
}
|
||||||
@@ -542,15 +542,15 @@ ${SelfName}TestSuite.test("subscript/${RangeName}/get").forEach(in: subscriptGet
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
% end
|
% end # RangeName
|
||||||
|
% end # SelfName, IsMutable, IsRaw, SelfType, PointerType
|
||||||
% end
|
|
||||||
|
|
||||||
% for (SelfName, IsRaw) in [
|
% for (SelfName, IsRaw) in [
|
||||||
% ('UnsafeMutableBufferPointer', False),
|
% ('UnsafeMutableBufferPointer', False),
|
||||||
% ('UnsafeMutableRawBufferPointer', True)
|
% ('UnsafeMutableRawBufferPointer', True)
|
||||||
% ]:
|
% ]:
|
||||||
% for RangeName in ['range', 'countableRange', 'closedRange', 'countableClosedRange']:
|
% for RangeName in ['range', 'countableRange', 'closedRange', 'countableClosedRange']:
|
||||||
|
|
||||||
UnsafeMutable${'Raw' if IsRaw else ''}BufferPointerTestSuite.test("subscript/${RangeName}/set")
|
UnsafeMutable${'Raw' if IsRaw else ''}BufferPointerTestSuite.test("subscript/${RangeName}/set")
|
||||||
% if not IsRaw:
|
% if not IsRaw:
|
||||||
// UnsafeRawBuffer (currently) invokes Collection._failEarlyRangeCheck
|
// UnsafeRawBuffer (currently) invokes Collection._failEarlyRangeCheck
|
||||||
@@ -585,7 +585,7 @@ UnsafeMutable${'Raw' if IsRaw else ''}BufferPointerTestSuite.test("subscript/${R
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
% else:
|
% else: # !closed
|
||||||
expectedValues = test.expectedValues
|
expectedValues = test.expectedValues
|
||||||
replacementValues = test.replacementValues
|
replacementValues = test.replacementValues
|
||||||
let isOutOfBounds: () -> Bool = {
|
let isOutOfBounds: () -> Bool = {
|
||||||
@@ -596,7 +596,7 @@ UnsafeMutable${'Raw' if IsRaw else ''}BufferPointerTestSuite.test("subscript/${R
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
% end
|
% end # !closed
|
||||||
|
|
||||||
var memory = SubscriptSetTest.allocateFor${'Raw' if IsRaw else ''}Buffer(
|
var memory = SubscriptSetTest.allocateFor${'Raw' if IsRaw else ''}Buffer(
|
||||||
count: elementCount)
|
count: elementCount)
|
||||||
@@ -640,7 +640,9 @@ UnsafeMutable${'Raw' if IsRaw else ''}BufferPointerTestSuite.test("subscript/${R
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
% end # RangeName
|
% end # RangeName
|
||||||
|
|
||||||
% end # SelfName
|
% end # SelfName
|
||||||
|
|
||||||
UnsafeMutableRawBufferPointerTestSuite.test("changeElementViaBuffer") {
|
UnsafeMutableRawBufferPointerTestSuite.test("changeElementViaBuffer") {
|
||||||
|
|||||||
Reference in New Issue
Block a user