Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Cuckoo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@
6767946AF36C2A279F53D3FC /* ToBeStubbedProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE705433C346CA3DF4E2AB96 /* ToBeStubbedProperty.swift */; };
67BC45751E3361D5B2EE6C47 /* Array+matchers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1D814F035D5D39FC84D26C /* Array+matchers.swift */; };
68472F9A24D3ECA700E096C6 /* GeneratedMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68472F9924D3ECA600E096C6 /* GeneratedMocks.swift */; };
68472F9C24D3EE1100E096C6 /* ObjectiveExamplesTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68472F9B24D3EE1100E096C6 /* ObjectiveExamplesTest.swift */; };
68666AF31756DE755BED16A0 /* GenericClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F01C5ABA73DC1B0CCE088669 /* GenericClass.swift */; };
68696CFDFD67F6D77057F64D /* CallMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C854CC76B478ED72B6D3A65 /* CallMatcher.swift */; };
689E3852D2B5C6C81837A08F /* StubFunctionThenTrait.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C749F49256DDA51A9C96C9 /* StubFunctionThenTrait.swift */; };
Expand Down Expand Up @@ -773,7 +772,6 @@
654DD2C28B20B62C30F20699 /* ObjectiveCatcher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ObjectiveCatcher.m; sourceTree = "<group>"; };
6777A3E4D2701ADC5254EDB5 /* Pods-Cuckoo_OCMock-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Cuckoo_OCMock-macOS.debug.xcconfig"; path = "Target Support Files/Pods-Cuckoo_OCMock-macOS/Pods-Cuckoo_OCMock-macOS.debug.xcconfig"; sourceTree = "<group>"; };
68472F9924D3ECA600E096C6 /* GeneratedMocks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GeneratedMocks.swift; path = Generated/GeneratedMocks.swift; sourceTree = "<group>"; };
68472F9B24D3EE1100E096C6 /* ObjectiveExamplesTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectiveExamplesTest.swift; sourceTree = "<group>"; };
6873C8013002AFEA7565BDAC /* ClassTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClassTest.swift; sourceTree = "<group>"; };
68BD8B62F4589B263FA137F0 /* Pods-Cuckoo_OCMock-macOS-Cuckoo_OCMock-macOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Cuckoo_OCMock-macOS-Cuckoo_OCMock-macOSTests.debug.xcconfig"; path = "Target Support Files/Pods-Cuckoo_OCMock-macOS-Cuckoo_OCMock-macOSTests/Pods-Cuckoo_OCMock-macOS-Cuckoo_OCMock-macOSTests.debug.xcconfig"; sourceTree = "<group>"; };
6975D97C79395805A3BB3B04 /* Dictionary+matchers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+matchers.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1194,7 +1192,6 @@
children = (
EAFD10D2F5491D90D226ED78 /* ObjectiveClassTest.swift */,
C3D36A00ADFA42CC4C411F3E /* ObjectiveProtocolTest.swift */,
68472F9B24D3EE1100E096C6 /* ObjectiveExamplesTest.swift */,
);
path = OCMock;
sourceTree = "<group>";
Expand Down Expand Up @@ -2772,7 +2769,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
68472F9C24D3EE1100E096C6 /* ObjectiveExamplesTest.swift in Sources */,
25328F4C5AD244EB5D8C1868 /* TestError.swift in Sources */,
4EB79BE67C370C4BD74B4604 /* ObjectiveClassTest.swift in Sources */,
749D92CA8AAF73824D8EED26 /* ObjectiveProtocolTest.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion OCMock/ObjCHelpers/NSInvocation+OCMockWrapper.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ - (NSArray*)arguments {
[self getArgument:&arg atIndex: i];

NSValue* _Nonnull n = [NSValue value:&arg withObjCType: argType];
if (OCMIsObjectType(argType)) {
if (OCMIsObjectType(argType) && arg) {
[arguments addObject:(__bridge id _Nonnull)(arg)];
} else if (n) {
[arguments addObject:n];
Expand Down
13 changes: 13 additions & 0 deletions OCMock/ObjectiveArgumentClosure.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ public func objectiveArgumentClosure<IN1, IN2>(from: Any) -> (IN1, IN2) -> Void
}
}

// TODO add more variants
public func objectiveOptionalArgumentClosure<IN1, IN2>(from: Any) -> (IN1?, IN2?) -> Void {
return { in1, in2 in
var arg = from
let block = UnsafeRawPointer(&arg).assumingMemoryBound(to: (@convention(block) (NSObject?, NSObject?) -> Void).self).pointee

let nsIn1 = in1 == nil ? nil : TrustMe<NSObject>.onThis(in1 as Any)
let nsIn2 = in2 == nil ? nil : TrustMe<NSObject>.onThis(in2 as Any)

block(nsIn1, nsIn2)
}
}

public func objectiveArgumentClosure<IN1, IN2, IN3>(from: Any) -> (IN1, IN2, IN3) -> Void {
return { in1, in2, in3 in
var arg = from
Expand Down
38 changes: 38 additions & 0 deletions Tests/OCMock/ObjectiveClassTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,39 @@ class ObjectiveClassTest: XCTestCase {

objcVerify(mock.dudka(lelo: objcAny()))
}

func testSwiftClassWithNullableArgs() {
let expectCompleteWithNil = expectation(description: "Should call completion with nil")
let expectNilArg = expectation(description: "Should call with nil")

let mock = objcStub(for: SwiftClass.self) { stubber, mock in
stubber.when(mock.say("cheeze", completion: objcAnyClosure())).then { args in
let completionHandler = objectiveOptionalArgumentClosure(from: args[1]) as (String, [String]?) -> Void
completionHandler("meh", nil)
}
stubber.when(mock.say(nil, completion: objcAnyClosure())).then { args in
let completionHandler = objectiveArgumentClosure(from: args[1]) as (String, [String]?) -> Void
completionHandler("nil now behaves", [])
}
}

mock.say("cheeze") { result, messages in
XCTAssertEqual("meh", result)
XCTAssertNil(messages)
expectCompleteWithNil.fulfill()
}

mock.say(nil) { result, messages in
XCTAssertEqual("nil now behaves", result)
XCTAssertEqual([], messages)
expectNilArg.fulfill()
}

wait(for: [expectCompleteWithNil, expectNilArg], timeout: 1)

objcVerify(mock.say("cheeze", completion: objcAnyClosure()))
objcVerify(mock.say(nil, completion: objcAnyClosure()))
}
}

class SwiftClass: NSObject {
Expand All @@ -168,6 +201,11 @@ class SwiftClass: NSObject {
dynamic func dudka(lelo: String) -> Bool {
return false
}

@objc
dynamic func say(_ message: String?, completion: @escaping (String, [String]?) -> Void) -> Void {
// mock me
}
}
#else
#warning("macOS tests are missing.")
Expand Down