From 82c32d7dee65ef7321311e74fa2c38836fa56733 Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Fri, 31 Oct 2014 17:14:55 -0400 Subject: [PATCH 01/15] New: Implementation of the CoreFoundation CFError This commit adds an implementation of the CoreFoundation CFError classes and functions. --- Objective-J/CFError.js | 158 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 Objective-J/CFError.js diff --git a/Objective-J/CFError.js b/Objective-J/CFError.js new file mode 100644 index 000000000..5169de5c6 --- /dev/null +++ b/Objective-J/CFError.js @@ -0,0 +1,158 @@ +/* + * CFError.js + * Objective-J + * + * Created by Andrew Hankinson. + * Copyright 2014, Andrew Hankinson. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +GLOBAL(kCFErrorLocalizedDescriptionKey) = "CPLocalizedDescription"; +GLOBAL(kCFErrorLocalizedFailureReasonKey) = "CPLocalizedFailureReason"; +GLOBAL(kCFErrorLocalizedRecoverySuggestionKey) = "CPLocalizedRecoverySuggestion"; +GLOBAL(kCFErrorDescriptionKey) = "CPDescription"; +GLOBAL(kCFErrorUnderlyingErrorKey) = "CPUnderlyingError"; + +GLOBAL(kCFErrorURLKey) = "_kCFErrorURLKey"; +GLOBAL(kCFErrorFilePathKey) = "_kCFErrorFilePathKey"; + +// GLOBAL(kCFErrorDomainPOSIX) = ""; +// GLOBAL(kCFErrorDomainOSStatus) = ""; +// GLOBAL(kCFErrorDomainMach) = ""; +GLOBAL(kCFErrorDomainCappuccino) = "CPErrorDomainCappuccino"; +GLOBAL(kCFErrorDomainCocoa) = kCFErrorDomainCappuccino; + + +GLOBAL(CFError) = function(/* CFString */ domain, /* int */ code, /* CFDictionary */ userInfo) +{ + this._domain = domain || NULL; + this._code = code || NULL; + this._userInfo = userInfo || new CFDictionary(); + this._UID = objj_generateObjectUID(); +} + +CFError.prototype.domain = function () +{ + return this._domain; +} +DISPLAY_NAME(CFError.prototype.domain) + +CFError.prototype.code = function () +{ + return this._code; +} +DISPLAY_NAME(CFError.prototype.code) + +/* + This follows the same logic to generate a description as the "real" CFError. +*/ +CFError.prototype.description = function () +{ + var localizedDesc = this._userInfo.valueForKey(kCFErrorLocalizedDescriptionKey); + if (localizedDesc) + return localizedDesc; + + var reason = this._userInfo.valueForKey(kCFErrorLocalizedFailureReasonKey); + if (reason) + { + var operationFailedStr = "The operation couldn\u2019t be completed. " + reason; + return operationFailedStr; + } + + // @TODO Add the bundle localized domain handler. + var result = "", + desc = this._userInfo.valueForKey(kCFErrorDescriptionKey); + if (desc) + { + // we have a description key. + var result = "The operation couldn\u2019t be completed. (error " + this._code + "- " + desc + ")"; + } + else + { + // just use error and code; + var result = "The operation couldn\u2019t be completed. (error " + this._code + ")"; + } + + return result; +} +DISPLAY_NAME(CFError.prototype.description) + +CFError.prototype.failureReason = function () +{ + return this._userInfo.valueForKey(kCFErrorLocalizedFailureReasonKey); +} +DISPLAY_NAME(CFError.prototype.failureReason) + +CFError.prototype.recoverySuggestion = function () +{ + return this._userInfo.valueForKey(kCFErrorLocalizedRecoverySuggestionKey); +} +DISPLAY_NAME(CFError.prototype.recoverySuggestion) + +CFError.prototype.userInfo = function () +{ + return this._userInfo; +} +DISPLAY_NAME(CFError.prototype.userInfo) + +/* + CFError Bridge Functions + The "Create" and "Copy" in the function names do not have any meaning + in Cappuccino; they are bridged here for compatibility reasons only. +*/ +GLOBAL(CFErrorCreate) = function(/* String */ domain, /*int */ code, /* CFDictionary */ userInfo) +{ + return new CFError(domain, code, userInfo); +} + +GLOBAL(CFErrorCreateWithUserInfoKeysAndValues) = function(/* String */ domain, /* int */ code, /* array */ userInfoKeys, /* array */ userInfoValues, /* int */ numUserInfoValues) +{ + var userInfo = new CFDictionary(); + while(numUserInfoValues--) + userInfo.setValueForKey(userInfoKeys[numUserInfoValues], userInfoValues[numUserInfoValues]); + + return new CFError(domain, code, userInfo); +} + +GLOBAL(CFErrorGetCode) = function(/* CFError */ err) +{ + return err.code; +} + +GLOBAL(CFErrorGetDomain) = function(/* CFError */ err) +{ + return err.domain; +} + +GLOBAL(CFErrorCopyDescription) = function(/* CFError */ err) +{ + return err.description; +} + +GLOBAL(CFErrorCopyUserInfo) = function(/* CFError */ err) +{ + return err.userInfo; +} + +GLOBAL(CFErrorCopyFailureReason) = function(/* CFError */ err) +{ + return err.failureReason; +} + +GLOBAL(CFErrorCopyRecoverySuggestion) = function(/* CFError */err) +{ + return err.recoverySuggestion; +} From 49cb446f8b36f0e141111f258334b0bda5b7dfd0 Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Fri, 31 Oct 2014 17:15:52 -0400 Subject: [PATCH 02/15] New: Initial commit of CFNetworkErrors file This commit adds constants for CFURL Errors to enable cross-compatibility with the Cocoa CF and CPURL error reporting functions --- Objective-J/CFNetworkErrors.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Objective-J/CFNetworkErrors.js diff --git a/Objective-J/CFNetworkErrors.js b/Objective-J/CFNetworkErrors.js new file mode 100644 index 000000000..9473579b9 --- /dev/null +++ b/Objective-J/CFNetworkErrors.js @@ -0,0 +1,25 @@ +GLOBAL(kCFURLErrorUnknown) = -998; +GLOBAL(kCFURLErrorCancelled) = -999; +GLOBAL(kCFURLErrorBadURL) = -1000; +GLOBAL(kCFURLErrorTimedOut) = -1001; +GLOBAL(kCFURLErrorUnsupportedURL) = -1002; +GLOBAL(kCFURLErrorCannotFindHost) = -1003; +GLOBAL(kCFURLErrorCannotConnectToHost) = -1004; +GLOBAL(kCFURLErrorNetworkConnectionLost) = -1005; +GLOBAL(kCFURLErrorDNSLookupFailed) = -1006; +GLOBAL(kCFURLErrorHTTPTooManyRedirects) = -1007; +GLOBAL(kCFURLErrorResourceUnavailable) = -1008; +GLOBAL(kCFURLErrorNotConnectedToInternet) = -1009; +GLOBAL(kCFURLErrorRedirectToNonExistentLocation) = -1010; +GLOBAL(kCFURLErrorBadServerResponse) = -1011; +GLOBAL(kCFURLErrorUserCancelledAuthentication) = -1012; +GLOBAL(kCFURLErrorUserAuthenticationRequired) = -1013; +GLOBAL(kCFURLErrorZeroByteResource) = -1014; +GLOBAL(kCFURLErrorCannotDecodeRawData) = -1015; +GLOBAL(kCFURLErrorCannotDecodeContentData) = -1016; +GLOBAL(kCFURLErrorCannotParseResponse) = -1017; +GLOBAL(kCFURLErrorRequestBodyStreamExhausted) = -1021; +GLOBAL(kCFURLErrorFileDoesNotExist) = -1100; +GLOBAL(kCFURLErrorFileIsDirectory) = -1101; +GLOBAL(kCFURLErrorNoPermissionsToReadFile) = -1102; +GLOBAL(kCFURLErrorDataLengthExceedsMaximum) = -1103; \ No newline at end of file From 0399b3daeda48760471a36d0cbfec578b2b2679a Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 07:41:51 -0400 Subject: [PATCH 03/15] Fixed: Renamed CPCoder method to match language Previously CPCoder had a method named "encodeValueOfObjCType" which is a misnomer. This commit renames the method to "encodeValueOfObjJType." --- Foundation/CPCoder.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Foundation/CPCoder.j b/Foundation/CPCoder.j index d02d918e0..0bdc7b89a 100644 --- a/Foundation/CPCoder.j +++ b/Foundation/CPCoder.j @@ -53,7 +53,7 @@ @param aType the structure or object type @param anObject the object to be encoded */ -- (void)encodeValueOfObjCType:(CPString)aType at:(id)anObject +- (void)encodeValueOfObjJType:(CPString)aType at:(id)anObject { _CPRaiseInvalidAbstractInvocation(self, _cmd); } From a34e8fbc9aa5c5cdc4a3ec8d2e4ebab5fbbc42ac Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 08:59:10 -0400 Subject: [PATCH 04/15] Fixed method calls for global CFError methods --- Objective-J/CFError.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Objective-J/CFError.js b/Objective-J/CFError.js index 5169de5c6..545c7eef5 100644 --- a/Objective-J/CFError.js +++ b/Objective-J/CFError.js @@ -26,20 +26,20 @@ GLOBAL(kCFErrorLocalizedRecoverySuggestionKey) = "CPLocalizedRecoverySuggestion" GLOBAL(kCFErrorDescriptionKey) = "CPDescription"; GLOBAL(kCFErrorUnderlyingErrorKey) = "CPUnderlyingError"; -GLOBAL(kCFErrorURLKey) = "_kCFErrorURLKey"; -GLOBAL(kCFErrorFilePathKey) = "_kCFErrorFilePathKey"; +GLOBAL(kCFErrorURLKey) = "CPURL"; +GLOBAL(kCFErrorFilePathKey) = "CPFilePath"; // GLOBAL(kCFErrorDomainPOSIX) = ""; // GLOBAL(kCFErrorDomainOSStatus) = ""; // GLOBAL(kCFErrorDomainMach) = ""; -GLOBAL(kCFErrorDomainCappuccino) = "CPErrorDomainCappuccino"; +GLOBAL(kCFErrorDomainCappuccino) = "CPCappuccinoErrorDomain"; GLOBAL(kCFErrorDomainCocoa) = kCFErrorDomainCappuccino; GLOBAL(CFError) = function(/* CFString */ domain, /* int */ code, /* CFDictionary */ userInfo) { this._domain = domain || NULL; - this._code = code || NULL; + this._code = code || 0; this._userInfo = userInfo || new CFDictionary(); this._UID = objj_generateObjectUID(); } @@ -78,7 +78,7 @@ CFError.prototype.description = function () if (desc) { // we have a description key. - var result = "The operation couldn\u2019t be completed. (error " + this._code + "- " + desc + ")"; + var result = "The operation couldn\u2019t be completed. (error " + this._code + " - " + desc + ")"; } else { @@ -120,7 +120,7 @@ GLOBAL(CFErrorCreate) = function(/* String */ domain, /*int */ code, /* CFDictio GLOBAL(CFErrorCreateWithUserInfoKeysAndValues) = function(/* String */ domain, /* int */ code, /* array */ userInfoKeys, /* array */ userInfoValues, /* int */ numUserInfoValues) { - var userInfo = new CFDictionary(); + var userInfo = new CFMutableDictionary(); while(numUserInfoValues--) userInfo.setValueForKey(userInfoKeys[numUserInfoValues], userInfoValues[numUserInfoValues]); @@ -129,30 +129,30 @@ GLOBAL(CFErrorCreateWithUserInfoKeysAndValues) = function(/* String */ domain, / GLOBAL(CFErrorGetCode) = function(/* CFError */ err) { - return err.code; + return err.code(); } GLOBAL(CFErrorGetDomain) = function(/* CFError */ err) { - return err.domain; + return err.domain(); } GLOBAL(CFErrorCopyDescription) = function(/* CFError */ err) { - return err.description; + return err.description(); } GLOBAL(CFErrorCopyUserInfo) = function(/* CFError */ err) { - return err.userInfo; + return err.userInfo(); } GLOBAL(CFErrorCopyFailureReason) = function(/* CFError */ err) { - return err.failureReason; + return err.failureReason(); } GLOBAL(CFErrorCopyRecoverySuggestion) = function(/* CFError */err) { - return err.recoverySuggestion; + return err.recoverySuggestion(); } From 0038eab6ab951750f9ee296ae3fbf59318ba7dea Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 08:59:35 -0400 Subject: [PATCH 05/15] Add CFError and CFNetworkErrors to the Includes list --- Objective-J/Includes.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Objective-J/Includes.js b/Objective-J/Includes.js index a4373e3a0..43adc2de2 100644 --- a/Objective-J/Includes.js +++ b/Objective-J/Includes.js @@ -38,6 +38,8 @@ #include "CFHTTPRequest.js" #include "CFPropertyList.js" #include "CFDictionary.js" +#include "CFError.js" +#include "CFNetworkErrors.js" #include "CFData.js" #include "CFURL.js" #include "MarkedStream.js" From 96135c9875d5256fba37073ebd3b2dfe35c174a7 Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 09:01:42 -0400 Subject: [PATCH 06/15] New: Toll-free bridged CPError with CFError This commit changes CPError to use a toll-free bridge with CFError, matching Cocoa's implementation of this class. --- Foundation/CPError.j | 152 +++++++++++++++++++++++++++++++------------ 1 file changed, 109 insertions(+), 43 deletions(-) diff --git a/Foundation/CPError.j b/Foundation/CPError.j index 4acafe2ce..7062bd08f 100644 --- a/Foundation/CPError.j +++ b/Foundation/CPError.j @@ -24,31 +24,52 @@ @import "CPObject.j" @import "CPString.j" -CPCappuccinoErrorDomain = CPCocoaErrorDomain = @"CPCappuccinoErrorDomain"; -// CPPOSIXErrorDomain = @"CPPOSIXErrorDomain"; -// CPOSStatusErrorDomain = @"CPOSStatusErrorDomain"; +CPCappuccinoErrorDomain = kCFErrorDomainCappuccino; +CPCocoaErrorDomain = kCFErrorDomainCappuccino; // compat -CPUnderlyingErrorKey = @"CPUnderlyingErrorKey"; +CPUnderlyingErrorKey = kCFErrorUnderlyingErrorKey; -CPLocalizedDescriptionKey = @"CPLocalizedDescriptionKey"; -CPLocalizedFailureReasonErrorKey = @"CPLocalizedFailureReasonErrorKey"; -CPLocalizedRecoverySuggestionErrorKey = @"CPLocalizedRecoverySuggestionErrorKey"; +CPLocalizedDescriptionKey = kCFErrorLocalizedDescriptionKey; +CPLocalizedFailureReasonErrorKey = kCFErrorLocalizedFailureReasonKey; +CPLocalizedRecoverySuggestionErrorKey = kCFErrorLocalizedRecoverySuggestionKey; CPLocalizedRecoveryOptionsErrorKey = @"CPLocalizedRecoveryOptionsErrorKey"; CPRecoveryAttempterErrorKey = @"CPRecoveryAttempterErrorKey"; CPHelpAnchorErrorKey = @"CPHelpAnchorErrorKey"; CPStringEncodingErrorKey = @"CPStringEncodingErrorKey"; -CPURLErrorKey = @"CPURLErrorKey"; -CPFilePathErrorKey = @"CPFilePathErrorKey"; +CPURLErrorKey = kCFErrorURLKey; +CPFilePathErrorKey = kCFErrorFilePathKey; +/*! + @class CPError + @ingroup foundation + @brief Used for encapsulating, presenting, and recovery from errors. + CPError is toll-free bridged with CFError() methods. + + An example of initializing a CPError: +
+
+var userInfo = @{CPLocalizedDescriptionKey: @"A localized error description",
+                 CPLocalizedFailureReasonErrorKey: @"A localized failure reason",
+                 CPUnderlyingErrorKey: @"An underlying error message"},
+
+    err = [CPError errorWithDomain:CPCappuccinoErrorDomain code:-10 userInfo:userInfo];
+
+ */ @implementation CPError : CPObject { - CPInteger _code @accessors(property=code, readonly); - CPString _domain @accessors(property=domain, readonly); - CPDictionary _userInfo @accessors(property=userInfo, readonly); } ++ (id)alloc +{ + var obj = new CFError(); + obj.isa = [self class]; + + return obj; +} + + + (id)errorWithDomain:(CPString)aDomain code:(CPInteger)aCode userInfo:(CPDictionary)aDict { return [[CPError alloc] initWithDomain:aDomain code:aCode userInfo:aDict]; @@ -56,44 +77,89 @@ CPFilePathErrorKey = @"CPFilePathErrorKey"; - (id)initWithDomain:(CPString)aDomain code:(CPInteger)aCode userInfo:(CPDictionary)aDict { - if (self = [super init]) - { - _domain = aDomain; - _code = aCode; - _userInfo = aDict; - } - - return self; + var result = new CFError(aDomain, aCode, aDict); + result.isa = [self class]; + return result; } -- (CPString)localizedDescription +- (CPInteger)code { - return [_userInfo objectForKey:CPLocalizedDescriptionKey]; -} - -- (CPString)localizedFailureReason -{ - return [_userInfo objectForKey:CPLocalizedFailureReasonErrorKey]; -} - -- (CPArray)localizedRecoveryOptions -{ - return [_userInfo objectForKey:CPLocalizedRecoveryOptionsErrorKey]; -} - -- (CPString)localizedRecoverySuggestion -{ - return [_userInfo objectForKey:CPLocalizedRecoverySuggestionErrorKey]; -} - -- (id)recoveryAttempter -{ - return [_userInfo objectForKey:CPRecoveryAttempterErrorKey]; + return self.code(); } - (CPString)description { - return [CPString stringWithFormat:@"Error Domain=%@ Code=%d UserInfo=%p %@", _domain, _code, _userInfo, [self localizedDescription]]; + return self.description(); +} + +- (CPString)domain +{ + return self.domain(); +} + +- (CPString)localizedDescription +{ + return self.description(); +} + +- (CPString)localizedFailureReason +{ + return self.failureReason(); +} + +- (CPArray)localizedRecoveryOptions +{ + var userInfo = self.userInfo(), + recoveryOptions = userInfo.valueForKey(CPLocalizedRecoveryOptionsErrorKey); + + return recoveryOptions; +} + +- (CPString)localizedRecoverySuggestion +{ + return self.recoverySuggestion(); +} + +- (id)recoveryAttempter +{ + var userInfo = self.userInfo(), + recoveryAttempter = userInfo.valueForKey(CPRecoveryAttempterErrorKey); + + return recoveryAttempter; +} + +- (CPString)description +{ + return [CPString stringWithFormat:@"Error Domain=%@ Code=%d \"%@\" UserInfo=%@", self.domain(), self.code(), self.description(), self.userInfo()]; } @end + +var CPErrorCodeKey = @"CPErrorCodeKey", + CPErrorDomainKey = @"CPErrorDomainKey", + CPErrorUserInfoKey = @"CPErrorUserInfoKey"; + +@implementation CPError (CPCoding) + +- (id)initWithCoder:(CPCoder)aCoder +{ + var code = [aCoder decodeIntForKey:CPErrorCodeKey], + domain = [aCoder decodeObjectForKey:CPErrorDomainKey], + userInfo = [aCoder decodeObjectForKey:CPErrorUserInfoKey]; + + return [self initWithDomain:domain + code:code + userInfo:userInfo]; +} + +- (void)encodeWithCoder:(CPCoder)aCoder +{ + [aCoder encodeObject:self.domain() forKey:CPErrorDomainKey]; + [aCoder encodeObject:self.code() forKey:CPErrorCodeKey]; + [aCoder encodeObject:self.userInfo() forKey:CPErrorUserInfoKey]; +} + +@end + +CFError.prototype.isa = CPError; + From 7811521c0895bbd334cad59674ff5453239be667 Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 09:02:56 -0400 Subject: [PATCH 07/15] New: CPURLError definitions This commit adds support for the CPURLError codes, with underlying support provided by Foundation's CFURL Errors. --- Foundation/CPURLError.j | 26 ++++++++++++++++++++++++++ Foundation/Foundation.j | 1 + 2 files changed, 27 insertions(+) create mode 100644 Foundation/CPURLError.j diff --git a/Foundation/CPURLError.j b/Foundation/CPURLError.j new file mode 100644 index 000000000..a54ebdaaf --- /dev/null +++ b/Foundation/CPURLError.j @@ -0,0 +1,26 @@ + +CPURLErrorDomain = @"CPURLErrorDomain"; +CPURLErrorUnknown = -1; +CPURLErrorCancelled = kCFURLErrorCancelled; +CPURLErrorBadURL = kCFURLErrorBadURL; +CPURLErrorTimedOut = kCFURLErrorTimedOut; +CPURLErrorUnsupportedURL = kCFURLErrorUnsupportedURL; +CPURLErrorCannotFindHost = kCFURLErrorCannotFindHost; +CPURLErrorCannotConnectToHost = kCFURLErrorCannotConnectToHost; +CPURLErrorNetworkConnectionLost = kCFURLErrorNetworkConnectionLost; +CPURLErrorDNSLookupFailed = kCFURLErrorDNSLookupFailed; +CPURLErrorHTTPTooManyRedirects = kCFURLErrorHTTPTooManyRedirects; +CPURLErrorResourceUnavailable = kCFURLErrorResourceUnavailable; +CPURLErrorNotConnectedToInternet = kCFURLErrorNotConnectedToInternet; +CPURLErrorRedirectToNonExistentLocation = kCFURLErrorRedirectToNonExistentLocation; +CPURLErrorBadServerResponse = kCFURLErrorBadServerResponse; +CPURLErrorUserCancelledAuthentication = kCFURLErrorUserCancelledAuthentication; +CPURLErrorUserAuthenticationRequired = kCFURLErrorUserAuthenticationRequired; +CPURLErrorZeroByteResource = kCFURLErrorZeroByteResource; +CPURLErrorCannotDecodeRawData = kCFURLErrorCannotDecodeRawData; +CPURLErrorCannotDecodeContentData = kCFURLErrorCannotDecodeContentData; +CPURLErrorCannotParseResponse = kCFURLErrorCannotParseResponse; +CPURLErrorFileDoesNotExist = kCFURLErrorFileDoesNotExist; +CPURLErrorFileIsDirectory = kCFURLErrorFileIsDirectory; +CPURLErrorNoPermissionsToReadFile = kCFURLErrorNoPermissionsToReadFile; +CPURLErrorDataLengthExceedsMaximum = kCFURLErrorDataLengthExceedsMaximum; \ No newline at end of file diff --git a/Foundation/Foundation.j b/Foundation/Foundation.j index ab9d5fdb2..3fa485412 100755 --- a/Foundation/Foundation.j +++ b/Foundation/Foundation.j @@ -73,6 +73,7 @@ @import "CPUndoManager.j" @import "CPURL.j" @import "CPURLConnection.j" +@import "CPURLError.j" @import "CPURLRequest.j" @import "CPURLResponse.j" @import "CPUserDefaults.j" From 6fe30547388aa3925641b7786fe503988bfd7115 Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 09:04:57 -0400 Subject: [PATCH 08/15] New: Unit tests for CFError methods --- Tests/Objective-J/CFErrorTest.j | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Tests/Objective-J/CFErrorTest.j diff --git a/Tests/Objective-J/CFErrorTest.j b/Tests/Objective-J/CFErrorTest.j new file mode 100644 index 000000000..b839ff723 --- /dev/null +++ b/Tests/Objective-J/CFErrorTest.j @@ -0,0 +1,60 @@ +@import + + +@implementation CFErrorTest : OJTestCase + +- (void)testCreate +{ + var err = new CFError(); + [self assertNotNull:err]; +} + +- (void)testCreateWithParams +{ + var err = new CFError(kCFErrorDomainCappuccino, -1000, nil); + [self assertNotNull:err]; + [self assert:-1000 equals:err.code()]; +} + +- (void)testCreateGlobal +{ + var err = CFErrorCreate(kCFErrorDomainCappuccino, -1000, nil); + [self assertNotNull:err]; + + [self assert:kCFErrorDomainCappuccino equals:err.domain()]; + [self assert:-1000 equals:err.code()]; + [self assert:@"CPErrorDomainCappuccino" equals:CFErrorGetDomain(err)]; +} + +- (void)testCreateWithUserInfoKeysAndValues +{ + var err = CFErrorCreateWithUserInfoKeysAndValues(kCFErrorDomainCappuccino, -1000, [kCFErrorLocalizedDescriptionKey, kCFErrorDescriptionKey], [@"A localized description", @"An error description"], 2); + [self assertNotNull:err]; + + var info = err.userInfo(); + [self assert:2 equals:info.count()]; +} + +- (void)testDescriptionCaseOne +{ + // Description case 1: Localized Key set + var err = CFErrorCreateWithUserInfoKeysAndValues(kCFErrorDomainCappuccino, -1000, [kCFErrorLocalizedDescriptionKey], [@"A localized Description Key"], 1); + [self assert:@"A localized Description Key" equals:err.description()]; + [self assert:@"A localized Description Key" equals:CFErrorCopyDescription(err)]; +} + +- (void)testDescriptionCaseTwo +{ + // Case 2: Reason set; description generated + var err = CFErrorCreateWithUserInfoKeysAndValues(kCFErrorDomainCappuccino, -1000, [kCFErrorLocalizedFailureReasonKey], [@"A localized reason"], 1); + [self assert:@"The operation couldn\u2019t be completed. A localized reason" equals:err.description()]; +} + +- (void)testDescriptionCaseThree +{ + // Case 3: Final fall-back. + var err = CFErrorCreateWithUserInfoKeysAndValues(kCFErrorDomainCappuccino, -1000, [kCFErrorDescriptionKey], [@"A description key"], 1); + [self assert:@"The operation couldn\u2019t be completed. (error -1000 - A description key)" equals:err.description()]; +} + +@end \ No newline at end of file From 2cc67f23ab93a095ba68ab7be5a94e2c39c3bc2e Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 09:12:35 -0400 Subject: [PATCH 09/15] New: CPError unit test --- Tests/Foundation/CPErrorTest.j | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Tests/Foundation/CPErrorTest.j diff --git a/Tests/Foundation/CPErrorTest.j b/Tests/Foundation/CPErrorTest.j new file mode 100644 index 000000000..4705f558a --- /dev/null +++ b/Tests/Foundation/CPErrorTest.j @@ -0,0 +1,24 @@ +@import +@import + +@implementation CPErrorTest : OJTestCase +{ +} + +- (void)testInstanceInstantiation +{ + var err = [[CPError alloc] initWithDomain:CPCappuccinoErrorDomain + code:-10 + userInfo:nil]; + [self assertNotNull:err]; +} + +- (void)testClassInstantiation +{ + var err = [CPError errorWithDomain:CPCappuccinoErrorDomain + code:-10 + userInfo:nil]; + [self assertNotNull:err]; +} + +@end \ No newline at end of file From 660d36e001dc928c7f18d0f744ea0d4ae9e38550 Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 09:26:37 -0400 Subject: [PATCH 10/15] Updating CPError tests --- Tests/Foundation/CPErrorTest.j | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Tests/Foundation/CPErrorTest.j b/Tests/Foundation/CPErrorTest.j index 4705f558a..7e482a3a2 100644 --- a/Tests/Foundation/CPErrorTest.j +++ b/Tests/Foundation/CPErrorTest.j @@ -21,4 +21,23 @@ [self assertNotNull:err]; } +- (void)testUserInfoDict +{ + var userInfo = @{ + CPLocalizedDescriptionKey: @"A localized error description", + CPUnderlyingErrorKey: @"An underlying error", + CPLocalizedFailureReasonErrorKey: @"A localized error reason", + CPLocalizedRecoverySuggestionErrorKey: @"The world is about to explode. You can choose to ignore this.", + CPLocalizedRecoveryOptionsErrorKey: ["Cry", "Ignore"] + }, + err = [CPError errorWithDomain:CPCappuccinoErrorDomain + code:-10 + userInfo:userInfo]; + + [self assertNotNull:[err userInfo]]; + [self assert:[err localizedDescription] equals:@"A localized error description"]; + [self assert:[err localizedRecoveryOptions] equals:["Cry", "Ignore"]]; + [self assertNull:[err recoveryAttempter]]; +} + @end \ No newline at end of file From ef5d1d6e58cd6556021818d8c4a34650df4d4622 Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 09:27:12 -0400 Subject: [PATCH 11/15] Fixed: Wrong method included on CPError --- Foundation/CPError.j | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Foundation/CPError.j b/Foundation/CPError.j index 7062bd08f..4ac772d61 100644 --- a/Foundation/CPError.j +++ b/Foundation/CPError.j @@ -87,9 +87,9 @@ var userInfo = @{CPLocalizedDescriptionKey: @"A localized error description", return self.code(); } -- (CPString)description +- (CPString)userInfo { - return self.description(); + return self.userInfo(); } - (CPString)domain @@ -97,6 +97,11 @@ var userInfo = @{CPLocalizedDescriptionKey: @"A localized error description", return self.domain(); } +/*! + By default this method returns the object in the user info dictionary for the key + NSLocalizedDescriptionKey. If the user info dictionary doesn’t contain a value for + NSLocalizedDescriptionKey, a default string is constructed from the domain and code. + */ - (CPString)localizedDescription { return self.description(); From 32c252393ab663e8a49d6c4e0800ecbd41638dd0 Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Sat, 1 Nov 2014 10:01:56 -0400 Subject: [PATCH 12/15] Fixed: Broken unit test --- Tests/Objective-J/CFErrorTest.j | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Objective-J/CFErrorTest.j b/Tests/Objective-J/CFErrorTest.j index b839ff723..cea9ba69a 100644 --- a/Tests/Objective-J/CFErrorTest.j +++ b/Tests/Objective-J/CFErrorTest.j @@ -23,7 +23,7 @@ [self assert:kCFErrorDomainCappuccino equals:err.domain()]; [self assert:-1000 equals:err.code()]; - [self assert:@"CPErrorDomainCappuccino" equals:CFErrorGetDomain(err)]; + [self assert:@"CPCappuccinoErrorDomain" equals:CFErrorGetDomain(err)]; } - (void)testCreateWithUserInfoKeysAndValues From de2e77cc8659fd2bca58185ddfddaf05a0f5951a Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Thu, 6 Nov 2014 17:23:27 -0500 Subject: [PATCH 13/15] Adding userInfo error keys and documenting CPURLError.j --- Foundation/CPURLError.j | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Foundation/CPURLError.j b/Foundation/CPURLError.j index a54ebdaaf..77d901256 100644 --- a/Foundation/CPURLError.j +++ b/Foundation/CPURLError.j @@ -1,5 +1,18 @@ +/* + * The CPURL Error Domain + */ CPURLErrorDomain = @"CPURLErrorDomain"; + +/* + * CPURL UserInfo Error Keys + */ +CPURLErrorFailingURLErrorKey = @"CPErrorFailingURLKey"; +CPURLErrorFailingURLStringErrorKey = @"CPURLErrorFailingURLStringKey"; + +/* + * CPURL Error Codes + */ CPURLErrorUnknown = -1; CPURLErrorCancelled = kCFURLErrorCancelled; CPURLErrorBadURL = kCFURLErrorBadURL; From b1d56924e6411ca123971c1d7056dc4ae636b91d Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Tue, 25 Nov 2014 17:56:04 -0500 Subject: [PATCH 14/15] Fixed: Formatting --- Objective-J/CFError.js | 60 +++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/Objective-J/CFError.js b/Objective-J/CFError.js index 545c7eef5..615bbade8 100644 --- a/Objective-J/CFError.js +++ b/Objective-J/CFError.js @@ -42,24 +42,26 @@ GLOBAL(CFError) = function(/* CFString */ domain, /* int */ code, /* CFDictionar this._code = code || 0; this._userInfo = userInfo || new CFDictionary(); this._UID = objj_generateObjectUID(); -} +}; -CFError.prototype.domain = function () +CFError.prototype.domain = function() { return this._domain; -} -DISPLAY_NAME(CFError.prototype.domain) +}; -CFError.prototype.code = function () +DISPLAY_NAME(CFError.prototype.domain); + +CFError.prototype.code = function() { return this._code; -} -DISPLAY_NAME(CFError.prototype.code) +}; + +DISPLAY_NAME(CFError.prototype.code); /* This follows the same logic to generate a description as the "real" CFError. */ -CFError.prototype.description = function () +CFError.prototype.description = function() { var localizedDesc = this._userInfo.valueForKey(kCFErrorLocalizedDescriptionKey); if (localizedDesc) @@ -87,26 +89,30 @@ CFError.prototype.description = function () } return result; -} -DISPLAY_NAME(CFError.prototype.description) +}; -CFError.prototype.failureReason = function () +DISPLAY_NAME(CFError.prototype.description); + +CFError.prototype.failureReason = function() { return this._userInfo.valueForKey(kCFErrorLocalizedFailureReasonKey); -} -DISPLAY_NAME(CFError.prototype.failureReason) +}; -CFError.prototype.recoverySuggestion = function () +DISPLAY_NAME(CFError.prototype.failureReason); + +CFError.prototype.recoverySuggestion = function() { return this._userInfo.valueForKey(kCFErrorLocalizedRecoverySuggestionKey); -} -DISPLAY_NAME(CFError.prototype.recoverySuggestion) +}; + +DISPLAY_NAME(CFError.prototype.recoverySuggestion); CFError.prototype.userInfo = function () { return this._userInfo; -} -DISPLAY_NAME(CFError.prototype.userInfo) +}; + +DISPLAY_NAME(CFError.prototype.userInfo); /* CFError Bridge Functions @@ -116,43 +122,43 @@ DISPLAY_NAME(CFError.prototype.userInfo) GLOBAL(CFErrorCreate) = function(/* String */ domain, /*int */ code, /* CFDictionary */ userInfo) { return new CFError(domain, code, userInfo); -} +}; GLOBAL(CFErrorCreateWithUserInfoKeysAndValues) = function(/* String */ domain, /* int */ code, /* array */ userInfoKeys, /* array */ userInfoValues, /* int */ numUserInfoValues) { var userInfo = new CFMutableDictionary(); - while(numUserInfoValues--) + while (numUserInfoValues--) userInfo.setValueForKey(userInfoKeys[numUserInfoValues], userInfoValues[numUserInfoValues]); return new CFError(domain, code, userInfo); -} +}; GLOBAL(CFErrorGetCode) = function(/* CFError */ err) { return err.code(); -} +}; GLOBAL(CFErrorGetDomain) = function(/* CFError */ err) { return err.domain(); -} +}; GLOBAL(CFErrorCopyDescription) = function(/* CFError */ err) { return err.description(); -} +}; GLOBAL(CFErrorCopyUserInfo) = function(/* CFError */ err) { return err.userInfo(); -} +}; GLOBAL(CFErrorCopyFailureReason) = function(/* CFError */ err) { return err.failureReason(); -} +}; GLOBAL(CFErrorCopyRecoverySuggestion) = function(/* CFError */err) { return err.recoverySuggestion(); -} +}; From 6f6938deb7356bcfb27f46868b5723537bd22f4b Mon Sep 17 00:00:00 2001 From: Andrew Hankinson Date: Tue, 25 Nov 2014 17:58:17 -0500 Subject: [PATCH 15/15] Fixed: Updated Comment --- Foundation/CPError.j | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Foundation/CPError.j b/Foundation/CPError.j index 4ac772d61..edc270514 100644 --- a/Foundation/CPError.j +++ b/Foundation/CPError.j @@ -99,8 +99,8 @@ var userInfo = @{CPLocalizedDescriptionKey: @"A localized error description", /*! By default this method returns the object in the user info dictionary for the key - NSLocalizedDescriptionKey. If the user info dictionary doesn’t contain a value for - NSLocalizedDescriptionKey, a default string is constructed from the domain and code. + CPLocalizedDescriptionKey. If the user info dictionary doesn’t contain a value for + CPLocalizedDescriptionKey, a default string is constructed from the domain and code. */ - (CPString)localizedDescription {