/*
 *  Copyright (c) 2013-2015 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>
#import <objc/runtime.h>

#if TARGET_OS_IPHONE
#define NSRect CGRect
#define NSZeroRect CGRectZero
#define NSMakeRect CGRectMake
#define valueWithRect valueWithCGRect
#endif

#pragma mark   Helper classes

@interface TestClassWithSimpleMethod : NSObject
+ (NSUInteger)initializeCallCount;
- (NSString *)foo;
@end

@implementation TestClassWithSimpleMethod

static NSUInteger initializeCallCount = 0;

+ (void)initialize
{
    initializeCallCount += 1;
}

+ (NSUInteger)initializeCallCount
{
    return initializeCallCount;
}

- (NSString *)foo
{
    return @"Foo";
}

@end


@interface TestClassThatCallsSelf : NSObject
{
    int methodInt;
}

- (NSString *)method1;
- (NSString *)method2;
- (NSRect)methodRect1;
- (NSRect)methodRect2;
- (int)methodInt;
- (void)methodVoid;
- (void)setMethodInt:(int)anInt;
@end

@implementation TestClassThatCallsSelf

- (NSString *)method1
{
	id retVal = [self method2];
	return retVal;
}

- (NSString *)method2
{
	return @"Foo";
}


- (NSRect)methodRect1
{
	NSRect retVal = [self methodRect2];
	return retVal;
}

- (NSRect)methodRect2
{
	return NSMakeRect(10, 10, 10, 10);
}

- (int)methodInt
{
	return methodInt;
}

- (void)methodVoid
{
}

- (void)setMethodInt:(int)anInt
{
	methodInt = anInt;
}

@end


@interface NSObject(OCMCategoryForTesting)

- (NSString *)categoryMethod;

@end

@implementation NSObject(OCMCategoryForTesting)

- (NSString *)categoryMethod
{
    return @"Foo-Category";
}

@end




@interface OCMockObjectPartialMocksTests : XCTestCase
{
    int numKVOCallbacks;
}

@end


@implementation OCMockObjectPartialMocksTests

#pragma mark   Tests for stubbing with partial mocks

- (void)testStubsMethodsOnPartialMock
{
	TestClassWithSimpleMethod *object = [[TestClassWithSimpleMethod alloc] init];
	id mock = [OCMockObject partialMockForObject:object];
	[[[mock stub] andReturn:@"hi"] foo];
	XCTAssertEqualObjects(@"hi", [mock foo], @"Should have returned stubbed value");
}

- (void)testForwardsUnstubbedMethodsCallsToRealObjectOnPartialMock
{
	TestClassWithSimpleMethod *object = [[TestClassWithSimpleMethod alloc] init];
	id mock = [OCMockObject partialMockForObject:object];
	XCTAssertEqualObjects(@"Foo", [mock foo], @"Should have returned value from real object.");
}

//- (void)testForwardsUnstubbedMethodsCallsToRealObjectOnPartialMockForTollFreeBridgedClasses
//{
//	mock = [OCMockObject partialMockForObject:[NSString stringWithString:@"hello2"]];
//	STAssertEqualObjects(@"HELLO2", [mock uppercaseString], @"Should have returned value from real object.");
//}

- (void)testStubsMethodOnRealObjectReference
{
	TestClassWithSimpleMethod *realObject = [[TestClassWithSimpleMethod alloc] init];
	id mock = [OCMockObject partialMockForObject:realObject];
	[[[mock stub] andReturn:@"TestFoo"] foo];
	XCTAssertEqualObjects(@"TestFoo", [realObject foo], @"Should have stubbed method.");
}

- (void)testCallsToSelfInRealObjectAreShadowedByPartialMock
{
	TestClassThatCallsSelf *realObject = [[TestClassThatCallsSelf alloc] init];
	id mock = [OCMockObject partialMockForObject:realObject];
	[[[mock stub] andReturn:@"FooFoo"] method2];
	XCTAssertEqualObjects(@"FooFoo", [mock method1], @"Should have called through to stubbed method.");
}

- (void)testCallsToSelfInRealObjectStructReturnAreShadowedByPartialMock
{
	TestClassThatCallsSelf *realObject = [[TestClassThatCallsSelf alloc] init];
	id mock = [OCMockObject partialMockForObject:realObject];
    [[[mock stub] andReturnValue:OCMOCK_VALUE(NSZeroRect)] methodRect2];
#if TARGET_OS_IPHONE
#define NSEqualRects CGRectEqualToRect
#endif
    XCTAssertTrue(NSEqualRects(NSZeroRect, [mock methodRect1]), @"Should have called through to stubbed method.");
}

- (void)testInvocationsOfNSObjectCategoryMethodsCanBeStubbed
{
    TestClassThatCallsSelf *realObject = [[TestClassThatCallsSelf alloc] init];
   	id mock = [OCMockObject partialMockForObject:realObject];
    [[[mock stub] andReturn:@"stubbed"] categoryMethod];
    XCTAssertEqualObjects(@"stubbed", [realObject categoryMethod], @"Should have stubbed NSObject's method");
}


#pragma mark   Tests for behaviour when setting up partial mocks

- (void)testPartialMockClassOverrideReportsOriginalClass
{
	TestClassThatCallsSelf *realObject = [[TestClassThatCallsSelf alloc] init];
	Class origClass = [realObject class];
	id mock = [OCMockObject partialMockForObject:realObject];
	XCTAssertEqualObjects([realObject class], origClass, @"Override of -class method did not work");
	XCTAssertEqualObjects([mock class], origClass, @"Mock proxy -class method did not work");
	XCTAssertFalse(origClass == object_getClass(realObject), @"Subclassing did not work");
	[mock stopMocking];
	XCTAssertEqualObjects([realObject class], origClass, @"Classes different after stopMocking");
	XCTAssertEqualObjects(object_getClass(realObject), origClass, @"Classes different after stopMocking");
}

- (void)testInitializeIsNotCalledOnMockedClass
{
    NSUInteger countBefore = [TestClassWithSimpleMethod initializeCallCount];

    TestClassWithSimpleMethod *object = [[TestClassWithSimpleMethod alloc] init];
    id mock = [OCMockObject partialMockForObject:object];
    [[[mock expect] andForwardToRealObject] foo];
    [object foo];

    NSUInteger countAfter = [TestClassWithSimpleMethod initializeCallCount];

    XCTAssertEqual(countBefore, countAfter, @"Creating a mock should not have resulted in call to +initialize");
}


- (void)testRefusesToCreateTwoPartialMocksForTheSameObject
{
    id object = [[TestClassThatCallsSelf alloc] init];

    id partialMock1 = [OCMockObject partialMockForObject:object];

    XCTAssertNotNil(partialMock1, @"Should have created first partial mock.");
    XCTAssertThrows([OCMockObject partialMockForObject:object], @"Should not have allowed creation of second partial mock");
}

- (void)testRefusesToCreatePartialMockForTollFreeBridgedClasses
{
    id object = (id)CFBridgingRelease(CFStringCreateWithCString(kCFAllocatorDefault, "foo", kCFStringEncodingASCII));
    XCTAssertThrowsSpecificNamed([OCMockObject partialMockForObject:object],
                                 NSException,
                                 NSInvalidArgumentException,
                                 @"should throw NSInvalidArgumentException exception");
}

#if TARGET_RT_64_BIT

- (void)testRefusesToCreatePartialMockForTaggedPointers
{
    NSDate *object = [NSDate dateWithTimeIntervalSince1970:0];
    XCTAssertThrowsSpecificNamed([OCMockObject partialMockForObject:object],
                                 NSException,
                                 NSInvalidArgumentException,
                                 @"should throw NSInvalidArgumentException exception");
}

#endif

- (void)testRefusesToCreatePartialMockForNilObject
{
    XCTAssertThrows(OCMPartialMock(nil));
}


#pragma mark   Tests for KVO interaction with mocks

/* Starting KVO observations on an already-mocked object generally should work. */
- (void)testAddingKVOObserverOnPartialMock
{
	static char *MyContext;
	TestClassThatCallsSelf *realObject = [[TestClassThatCallsSelf alloc] init];
	Class origClass = [realObject class];

	id mock = [OCMockObject partialMockForObject:realObject];
	Class ourSubclass = object_getClass(realObject);

	[realObject addObserver:self forKeyPath:@"methodInt" options:NSKeyValueObservingOptionNew context:MyContext];
	Class kvoClass = object_getClass(realObject);

	/* KVO additionally overrides the -class method, but they return the superclass of their special
	   subclass, which in this case is the special mock subclass */
	XCTAssertEqualObjects([realObject class], ourSubclass, @"KVO override of class did not return our subclass");
	XCTAssertFalse(ourSubclass == kvoClass, @"KVO with subclass did not work");

	[realObject setMethodInt:45];
	XCTAssertEqual(numKVOCallbacks, 1, @"did not get subclass KVO notification");
	[mock setMethodInt:47];
	XCTAssertEqual(numKVOCallbacks, 2, @"did not get mock KVO notification");

	[realObject removeObserver:self forKeyPath:@"methodInt" context:MyContext];
	XCTAssertEqualObjects([realObject class], origClass, @"Classes different after stopKVO");
	XCTAssertEqualObjects(object_getClass(realObject), ourSubclass, @"Classes different after stopKVO");

	[mock stopMocking];
	XCTAssertEqualObjects([realObject class], origClass, @"Classes different after stopMocking");
	XCTAssertEqualObjects(object_getClass(realObject), origClass, @"Classes different after stopMocking");
}

