Files
swift-mirror/test/Interpreter/SDK/cf.swift
Jordan Rose 01cb554387 Re-apply "Make all CF types Equatable and Hashable." (#4568)
Like NSObject, CFType has primitive operations CFEqual and CFHash,
so Swift should allow those types to show up in Hashable positions
(like dictionaries). The most general way to do this was to
introduce a new protocol, _CFObject, and then have the importer
automatically make all CF types conform to it.

This did require one additional change: the == implementation that
calls through to CFEqual is in a new CoreFoundation overlay, but the
conformance is in the underlying Clang module. Therefore, operator
lookup for conformances has been changed to look in the overlay for
an imported declaration (if there is one).

This re-applies 361ab62454, reverted in
f50b1e73dc, after a /very/ long interval
where we decided if it was worth breaking people who've added these
conformances on their own. Since the workaround isn't too difficult---
use `#if swift(>=3.2)` to guard the extension introducing the
conformance---it was deemed acceptable.

https://bugs.swift.org/browse/SR-2388
2017-05-08 14:05:11 -07:00

96 lines
2.8 KiB
Swift

// RUN: %target-run-simple-swift
// REQUIRES: executable_test
// REQUIRES: objc_interop
import Foundation
import StdlibUnittest
var CFTestSuite = TestSuite("CoreFoundation")
extension CFString {
static func from(_ contents: String) -> CFString {
return CFStringCreateWithCString(nil, contents, /*ascii*/0)
}
}
CFTestSuite.test("Set<CFString>") {
var s = Set<CFString>()
// Use long strings to avoid the tagged pointer optimization.
s.insert(.from("abcxxxxxxxxxxx"))
s.insert(.from("defxxxxxxxxxxx"))
expectTrue(s.contains(.from("abcxxxxxxxxxxx")))
expectFalse(s.contains(.from("efxxxxxxxxxxx")))
expectTrue(s.contains("abcxxxxxxxxxxx" as NSString))
expectFalse(s.contains("efxxxxxxxxxxx" as NSString))
// Attempt to make this really a Swift string that's then bridged.
let good = "abcxxxxxxxxxxx"
expectTrue(s.contains(good as NSString))
let bad = "efxxxxxxxxxxx"
expectFalse(s.contains(bad as NSString))
}
CFTestSuite.test("AnyHashable") {
let strings = ["abc" as NSString as AnyHashable, "def" as CFString as AnyHashable]
expectTrue(strings.contains("abc"))
expectTrue(strings.contains("def"))
let stringSet = Set(strings)
expectTrue(stringSet.contains("abc"))
expectTrue(stringSet.contains("def"))
}
CFTestSuite.test("Dictionary/casting") {
let orig: [CFString: Any] = [
.from("abcxxxxxxxxxxx"): "abc",
.from("defxxxxxxxxxxx"): "def"
]
expectEqual(orig[.from("abcxxxxxxxxxxx")] as! String?, "abc")
let bridged = orig as [String: Any]
expectEqual(bridged["abcxxxxxxxxxxx"] as! String?, "abc")
let upcast = orig as [AnyHashable: Any]
expectEqual(upcast["abcxxxxxxxxxxx"] as! String?, "abc")
}
CFTestSuite.test("Dictionary/as CFDictionary") {
let orig: [CFString: Any] = [
.from("abcxxxxxxxxxxx"): "abc",
.from("defxxxxxxxxxxx"): "def"
]
expectEqual(orig[.from("abcxxxxxxxxxxx")] as! String?, "abc")
let cf = orig as CFDictionary
withExtendedLifetime(CFString.from("abcxxxxxxxxxxx")) {
expectTrue(CFDictionaryContainsKey(cf, Unmanaged.passUnretained($0).toOpaque()))
}
}
CFTestSuite.test("Dictionary/round-trip") {
let orig: [CFString: Any] = [
.from("abcxxxxxxxxxxx"): "abc",
.from("defxxxxxxxxxxx"): "def"
]
expectEqual(orig[.from("abcxxxxxxxxxxx")] as! String?, "abc")
let cf = orig as CFDictionary
// This is an unchecked cast because we can't check the types of CF objects.
let swiftTyped = cf as! [CFString: Any]
expectEqual(swiftTyped[.from("abcxxxxxxxxxxx")] as! String?, "abc")
let swiftBridged = cf as? [String: Any]
expectNotNil(swiftBridged)
expectEqual(swiftBridged!["abcxxxxxxxxxxx"] as! String?, "abc")
// FIXME: CF-to-AnyHashable isn't permitted yet, so we need 'as?'.
let swiftAny = cf as? [AnyHashable: Any]
expectNotNil(swiftAny)
expectEqual(swiftAny!["abcxxxxxxxxxxx"] as! String?, "abc")
}
runAllTests()