Skip to content

Commit

Permalink
Merge branch 'dmaclach-realNil'
Browse files Browse the repository at this point in the history
  • Loading branch information
erikdoe committed Jul 14, 2020
2 parents 461c694 + 7932a18 commit b8746e5
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 23 deletions.
14 changes: 13 additions & 1 deletion Source/OCMock.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@
817EB15C1BD765130047E85A /* OCMBlockArgCaller.h in Headers */ = {isa = PBXBuildFile; fileRef = 2FA2891034E7B73AA3511D17 /* OCMBlockArgCaller.h */; };
817EB15D1BD765130047E85A /* OCMArgAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 2FA2833B48908EAD36444671 /* OCMArgAction.h */; };
817EB1661BD7674D0047E85A /* OCMFunctionsPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 03F370CA1BAA1DE800CAD3E8 /* OCMFunctionsPrivate.h */; };
8B11D4B72448E2E900247BE2 /* OCMCPlusPlus98Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8B11D4B62448E2E900247BE2 /* OCMCPlusPlus98Tests.mm */; settings = {COMPILER_FLAGS = "-std=gnu++98"; }; };
8B11D4B82448E2F400247BE2 /* OCMCPlusPlus98Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8B11D4B62448E2E900247BE2 /* OCMCPlusPlus98Tests.mm */; settings = {COMPILER_FLAGS = "-std=gnu++98"; }; };
8B11D4BA2448E53600247BE2 /* OCMCPlusPlus11Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8B11D4B92448E53600247BE2 /* OCMCPlusPlus11Tests.mm */; settings = {COMPILER_FLAGS = "-std=gnu++11"; }; };
8B11D4BB2448E53600247BE2 /* OCMCPlusPlus11Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8B11D4B92448E53600247BE2 /* OCMCPlusPlus11Tests.mm */; settings = {COMPILER_FLAGS = "-std=gnu++11"; }; };
8BF73E53246CA75E00B9A52C /* OCMNoEscapeBlockTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BF73E52246CA75E00B9A52C /* OCMNoEscapeBlockTests.m */; settings = {COMPILER_FLAGS = "-Xclang -fexperimental-optimized-noescape"; }; };
8BF73E54246CA75E00B9A52C /* OCMNoEscapeBlockTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BF73E52246CA75E00B9A52C /* OCMNoEscapeBlockTests.m */; settings = {COMPILER_FLAGS = "-Xclang -fexperimental-optimized-noescape"; }; };
8DE97C5522B43EE60098C63F /* OCMockObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 03B3159E146333BF0052CD09 /* OCMockObject.m */; };
Expand Down Expand Up @@ -547,7 +551,7 @@
2FA28006D043CBDBBAEF6E3F /* OCMMacroState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMMacroState.h; sourceTree = "<group>"; };
2FA280987F4EA8A4D79000D0 /* OCMMacroState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCMMacroState.m; sourceTree = "<group>"; };
2FA280EB5E8CDEEAE76861F7 /* OCMNonRetainingObjectReturnValueProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCMNonRetainingObjectReturnValueProvider.m; sourceTree = "<group>"; };
2FA2813F93050582D83E1499 /* OCMockObjectRuntimeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCMockObjectRuntimeTests.m; sourceTree = "<group>"; };
2FA2813F93050582D83E1499 /* OCMockObjectRuntimeTests.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.objc; fileEncoding = 4; path = OCMockObjectRuntimeTests.m; sourceTree = "<group>"; };
2FA2822E19948FC997965267 /* OCMockObjectTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCMockObjectTests.m; sourceTree = "<group>"; };
2FA2833B48908EAD36444671 /* OCMArgAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMArgAction.h; sourceTree = "<group>"; };
2FA283D58AA7569D8A5B0C57 /* OCMBlockArgCaller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCMBlockArgCaller.m; sourceTree = "<group>"; };
Expand All @@ -571,6 +575,8 @@
3CFBDD751BB3DB200050D9C5 /* TestClassWithCustomReferenceCounting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestClassWithCustomReferenceCounting.h; sourceTree = "<group>"; };
3CFBDD761BB3DB200050D9C5 /* TestClassWithCustomReferenceCounting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestClassWithCustomReferenceCounting.m; sourceTree = "<group>"; };
817EB1621BD765130047E85A /* OCMock.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OCMock.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8B11D4B62448E2E900247BE2 /* OCMCPlusPlus98Tests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OCMCPlusPlus98Tests.mm; sourceTree = "<group>"; };
8B11D4B92448E53600247BE2 /* OCMCPlusPlus11Tests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OCMCPlusPlus11Tests.mm; sourceTree = "<group>"; };
8BF73E52246CA75E00B9A52C /* OCMNoEscapeBlockTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OCMNoEscapeBlockTests.m; sourceTree = "<group>"; };
8DE97CA022B43EE60098C63F /* OCMock.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OCMock.framework; sourceTree = BUILT_PRODUCTS_DIR; };
A02926811CA0725A00594AAF /* TestObjects.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = TestObjects.xcdatamodel; sourceTree = "<group>"; };
Expand Down Expand Up @@ -751,6 +757,8 @@
037ECD5318FAD84100AF0E4C /* OCMInvocationMatcherTests.m */,
031E50571BB4A56300E257C3 /* OCMBoxedReturnValueProviderTests.m */,
03B316211463350E0052CD09 /* OCMConstraintTests.m */,
8B11D4B62448E2E900247BE2 /* OCMCPlusPlus98Tests.mm */,
8B11D4B92448E53600247BE2 /* OCMCPlusPlus11Tests.mm */,
2FA28EDBF243639C57F88A1B /* OCMArgTests.m */,
036865631D3571A8005E6BEE /* OCMQuantifierTests.m */,
03B316291463350E0052CD09 /* OCObserverMockObjectTests.m */,
Expand Down Expand Up @@ -1501,9 +1509,11 @@
03565A4818F05721003AE91E /* OCMStubRecorderTests.m in Sources */,
03565A4518F05721003AE91E /* OCMockObjectForwardingTargetTests.m in Sources */,
2FA28FA53C57236B6DD64E82 /* OCMockObjectRuntimeTests.m in Sources */,
8B11D4BA2448E53600247BE2 /* OCMCPlusPlus11Tests.mm in Sources */,
2FA2839F33289795284C32FB /* OCMockObjectTests.m in Sources */,
038599F723807B06002B3ABE /* OCMockObjectInternalTests.m in Sources */,
8BF73E53246CA75E00B9A52C /* OCMNoEscapeBlockTests.m in Sources */,
8B11D4B72448E2E900247BE2 /* OCMCPlusPlus98Tests.mm in Sources */,
2FA28AB33F01A7D980F2C705 /* OCMockObjectDynamicPropertyMockingTests.m in Sources */,
031E50581BB4A56300E257C3 /* OCMBoxedReturnValueProviderTests.m in Sources */,
);
Expand Down Expand Up @@ -1614,9 +1624,11 @@
03C9CA1D18F05A75006DF94D /* OCMockObjectProtocolMocksTests.m in Sources */,
03E98D5118F310EE00522D42 /* OCMockObjectMacroTests.m in Sources */,
A06930951CA1BFC900513023 /* TestObjects.xcdatamodeld in Sources */,
8B11D4BB2448E53600247BE2 /* OCMCPlusPlus11Tests.mm in Sources */,
2FA28295E1F58F40A77D7448 /* OCMockObjectRuntimeTests.m in Sources */,
038599F823807B06002B3ABE /* OCMockObjectInternalTests.m in Sources */,
8BF73E54246CA75E00B9A52C /* OCMNoEscapeBlockTests.m in Sources */,
8B11D4B82448E2F400247BE2 /* OCMCPlusPlus98Tests.mm in Sources */,
2FA28246CD449A01717B1CEC /* OCMockObjectTests.m in Sources */,
2FA28F12AAD384A8CB16094B /* OCMockObjectDynamicPropertyMockingTests.m in Sources */,
);
Expand Down
15 changes: 8 additions & 7 deletions Source/OCMock/OCMBoxedReturnValueProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#import "OCMFunctionsPrivate.h"
#import "NSValue+OCMAdditions.h"


