| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- // Software License Agreement (BSD License)
- //
- // Copyright (c) 2010-2025, Deusty, LLC
- // All rights reserved.
- //
- // Redistribution and use of this software in source and binary forms,
- // with or without modification, are permitted provided that the following conditions are met:
- //
- // * Redistributions of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- //
- // * Neither the name of Deusty nor the names of its contributors may be used
- // to endorse or promote products derived from this software without specific
- // prior written permission of Deusty, LLC.
- #import "DDSMocking.h"
- @implementation DDSMocking
- @end
- @implementation DDBasicMockArgument
- - (instancetype)initWithBlock:(void(^)(id object))block {
- if (self = [super init]) {
- self.block = block;
- }
- return self;
- }
- + (instancetype)alongsideWithBlock:(void(^)(id object))block {
- return [[self alloc] initWithBlock:block];
- }
- - (id)copyWithZone:(NSZone *)zone {
- return [self.class alongsideWithBlock:self.block];
- }
- @end
- @implementation DDBasicMockArgumentPosition
- - (instancetype)initWithSelector:(NSString *)selector position:(NSNumber *)position {
- if (self = [super init]) {
- self.selector = selector;
- self.position = position;
- }
- return self;
- }
- - (id)copyWithZone:(NSZone *)zone {
- return [[self.class alloc] initWithSelector:self.selector position:self.position];
- }
- - (BOOL)isEqual:(id)object {
- if (object == self) {
- return YES;
- }
-
- if (![object isKindOfClass:self.class]) {
- return NO;
- }
-
- __auto_type position = (DDBasicMockArgumentPosition *)object;
- return [position.selector isEqualToString:self.selector] && [position.position isEqualToNumber:self.position];
- }
- - (NSUInteger)hash {
- return [self.selector hash] + [self.position hash];
- }
- - (NSString *)debugDescription {
- return [NSString stringWithFormat:@"%@ selector: %@ position: %@", [super debugDescription], self.selector, self.position];
- }
- - (NSString *)description {
- return [NSString stringWithFormat:@"%@ selector: %@ position: %@", [super description], self.selector, self.position];
- }
- @end
- @interface DDBasicMock ()
- @property (strong, nonatomic, readwrite) id object;
- @property (assign, nonatomic, readwrite) BOOL stubEnabled;
- @property (copy, nonatomic, readwrite) NSDictionary <DDBasicMockArgumentPosition *, DDBasicMockArgument *>*positionsAndArguments; // extend later to NSArray if needed.
- @end
- @implementation DDBasicMock
- - (instancetype)initWithInstance:(id)object {
- self.object = object;
- self.positionsAndArguments = [NSDictionary new];
- return self;
- }
- + (instancetype)decoratedInstance:(id)object {
- return [[self alloc] initWithInstance:object];
- }
- - (instancetype)enableStub {
- self.stubEnabled = YES;
- return self;
- }
- - (instancetype)disableStub {
- self.stubEnabled = NO;
- return self;
- }
- - (void)addArgument:(DDBasicMockArgument *)argument forSelector:(SEL)selector atIndex:(NSInteger)index {
- NSMutableDictionary *dictionary = [self.positionsAndArguments mutableCopy];
- __auto_type thePosition = [[DDBasicMockArgumentPosition alloc] initWithSelector:NSStringFromSelector(selector)
- position:@(index)];
- dictionary[thePosition] = [argument copy];
- self.positionsAndArguments = dictionary;
- }
- - (void)forwardInvocation:(NSInvocation *)invocation {
- __auto_type numberOfArguments = [[invocation methodSignature] numberOfArguments];
- BOOL found = NO;
- for (NSUInteger i = 2; i < numberOfArguments; ++i) {
- void *abc = nil;
- [invocation getArgument:&abc atIndex:i];
- id argument = (__bridge id)(abc);
- __auto_type thePosition = [[DDBasicMockArgumentPosition alloc] initWithSelector:NSStringFromSelector(invocation.selector) position:@(i)];
- __auto_type argListener = self.positionsAndArguments[thePosition];
- if (argListener) {
- found = YES;
- argListener.block(argument);
- }
- }
- if (!found) {
- [invocation invokeWithTarget:self.object];
- }
- }
- - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
- return [self.object methodSignatureForSelector:sel];
- }
- - (BOOL)respondsToSelector:(SEL)aSelector {
- return [self.object respondsToSelector:aSelector];
- }
- @end
|