/* Mocking a class which already has KVO observations does not work, but does not crash. */
- (void)testPartialMockOnKVOObserved
{
	static char *MyContext;
	TestClassThatCallsSelf *realObject = [[TestClassThatCallsSelf alloc] init];
	Class origClass = [realObject class];
    
	[realObject addObserver:self forKeyPath:@"methodInt" options:NSKeyValueObservingOptionNew context:MyContext];
	Class kvoClass = object_getClass(realObject);

	id mock = [OCMockObject partialMockForObject:realObject];
	Class ourSubclass = object_getClass(realObject);
    
	XCTAssertEqualObjects([realObject class], origClass, @"We did not preserve the original [self class]");
	XCTAssertFalse(ourSubclass == kvoClass, @"KVO with subclass did not work");
    
	/* Due to the way we replace the object's class, the KVO class gets overwritten and
	   KVO notifications stop functioning.  If we did not do this, the presence of the mock
	   subclass would cause KVO to crash, at least without further tinkering. */
	[realObject setMethodInt:45];
//	STAssertEquals(numKVOCallbacks, 1, @"did not get subclass KVO notification");
	XCTAssertEqual(numKVOCallbacks, 0, @"got subclass KVO notification");
	[mock setMethodInt:47];
//	STAssertEquals(numKVOCallbacks, 2, @"did not get mock KVO notification");
	XCTAssertEqual(numKVOCallbacks, 0, @"got mock KVO notification");

	[mock stopMocking];
	XCTAssertEqualObjects([realObject class], origClass, @"Classes different after stopMocking");
//	STAssertEqualObjects(object_getClass(realObject), kvoClass, @"KVO class different after stopMocking");
	XCTAssertEqualObjects(object_getClass(realObject), origClass, @"class different after stopMocking");

	[realObject removeObserver:self forKeyPath:@"methodInt" context:MyContext];
	XCTAssertEqualObjects([realObject class], origClass, @"Classes different after stopKVO");
	XCTAssertEqualObjects(object_getClass(realObject), origClass, @"Classes different after stopKVO");
}


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
	numKVOCallbacks++;
}


