Files
swift-mirror/test/stdlib/ErrorBridged.swift
Brent Royal-Gordon 1875783734 Use more robust Swift type names for error domains
getErrorDomainStringForObjC() now includes the parent types in the error domain string. Its implementation does not support generic types or private discriminators, but those types can’t be PrintAsObjC’d anyway, so we should never see them.
2018-12-21 15:45:23 -08:00

771 lines
23 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-build-swift -o %t/ErrorBridged -DPTR_SIZE_%target-ptrsize -module-name main %s
// RUN: %target-run %t/ErrorBridged
// REQUIRES: executable_test
// REQUIRES: objc_interop
import StdlibUnittest
import Foundation
import CoreLocation
import Darwin
var ErrorBridgingTests = TestSuite("ErrorBridging")
var NoisyErrorLifeCount = 0
var NoisyErrorDeathCount = 0
var CanaryHandle = 0
protocol OtherProtocol {
var otherProperty: String { get }
}
protocol OtherClassProtocol : class {
var otherClassProperty: String { get }
}
class NoisyError : Error, OtherProtocol, OtherClassProtocol {
init() { NoisyErrorLifeCount += 1 }
deinit { NoisyErrorDeathCount += 1 }
let _domain = "NoisyError"
let _code = 123
let otherProperty = "otherProperty"
let otherClassProperty = "otherClassProperty"
}
@objc enum EnumError : Int, Error {
case BadError = 9000
case ReallyBadError = 9001
}
ErrorBridgingTests.test("NSError") {
NoisyErrorLifeCount = 0
NoisyErrorDeathCount = 0
autoreleasepool {
let ns = NSError(domain: "SomeDomain", code: 321, userInfo: nil)
objc_setAssociatedObject(ns, &CanaryHandle, NoisyError(),
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
let e: Error = ns
expectEqual(e._domain, "SomeDomain")
expectEqual(e._code, 321)
let ns2 = e as NSError
expectTrue(ns === ns2)
expectEqual(ns2._domain, "SomeDomain")
expectEqual(ns2._code, 321)
}
expectEqual(NoisyErrorDeathCount, NoisyErrorLifeCount)
}
ErrorBridgingTests.test("NSCopying") {
autoreleasepool {
let orig = EnumError.ReallyBadError as NSError
let copy = orig.copy() as! NSError
expectEqual(orig, copy)
}
}
// Gated on the availability of NSKeyedArchiver.archivedData(withRootObject:).
@available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)
func archiveAndUnarchiveObject<T: NSCoding>(
_ object: T
) -> T?
where T: NSObject {
let unarchiver = NSKeyedUnarchiver(forReadingWith:
NSKeyedArchiver.archivedData(withRootObject: object)
)
unarchiver.requiresSecureCoding = true
return unarchiver.decodeObject(of: T.self, forKey: "root")
}
ErrorBridgingTests.test("NSCoding") {
if #available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
autoreleasepool {
let orig = EnumError.ReallyBadError as NSError
let unarchived = archiveAndUnarchiveObject(orig)!
expectEqual(orig, unarchived)
expectTrue(type(of: unarchived) == NSError.self)
}
}
}
ErrorBridgingTests.test("NSError-to-enum bridging") {
NoisyErrorLifeCount = 0
NoisyErrorDeathCount = 0
let testURL = URL(string: "https://swift.org")!
autoreleasepool {
let underlyingError = CocoaError(.fileLocking)
as Error as NSError
let ns = NSError(domain: NSCocoaErrorDomain,
code: NSFileNoSuchFileError,
userInfo: [
NSFilePathErrorKey: "/dev/null",
NSStringEncodingErrorKey: /*ASCII=*/1,
NSUnderlyingErrorKey: underlyingError,
NSURLErrorKey: testURL
])
objc_setAssociatedObject(ns, &CanaryHandle, NoisyError(),
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
let e: Error = ns
let cocoaCode: Int?
switch e {
case let x as CocoaError:
cocoaCode = x._code
expectTrue(x.isFileError)
expectEqual(x.code, .fileNoSuchFile)
default:
cocoaCode = nil
}
expectEqual(NSFileNoSuchFileError, cocoaCode)
let cocoaCode2: Int? = (ns as? CocoaError)?._code
expectEqual(NSFileNoSuchFileError, cocoaCode2)
let isNoSuchFileError: Bool
switch e {
case CocoaError.fileNoSuchFile:
isNoSuchFileError = true
default:
isNoSuchFileError = false
}
expectTrue(isNoSuchFileError)
// Check the contents of the error.
let cocoaError = e as! CocoaError
expectEqual("/dev/null", cocoaError.filePath)
expectEqual(String.Encoding.ascii, cocoaError.stringEncoding)
expectEqual(underlyingError, cocoaError.underlying.map { $0 as NSError })
expectEqual(testURL, cocoaError.url)
// URLError domain
let nsURL = NSError(domain: NSURLErrorDomain,
code: NSURLErrorBadURL,
userInfo: [NSURLErrorFailingURLErrorKey: testURL])
let eURL: Error = nsURL
let isBadURLError: Bool
switch eURL {
case URLError.badURL:
isBadURLError = true
default:
isBadURLError = false
}
expectTrue(isBadURLError)
let urlError = eURL as! URLError
expectEqual(testURL, urlError.failingURL)
expectNil(urlError.failureURLPeerTrust)
// CoreLocation error domain
let nsCL = NSError(domain: kCLErrorDomain,
code: CLError.headingFailure.rawValue,
userInfo: [NSURLErrorKey: testURL])
let eCL: Error = nsCL
let isHeadingFailure: Bool
switch eCL {
case CLError.headingFailure:
isHeadingFailure = true
default:
isHeadingFailure = false
}
let isCLError: Bool
switch eCL {
case let error as CLError:
isCLError = true
expectEqual(testURL, (error as NSError).userInfo[NSURLErrorKey] as? URL)
expectEqual(testURL, error.userInfo[NSURLErrorKey] as? URL)
default:
isCLError = false
}
expectTrue(isCLError)
// NSPOSIXError domain
let nsPOSIX = NSError(domain: NSPOSIXErrorDomain,
code: Int(EDEADLK),
userInfo: [:])
let ePOSIX: Error = nsPOSIX
let isDeadlock: Bool
switch ePOSIX {
case POSIXError.EDEADLK:
isDeadlock = true
default:
isDeadlock = false
}
expectTrue(isDeadlock)
// NSMachError domain
let nsMach = NSError(domain: NSMachErrorDomain,
code: Int(KERN_MEMORY_FAILURE),
userInfo: [:])
let eMach: Error = nsMach
let isMemoryFailure: Bool
switch eMach {
case MachError.memoryFailure:
isMemoryFailure = true
default:
isMemoryFailure = false
}
expectTrue(isMemoryFailure)
}
expectEqual(NoisyErrorDeathCount, NoisyErrorLifeCount)
}
func opaqueUpcastToAny<T>(_ x: T) -> Any {
return x
}
struct StructError: Error {
var _domain: String { return "StructError" }
var _code: Int { return 4812 }
}
ErrorBridgingTests.test("Error-to-NSError bridging") {
NoisyErrorLifeCount = 0
NoisyErrorDeathCount = 0
autoreleasepool {
let e: Error = NoisyError()
let ns = e as NSError
let ns2 = e as NSError
expectTrue(ns === ns2)
expectEqual(ns._domain, "NoisyError")
expectEqual(ns._code, 123)
let e3: Error = ns
expectEqual(e3._domain, "NoisyError")
expectEqual(e3._code, 123)
let ns3 = e3 as NSError
expectTrue(ns === ns3)
let nativeNS = NSError(domain: NSCocoaErrorDomain,
code: NSFileNoSuchFileError,
userInfo: nil)
objc_setAssociatedObject(ns, &CanaryHandle, NoisyError(),
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
let nativeE: Error = nativeNS
let nativeNS2 = nativeE as NSError
expectTrue(nativeNS === nativeNS2)
expectEqual(nativeNS2._domain, NSCocoaErrorDomain)
expectEqual(nativeNS2._code, NSFileNoSuchFileError)
let any: Any = NoisyError()
let ns4 = any as! NSError
expectEqual(ns4._domain, "NoisyError")
expectEqual(ns4._code, 123)
let ao: AnyObject = NoisyError()
let ns5 = ao as! NSError
expectEqual(ns5._domain, "NoisyError")
expectEqual(ns5._code, 123)
let any2: Any = StructError()
let ns6 = any2 as! NSError
expectEqual(ns6._domain, "StructError")
expectEqual(ns6._code, 4812)
}
expectEqual(NoisyErrorDeathCount, NoisyErrorLifeCount)
}
ErrorBridgingTests.test("NSError-to-error bridging in bridged container") {
autoreleasepool {
let error = NSError(domain: "domain", code: 42, userInfo: nil)
let nsdictionary = ["error": error] as NSDictionary
let dictionary = nsdictionary as? Dictionary<String, Error>
expectNotNil(dictionary)
expectEqual(error, dictionary?["error"] as NSError?)
}
}
ErrorBridgingTests.test("enum-to-NSError round trip") {
autoreleasepool {
// Emulate throwing an error from Objective-C.
func throwNSError(_ error: EnumError) throws {
throw NSError(domain: "main.EnumError", code: error.rawValue,
userInfo: [:])
}
var caughtError: Bool
caughtError = false
do {
try throwNSError(.BadError)
expectUnreachable()
} catch let error as EnumError {
expectEqual(.BadError, error)
caughtError = true
} catch _ {
expectUnreachable()
}
expectTrue(caughtError)
caughtError = false
do {
try throwNSError(.ReallyBadError)
expectUnreachable()
} catch EnumError.BadError {
expectUnreachable()
} catch EnumError.ReallyBadError {
caughtError = true
} catch _ {
expectUnreachable()
}
expectTrue(caughtError)
}
}
class SomeNSErrorSubclass: NSError {}
ErrorBridgingTests.test("Thrown NSError identity is preserved") {
do {
let e = NSError(domain: "ClericalError", code: 219,
userInfo: ["yeah": "yeah"])
do {
throw e
} catch let e2 as NSError {
expectTrue(e === e2)
expectTrue(e2.userInfo["yeah"] as? String == "yeah")
} catch {
expectUnreachable()
}
}
do {
let f = SomeNSErrorSubclass(domain: "ClericalError", code: 219,
userInfo: ["yeah": "yeah"])
do {
throw f
} catch let f2 as NSError {
expectTrue(f === f2)
expectTrue(f2.userInfo["yeah"] as? String == "yeah")
} catch {
expectUnreachable()
}
}
}
// Check errors customized via protocol.
struct MyCustomizedError : Error {
let code: Int
}
extension MyCustomizedError : LocalizedError {
var errorDescription: String? {
return NSLocalizedString("something went horribly wrong", comment: "")
}
var failureReason: String? {
return NSLocalizedString("because someone wrote 'throw'", comment: "")
}
var recoverySuggestion: String? {
return NSLocalizedString("delete the 'throw'", comment: "")
}
var helpAnchor: String? {
return NSLocalizedString("there is no help when writing tests", comment: "")
}
}
extension MyCustomizedError : CustomNSError {
static var errorDomain: String {
return "custom"
}
/// The error code within the given domain.
var errorCode: Int {
return code
}
/// The user-info dictionary.
var errorUserInfo: [String : Any] {
return [NSURLErrorKey : URL(string: "https://swift.org")!]
}
}
extension MyCustomizedError : RecoverableError {
var recoveryOptions: [String] {
return ["Delete 'throw'", "Disable the test" ]
}
func attemptRecovery(optionIndex recoveryOptionIndex: Int) -> Bool {
return recoveryOptionIndex == 0
}
}
/// An error type that provides localization and recovery, but doesn't
/// customize NSError directly.
enum MySwiftCustomizedError : Error {
case failed
static var errorDescriptionCount = 0
}
extension MySwiftCustomizedError : LocalizedError {
var errorDescription: String? {
MySwiftCustomizedError.errorDescriptionCount =
MySwiftCustomizedError.errorDescriptionCount + 1
return NSLocalizedString("something went horribly wrong", comment: "")
}
var failureReason: String? {
return NSLocalizedString("because someone wrote 'throw'", comment: "")
}
var recoverySuggestion: String? {
return NSLocalizedString("delete the 'throw'", comment: "")
}
var helpAnchor: String? {
return NSLocalizedString("there is no help when writing tests", comment: "")
}
}
extension MySwiftCustomizedError : RecoverableError {
var recoveryOptions: [String] {
return ["Delete 'throw'", "Disable the test" ]
}
func attemptRecovery(optionIndex recoveryOptionIndex: Int) -> Bool {
return recoveryOptionIndex == 0
}
}
/// Fake definition of the informal protocol
/// "NSErrorRecoveryAttempting" that we use to poke at the object
/// produced for a RecoverableError.
@objc protocol FakeNSErrorRecoveryAttempting {
@objc(attemptRecoveryFromError:optionIndex:delegate:didRecoverSelector:contextInfo:)
func attemptRecovery(fromError nsError: Error,
optionIndex recoveryOptionIndex: Int,
delegate: AnyObject?,
didRecoverSelector: Selector,
contextInfo: UnsafeMutableRawPointer?)
@objc(attemptRecoveryFromError:optionIndex:)
func attemptRecovery(fromError nsError: Error,
optionIndex recoveryOptionIndex: Int) -> Bool
}
class RecoveryDelegate {
let expectedSuccess: Bool
let expectedContextInfo: UnsafeMutableRawPointer?
var called = false
init(expectedSuccess: Bool,
expectedContextInfo: UnsafeMutableRawPointer?) {
self.expectedSuccess = expectedSuccess
self.expectedContextInfo = expectedContextInfo
}
@objc func recover(success: Bool, contextInfo: UnsafeMutableRawPointer?) {
expectEqual(expectedSuccess, success)
expectEqual(expectedContextInfo, contextInfo)
called = true
}
}
/// Helper for testing a customized error.
func testCustomizedError(error: Error, nsError: NSError) {
// LocalizedError
if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
expectNil(nsError.userInfo[NSLocalizedDescriptionKey])
expectNil(nsError.userInfo[NSLocalizedFailureReasonErrorKey])
expectNil(nsError.userInfo[NSLocalizedRecoverySuggestionErrorKey])
expectNil(nsError.userInfo[NSHelpAnchorErrorKey])
} else {
expectEqual("something went horribly wrong",
nsError.userInfo[NSLocalizedDescriptionKey] as? String)
expectEqual("because someone wrote 'throw'",
nsError.userInfo[NSLocalizedFailureReasonErrorKey] as? String)
expectEqual("delete the 'throw'",
nsError.userInfo[NSLocalizedRecoverySuggestionErrorKey] as? String)
expectEqual("there is no help when writing tests",
nsError.userInfo[NSHelpAnchorErrorKey] as? String)
}
expectEqual("something went horribly wrong", error.localizedDescription)
expectEqual("something went horribly wrong", nsError.localizedDescription)
expectEqual("because someone wrote 'throw'", nsError.localizedFailureReason)
expectEqual("delete the 'throw'", nsError.localizedRecoverySuggestion)
expectEqual("there is no help when writing tests", nsError.helpAnchor)
// RecoverableError
if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
expectNil(nsError.userInfo[NSLocalizedRecoveryOptionsErrorKey])
} else {
expectEqual(["Delete 'throw'", "Disable the test" ],
nsError.userInfo[NSLocalizedRecoveryOptionsErrorKey] as? [String])
}
expectEqual(["Delete 'throw'", "Disable the test" ],
nsError.localizedRecoveryOptions)
// Directly recover.
let ctx = UnsafeMutableRawPointer(bitPattern:0x1234567)
let attempter: AnyObject
if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
expectNil(nsError.userInfo[NSRecoveryAttempterErrorKey])
attempter = nsError.recoveryAttempter! as AnyObject
} else {
attempter = nsError.userInfo[NSRecoveryAttempterErrorKey]! as AnyObject
}
expectEqual(attempter.attemptRecovery(fromError: nsError, optionIndex: 0), true)
expectEqual(attempter.attemptRecovery(fromError: nsError, optionIndex: 1), false)
// Recover through delegate.
let rd1 = RecoveryDelegate(expectedSuccess: true, expectedContextInfo: ctx)
expectEqual(false, rd1.called)
attempter.attemptRecovery(
fromError: nsError,
optionIndex: 0,
delegate: rd1,
didRecoverSelector: #selector(RecoveryDelegate.recover(success:contextInfo:)),
contextInfo: ctx)
expectEqual(true, rd1.called)
let rd2 = RecoveryDelegate(expectedSuccess: false, expectedContextInfo: nil)
expectEqual(false, rd2.called)
attempter.attemptRecovery(
fromError: nsError,
optionIndex: 1,
delegate: rd2,
didRecoverSelector: #selector(RecoveryDelegate.recover(success:contextInfo:)),
contextInfo: nil)
expectEqual(true, rd2.called)
}
ErrorBridgingTests.test("Customizing NSError via protocols") {
let error = MyCustomizedError(code: 12345)
let nsError = error as NSError
// CustomNSError
expectEqual("custom", nsError.domain)
expectEqual(12345, nsError.code)
expectEqual(URL(string: "https://swift.org"),
nsError.userInfo[NSURLErrorKey] as? URL)
testCustomizedError(error: error, nsError: nsError)
}
ErrorBridgingTests.test("Customizing localization/recovery via protocols") {
let error = MySwiftCustomizedError.failed
let nsError = error as NSError
testCustomizedError(error: error, nsError: nsError)
}
ErrorBridgingTests.test("Customizing localization/recovery laziness") {
let countBefore = MySwiftCustomizedError.errorDescriptionCount
let error = MySwiftCustomizedError.failed
let nsError = error as NSError
// RecoverableError
if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
expectNil(nsError.userInfo[NSLocalizedRecoveryOptionsErrorKey])
} else {
expectEqual(["Delete 'throw'", "Disable the test" ],
nsError.userInfo[NSLocalizedRecoveryOptionsErrorKey] as? [String])
}
expectEqual(["Delete 'throw'", "Disable the test" ], nsError.localizedRecoveryOptions)
// None of the operations above should affect the count
if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
expectEqual(countBefore, MySwiftCustomizedError.errorDescriptionCount)
}
// This one does affect the count.
expectEqual("something went horribly wrong", error.localizedDescription)
// Check that we did get a call to errorDescription.
if #available(OSX 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
expectEqual(countBefore+1, MySwiftCustomizedError.errorDescriptionCount)
}
}
enum DefaultCustomizedError1 : CustomNSError {
case bad
case worse
}
enum DefaultCustomizedError2 : Int, CustomNSError {
case bad = 7
case worse = 13
}
enum DefaultCustomizedError3 : UInt, CustomNSError {
case bad = 9
case worse = 115
#if PTR_SIZE_64
case dreadful = 0xFFFFFFFFFFFFFFFF
#elseif PTR_SIZE_32
case dreadful = 0xFFFFFFFF
#else
#error ("Unknown pointer size")
#endif
static var errorDomain: String {
return "customized3"
}
}
enum DefaultCustomizedParent {
enum ChildError: CustomNSError {
case foo
}
}
ErrorBridgingTests.test("Default-customized via CustomNSError") {
expectEqual(1, (DefaultCustomizedError1.worse as NSError).code)
expectEqual(13, (DefaultCustomizedError2.worse as NSError).code)
expectEqual(115, (DefaultCustomizedError3.worse as NSError).code)
expectEqual(-1, (DefaultCustomizedError3.dreadful as NSError).code)
expectEqual("main.DefaultCustomizedError1", (DefaultCustomizedError1.worse as NSError).domain)
expectEqual("customized3", (DefaultCustomizedError3.worse as NSError).domain)
expectEqual("main.DefaultCustomizedParent.ChildError", (DefaultCustomizedParent.ChildError.foo as NSError).domain)
}
class MyNSError : NSError { }
ErrorBridgingTests.test("NSError subclass identity") {
let myNSError: Error = MyNSError(domain: "MyNSError", code: 0, userInfo: [:])
let nsError = myNSError as NSError
expectTrue(type(of: nsError) == MyNSError.self)
}
ErrorBridgingTests.test("Wrapped NSError identity") {
let nsError = NSError(domain: NSCocoaErrorDomain,
code: NSFileNoSuchFileError,
userInfo: [
NSFilePathErrorKey : "/dev/null",
NSStringEncodingErrorKey : /*ASCII=*/1,
])
let error: Error = nsError
let nsError2: NSError = error as NSError
expectTrue(nsError === nsError2)
// Extracting the NSError via the runtime.
let cocoaErrorAny: Any = error as! CocoaError
let nsError3: NSError = cocoaErrorAny as! NSError
expectTrue(nsError === nsError3)
if let cocoaErrorAny2: Any = error as? CocoaError {
let nsError4: NSError = cocoaErrorAny2 as! NSError
expectTrue(nsError === nsError4)
} else {
expectUnreachable()
}
// Extracting the NSError via direct call.
let cocoaError = error as! CocoaError
let nsError5: NSError = cocoaError as NSError
expectTrue(nsError === nsError5)
if error is CocoaError {
let nsError6: NSError = cocoaError as NSError
expectTrue(nsError === nsError6)
} else {
expectUnreachable()
}
}
extension Error {
func asNSError() -> NSError {
return self as NSError
}
}
func unconditionalCast<T>(_ x: Any, to: T.Type) -> T {
return x as! T
}
func conditionalCast<T>(_ x: Any, to: T.Type) -> T? {
return x as? T
}
// SR-1562
ErrorBridgingTests.test("Error archetype identity") {
let myError = NSError(domain: "myErrorDomain", code: 0,
userInfo: [ "one" : 1 ])
expectTrue(myError === myError.asNSError())
expectTrue(unconditionalCast(myError, to: Error.self) as NSError
=== myError)
expectTrue(conditionalCast(myError, to: Error.self)! as NSError
=== myError)
let nsError = NSError(domain: NSCocoaErrorDomain,
code: NSFileNoSuchFileError,
userInfo: [
NSFilePathErrorKey : "/dev/null",
NSStringEncodingErrorKey : /*ASCII=*/1,
])
let cocoaError = nsError as Error as! CocoaError
expectTrue(cocoaError.asNSError() === nsError)
expectTrue(unconditionalCast(cocoaError, to: Error.self) as NSError
=== nsError)
expectTrue(conditionalCast(cocoaError, to: Error.self)! as NSError
=== nsError)
}
// SR-9389
class ParentA: NSObject {
@objc(ParentAError) enum Error: Int, Swift.Error {
case failed
}
}
class ParentB: NSObject {
@objc(ParentBError) enum Error: Int, Swift.Error {
case failed
}
}
private class NonPrintAsObjCClass: NSObject {
@objc enum Error: Int, Swift.Error {
case foo
}
}
@objc private enum NonPrintAsObjCError: Int, Error {
case bar
}
ErrorBridgingTests.test("@objc error domains for nested types") {
// Domain strings should correspond to Swift types, including parent types.
expectEqual(ParentA.Error.failed._domain, "main.ParentA.Error")
expectEqual(ParentB.Error.failed._domain, "main.ParentB.Error")
func makeNSError(like error: Error) -> NSError {
return NSError(domain: error._domain, code: error._code)
}
// NSErrors corresponding to Error types with the same name but nested in
// different enclosing types should not be castable to the wrong error type.
expectTrue(makeNSError(like: ParentA.Error.failed) is ParentA.Error)
expectFalse(makeNSError(like: ParentA.Error.failed) is ParentB.Error)
expectFalse(makeNSError(like: ParentB.Error.failed) is ParentA.Error)
expectTrue(makeNSError(like: ParentB.Error.failed) is ParentB.Error)
// If an @objc enum error is not eligible for PrintAsObjC, we should treat it
// as though it inherited the default implementation, which calls
// String(reflecting:).
expectEqual(NonPrintAsObjCClass.Error.foo._domain,
String(reflecting: NonPrintAsObjCClass.Error.self))
expectEqual(NonPrintAsObjCError.bar._domain,
String(reflecting: NonPrintAsObjCError.self))
}
runAllTests()