@implementation OCMBoxedReturnValueProvider

- (void)handleInvocation:(NSInvocation *)anInvocation
Expand All @@ -26,10 +27,11 @@ - (void)handleInvocation:(NSInvocation *)anInvocation
NSUInteger returnTypeSize = [[anInvocation methodSignature] methodReturnLength];
char valueBuffer[returnTypeSize];
NSValue *returnValueAsNSValue = (NSValue *)returnValue;
[returnValueAsNSValue getValue:valueBuffer];

if([self isMethodReturnType:returnType compatibleWithValueType:[returnValueAsNSValue objCType]])
if([self isMethodReturnType:returnType compatibleWithValueType:[returnValueAsNSValue objCType]
value:valueBuffer valueSize:returnTypeSize])
{
[returnValueAsNSValue getValue:valueBuffer];
[anInvocation setReturnValue:valueBuffer];
}
else if([returnValueAsNSValue getBytes:valueBuffer objCType:returnType])
Expand All @@ -43,16 +45,15 @@ - (void)handleInvocation:(NSInvocation *)anInvocation
}
}


- (BOOL)isMethodReturnType:(const char *)returnType compatibleWithValueType:(const char *)valueType
- (BOOL)isMethodReturnType:(const char *)returnType compatibleWithValueType:(const char *)valueType value:(const void *)value valueSize:(size_t)valueSize
{
/* Same types are obviously compatible */
if(strcmp(returnType, valueType) == 0)
return YES;

/* Allow void* for methods that return id, mainly to be able to handle nil */
if(strcmp(returnType, @encode(id)) == 0 && strcmp(valueType, @encode(void *)) == 0)
return YES;
/* Special treatment for nil and Nil */
if(strcmp(returnType, @encode(id)) == 0 || strcmp(returnType, @encode(Class)) == 0)
return OCMIsNilValue(valueType, value, valueSize);

return OCMEqualTypesAllowingOpaqueStructs(returnType, valueType);
}
Expand Down
18 changes: 18 additions & 0 deletions Source/OCMock/OCMFunctions.m
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,24 @@ BOOL OCMEqualTypesAllowingOpaqueStructs(const char *type1, const char *type2)
}
}

