├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── RMErrors.podspec
├── RMErrors.xcworkspace
└── contents.xcworkspacedata
├── RMErrors
├── RMErrorCodeBoundary.h
├── RMErrorCodeDefinition.h
├── RMErrorCodeDefinition.m
├── RMErrorCodeRangeBoundary.h
├── RMErrorCodeRangeBoundary.m
├── RMErrorCodes.h
├── RMErrorCodes.m
├── RMErrorDescription.h
├── RMErrorDescription.m
├── RMErrorDomainDefinition.h
├── RMErrorDomainDefinition.m
├── RMErrorDomains.h
├── RMErrorDomains.m
├── RMErrorTransformation.h
├── RMErrorTransformations.h
├── RMErrorTransformations.m
├── RMErrors.h
└── RMErrors.m
└── Tests
├── .gitignore
├── Podfile
├── RMErrorsIOSTests
├── Info.plist
└── RMErrorsIOSTests.m
├── RMErrorsOSXTests
├── Info.plist
└── RMErrorsOSXTests.m
├── RMErrorsTests.xcodeproj
├── project.pbxproj
└── xcshareddata
│ └── xcschemes
│ ├── RMErrorsIOSTests.xcscheme
│ └── RMErrorsOSXTests.xcscheme
└── Tests
├── Fixtures
└── RMErrors.plist
├── RMErrorCodeDefinitionTest.m
├── RMErrorCodeRangeBoundaryTest.m
├── RMErrorCodesTest.m
├── RMErrorDomainDefinitionTest.m
├── RMErrorDomainsTest.m
├── RMErrorsTest.m
└── RMErrorsTransformationTest.m
/.gitignore:
--------------------------------------------------------------------------------
1 | xcuserdata
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode7.1
3 | sudo: false
4 | env:
5 | global:
6 | - LC_CTYPE=en_US.UTF-8
7 | - LANG=en_US.UTF-8
8 | matrix:
9 | - DESTINATION="OS=9.1,name=iPhone 6s" TEST_SCHEME="RMErrorsIOSTests" EXAMPLE_SCHEME="RMErrors iOS Example" SDK=iphonesimulator9.1 RUN_TESTS="YES" BUILD_EXAMPLE="YES" POD_LINT="NO"
10 | - DESTINATION="OS=9.0,name=iPhone 6 Plus" TEST_SCHEME="RMErrorsIOSTests" EXAMPLE_SCHEME="RMErrors iOS Example" SDK=iphonesimulator9.1 RUN_TESTS="YES" BUILD_EXAMPLE="YES" POD_LINT="NO"
11 | - DESTINATION="OS=8.4,name=iPhone 6" TEST_SCHEME="RMErrorsIOSTests" EXAMPLE_SCHEME="RMErrors iOS Example" SDK=iphonesimulator9.1 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
12 | - DESTINATION="OS=8.3,name=iPhone 5S" TEST_SCHEME="RMErrorsIOSTests" EXAMPLE_SCHEME="RMErrors iOS Example" SDK=iphonesimulator9.1 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
13 | - DESTINATION="OS=8.2,name=iPhone 5" TEST_SCHEME="RMErrorsIOSTests" EXAMPLE_SCHEME="RMErrors iOS Example" SDK=iphonesimulator9.1 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO"
14 | - DESTINATION="OS=8.1,name=iPhone 4S" TEST_SCHEME="RMErrorsIOSTests" EXAMPLE_SCHEME="RMErrors iOS Example" SDK=iphonesimulator9.1 RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="YES"
15 | - DESTINATION="arch=x86_64" TEST_SCHEME="RMErrorsOSXTests" SDK=macosx10.11 EXAMPLE_SCHEME="RMErrors Example" RUN_TESTS="NO" BUILD_EXAMPLE="YES" POD_LINT="NO"
16 | before_install:
17 | - gem install cocoapods --no-rdoc --no-ri --no-document --quiet
18 | - gem install xcpretty --no-rdoc --no-ri --no-document --quiet
19 | - cd Tests && pod install && cd $TRAVIS_BUILD_DIR
20 | script:
21 | - set -o pipefail
22 | - xcodebuild -version
23 | - xcodebuild -showsdks
24 | - if [ $RUN_TESTS == "YES" ]; then
25 | xcodebuild -workspace RMErrors.xcworkspace -scheme "$TEST_SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO test | xcpretty -c;
26 | fi
27 | - if [ $POD_LINT == "YES" ]; then
28 | pod lib lint --quick;
29 | fi
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Ride Group Inc (http://ride.com/)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RMErrors
2 | [](https://travis-ci.org/ride/RMErrors)
3 |
4 | > Powerful Error Handling for **iOS** and **OSX** apps
5 |
6 | RMErrors describes instances `NSError` and returns friendly messages following rules set in a simple property list.
7 |
8 | ## How it Works
9 |
10 | The following example RMErrors.plist will setup RMErrors to:
11 |
12 | * NSError with domain `NSURLErrorDomain` and code between `-1003` and `-1009` will be described with friendly message `the connection failed because the device is not connected to the internet`.
13 | * NSError with domain `NSURLErrorDomain` and code `-1001` will be described with friendly message `The connection timed out, please make sure you're connected to the internet and try again`.
14 | * NSError with domain `NSURLErrorDomain` and other codes not included by any of the previous rules will be described with friendly message `Network issue`
15 | * NSError with domain other than `NSURLErrorDomain` will be described with friendly message `Oopss, something went wrong`.
16 |
17 |
18 | ```plist
19 |
20 |
21 |
22 |
23 | (default)
24 |
25 | code
26 | -1
27 | friendlyMessage
28 | Oopss, something went wrong
29 |
30 | domains
31 |
32 | NSURLErrorDomain
33 |
34 | (default)
35 |
36 | transient
37 |
38 | friendlyMessage
39 | Network issue
40 |
41 | codes
42 |
43 | -1009..-1003
44 |
45 | transient
46 |
47 | friendlyMessage
48 | the connection failed because the device is not connected to the internet
49 |
50 | -1001
51 |
52 | transient
53 |
54 | friendlyMessage
55 | The connection timed out, please make sure you're connected to the internet and try again
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | ```
64 |
65 |
66 | ## Usage
67 |
68 | ### Install from Cocoapods
69 |
70 | ```rb
71 | pod 'RMErrors'
72 | ```
73 |
74 | ```bash
75 | $ pod install
76 | ```
77 |
78 | ### Prepare configuration file
79 |
80 | Create a new property list file in your project and make sure it's included in all the Xcode targets you intent to use from.
81 |
82 | ### Initialize
83 |
84 | ```obj-c
85 | RMErrors *errors = [[RMErrors alloc] init];
86 | [errors loadPropertyList]; //loads from RMErrors.plist in main bundle.
87 | ```
88 |
89 | ### Describing Errors
90 |
91 | ```obj-c
92 | RMErrorDescription *description = [errors describe:[NSError errorWithDomain:@"com.foo.bar.oopsie" code:500 userInfo:nil]];
93 | NSLog(@"Friendly Message: %@", description.friendlyMessage);
94 | ```
95 |
96 | Outputs:
97 |
98 | "Oopss, something went wrong"
99 |
100 | ## Test & Enhance
101 |
102 | ```bash
103 | $ cd Tests && pod install
104 | $ open RMErrors.xcworkspace
105 | ```
106 |
--------------------------------------------------------------------------------
/RMErrors.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'RMErrors'
3 | s.version = '1.0.1'
4 | s.license = 'MIT'
5 | s.summary = 'Powerful error handling for iOS and OSX'
6 | s.homepage = 'https://github.com/ride/RMErrors'
7 | s.authors = { 'Bithavoc' => 'im@bithavoc.io' }
8 | s.source = { :git => 'https://github.com/ride/RMErrors.git', :tag=>s.version }
9 |
10 | s.requires_arc = true
11 |
12 | s.public_header_files = 'RMErrors/*.{h}'
13 | s.source_files = 'RMErrors/*.{h,m}'
14 |
15 | s.ios.deployment_target = '8.0'
16 | s.osx.deployment_target = '10.9'
17 | s.watchos.deployment_target = '2.0'
18 | end
19 |
--------------------------------------------------------------------------------
/RMErrors.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
9 |
10 |
12 |
13 |
15 |
16 |
17 |
20 |
22 |
23 |
25 |
26 |
28 |
29 |
31 |
32 |
34 |
35 |
37 |
38 |
40 |
41 |
43 |
44 |
46 |
47 |
49 |
50 |
52 |
53 |
55 |
56 |
58 |
59 |
61 |
62 |
64 |
65 |
67 |
68 |
70 |
71 |
73 |
74 |
75 |
77 |
78 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorCodeBoundary.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodeBoundary.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 |
11 | @protocol RMErrorCodeBoundary
12 |
13 | /**
14 | Evaluates the error code and return YES if it fits the boundary
15 | */
16 | - (BOOL)matches:(NSInteger)code;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorCodeDefinition.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodeDefinition.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 | #import "RMErrorCodeBoundary.h"
11 | #import "RMErrorDescription.h"
12 |
13 | /**
14 | Describes how the app sees error code for a Domain.
15 | */
16 | @interface RMErrorCodeDefinition : NSObject
17 |
18 | /**
19 | Initializes the Error Code definition with a boundary, friendly message and transient indicator
20 | @param boundary Boundary to Match the error code
21 | @param friendlyMessage (optional) a text message to show in UI when error is matched
22 | @param transient indicates whether the error is transient or not
23 | */
24 | - (instancetype)initWithBoundary:(id)boundary
25 | friendlyMessage:(NSString *)friendlyMessage transient:(BOOL)transient NS_DESIGNATED_INITIALIZER;
26 |
27 | /**
28 | Initializes the Error Code definition with boundary and attributes dictionary(RMErrors.plist)
29 | @param boundary Boundary to Match the error code
30 | @param attributes NSDictionary with attributes (See RMErrors.plist)
31 | */
32 | - (instancetype)initWithBoundary:(id)boundary andAttributes:(NSDictionary *)attributes;
33 |
34 | /**
35 | Boundary of this error code.
36 | See RMErrorCodeRangeBoundary.
37 | */
38 | @property (nonatomic, readonly) id boundary;
39 |
40 | /**
41 | User-Friendly message associated with the matched code boundary.
42 | */
43 | @property (nonatomic, readonly) NSString *friendlyMessage;
44 |
45 | /**
46 | Indicates whether the matched error code is transient. Transient errors should be retried with our without user intervention after a certain amount of time.
47 | */
48 | @property (nonatomic, readonly) BOOL transient;
49 |
50 | /**
51 | Indicates whether it can describe the error or not
52 | */
53 | - (BOOL)canDescribe:(NSInteger)code;
54 |
55 | /**
56 | Describes the given error code with a default message
57 | @param code error code to describe
58 | @param defaultMessage default known message for the error code
59 | */
60 | - (RMErrorDescription *)describe:(NSInteger)code withDefaultMessage:(NSString *)defaultMessage;
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorCodeDefinition.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodeDefinition.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import "RMErrorCodeDefinition.h"
10 | #import "RMErrorCodeRangeBoundary.h"
11 |
12 | static NSString *const RMErrorCodeDefinitionAttributeFriendlyMessageName= @"friendlyMessage";
13 | static NSString *const RMErrorCodeDefinitionAttributeTransientName= @"transient";
14 |
15 | @implementation RMErrorCodeDefinition
16 | @synthesize boundary = _boundary;
17 | @synthesize friendlyMessage = _friendlyMessage;
18 | @synthesize transient = _transient;
19 |
20 | - (instancetype)init {
21 | return [self initWithBoundary:nil friendlyMessage:nil transient:NO];
22 | }
23 |
24 | - (instancetype)initWithBoundary:(id)boundary
25 | friendlyMessage:(NSString *)friendlyMessage transient:(BOOL)transient {
26 | if((self = [super init])) {
27 | NSParameterAssert(boundary);
28 | _boundary = boundary;
29 | _friendlyMessage = friendlyMessage;
30 | _transient = transient;
31 | }
32 | return self;
33 | }
34 |
35 | - (instancetype)initWithBoundary:(id)boundary andAttributes:(NSDictionary *)attributes {
36 | NSString *friendlyMessage = attributes[RMErrorCodeDefinitionAttributeFriendlyMessageName];
37 | NSNumber *transient = attributes[RMErrorCodeDefinitionAttributeTransientName];
38 | return [self initWithBoundary:boundary friendlyMessage:friendlyMessage transient:transient.boolValue];
39 | }
40 |
41 | - (BOOL)canDescribe:(NSInteger)code {
42 | return [self.boundary matches:code];
43 | }
44 |
45 | - (RMErrorDescription *)describe:(NSInteger)code withDefaultMessage:(NSString *)defaultMessage {
46 | NSString *msg = self.friendlyMessage;
47 | if(!msg) {
48 | msg = defaultMessage;
49 | }
50 | return [[RMErrorDescription alloc] initWithFriendlyMessage:msg transient:self.transient code:code];
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorCodeRangeBoundary.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodeRangeBoundary.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 | #import "RMErrorCodeBoundary.h"
11 |
12 | extern NSInteger const RMErrorCodeRangeBoundaryDefaultLimit;
13 |
14 | /**
15 | Boundary of error codes based on upper and lower inclusive limits
16 | */
17 | @interface RMErrorCodeRangeBoundary : NSObject
18 |
19 | /**
20 | Initializes the Boundary Ranges with lower and upper limits.
21 | */
22 | - (instancetype)initWithLower:(NSInteger)lower andUpper:(NSInteger)upper NS_DESIGNATED_INITIALIZER;
23 |
24 | /**
25 | Upper limit of the error code (inclusive).
26 | */
27 | @property (nonatomic, readonly) NSInteger upperLimit;
28 |
29 | /**
30 | Lower limit of the error codes (inclusive).
31 | */
32 | @property (nonatomic, readonly) NSInteger lowerLimit;
33 |
34 | /**
35 | Creates a range boundary using the given pattern.
36 | A pattern is an string as "500..599" or just "500" which is the same as "500..500".
37 | */
38 | + (instancetype)boundaryWithPattern:(NSString *)pattern;
39 |
40 | /**
41 | Returns a range boundary that matches all the error codes
42 | */
43 | + (instancetype)wildcard;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorCodeRangeBoundary.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodeRangeBoundary.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import "RMErrorCodeRangeBoundary.h"
10 |
11 | NSInteger const RMErrorCodeRangeBoundaryDefaultLimit = -1;
12 |
13 | static NSString *const RMErrorCodeRangeBoundaryPatternSeparator = @"..";
14 |
15 | @implementation RMErrorCodeRangeBoundary
16 | @synthesize upperLimit = _upperLimit;
17 | @synthesize lowerLimit = _lowerLimit;
18 |
19 | - (instancetype)init {
20 | return [self initWithLower:RMErrorCodeRangeBoundaryDefaultLimit andUpper:RMErrorCodeRangeBoundaryDefaultLimit];
21 | }
22 |
23 | - (instancetype)initWithLower:(NSInteger)lower andUpper:(NSInteger)upper {
24 | if((self = [super init])) {
25 | _lowerLimit = lower;
26 | _upperLimit = upper;
27 | }
28 | return self;
29 | }
30 |
31 | - (BOOL)matches:(NSInteger)code {
32 | return code >= self.lowerLimit && code <= self.upperLimit;
33 | }
34 |
35 | + (instancetype)boundaryWithPattern:(NSString *)pattern {
36 | NSParameterAssert(pattern);
37 | NSArray *limits = [pattern componentsSeparatedByString:RMErrorCodeRangeBoundaryPatternSeparator];
38 | NSString *lowerText = limits.firstObject;
39 | NSInteger lower = RMErrorCodeRangeBoundaryDefaultLimit;
40 | if(lowerText.length != 0) {
41 | lower = lowerText.integerValue;
42 | }
43 | NSInteger upper = lower;
44 | NSString *upperText = limits.lastObject;
45 | if(upperText.length != 0) {
46 | upper = upperText.integerValue;
47 | }
48 | return [[RMErrorCodeRangeBoundary alloc] initWithLower:lower andUpper:upper];
49 | }
50 |
51 | + (instancetype)wildcard {
52 | static RMErrorCodeRangeBoundary *_wildcard;
53 | static dispatch_once_t onceToken;
54 | dispatch_once(&onceToken, ^{
55 | _wildcard = [[RMErrorCodeRangeBoundary alloc]initWithLower:NSIntegerMin andUpper:NSIntegerMax];
56 | });
57 | return _wildcard;
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorCodes.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodes.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 | #import "RMErrorCodeDefinition.h"
11 | #import "RMErrorDescription.h"
12 |
13 | /**
14 | Collection of error codes known from an error domain
15 | */
16 | @interface RMErrorCodes : NSObject
17 |
18 | /**
19 | Adds definitions from Content Dictionary (RMErrors.plist) to the collection
20 | */
21 | - (void)addFromContent:(NSDictionary *)content;
22 |
23 | /**
24 | Adds an error code definition to the collection
25 | */
26 | - (void)add:(RMErrorCodeDefinition *)definition;
27 |
28 | /**
29 | Returns all the available error definitions
30 | */
31 | @property (nonatomic, readonly) NSArray *definitions;
32 |
33 | /**
34 | Describes the given error code with default message. Nil will be returned if none of the code definition can describe the error.
35 | */
36 | - (RMErrorDescription *)describe:(NSInteger)code withDefaultMessage:(NSString *)defaultMessage;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorCodes.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodes.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import "RMErrorCodes.h"
10 | #import "RMErrorCodeRangeBoundary.h"
11 |
12 | @interface RMErrorCodes()
13 |
14 | @property (nonatomic) NSMutableArray *codes;
15 |
16 | @end
17 |
18 | @implementation RMErrorCodes
19 | @dynamic definitions;
20 | @synthesize codes;
21 |
22 | - (instancetype)init {
23 | return [self initWithDictionary:nil];
24 | }
25 |
26 | - (instancetype)initWithDictionary:(NSDictionary *)domains {
27 | if((self = [super init])) {
28 | self.codes = [NSMutableArray array];
29 | }
30 | return self;
31 | }
32 |
33 | - (void)addFromContent:(NSDictionary *)content {
34 | for (NSString *pattern in content.allKeys) {
35 | NSDictionary *codeAttributes = content[pattern];
36 | id boundary = [RMErrorCodeRangeBoundary boundaryWithPattern:pattern];
37 | RMErrorCodeDefinition *definition = [[RMErrorCodeDefinition alloc] initWithBoundary:boundary andAttributes:codeAttributes];
38 | [self add:definition];
39 | }
40 | }
41 |
42 | - (void)add:(RMErrorCodeDefinition *)definition {
43 | NSParameterAssert([definition isKindOfClass:[RMErrorCodeDefinition class]]);
44 | [self.codes addObject:definition];
45 | }
46 |
47 | - (NSArray *)definitions {
48 | return [self.codes copy];
49 | }
50 |
51 | - (RMErrorDescription *)describe:(NSInteger)code withDefaultMessage:(NSString *)defaultMessage {
52 | for (RMErrorCodeDefinition *definition in self.codes) {
53 | if([definition canDescribe:code]) {
54 | return [definition describe:code withDefaultMessage:defaultMessage];
55 | }
56 | }
57 | return nil;
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorDescription.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorDescription.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 |
11 | extern NSString *const RMErrorDescriptionContentFriendlyMessageKey;
12 | extern NSString *const RMErrorDescriptionContentTransientKey;
13 | extern NSString *const RMErrorDescriptionContentCodeKey;
14 |
15 | /**
16 | Description of an error that occurred in the application
17 | */
18 | @interface RMErrorDescription : NSObject
19 |
20 | /**
21 | Initializes the error description with the given message and transient indicator
22 | */
23 | - (instancetype)initWithFriendlyMessage:(NSString *)friendlyMessage transient:(BOOL)transient code:(NSInteger)code NS_DESIGNATED_INITIALIZER;
24 |
25 | - (instancetype)initWithContent:(NSDictionary *)content;
26 |
27 | /**
28 | Indicates whether the error is transient or not
29 | */
30 | @property (nonatomic, readonly) BOOL transient;
31 |
32 | /**
33 | A user friendly message to be shown to the user
34 | */
35 | @property (nonatomic, readonly) NSString *friendlyMessage;
36 |
37 | /**
38 | Error code
39 | */
40 | @property (nonatomic, readonly) NSInteger code;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorDescription.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorDescription.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import "RMErrorDescription.h"
10 |
11 | NSString *const RMErrorDescriptionContentFriendlyMessageKey = @"friendlyMessage";
12 | NSString *const RMErrorDescriptionContentTransientKey = @"transient";
13 | NSString *const RMErrorDescriptionContentCodeKey = @"code";
14 |
15 | @implementation RMErrorDescription
16 | @synthesize transient = _transient;
17 | @synthesize friendlyMessage = _friendlyMessage;
18 | @synthesize code = _code;
19 |
20 | - (instancetype)init {
21 | return [self initWithFriendlyMessage:nil transient:NO code:-1];
22 | }
23 |
24 | - (instancetype)initWithFriendlyMessage:(NSString *)friendlyMessage transient:(BOOL)transient code:(NSInteger)code {
25 | if((self = [super init])) {
26 | _friendlyMessage = friendlyMessage;
27 | _transient = transient;
28 | _code = code;
29 | }
30 | return self;
31 | }
32 |
33 | - (instancetype)initWithContent:(NSDictionary *)content {
34 | NSString *friendlyMessage = content[RMErrorDescriptionContentFriendlyMessageKey];
35 | NSNumber *transient = content[RMErrorDescriptionContentTransientKey];
36 | NSNumber *code = content[RMErrorDescriptionContentCodeKey];
37 | return [self initWithFriendlyMessage:friendlyMessage transient:transient.boolValue code:code.integerValue];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorDomainDefinition.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorDomainDefinition.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 | #import "RMErrorCodes.h"
11 | #import "RMErrorCodeDefinition.h"
12 |
13 | /**
14 | Describes how the app sees an Error Domain.
15 | */
16 | @interface RMErrorDomainDefinition : NSObject
17 |
18 | /**
19 | Initializes an error domain definition with the given domain name
20 | */
21 | - (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
22 |
23 | /**
24 | Name of Error Domain
25 | */
26 | @property (nonatomic, readonly) NSString *name;
27 |
28 | /**
29 | Error codes definitions under this domain
30 | */
31 | @property (nonatomic, readonly) RMErrorCodes *codes;
32 |
33 | /**
34 | Loads content of this domain definition RMErrors.plist content
35 | */
36 | - (void)loadFromContent:(NSDictionary *)content;
37 |
38 | /**
39 | Indicates whether the error can be described by this domain
40 | */
41 | - (BOOL)canDescribe:(NSError *)error;
42 |
43 | /**
44 | Process the given error and returns a description of it
45 | */
46 | - (RMErrorDescription *)describe:(NSError *)error;
47 |
48 | /**
49 | Default code used when none of the codes are matched
50 | */
51 | @property (nonatomic) RMErrorCodeDefinition *defaultCode;
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorDomainDefinition.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorDomainDefinition.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import "RMErrorDomainDefinition.h"
10 | #import "RMErrorCodes.h"
11 | #import "RMErrorCodeRangeBoundary.h"
12 |
13 | static NSString *const RMErrorDomainDefinitionContentCodesKey = @"codes";
14 | static NSString *const RMErrorDomainDefinitionContentDefaultCodeKey = @"(default)";
15 |
16 | @implementation RMErrorDomainDefinition
17 | @synthesize name = _name;
18 | @synthesize codes = _codes;
19 | @synthesize defaultCode = _defaultCode;
20 |
21 | - (instancetype)init {
22 | return [self initWithName:nil];
23 | }
24 |
25 | - (instancetype)initWithName:(NSString *)name {
26 | if((self = [super init])) {
27 | NSParameterAssert(name);
28 | _name = name;
29 | _codes = [[RMErrorCodes alloc] init];
30 | }
31 | return self;
32 | }
33 |
34 | - (void)loadFromContent:(NSDictionary *)content {
35 | [self.codes addFromContent:content[RMErrorDomainDefinitionContentCodesKey]];
36 | NSDictionary *defaultCodeContent = content[RMErrorDomainDefinitionContentDefaultCodeKey];
37 | if(defaultCodeContent) {
38 | self.defaultCode = [[RMErrorCodeDefinition alloc] initWithBoundary:[RMErrorCodeRangeBoundary wildcard] andAttributes:defaultCodeContent];
39 | }
40 | }
41 |
42 | - (BOOL)canDescribe:(NSError *)error {
43 | return [error.domain isEqualToString:self.name];
44 | }
45 |
46 | - (RMErrorDescription *)describe:(NSError *)error {
47 | NSInteger code = error.code;
48 | NSString *originalMessage = error.userInfo[NSLocalizedDescriptionKey];
49 | RMErrorDescription *description = [self.codes describe:code withDefaultMessage:originalMessage];
50 | if(description) {
51 | return description;
52 | }
53 | return [self.defaultCode describe:code withDefaultMessage:originalMessage];
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorDomains.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorDomains.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 | #import "RMErrorDomainDefinition.h"
11 | #import "RMErrorDescription.h"
12 |
13 | /**
14 | Collection of Error domains known by the app
15 | */
16 | @interface RMErrorDomains : NSObject
17 |
18 | /**
19 | Adds definitions from Content Dictionary (RMErrors.plist) to the collection
20 | */
21 | - (void)addFromContent:(NSDictionary *)content;
22 |
23 | /**
24 | Adds an error domain definition to the collection
25 | */
26 | - (void)add:(RMErrorDomainDefinition *)definition;
27 |
28 | /**
29 | Returns all the available domain definitions
30 | */
31 | @property (nonatomic, readonly) NSArray *definitions;
32 |
33 | /**
34 | Describes an error
35 | */
36 | - (RMErrorDescription *)describe:(NSError *)error;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorDomains.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorDomains.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import "RMErrorDomains.h"
10 | #import "RMErrorDomainDefinition.h"
11 |
12 | @interface RMErrorDomains()
13 |
14 | @property (nonatomic) NSMutableArray *domains;
15 |
16 | @end
17 |
18 | @implementation RMErrorDomains
19 | @dynamic definitions;
20 | @synthesize domains;
21 |
22 | - (instancetype)init {
23 | return [self initWithDictionary:nil];
24 | }
25 |
26 | - (instancetype)initWithDictionary:(NSDictionary *)domains {
27 | if((self = [super init])) {
28 | self.domains = [NSMutableArray array];
29 | }
30 | return self;
31 | }
32 |
33 | - (void)addFromContent:(NSDictionary *)content {
34 | for (NSString *domain in content.allKeys) {
35 | NSDictionary *domainContent = content[domain];
36 | RMErrorDomainDefinition *definition = [[RMErrorDomainDefinition alloc] initWithName:domain];
37 | [definition loadFromContent:domainContent];
38 | [self add:definition];
39 | }
40 | }
41 |
42 | - (void)add:(RMErrorDomainDefinition *)definition {
43 | NSParameterAssert([definition isKindOfClass:[RMErrorDomainDefinition class]]);
44 | [self.domains addObject:definition];
45 | }
46 |
47 | - (NSArray *)definitions {
48 | return [self.domains copy];
49 | }
50 |
51 | - (RMErrorDescription *)describe:(NSError *)error {
52 | for (RMErrorDomainDefinition *domain in self.domains) {
53 | if([domain canDescribe:error]) {
54 | return [domain describe:error];
55 | }
56 | }
57 | return nil;
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorTransformation.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorTransformation.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 |
11 | /**
12 | Implemented by error transformations
13 | */
14 | @protocol RMErrorTransformation
15 |
16 | /*
17 | Transforms one NSError into another. Depending on the implementation, either a new NSerror or the original could be returned.
18 | */
19 | - (NSError *)transform:(NSError *)original;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorTransformations.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorTransformations.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 | #import "RMErrorTransformation.h"
11 |
12 | /**
13 | Collection of Transformations
14 | */
15 | @interface RMErrorTransformations : NSObject
16 |
17 | /**
18 | Adds a Transformation to the collection.
19 | */
20 | - (void)add:(id)transformation;
21 |
22 | /**
23 | Transforms an error into a new instance, depending on the implementation the original could be returned.
24 | */
25 | - (NSError *)transform:(NSError *)original;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/RMErrors/RMErrorTransformations.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorTransformations.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import "RMErrorTransformations.h"
10 |
11 | @interface RMErrorTransformations()
12 |
13 | @property (nonatomic) NSMutableArray *list;
14 |
15 | @end
16 |
17 | @implementation RMErrorTransformations
18 | @synthesize list;
19 |
20 | - (instancetype)init {
21 | if((self = [super init])) {
22 | self.list = [NSMutableArray array];
23 | }
24 | return self;
25 | }
26 |
27 | - (void)add:(id)transformation {
28 | NSParameterAssert(transformation);
29 | [self.list addObject:transformation];
30 | }
31 |
32 | - (NSError *)transform:(NSError *)original {
33 | NSError *last = original;
34 | for (id transformation in self.list) {
35 | last = [transformation transform:last];
36 | }
37 | return last;
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/RMErrors/RMErrors.h:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrors.h
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | @import Foundation;
10 | #import "RMErrorDomains.h"
11 | #import "RMErrorDescription.h"
12 | #import "RMErrorTransformations.h"
13 | #import "RMErrorCodes.h"
14 |
15 | extern NSString *__nonnull const RMErrorsContentDomainsKey;
16 | extern NSString *__nonnull const RMErrorsContentDefaultKey;
17 | extern NSString *__nonnull const RMErrorsDefaultFileName;
18 |
19 | @interface RMErrors : NSObject
20 |
21 | /**
22 | Error Domain definitions
23 | */
24 | @property (nonatomic, nonnull, readonly) RMErrorDomains* domains;
25 |
26 | /**
27 | A collection of transformation to run prior describing the original error.
28 | */
29 | @property (nonatomic, nonnull, readonly) RMErrorTransformations *transformations;
30 |
31 | /**
32 | Default error description in case is not found in domains and errors.
33 | */
34 | @property (nonatomic, nullable) RMErrorDescription *defaultDescription;
35 |
36 | /**
37 | Load from parsed RMErrors.plist
38 | */
39 | - (void)load:(nonnull NSDictionary *)content;
40 |
41 | /*
42 | Loads from property list in the main bundle
43 | */
44 | - (void)loadPropertyList;
45 |
46 | /*
47 | Load the content of RMErrors with Property List
48 | @param name Name of the property list in the bundle. Can not be nil.
49 | @param bundle Bundle to load the property list from. Can not be nil.
50 | */
51 | - (void)loadPropertyList:(nonnull NSString *)name bundle:(nonnull NSBundle *)bundle;
52 |
53 | /**
54 | Process an error and returns a description
55 | */
56 | - (nullable RMErrorDescription *)describe:(nonnull NSError *)error;
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/RMErrors/RMErrors.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrors.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/24/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import "RMErrors.h"
10 |
11 | NSString *const RMErrorsContentDomainsKey = @"domains";
12 | NSString *const RMErrorsContentDefaultKey = @"(default)";
13 | NSString *const RMErrorsDefaultFileName = @"RMErrors";
14 |
15 | @implementation RMErrors
16 | @synthesize domains = _domains;
17 | @synthesize transformations = _transformations;
18 | @synthesize defaultDescription = _defaultDescription;
19 |
20 | - (instancetype)init {
21 | if((self = [super init])) {
22 | _domains = [[RMErrorDomains alloc] init];
23 | _transformations = [[RMErrorTransformations alloc] init];
24 | }
25 | return self;
26 | }
27 |
28 | - (void)load:(NSDictionary *)content {
29 | [self.domains addFromContent:content[RMErrorsContentDomainsKey]];
30 | NSDictionary *defaultContent = content[RMErrorsContentDefaultKey];
31 | if(defaultContent) {
32 | self.defaultDescription = [[RMErrorDescription alloc] initWithContent:defaultContent];
33 | }
34 | }
35 |
36 | - (nullable RMErrorDescription *)describe:(NSError *)error {
37 | NSError *transformed = [self.transformations transform:error];
38 | RMErrorDescription *description = [self.domains describe:transformed];
39 | if(description) {
40 | return description;
41 | }
42 | return self.defaultDescription;
43 | }
44 |
45 | - (void)loadPropertyList {
46 | [self loadPropertyList:RMErrorsDefaultFileName bundle:[NSBundle mainBundle]];
47 | }
48 |
49 | - (void)loadPropertyList:(NSString *)name bundle:(NSBundle *)bundle {
50 | NSString *path = [bundle pathForResource:name ofType:@"plist"];
51 | NSDictionary *content = [NSDictionary dictionaryWithContentsOfFile:path];
52 | if(!content) {
53 | NSString *reason = [NSString stringWithFormat:@"Unable to load %@.plist", name];
54 | [[NSException exceptionWithName:@"RMErrorsConfigFileException" reason:reason userInfo:nil] raise];
55 | }
56 | [self load:content];
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/Tests/.gitignore:
--------------------------------------------------------------------------------
1 | /Pods
2 | /Podfile.lock
3 |
--------------------------------------------------------------------------------
/Tests/Podfile:
--------------------------------------------------------------------------------
1 | xcodeproj 'RMErrorsTests'
2 | workspace '../RMErrors'
3 | use_frameworks!
4 |
5 | def common_pods
6 | pod 'RMErrors', :path => '../'
7 | end
8 |
9 | target :ios do
10 | platform :ios, '8.0'
11 | link_with 'RMErrorsIOSTests'
12 | common_pods
13 | end
14 |
15 | target :osx do
16 | platform :osx, '10.9'
17 | link_with 'RMErrorsOSXTests'
18 | common_pods
19 | end
20 |
21 |
--------------------------------------------------------------------------------
/Tests/RMErrorsIOSTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Tests/RMErrorsIOSTests/RMErrorsIOSTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorsIOSTests.m
3 | // RMErrorsIOSTests
4 | //
5 | // Created by Johan Ride on 11/10/15.
6 | //
7 | //
8 |
9 | #import
10 |
11 | @interface RMErrorsIOSTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation RMErrorsIOSTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Tests/RMErrorsOSXTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Tests/RMErrorsOSXTests/RMErrorsOSXTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorsOSXTests.m
3 | // RMErrorsOSXTests
4 | //
5 | // Created by Johan Ride on 11/10/15.
6 | //
7 | //
8 |
9 | #import
10 |
11 | @interface RMErrorsOSXTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation RMErrorsOSXTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/Tests/RMErrorsTests.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1E84A7DA1BF29C3D00D1532C /* RMErrorsIOSTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7D91BF29C3D00D1532C /* RMErrorsIOSTests.m */; };
11 | 1E84A7E01BF29E1300D1532C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E84A7DF1BF29E1300D1532C /* Foundation.framework */; };
12 | 1E84A7EB1BF29F2000D1532C /* RMErrorCodeDefinitionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E31BF29F2000D1532C /* RMErrorCodeDefinitionTest.m */; };
13 | 1E84A7EC1BF29F2000D1532C /* RMErrorCodeRangeBoundaryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E41BF29F2000D1532C /* RMErrorCodeRangeBoundaryTest.m */; };
14 | 1E84A7ED1BF29F2000D1532C /* RMErrorCodesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E51BF29F2000D1532C /* RMErrorCodesTest.m */; };
15 | 1E84A7EE1BF29F2000D1532C /* RMErrorDomainDefinitionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E61BF29F2000D1532C /* RMErrorDomainDefinitionTest.m */; };
16 | 1E84A7EF1BF29F2000D1532C /* RMErrorDomainsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E71BF29F2000D1532C /* RMErrorDomainsTest.m */; };
17 | 1E84A7F11BF29F2000D1532C /* RMErrorsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E91BF29F2000D1532C /* RMErrorsTest.m */; };
18 | 1E84A7F21BF29F2000D1532C /* RMErrorsTransformationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7EA1BF29F2000D1532C /* RMErrorsTransformationTest.m */; };
19 | 1E9597CA1BF2FAEA004C4851 /* RMErrorsOSXTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E9597C91BF2FAEA004C4851 /* RMErrorsOSXTests.m */; };
20 | 1E9597CF1BF2FAFC004C4851 /* RMErrorCodeDefinitionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E31BF29F2000D1532C /* RMErrorCodeDefinitionTest.m */; };
21 | 1E9597D01BF2FAFC004C4851 /* RMErrorCodeRangeBoundaryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E41BF29F2000D1532C /* RMErrorCodeRangeBoundaryTest.m */; };
22 | 1E9597D11BF2FAFC004C4851 /* RMErrorCodesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E51BF29F2000D1532C /* RMErrorCodesTest.m */; };
23 | 1E9597D21BF2FAFC004C4851 /* RMErrorDomainDefinitionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E61BF29F2000D1532C /* RMErrorDomainDefinitionTest.m */; };
24 | 1E9597D31BF2FAFC004C4851 /* RMErrorDomainsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E71BF29F2000D1532C /* RMErrorDomainsTest.m */; };
25 | 1E9597D41BF2FAFC004C4851 /* RMErrorsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7E91BF29F2000D1532C /* RMErrorsTest.m */; };
26 | 1E9597D51BF2FAFC004C4851 /* RMErrorsTransformationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E84A7EA1BF29F2000D1532C /* RMErrorsTransformationTest.m */; };
27 | 1EFF20BB1BF63963002A65C1 /* RMErrors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1EFF20BA1BF63963002A65C1 /* RMErrors.plist */; };
28 | 1EFF20BC1BF63966002A65C1 /* RMErrors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1EFF20BA1BF63963002A65C1 /* RMErrors.plist */; };
29 | 4C57D94F189E98E8470F6437 /* Pods_osx.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8764C77DB944C27DB9414DF2 /* Pods_osx.framework */; };
30 | 6150E705DB159ECDB2520F37 /* Pods_ios.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BBC31B3CBFB36F4316ECC00 /* Pods_ios.framework */; };
31 | /* End PBXBuildFile section */
32 |
33 | /* Begin PBXFileReference section */
34 | 1E84A7D61BF29C3D00D1532C /* RMErrorsIOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RMErrorsIOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
35 | 1E84A7D91BF29C3D00D1532C /* RMErrorsIOSTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RMErrorsIOSTests.m; sourceTree = ""; };
36 | 1E84A7DB1BF29C3D00D1532C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
37 | 1E84A7DF1BF29E1300D1532C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
38 | 1E84A7E31BF29F2000D1532C /* RMErrorCodeDefinitionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMErrorCodeDefinitionTest.m; sourceTree = ""; };
39 | 1E84A7E41BF29F2000D1532C /* RMErrorCodeRangeBoundaryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMErrorCodeRangeBoundaryTest.m; sourceTree = ""; };
40 | 1E84A7E51BF29F2000D1532C /* RMErrorCodesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMErrorCodesTest.m; sourceTree = ""; };
41 | 1E84A7E61BF29F2000D1532C /* RMErrorDomainDefinitionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMErrorDomainDefinitionTest.m; sourceTree = ""; };
42 | 1E84A7E71BF29F2000D1532C /* RMErrorDomainsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMErrorDomainsTest.m; sourceTree = ""; };
43 | 1E84A7E91BF29F2000D1532C /* RMErrorsTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMErrorsTest.m; sourceTree = ""; };
44 | 1E84A7EA1BF29F2000D1532C /* RMErrorsTransformationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMErrorsTransformationTest.m; sourceTree = ""; };
45 | 1E9597C71BF2FAEA004C4851 /* RMErrorsOSXTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RMErrorsOSXTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
46 | 1E9597C91BF2FAEA004C4851 /* RMErrorsOSXTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RMErrorsOSXTests.m; sourceTree = ""; };
47 | 1E9597CB1BF2FAEA004C4851 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
48 | 1EFF20BA1BF63963002A65C1 /* RMErrors.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = RMErrors.plist; sourceTree = ""; };
49 | 2BBC31B3CBFB36F4316ECC00 /* Pods_ios.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50 | 35578B838AB067E90CF97C5D /* Pods-osx.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-osx.release.xcconfig"; path = "Pods/Target Support Files/Pods-osx/Pods-osx.release.xcconfig"; sourceTree = ""; };
51 | 7767EB1B31CE7690808120B9 /* Pods-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios/Pods-ios.debug.xcconfig"; sourceTree = ""; };
52 | 8764C77DB944C27DB9414DF2 /* Pods_osx.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_osx.framework; sourceTree = BUILT_PRODUCTS_DIR; };
53 | D96A260D7F7B8FD3663122A1 /* Pods-osx.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-osx.debug.xcconfig"; path = "Pods/Target Support Files/Pods-osx/Pods-osx.debug.xcconfig"; sourceTree = ""; };
54 | FDC8FB2FD40BCD8294ADF04E /* Pods-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios/Pods-ios.release.xcconfig"; sourceTree = ""; };
55 | /* End PBXFileReference section */
56 |
57 | /* Begin PBXFrameworksBuildPhase section */
58 | 1E84A7D31BF29C3D00D1532C /* Frameworks */ = {
59 | isa = PBXFrameworksBuildPhase;
60 | buildActionMask = 2147483647;
61 | files = (
62 | 1E84A7E01BF29E1300D1532C /* Foundation.framework in Frameworks */,
63 | 6150E705DB159ECDB2520F37 /* Pods_ios.framework in Frameworks */,
64 | );
65 | runOnlyForDeploymentPostprocessing = 0;
66 | };
67 | 1E9597C41BF2FAEA004C4851 /* Frameworks */ = {
68 | isa = PBXFrameworksBuildPhase;
69 | buildActionMask = 2147483647;
70 | files = (
71 | 4C57D94F189E98E8470F6437 /* Pods_osx.framework in Frameworks */,
72 | );
73 | runOnlyForDeploymentPostprocessing = 0;
74 | };
75 | /* End PBXFrameworksBuildPhase section */
76 |
77 | /* Begin PBXGroup section */
78 | 1E84A7CB1BF29BE000D1532C = {
79 | isa = PBXGroup;
80 | children = (
81 | 1E84A7E21BF29ECD00D1532C /* Tests */,
82 | 1E9597C81BF2FAEA004C4851 /* RMErrorsOSXTests */,
83 | 1E84A7E11BF29E1900D1532C /* Frameworks */,
84 | 1E84A7D81BF29C3D00D1532C /* RMErrorsIOSTests */,
85 | 1E84A7D71BF29C3D00D1532C /* Products */,
86 | AFDD49766CA6D337187962F0 /* Pods */,
87 | );
88 | sourceTree = "";
89 | };
90 | 1E84A7D71BF29C3D00D1532C /* Products */ = {
91 | isa = PBXGroup;
92 | children = (
93 | 1E84A7D61BF29C3D00D1532C /* RMErrorsIOSTests.xctest */,
94 | 1E9597C71BF2FAEA004C4851 /* RMErrorsOSXTests.xctest */,
95 | );
96 | name = Products;
97 | sourceTree = "";
98 | };
99 | 1E84A7D81BF29C3D00D1532C /* RMErrorsIOSTests */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 1E84A7D91BF29C3D00D1532C /* RMErrorsIOSTests.m */,
103 | 1E84A7DB1BF29C3D00D1532C /* Info.plist */,
104 | );
105 | path = RMErrorsIOSTests;
106 | sourceTree = "";
107 | };
108 | 1E84A7E11BF29E1900D1532C /* Frameworks */ = {
109 | isa = PBXGroup;
110 | children = (
111 | 1E84A7DF1BF29E1300D1532C /* Foundation.framework */,
112 | 2BBC31B3CBFB36F4316ECC00 /* Pods_ios.framework */,
113 | 8764C77DB944C27DB9414DF2 /* Pods_osx.framework */,
114 | );
115 | name = Frameworks;
116 | sourceTree = "";
117 | };
118 | 1E84A7E21BF29ECD00D1532C /* Tests */ = {
119 | isa = PBXGroup;
120 | children = (
121 | 1EFF20B91BF63908002A65C1 /* Fixtures */,
122 | 1E84A7E31BF29F2000D1532C /* RMErrorCodeDefinitionTest.m */,
123 | 1E84A7E41BF29F2000D1532C /* RMErrorCodeRangeBoundaryTest.m */,
124 | 1E84A7E51BF29F2000D1532C /* RMErrorCodesTest.m */,
125 | 1E84A7E61BF29F2000D1532C /* RMErrorDomainDefinitionTest.m */,
126 | 1E84A7E71BF29F2000D1532C /* RMErrorDomainsTest.m */,
127 | 1E84A7E91BF29F2000D1532C /* RMErrorsTest.m */,
128 | 1E84A7EA1BF29F2000D1532C /* RMErrorsTransformationTest.m */,
129 | );
130 | path = Tests;
131 | sourceTree = "";
132 | };
133 | 1E9597C81BF2FAEA004C4851 /* RMErrorsOSXTests */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 1E9597C91BF2FAEA004C4851 /* RMErrorsOSXTests.m */,
137 | 1E9597CB1BF2FAEA004C4851 /* Info.plist */,
138 | );
139 | path = RMErrorsOSXTests;
140 | sourceTree = "";
141 | };
142 | 1EFF20B91BF63908002A65C1 /* Fixtures */ = {
143 | isa = PBXGroup;
144 | children = (
145 | 1EFF20BA1BF63963002A65C1 /* RMErrors.plist */,
146 | );
147 | path = Fixtures;
148 | sourceTree = "";
149 | };
150 | AFDD49766CA6D337187962F0 /* Pods */ = {
151 | isa = PBXGroup;
152 | children = (
153 | 7767EB1B31CE7690808120B9 /* Pods-ios.debug.xcconfig */,
154 | FDC8FB2FD40BCD8294ADF04E /* Pods-ios.release.xcconfig */,
155 | D96A260D7F7B8FD3663122A1 /* Pods-osx.debug.xcconfig */,
156 | 35578B838AB067E90CF97C5D /* Pods-osx.release.xcconfig */,
157 | );
158 | name = Pods;
159 | sourceTree = "";
160 | };
161 | /* End PBXGroup section */
162 |
163 | /* Begin PBXNativeTarget section */
164 | 1E84A7D51BF29C3D00D1532C /* RMErrorsIOSTests */ = {
165 | isa = PBXNativeTarget;
166 | buildConfigurationList = 1E84A7DC1BF29C3D00D1532C /* Build configuration list for PBXNativeTarget "RMErrorsIOSTests" */;
167 | buildPhases = (
168 | 33DC975854BB9C9B7CBE00E4 /* Check Pods Manifest.lock */,
169 | 1E84A7D21BF29C3D00D1532C /* Sources */,
170 | 1E84A7D31BF29C3D00D1532C /* Frameworks */,
171 | 1E84A7D41BF29C3D00D1532C /* Resources */,
172 | 326D9A1631CD824DE4AC9585 /* Embed Pods Frameworks */,
173 | F5FD045F7CB9868EF0E410D7 /* Copy Pods Resources */,
174 | );
175 | buildRules = (
176 | );
177 | dependencies = (
178 | );
179 | name = RMErrorsIOSTests;
180 | productName = RMErrorsIOSTests;
181 | productReference = 1E84A7D61BF29C3D00D1532C /* RMErrorsIOSTests.xctest */;
182 | productType = "com.apple.product-type.bundle.unit-test";
183 | };
184 | 1E9597C61BF2FAEA004C4851 /* RMErrorsOSXTests */ = {
185 | isa = PBXNativeTarget;
186 | buildConfigurationList = 1E9597CE1BF2FAEA004C4851 /* Build configuration list for PBXNativeTarget "RMErrorsOSXTests" */;
187 | buildPhases = (
188 | 23D7C20CFC8C5B07052DDFAF /* Check Pods Manifest.lock */,
189 | 1E9597C31BF2FAEA004C4851 /* Sources */,
190 | 1E9597C41BF2FAEA004C4851 /* Frameworks */,
191 | 1E9597C51BF2FAEA004C4851 /* Resources */,
192 | 6A0C4EB7DA69FA2C584D4BE8 /* Embed Pods Frameworks */,
193 | BC83CFC9B336B4261E577ABD /* Copy Pods Resources */,
194 | );
195 | buildRules = (
196 | );
197 | dependencies = (
198 | );
199 | name = RMErrorsOSXTests;
200 | productName = RMErrorsOSXTests;
201 | productReference = 1E9597C71BF2FAEA004C4851 /* RMErrorsOSXTests.xctest */;
202 | productType = "com.apple.product-type.bundle.unit-test";
203 | };
204 | /* End PBXNativeTarget section */
205 |
206 | /* Begin PBXProject section */
207 | 1E84A7CC1BF29BE000D1532C /* Project object */ = {
208 | isa = PBXProject;
209 | attributes = {
210 | LastUpgradeCheck = 0710;
211 | TargetAttributes = {
212 | 1E84A7D51BF29C3D00D1532C = {
213 | CreatedOnToolsVersion = 7.1;
214 | };
215 | 1E9597C61BF2FAEA004C4851 = {
216 | CreatedOnToolsVersion = 7.1;
217 | };
218 | };
219 | };
220 | buildConfigurationList = 1E84A7CF1BF29BE000D1532C /* Build configuration list for PBXProject "RMErrorsTests" */;
221 | compatibilityVersion = "Xcode 3.2";
222 | developmentRegion = English;
223 | hasScannedForEncodings = 0;
224 | knownRegions = (
225 | en,
226 | );
227 | mainGroup = 1E84A7CB1BF29BE000D1532C;
228 | productRefGroup = 1E84A7D71BF29C3D00D1532C /* Products */;
229 | projectDirPath = "";
230 | projectRoot = "";
231 | targets = (
232 | 1E84A7D51BF29C3D00D1532C /* RMErrorsIOSTests */,
233 | 1E9597C61BF2FAEA004C4851 /* RMErrorsOSXTests */,
234 | );
235 | };
236 | /* End PBXProject section */
237 |
238 | /* Begin PBXResourcesBuildPhase section */
239 | 1E84A7D41BF29C3D00D1532C /* Resources */ = {
240 | isa = PBXResourcesBuildPhase;
241 | buildActionMask = 2147483647;
242 | files = (
243 | 1EFF20BB1BF63963002A65C1 /* RMErrors.plist in Resources */,
244 | );
245 | runOnlyForDeploymentPostprocessing = 0;
246 | };
247 | 1E9597C51BF2FAEA004C4851 /* Resources */ = {
248 | isa = PBXResourcesBuildPhase;
249 | buildActionMask = 2147483647;
250 | files = (
251 | 1EFF20BC1BF63966002A65C1 /* RMErrors.plist in Resources */,
252 | );
253 | runOnlyForDeploymentPostprocessing = 0;
254 | };
255 | /* End PBXResourcesBuildPhase section */
256 |
257 | /* Begin PBXShellScriptBuildPhase section */
258 | 23D7C20CFC8C5B07052DDFAF /* Check Pods Manifest.lock */ = {
259 | isa = PBXShellScriptBuildPhase;
260 | buildActionMask = 2147483647;
261 | files = (
262 | );
263 | inputPaths = (
264 | );
265 | name = "Check Pods Manifest.lock";
266 | outputPaths = (
267 | );
268 | runOnlyForDeploymentPostprocessing = 0;
269 | shellPath = /bin/sh;
270 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
271 | showEnvVarsInLog = 0;
272 | };
273 | 326D9A1631CD824DE4AC9585 /* Embed Pods Frameworks */ = {
274 | isa = PBXShellScriptBuildPhase;
275 | buildActionMask = 2147483647;
276 | files = (
277 | );
278 | inputPaths = (
279 | );
280 | name = "Embed Pods Frameworks";
281 | outputPaths = (
282 | );
283 | runOnlyForDeploymentPostprocessing = 0;
284 | shellPath = /bin/sh;
285 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios/Pods-ios-frameworks.sh\"\n";
286 | showEnvVarsInLog = 0;
287 | };
288 | 33DC975854BB9C9B7CBE00E4 /* Check Pods Manifest.lock */ = {
289 | isa = PBXShellScriptBuildPhase;
290 | buildActionMask = 2147483647;
291 | files = (
292 | );
293 | inputPaths = (
294 | );
295 | name = "Check Pods Manifest.lock";
296 | outputPaths = (
297 | );
298 | runOnlyForDeploymentPostprocessing = 0;
299 | shellPath = /bin/sh;
300 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
301 | showEnvVarsInLog = 0;
302 | };
303 | 6A0C4EB7DA69FA2C584D4BE8 /* Embed Pods Frameworks */ = {
304 | isa = PBXShellScriptBuildPhase;
305 | buildActionMask = 2147483647;
306 | files = (
307 | );
308 | inputPaths = (
309 | );
310 | name = "Embed Pods Frameworks";
311 | outputPaths = (
312 | );
313 | runOnlyForDeploymentPostprocessing = 0;
314 | shellPath = /bin/sh;
315 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-osx/Pods-osx-frameworks.sh\"\n";
316 | showEnvVarsInLog = 0;
317 | };
318 | BC83CFC9B336B4261E577ABD /* Copy Pods Resources */ = {
319 | isa = PBXShellScriptBuildPhase;
320 | buildActionMask = 2147483647;
321 | files = (
322 | );
323 | inputPaths = (
324 | );
325 | name = "Copy Pods Resources";
326 | outputPaths = (
327 | );
328 | runOnlyForDeploymentPostprocessing = 0;
329 | shellPath = /bin/sh;
330 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-osx/Pods-osx-resources.sh\"\n";
331 | showEnvVarsInLog = 0;
332 | };
333 | F5FD045F7CB9868EF0E410D7 /* Copy Pods Resources */ = {
334 | isa = PBXShellScriptBuildPhase;
335 | buildActionMask = 2147483647;
336 | files = (
337 | );
338 | inputPaths = (
339 | );
340 | name = "Copy Pods Resources";
341 | outputPaths = (
342 | );
343 | runOnlyForDeploymentPostprocessing = 0;
344 | shellPath = /bin/sh;
345 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios/Pods-ios-resources.sh\"\n";
346 | showEnvVarsInLog = 0;
347 | };
348 | /* End PBXShellScriptBuildPhase section */
349 |
350 | /* Begin PBXSourcesBuildPhase section */
351 | 1E84A7D21BF29C3D00D1532C /* Sources */ = {
352 | isa = PBXSourcesBuildPhase;
353 | buildActionMask = 2147483647;
354 | files = (
355 | 1E84A7ED1BF29F2000D1532C /* RMErrorCodesTest.m in Sources */,
356 | 1E84A7EF1BF29F2000D1532C /* RMErrorDomainsTest.m in Sources */,
357 | 1E84A7F21BF29F2000D1532C /* RMErrorsTransformationTest.m in Sources */,
358 | 1E84A7DA1BF29C3D00D1532C /* RMErrorsIOSTests.m in Sources */,
359 | 1E84A7EE1BF29F2000D1532C /* RMErrorDomainDefinitionTest.m in Sources */,
360 | 1E84A7F11BF29F2000D1532C /* RMErrorsTest.m in Sources */,
361 | 1E84A7EB1BF29F2000D1532C /* RMErrorCodeDefinitionTest.m in Sources */,
362 | 1E84A7EC1BF29F2000D1532C /* RMErrorCodeRangeBoundaryTest.m in Sources */,
363 | );
364 | runOnlyForDeploymentPostprocessing = 0;
365 | };
366 | 1E9597C31BF2FAEA004C4851 /* Sources */ = {
367 | isa = PBXSourcesBuildPhase;
368 | buildActionMask = 2147483647;
369 | files = (
370 | 1E9597CF1BF2FAFC004C4851 /* RMErrorCodeDefinitionTest.m in Sources */,
371 | 1E9597D01BF2FAFC004C4851 /* RMErrorCodeRangeBoundaryTest.m in Sources */,
372 | 1E9597D11BF2FAFC004C4851 /* RMErrorCodesTest.m in Sources */,
373 | 1E9597D21BF2FAFC004C4851 /* RMErrorDomainDefinitionTest.m in Sources */,
374 | 1E9597D31BF2FAFC004C4851 /* RMErrorDomainsTest.m in Sources */,
375 | 1E9597D41BF2FAFC004C4851 /* RMErrorsTest.m in Sources */,
376 | 1E9597D51BF2FAFC004C4851 /* RMErrorsTransformationTest.m in Sources */,
377 | 1E9597CA1BF2FAEA004C4851 /* RMErrorsOSXTests.m in Sources */,
378 | );
379 | runOnlyForDeploymentPostprocessing = 0;
380 | };
381 | /* End PBXSourcesBuildPhase section */
382 |
383 | /* Begin XCBuildConfiguration section */
384 | 1E84A7D01BF29BE000D1532C /* Debug */ = {
385 | isa = XCBuildConfiguration;
386 | buildSettings = {
387 | CLANG_ENABLE_MODULES = YES;
388 | CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
389 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
390 | };
391 | name = Debug;
392 | };
393 | 1E84A7D11BF29BE000D1532C /* Release */ = {
394 | isa = XCBuildConfiguration;
395 | buildSettings = {
396 | CLANG_ENABLE_MODULES = YES;
397 | CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION = YES;
398 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
399 | };
400 | name = Release;
401 | };
402 | 1E84A7DD1BF29C3D00D1532C /* Debug */ = {
403 | isa = XCBuildConfiguration;
404 | baseConfigurationReference = 7767EB1B31CE7690808120B9 /* Pods-ios.debug.xcconfig */;
405 | buildSettings = {
406 | ALWAYS_SEARCH_USER_PATHS = NO;
407 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
408 | CLANG_CXX_LIBRARY = "libc++";
409 | CLANG_ENABLE_MODULES = YES;
410 | CLANG_ENABLE_OBJC_ARC = YES;
411 | CLANG_WARN_BOOL_CONVERSION = YES;
412 | CLANG_WARN_CONSTANT_CONVERSION = YES;
413 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
414 | CLANG_WARN_EMPTY_BODY = YES;
415 | CLANG_WARN_ENUM_CONVERSION = YES;
416 | CLANG_WARN_INT_CONVERSION = YES;
417 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
418 | CLANG_WARN_UNREACHABLE_CODE = YES;
419 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
420 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
421 | COPY_PHASE_STRIP = NO;
422 | DEBUG_INFORMATION_FORMAT = dwarf;
423 | ENABLE_STRICT_OBJC_MSGSEND = YES;
424 | ENABLE_TESTABILITY = YES;
425 | GCC_C_LANGUAGE_STANDARD = gnu99;
426 | GCC_DYNAMIC_NO_PIC = NO;
427 | GCC_NO_COMMON_BLOCKS = YES;
428 | GCC_OPTIMIZATION_LEVEL = 0;
429 | GCC_PREPROCESSOR_DEFINITIONS = (
430 | "DEBUG=1",
431 | "$(inherited)",
432 | );
433 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
434 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
435 | GCC_WARN_UNDECLARED_SELECTOR = YES;
436 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
437 | GCC_WARN_UNUSED_FUNCTION = YES;
438 | GCC_WARN_UNUSED_VARIABLE = YES;
439 | INFOPLIST_FILE = RMErrorsIOSTests/Info.plist;
440 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
441 | MTL_ENABLE_DEBUG_INFO = YES;
442 | ONLY_ACTIVE_ARCH = YES;
443 | PRODUCT_BUNDLE_IDENTIFIER = com.ride.RMErrorsIOSTests;
444 | PRODUCT_NAME = "$(TARGET_NAME)";
445 | SDKROOT = iphoneos;
446 | };
447 | name = Debug;
448 | };
449 | 1E84A7DE1BF29C3D00D1532C /* Release */ = {
450 | isa = XCBuildConfiguration;
451 | baseConfigurationReference = FDC8FB2FD40BCD8294ADF04E /* Pods-ios.release.xcconfig */;
452 | buildSettings = {
453 | ALWAYS_SEARCH_USER_PATHS = NO;
454 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
455 | CLANG_CXX_LIBRARY = "libc++";
456 | CLANG_ENABLE_MODULES = YES;
457 | CLANG_ENABLE_OBJC_ARC = YES;
458 | CLANG_WARN_BOOL_CONVERSION = YES;
459 | CLANG_WARN_CONSTANT_CONVERSION = YES;
460 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
461 | CLANG_WARN_EMPTY_BODY = YES;
462 | CLANG_WARN_ENUM_CONVERSION = YES;
463 | CLANG_WARN_INT_CONVERSION = YES;
464 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
465 | CLANG_WARN_UNREACHABLE_CODE = YES;
466 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
467 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
468 | COPY_PHASE_STRIP = NO;
469 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
470 | ENABLE_NS_ASSERTIONS = NO;
471 | ENABLE_STRICT_OBJC_MSGSEND = YES;
472 | GCC_C_LANGUAGE_STANDARD = gnu99;
473 | GCC_NO_COMMON_BLOCKS = YES;
474 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
475 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
476 | GCC_WARN_UNDECLARED_SELECTOR = YES;
477 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
478 | GCC_WARN_UNUSED_FUNCTION = YES;
479 | GCC_WARN_UNUSED_VARIABLE = YES;
480 | INFOPLIST_FILE = RMErrorsIOSTests/Info.plist;
481 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
482 | MTL_ENABLE_DEBUG_INFO = NO;
483 | PRODUCT_BUNDLE_IDENTIFIER = com.ride.RMErrorsIOSTests;
484 | PRODUCT_NAME = "$(TARGET_NAME)";
485 | SDKROOT = iphoneos;
486 | VALIDATE_PRODUCT = YES;
487 | };
488 | name = Release;
489 | };
490 | 1E9597CC1BF2FAEA004C4851 /* Debug */ = {
491 | isa = XCBuildConfiguration;
492 | baseConfigurationReference = D96A260D7F7B8FD3663122A1 /* Pods-osx.debug.xcconfig */;
493 | buildSettings = {
494 | ALWAYS_SEARCH_USER_PATHS = NO;
495 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
496 | CLANG_CXX_LIBRARY = "libc++";
497 | CLANG_ENABLE_MODULES = YES;
498 | CLANG_ENABLE_OBJC_ARC = YES;
499 | CLANG_WARN_BOOL_CONVERSION = YES;
500 | CLANG_WARN_CONSTANT_CONVERSION = YES;
501 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
502 | CLANG_WARN_EMPTY_BODY = YES;
503 | CLANG_WARN_ENUM_CONVERSION = YES;
504 | CLANG_WARN_INT_CONVERSION = YES;
505 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
506 | CLANG_WARN_UNREACHABLE_CODE = YES;
507 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
508 | CODE_SIGN_IDENTITY = "-";
509 | COMBINE_HIDPI_IMAGES = YES;
510 | COPY_PHASE_STRIP = NO;
511 | DEBUG_INFORMATION_FORMAT = dwarf;
512 | ENABLE_STRICT_OBJC_MSGSEND = YES;
513 | ENABLE_TESTABILITY = YES;
514 | GCC_C_LANGUAGE_STANDARD = gnu99;
515 | GCC_DYNAMIC_NO_PIC = NO;
516 | GCC_NO_COMMON_BLOCKS = YES;
517 | GCC_OPTIMIZATION_LEVEL = 0;
518 | GCC_PREPROCESSOR_DEFINITIONS = (
519 | "DEBUG=1",
520 | "$(inherited)",
521 | );
522 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
523 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
524 | GCC_WARN_UNDECLARED_SELECTOR = YES;
525 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
526 | GCC_WARN_UNUSED_FUNCTION = YES;
527 | GCC_WARN_UNUSED_VARIABLE = YES;
528 | INFOPLIST_FILE = RMErrorsOSXTests/Info.plist;
529 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
530 | MACOSX_DEPLOYMENT_TARGET = 10.11;
531 | MTL_ENABLE_DEBUG_INFO = YES;
532 | ONLY_ACTIVE_ARCH = YES;
533 | PRODUCT_BUNDLE_IDENTIFIER = com.ride.RMErrorsOSXTests;
534 | PRODUCT_NAME = "$(TARGET_NAME)";
535 | SDKROOT = macosx;
536 | };
537 | name = Debug;
538 | };
539 | 1E9597CD1BF2FAEA004C4851 /* Release */ = {
540 | isa = XCBuildConfiguration;
541 | baseConfigurationReference = 35578B838AB067E90CF97C5D /* Pods-osx.release.xcconfig */;
542 | buildSettings = {
543 | ALWAYS_SEARCH_USER_PATHS = NO;
544 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
545 | CLANG_CXX_LIBRARY = "libc++";
546 | CLANG_ENABLE_MODULES = YES;
547 | CLANG_ENABLE_OBJC_ARC = YES;
548 | CLANG_WARN_BOOL_CONVERSION = YES;
549 | CLANG_WARN_CONSTANT_CONVERSION = YES;
550 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
551 | CLANG_WARN_EMPTY_BODY = YES;
552 | CLANG_WARN_ENUM_CONVERSION = YES;
553 | CLANG_WARN_INT_CONVERSION = YES;
554 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
555 | CLANG_WARN_UNREACHABLE_CODE = YES;
556 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
557 | CODE_SIGN_IDENTITY = "-";
558 | COMBINE_HIDPI_IMAGES = YES;
559 | COPY_PHASE_STRIP = NO;
560 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
561 | ENABLE_NS_ASSERTIONS = NO;
562 | ENABLE_STRICT_OBJC_MSGSEND = YES;
563 | GCC_C_LANGUAGE_STANDARD = gnu99;
564 | GCC_NO_COMMON_BLOCKS = YES;
565 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
566 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
567 | GCC_WARN_UNDECLARED_SELECTOR = YES;
568 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
569 | GCC_WARN_UNUSED_FUNCTION = YES;
570 | GCC_WARN_UNUSED_VARIABLE = YES;
571 | INFOPLIST_FILE = RMErrorsOSXTests/Info.plist;
572 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
573 | MACOSX_DEPLOYMENT_TARGET = 10.11;
574 | MTL_ENABLE_DEBUG_INFO = NO;
575 | PRODUCT_BUNDLE_IDENTIFIER = com.ride.RMErrorsOSXTests;
576 | PRODUCT_NAME = "$(TARGET_NAME)";
577 | SDKROOT = macosx;
578 | };
579 | name = Release;
580 | };
581 | /* End XCBuildConfiguration section */
582 |
583 | /* Begin XCConfigurationList section */
584 | 1E84A7CF1BF29BE000D1532C /* Build configuration list for PBXProject "RMErrorsTests" */ = {
585 | isa = XCConfigurationList;
586 | buildConfigurations = (
587 | 1E84A7D01BF29BE000D1532C /* Debug */,
588 | 1E84A7D11BF29BE000D1532C /* Release */,
589 | );
590 | defaultConfigurationIsVisible = 0;
591 | defaultConfigurationName = Release;
592 | };
593 | 1E84A7DC1BF29C3D00D1532C /* Build configuration list for PBXNativeTarget "RMErrorsIOSTests" */ = {
594 | isa = XCConfigurationList;
595 | buildConfigurations = (
596 | 1E84A7DD1BF29C3D00D1532C /* Debug */,
597 | 1E84A7DE1BF29C3D00D1532C /* Release */,
598 | );
599 | defaultConfigurationIsVisible = 0;
600 | defaultConfigurationName = Release;
601 | };
602 | 1E9597CE1BF2FAEA004C4851 /* Build configuration list for PBXNativeTarget "RMErrorsOSXTests" */ = {
603 | isa = XCConfigurationList;
604 | buildConfigurations = (
605 | 1E9597CC1BF2FAEA004C4851 /* Debug */,
606 | 1E9597CD1BF2FAEA004C4851 /* Release */,
607 | );
608 | defaultConfigurationIsVisible = 0;
609 | defaultConfigurationName = Release;
610 | };
611 | /* End XCConfigurationList section */
612 | };
613 | rootObject = 1E84A7CC1BF29BE000D1532C /* Project object */;
614 | }
615 |
--------------------------------------------------------------------------------
/Tests/RMErrorsTests.xcodeproj/xcshareddata/xcschemes/RMErrorsIOSTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
14 |
15 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
39 |
40 |
41 |
42 |
48 |
49 |
51 |
52 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/Tests/RMErrorsTests.xcodeproj/xcshareddata/xcschemes/RMErrorsOSXTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
14 |
15 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
39 |
40 |
41 |
42 |
48 |
49 |
51 |
52 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/Tests/Tests/Fixtures/RMErrors.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | (default)
6 |
7 | code
8 | -1
9 | friendlyMessage
10 | Oopss, something went wrong
11 |
12 | domains
13 |
14 | NSURLErrorDomain
15 |
16 | (default)
17 |
18 | transient
19 |
20 |
21 | codes
22 |
23 | -1003..-1009
24 |
25 | transient
26 |
27 | friendlyMessage
28 | the connection failed because the device is not connected to the internet
29 |
30 | -1001
31 |
32 | transient
33 |
34 | friendlyMessage
35 | The connection timed out, please make sure you're connected to the internet and try again
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Tests/Tests/RMErrorCodeDefinitionTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodeDefinitionTest.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RMErrorCodeDefinition.h"
11 |
12 | @interface RMErrorCodeDefinitionTest : XCTestCase
13 |
14 | @end
15 |
16 | @implementation RMErrorCodeDefinitionTest
17 |
18 | - (BOOL)matches:(NSInteger)code {
19 | if(code <= 200) {
20 | return NO;
21 | }
22 | return YES;
23 | }
24 |
25 | - (void)testDefaultInitializer {
26 | RMErrorCodeDefinition *definition = [[RMErrorCodeDefinition alloc] initWithBoundary:self friendlyMessage:@"oops!" transient:YES];
27 | XCTAssertEqualObjects(definition.friendlyMessage, @"oops!");
28 | XCTAssertTrue(definition.transient);
29 | XCTAssertEqualObjects(definition.boundary, self, @"boundary should have been the same passed in initializer");
30 | }
31 |
32 | - (void)testDefaultWithAttributes {
33 | NSDictionary *attributes = @{
34 | @"friendlyMessage": @"oops!",
35 | @"transient": @(YES)
36 | };
37 | RMErrorCodeDefinition *definition = [[RMErrorCodeDefinition alloc] initWithBoundary:self andAttributes:attributes];
38 | XCTAssertEqualObjects(definition.friendlyMessage, @"oops!");
39 | XCTAssertTrue(definition.transient);
40 | XCTAssertEqualObjects(definition.boundary, self, @"boundary should have been the same passed in initializer");
41 | }
42 |
43 | - (void)testDescribeWithoutFriendlyMessage {
44 | NSDictionary *attributes = @{
45 | @"transient": @(YES)
46 | };
47 | RMErrorCodeDefinition *definition = [[RMErrorCodeDefinition alloc] initWithBoundary:self andAttributes:attributes];
48 | RMErrorDescription *errorDescription = [definition describe:300 withDefaultMessage:@"original error message"];
49 | XCTAssertEqualObjects(errorDescription.friendlyMessage, @"original error message", @"should have described with the original error message since no friendlyMessage was provided");
50 | }
51 |
52 | - (void)testDescribeWithFriendlyMessage {
53 | NSDictionary *attributes = @{
54 | @"friendlyMessage": @"Oops, sorry",
55 | @"transient": @(YES)
56 | };
57 | RMErrorCodeDefinition *definition = [[RMErrorCodeDefinition alloc] initWithBoundary:self andAttributes:attributes];
58 | RMErrorDescription *errorDescription = [definition describe:300 withDefaultMessage:@"original error message"];
59 | XCTAssertEqualObjects(errorDescription.friendlyMessage, @"Oops, sorry", @"should have described with the friendly message since it was included in the error definition");
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/Tests/Tests/RMErrorCodeRangeBoundaryTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodeRangeBoundaryTest.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RMErrorCodeRangeBoundary.h"
11 |
12 | @interface RMErrorCodeRangeBoundaryTest : XCTestCase
13 |
14 | @end
15 |
16 | @implementation RMErrorCodeRangeBoundaryTest
17 |
18 | - (void)testDefaultInitializer {
19 | RMErrorCodeRangeBoundary *boundary = [[RMErrorCodeRangeBoundary alloc] init];
20 | XCTAssertEqual(boundary.lowerLimit, RMErrorCodeRangeBoundaryDefaultLimit);
21 | XCTAssertEqual(boundary.upperLimit, RMErrorCodeRangeBoundaryDefaultLimit);
22 | }
23 |
24 | - (void)testDesignatedInitializer {
25 | RMErrorCodeRangeBoundary *boundary = [[RMErrorCodeRangeBoundary alloc] initWithLower:500 andUpper:599];
26 | XCTAssertEqual(boundary.lowerLimit, 500);
27 | XCTAssertEqual(boundary.upperLimit, 599);
28 | }
29 |
30 | - (void)testEmptyPattern {
31 | RMErrorCodeRangeBoundary *boundary = [RMErrorCodeRangeBoundary boundaryWithPattern:@""];
32 | XCTAssertEqual(boundary.lowerLimit, RMErrorCodeRangeBoundaryDefaultLimit);
33 | XCTAssertEqual(boundary.upperLimit, RMErrorCodeRangeBoundaryDefaultLimit);
34 | }
35 |
36 | - (void)testInvalidPattern {
37 | RMErrorCodeRangeBoundary *boundary = [RMErrorCodeRangeBoundary boundaryWithPattern:@".."];
38 | XCTAssertEqual(boundary.lowerLimit, RMErrorCodeRangeBoundaryDefaultLimit);
39 | XCTAssertEqual(boundary.upperLimit, RMErrorCodeRangeBoundaryDefaultLimit);
40 | }
41 |
42 | - (void)testImplicitPattern {
43 | RMErrorCodeRangeBoundary *boundary = [RMErrorCodeRangeBoundary boundaryWithPattern:@"404"];
44 | XCTAssertNotNil(boundary);
45 |
46 | XCTAssertEqual(boundary.lowerLimit, 404);
47 | XCTAssertEqual(boundary.upperLimit, 404);
48 | }
49 |
50 | - (void)testExplicitPattern {
51 | RMErrorCodeRangeBoundary *boundary = [RMErrorCodeRangeBoundary boundaryWithPattern:@"403..404"];
52 | XCTAssertNotNil(boundary);
53 |
54 | XCTAssertEqual(boundary.lowerLimit, 403);
55 | XCTAssertEqual(boundary.upperLimit, 404);
56 | }
57 |
58 | - (void)testLowerInclusiveMatching {
59 | RMErrorCodeRangeBoundary *boundary = [[RMErrorCodeRangeBoundary alloc] initWithLower:200 andUpper:200];
60 | XCTAssertTrue([boundary matches:200]);
61 | XCTAssertFalse([boundary matches:199]);
62 | }
63 |
64 | - (void)testUpperInclusiveMatching {
65 | RMErrorCodeRangeBoundary *boundary = [[RMErrorCodeRangeBoundary alloc] initWithLower:200 andUpper:299];
66 | XCTAssertTrue([boundary matches:200]);
67 | XCTAssertTrue([boundary matches:299]);
68 | XCTAssertFalse([boundary matches:300]);
69 | }
70 |
71 | - (void)testWildcard {
72 | RMErrorCodeRangeBoundary *boundary = [RMErrorCodeRangeBoundary wildcard];
73 | XCTAssertTrue([boundary matches:NSIntegerMin]);
74 | XCTAssertTrue([boundary matches:NSIntegerMax]);
75 | }
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/Tests/Tests/RMErrorCodesTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorCodesTest.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 |
13 | @interface RMErrorCodesTest : XCTestCase {
14 | NSDictionary *_content;
15 | }
16 |
17 | @end
18 |
19 | @implementation RMErrorCodesTest
20 |
21 | - (void)setUp {
22 | [super setUp];
23 | _content = @{
24 | @"500-599": @{
25 | @"friendlyMessage": @"server down, try again later",
26 | @"transient": @(YES)
27 | }
28 | };
29 | }
30 |
31 | - (void)testAddFromContent {
32 | RMErrorCodes *codes = [[RMErrorCodes alloc] init];
33 | [codes addFromContent:_content];
34 | XCTAssertEqual(codes.definitions.count, 1);
35 |
36 | RMErrorCodeDefinition* definition = codes.definitions.firstObject;
37 | XCTAssertEqualObjects([definition class], [RMErrorCodeDefinition class]);
38 | XCTAssertEqualObjects(definition.boundary.class, [RMErrorCodeRangeBoundary class]);
39 | XCTAssertTrue(definition.transient);
40 | XCTAssertEqual(definition.friendlyMessage, @"server down, try again later");
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Tests/Tests/RMErrorDomainDefinitionTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorDomainDefinitionTest.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RMErrorDomainDefinition.h"
11 |
12 | @interface RMErrorDomainDefinitionTest : XCTestCase
13 |
14 | @end
15 |
16 | @implementation RMErrorDomainDefinitionTest
17 |
18 | - (void)testDesignatedInitializer {
19 | RMErrorDomainDefinition *definition = [[RMErrorDomainDefinition alloc]initWithName:@"NSURLErrorDomain"];
20 | XCTAssertEqualObjects(definition.name, @"NSURLErrorDomain");
21 | XCTAssertNotNil(definition.codes);
22 | }
23 |
24 | - (void)testAttributesInitializer {
25 | NSDictionary *attributes = @{
26 | @"codes": @{
27 | @"500": @{}
28 | }
29 | };
30 | RMErrorDomainDefinition *definition = [[RMErrorDomainDefinition alloc]initWithName:@"NSURLErrorDomain"];
31 | [definition loadFromContent:attributes];
32 | XCTAssertEqualObjects(definition.name, @"NSURLErrorDomain");
33 | XCTAssertNotNil(definition.codes);
34 | XCTAssertEqual(definition.codes.definitions.count, 1);
35 | }
36 |
37 | - (void)testMatchNoDefaultCode {
38 | NSDictionary *content = @{
39 | @"codes": @{
40 | @"500": @{}
41 | }
42 | };
43 | RMErrorDomainDefinition *definition = [[RMErrorDomainDefinition alloc]initWithName:@"NSURLErrorDomain"];
44 | [definition loadFromContent:content];
45 | RMErrorDescription *description =[definition describe:[NSError errorWithDomain:@"NSURLErrorDomain" code:20 userInfo:nil]];
46 | XCTAssertNil(description, @"should have been nil since there is no default code at this error domain level");
47 | }
48 |
49 | - (void)testMatchWithDefaultCode {
50 | NSDictionary *content = @{
51 | @"(default)": @{
52 | @"transient": @(YES),
53 | },
54 | @"codes": @{
55 | @"500": @{}
56 | }
57 | };
58 | RMErrorDomainDefinition *definition = [[RMErrorDomainDefinition alloc]initWithName:@"NSURLErrorDomain"];
59 | [definition loadFromContent:content];
60 | RMErrorDescription *description =[definition describe:[NSError errorWithDomain:@"NSURLErrorDomain" code:20 userInfo:@{
61 | NSLocalizedDescriptionKey: @"original error message",
62 | }]];
63 | XCTAssertNotNil(description, @"should have been an error description instance since there is a default code at this error domain level");
64 | XCTAssertTrue(description.transient);
65 | XCTAssertEqualObjects(description.friendlyMessage, @"original error message", @"should have included the original NSError message since friendlyMessage was not specified in default code for the domain");
66 | }
67 |
68 | - (void)testMatchWithDefaultCodeAndFriendlyMessageOverride {
69 | NSDictionary *content = @{
70 | @"(default)": @{
71 | @"transient": @(YES),
72 | @"friendlyMessage": @"Default error message for all codes in this domain",
73 | },
74 | @"codes": @{
75 | @"500": @{}
76 | }
77 | };
78 | RMErrorDomainDefinition *definition = [[RMErrorDomainDefinition alloc]initWithName:@"NSURLErrorDomain"];
79 | [definition loadFromContent:content];
80 | RMErrorDescription *description =[definition describe:[NSError errorWithDomain:@"NSURLErrorDomain" code:20 userInfo:@{
81 | NSLocalizedDescriptionKey: @"original error message",
82 | }]];
83 | XCTAssertNotNil(description, @"should have been an error description instance since there is a default code at this error domain level");
84 | XCTAssertTrue(description.transient);
85 | XCTAssertEqualObjects(description.friendlyMessage, @"Default error message for all codes in this domain", @"should have included the overriden default message for the domain");
86 | }
87 | @end
88 |
--------------------------------------------------------------------------------
/Tests/Tests/RMErrorDomainsTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorDomainsTest.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface RMErrorDomainsTest : XCTestCase {
13 | NSDictionary *_content;
14 | }
15 |
16 | @end
17 |
18 | @implementation RMErrorDomainsTest
19 |
20 | - (void)setUp {
21 | [super setUp];
22 | _content = @{
23 | @"NSURLErrorDomain": @{
24 | @"codes": @{
25 | @"500-599": @{}
26 | }
27 | }
28 | };
29 | }
30 |
31 | - (void)testAddFromContent {
32 | RMErrorDomains *domains = [[RMErrorDomains alloc] init];
33 | [domains addFromContent:_content];
34 | XCTAssertEqual(domains.definitions.count, 1);
35 |
36 | RMErrorDomainDefinition* definition = domains.definitions.firstObject;
37 | XCTAssertEqualObjects([definition class], [RMErrorDomainDefinition class]);
38 | XCTAssertEqualObjects(definition.name, @"NSURLErrorDomain");
39 | XCTAssertEqual(definition.codes.definitions.count, 1);
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/Tests/Tests/RMErrorsTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorsTest.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RMErrors.h"
11 | #import "RMErrorCodeRangeBoundary.h"
12 |
13 | @interface RMErrorsTest : XCTestCase
14 |
15 | @end
16 |
17 | @implementation RMErrorsTest
18 |
19 | - (void)testLoadContent {
20 | RMErrors *errors = [[RMErrors alloc] init];
21 | [errors load:@{
22 | @"domains": @{
23 | @"NSURLErrorDomain": @{}
24 | }
25 | }];
26 | XCTAssertEqual(errors.domains.definitions.count, 1);
27 | }
28 |
29 | - (void)testLoadPropertyList {
30 | RMErrors *errors = [[RMErrors alloc] init];
31 | [errors loadPropertyList:RMErrorsDefaultFileName bundle:[NSBundle bundleForClass:self.class]];
32 | XCTAssertEqual(errors.domains.definitions.count, 1);
33 | }
34 |
35 | - (void)testDescribe {
36 | RMErrors *errors = [[RMErrors alloc] init];
37 | RMErrorDomainDefinition *errorDomain = [[RMErrorDomainDefinition alloc] initWithName:@"com.foo.bar.oopsie"];
38 | [errorDomain.codes add:[[RMErrorCodeDefinition alloc] initWithBoundary:[RMErrorCodeRangeBoundary boundaryWithPattern:@"500..503"] friendlyMessage:@"server error" transient:YES]];
39 |
40 | [errors.domains add:errorDomain];
41 |
42 | [errorDomain.codes add:[[RMErrorCodeDefinition alloc] initWithBoundary:[RMErrorCodeRangeBoundary boundaryWithPattern:@"504..510"] friendlyMessage:@"server is gone forever" transient:NO]];
43 |
44 | [errors.domains add:errorDomain];
45 |
46 | RMErrorDescription *description = [errors describe:[NSError errorWithDomain:@"com.foo.bar.oopsie" code:500 userInfo:nil]];
47 | XCTAssertNotNil(description);
48 | XCTAssertEqualObjects(description.friendlyMessage, @"server error");
49 | XCTAssertTrue(description.transient);
50 |
51 |
52 | description = [errors describe:[NSError errorWithDomain:@"com.foo.bar.oopsie" code:507 userInfo:nil]];
53 | XCTAssertNotNil(description);
54 | XCTAssertEqualObjects(description.friendlyMessage, @"server is gone forever");
55 | XCTAssertFalse(description.transient);
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/Tests/Tests/RMErrorsTransformationTest.m:
--------------------------------------------------------------------------------
1 | //
2 | // RMErrorsTransformationTest.m
3 | // RideMarketplace
4 | //
5 | // Created by Johan Ride on 8/25/15.
6 | // Copyright (c) 2015 Ride. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface RMTestHelloErrorTransformation : NSObject
13 |
14 | @end
15 |
16 | @implementation RMTestHelloErrorTransformation
17 |
18 | - (NSError *)transform:(nonnull NSError *)original {
19 | NSString *msg = original.userInfo[@"msg"];
20 | if([@"hello" isEqualToString:msg]) {
21 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:original.userInfo];
22 | userInfo[@"msg"] = [original.userInfo[@"msg"] stringByAppendingString:@" world"];
23 | return [NSError errorWithDomain:original.domain code:original.code userInfo:userInfo];
24 | }
25 | return original;
26 | }
27 |
28 | @end
29 |
30 | @interface RMTestWorldErrorTransformation : NSObject
31 |
32 | @end
33 |
34 | @implementation RMTestWorldErrorTransformation
35 |
36 | - (NSError *)transform:(NSError *)original {
37 | if(original.userInfo[@"msg"]) {
38 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:original.userInfo];
39 | userInfo[NSLocalizedDescriptionKey] = userInfo[@"msg"];
40 | return [NSError errorWithDomain:original.domain code:original.code userInfo:userInfo];
41 | }
42 | return original;
43 | }
44 |
45 | @end
46 |
47 | @interface RMErrorsTransformationTest : XCTestCase
48 |
49 | @end
50 |
51 | @implementation RMErrorsTransformationTest
52 |
53 | - (void)testTransformationOriginal {
54 | RMErrorTransformations *transformations = [[RMErrorTransformations alloc] init];
55 | [transformations add:[[RMTestHelloErrorTransformation alloc] init]];
56 | [transformations add:[[RMTestWorldErrorTransformation alloc] init]];
57 |
58 | NSError *original = [NSError errorWithDomain:@"com.foo.test" code:1 userInfo:@{NSLocalizedDescriptionKey: @"this is not a greeting, should be kept original"}];
59 | NSError *transformed = [transformations transform:original];
60 | XCTAssertEqualObjects(transformed.userInfo[NSLocalizedDescriptionKey], @"this is not a greeting, should be kept original");
61 | }
62 |
63 | - (void)testTransformationChain {
64 | RMErrorTransformations *transformations = [[RMErrorTransformations alloc] init];
65 | [transformations add:[[RMTestHelloErrorTransformation alloc] init]];
66 | [transformations add:[[RMTestWorldErrorTransformation alloc] init]];
67 |
68 | NSError *original = [NSError errorWithDomain:@"com.foo.test" code:1 userInfo:@{@"msg": @"hello"}];
69 | NSError *transformed = [transformations transform:original];
70 | XCTAssertEqualObjects(transformed.userInfo[NSLocalizedDescriptionKey], @"hello world");
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------