Răsfoiți Sursa

Add Dynamic.isError to check if the wrapped object is an error.

Mhd Hejazi 5 ani în urmă
părinte
comite
487f8eda1b

+ 3 - 2
Sources/Dynamic/Dynamic.swift

@@ -22,10 +22,10 @@ public class Dynamic: CustomDebugStringConvertible, Loggable {
 
 
     private let object: AnyObject?
     private let object: AnyObject?
     private let memberName: String?
     private let memberName: String?
-
     private var invocation: Invocation?
     private var invocation: Invocation?
     private var error: Error?
     private var error: Error?
 
 
+    public var isError: Bool { error != nil || object is Error }
     public var debugDescription: String { object?.debugDescription ?? "<nil>" }
     public var debugDescription: String { object?.debugDescription ?? "<nil>" }
 
 
     public init(_ object: Any?, memberName: String? = nil) {
     public init(_ object: Any?, memberName: String? = nil) {
@@ -122,7 +122,7 @@ public class Dynamic: CustomDebugStringConvertible, Loggable {
     }
     }
 
 
     private func callMethod(_ selector: String, with arguments: [Any?] = []) {
     private func callMethod(_ selector: String, with arguments: [Any?] = []) {
-        guard var target = object as? NSObject, !(object is Error) else { return }
+        guard var target = object as? NSObject, !isError else { return }
         log("Call: [\(type(of: target)) \(selector)]")
         log("Call: [\(type(of: target)) \(selector)]")
 
 
         var invocation: Invocation
         var invocation: Invocation
@@ -136,6 +136,7 @@ public class Dynamic: CustomDebugStringConvertible, Loggable {
         do {
         do {
             invocation = try Invocation(target: target, selector: NSSelectorFromString(selector))
             invocation = try Invocation(target: target, selector: NSSelectorFromString(selector))
         } catch {
         } catch {
+            print("WARNING: Trying to access an unrecognized member: \(type(of: target)).\(selector)")
             self.error = error
             self.error = error
             return
             return
         }
         }

+ 5 - 5
Sources/Dynamic/Invocation.swift

@@ -55,7 +55,7 @@ class Invocation: Loggable {
             let signature = (@convention(c)(NSObject, Selector, Selector) -> Any).self
             let signature = (@convention(c)(NSObject, Selector, Selector) -> Any).self
             let method = unsafeBitCast(target.method(for: selector), to: signature)
             let method = unsafeBitCast(target.method(for: selector), to: signature)
             guard let result = method(target, selector, self.selector) as? NSObject else {
             guard let result = method(target, selector, self.selector) as? NSObject else {
-                let error = InvocationError.doesNotRecognizeSelector(type(of: target), self.selector)
+                let error = InvocationError.unrecognizedSelector(type(of: target), self.selector)
                 log("ERROR:", error)
                 log("ERROR:", error)
                 throw error
                 throw error
             }
             }
@@ -89,7 +89,7 @@ class Invocation: Loggable {
             let signature = (@convention(c)(AnyObject, Selector, AnyObject) -> AnyObject).self
             let signature = (@convention(c)(AnyObject, Selector, AnyObject) -> AnyObject).self
             let method = unsafeBitCast(NSInvocation.method(for: selector), to: signature)
             let method = unsafeBitCast(NSInvocation.method(for: selector), to: signature)
             guard let result = method(NSInvocation, selector, methodSignature) as? NSObject else {
             guard let result = method(NSInvocation, selector, methodSignature) as? NSObject else {
-                let error = InvocationError.doesNotRecognizeSelector(type(of: target), self.selector)
+                let error = InvocationError.unrecognizedSelector(type(of: target), self.selector)
                 log("ERROR:", error)
                 log("ERROR:", error)
                 throw error
                 throw error
             }
             }
@@ -215,13 +215,13 @@ class Invocation: Loggable {
 }
 }
 
 
 public enum InvocationError: CustomNSError {
 public enum InvocationError: CustomNSError {
-    case doesNotRecognizeSelector(_ classType: AnyClass, _ selector: Selector)
+    case unrecognizedSelector(_ classType: AnyClass, _ selector: Selector)
 
 
     public static var errorDomain: String { String(describing: Invocation.self) }
     public static var errorDomain: String { String(describing: Invocation.self) }
 
 
     public var errorCode: Int {
     public var errorCode: Int {
         switch self {
         switch self {
-        case .doesNotRecognizeSelector:
+        case .unrecognizedSelector:
             return 404
             return 404
         }
         }
     }
     }
@@ -229,7 +229,7 @@ public enum InvocationError: CustomNSError {
     public var errorUserInfo: [String: Any] {
     public var errorUserInfo: [String: Any] {
         var message: String
         var message: String
         switch self {
         switch self {
-        case .doesNotRecognizeSelector(let classType, let selector):
+        case .unrecognizedSelector(let classType, let selector):
             message = "'\(String(describing: classType))' doesn't recognize selector '\(selector)'"
             message = "'\(String(describing: classType))' doesn't recognize selector '\(selector)'"
         }
         }
         return [NSLocalizedDescriptionKey: message]
         return [NSLocalizedDescriptionKey: message]

+ 1 - 0
Tests/DynamicTests/DynamicTests.swift

@@ -184,6 +184,7 @@ final class DynamicTests: XCTestCase {
     func testEdgeCases() {
     func testEdgeCases() {
         let error = ObjC.NSDateFormatter().invalidMethod()
         let error = ObjC.NSDateFormatter().invalidMethod()
         XCTAssertTrue(error.asObject is Error, "Calling non existing method should return error")
         XCTAssertTrue(error.asObject is Error, "Calling non existing method should return error")
+        XCTAssertTrue(error.isError, "isError should return true for errors")
 
 
         let errorChained = error.thisMethodCallHasNoEffect(123).randomProperty
         let errorChained = error.thisMethodCallHasNoEffect(123).randomProperty
         XCTAssertTrue(errorChained === error, "Calling methods and properties form error should return the same object")
         XCTAssertTrue(errorChained === error, "Calling methods and properties form error should return the same object")