BOOL OCMIsNilValue(const char *objectCType, const void *value, size_t valueSize)
{
// First, check value itself
for(size_t i = 0; i < valueSize; i++)
if(((const char *)value)[i] != 0)
return NO;

// Depending on the compilation settings of the file where the return value gets recorded,
// nil and Nil get potentially different encodings. Check all known encodings.
if((strcmp(objectCType, @encode(void *)) == 0) || // Standard Objective-C
(strcmp(objectCType, @encode(int)) == 0) || // 32 bit C++ (before nullptr)
(strcmp(objectCType, @encode(long long)) == 0) || // 64 bit C++ (before nullptr)
(strcmp(objectCType, @encode(char *)) == 0)) // C++ with nullptr
return YES;

return NO;
}


BOOL OCMIsAppleBaseClass(Class cls)
{
Expand Down
1 change: 1 addition & 0 deletions Source/OCMock/OCMFunctionsPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ BOOL OCMIsObjectType(const char *objCType);
const char *OCMTypeWithoutQualifiers(const char *objCType);
BOOL OCMEqualTypesAllowingOpaqueStructs(const char *type1, const char *type2);
CFNumberType OCMNumberTypeForObjCType(const char *objcType);
BOOL OCMIsNilValue(const char *objectCType, const void *value, size_t valueSize);

BOOL OCMIsAppleBaseClass(Class cls);
BOOL OCMIsApplePrivateMethod(Class cls, SEL sel);
Expand Down
23 changes: 11 additions & 12 deletions Source/OCMockTests/OCMBoxedReturnValueProviderTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
#import "OCMBoxedReturnValueProvider.h"

@interface OCMBoxedReturnValueProvider(Private)
- (BOOL)isMethodReturnType:(const char *)returnType compatibleWithValueType:(const char *)valueType;
- (BOOL)isMethodReturnType:(const char *)returnType compatibleWithValueType:(const char *)valueType value:(const char*)value valueSize:(size_t)valueSize;
@end


@interface OCMBoxedReturnValueProviderTests : XCTestCase

@end
Expand Down Expand Up @@ -53,12 +54,12 @@ - (void)testCorrectEqualityForCppProperty
"r^{GURL}";

OCMBoxedReturnValueProvider *boxed = [OCMBoxedReturnValueProvider new];
XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type2]);
XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type3]);
XCTAssertTrue([boxed isMethodReturnType:type2 compatibleWithValueType:type1]);
XCTAssertTrue([boxed isMethodReturnType:type2 compatibleWithValueType:type3]);
XCTAssertTrue([boxed isMethodReturnType:type3 compatibleWithValueType:type1]);
XCTAssertTrue([boxed isMethodReturnType:type3 compatibleWithValueType:type2]);
XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type2 value:NULL valueSize:0]);
XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type3 value:NULL valueSize:0]);
XCTAssertTrue([boxed isMethodReturnType:type2 compatibleWithValueType:type1 value:NULL valueSize:0]);
XCTAssertTrue([boxed isMethodReturnType:type2 compatibleWithValueType:type3 value:NULL valueSize:0]);
XCTAssertTrue([boxed isMethodReturnType:type3 compatibleWithValueType:type1 value:NULL valueSize:0]);
XCTAssertTrue([boxed isMethodReturnType:type3 compatibleWithValueType:type2 value:NULL valueSize:0]);
}