#pragma mark   Tests for end of stubbing with partial mocks

- (void)testReturnsToRealImplementationWhenExpectedCallOccurred
{
    TestClassWithSimpleMethod *realObject = [[TestClassWithSimpleMethod alloc] init];
   	id mock = [OCMockObject partialMockForObject:realObject];
   	[[[mock expect] andReturn:@"TestFoo"] foo];
   	XCTAssertEqualObjects(@"TestFoo", [realObject foo], @"Should have stubbed method.");
   	XCTAssertEqualObjects(@"Foo", [realObject foo], @"Should have 'unstubbed' method.");
}

- (void)testRestoresObjectWhenStopped
{
	TestClassWithSimpleMethod *realObject = [[TestClassWithSimpleMethod alloc] init];
	id mock = [OCMockObject partialMockForObject:realObject];
	[[[mock stub] andReturn:@"TestFoo"] foo];
	XCTAssertEqualObjects(@"TestFoo", [realObject foo], @"Should have stubbed method.");
	XCTAssertEqualObjects(@"TestFoo", [realObject foo], @"Should have stubbed method.");
	[mock stopMocking];
	XCTAssertEqualObjects(@"Foo", [realObject foo], @"Should have 'unstubbed' method.");
}


#pragma mark   Tests for explicit forward to real object with partial mocks

