Skip to content

Commit 3a86c0f

Browse files
committed
Merge pull request #18 from johankool/master
Pretty print errors
2 parents db6dea5 + 50a9f98 commit 3a86c0f

File tree

4 files changed

+41
-29
lines changed

4 files changed

+41
-29
lines changed

EFDataMappingKit.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "EFDataMappingKit"
3-
s.version = "0.1.2"
3+
s.version = "0.1.3"
44
s.summary = "EFDataMappingKit maps data such as those coming from JSON onto an instance using mappings"
55
s.description = "EFDataMappingKit maps data such as those coming from JSON onto an instance using mappings. The mappings are also used to simplify implementing the NSCoding protocol for a class, and to create a dictionary representation of an instance."
66
s.homepage = "https://github.com/Egeniq/EFDataMappingKit"

EFMapping/EFMapper.m

+5-5
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ - (BOOL)validateValues:(NSDictionary *)values forClass:(Class)aClass onObject:(i
177177
}
178178

179179
if ([errorsInArray count] > 0) {
180-
NSString *description = [NSString stringWithFormat:@"Encountered %lu validation error(s) in array for key %@", (unsigned long)[errorsInArray count], mapping.internalKey];
180+
NSString *description = [NSString stringWithFormat:@"Encountered %lu validation error%@ in array for key %@", (unsigned long)[errorsInArray count], [errorsInArray count] == 1 ? @"" : @"s", mapping.internalKey];
181181
NSError *validationError = [NSError errorWithDomain:EFMappingErrorDomain code:EFMappingUnexpectedClass userInfo:@{NSLocalizedDescriptionKey: description, EFMappingErrorValidationErrorsKey: errorsInArray}];
182182
errors[mapping.internalKey] = validationError;
183183
} else {
@@ -218,7 +218,7 @@ - (BOOL)validateValues:(NSDictionary *)values forClass:(Class)aClass onObject:(i
218218
}];
219219

220220
if ([errorsInDictionary count] > 0) {
221-
NSString *description = [NSString stringWithFormat:@"Encountered %lu validation error(s) in dictionary for key %@", (unsigned long)[errorsInDictionary count], mapping.internalKey];
221+
NSString *description = [NSString stringWithFormat:@"Encountered %lu validation error%@ in dictionary for key %@", (unsigned long)[errorsInDictionary count], [errorsInDictionary count] == 1 ? @"" : @"s", mapping.internalKey];
222222
NSError *validationError = [NSError errorWithDomain:EFMappingErrorDomain code:EFMappingUnexpectedClass userInfo:@{NSLocalizedDescriptionKey: description, EFMappingErrorValidationErrorsKey: errorsInDictionary}];
223223
errors[mapping.internalKey] = validationError;
224224
} else {
@@ -265,7 +265,7 @@ - (BOOL)validateValues:(NSDictionary *)values forClass:(Class)aClass onObject:(i
265265

266266
if ([errors count] > 0) {
267267
if (error != NULL) {
268-
NSString *description = [NSString stringWithFormat:NSLocalizedString(@"Encountered %d validation error(s) in %@", @""), [errors count], NSStringFromClass(aClass)];
268+
NSString *description = [NSString stringWithFormat:NSLocalizedString(@"Encountered %d validation error%@ in %@", @""), [errors count], [errors count] == 1 ? @"" : @"s", NSStringFromClass(aClass)];
269269
*error = [NSError errorWithDomain:EFMappingErrorDomain code:EFMappingInvalidValues userInfo:@{NSLocalizedDescriptionKey: description, EFMappingErrorValidationErrorsKey: errors}];
270270
}
271271
return NO;
@@ -409,7 +409,7 @@ - (BOOL)validateValue:(id)value isCollection:(BOOL)isCollection mapping:(EFMappi
409409
if (isCollection) {
410410
if (value && ![value isKindOfClass:mapping.collectionClass]) {
411411
if (error != NULL) {
412-
NSString *description = [NSString stringWithFormat:@"Did not expect value (%@) of class %@ for key %@ but %@ instance", value, NSStringFromClass([value class]), mapping.internalKey, NSStringFromClass(mapping.collectionClass)];
412+
NSString *description = [NSString stringWithFormat:@"Did not expect value (%@) of class %@ for key %@ but a %@ instance", value, NSStringFromClass([value class]), mapping.internalKey, NSStringFromClass(mapping.collectionClass)];
413413
*error = [NSError errorWithDomain:EFMappingErrorDomain code:EFMappingUnexpectedClass userInfo:@{NSLocalizedDescriptionKey: description}];
414414
}
415415
return NO;
@@ -424,7 +424,7 @@ - (BOOL)validateValue:(id)value isCollection:(BOOL)isCollection mapping:(EFMappi
424424
}
425425
} else {
426426
if (error != NULL) {
427-
NSString *description = [NSString stringWithFormat:@"Did not expect value (%@) of class %@ for key %@ but %@ instance%@", value, NSStringFromClass([value class]), mapping.internalKey, NSStringFromClass(mapping.internalClass), [self mappingsForClass:mapping.internalClass] ? @" or NSDictionary" : @""];
427+
NSString *description = [NSString stringWithFormat:@"Did not expect value (%@) of class %@ for key %@ but a %@ instance%@", value, NSStringFromClass([value class]), mapping.internalKey, NSStringFromClass(mapping.internalClass), [self mappingsForClass:mapping.internalClass] ? @" or NSDictionary" : @""];
428428
*error = [NSError errorWithDomain:EFMappingErrorDomain code:EFMappingUnexpectedClass userInfo:@{NSLocalizedDescriptionKey: description}];
429429
}
430430
return NO;

EFMapping/EFMappingError.m

+18-16
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,29 @@
1111
NSString * const EFMappingErrorDomain = @"EFMappingErrorDomain";
1212
NSString * const EFMappingErrorValidationErrorsKey = @"validationErrors";
1313

14-
NSString* EFPrettyMappingError(NSError *error) {
14+
NSString* EFPrettyMappingErrorWithIndentation(NSError *error, NSUInteger indentationLevel) {
1515
if ([error.domain isEqualToString:EFMappingErrorDomain]) {
1616
NSMutableString *string = [NSMutableString string];
17-
if (error.code == EFMappingInvalidValues) {
18-
[string appendFormat:@"%@:", error.userInfo[NSLocalizedDescriptionKey]];
19-
id errors = error.userInfo[EFMappingErrorValidationErrorsKey];
20-
if ([errors isKindOfClass:[NSArray class]]) {
21-
[errors enumerateObjectsUsingBlock:^(NSError *subError, NSUInteger idx, BOOL *stop) {
22-
[string appendFormat:@"\n\t- %lu: %@", (unsigned long)idx, subError.userInfo[NSLocalizedDescriptionKey]];
23-
}];
24-
} else if ([errors isKindOfClass:[NSDictionary class]]) {
25-
[errors enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSError *subError, BOOL *stop) {
26-
[string appendFormat:@"\n\t- %@: %@", key, subError.userInfo[NSLocalizedDescriptionKey]];
27-
}];
28-
}
29-
} else {
30-
// Do some recursive stuff here!
17+
[string appendString:error.userInfo[NSLocalizedDescriptionKey]];
18+
id errors = error.userInfo[EFMappingErrorValidationErrorsKey];
19+
NSString *tabs = [@"\n" stringByPaddingToLength:indentationLevel + 2 withString:@"\t" startingAtIndex:0];
20+
if ([errors isKindOfClass:[NSArray class]]) {
21+
[string appendString:@":"];
22+
[errors enumerateObjectsUsingBlock:^(NSError *subError, NSUInteger idx, BOOL *stop) {
23+
[string appendFormat:@"%@%lu: %@", tabs, (unsigned long)idx, EFPrettyMappingErrorWithIndentation(subError, indentationLevel + 1)];
24+
}];
25+
} else if ([errors isKindOfClass:[NSDictionary class]]) {
26+
[string appendString:@":"];
27+
[errors enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSError *subError, BOOL *stop) {
28+
[string appendFormat:@"%@%@: %@", tabs, key, EFPrettyMappingErrorWithIndentation(subError, indentationLevel + 1)];
29+
}];
3130
}
32-
[string appendString:@"\n"];
3331
return string;
3432
} else {
3533
return [error description];
3634
}
35+
}
36+
37+
NSString* EFPrettyMappingError(NSError *error) {
38+
return EFPrettyMappingErrorWithIndentation(error, 0);
3739
}

EFMappingTests/EFMappingTest.m

+17-7
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,6 @@ - (void)testSettingValues {
8282
m.externalKey = @"id";
8383
m.internalKey = @"guid";
8484
m.requires = [EFRequires exists];
85-
m.transformationBlock = ^id(id value, BOOL reverse) {
86-
if (reverse) {
87-
return [(NSURL *)value absoluteString];
88-
} else {
89-
return [NSURL URLWithString:(NSString *)value];
90-
}
91-
};
9285
}]] forClass:[EFSample class]];
9386

9487
NSError *error;
@@ -201,4 +194,21 @@ - (void)testRequirements {
201194
XCTAssertFalse([[EFRequires either:array or:[EFRequires equalTo:@10]] evaluateForValue:@1], @"Value or");
202195
}
203196

197+
- (void)testPrettyErrors {
198+
EFMapper *mapper = [[EFMapper alloc] init];
199+
[mapper registerMappings:@[[EFMapping mapping:^(EFMapping *m){m.internalClass = [NSString class]; m.externalKey = @"id"; m.internalKey = @"guid"; m.requires = [EFRequires exists];}],
200+
[EFMapping mappingForArrayOfClass:[EFSample class] externalKey:@"children" internalKey:@"relatedSamples"]] forClass:[EFSample class]];
201+
202+
NSError *error;
203+
EFSample *sample = [mapper objectOfClass:[EFSample class] withValues:@{@"id": @"1", @"children": @[@{@"id": @"2"}, @{@"id": @3, @"children": @[@{@"id": @"4"}, @{@"id": @5}]}]} error:&error];
204+
NSString *expectedErrorMsg = @"Encountered 1 validation error in EFSample:\n\
205+
\trelatedSamples: Encountered 1 validation error in array for key relatedSamples:\n\
206+
\t\t0: Encountered 2 validation errors in EFSample:\n\
207+
\t\t\tguid: Did not expect value (3) of class __NSCFNumber for key guid but a NSString instance\n\
208+
\t\t\trelatedSamples: Encountered 1 validation error in array for key relatedSamples:\n\
209+
\t\t\t\t0: Encountered 1 validation error in EFSample:\n\
210+
\t\t\t\t\tguid: Did not expect value (5) of class __NSCFNumber for key guid but a NSString instance";
211+
XCTAssertEqualObjects(EFPrettyMappingError(error), expectedErrorMsg, @"Pretty print error differs");
212+
}
213+
204214
@end

0 commit comments

Comments
 (0)