mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[validation-test] Splitting Arrays.swift.gyb into multiple files
In order to parallelize tests more and avoid a single long running bottleneck. <rdar://problem/30269532>
This commit is contained in:
@@ -73,15 +73,6 @@ CopyToNativeArrayBufferTests.test("Collection._copyToContiguousArray()") {
|
||||
all_array_types = ['ContiguousArray', 'ArraySlice', 'Array']
|
||||
}%
|
||||
|
||||
%for Self in all_array_types:
|
||||
extension ${Self} {
|
||||
typealias _BufferID = UnsafeRawPointer?
|
||||
var _bufferID: _BufferID {
|
||||
return unsafeBitCast(_owner, to: _BufferID.self)
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
var ArrayTestSuite = TestSuite("Array")
|
||||
|
||||
ArrayTestSuite.test("sizeof") {
|
||||
@@ -125,246 +116,6 @@ ArrayTestSuite.test("Native/isEmpty") {
|
||||
expectFalse(a.isEmpty)
|
||||
}
|
||||
|
||||
protocol TestProtocol1 {}
|
||||
|
||||
% for array_type in all_array_types:
|
||||
|
||||
// Check that the generic parameter is called 'Element'.
|
||||
extension ${array_type} where Element : TestProtocol1 {
|
||||
var _elementIsTestProtocol1: Bool {
|
||||
fatalError("not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an ${array_type} that does not share its buffer with other arrays.
|
||||
func getFresh${array_type}<S : Sequence>(_ sequence: S)
|
||||
-> ${array_type}<S.Iterator.Element> {
|
||||
var result: ${array_type}<S.Iterator.Element> = []
|
||||
result.reserveCapacity(sequence.underestimatedCount)
|
||||
for element in sequence {
|
||||
result.append(element)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
enum EnumWithoutPayloads : Equatable {
|
||||
case A, B, C, D
|
||||
}
|
||||
|
||||
func == (lhs: EnumWithoutPayloads, rhs: EnumWithoutPayloads) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case (.A, .A), (.B, .B), (.C, .C), (.D, .D):
|
||||
return true
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
struct SequenceWithCustomUnderestimatedCount : Sequence {
|
||||
init(_ data: [Int]) {
|
||||
self._data = MinimalSequence(elements: data.map(OpaqueValue.init))
|
||||
}
|
||||
|
||||
func makeIterator() -> MinimalSequence<OpaqueValue<Int>>.Iterator {
|
||||
return _data.makeIterator()
|
||||
}
|
||||
|
||||
var underestimatedCount: Int {
|
||||
SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled += 1
|
||||
return _data.underestimatedCount
|
||||
}
|
||||
|
||||
static var timesUnderestimatedCountWasCalled: Int = 0
|
||||
|
||||
let _data: MinimalSequence<OpaqueValue<Int>>
|
||||
}
|
||||
|
||||
% for array_type in all_array_types:
|
||||
|
||||
ArrayTestSuite.test("${array_type}/init(Sequence)") {
|
||||
let base = SequenceWithCustomUnderestimatedCount(
|
||||
[ 0, 30, 10, 90 ])
|
||||
|
||||
SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled = 0
|
||||
|
||||
let result = ${array_type}(base)
|
||||
|
||||
expectEqual([ 0, 30, 10, 90 ], result.map { $0.value })
|
||||
|
||||
expectEqual(1, SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled)
|
||||
|
||||
expectEqualSequence(
|
||||
[], Array(base).map { $0.value }, "sequence should be consumed")
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/Sliceable/Enums") {
|
||||
typealias E = EnumWithoutPayloads
|
||||
|
||||
do {
|
||||
let expected = [E.A, E.B, E.C, E.D]
|
||||
let sliceable = ${array_type}(expected)
|
||||
checkSliceableWithBidirectionalIndex(expected, sliceable)
|
||||
}
|
||||
|
||||
/*
|
||||
FIXME: add this test when Array<T> can be conditionally Equatable.
|
||||
do {
|
||||
let expected = [[E.A, E.B], [E.B, E.C], [E.D], [E.A, E.B, E.D]]
|
||||
let sliceable = ${array_type}(expected)
|
||||
checkSliceableWithBidirectionalIndex(
|
||||
expected, sliceable, SourceLocStack().withCurrentLoc())
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/appendNonUnique") {
|
||||
var x: ${array_type}<Int> = []
|
||||
x.reserveCapacity(10002)
|
||||
let capacity = x.capacity
|
||||
for _ in 1...10000 {
|
||||
let y = x
|
||||
x.append(1)
|
||||
expectTrue(x.capacity == capacity)
|
||||
let z = x
|
||||
x.remove(at: 0)
|
||||
}
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/appendUndercountedCollection") {
|
||||
// test that the array safely handles a
|
||||
// collection that understates its count
|
||||
var i = 0
|
||||
let l = repeatElement(42, count: 10_000).lazy
|
||||
// capture i by reference and change behavior
|
||||
// between first pass (for count) and second
|
||||
.filter { _ in i += 1; return i > 10_000 }
|
||||
var a: ${array_type}<Int> = []
|
||||
a.append(contentsOf: l)
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/emptyAllocation") {
|
||||
let arr0 = ${array_type}<Int>()
|
||||
let arr1 = ${array_type}<LifetimeTracked>(repeating: LifetimeTracked(0), count: 0)
|
||||
// Empty arrays all use the same buffer
|
||||
expectEqual(arr0._bufferID, arr1._bufferID)
|
||||
|
||||
let arr2: ${array_type}<LifetimeTracked> = []
|
||||
let emptyLiteralsShareBuffer = arr0._bufferID == arr2._bufferID
|
||||
expectTrue(emptyLiteralsShareBuffer)
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/filter") {
|
||||
do {
|
||||
let arr: ${array_type}<Int> = []
|
||||
var result = arr.filter() {
|
||||
(x: Int) -> Bool in
|
||||
expectUnreachable()
|
||||
return true
|
||||
}
|
||||
expectType(Array<Int>.self, &result)
|
||||
expectEqual([], result)
|
||||
expectEqual(0, result.capacity)
|
||||
}
|
||||
do {
|
||||
let arr: ${array_type}<Int> = [ 0, 30, 10, 90 ]
|
||||
let result = arr.filter() { (x: Int) -> Bool in true }
|
||||
expectEqual([ 0, 30, 10, 90 ], result)
|
||||
expectGE(2 * result.count, result.capacity)
|
||||
}
|
||||
do {
|
||||
let arr: ${array_type}<Int> = [ 0, 30, 10, 90 ]
|
||||
let result = arr.filter() { (x: Int) -> Bool in false }
|
||||
expectEqual([], result)
|
||||
expectGE(2 * result.count, result.capacity)
|
||||
}
|
||||
do {
|
||||
let arr: ${array_type}<Int> = [ 0, 30, 10, 90 ]
|
||||
let result = arr.filter() { $0 % 3 == 0 }
|
||||
expectEqual([ 0, 30, 90 ], result)
|
||||
expectGE(2 * result.count, result.capacity)
|
||||
}
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/map") {
|
||||
do {
|
||||
let arr: ${array_type}<Int> = []
|
||||
var result = arr.map() {
|
||||
(x: Int) -> Int16 in
|
||||
expectUnreachable()
|
||||
return 42
|
||||
}
|
||||
expectType(Array<Int16>.self, &result)
|
||||
expectEqual([], result)
|
||||
expectEqual(0, result.capacity)
|
||||
}
|
||||
do {
|
||||
let arr: ${array_type}<Int> = [ 0, 30, 10, 90 ]
|
||||
let result = arr.map() { $0 + 1 }
|
||||
expectEqual([ 1, 31, 11, 91 ], result)
|
||||
expectGE(2 * result.count, result.capacity)
|
||||
}
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/flatMap") {
|
||||
let enumerate : (Int) -> ${array_type}<Int> =
|
||||
{ return ${array_type}(1..<($0 + 1)) }
|
||||
expectEqualSequence([], ${array_type}().flatMap(enumerate))
|
||||
expectEqualSequence([ 1 ], ${array_type}([ 1 ]).flatMap(enumerate))
|
||||
expectEqualSequence(
|
||||
[ 1, 1, 2 ],
|
||||
${array_type}([ 1, 2 ]).flatMap(enumerate))
|
||||
expectEqualSequence(
|
||||
[ 1, 1, 1, 2 ],
|
||||
${array_type}([ 1, 2 ]).flatMap(enumerate).flatMap(enumerate))
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/Mirror") {
|
||||
do {
|
||||
let input: ${array_type}<Int> = []
|
||||
var output = ""
|
||||
dump(input, to: &output)
|
||||
|
||||
let expected =
|
||||
"- 0 elements\n"
|
||||
|
||||
expectEqual(expected, output)
|
||||
}
|
||||
do {
|
||||
let input: ${array_type}<Int> = [ 10, 20, 30, 40 ]
|
||||
var output = ""
|
||||
dump(input, to: &output)
|
||||
|
||||
let expected =
|
||||
"▿ 4 elements\n" +
|
||||
" - 10\n" +
|
||||
" - 20\n" +
|
||||
" - 30\n" +
|
||||
" - 40\n"
|
||||
|
||||
expectEqual(expected, output)
|
||||
}
|
||||
% if array_type == 'ArraySlice':
|
||||
do {
|
||||
let base = [ 10, 20, 30, 40 ]
|
||||
let input: ArraySlice<Int> = base[1..<3]
|
||||
var output = ""
|
||||
dump(input, to: &output)
|
||||
|
||||
let expected =
|
||||
"▿ 2 elements\n" +
|
||||
" - 20\n" +
|
||||
" - 30\n"
|
||||
|
||||
expectEqual(expected, output)
|
||||
}
|
||||
% end
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
% for Kind in ['Array', 'ContiguousArray']:
|
||||
ArrayTestSuite.test("${Kind}/popLast") {
|
||||
// Empty
|
||||
@@ -420,135 +171,6 @@ ArrayTestSuite.test("ArraySlice/removeFirst") {
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// _withUnsafeMutableBufferPointerIfSupported()
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
struct WithUnsafeMutableBufferPointerIfSupportedTest {
|
||||
let sequence: [Int]
|
||||
let loc: SourceLoc
|
||||
|
||||
init(
|
||||
_ sequence: [Int],
|
||||
file: String = #file, line: UInt = #line
|
||||
) {
|
||||
self.sequence = sequence
|
||||
self.loc = SourceLoc(file, line, comment: "test data")
|
||||
}
|
||||
}
|
||||
|
||||
let withUnsafeMutableBufferPointerIfSupportedTests = [
|
||||
WithUnsafeMutableBufferPointerIfSupportedTest([]),
|
||||
WithUnsafeMutableBufferPointerIfSupportedTest([ 10 ]),
|
||||
WithUnsafeMutableBufferPointerIfSupportedTest([ 10, 20, 30, 40, 50 ]),
|
||||
]
|
||||
|
||||
% for array_type in all_array_types:
|
||||
|
||||
ArrayTestSuite.test("${array_type}/_withUnsafeMutableBufferPointerIfSupported") {
|
||||
for test in withUnsafeMutableBufferPointerIfSupportedTests {
|
||||
var a = getFresh${array_type}(test.sequence.map(OpaqueValue.init))
|
||||
do {
|
||||
// Read.
|
||||
var result = a._withUnsafeMutableBufferPointerIfSupported {
|
||||
(baseAddress, count) -> OpaqueValue<[OpaqueValue<Int>]> in
|
||||
let bufferPointer =
|
||||
UnsafeMutableBufferPointer(start: baseAddress, count: count)
|
||||
return OpaqueValue(Array(bufferPointer))
|
||||
}
|
||||
expectType(Optional<OpaqueValue<Array<OpaqueValue<Int>>>>.self, &result)
|
||||
expectEqualSequence(test.sequence, result!.value.map { $0.value })
|
||||
expectEqualSequence(test.sequence, a.map { $0.value })
|
||||
}
|
||||
do {
|
||||
// Read and write.
|
||||
var result = a._withUnsafeMutableBufferPointerIfSupported {
|
||||
(baseAddress, count) -> OpaqueValue<Array<OpaqueValue<Int>>> in
|
||||
let bufferPointer =
|
||||
UnsafeMutableBufferPointer(start: baseAddress, count: count)
|
||||
let result = OpaqueValue(Array(bufferPointer))
|
||||
for i in bufferPointer.indices {
|
||||
bufferPointer[i] = OpaqueValue(bufferPointer[i].value * 10)
|
||||
}
|
||||
return result
|
||||
}
|
||||
expectType(Optional<OpaqueValue<Array<OpaqueValue<Int>>>>.self, &result)
|
||||
expectEqualSequence(test.sequence, result!.value.map { $0.value })
|
||||
expectEqualSequence(
|
||||
test.sequence.map { $0 * 10 },
|
||||
a.map { $0.value })
|
||||
}
|
||||
}
|
||||
// FIXME: tests for arrays bridged from Objective-C.
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/_withUnsafeMutableBufferPointerIfSupported/ReplacingTheBufferTraps/1") {
|
||||
var a = getFresh${array_type}([ OpaqueValue(10) ])
|
||||
var result = a._withUnsafeMutableBufferPointerIfSupported {
|
||||
(baseAddress, count) -> OpaqueValue<Int> in
|
||||
// buffer = UnsafeMutableBufferPointer(start: buffer.baseAddress, count: 0)
|
||||
// FIXME: does not trap since the buffer is not passed inout.
|
||||
// expectCrashLater()
|
||||
return OpaqueValue(42)
|
||||
}
|
||||
}
|
||||
|
||||
ArrayTestSuite.test("${array_type}/_withUnsafeMutableBufferPointerIfSupported/ReplacingTheBufferTraps/2") {
|
||||
var a = getFresh${array_type}([ OpaqueValue(10) ])
|
||||
var result = a._withUnsafeMutableBufferPointerIfSupported {
|
||||
(baseAddress, count) -> OpaqueValue<Int> in
|
||||
// buffer = UnsafeMutableBufferPointer(start: nil, count: 1)
|
||||
// FIXME: does not trap since the buffer is not passed inout.
|
||||
// expectCrashLater()
|
||||
return OpaqueValue(42)
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// withUnsafeMutableBytes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Test the uniqueness of the raw buffer.
|
||||
ArrayTestSuite.test("${array_type}/withUnsafeMutableBytes") {
|
||||
var a = getFresh${array_type}([UInt8](repeating: 10, count: 1))
|
||||
let b = a
|
||||
a.withUnsafeMutableBytes { bytes in
|
||||
bytes[0] = 42
|
||||
}
|
||||
expectEqual(42, a[0])
|
||||
expectEqual(10, b[0])
|
||||
}
|
||||
|
||||
//===---
|
||||
// Check that iterators traverse a snapshot of the collection.
|
||||
//===---
|
||||
|
||||
ArrayTestSuite.test(
|
||||
"${array_type}/mutationDoesNotAffectIterator/subscript/store") {
|
||||
var arr: ${array_type}<Int> = [ 1010, 1020, 1030 ]
|
||||
var iter = arr.makeIterator()
|
||||
arr[0] = 1011
|
||||
expectEqual([ 1010, 1020, 1030 ], Array(IteratorSequence(iter)))
|
||||
}
|
||||
|
||||
ArrayTestSuite.test(
|
||||
"${array_type}/mutationDoesNotAffectIterator/subscript/append") {
|
||||
var arr: ${array_type}<Int> = [ 1010, 1020, 1030 ]
|
||||
var iter = arr.makeIterator()
|
||||
arr.append(1040)
|
||||
expectEqual([ 1010, 1020, 1030 ], Array(IteratorSequence(iter)))
|
||||
}
|
||||
|
||||
ArrayTestSuite.test(
|
||||
"${array_type}/mutationDoesNotAffectIterator/subscript/replaceSubrange") {
|
||||
var arr: ${array_type}<Int> = [ 1010, 1020, 1030 ]
|
||||
var iter = arr.makeIterator()
|
||||
arr.replaceSubrange(1..<3, with: [ 1040, 1050, 1060 ])
|
||||
expectEqual([ 1010, 1020, 1030 ], Array(IteratorSequence(iter)))
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Array and EvilCollection that changes its size while we are not looking
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -755,50 +377,6 @@ for (step, evilBoundsCheck) in [ (1, true), (-1, false), (-1, true) ] {
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Special cases and one-off tests.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
% for array_type in all_array_types:
|
||||
|
||||
ArrayTestSuite.test("${array_type}<Void>/map") {
|
||||
// This code used to crash because it generated an array of Void with
|
||||
// stride == 0.
|
||||
do {
|
||||
let input: ${array_type}<Void> = [ (), (), () ]
|
||||
let result = input.map { (_) -> Void in return () }
|
||||
expectEqual(3, result.count)
|
||||
}
|
||||
|
||||
do {
|
||||
let input: ${array_type}<OpaqueValue<Int>> = [
|
||||
OpaqueValue(10), OpaqueValue(20), OpaqueValue(30)
|
||||
]
|
||||
let result = input.map { (_) -> Void in return () }
|
||||
expectEqual(3, result.count)
|
||||
}
|
||||
}
|
||||
|
||||
% end
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MutableCollectionType and RangeReplaceableCollectionType conformance tests.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
% for array_type in all_array_types:
|
||||
ArrayTestSuite.test("${array_type}/AssociatedTypes") {
|
||||
typealias Collection = ${array_type}<OpaqueValue<Int>>
|
||||
typealias CollectionSlice = ArraySlice<OpaqueValue<Int>>
|
||||
expectCollectionAssociatedTypes(
|
||||
collectionType: Collection.self,
|
||||
iteratorType: IndexingIterator<Collection>.self,
|
||||
subSequenceType: CollectionSlice.self,
|
||||
indexType: Int.self,
|
||||
indexDistanceType: Int.self,
|
||||
indicesType: CountableRange<Int>.self)
|
||||
}
|
||||
% end
|
||||
|
||||
func ArraySliceWithNonZeroStartIndex<T>(_ elements: [T]) -> ArraySlice<T> {
|
||||
var r = ArraySlice<T>(_startIndex: 1000)
|
||||
r.append(contentsOf: elements)
|
||||
|
||||
Reference in New Issue
Block a user