Files
swift-mirror/validation-test/stdlib/Arrays.swift.gyb
Saleem Abdulrasool 1c41c0887c validation-test: adjust stdlib tests for Windows
The embedded shell script in the RUN command for lit is problematic for
non-sh shell environments (i.e. Windows).  This adjusts the tests to
uniformly build the code for the ObjC runtime.  However, the Objective-C
code is only built under the same circumstances that it is currently
enabled - the availability of the needed frameworks.  The empty object
on other runtimes will have no material impact.  The swift side of it
checks whether the runtime is built with ObjC interop.  This allows us
to largely use the same command line for all the targets.  The last
missing piece is that the `-fobjc-runtime` requires that we run a modern
ObjC runtime.  We enable this unconditionally in lit for the non-Apple
targets.

This improves the validation test coverage for the standard library on
Windows.
2019-06-03 08:36:22 -07:00

2550 lines
64 KiB
Swift

// RUN: %empty-directory(%t)
//
// RUN: %gyb %s -o %t/main.swift
// RUN: %target-clang -fobjc-arc %S/Inputs/SlurpFastEnumeration/SlurpFastEnumeration.m -c -o %t/SlurpFastEnumeration.o
// RUN: %line-directive %t/main.swift -- %target-build-swift %t/main.swift %S/Inputs/ArrayTypesAndHelpers.swift -I %S/Inputs/SlurpFastEnumeration/ -Xlinker %t/SlurpFastEnumeration.o -o %t/Arrays -Xfrontend -disable-access-control
//
// RUN: %target-codesign %t/Arrays && %line-directive %t/main.swift -- %target-run %t/Arrays
// REQUIRES: executable_test
import Swift
import StdlibUnittest
import StdlibCollectionUnittest
#if _runtime(_ObjC)
import Foundation
import StdlibUnittestFoundationExtras
#endif
let CopyToNativeArrayBufferTests = TestSuite("CopyToNativeArrayBufferTests")
extension Array {
func _rawIdentifier() -> Int {
return unsafeBitCast(self, to: Int.self)
}
}
CopyToNativeArrayBufferTests.test("Sequence._copyToContiguousArray()") {
do {
// Call from a static context.
let s =
MinimalSequence(elements: LifetimeTracked(10)..<LifetimeTracked(27))
expectEqual(0, s.timesMakeIteratorCalled.value)
let copy = s._copyToContiguousArray()
expectEqual(1, s.timesMakeIteratorCalled.value)
expectEqualSequence(
Array(10..<27),
copy.map { $0.value })
}
do {
// Call from a generic context.
let wrapped = MinimalSequence(elements: LifetimeTracked(10)..<LifetimeTracked(27))
let s = LoggingSequence(wrapping: wrapped)
expectEqual(0, wrapped.timesMakeIteratorCalled.value)
let copy = s._copyToContiguousArray()
expectEqual(1, wrapped.timesMakeIteratorCalled.value)
expectEqualSequence(
Array(10..<27),
copy.map { $0.value })
}
}
CopyToNativeArrayBufferTests.test("Collection._copyToContiguousArray()") {
// Check that collections are handled with the collection-specific API. This
// means that we are calling the right default implementation (one for
// collections, not the one for sequences).
do {
// Call from a static context.
let c =
DefaultedCollection(elements: LifetimeTracked(10)..<LifetimeTracked(27))
expectEqual(0, c.timesMakeIteratorCalled.value)
expectEqual(0, c.timesStartIndexCalled.value)
let copy = c._copyToContiguousArray()
// _copyToContiguousArray calls Sequence._copyContents, which makes an iterator.
expectEqual(1, c.timesMakeIteratorCalled.value)
expectNotEqual(0, c.timesStartIndexCalled.value)
expectEqualSequence(
Array(10..<27),
copy.map { $0.value })
}
do {
// Call from a generic context.
let wrapped =
DefaultedCollection(elements: LifetimeTracked(10)..<LifetimeTracked(27))
let s = LoggingSequence(wrapping: wrapped)
expectEqual(0, wrapped.timesMakeIteratorCalled.value)
expectEqual(0, wrapped.timesStartIndexCalled.value)
let copy = s._copyToContiguousArray()
// _copyToContiguousArray calls Sequence._copyContents, which makes an iterator.
expectEqual(1, wrapped.timesMakeIteratorCalled.value)
expectNotEqual(0, wrapped.timesStartIndexCalled.value)
expectEqualSequence(
Array(10..<27),
copy.map { $0.value })
}
}
%{
all_array_types = ['ContiguousArray', 'ArraySlice', 'Array']
}%
var ArrayTestSuite = TestSuite("Array")
ArrayTestSuite.test("sizeof") {
var a = [ 10, 20, 30 ]
#if arch(i386) || arch(arm)
expectEqual(4, MemoryLayout.size(ofValue: a))
#else
expectEqual(8, MemoryLayout.size(ofValue: a))
#endif
}
ArrayTestSuite.test("valueDestruction") {
var a = [LifetimeTracked]()
for i in 100...110 {
a.append(LifetimeTracked(i))
}
}
ArrayTestSuite.test("capacity/reserveCapacity(_:)") {
var a1 = [1010, 1020, 1030]
expectGE(a1.capacity, 3)
a1.append(1040)
expectGT(a1.capacity, 3)
// Reserving new capacity jumps up to next limit.
a1.reserveCapacity(7)
expectGE(a1.capacity, 7)
// Can reserve right up to a limit.
a1.reserveCapacity(24)
expectGE(a1.capacity, 24)
// Fill up to the limit, no reallocation.
for v in stride(from: 50, through: 240, by: 10).lazy.map({ 1000 + $0 }) {
a1.append(v)
}
expectEqual(24, a1.count)
expectGE(a1.capacity, 24)
a1.append(1250)
expectGT(a1.capacity, 24)
}
ArrayTestSuite.test("init(arrayLiteral:)") {
do {
let empty = Array<Int>()
expectEqual(0, empty.count)
}
do {
let a = Array(arrayLiteral: 1010)
expectEqual(1, a.count)
expectEqual(1010, a[0])
}
do {
let a = Array(arrayLiteral: 1010, 1020)
expectEqual(2, a.count)
expectEqual(1010, a[0])
expectEqual(1020, a[1])
}
do {
let a = Array(arrayLiteral: 1010, 1020, 1030)
expectEqual(3, a.count)
expectEqual(1010, a[0])
expectEqual(1020, a[1])
expectEqual(1030, a[2])
}
do {
let a = Array(arrayLiteral: 1010, 1020, 1030, 1040)
expectEqual(4, a.count)
expectEqual(1010, a[0])
expectEqual(1020, a[1])
expectEqual(1030, a[2])
expectEqual(1040, a[3])
}
do {
let a: Array<Int> = [ 1010, 1020, 1030 ]
expectEqual(3, a.count)
expectEqual(1010, a[0])
expectEqual(1020, a[1])
expectEqual(1030, a[2])
}
}
ArrayTestSuite.test("init(repeating:count:)") {
do {
let a = Array(repeating: 1010, count: 5)
expectEqual(a.count, 5)
expectEqual(1010, a[0])
expectEqual(1010, a[1])
expectEqual(1010, a[2])
expectEqual(1010, a[3])
expectEqual(1010, a[4])
}
}
ArrayTestSuite.test("Hashable") {
let a1: [Array<Int>] = [
[1, 2, 3],
[1, 3, 2],
[3, 1, 2],
[1, 2],
[1],
[],
[1, 1, 1]
]
checkHashable(a1, equalityOracle: { $0 == $1 })
let a2: [Array<Array<Int>>] = [
[[], [1], [1, 2], [2, 1]],
[[], [1], [2, 1], [2, 1]],
[[1], [], [2, 1], [2, 1]],
[[1], [], [2, 1], [2]],
[[1], [], [2, 1]]
]
checkHashable(a2, equalityOracle: { $0 == $1 })
// These arrays share the same sequence of leaf integers, but they must
// still all hash differently.
let a3: [Array<Array<Int>>] = [
// Grouping changes must perturb the hash.
[[1], [2], [3], [4], [5]],
[[1, 2], [3], [4], [5]],
[[1], [2, 3], [4], [5]],
[[1], [2], [3, 4], [5]],
[[1], [2], [3], [4, 5]],
[[1, 2, 3], [4], [5]],
[[1], [2, 3, 4], [5]],
[[1], [2], [3, 4, 5]],
[[1, 2, 3, 4], [5]],
[[1], [2, 3, 4, 5]],
[[1, 2], [3, 4], [5]],
[[1], [2, 3], [4, 5]],
[[1, 2, 3, 4, 5]],
// Empty arrays must perturb the hash.
[[], [1], [2], [3], [4], [5]],
[[1], [], [2], [3], [4], [5]],
[[1], [2], [3], [4], [5], []],
[[1], [], [], [2], [3], [], [4], [], [5]],
]
checkHashable(a3, equalityOracle: { $0 == $1 })
}
#if _runtime(_ObjC)
//===----------------------------------------------------------------------===//
// NSArray -> Array bridging tests.
//===----------------------------------------------------------------------===//
ArrayTestSuite.test("BridgedFromObjC.Verbatim.ArrayIsCopied") {
var (a, nsa) = getBridgedVerbatimArrayAndNSMutableArray()
expectTrue(isCocoaArray(a))
// Find an existing value.
do {
let v = a[0] as! TestObjCValueTy
expectEqual(1010, v.value)
}
// Remove the value from the NSMutableArray.
nsa.removeObject(at: 0)
// Find an existing value, again.
do {
let v = a[0] as! TestObjCValueTy
expectEqual(1010, v.value)
}
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.ArrayIsCopied") {
var (a, nsa) = getBridgedNonverbatimArrayAndNSMutableArray()
expectTrue(isNativeArray(a))
// Find an existing value.
do {
let v = a[0]
expectEqual(1010, v.value)
}
// Remove the value from the NSMutableArray.
nsa.removeObject(at: 0)
// Find an existing value, again.
do {
let v = a[0]
expectEqual(1010, v.value)
}
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.NSArrayIsRetained") {
let nsa: NSArray = autoreleasepool {
NSArray(array: getAsNSArray([1010, 1020, 1030]))
}
let a: [AnyObject] = convertNSArrayToArray(nsa)
let bridgedBack: NSArray = convertArrayToNSArray(a)
expectEqual(
unsafeBitCast(nsa, to: Int.self),
unsafeBitCast(bridgedBack, to: Int.self))
_blackHole(nsa)
_blackHole(a)
_blackHole(bridgedBack)
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.NSArrayIsCopied") {
let nsa: NSArray = autoreleasepool {
NSArray(array: getAsNSArray([1010, 1020, 1030]))
}
let a: [TestBridgedValueTy] = convertNSArrayToArray(nsa)
let bridgedBack: NSArray = convertArrayToNSArray(a)
expectNotEqual(
unsafeBitCast(nsa, to: Int.self),
unsafeBitCast(bridgedBack, to: Int.self))
_blackHole(nsa)
_blackHole(a)
_blackHole(bridgedBack)
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.ImmutableArrayIsRetained") {
let nsa: NSArray = CustomImmutableNSArray(_privateInit: ())
CustomImmutableNSArray.timesCopyWithZoneWasCalled = 0
CustomImmutableNSArray.timesObjectAtIndexWasCalled = 0
CustomImmutableNSArray.timesObjectEnumeratorWasCalled = 0
CustomImmutableNSArray.timesCountWasCalled = 0
let a: [AnyObject] = convertNSArrayToArray(nsa)
expectEqual(1, CustomImmutableNSArray.timesCopyWithZoneWasCalled)
expectEqual(0, CustomImmutableNSArray.timesObjectAtIndexWasCalled)
expectEqual(0, CustomImmutableNSArray.timesObjectEnumeratorWasCalled)
expectEqual(0, CustomImmutableNSArray.timesCountWasCalled)
let bridgedBack: NSArray = convertArrayToNSArray(a)
expectEqual(
unsafeBitCast(nsa, to: Int.self),
unsafeBitCast(bridgedBack, to: Int.self))
_blackHole(nsa)
_blackHole(a)
_blackHole(bridgedBack)
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.ImmutableArrayIsCopied") {
let nsa: NSArray = CustomImmutableNSArray(_privateInit: ())
CustomImmutableNSArray.timesCopyWithZoneWasCalled = 0
CustomImmutableNSArray.timesObjectAtIndexWasCalled = 0
CustomImmutableNSArray.timesObjectEnumeratorWasCalled = 0
CustomImmutableNSArray.timesCountWasCalled = 0
TestBridgedValueTy.bridgeOperations = 0
let a: [TestBridgedValueTy] = convertNSArrayToArray(nsa)
//FIXME: Why is this copied?
expectEqual(1, CustomImmutableNSArray.timesCopyWithZoneWasCalled)
expectEqual(3, CustomImmutableNSArray.timesObjectAtIndexWasCalled)
expectNotEqual(0, CustomImmutableNSArray.timesCountWasCalled)
expectEqual(3, TestBridgedValueTy.bridgeOperations)
let bridgedBack: NSArray = convertArrayToNSArray(a)
expectNotEqual(
unsafeBitCast(nsa, to: Int.self),
unsafeBitCast(bridgedBack, to: Int.self))
_blackHole(nsa)
_blackHole(a)
_blackHole(bridgedBack)
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.Subscript") {
let a = getBridgedVerbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isCocoaArray(a))
// Find an existing value.
do {
var v = a[0]
expectEqual(1010, (v as! TestObjCValueTy).value)
v = a[1]
expectEqual(1020, (v as! TestObjCValueTy).value)
v = a[2]
expectEqual(1030, (v as! TestObjCValueTy).value)
}
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.Subscript") {
var a = getBridgedNonverbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isNativeArray(a))
// Find an existing value.
do {
var v = a[0]
expectEqual(1010, v.value)
v = a[1]
expectEqual(1020, v.value)
v = a[2]
expectEqual(1030, v.value)
}
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.RemoveAt") {
var a = getBridgedVerbatimArray()
let identity = a._rawIdentifier()
expectTrue(isCocoaArray(a))
let index = 0
expectEqual(1010, (a[index] as! TestObjCValueTy).value)
expectEqual(identity, a._rawIdentifier())
let removedElement = a.remove(at: index)
expectNotEqual(identity, a._rawIdentifier())
expectTrue(isNativeArray(a))
expectEqual(1010, (removedElement as! TestObjCValueTy).value)
expectEqual(2, a.count)
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAt") {
var a = getBridgedNonverbatimArray()
let identity = a._rawIdentifier()
expectTrue(isNativeArray(a))
let index = 0
expectEqual(1010, a[index].value)
expectEqual(identity, a._rawIdentifier())
let removedElement = a.remove(at: index)
expectEqual(identity, a._rawIdentifier())
expectTrue(isNativeArray(a))
expectEqual(1010, removedElement.value)
expectEqual(2, a.count)
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") {
do {
var a = getBridgedVerbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isCocoaArray(a))
let originalCapacity = a.count
expectEqual(3, a.count)
expectEqual(1010, (a[0] as! TestObjCValueTy).value)
a.removeAll()
expectNotEqual(identity1, a._rawIdentifier())
expectLT(a._buffer.capacity, originalCapacity)
expectEqual(0, a.count)
}
do {
var a = getBridgedVerbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isCocoaArray(a))
let originalCapacity = a.count
expectEqual(3, a.count)
expectEqual(1010, (a[0] as! TestObjCValueTy).value)
a.removeAll(keepingCapacity: true)
expectNotEqual(identity1, a._rawIdentifier())
expectGE(a._buffer.capacity, originalCapacity)
expectEqual(0, a.count)
}
do {
var a1 = getBridgedVerbatimArray()
let identity1 = a1._rawIdentifier()
expectTrue(isCocoaArray(a1))
let originalCapacity = a1.count
expectEqual(3, a1.count)
expectEqual(1010, (a1[0] as! TestObjCValueTy).value)
var a2 = a1
a2.removeAll()
let identity2 = a2._rawIdentifier()
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity2, identity1)
expectEqual(3, a1.count)
expectEqual(1010, (a1[0] as! TestObjCValueTy).value)
expectLT(a2._buffer.capacity, originalCapacity)
expectEqual(0, a2.count)
}
do {
var a1 = getBridgedVerbatimArray()
let identity1 = a1._rawIdentifier()
expectTrue(isCocoaArray(a1))
let originalCapacity = a1.count
expectEqual(3, a1.count)
expectEqual(1010, (a1[0] as! TestObjCValueTy).value)
var a2 = a1
a2.removeAll(keepingCapacity: true)
let identity2 = a2._rawIdentifier()
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity2, identity1)
expectEqual(3, a1.count)
expectEqual(1010, (a1[0] as! TestObjCValueTy).value)
expectGE(a2._buffer.capacity, originalCapacity)
expectEqual(0, a2.count)
}
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") {
do {
var a = getBridgedNonverbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isNativeArray(a))
let originalCapacity = a.count
expectEqual(3, a.count)
expectEqual(1010, a[0].value)
a.removeAll()
expectNotEqual(identity1, a._rawIdentifier())
expectLT(a._buffer.capacity, originalCapacity)
expectEqual(0, a.count)
}
do {
var a = getBridgedNonverbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isNativeArray(a))
let originalCapacity = a.count
expectEqual(3, a.count)
expectEqual(1010, a[0].value)
a.removeAll(keepingCapacity: true)
expectEqual(identity1, a._rawIdentifier())
expectGE(a._buffer.capacity, originalCapacity)
expectEqual(0, a.count)
}
do {
var a1 = getBridgedNonverbatimArray()
let identity1 = a1._rawIdentifier()
expectTrue(isNativeArray(a1))
let originalCapacity = a1.count
expectEqual(3, a1.count)
expectEqual(1010, a1[0].value)
var a2 = a1
a2.removeAll()
let identity2 = a2._rawIdentifier()
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity2, identity1)
expectEqual(3, a1.count)
expectEqual(1010, a1[0].value)
expectLT(a2._buffer.capacity, originalCapacity)
expectEqual(0, a2.count)
}
do {
var a1 = getBridgedNonverbatimArray()
let identity1 = a1._rawIdentifier()
expectTrue(isNativeArray(a1))
let originalCapacity = a1.count
expectEqual(3, a1.count)
expectEqual(1010, a1[0].value)
var a2 = a1
a2.removeAll(keepingCapacity: true)
let identity2 = a2._rawIdentifier()
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity2, identity1)
expectEqual(3, a1.count)
expectEqual(1010, a1[0].value)
expectGE(a2._buffer.capacity, originalCapacity)
expectEqual(0, a2.count)
}
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.Count") {
let a = getBridgedVerbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isCocoaArray(a))
expectEqual(3, a.count)
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.Count") {
let a = getBridgedNonverbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isNativeArray(a))
expectEqual(3, a.count)
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.Generate") {
let a = getBridgedVerbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isCocoaArray(a))
var iter = a.makeIterator()
var values = Array<Int>()
while let value = iter.next() {
values.append((value as! TestObjCValueTy).value)
}
expectEqual(values, [1010, 1020, 1030])
expectNil(iter.next())
expectNil(iter.next())
expectNil(iter.next())
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.Generate") {
let a = getBridgedNonverbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isNativeArray(a))
var iter = a.makeIterator()
var values = Array<Int>()
while let value = iter.next() {
values.append(value.value)
}
expectEqual(values, [1010, 1020, 1030])
expectNil(iter.next())
expectNil(iter.next())
expectNil(iter.next())
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.Generate_Empty") {
let a = getBridgedVerbatimArray([])
let identity1 = a._rawIdentifier()
expectTrue(isCocoaArray(a))
var iter = a.makeIterator()
expectNil(iter.next())
expectNil(iter.next())
expectNil(iter.next())
expectNil(iter.next())
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.Generate_Empty") {
let a = getBridgedNonverbatimArray([])
let identity1 = a._rawIdentifier()
expectTrue(isNativeArray(a))
var iter = a.makeIterator()
expectNil(iter.next())
expectNil(iter.next())
expectNil(iter.next())
expectNil(iter.next())
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.Generate_Huge") {
let a = getHugeBridgedVerbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isCocoaArray(a))
var iter = a.makeIterator()
var values = Array<Int>()
while let value = iter.next() {
values.append((value as! TestObjCValueTy).value)
}
var expectedValues = Array<Int>()
for i in 1...32 {
expectedValues += [1000 + i]
}
expectEqual(values, expectedValues)
expectNil(iter.next())
expectNil(iter.next())
expectNil(iter.next())
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.Generate_Huge") {
let a = getHugeBridgedNonverbatimArray()
let identity1 = a._rawIdentifier()
expectTrue(isNativeArray(a))
var iter = a.makeIterator()
var values = Array<Int>()
while let value = iter.next() {
values.append(value.value)
}
var expectedValues = Array<Int>()
for i in 1...32 {
expectedValues += [1000 + i]
}
expectEqual(values, expectedValues)
expectNil(iter.next())
expectNil(iter.next())
expectNil(iter.next())
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.EqualityTest_Empty") {
let a1 = getBridgedVerbatimEquatableArray([])
let identity1 = a1._rawIdentifier()
expectTrue(isCocoaArray(a1))
let a2 = getBridgedVerbatimEquatableArray([])
let identity2 = a2._rawIdentifier()
expectTrue(isCocoaArray(a2))
// We can't check that `identity1 != identity2` because Foundation might be
// returning the same singleton NSArray for empty arrays.
expectEqual(a1, a2)
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity2, a2._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.EqualityTest_Empty") {
var a1 = getBridgedNonverbatimEquatableArray([])
a1.append(TestBridgedEquatableValueTy(1))
a1.removeLast()
let identity1 = a1._rawIdentifier()
expectTrue(isNativeArray(a1))
let a2 = getBridgedNonverbatimEquatableArray([])
let identity2 = a2._rawIdentifier()
expectTrue(isNativeArray(a2))
expectNotEqual(identity1, identity2)
expectEqual(a1, a2)
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity2, a2._rawIdentifier())
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.EqualityTest_Small") {
func helper(_ na1: Array<Int>, _ na2: Array<Int>, _ expectedEq: Bool) {
let a1 = getBridgedVerbatimEquatableArray(na1)
let identity1 = a1._rawIdentifier()
expectTrue(isCocoaArray(a1))
var a2 = getBridgedVerbatimEquatableArray(na2)
var identity2 = a2._rawIdentifier()
expectTrue(isCocoaArray(a2))
do {
let eq1 = (a1 == a2)
expectEqual(eq1, expectedEq)
let eq2 = (a2 == a1)
expectEqual(eq2, expectedEq)
let neq1 = (a1 != a2)
expectNotEqual(neq1, expectedEq)
let neq2 = (a2 != a1)
expectNotEqual(neq2, expectedEq)
}
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity2, a2._rawIdentifier())
a2.append(TestObjCEquatableValueTy(1111))
a2.removeLast()
expectTrue(isNativeArray(a2))
expectNotEqual(identity2, a2._rawIdentifier())
identity2 = a2._rawIdentifier()
do {
let eq1 = (a1 == a2)
expectEqual(eq1, expectedEq)
let eq2 = (a2 == a1)
expectEqual(eq2, expectedEq)
let neq1 = (a1 != a2)
expectNotEqual(neq1, expectedEq)
let neq2 = (a2 != a1)
expectNotEqual(neq2, expectedEq)
}
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity2, a2._rawIdentifier())
}
helper([], [], true)
helper([1010],
[1010],
true)
helper([1010, 1020],
[1010, 1020],
true)
helper([1010, 1020, 1030],
[1010, 1020, 1030],
true)
helper([1010, 1020, 1030],
[1010, 1020, 1111],
false)
helper([1010, 1020, 1030],
[1010, 1020],
false)
helper([1010, 1020, 1030],
[1010],
false)
helper([1010, 1020, 1030],
[],
false)
helper([1010, 1020, 1030],
[1010, 1020, 1030, 1040],
false)
}
//===---
// Array -> NSArray bridging tests.
//
// Values are bridged verbatim.
//===---
ArrayTestSuite.test("BridgedToObjC.Verbatim.Count") {
let d = getBridgedNSArrayOfRefTypesBridgedVerbatim()
expectEqual(3, d.count)
}
ArrayTestSuite.test("BridgedToObjC.Verbatim.ObjectForKey") {
let a = getBridgedNSArrayOfRefTypesBridgedVerbatim()
var v: AnyObject? = a.object(at: 0) as AnyObject
expectEqual(1010, (v as! TestObjCValueTy).value)
let idValue10 = unsafeBitCast(v, to: UInt.self)
v = a.object(at: 1) as AnyObject
expectEqual(1020, (v as! TestObjCValueTy).value)
let idValue20 = unsafeBitCast(v, to: UInt.self)
v = a.object(at: 2) as AnyObject
expectEqual(1030, (v as! TestObjCValueTy).value)
let idValue30 = unsafeBitCast(v, to: UInt.self)
for _ in 0..<3 {
expectEqual(idValue10, unsafeBitCast(
a.object(at: 0) as AnyObject, to: UInt.self))
expectEqual(idValue20, unsafeBitCast(
a.object(at: 1) as AnyObject, to: UInt.self))
expectEqual(idValue30, unsafeBitCast(
a.object(at: 2) as AnyObject, to: UInt.self))
}
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Verbatim.KeyEnumerator.NextObject") {
let a = getBridgedNSArrayOfRefTypesBridgedVerbatim()
var capturedIdentities = Array<UInt>()
for _ in 0..<3 {
let enumerator = a.objectEnumerator()
var values = Array<Int>()
var identities = Array<UInt>()
while let value = enumerator.nextObject() {
let valueObj = (value as! TestObjCValueTy)
values.append(valueObj.value)
let identity = unsafeBitCast(valueObj, to: UInt.self)
identities.append(identity)
}
expectEqual([ 1010, 1020, 1030 ], values)
if capturedIdentities.isEmpty {
capturedIdentities = identities
} else {
expectEqual(capturedIdentities, identities)
}
expectNil(enumerator.nextObject())
expectNil(enumerator.nextObject())
expectNil(enumerator.nextObject())
}
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Verbatim.ObjectEnumerator.NextObject_Empty") {
let a = getBridgedEmptyNSArray()
let enumerator = a.objectEnumerator()
expectNil(enumerator.nextObject())
expectNil(enumerator.nextObject())
expectNil(enumerator.nextObject())
}
ArrayTestSuite.test("BridgedToObjC.Verbatim.ObjectEnumerator.FastEnumeration.UseFromSwift") {
let a = getBridgedNSArrayOfRefTypesBridgedVerbatim()
checkArrayFastEnumerationFromSwift(
[ 1010, 1020, 1030 ],
a, { a.objectEnumerator() },
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Verbatim.ObjectEnumerator.FastEnumeration.UseFromObjC") {
let a = getBridgedNSArrayOfRefTypesBridgedVerbatim()
checkArrayFastEnumerationFromObjC(
[ 1010, 1020, 1030 ],
a, { a.objectEnumerator() },
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Verbatim.ObjectEnumerator.FastEnumeration_Empty") {
let a = getBridgedEmptyNSArray()
checkArrayFastEnumerationFromSwift(
[], a, { a.objectEnumerator() },
{ ($0 as! TestObjCValueTy).value })
checkArrayFastEnumerationFromObjC(
[], a, { a.objectEnumerator() },
{ ($0 as! TestObjCValueTy).value })
}
ArrayTestSuite.test("BridgedToObjC.Verbatim.FastEnumeration.UseFromSwift") {
let a = getBridgedNSArrayOfRefTypesBridgedVerbatim()
checkArrayFastEnumerationFromSwift(
[ 1010, 1020, 1030 ],
a, { a },
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Verbatim.FastEnumeration.UseFromObjC") {
let a = getBridgedNSArrayOfRefTypesBridgedVerbatim()
checkArrayFastEnumerationFromObjC(
[ 1010, 1020, 1030 ],
a, { a },
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Verbatim.FastEnumeration_Empty") {
let a = getBridgedEmptyNSArray()
checkArrayFastEnumerationFromSwift(
[], a, { a },
{ ($0 as! TestObjCValueTy).value })
checkArrayFastEnumerationFromObjC(
[], a, { a },
{ ($0 as! TestObjCValueTy).value })
}
//===---
// Array -> NSArray bridging tests.
//
// Values are bridged non-verbatim.
//===---
ArrayTestSuite.test("BridgedToObjC.KeyValue_ValueTypesCustomBridged") {
let a = getBridgedNSArrayOfObjValue_ValueTypesCustomBridged()
let enumerator = a.objectEnumerator()
var values = Array<Int>()
while let valueObj = enumerator.nextObject() {
let value: AnyObject = valueObj as AnyObject
let v = (value as! TestObjCValueTy).value
values.append(v)
}
expectEqual([ 1010, 1020, 1030 ], values)
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Custom.ObjectEnumerator.FastEnumeration.UseFromSwift") {
let a = getBridgedNSArrayOfObjValue_ValueTypesCustomBridged()
checkArrayFastEnumerationFromSwift(
[ 1010, 1020, 1030 ],
a, { a.objectEnumerator() },
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Custom.ObjectEnumerator.FastEnumeration.UseFromSwift.Partial") {
let a = getBridgedNSArrayOfObjValue_ValueTypesCustomBridged(
numElements: 9)
checkArrayEnumeratorPartialFastEnumerationFromSwift(
[ 1010, 1020, 1030, 1040, 1050,
1060, 1070, 1080, 1090 ],
a, maxFastEnumerationItems: 5,
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 9)
}
ArrayTestSuite.test("BridgedToObjC.Custom.ObjectEnumerator.FastEnumeration.UseFromObjC") {
let a = getBridgedNSArrayOfObjValue_ValueTypesCustomBridged()
checkArrayFastEnumerationFromObjC(
[ 1010, 1020, 1030 ],
a, { a.objectEnumerator() },
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Custom.FastEnumeration.UseFromSwift") {
let a = getBridgedNSArrayOfObjValue_ValueTypesCustomBridged()
checkArrayFastEnumerationFromSwift(
[ 1010, 1020, 1030 ],
a, { a },
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Custom.FastEnumeration.UseFromObjC") {
let a = getBridgedNSArrayOfObjValue_ValueTypesCustomBridged()
checkArrayFastEnumerationFromObjC(
[ 1010, 1020, 1030 ],
a, { a },
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Custom.FastEnumeration_Empty") {
let a = getBridgedNSArrayOfObjValue_ValueTypesCustomBridged(
numElements: 0)
checkArrayFastEnumerationFromSwift(
[], a, { a },
{ ($0 as! TestObjCValueTy).value })
checkArrayFastEnumerationFromObjC(
[], a, { a },
{ ($0 as! TestObjCValueTy).value })
}
ArrayTestSuite.test("BridgedToObjC.Key_ValueTypeCustomBridged") {
let a = getBridgedNSArrayOfObj_ValueTypeCustomBridged()
let enumerator = a.objectEnumerator()
var values = Array<Int>()
while let valueObj = enumerator.nextObject() {
let value: AnyObject = valueObj as AnyObject
let v = (value as! TestObjCValueTy).value
values.append(v)
}
expectEqual([ 1010, 1020, 1030 ], values)
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("BridgedToObjC.Value_ValueTypeCustomBridged") {
let a = getBridgedNSArrayOfValue_ValueTypeCustomBridged()
let enumerator = a.objectEnumerator()
var values = Array<Int>()
while let valueObj = enumerator.nextObject() {
let value: AnyObject = valueObj as AnyObject
let v = (value as! TestObjCValueTy).value
values.append(v)
}
expectEqual([ 1010, 1020, 1030 ], values)
expectAutoreleasedValues(unopt: 3)
}
//===---
// NSArray -> Array -> NSArray bridging tests.
//===---
ArrayTestSuite.test("BridgingRoundtrip") {
let a = getRoundtripBridgedNSArray()
let enumerator = a.objectEnumerator()
var values = Array<Int>()
while let valueObj = enumerator.nextObject() {
let value: AnyObject = valueObj as AnyObject
let v = (value as! TestObjCValueTy).value
values.append(v)
}
expectEqual([ 1010, 1020, 1030 ], values)
}
//===---
// NSArray -> Array implicit conversion.
//===---
ArrayTestSuite.test("NSArrayToArrayConversion") {
let values = [ 1010, 1020, 1030 ].map { TestObjCValueTy($0) }
let nsa = NSArray(array: values)
let a: Array = nsa as Array
var bridgedValues = Array<Int>()
for value in a {
let v = (value as! TestObjCValueTy).value
bridgedValues.append(v)
}
expectEqual([ 1010, 1020, 1030 ], bridgedValues)
}
ArrayTestSuite.test("ArrayToNSArrayConversion") {
var a = Array<TestObjCValueTy>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
let nsa: NSArray = a as NSArray
checkArrayFastEnumerationFromSwift(
[ 1010, 1020, 1030 ],
nsa, { a as NSArray },
{ ($0 as! TestObjCValueTy).value })
expectAutoreleasedValues(unopt: 3)
}
//===---
// Array upcasts
//===---
ArrayTestSuite.test("ArrayUpcastEntryPoint") {
var a = Array<TestObjCValueTy>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
var aAsAnyObject: Array<AnyObject> = _arrayForceCast(a)
expectEqual(3, aAsAnyObject.count)
var v: AnyObject = aAsAnyObject[0]
expectEqual(1010, (v as! TestObjCValueTy).value)
v = aAsAnyObject[1]
expectEqual(1020, (v as! TestObjCValueTy).value)
v = aAsAnyObject[2]
expectEqual(1030, (v as! TestObjCValueTy).value)
}
ArrayTestSuite.test("ArrayUpcast") {
var a = Array<TestObjCValueTy>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
var dAsAnyObject: Array<AnyObject> = a
expectEqual(3, dAsAnyObject.count)
var v: AnyObject = dAsAnyObject[0]
expectEqual(1010, (v as! TestObjCValueTy).value)
v = dAsAnyObject[1]
expectEqual(1020, (v as! TestObjCValueTy).value)
v = dAsAnyObject[2]
expectEqual(1030, (v as! TestObjCValueTy).value)
}
ArrayTestSuite.test("ArrayUpcastBridgedEntryPoint") {
var a = Array<TestBridgedValueTy>()
a.append(TestBridgedValueTy(1010))
a.append(TestBridgedValueTy(1020))
a.append(TestBridgedValueTy(1030))
do {
var aOO: Array<AnyObject> = _arrayConditionalCast(a)!
expectEqual(3, aOO.count)
var v: AnyObject = aOO[0]
expectEqual(1010, (v as! TestBridgedValueTy).value)
v = aOO[1]
expectEqual(1020, (v as! TestBridgedValueTy).value)
v = aOO[2]
expectEqual(1030, (v as! TestBridgedValueTy).value)
}
}
ArrayTestSuite.test("ArrayUpcastBridged") {
var a = Array<TestBridgedValueTy>()
a.append(TestBridgedValueTy(1010))
a.append(TestBridgedValueTy(1020))
a.append(TestBridgedValueTy(1030))
do {
var aOO = a as Array<AnyObject>
expectEqual(3, aOO.count)
var v: AnyObject = aOO[0]
expectEqual(1010, (v as! TestBridgedValueTy).value)
v = aOO[1]
expectEqual(1020, (v as! TestBridgedValueTy).value)
v = aOO[2]
expectEqual(1030, (v as! TestBridgedValueTy).value)
}
}
//===---
// Array downcasts
//===---
ArrayTestSuite.test("ArrayDowncastEntryPoint") {
var a = Array<AnyObject>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
// Successful downcast.
let aCC: Array<TestObjCValueTy> = _arrayForceCast(a)
expectEqual(3, aCC.count)
var v = aCC[0]
expectEqual(1010, v.value)
v = aCC[1]
expectEqual(1020, v.value)
v = aCC[2]
expectEqual(1030, v.value)
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("ArrayDowncast") {
var a = Array<AnyObject>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
// Successful downcast.
let aCC = a as! Array<TestObjCValueTy>
expectEqual(3, aCC.count)
var v = aCC[0]
expectEqual(1010, v.value)
v = aCC[1]
expectEqual(1020, v.value)
v = aCC[2]
expectEqual(1030, v.value)
expectAutoreleasedValues(unopt: 3)
}
ArrayTestSuite.test("ArrayDowncastConditionalEntryPoint") {
var a = Array<AnyObject>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
// Successful downcast.
if let aCC
= _arrayConditionalCast(a) as Array<TestObjCValueTy>? {
expectEqual(3, aCC.count)
var v = aCC[0]
expectEqual(1010, v.value)
v = aCC[1]
expectEqual(1020, v.value)
v = aCC[2]
expectEqual(1030, v.value)
} else {
expectTrue(false)
}
// Unsuccessful downcast
a[0] = 17 as NSNumber
a[1] = "hello" as NSString
if let _ = _arrayConditionalCast(a) as Array<TestObjCValueTy>? {
expectTrue(false)
}
}
ArrayTestSuite.test("ArrayDowncastConditional") {
var a = Array<AnyObject>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
// Successful downcast.
if let aCC = a as? Array<TestObjCValueTy> {
expectEqual(3, aCC.count)
var v = aCC[0]
expectEqual(1010, v.value)
v = aCC[1]
expectEqual(1020, v.value)
v = aCC[2]
expectEqual(1030, v.value)
} else {
expectTrue(false)
}
// Unsuccessful downcast
a[0] = 17 as NSNumber
a[1] = "hello" as NSString
if let _ = a as? Array<TestObjCValueTy> {
expectTrue(false)
}
}
ArrayTestSuite.test("ArrayBridgeFromObjectiveCEntryPoint") {
var a = Array<AnyObject>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
// Successful downcast.
let aCV: Array<TestBridgedValueTy> = _arrayConditionalCast(a)!
do {
expectEqual(3, aCV.count)
var v = aCV[0]
expectEqual(1010, v.value)
v = aCV[1]
expectEqual(1020, v.value)
v = aCV[2]
expectEqual(1030, v.value)
}
// // Successful downcast.
let aVC: Array<TestObjCValueTy> = _arrayConditionalCast(a)!
do {
expectEqual(3, aVC.count)
var v = aVC[0]
expectEqual(1010, v.value)
v = aVC[1]
expectEqual(1020, v.value)
v = aVC[2]
expectEqual(1030, v.value)
}
}
ArrayTestSuite.test("ArrayBridgeFromObjectiveC") {
var a = Array<AnyObject>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
// Successful downcast.
let aCV = a as! Array<TestBridgedValueTy>
do {
expectEqual(3, aCV.count)
var v = aCV[0]
expectEqual(1010, v.value)
v = aCV[1]
expectEqual(1020, v.value)
v = aCV[2]
expectEqual(1030, v.value)
}
// Successful downcast.
let aVC = a as! Array<TestObjCValueTy>
do {
expectEqual(3, aVC.count)
var v = aVC[0]
expectEqual(1010, v.value)
v = aVC[1]
expectEqual(1020, v.value)
v = aVC[2]
expectEqual(1030, v.value)
}
}
ArrayTestSuite.test("ArrayBridgeFromObjectiveCConditionalEntryPoint") {
var a = Array<AnyObject>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
// Successful downcast.
if let aCV = _arrayConditionalCast(a) as Array<TestBridgedValueTy>? {
expectEqual(3, aCV.count)
var v = aCV[0]
expectEqual(1010, v.value)
v = aCV[1]
expectEqual(1020, v.value)
v = aCV[2]
expectEqual(1030, v.value)
} else {
expectTrue(false)
}
// Successful downcast.
if let aVC = _arrayConditionalCast(a) as Array<TestObjCValueTy>? {
expectEqual(3, aVC.count)
var v = aVC[0]
expectEqual(1010, v.value)
v = aVC[1]
expectEqual(1020, v.value)
v = aVC[2]
expectEqual(1030, v.value)
} else {
expectTrue(false)
}
// Unsuccessful downcasts
a[0] = 17 as NSNumber
a[1] = "hello" as NSString
if let _ = _arrayConditionalCast(a) as Array<TestBridgedValueTy>? {
expectTrue(false)
}
if let _ = _arrayConditionalCast(a) as Array<TestObjCValueTy>? {
expectTrue(false)
}
}
ArrayTestSuite.test("ArrayBridgeFromObjectiveCConditional") {
var a = Array<AnyObject>()
a.append(TestObjCValueTy(1010))
a.append(TestObjCValueTy(1020))
a.append(TestObjCValueTy(1030))
// Successful downcast.
if let aCV = a as? Array<TestBridgedValueTy> {
expectEqual(3, aCV.count)
var v = aCV[0]
expectEqual(1010, v.value)
v = aCV[1]
expectEqual(1020, v.value)
v = aCV[2]
expectEqual(1030, v.value)
} else {
expectTrue(false)
}
// Successful downcast.
if let aVC = a as? Array<TestObjCValueTy> {
expectEqual(3, aVC.count)
var v = aVC[0]
expectEqual(1010, v.value)
v = aVC[1]
expectEqual(1020, v.value)
v = aVC[2]
expectEqual(1030, v.value)
} else {
expectTrue(false)
}
// Unsuccessful downcasts
a[0] = 17 as NSNumber
a[1] = "hello" as NSString
if let _ = a as? Array<TestBridgedValueTy> {
expectTrue(false)
}
if let _ = a as? Array<TestObjCValueTy> {
expectTrue(false)
}
}
#endif
//===---
// Check that iterators traverse a snapshot of the collection.
//===---
ArrayTestSuite.test("mutationDoesNotAffectIterator/subscript/store") {
var array = getDerivedAPIsArray()
let iter = array.makeIterator()
array[0] = 1011
expectEqual([1010 ,1020, 1030], Array(IteratorSequence(iter)))
}
ArrayTestSuite.test("mutationDoesNotAffectIterator/removeAt,1") {
var array = getDerivedAPIsArray()
let iter = array.makeIterator()
expectEqual(1010, array.remove(at: 0))
expectEqual([1010 ,1020, 1030], Array(IteratorSequence(iter)))
}
ArrayTestSuite.test("mutationDoesNotAffectIterator/removeAt,all") {
var array = getDerivedAPIsArray()
let iter = array.makeIterator()
expectEqual(1010, array.remove(at: 0))
expectEqual(1020, array.remove(at: 0))
expectEqual(1030, array.remove(at: 0))
expectEqual([1010 ,1020, 1030], Array(IteratorSequence(iter)))
}
ArrayTestSuite.test(
"mutationDoesNotAffectIterator/removeAll,keepingCapacity=false") {
var array = getDerivedAPIsArray()
let iter = array.makeIterator()
array.removeAll(keepingCapacity: false)
expectEqual([1010 ,1020, 1030], Array(IteratorSequence(iter)))
}
ArrayTestSuite.test(
"mutationDoesNotAffectIterator/removeAll,keepingCapacity=true") {
var array = getDerivedAPIsArray()
let iter = array.makeIterator()
array.removeAll(keepingCapacity: true)
expectEqual([1010 ,1020, 1030], Array(IteratorSequence(iter)))
}
//===----------------------------------------------------------------------===//
// Native array tests
// FIXME: incomplete.
//===----------------------------------------------------------------------===//
ArrayTestSuite.test("Native/count/empty") {
let a = [LifetimeTracked]()
expectEqual(0, a.count)
}
ArrayTestSuite.test("Native/count") {
let a = [ LifetimeTracked(10), LifetimeTracked(20), LifetimeTracked(30) ]
expectEqual(3, a.count)
}
ArrayTestSuite.test("Native/isEmpty/empty") {
let a = [LifetimeTracked]()
expectTrue(a.isEmpty)
}
ArrayTestSuite.test("Native/isEmpty") {
let a = [ LifetimeTracked(10), LifetimeTracked(20), LifetimeTracked(30) ]
expectFalse(a.isEmpty)
}
% for Kind in ['Array', 'ContiguousArray', 'ArraySlice']:
ArrayTestSuite.test("${Kind}/popLast") {
// Empty
do {
var a = ${Kind}<Int>()
let popped = a.popLast()
expectNil(popped)
expectTrue(a.isEmpty)
}
do {
var popped = [LifetimeTracked]()
var a: ${Kind} = [LifetimeTracked(1010), LifetimeTracked(2020), LifetimeTracked(3030)]
while let element = a.popLast() {
popped.append(element)
}
expectEqualSequence([1010, 2020, 3030], popped.reversed().lazy.map({ $0.value }))
expectTrue(a.isEmpty)
}
}
% end
//===----------------------------------------------------------------------===//
// COW(🐄) tests
//===----------------------------------------------------------------------===//
class COWBox<
T: Equatable & CustomStringConvertible>
: Equatable, CustomStringConvertible {
var value: T
init(_ value: T) {
self.value = value
}
var description: String {
return "Boxed: \(value.description)"
}
static func ==(lhs: COWBox, rhs: COWBox) -> Bool {
return lhs.value == rhs.value
}
}
ArrayTestSuite.test("COW.Smoke") {
var a1 = Array<COWBox<Int>>(repeating: COWBox(0), count: 10)
let identity1 = a1._rawIdentifier()
a1[0] = COWBox(1)
a1[1] = COWBox(2)
a1[2] = COWBox(3)
var a2 = a1
expectEqual(identity1, a2._rawIdentifier())
a2[3] = COWBox(4)
expectNotEqual(identity1, a2._rawIdentifier())
a1[4] = COWBox(5)
expectEqual(identity1, a1._rawIdentifier())
_blackHole(a1)
_blackHole(a2)
}
ArrayTestSuite.test("COW.Fast.SubscriptWithIndexDoesNotReallocate") {
var a = getCOWFastArray()
let identity1 = a._rawIdentifier()
let startIndex = a.startIndex
expectNotEqual(0, a[startIndex])
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("COW.Slow.SubscriptWithIndexDoesNotReallocate") {
var a = getCOWSlowArray()
let identity1 = a._rawIdentifier()
let startIndex = a.startIndex
expectNotEqual(0, a[startIndex].value)
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("COW.Fast.RemoveAtDoesNotReallocate") {
do {
var a = getCOWFastArray()
let identity1 = a._rawIdentifier()
let index1 = 1
expectEqual(identity1, a._rawIdentifier())
expectEqual(2, a[index1])
let removed = a.remove(at: index1)
expectEqual(2, removed)
expectEqual(identity1, a._rawIdentifier())
}
do {
let a1 = getCOWFastArray()
let identity1 = a1._rawIdentifier()
var a2 = a1
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity1, a2._rawIdentifier())
let index1 = 1
expectEqual(2, a2[index1])
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity1, a2._rawIdentifier())
let removed = a2.remove(at: index1)
expectEqual(2, removed)
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity1, a2._rawIdentifier())
}
}
ArrayTestSuite.test("COW.Slow.RemoveAtDoesNotReallocate") {
do {
var a = getCOWSlowArray()
let identity1 = a._rawIdentifier()
let index1 = 1
expectEqual(identity1, a._rawIdentifier())
expectEqual(2, a[index1].value)
let removed = a.remove(at: index1)
expectEqual(2, removed.value)
expectEqual(identity1, a._rawIdentifier())
}
do {
let a1 = getCOWSlowArray()
let identity1 = a1._rawIdentifier()
var a2 = a1
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity1, a2._rawIdentifier())
let index1 = 1
expectEqual(2, a2[index1].value)
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity1, a2._rawIdentifier())
let removed = a2.remove(at: index1)
expectEqual(2, removed.value)
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity1, a2._rawIdentifier())
}
}
ArrayTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate")
.skip(.linuxAny(reason: "rdar://problem/34268868")).code {
do {
var a = getCOWFastArray()
let originalCapacity = a.capacity
expectEqual(3, a.count)
expectEqual(2, a[1])
a.removeAll()
let identity1 = a._rawIdentifier()
expectLT(a.capacity, originalCapacity)
expectEqual(0, a.count)
expectEqual(identity1, a._rawIdentifier())
}
do {
var a = getCOWFastArray()
let identity1 = a._rawIdentifier()
let originalCapacity = a.capacity
expectEqual(3, a.count)
expectEqual(2, a[1])
a.removeAll(keepingCapacity: true)
expectEqual(identity1, a._rawIdentifier())
expectEqual(originalCapacity, a.capacity)
expectEqual(0, a.count)
}
do {
var a1 = getCOWFastArray()
let identity1 = a1._rawIdentifier()
expectEqual(3, a1.count)
expectEqual(2, a1[1])
var a2 = a1
a2.removeAll()
let identity2 = a2._rawIdentifier()
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity2, identity1)
expectEqual(3, a1.count)
expectEqual(2, a1[1])
expectEqual(0, a2.count)
// Keep variables alive.
_blackHole(a1)
_blackHole(a2)
}
do {
var a1 = getCOWFastArray()
let identity1 = a1._rawIdentifier()
let originalCapacity = a1.capacity
expectEqual(3, a1.count)
expectEqual(2, a1[1])
var a2 = a1
a2.removeAll(keepingCapacity: true)
let identity2 = a2._rawIdentifier()
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity2, identity1)
expectEqual(3, a1.count)
expectEqual(2, a1[1])
expectEqual(originalCapacity, a2.capacity)
expectEqual(0, a2.count)
// Keep variables alive.
_blackHole(a1)
_blackHole(a2)
}
}
ArrayTestSuite.test("COW.Slow.RemoveAllDoesNotReallocate")
.skip(.linuxAny(reason: "rdar://problem/34268868")).code {
do {
var a = getCOWSlowArray()
let originalCapacity = a.capacity
expectEqual(3, a.count)
expectEqual(2, a[1].value)
a.removeAll()
let identity1 = a._rawIdentifier()
expectLT(a.capacity, originalCapacity)
expectEqual(0, a.count)
expectEqual(identity1, a._rawIdentifier())
}
do {
var a = getCOWSlowArray()
let identity1 = a._rawIdentifier()
let originalCapacity = a.capacity
expectEqual(3, a.count)
expectEqual(2, a[1].value)
a.removeAll(keepingCapacity: true)
expectEqual(identity1, a._rawIdentifier())
expectEqual(originalCapacity, a.capacity)
expectEqual(0, a.count)
}
do {
var a1 = getCOWSlowArray()
let identity1 = a1._rawIdentifier()
expectEqual(3, a1.count)
expectEqual(2, a1[1].value)
var a2 = a1
a2.removeAll()
let identity2 = a2._rawIdentifier()
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity2, identity1)
expectEqual(3, a1.count)
expectEqual(2, a1[1].value)
expectEqual(0, a2.count)
// Keep variables alive.
_blackHole(a1)
_blackHole(a2)
}
do {
var a1 = getCOWSlowArray()
let identity1 = a1._rawIdentifier()
let originalCapacity = a1.capacity
expectEqual(3, a1.count)
expectEqual(2, a1[1].value)
var a2 = a1
a2.removeAll(keepingCapacity: true)
let identity2 = a2._rawIdentifier()
expectEqual(identity1, a1._rawIdentifier())
expectNotEqual(identity2, identity1)
expectEqual(3, a1.count)
expectEqual(2, a1[1].value)
expectEqual(originalCapacity, a2.capacity)
expectEqual(0, a2.count)
// Keep variables alive.
_blackHole(a1)
_blackHole(a2)
}
}
ArrayTestSuite.test("COW.Fast.CountDoesNotReallocate") {
let a = getCOWFastArray()
let identity1 = a._rawIdentifier()
expectEqual(3, a.count)
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("COW.Slow.CountDoesNotReallocate") {
let a = getCOWSlowArray()
let identity1 = a._rawIdentifier()
expectEqual(3, a.count)
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("COW.Fast.GenerateDoesNotReallocate") {
let a = getCOWFastArray()
let identity1 = a._rawIdentifier()
var iter = a.makeIterator()
var copy = Array<Int>()
while let value = iter.next() {
copy.append(value)
}
expectEqual(copy, [ 1, 2, 3 ])
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("COW.Slow.GenerateDoesNotReallocate") {
let a = getCOWSlowArray()
let identity1 = a._rawIdentifier()
var iter = a.makeIterator()
var copy = Array<Int>()
while let value = iter.next() {
copy.append(value.value)
}
expectEqual(copy, [ 1, 2, 3 ])
expectEqual(identity1, a._rawIdentifier())
}
ArrayTestSuite.test("COW.Fast.EqualityTestDoesNotReallocate") {
let a1 = getCOWFastArray()
let identity1 = a1._rawIdentifier()
var a2 = getCOWFastArray()
let identity2 = a2._rawIdentifier()
expectEqual(a1, a2)
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity2, a2._rawIdentifier())
a2[1] = 5
expectTrue(a1 != a2)
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity2, a2._rawIdentifier())
}
ArrayTestSuite.test("COW.Slow.EqualityTestDoesNotReallocate") {
let a1 = getCOWSlowArray()
let identity1 = a1._rawIdentifier()
var a2 = getCOWSlowArray()
let identity2 = a2._rawIdentifier()
expectEqual(a1, a2)
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity2, a2._rawIdentifier())
a2[2] = COWBox(5)
expectTrue(a1 != a2)
expectEqual(identity1, a1._rawIdentifier())
expectEqual(identity2, a2._rawIdentifier())
}
//===----------------------------------------------------------------------===//
// Index tests
//===----------------------------------------------------------------------===//
public struct ArrayIndexTest<T: Collection> {
public enum Operation {
case append(Int)
case insert(Int, at: Int)
case partition(by: (OpaqueValue<Int>) throws -> Bool)
case removeFirst
case removeFirstN(Int)
case removeLast
case removeLastN(Int)
case removeAt(Int)
case removeAll(Bool)
case removeClosedSubrange(ClosedRange<Int>)
case removeHalfClosedSubrange(Range<Int>)
}
public let data: T
public let expectedStart: Int
public let expectedEnd: Int
public let range: Range<Int>?
public let operation: Operation
public let loc: SourceLoc
public init(data: T, expectedStart: Int, expectedEnd: Int,
operation: Operation, range: Range<Int>? = nil,
file: String = #file, line: UInt = #line) {
self.data = data
self.expectedStart = expectedStart
self.expectedEnd = expectedEnd
self.operation = operation
self.range = range
self.loc = SourceLoc(file, line, comment: "Array index test data")
}
}
let indexTests: [ArrayIndexTest<[Int]>] = [
// Check how partition() affects indices.
ArrayIndexTest(
data: [ 99, 1010, 99 ],
expectedStart: 1,
expectedEnd: 2,
operation: .partition(by: { $0.value > 100 } ),
range: 1..<2
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 1,
expectedEnd: 3,
operation: .partition(by: { $0.value > 0} ),
range: 1..<3
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 1,
expectedEnd: 3,
operation: .partition(by: { $0.value > 3000 }),
range: 1..<3
),
// Check how partition(by:) affects indices.
ArrayIndexTest(
data: [ 10, 2, -33, 44, -5 ],
expectedStart: 0,
expectedEnd: 5,
operation: .partition(by: { $0.value > 0 })
),
ArrayIndexTest(
data: [ 10, 2, -33, 44, -5 ],
expectedStart: 0,
expectedEnd: 5,
operation: .partition(by: { $0.value > 100 })
),
// Check how append affects indices.
ArrayIndexTest(
data: [ 2 ],
expectedStart: 0,
expectedEnd: 2,
operation: .append(1)
),
ArrayIndexTest(
data: [],
expectedStart: 0,
expectedEnd: 1,
operation: .append(1)
),
// FIXME: re-enable when rdar://problem/33358110 is addressed
// ArrayIndexTest(
// data: [ 42, 2525, 3535, 42 ],
// expectedStart: 1,
// expectedEnd: 3,
// operation: .append(1),
// range: 1..<2
// ),
// Check how insert(_:at:) affects indices.
ArrayIndexTest(
data: [ 2 ],
expectedStart: 0,
expectedEnd: 2,
operation: .insert(2, at: 0)
),
ArrayIndexTest(
data: [ 2 ],
expectedStart: 0,
expectedEnd: 2,
operation: .insert(2, at: 1)
),
ArrayIndexTest(
data: [ 42, 2525, 3535, 42 ],
expectedStart: 1,
expectedEnd: 3,
operation: .insert(2, at: 1),
range: 1..<2
),
// Check how removeLast() affects indices.
ArrayIndexTest(
data: [ 1 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeLast
),
ArrayIndexTest(
data: [ 1, 2 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeLast
),
ArrayIndexTest(
data: [ 99, 1010, 99 ],
expectedStart: 1,
expectedEnd: 1,
operation: .removeLast,
range: 1..<2
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 1,
expectedEnd: 2,
operation: .removeLast,
range: 1..<3
),
// Check how remove(at:) affects indices.
ArrayIndexTest(
data: [ 1 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeAt(0)
),
ArrayIndexTest(
data: [ 1, 2 ],
expectedStart: 0,
expectedEnd: 1,
operation: .removeAt(1)
),
ArrayIndexTest(
data: [ 99, 1010, 99 ],
expectedStart: 1,
expectedEnd: 1,
operation: .removeAt(1),
range: 1..<2
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 1,
expectedEnd: 2,
operation: .removeAt(1),
range: 1..<3
),
// Check how removeAll(keepingCapacity:) affects indices.
ArrayIndexTest(
data: [ 1, 2, 3 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeAll(true)
),
ArrayIndexTest(
data: [ 1, 2 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeAll(false)
),
ArrayIndexTest(
data: [ 99, 1010, 99 ],
expectedStart: 1,
expectedEnd: 1,
operation: .removeAll(true),
range: 1..<2
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeAll(false),
range: 1..<2
),
// Check how removeFirst() affects indices.
ArrayIndexTest(
data: [ 1 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeFirst
),
ArrayIndexTest(
data: [ 1, 2 ],
expectedStart: 0,
expectedEnd: 1,
operation: .removeFirst
),
ArrayIndexTest(
data: [ 99, 1010, 99 ],
expectedStart: 2,
expectedEnd: 2,
operation: .removeFirst,
range: 1..<2
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 2,
expectedEnd: 3,
operation: .removeFirst,
range: 1..<3
),
// Check how removeFirst(_:) affects indices.
ArrayIndexTest(
data: [ 1, 2 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeFirstN(2)
),
ArrayIndexTest(
data: [ 1, 2, 3, 4 ],
expectedStart: 0,
expectedEnd: 2,
operation: .removeFirstN(2)
),
ArrayIndexTest(
data: [ 99, 1010, 99 ],
expectedStart: 3,
expectedEnd: 3,
operation: .removeFirstN(2),
range: 1..<3
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 3,
expectedEnd: 4,
operation: .removeFirstN(2),
range: 1..<4
),
// Check how removeLast() affects indices.
ArrayIndexTest(
data: [ 1 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeLast
),
ArrayIndexTest(
data: [ 1, 2 ],
expectedStart: 0,
expectedEnd: 1,
operation: .removeLast
),
ArrayIndexTest(
data: [ 99, 1010, 99 ],
expectedStart: 1,
expectedEnd: 1,
operation: .removeLast,
range: 1..<2
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 1,
expectedEnd: 1,
operation: .removeLast,
range: 1..<2
),
// Check how removeSubrange(_:ClosedRange) affects indices.
ArrayIndexTest(
data: [ 1 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeHalfClosedSubrange(0..<1)
),
ArrayIndexTest(
data: [ 1, 2, 3 ],
expectedStart: 0,
expectedEnd: 1,
operation: .removeHalfClosedSubrange(0..<2)
),
ArrayIndexTest(
data: [ 1, 2, 3 ],
expectedStart: 0,
expectedEnd: 1,
operation: .removeHalfClosedSubrange(0..<3)
),
ArrayIndexTest(
data: [ 99, 1010, 99 ],
expectedStart: 1,
expectedEnd: 1,
operation: .removeHalfClosedSubrange(1..<2),
range: 1..<2
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 1,
expectedEnd: 2,
operation: .removeHalfClosedSubrange(1..<2),
range: 1..<3
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99 ],
expectedStart: 1,
expectedEnd: 2,
operation: .removeHalfClosedSubrange(2..<4),
range: 1..<4
),
// Check how removeSubrange(_:Range) affects indices.
ArrayIndexTest(
data: [ 1, 2 ],
expectedStart: 0,
expectedEnd: 0,
operation: .removeClosedSubrange(0...1)
),
ArrayIndexTest(
data: [ 1, 2, 3 ],
expectedStart: 0,
expectedEnd: 1,
operation: .removeClosedSubrange(0...1)
),
ArrayIndexTest(
data: [ 1, 2, 3 ],
expectedStart: 0,
expectedEnd: 1,
operation: .removeClosedSubrange(0...2)
),
ArrayIndexTest(
data: [ 99, 1010, 99 ],
expectedStart: 1,
expectedEnd: 1,
operation: .removeClosedSubrange(1...2),
range: 1..<3
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99, 44 ],
expectedStart: 1,
expectedEnd: 2,
operation: .removeClosedSubrange(2...3),
range: 1..<4
),
ArrayIndexTest(
data: [ 99, 1010, 2020, 99, 44 ],
expectedStart: 1,
expectedEnd: 2,
operation: .removeClosedSubrange(1...2),
range: 1..<4
)
]
% for Kind in ['Array', 'ContiguousArray', 'ArraySlice']:
ArrayTestSuite.test("ArrayIndexTests") {
for test in indexTests {
let testData = test.data.map(OpaqueValue.init)
% if Kind == 'ArraySlice':
guard let range = test.range else { continue }
var a = testData[range]
% else:
if test.range != nil { continue }
var a = ${Kind}(testData)
% end
switch test.operation {
case let .append(v):
a.append(OpaqueValue(v))
case let .insert(v, index):
a.insert(OpaqueValue(v), at: index)
case let .partition(c):
expectDoesNotThrow({
_ = try a.partition(by: c)
})
case .removeFirst:
a.removeFirst()
case let .removeFirstN(n):
a.removeFirst(n)
case .removeLast:
a.removeLast()
case let .removeLastN(n):
a.removeLast(n)
case let .removeAt(index):
a.remove(at: index)
case let .removeAll(keepCapacity):
a.removeAll(keepingCapacity: keepCapacity)
case let .removeHalfClosedSubrange(range):
a.removeSubrange(range)
case let .removeClosedSubrange(range):
a.removeSubrange(range)
}
expectEqual(test.expectedStart, a.startIndex, stackTrace: SourceLocStack().with(test.loc))
expectEqual(test.expectedEnd, a.endIndex, stackTrace: SourceLocStack().with(test.loc))
}
}
% end
//===----------------------------------------------------------------------===//
// Array and EvilCollection that changes its size while we are not looking
//===----------------------------------------------------------------------===//
let evilBoundsError = "EvilCollection: index out of range"
final class EvilSequence : Sequence {
init(_ growth: Int) {
self.growth = growth
}
var growth: Int
var _count: Int = 20
var underestimatedCount: Int {
defer { _count += growth }
return _count
}
func makeIterator() -> AnyIterator<LifetimeTracked> {
var i = 0
return AnyIterator {
if i >= self._count { return nil }
let result = LifetimeTracked(i)
i += 1
return result
}
}
}
final class EvilCollection : Collection {
func index(after i: Int) -> Int {
return i + 1
}
init(_ growth: Int, boundsChecked: Bool) {
self.growth = growth
self.boundsChecked = boundsChecked
}
var growth: Int
var _count: Int = 20
var boundsChecked: Bool
var startIndex : Int {
_count += growth
return 0
}
var endIndex : Int {
return _count
}
subscript(i: Int) -> LifetimeTracked {
if boundsChecked {
precondition(i >= 0 && i < _count, evilBoundsError)
}
return LifetimeTracked(i)
}
// Default implementation will call _failEarlyRangeCheck,
// passing in a startIndex that will grow _count faster than
// necessary.
func formIndex(after i: inout Int) {
i += 1
}
}
for (step, evilBoundsCheck) in [ (1, true), (-1, false), (-1, true) ] {
let message = step < 0 && evilBoundsCheck
? evilBoundsError
: "invalid Collection: count differed in successive traversals"
let constructionMessage = step < 0
? "invalid Collection: less than 'count' elements in collection"
: "invalid Collection: more than 'count' elements in collection"
// The invalid Collection error is a _debugPreconditon that will only fire
// in a Debug assert configuration.
let expectedToFail = (step < 0 && evilBoundsCheck) ||
_isDebugAssertConfiguration()
let natureOfEvil = step > 0 ? "Growth" : "Shrinkage"
let boundsChecked = evilBoundsCheck ? "BoundsChecked" : "NoBoundsCheck"
let testPrefix = "MemorySafety/\(boundsChecked)/Evil\(natureOfEvil)"
ArrayTestSuite.test("\(testPrefix)/Infrastructure/EvilSequence") {
let evil = EvilSequence(step)
let count0 = evil.underestimatedCount
let count1 = evil.underestimatedCount
expectNotEqual(count0, count1)
if step > 0 {
expectLE(count0, count1)
}
else {
expectGE(count0, count1)
}
}
let t1 = ArrayTestSuite.test("\(testPrefix)/Infrastructure/EvilCollection")
(evilBoundsCheck && _isDebugAssertConfiguration()
? t1.crashOutputMatches(evilBoundsError) : t1)
.code {
let evil = EvilCollection(step, boundsChecked: evilBoundsCheck)
let count0 = evil.count
let count1 = evil.count
expectNotEqual(count0, count1)
if step > 0 {
expectLE(count0, count1)
}
else {
expectGE(count0, count1)
}
if evilBoundsCheck {
expectCrashLater()
}
let x = evil[-1]
_blackHole(x)
}
let t2 = ArrayTestSuite.test("\(testPrefix)/Construction")
(_isDebugAssertConfiguration() && expectedToFail
? t2.crashOutputMatches(constructionMessage) : t2)
.code {
let evil = EvilCollection(step, boundsChecked: evilBoundsCheck)
if step < 0 || _isDebugAssertConfiguration() {
expectCrashLater()
}
let a = Array(evil)
_blackHole(a)
}
for (op, rangeMax) in ["Grow":0, "Shrink":200] {
let t3 = ArrayTestSuite.test("\(testPrefix)/replaceSubrange/\(op)Unique")
(_isDebugAssertConfiguration() ? t3.crashOutputMatches(message) : t3)
.code {
let evil = EvilCollection(step, boundsChecked: evilBoundsCheck)
var a = Array((0..<200).lazy.map { LifetimeTracked($0) })
if expectedToFail {
expectCrashLater()
}
a.replaceSubrange(0..<rangeMax, with: evil)
}
let t4 = ArrayTestSuite.test("\(testPrefix)/replaceSubrange/\(op)NonUnique")
(_isDebugAssertConfiguration() ? t4.crashOutputMatches(message) : t4)
.code {
let evil = EvilCollection(step, boundsChecked: evilBoundsCheck)
var a = Array((0..<200).lazy.map { LifetimeTracked($0) })
let b = a
if expectedToFail {
expectCrashLater()
}
a.replaceSubrange(0..<rangeMax, with: evil)
_blackHole(b)
}
}
ArrayTestSuite.test("\(testPrefix)/SequenceMap")
.skip(.custom(
{ _isFastAssertConfiguration() },
reason: "this trap is not guaranteed to happen in -Ounchecked"))
.code {
let evil = EvilSequence(step)
if step < 0 {
expectCrashLater()
}
let a = evil.map { $0 }
_blackHole(a)
}
ArrayTestSuite.test("\(testPrefix)/CollectionMap")
.code {
let evil = EvilCollection(step, boundsChecked: evilBoundsCheck)
if expectedToFail {
expectCrashLater()
}
let a = evil.map { $0 }
_blackHole(a)
}
ArrayTestSuite.test("\(testPrefix)/FilterAll")
.code {
let evil = EvilCollection(step, boundsChecked: evilBoundsCheck)
let a = evil.filter { _ in true }
_blackHole(a)
}
ArrayTestSuite.test("\(testPrefix)/FilterNone")
.code {
let evil = EvilCollection(step, boundsChecked: evilBoundsCheck)
let a = evil.filter { _ in false }
_blackHole(a)
}
}
runAllTests()