blob: dbe14a492869cea42faebfacfb163c40044854b9 [file] [log] [blame]
//
// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file 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 "Service/Tests/TestsBundle/EDOTestDummy.h"
#import <CoreImage/CoreImage.h>
#include <objc/runtime.h>
#import "Service/Sources/EDOClientService.h"
#import "Service/Tests/FunctionalTests/EDOTestDummyInTest.h"
#import "Service/Tests/TestsBundle/EDOTestProtocolInApp.h"
static const NSInteger kLargeArraySize = 1000;
@implementation EDOTestDummyException
@end
@implementation EDOTestDummy
+ (EDOTestDummy *)classMethodWithNumber:(NSNumber *)value {
return [[self alloc] initWithValue:value.intValue];
}
- (instancetype)initWithValue:(int)value {
self = [self init];
if (self) {
_value = value;
}
return self;
}
#pragma mark - NSCopying
- (instancetype)copyWithZone:(nullable NSZone *)zone {
return self;
}
- (NSString *)description {
return [NSString stringWithFormat:@"Test Dummy %d", self.value];
}
- (void)voidWithValuePlusOne {
++_value;
}
- (void)voidWithInt:(int)arg1 {
_value += arg1;
}
- (void)voidWithNumber:(NSNumber *)value {
_value += value.intValue;
}
- (void)voidWithString:(NSString *)string data:(NSData *)data {
_value += (int)(string.length + data.length);
}
- (void)voidWithClass:(Class)clazz {
// Use the @c clazz to make sure it will not crash.
NSLog(@"%@", clazz);
}
- (void)voidWithStruct:(EDOTestDummyStruct)value {
_value += value.value;
}
- (void)voidWithId:(id)any {
if (!any) {
[[self exceptionWithReason:@"NilArg"] raise];
} else if ([any class] == NSClassFromString(@"EDOObject")) {
[[self exceptionWithReason:@"EDOArg"] raise];
} else {
[[self exceptionWithReason:@"NonNilArg"] raise];
}
}
- (void)voidWithValueOut:(NSNumber **)numberOut {
if (!numberOut) {
[[self exceptionWithReason:@"NilOutArg"] raise];
} else if (*numberOut != nil) {
*numberOut = [NSNumber numberWithInt:(*numberOut).intValue + _value];
} else {
*numberOut = [NSNumber numberWithInt:_value];
}
}
- (void)voidWithErrorOut:(NSError **)errorOut {
if (errorOut) {
*errorOut = [self error];
} else {
[[self exceptionWithReason:@"NilErrorOut"] raise];
}
}
- (void)voidWithOutObject:(EDOTestDummy **)dummyOut {
if (!dummyOut) {
[[self exceptionWithReason:@"dummyOut is nil"] raise];
} else if (*dummyOut) {
(*dummyOut).value += 5;
} else {
*dummyOut = [[EDOTestDummy alloc] initWithValue:self.value + 5];
}
}
- (void)voidWithValue:(int)value outSelf:(EDOTestDummy **)dummyOut {
self.value += value + (*dummyOut).value;
*dummyOut = self;
}
- (void)voidWithBlock:(void (^)(void))block {
// Block_copy should work on the remote block.
block = (__bridge id)Block_copy((__bridge void *)block);
if (block) {
block();
}
}
- (void)voidWithBlockAssigned:(void (^)(void))block {
// Regular assignment should do copy internally and maintain its lifecycle.
_block = block;
}
- (void)voidWithBlockAssignedAndInvoked:(void (^)(void))block {
// Regular assignment should do copy internally and maintain its lifecycle.
_block = block;
if (_block) {
_block();
}
}
- (void)voidWithProtocol:(Protocol *)protocol {
// Do nothing.
}
- (void)voidWithNullCPointer:(void *)cPointer {
// This can be called remotely, but only with NULL pointer values.
NSAssert(cPointer == NULL,
@"It should not be possible to pass a non-NULL value to this parameter.");
}
- (void)voidWithObjectArray:(NSArray<id> *)array {
// Do nothing
}
- (EDOTestDummyStruct)returnStructWithBlockStret:(EDOTestDummyStruct (^)(void))block {
return block();
}
- (double)returnWithBlockDouble:(double (^)(void))block {
// copy should work on the remote block.
block = [block copy];
return block();
}
- (id)returnWithBlockObject:(id (^)(EDOTestDummy *))block {
return block(self);
}
- (EDOTestDummy *)returnWithBlockOutObject:(void (^)(EDOTestDummy **))block {
EDOTestDummy *dummy;
block(&dummy);
return dummy;
}
- (EDOTestDummy *)returnWithInt:(int)intVar
dummyStruct:(EDOTestDummyStruct)dummyStruct
object:(id)object
blockComplex:
(EDOTestDummy * (^)(EDOTestDummyStruct, int, id, EDOTestDummy *))block {
return block(dummyStruct, intVar, object, self);
}
- (void)invokeBlock {
self.block();
}
- (int)returnInt {
return _value;
}
- (EDOTestDummyStruct)returnStruct {
return (EDOTestDummyStruct){.value = _value};
}
- (NSNumber *)returnNumber {
return [NSNumber numberWithInt:_value];
}
- (NSString *)returnString {
return [NSString stringWithFormat:@"%d", _value];
}
- (NSData *)returnData {
return [NSMutableData dataWithLength:_value];
}
- (EDOTestDummy *)returnSelf {
return self;
}
- (instancetype)returnDeepCopy {
return [[EDOTestDummy alloc] initWithValue:self.value];
}
- (NSDictionary<NSString *, NSNumber *> *)returnDictionary {
return @{ @"one" : @1, @"two" : @2, @"three" : @3, @"four" : @4 };
}
- (NSArray<NSNumber *> *)returnArray {
return @[ @1, @2, @3, @4 ];
}
- (NSArray<NSNumber *> *)returnLargeArray {
NSMutableArray<NSNumber *> *array = [[NSMutableArray alloc] initWithCapacity:kLargeArraySize];
for (int i = 0; i < kLargeArraySize; i++) {
[array addObject:@(i)];
}
return [array copy];
}
- (NSSet<NSNumber *> *)returnSet {
return [NSSet setWithObjects:@1, @2, @3, @4, nil];
}
- (Class)returnClass {
return [self class];
}
- (id)returnIdNil {
return nil;
}
- (Protocol *)returnWithProtocolInApp {
return @protocol(EDOTestProtocolInApp);
}
- (EDOTestDummy *)returnWeakDummy {
return _weakDummyInTest;
}
- (EDOTestDummy *)weaklyHeldDummyForMemoryTest {
EDOTestDummy *dummy = [[EDOTestDummy alloc] initWithValue:10];
_weakDummyInTest = dummy;
return dummy;
}
- (void (^)(void))returnBlock {
static void (^sameBlock)(void) = ^{
};
return sameBlock;
}
- (NSString *)nameFromSelector:(SEL)selector {
return NSStringFromSelector(selector);
}
- (SEL)selectorFromName:(NSString *)name {
return NSSelectorFromString(name);
}
- (CGFloat)colorRed:(CIColor *)color {
return color.red;
}
- (void)selWithThrow {
[[self exceptionWithReason:@"Just Throw"] raise];
}
- (EDOTestDummyStruct)structWithStruct:(EDOTestDummyStruct)value {
_value += value.value;
return (EDOTestDummyStruct){.value = _value};
}
- (EDOTestDummy *)returnIdWithInt:(int)value {
int oldValue = _value;
_value += value * 2;
return [[EDOTestDummy alloc] initWithValue:value + oldValue];
}
- (Class)classsWithClass:(Class)clz {
return clz;
}
- (NSNumber *)returnNumberWithInt:(int)arg value:(NSNumber *)value {
return [NSNumber numberWithInteger:arg + value.intValue + _value];
}
- (BOOL)returnBoolWithError:(NSError **)errorOrNil {
if (!errorOrNil) {
return NO;
} else {
*errorOrNil = [self error];
return YES;
}
}
- (NSString *)returnClassNameWithObject:(id)object {
return NSStringFromClass(object_getClass(object));
}
- (NSString *)returnClassNameWithObjectRef:(id *)objRef {
if (!objRef) {
return nil;
} else if (!*objRef) {
return @"";
} else {
return NSStringFromClass(object_getClass(*objRef));
}
}
- (NSInteger)returnCountWithArray:(NSArray *)value {
return value.count;
}
- (NSInteger)returnSumWithArray:(NSArray *)value {
NSInteger result = 0;
for (NSNumber *number in value) {
result += number.integerValue;
}
return result;
}
- (NSInteger)returnSumWithArrayAndProxyCheck:(NSArray *)value {
NSAssert(!value.isProxy,
@"This method is to test pass-by-value. The parameter should not be a proxy.");
return [self returnSumWithArray:value];
}
- (int *)returnIntPointer {
return NULL;
}
- (UInt64)memoryAddressFromObject:(id)object {
return (UInt64)(__bridge void *)object;
}
- (UInt64)memoryAddressFromObjectRef:(id *)objRef {
return (UInt64)(__bridge void *)(*objRef);
}
- (NSException *)exceptionWithReason:(NSString *)reason {
return [EDOTestDummyException
exceptionWithName:[NSString stringWithFormat:@"Dummy %@ %d", reason, _value]
reason:reason
userInfo:nil];
}
- (NSError *)error {
return [NSError errorWithDomain:NSOSStatusErrorDomain code:self.value userInfo:nil];
}
+ (void)enumerateSelector:(void (^)(SEL selector))block {
SEL allSelectors[] = {
@selector(voidWithValuePlusOne),
@selector(voidWithInt:),
@selector(voidWithNumber:),
@selector(voidWithString:data:),
@selector(voidWithClass:),
@selector(voidWithStruct:),
@selector(voidWithId:),
@selector(voidWithValueOut:),
@selector(voidWithErrorOut:),
@selector(voidWithOutObject:),
@selector(voidWithValue:outSelf:),
@selector(returnInt),
@selector(returnStruct),
@selector(returnNumber),
@selector(returnString),
@selector(returnData),
@selector(returnSelf),
@selector(returnDeepCopy),
@selector(returnClass),
@selector(returnDictionary),
@selector(returnArray),
@selector(returnSet),
@selector(returnIdNil),
@selector(selWithThrow),
@selector(structWithStruct:),
@selector(returnIdWithInt:),
@selector(classsWithClass:),
@selector(returnNumberWithInt:value:),
@selector(returnBoolWithError:),
};
for (int i = 0; i < sizeof(allSelectors) / sizeof(SEL); ++i) {
block(allSelectors[i]);
}
}
#pragma mark - NSFastEnumeration
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
objects:(id __unsafe_unretained _Nullable[_Nonnull])buffer
count:(NSUInteger)len {
// Dummy implementation, not throw anything and succeed quietly.
return 0;
}
#pragma mark - EDOTestProtocolInApp
- (NSString *)protocolName {
return NSStringFromProtocol(@protocol(EDOTestProtocolInApp));
}
@end
@implementation EDOTestDummy (InTest)
- (int)callBackToTest:(EDOTestDummyInTest *)dummy withValue:(int)value {
value += [dummy callTestDummy:self];
return value + self.value;
}
- (int)selWithOutEDO:(EDOTestDummyInTest **)dummyOut dummy:(EDOTestDummyInTest *)dummyIn {
NSAssert(NSClassFromString(@"EDOTestDummyInTest") == nil,
@"EDOTestDummyInTest shouldn't be defined.");
if (!dummyOut) {
[[self exceptionWithReason:@"dummyOut is nil"] raise];
} else {
return (*dummyOut = [dummyIn makeAnotherDummy:self.value]).value.intValue;
}
return 0;
}
- (EDOTestDummyInTest *)selWithInOutEDO:(EDOTestDummyInTest **)dummyInOut {
if (!dummyInOut) {
[[self exceptionWithReason:@"DummyIn is nil"] raise];
return nil;
} else {
return [*dummyInOut makeAnotherDummy:self.value];
}
}
- (void)setDummInTest:(EDOTestDummyInTest *)dummyInTest withDummy:(EDOTestDummyInTest *)dummy {
dummyInTest.dummyInTest = dummy;
}
- (EDOTestDummyInTest *)getRootObject:(UInt16)port {
return [EDOClientService rootObjectWithPort:port];
}
- (EDOTestDummyInTest *)createEDOWithPort:(UInt16)port {
EDOTestDummyInTest *dummyInTest = [EDOClientService rootObjectWithPort:port];
// This returns a EDOObject.
return [dummyInTest makeAnotherDummy:5];
}
- (int)returnPlus10AndAsyncExecuteBlock:(EDOTestDummyInTest *)dummyInTest {
// Dispatch to the background queue to invoke the remote method to avoid the deadlock.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[dummyInTest invokeBlock];
});
return self.value + 10;
}
@end