Files
swift-mirror/test/Interpreter/SDK/class_getImageName.swift
Jordan Rose 2947fd5ff6 [test] Tweak class_getImageName to correctly handle 2018 OS betas
I messed up the condition here---'targetEnvironment(device)' is
ignored and should be written '!targetEnvironment(simulator)'---but
even besides that I didn't actually have the right conditions for
which iOS devices this passes on and which it doesn't. Rather than
trying to perfectly match this with an XFAIL, just skip the parts of
the test that depend on having a new enough 2018 OS build if we, well,
don't have it.

rdar://problem/42398849
2018-07-19 15:18:44 -07:00

133 lines
4.7 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-build-swift -emit-library -o %t/libGetImageNameHelper.dylib -emit-module %S/Inputs/class_getImageName-helper.swift -Xlinker -install_name -Xlinker @executable_path/libGetImageNameHelper.dylib
// RUN: %target-codesign %t/libGetImageNameHelper.dylib
// RUN: %target-build-swift -g %s -I %t -o %t/main -L %t -lGetImageNameHelper
// RUN: %target-run %t/main %t/libGetImageNameHelper.dylib
// REQUIRES: executable_test
// REQUIRES: objc_interop
import Darwin
import ObjectiveC
import GetImageNameHelper
import StdlibUnittest
func check(_ cls: AnyClass, in library: String) {
guard let imageName = class_getImageName(cls) else {
expectUnreachable("could not find image for \(cls)")
return
}
expectTrue(String(cString: imageName).hasSuffix(library),
"wrong library for \(cls)")
}
var newOSButCannotUseObjCRuntimeHook = false
if #available(macOS 10.14, iOS 12, tvOS 12, watchOS 5, *) {
// The only place these tests will fail is on early versions of the 2018 OSs.
// The final versions will have 'objc_setHook_getImageName'; anything earlier
// will be handled by manually overwriting the original implementation of
// 'class_getImageName'.
newOSButCannotUseObjCRuntimeHook =
(nil == dlsym(UnsafeMutableRawPointer(bitPattern: -2),
"objc_setHook_getImageName"))
}
var testSuite = TestSuite("class_getImageName")
testSuite.test("Simple") {
check(SimpleSwiftObject.self, in: "libGetImageNameHelper.dylib")
check(SimpleNSObject.self, in: "libGetImageNameHelper.dylib")
}
testSuite.test("Generic")
.skip(.custom({ newOSButCannotUseObjCRuntimeHook },
reason: "hook for class_getImageName not present"))
.code {
check(GenericSwiftObject<Int>.self, in: "libGetImageNameHelper.dylib")
check(GenericSwiftObject<NSObject>.self, in: "libGetImageNameHelper.dylib")
check(GenericNSObject<Int>.self, in: "libGetImageNameHelper.dylib")
check(GenericNSObject<NSObject>.self, in: "libGetImageNameHelper.dylib")
}
testSuite.test("GenericAncestry")
.skip(.custom({ newOSButCannotUseObjCRuntimeHook },
reason: "hook for class_getImageName not present"))
.code {
check(GenericAncestrySwiftObject.self, in: "libGetImageNameHelper.dylib")
check(GenericAncestryNSObject.self, in: "libGetImageNameHelper.dylib")
}
testSuite.test("Resilient") {
check(ResilientFieldSwiftObject.self, in: "libGetImageNameHelper.dylib")
check(ResilientFieldNSObject.self, in: "libGetImageNameHelper.dylib")
}
testSuite.test("ObjC") {
check(NSObject.self, in: "libobjc.A.dylib")
}
testSuite.test("KVO/Simple") {
// We use object_getClass in this test to not look through KVO's artificial
// subclass.
let obj = SimpleNSObject()
autoreleasepool {
let observation = obj.observe(\.observableName) { _, _ in }
withExtendedLifetime(observation) {
let theClass = object_getClass(obj)
precondition(theClass !== SimpleNSObject.self, "no KVO subclass?")
expectNil(class_getImageName(theClass),
"should match what happens with NSObject (below)")
}
}
}
testSuite.test("KVO/GenericAncestry") {
// We use object_getClass in this test to not look through KVO's artificial
// subclass.
let obj = GenericAncestryNSObject()
autoreleasepool {
let observation = obj.observe(\.observableName) { _, _ in }
withExtendedLifetime(observation) {
let theClass = object_getClass(obj)
precondition(theClass !== GenericAncestryNSObject.self, "no KVO subclass?")
expectNil(class_getImageName(theClass),
"should match what happens with NSObject (below)")
}
}
}
testSuite.test("KVO/ObjC") {
// We use object_getClass in this test to not look through KVO's artificial
// subclass.
let obj = NSObject()
autoreleasepool {
let observation = obj.observe(\.description) { _, _ in }
withExtendedLifetime(observation) {
let theClass = object_getClass(obj)
precondition(theClass !== NSObject.self, "no KVO subclass?")
expectNil(class_getImageName(theClass),
"should match what happens with the Swift objects (above)")
}
}
}
testSuite.test("dynamic") {
let newClass: AnyClass = objc_allocateClassPair(/*superclass*/nil,
"CompletelyDynamic",
/*extraBytes*/0)!
objc_registerClassPair(newClass)
// We don't actually care what the result is; we just need to not crash.
_ = class_getImageName(newClass)
}
testSuite.test("nil") {
// The ObjC runtime should handle this before it even gets to Swift's custom
// implementation, but just in case.
expectNil(class_getImageName(nil))
}
runAllTests()