stdlib: Add some basic array bridging tests

Swift SVN r29307
This commit is contained in:
Dmitri Hrybenko
2015-06-04 20:13:11 +00:00
parent 35dac3b7c8
commit 41934b5433

View File

@@ -13,6 +13,7 @@
import Darwin
import StdlibUnittest
import StdlibUnittestFoundationExtras
import Foundation
%{
@@ -552,19 +553,273 @@ ArrayTestSuite.test("${array_type}<${element_type}>/subscript(_: Range<Int>)/COW
% end
% end
// FIXME: all the tests below are applicable to ArraySlice, too.
//===----------------------------------------------------------------------===//
// NSArray -> Array bridging tests
// FIXME: incomplete.
//===----------------------------------------------------------------------===//
func isNativeArray<Element>(a: Array<Element>) -> Bool {
return a._getArrayPropertyIsNative()
}
func isCocoaArray<Element>(a: Array<Element>) -> Bool {
return !isNativeArray(a)
}
func getAsImmutableNSArray(a: Array<Int>) -> NSArray {
var elements = a.map { TestObjCValueTy($0) as AnyObject? }
return NSArray(objects: &elements, count: elements.count)
}
func getAsNSArray(a: Array<Int>) -> NSArray {
// Return an `NSMutableArray` to make sure that it has a unique
// pointer identity.
return getAsNSMutableArray(a)
}
func getAsNSMutableArray(a: Array<Int>) -> NSMutableArray {
let result = NSMutableArray()
for element in a {
result.addObject(TestObjCValueTy(element))
}
return result
}
@objc
class CustomImmutableNSArray : NSArray {
init(_privateInit: ()) {
super.init()
}
override init() {
expectUnreachable()
super.init()
}
override init(objects: UnsafePointer<AnyObject?>, count: Int) {
super.init(objects: objects, count: count)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) not implemented by CustomImmutableNSArray")
}
@objc
override func copyWithZone(zone: NSZone) -> AnyObject {
++CustomImmutableNSArray.timesCopyWithZoneWasCalled
return self
}
@objc
override func objectAtIndex(index: Int) -> AnyObject {
++CustomImmutableNSArray.timesObjectAtIndexWasCalled
return _data[index]
}
@objc
override var count: Int {
++CustomImmutableNSArray.timesCountWasCalled
return _data.count
}
@objc
override func countByEnumeratingWithState(
state: UnsafeMutablePointer<NSFastEnumerationState>,
objects: AutoreleasingUnsafeMutablePointer<AnyObject?>,
count: Int
) -> Int {
var theState = state.memory
if theState.state == 0 {
theState.state = 1
theState.itemsPtr =
AutoreleasingUnsafeMutablePointer(_data._baseAddressIfContiguous)
theState.mutationsPtr = _fastEnumerationStorageMutationsPtr
state.memory = theState
return _data.count
}
return 0
}
let _data = [ 10, 20, 30 ].map { TestObjCValueTy($0) }
static var timesCopyWithZoneWasCalled = 0
static var timesObjectAtIndexWasCalled = 0
static var timesCountWasCalled = 0
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.BridgeUsingAs") {
if true {
let source = [ 10, 20, 30 ]
let nsa = getAsNSArray(source)
var result = nsa as Array
expectTrue(isCocoaArray(result))
expectType(Array<AnyObject>.self, &result)
checkSequence(
source.map { TestObjCValueTy($0) as AnyObject },
result,
{ ($0 as! TestObjCValueTy).value == ($1 as! TestObjCValueTy).value })
}
if true {
let source = [ 10, 20, 30 ]
let nsa = getAsNSArray(source)
var result = nsa as! Array<TestObjCValueTy>
expectTrue(isCocoaArray(result))
expectType(Array<TestObjCValueTy>.self, &result)
checkSequence(
source.map { TestObjCValueTy($0) },
result,
{ $0.value == $1.value })
}
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.BridgeUsingAs") {
let source = [ 10, 20, 30 ]
let nsa = getAsNSArray(source)
var result = nsa as! Array<TestBridgedValueTy>
expectTrue(isNativeArray(result))
expectType(Array<TestBridgedValueTy>.self, &result)
checkSequence(
source.map { TestBridgedValueTy($0) },
result,
{ $0.value == $1.value })
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.ArrayIsCopied") {
let source = [ 10, 20, 30 ]
let nsa = getAsNSMutableArray(source)
let result = nsa as Array<AnyObject>
expectTrue(isCocoaArray(result))
// Delete the value from NSMutableArray.
expectEqual(20, (nsa[1] as! TestObjCValueTy).value)
nsa.removeObjectAtIndex(1)
expectEqual(30, (nsa[1] as! TestObjCValueTy).value)
// Check that the Array is not affected.
expectEqual(20, result[1].value)
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.ArrayIsCopied") {
let source = [ 10, 20, 30 ]
let nsa = getAsNSMutableArray(source)
var result = nsa as! Array<TestBridgedValueTy>
expectTrue(isNativeArray(result))
// Delete the value from NSMutableArray.
expectEqual(20, (nsa[1] as! TestObjCValueTy).value)
nsa.removeObjectAtIndex(1)
expectEqual(30, (nsa[1] as! TestObjCValueTy).value)
// Check that the Array is not affected.
expectEqual(20, result[1].value)
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.NSArrayIsRetained") {
let nsa = NSArray(array: getAsNSArray([ 10, 20, 30 ]))
var a: Array<AnyObject> = _convertNSArrayToArray(nsa)
var bridgedBack: NSArray = _convertArrayToNSArray(a)
expectEqual(
unsafeBitCast(nsa, Word.self),
unsafeBitCast(bridgedBack, Word.self))
_fixLifetime(nsa)
_fixLifetime(a)
_fixLifetime(bridgedBack)
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.NSArrayIsCopied") {
let nsa = NSArray(array: getAsNSArray([ 10, 20, 30 ]))
var a: Array<TestBridgedValueTy> = _convertNSArrayToArray(nsa)
var bridgedBack: NSArray = _convertArrayToNSArray(a)
expectNotEqual(
unsafeBitCast(nsa, Word.self),
unsafeBitCast(bridgedBack, Word.self))
_fixLifetime(nsa)
_fixLifetime(a)
_fixLifetime(bridgedBack)
}
ArrayTestSuite.test("BridgedFromObjC.Verbatim.ImmutableArrayIsRetained") {
let nsa: NSArray = CustomImmutableNSArray(_privateInit: ())
CustomImmutableNSArray.timesCopyWithZoneWasCalled = 0
CustomImmutableNSArray.timesObjectAtIndexWasCalled = 0
CustomImmutableNSArray.timesCountWasCalled = 0
let a: Array<AnyObject> = _convertNSArrayToArray(nsa)
expectEqual(1, CustomImmutableNSArray.timesCopyWithZoneWasCalled)
expectEqual(0, CustomImmutableNSArray.timesObjectAtIndexWasCalled)
expectEqual(0, CustomImmutableNSArray.timesCountWasCalled)
let bridgedBack: NSArray = _convertArrayToNSArray(a)
expectEqual(
unsafeBitCast(nsa, Word.self),
unsafeBitCast(bridgedBack, Word.self))
_fixLifetime(nsa)
_fixLifetime(a)
_fixLifetime(bridgedBack)
}
ArrayTestSuite.test("BridgedFromObjC.Nonverbatim.ImmutableArrayIsCopied") {
let nsa: NSArray = CustomImmutableNSArray(_privateInit: ())
CustomImmutableNSArray.timesCopyWithZoneWasCalled = 0
CustomImmutableNSArray.timesObjectAtIndexWasCalled = 0
CustomImmutableNSArray.timesCountWasCalled = 0
TestBridgedValueTy.bridgeOperations = 0
var a: Array<TestBridgedValueTy> = []
// FIXME: bridging shouldn't dump array contents into the autorelease pool.
autoreleasepoolIfUnoptimizedReturnAutoreleased {
a = _convertNSArrayToArray(nsa)
expectEqual(1, CustomImmutableNSArray.timesCopyWithZoneWasCalled)
expectEqual(3, CustomImmutableNSArray.timesObjectAtIndexWasCalled)
expectNotEqual(0, CustomImmutableNSArray.timesCountWasCalled)
expectEqual(3, TestBridgedValueTy.bridgeOperations)
}
let bridgedBack: NSArray = _convertArrayToNSArray(a)
expectNotEqual(
unsafeBitCast(nsa, Word.self),
unsafeBitCast(bridgedBack, Word.self))
_fixLifetime(nsa)
_fixLifetime(a)
_fixLifetime(bridgedBack)
}
// FIXME: test API calls on the BridgedFromObjC arrays.
//===----------------------------------------------------------------------===//
// Array -> NSArray bridging tests
//
// Key and Value are bridged verbatim.
// Element is bridged verbatim.
//
// FIXME: incomplete.
//===----------------------------------------------------------------------===//
ArrayTestSuite.test("BridgedToObjC.Verbatim.BridgeUsingAs") {
let source = [ 10, 20, 30 ].map { TestObjCValueTy($0) }
let result = source as NSArray
expectTrue(isNativeNSArray(result))
expectEqual(3, result.count)
autoreleasepoolIfUnoptimizedReturnAutoreleased {
expectEqual(10, (result[0] as! TestObjCValueTy).value)
expectEqual(20, (result[1] as! TestObjCValueTy).value)
expectEqual(30, (result[2] as! TestObjCValueTy).value)
}
}
ArrayTestSuite.test("BridgedToObjC/Verbatim/count/empty") {
let a = getBridgedNSArrayOfRefTypeVerbatimBridged(numElements: 0)
expectEqual(0, a.count)
@@ -819,11 +1074,23 @@ ArrayTestSuite.test("BridgedToObjC/Verbatim/BridgeBack/Adopt") {
//===----------------------------------------------------------------------===//
// Array -> NSArray bridging tests
//
// Key and Value are bridged non-verbatim.
// Element is bridged non-verbatim.
//
// FIXME: incomplete.
//===----------------------------------------------------------------------===//
ArrayTestSuite.test("BridgedToObjC.Nonverbatim.BridgeUsingAs") {
let source = [ 10, 20, 30 ].map { TestBridgedValueTy($0) }
var result = source as NSArray
expectTrue(isNativeNSArray(result))
expectEqual(3, result.count)
autoreleasepoolIfUnoptimizedReturnAutoreleased {
expectEqual(10, (result[0] as! TestBridgedValueTy).value)
expectEqual(20, (result[1] as! TestBridgedValueTy).value)
expectEqual(30, (result[2] as! TestBridgedValueTy).value)
}
}
ArrayTestSuite.test("BridgedToObjC/Custom/count/empty") {
let a = getBridgedNSArrayOfValueTypeCustomBridged(numElements: 0)
expectEqual(0, a.count)
@@ -1129,6 +1396,61 @@ ArrayTestSuite.test("BridgedToObjC/Custom/BridgeBack/Adopt") {
expectEqual(identity1, unsafeBitCast(native, UWord.self))
}
//===----------------------------------------------------------------------===//
// NSArray -> Array -> NSArray bridging tests.
//===----------------------------------------------------------------------===//
ArrayTestSuite.test("BridgedToObjC.Verbatim.RoundtripThroughSwiftArray") {
% for (MiddleType, AsCast) in [
% ('Array<AnyObject>', 'as'),
% ('Array<TestObjCValueTy>', 'as!'),
% ]:
if true {
let nsa: NSArray = getAsImmutableNSArray([ 10, 20, 30 ])
let a: ${MiddleType} = _convertNSArrayToArray(nsa)
let bridgedBack = _convertArrayToNSArray(a)
expectEqual(
unsafeBitCast(nsa, Word.self),
unsafeBitCast(bridgedBack, Word.self))
_fixLifetime(nsa)
_fixLifetime(a)
_fixLifetime(bridgedBack)
}
if true {
let nsa: NSArray = getAsImmutableNSArray([ 10, 20, 30 ])
let a = nsa ${AsCast} ${MiddleType}
let bridgedBack: NSArray = a as NSArray
expectEqual(
unsafeBitCast(nsa, Word.self),
unsafeBitCast(bridgedBack, Word.self))
_fixLifetime(nsa)
_fixLifetime(a)
_fixLifetime(bridgedBack)
}
% end
}
ArrayTestSuite.test("BridgedToObjC.Nonverbatim.RoundtripThroughSwiftArray") {
if true {
TestBridgedValueTy.bridgeOperations = 0
let nsa: NSArray = getAsImmutableNSArray([ 10, 20, 30 ])
let a: Array<TestBridgedValueTy> = _convertNSArrayToArray(nsa)
let bridgedBack = _convertArrayToNSArray(a)
expectEqual(3, TestBridgedValueTy.bridgeOperations)
}
if true {
TestBridgedValueTy.bridgeOperations = 0
let nsa: NSArray = getAsImmutableNSArray([ 10, 20, 30 ])
let a = nsa as! Array<TestBridgedValueTy>
let bridgedBack: NSArray = a as NSArray
expectEqual(3, TestBridgedValueTy.bridgeOperations)
}
}
//===----------------------------------------------------------------------===//
// Array and EvilCollection that changes its size while we are not looking
//===----------------------------------------------------------------------===//
@@ -1227,7 +1549,7 @@ for (step, evilBoundsCheck) in [ (1, true), (-1, false), (-1, true) ] {
}
//===----------------------------------------------------------------------===//
// Special cases and one-off tests
// Special cases and one-off tests.
//===----------------------------------------------------------------------===//
% for array_type in all_array_types: