From 43b59338cc1a1d3f952ba72f36cdb2a353f5d4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endika=20Guti=C3=A9rrez?= Date: Mon, 16 Dec 2013 17:40:57 +0100 Subject: [PATCH] Added NSNull ActAsNullObjects --- NullObjects.xcodeproj/project.pbxproj | 20 +++++++++++++++++ NullObjects/NONull.m | 1 - NullObjects/NSNull+NullObjects.h | 17 ++++++++++++++ NullObjects/NSNull+NullObjects.m | 32 +++++++++++++++++++++++++++ NullObjects/NullObjects.h | 1 + NullObjectsTests/NullObjectsTests.m | 31 ++++++++++++++++++++++++++ 6 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 NullObjects/NSNull+NullObjects.h create mode 100644 NullObjects/NSNull+NullObjects.m diff --git a/NullObjects.xcodeproj/project.pbxproj b/NullObjects.xcodeproj/project.pbxproj index 064a852..787c1c7 100644 --- a/NullObjects.xcodeproj/project.pbxproj +++ b/NullObjects.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 0D149D65185F49D300A39AF6 /* NONull.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D149D64185F49D300A39AF6 /* NONull.m */; }; + 0D149D68185F614F00A39AF6 /* NSNull+NullObjects.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D149D67185F614F00A39AF6 /* NSNull+NullObjects.m */; }; 0DDBCE27185F414C00B42744 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0DDBCE26185F414C00B42744 /* Foundation.framework */; }; 0DDBCE2C185F414C00B42744 /* NullObjects.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0DDBCE2B185F414C00B42744 /* NullObjects.h */; }; 0DDBCE35185F414C00B42744 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0DDBCE34185F414C00B42744 /* XCTest.framework */; }; @@ -44,6 +45,8 @@ /* Begin PBXFileReference section */ 0D149D63185F49D300A39AF6 /* NONull.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NONull.h; sourceTree = ""; }; 0D149D64185F49D300A39AF6 /* NONull.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NONull.m; sourceTree = ""; }; + 0D149D66185F614F00A39AF6 /* NSNull+NullObjects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNull+NullObjects.h"; sourceTree = ""; }; + 0D149D67185F614F00A39AF6 /* NSNull+NullObjects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNull+NullObjects.m"; sourceTree = ""; }; 0DDBCE23185F414C00B42744 /* libNullObjects.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNullObjects.a; sourceTree = BUILT_PRODUCTS_DIR; }; 0DDBCE26185F414C00B42744 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 0DDBCE2A185F414C00B42744 /* NullObjects-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NullObjects-Prefix.pch"; sourceTree = ""; }; @@ -114,6 +117,8 @@ 0DDBCE2B185F414C00B42744 /* NullObjects.h */, 0D149D63185F49D300A39AF6 /* NONull.h */, 0D149D64185F49D300A39AF6 /* NONull.m */, + 0D149D66185F614F00A39AF6 /* NSNull+NullObjects.h */, + 0D149D67185F614F00A39AF6 /* NSNull+NullObjects.m */, 0DDBCE29185F414C00B42744 /* Supporting Files */, ); path = NullObjects; @@ -227,6 +232,7 @@ buildActionMask = 2147483647; files = ( 0D149D65185F49D300A39AF6 /* NONull.m in Sources */, + 0D149D68185F614F00A39AF6 /* NSNull+NullObjects.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -370,6 +376,13 @@ "$(inherited)", ); INFOPLIST_FILE = "NullObjectsTests/NullObjectsTests-Info.plist"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + XCTest, + "-ObjC", + "-all_load", + ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = xctest; }; @@ -387,6 +400,13 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "NullObjects/NullObjects-Prefix.pch"; INFOPLIST_FILE = "NullObjectsTests/NullObjectsTests-Info.plist"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + XCTest, + "-ObjC", + "-all_load", + ); PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = xctest; }; diff --git a/NullObjects/NONull.m b/NullObjects/NONull.m index f7513f9..f6b59aa 100644 --- a/NullObjects/NONull.m +++ b/NullObjects/NONull.m @@ -12,7 +12,6 @@ NSString * const NONullDummyMethodBlock = @"NODummyMethodBlock"; NSString * const NONullBlackHole = @"NONullBlackHole"; -NSString * const NOTraceable = @"NOTraceable"; id dummyMethod(id self, SEL _cmd) { return nil; diff --git a/NullObjects/NSNull+NullObjects.h b/NullObjects/NSNull+NullObjects.h new file mode 100644 index 0000000..5eccbac --- /dev/null +++ b/NullObjects/NSNull+NullObjects.h @@ -0,0 +1,17 @@ +// +// NSNull+NullObjects.h +// NullObjects +// +// Created by Endika Gutiérrez Salas on 16/12/13. +// Copyright (c) 2013 Endika Gutiérrez Salas. All rights reserved. +// + +#import + +@interface NSNull (NullObjects) + ++ (void)actAsNullObject; ++ (void)actAsBlackhole; ++ (void)actAsNullObjectWithOptions:(NSDictionary *)options; + +@end diff --git a/NullObjects/NSNull+NullObjects.m b/NullObjects/NSNull+NullObjects.m new file mode 100644 index 0000000..fc67154 --- /dev/null +++ b/NullObjects/NSNull+NullObjects.m @@ -0,0 +1,32 @@ +// +// NSNull+NullObjects.m +// NullObjects +// +// Created by Endika Gutiérrez Salas on 16/12/13. +// Copyright (c) 2013 Endika Gutiérrez Salas. All rights reserved. +// + +#import "NSNull+NullObjects.h" + +#import + +#import "NONull.h" + +@implementation NSNull (NullObjects) + ++ (void)actAsNullObject +{ + object_setClass([NSNull null], [NONull class]); +} + ++ (void)actAsBlackhole +{ + object_setClass([NSNull null], [[NONull blackhole] class]); +} + ++ (void)actAsNullObjectWithOptions:(NSDictionary *)options +{ + object_setClass([NSNull null], [NONull nullClassWithOptions:options]); +} + +@end diff --git a/NullObjects/NullObjects.h b/NullObjects/NullObjects.h index 849a4d2..f02bc0c 100644 --- a/NullObjects/NullObjects.h +++ b/NullObjects/NullObjects.h @@ -7,3 +7,4 @@ // #import "NONull.h" +#import "NSNull+NullObjects.h" diff --git a/NullObjectsTests/NullObjectsTests.m b/NullObjectsTests/NullObjectsTests.m index a06f285..917b524 100644 --- a/NullObjectsTests/NullObjectsTests.m +++ b/NullObjectsTests/NullObjectsTests.m @@ -54,4 +54,35 @@ - (void)testBlackholeNull XCTAssertEqual(blackhole[@"key"], blackhole, @"[NONull null] should return self for any method"); } +- (void)testNSNullActAsNullObject +{ + [NSNull actAsNullObject]; + + id simpleNull = (id) [NSNull null]; + + XCTAssertNoThrow([simpleNull lastObject], @"[NSNull actAsNullObject] never should raise exception"); + XCTAssertNoThrow([[simpleNull firstObject] stringValue], @"[NONull null] never should raise exception"); + XCTAssertNoThrow([simpleNull objectForKey:@"key"], @"[NONull null] never should raise exception"); + + XCTAssertEqual((__bridge void *)[simpleNull firstObject], nil, @"[NONull null] should return nil for any method"); + XCTAssertEqual((__bridge void *)[simpleNull objectForKey:@"key"], nil, @"[NONull null] should return nil for any method"); +} + +- (void)testNSNullActAsBlackholeNull +{ + [NSNull actAsBlackhole]; + + id blackhole = (id) [NSNull null]; + + XCTAssertNoThrow([blackhole lastObject], @"[NONull blackhole] never should raise exception"); + XCTAssertNoThrow([[blackhole firstObject] stringValue], @"[NONull blackhole] never should raise exception"); + XCTAssertNoThrow([blackhole objectForKey:@"key"], @"[NONull blackhole] never should raise exception"); + + XCTAssertEqual([blackhole firstObject], blackhole, @"[NONull null] should return self for any method"); + XCTAssertEqual([[[blackhole firstObject] firstObject] string], blackhole, @"[NONull null] should return self for any method"); + XCTAssertEqual([blackhole objectForKey:@"key"], blackhole, @"[NONull null] should return self for any method"); + XCTAssertEqual(blackhole[@"key"], blackhole, @"[NONull null] should return self for any method"); +} + + @end