forked from swiftlang/swift-corelibs-foundation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTestBridging.swift
94 lines (81 loc) · 3.55 KB
/
TestBridging.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
#if NS_FOUNDATION_ALLOWS_TESTABLE_IMPORT
#if canImport(SwiftFoundation) && !DEPLOYMENT_RUNTIME_OBJC
@testable import SwiftFoundation
#else
@testable import Foundation
#endif
#endif
struct StructWithDescriptionAndDebugDescription:
CustomStringConvertible, CustomDebugStringConvertible
{
var description: String { "description" }
var debugDescription: String { "debugDescription" }
}
class TestBridging : XCTestCase {
func testBridgedDescription() throws {
#if canImport(Foundation) && canImport(SwiftFoundation)
/*
Do not test this on Darwin.
On systems where swift-corelibs-foundation is the Foundation module,
the stdlib gives us the ability to specify how bridging works
(by using our __SwiftValue class), which is what we're testing
here when we do 'a as AnyObject'. But on Darwin, bridging is out
of SCF's hands — there is an ObjC __SwiftValue class vended by
the runtime.
Deceptively, below, when we say 'NSObject', we mean SwiftFoundation.NSObject,
not the ObjC NSObject class — which is what __SwiftValue actually
derives from. So, as? NSObject below returns nil on Darwin.
Since this functionality is tested by the stdlib tests on Darwin,
just skip this test here.
*/
#else
// Struct with working (debug)description properties:
let a = StructWithDescriptionAndDebugDescription()
XCTAssertEqual("description", a.description)
XCTAssertEqual("debugDescription", a.debugDescription)
// Wrap it up in a SwiftValue container
let b = (a as AnyObject) as? NSObject
XCTAssertNotNil(b)
let c = try XCTUnwrap(b)
// Check that the wrapper forwards (debug)description
// to the wrapped description property.
XCTAssertEqual("description", c.description)
XCTAssertEqual("description", c.debugDescription)
#endif
}
func testDynamicCast() throws {
// Covers https://github.com/apple/swift-corelibs-foundation/pull/2500
class TestClass {}
let anyArray: Any = [TestClass()]
XCTAssertNotNil(anyArray as? NSObject)
}
func testConstantsImmortal() throws {
func release(_ ptr: UnsafeRawPointer, count: Int) {
let object: Unmanaged<NSNumber> = Unmanaged.fromOpaque(ptr)
for _ in 0..<count {
object.release()
}
}
let trueConstant = NSNumber(value: true)
let falseConstant = NSNumber(value: false)
// To accurately read the whole refcount, we need to read the second
// word of the pointer.
let truePtr = unsafeBitCast(trueConstant, to: UnsafePointer<Int>.self)
let falsePtr = unsafeBitCast(falseConstant, to: UnsafePointer<Int>.self)
let trueRefCount = truePtr.advanced(by: 1).pointee
let falseRefCount = falsePtr.advanced(by: 1).pointee
XCTAssertEqual(trueRefCount, falseRefCount)
release(truePtr, count: 5)
release(falsePtr, count: 5)
XCTAssertEqual(trueRefCount, truePtr.advanced(by: 1).pointee)
XCTAssertEqual(falseRefCount, falsePtr.advanced(by: 1).pointee)
}
}