- (void)testForwardsToRealObjectWhenSetUpAndCalledOnMock
{
	TestClassWithSimpleMethod *realObject = [[TestClassWithSimpleMethod alloc] init];
	id mock = [OCMockObject partialMockForObject:realObject];
    
	[[[mock expect] andForwardToRealObject] foo];
	XCTAssertEqual(@"Foo", [mock foo], @"Should have called method on real object.");
    
	[mock verify];
}

- (void)testForwardsToRealObjectWhenSetUpAndCalledOnRealObject
{
	TestClassWithSimpleMethod *realObject = [[TestClassWithSimpleMethod alloc] init];
	id mock = [OCMockObject partialMockForObject:realObject];
	
	[[[mock expect] andForwardToRealObject] foo];
	XCTAssertEqual(@"Foo", [realObject foo], @"Should have called method on real object.");
	
	[mock verify];
}

- (void)testReturnValueFromRealObjectShouldBeReturnedEvenWithPrecedingAndCall
{
  TestClassThatCallsSelf *object = [[TestClassThatCallsSelf alloc] init];
  OCMockObject *mock = OCMPartialMock(object);
  [[[[mock stub] andCall:@selector(firstReturnValueMethod) onObject:self] andForwardToRealObject] method2];
  XCTAssertEqualObjects([object method2], @"Foo", @"Should have returned value from real object.");
}

- (NSString *)firstReturnValueMethod
{
    return @"Bar";
}

- (void)testExpectedMethodCallsExpectedMethodWithExpectationOrdering
{
    TestClassThatCallsSelf *object = [[TestClassThatCallsSelf alloc] init];
    id mock = OCMPartialMock(object);
    [mock setExpectationOrderMatters:YES];
    [[[mock expect] andForwardToRealObject] method1];
    [[[mock expect] andForwardToRealObject] method2];
    XCTAssertNoThrow([object method1], @"Calling an expected method that internally calls another expected method should not make expectations appear to be out of order.");
}


#pragma mark   Tests for method swizzling with partial mocks

- (NSString *)differentMethodInDifferentClass
{
	return @"swizzled!";
}

- (void)testImplementsMethodSwizzling
{
	// using partial mocks and the indirect return value provider
	TestClassThatCallsSelf *foo = [[TestClassThatCallsSelf alloc] init];
	id mock = [OCMockObject partialMockForObject:foo];
	[[[mock stub] andCall:@selector(differentMethodInDifferentClass) onObject:self] method1];
	XCTAssertEqualObjects(@"swizzled!", [foo method1], @"Should have returned value from different method");
}


- (void)aMethodWithVoidReturn
{
}

- (void)testMethodSwizzlingWorksForVoidReturns
{
	TestClassThatCallsSelf *foo = [[TestClassThatCallsSelf alloc] init];
	id mock = [OCMockObject partialMockForObject:foo];
	[[[mock stub] andCall:@selector(aMethodWithVoidReturn) onObject:self] methodVoid];
	XCTAssertNoThrow([foo method1], @"Should have worked.");
}


@end
