Permalink
Browse files

Use NSProxy as base class for FBApplicationProcessProxy (#979)

Summary:
Allows to forward NSKeyValueObserverRegistration methods.

Fixes issue #975 — Allows to work with Xcode 10 beta 5 and beta 6.

Tested for Xcode 9.4.1 as well
Pull Request resolved: #979

Differential Revision: D9399064

Pulled By: marekcirkos

fbshipit-source-id: f1976e0fdefdaaf2ed5c52eeeace6c99acb50ee8
  • Loading branch information...
fr0l authored and facebook-github-bot committed Aug 20, 2018
1 parent b534734 commit c233bf0776f87e5a589a83e688508c383b0cdb34
@@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
18033EFF208761FC00FED81D /* RoutingHTTPServer.framework in Copy frameworks */ = {isa = PBXBuildFile; fileRef = AD42DD2B1CF1238500806E5D /* RoutingHTTPServer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1FC3B2E32121ECF600B61EE0 /* FBApplicationProcessProxyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FC3B2E12121EC8C00B61EE0 /* FBApplicationProcessProxyTests.m */; };
711084441DA3AA7500F913D6 /* FBXPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 711084421DA3AA7500F913D6 /* FBXPath.h */; settings = {ATTRIBUTES = (Public, ); }; };
711084451DA3AA7500F913D6 /* FBXPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 711084431DA3AA7500F913D6 /* FBXPath.m */; };
7119E1EC1E891F8600D0B125 /* FBPickerWheelSelectTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7119E1EB1E891F8600D0B125 /* FBPickerWheelSelectTests.m */; };
@@ -412,6 +413,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
1FC3B2E12121EC8C00B61EE0 /* FBApplicationProcessProxyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBApplicationProcessProxyTests.m; sourceTree = "<group>"; };
44757A831D42CE8300ECF35E /* XCUIDeviceRotationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCUIDeviceRotationTests.m; sourceTree = "<group>"; };
711084421DA3AA7500F913D6 /* FBXPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBXPath.h; sourceTree = "<group>"; };
711084431DA3AA7500F913D6 /* FBXPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBXPath.m; sourceTree = "<group>"; };
@@ -1126,6 +1128,7 @@
isa = PBXGroup;
children = (
ADBC39951D07840300327304 /* Doubles */,
1FC3B2E12121EC8C00B61EE0 /* FBApplicationProcessProxyTests.m */,
71A7EAFB1E229302001DA4F2 /* FBClassChainTests.m */,
EEE16E961D33A25500172525 /* FBConfigurationTests.m */,
ADBC39931D0782CD00327304 /* FBElementCacheTests.m */,
@@ -1882,6 +1885,7 @@
EE3F8CFE1D08AA17006F02CE /* FBRunLoopSpinnerTests.m in Sources */,
714801D11FA9D9FA00DC5997 /* FBSDKVersionTests.m in Sources */,
EE3F8D001D08B05F006F02CE /* FBElementTypeTransformerTests.m in Sources */,
1FC3B2E32121ECF600B61EE0 /* FBApplicationProcessProxyTests.m in Sources */,
EEE16E971D33A25500172525 /* FBConfigurationTests.m in Sources */,
ADBC39941D0782CD00327304 /* FBElementCacheTests.m in Sources */,
EE8DDD7920C565FB004D4925 /* XCUIApplicationFBHelpersTests.m in Sources */,
@@ -122,7 +122,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
return;
}
XCUIApplicationProcess *applicationProcess = change[NSKeyValueChangeNewKey];
if (!applicationProcess || ![applicationProcess isMemberOfClass:XCUIApplicationProcess.class]) {
if (!applicationProcess || [applicationProcess isProxy] || ![applicationProcess isMemberOfClass:XCUIApplicationProcess.class]) {
return;
}
[object setValue:[FBApplicationProcessProxy proxyWithApplicationProcess:applicationProcess] forKey:keyPath];
@@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
Proxy that would forward all calls to it's applicationProcess.
However it will block call to waitForQuiescence if shouldWaitForQuiescence is set to NO
*/
@interface FBApplicationProcessProxy : NSObject
@interface FBApplicationProcessProxy : NSProxy

/**
Convenience initializer
@@ -20,11 +20,18 @@ @implementation FBApplicationProcessProxy
+ (instancetype)proxyWithApplicationProcess:(XCUIApplicationProcess *)applicationProcess
{
NSParameterAssert(applicationProcess);
FBApplicationProcessProxy *proxy = [self.class new];
NSParameterAssert([[applicationProcess class] isEqual:XCUIApplicationProcess.class]);
FBApplicationProcessProxy *proxy = [[self.class alloc] init];
proxy.applicationProcess = applicationProcess;
return proxy;
}

- (instancetype)init {
return self;
}

#pragma mark - Override XCUIApplicationProcess methods

- (void)waitForQuiescence
{
if (!self.shouldWaitForQuiescence) {
@@ -45,9 +52,21 @@ - (void)waitForQuiescenceIncludingAnimationsIdle:(BOOL)includeAnimations
[self.applicationProcess waitForQuiescenceIncludingAnimationsIdle:includeAnimations];
}

#pragma mark - Forward not implemented methods to applicationProcess

- (id)forwardingTargetForSelector:(SEL)aSelector
{
return self.applicationProcess;
}

- (void)forwardInvocation:(NSInvocation *)invocation
{
[invocation invokeWithTarget:self.applicationProcess];
}

- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
return [self.applicationProcess methodSignatureForSelector:sel];
}

@end
@@ -0,0 +1,82 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

#import <XCTest/XCTest.h>
#import "FBApplicationProcessProxy.h"
#import "XCUIApplicationProcess.h"

@interface FBApplicationProcessProxy (NonProxiedMethod)
- (void)objectsMethod;
@end

@implementation FBApplicationProcessProxy (NonProxiedMethod)

- (void)objectsMethod
{
// intentionally empty
}

@end

@interface FBApplicationProcessProxy (ProxiedMethod)
- (int)proxiedMethod;
@end

@interface XCUIApplicationProcess (TestableMethods)
- (void)objectsMethod;
- (int)proxiedMethod;
@end

@implementation XCUIApplicationProcess (TestableMethods)

- (int)proxiedMethod;
{
return 1;
}

- (void)objectsMethod
{
NSString *errorMessage = [NSString stringWithFormat:@"Method %@ must NOT be proxied", NSStringFromSelector(_cmd)];
NSException * exception = [[NSException alloc] initWithName:@"Test failed" reason:errorMessage userInfo:nil];
[exception raise];
}

@end

@interface FBApplicationProcessProxyTest : XCTestCase

@end

@implementation FBApplicationProcessProxyTest

- (void)testMethodCallIsProxied {
XCUIApplicationProcess *applicationProcess = [[XCUIApplicationProcess alloc] init];
FBApplicationProcessProxy *proxy = [FBApplicationProcessProxy proxyWithApplicationProcess:applicationProcess];
XCTAssertEqual([proxy proxiedMethod], 1);
}

- (void)testMethodCallIsNotProxied {
XCUIApplicationProcess *applicationProcess = [[XCUIApplicationProcess alloc] init];
FBApplicationProcessProxy *proxy = [FBApplicationProcessProxy proxyWithApplicationProcess:applicationProcess];
XCTAssertNoThrow([proxy objectsMethod]);
}

- (void)testProxyIsProxy {
XCUIApplicationProcess *applicationProcess = [[XCUIApplicationProcess alloc] init];
FBApplicationProcessProxy *proxy = [FBApplicationProcessProxy proxyWithApplicationProcess:applicationProcess];
XCTAssertTrue([proxy isProxy]);
}

- (void)testAssertProxyObjectParameter {
XCUIApplicationProcess *applicationProcess = [[XCUIApplicationProcess alloc] init];
id proxy = (id)[FBApplicationProcessProxy proxyWithApplicationProcess:applicationProcess];
XCTAssertThrows([FBApplicationProcessProxy proxyWithApplicationProcess:proxy]);
}

@end

0 comments on commit c233bf0

Please sign in to comment.