Expand All @@ -78,7 +79,7 @@ - (void)testCorrectEqualityForCppReturnTypesWithVtables
"ar> >={__rep=(?={__long=QQ*}{__short=(?=Cc)[23c]}{__raw=[3Q]})}}}}";

OCMBoxedReturnValueProvider *boxed = [OCMBoxedReturnValueProvider new];
XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type2]);
XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type2 value:NULL valueSize:0]);
}


Expand All @@ -89,8 +90,7 @@ - (void)testCorrectEqualityForStructureWithUnknownName
const char *type2 = "{CLLocationCoordinate2D=dd}";

OCMBoxedReturnValueProvider *boxed = [OCMBoxedReturnValueProvider new];
XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type2]);

XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type2 value:NULL valueSize:0]);
}


Expand All @@ -115,8 +115,7 @@ - (void)testCorrectEqualityForStructureWithoutName
"pressed_pair<GURL *, std::__1::default_delete<GURL> >=^{GURL}}}}";

OCMBoxedReturnValueProvider *boxed = [OCMBoxedReturnValueProvider new];
XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type2]);

XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type2 value:NULL valueSize:0]);
}

@end
Expand Down
45 changes: 45 additions & 0 deletions Source/OCMockTests/OCMCPlusPlus11Tests.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2020 Erik Doernenburg and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use these files except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>

#if !defined(__cplusplus)
#error This file must be compiled with C++
#endif

#if !__has_feature(cxx_nullptr)
#error This file must be compiled with a version of C++ that supports nullptr
#endif

@interface OCMCPlusPlus11Tests : XCTestCase
@end


@implementation OCMCPlusPlus11Tests

- (void)testSetsUpStubReturningNilForIdReturnType
{
id mock = OCMPartialMock([NSArray arrayWithObject:@"Foo"]);

OCMExpect([mock lastObject]).andReturn(nil);
XCTAssertNil([mock lastObject], @"Should have returned stubbed value");

OCMExpect([mock lastObject]).andReturn(Nil);
XCTAssertNil([mock lastObject], @"Should have returned stubbed value");
}

@end
45 changes: 45 additions & 0 deletions Source/OCMockTests/OCMCPlusPlus98Tests.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2020 Erik Doernenburg and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use these files except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>

#if !defined(__cplusplus)
#error This file must be compiled with C++
#endif

#if __has_feature(cxx_nullptr)
#error This file must be compiled with a version of C++ (98) that doesn't support nullptr
#endif

@interface OCMCPlusPlus98Tests : XCTestCase
@end


@implementation OCMCPlusPlus98Tests

- (void)testSetsUpStubReturningNilForIdReturnType
{
id mock = OCMPartialMock([NSArray arrayWithObject:@"Foo"]);

OCMExpect([mock lastObject]).andReturn(nil);
XCTAssertNil([mock lastObject], @"Should have returned stubbed value");

OCMExpect([mock lastObject]).andReturn(Nil);
XCTAssertNil([mock lastObject], @"Should have returned stubbed value");
}

@end
33 changes: 30 additions & 3 deletions Source/OCMockTests/OCMockObjectMacroTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ - (NSDecimalNumber*)method {

@end

@interface TestClassWithClassReturnMethod : NSObject

- (Class)method;

@end

@implementation TestClassWithClassReturnMethod

- (Class)method
{
return [self class];
}

@end



// implemented in OCMockObjectClassMethodMockingTests

Expand Down Expand Up @@ -177,11 +193,22 @@ - (void)testSetsUpStubsWithStructureReturnValues

- (void)testSetsUpStubReturningNilForIdReturnType
{
id mock = OCMClassMock([NSString class]);
id mock = OCMPartialMock([NSArray arrayWithObject:@"Foo"]);

OCMStub([mock lastObject]).andReturn(nil);
XCTAssertNil([mock lastObject], @"Should have returned stubbed value");
}

- (void)testSetsUpStubReturningNilForClassReturnType
{
id mock = OCMPartialMock([[TestClassWithClassReturnMethod alloc] init]);

OCMStub([mock lowercaseString]).andReturn(nil);
OCMStub([mock method]).andReturn(Nil);
XCTAssertNil([mock method], @"Should have returned stubbed value");

XCTAssertNil([mock lowercaseString], @"Should have returned stubbed value");
// sometimes nil is used where Nil should be used
OCMStub([mock method]).andReturn(nil);
XCTAssertNil([mock method], @"Should have returned stubbed value");
}

- (void)testSetsUpExceptionThrowing
Expand Down

0 comments on commit b8746e5

Please sign in to comment.