/*
 *  Copyright (c) 2004-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 "OCMBoxedReturnValueProvider.h"

// --------------------------------------------------------------------------------------
//	Helper classes and protocols for testing
// --------------------------------------------------------------------------------------

@interface OCMBoxedReturnValueProvider (Private)
- (BOOL)isMethodReturnType:(const char *)returnType compatibleWithValueType:(const char *)valueType;
@end

@interface TestClassWithSelectorMethod : NSObject

- (void)doWithSelector:(SEL)aSelector;

@end

@implementation TestClassWithSelectorMethod

- (void)doWithSelector:(__unused SEL)aSelector
{
}

@end


@interface TestClassWithIntPointerMethod : NSObject

- (void)returnValueInPointer:(int *)ptr;

@end

@implementation TestClassWithIntPointerMethod

- (void)returnValueInPointer:(int *)ptr
{
    *ptr = 555;
}

@end

@interface TestClassWithOpaquePointerMethod : NSObject
typedef struct TestOpaque *OpaquePtr;

- (OpaquePtr)opaquePtrValue;

@end

@implementation TestClassWithOpaquePointerMethod

typedef struct TestOpaque {
    int i;
    int j;
} TestOpaque;

TestOpaque myOpaque;

- (OpaquePtr)opaquePtrValue
{
    myOpaque.i = 3;
    myOpaque.i = 4;
    return &myOpaque;
}

@end

@interface TestClassWithProperty : NSObject

@property (nonatomic, retain) NSString *title;

@end

@implementation TestClassWithProperty

@synthesize title;

@end


@interface NotificationRecorderForTesting : NSObject
{
	@public
	NSNotification *notification;
}

@end

@implementation NotificationRecorderForTesting

- (void)dealloc
{
	[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)receiveNotification:(NSNotification *)aNotification
{
	notification = aNotification;
}

@end

static NSString *TestNotification = @"TestNotification";


@interface OCMockObjectTests : XCTestCase
{
	id mock;
}

@end


// --------------------------------------------------------------------------------------
//  setup
// --------------------------------------------------------------------------------------


@implementation OCMockObjectTests

- (void)setUp
{
	mock = [OCMockObject mockForClass:[NSString class]];
}


// --------------------------------------------------------------------------------------
//	accepting stubbed methods / rejecting methods not stubbed
// --------------------------------------------------------------------------------------

- (void)testAcceptsStubbedMethod
{
	[[mock stub] lowercaseString];
	[mock lowercaseString];
}

- (void)testRaisesExceptionWhenUnknownMethodIsCalled
{
	[[mock stub] lowercaseString];
	XCTAssertThrows([mock uppercaseString], @"Should have raised an exception.");
}


- (void)testAcceptsStubbedMethodWithSpecificArgument
{
	[[mock stub] hasSuffix:@"foo"];
	[mock hasSuffix:@"foo"];
}


- (void)testAcceptsStubbedMethodWithConstraint
{
	[[mock stub] hasSuffix:[OCMArg any]];
	[mock hasSuffix:@"foo"];
	[mock hasSuffix:@"bar"];
}

- (void)testAcceptsStubbedMethodWithBlockArgument
{
	mock = [OCMockObject mockForClass:[NSArray class]];
	[[mock stub] indexesOfObjectsPassingTest:[OCMArg any]];
	[mock indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) { return YES; }];
}


- (void)testAcceptsStubbedMethodWithBlockConstraint
{
	[[mock stub] hasSuffix:[OCMArg checkWithBlock:^(id value) { return [value isEqualToString:@"foo"]; }]];

	XCTAssertNoThrow([mock hasSuffix:@"foo"], @"Should not have thrown a exception");
	XCTAssertThrows([mock hasSuffix:@"bar"], @"Should have thrown a exception");
}


- (void)testAcceptsStubbedMethodWithNilArgument
{
	[[mock stub] hasSuffix:nil];
	[mock hasSuffix:nil];
}

- (void)testRaisesExceptionWhenMethodWithWrongArgumentIsCalled
{
	[[mock stub] hasSuffix:@"foo"];
	XCTAssertThrows([mock hasSuffix:@"xyz"], @"Should have raised an exception.");
}


- (void)testAcceptsStubbedMethodWithScalarArgument
{
	[[mock stub] stringByPaddingToLength:20 withString:@"foo" startingAtIndex:5];
	[mock stringByPaddingToLength:20 withString:@"foo" startingAtIndex:5];
}

- (void)testRaisesExceptionWhenMethodWithOneWrongScalarArgumentIsCalled
{
	[[mock stub] stringByPaddingToLength:20 withString:@"foo" startingAtIndex:5];
	XCTAssertThrows([mock stringByPaddingToLength:20 withString:@"foo" startingAtIndex:3], @"Should have raised an exception.");
}


- (void)testAcceptsStubbedMethodWithSelectorArgument
{
    mock = [OCMockObject mockForClass:[TestClassWithSelectorMethod class]];
    [[mock stub] doWithSelector:@selector(allKeys)];
    [mock doWithSelector:@selector(allKeys)];
}

- (void)testRaisesExceptionWhenMethodWithWrongSelectorArgumentIsCalled
{
    mock = [OCMockObject mockForClass:[TestClassWithSelectorMethod class]];
    [[mock stub] doWithSelector:@selector(allKeys)];
    XCTAssertThrows([mock doWithSelector:@selector(allValues)]);
}

- (void)testAcceptsStubbedMethodWithAnySelectorArgument
{
    mock = [OCMockObject mockForClass:[TestClassWithSelectorMethod class]];
    [[mock stub] doWithSelector:[OCMArg anySelector]];
    [mock doWithSelector:@selector(allKeys)];
}


- (void)testAcceptsStubbedMethodWithPointerArgument
{
    NSError __autoreleasing *error;
	[[[mock stub] andReturnValue:@YES] writeToFile:[OCMArg any] atomically:YES encoding:NSMacOSRomanStringEncoding error:&error];

	XCTAssertTrue([mock writeToFile:@"foo" atomically:YES encoding:NSMacOSRomanStringEncoding error:&error]);
}

- (void)testRaisesExceptionWhenMethodWithWrongPointerArgumentIsCalled
{
	NSString *string;
	NSString *anotherString;
	NSArray *array;

	[[mock stub] completePathIntoString:&string caseSensitive:YES matchesIntoArray:&array filterTypes:[OCMArg any]];

	XCTAssertThrows([mock completePathIntoString:&anotherString caseSensitive:YES matchesIntoArray:&array filterTypes:[OCMArg any]]);
}

- (void)testAcceptsStubbedMethodWithAnyPointerArgument
{
    [[mock stub] getCharacters:[OCMArg anyPointer]];
    
    unichar buffer[10];
    XCTAssertNoThrow([mock getCharacters:buffer], @"Should have stubbed method.");
}


- (void)testAcceptsStubbedMethodWithMatchingCharPointer
{
    char buffer[10] = "foo";
    [[[mock stub] andReturnValue:@YES] getCString:buffer maxLength:10 encoding:NSASCIIStringEncoding];

    BOOL result = [mock getCString:buffer maxLength:10 encoding:NSASCIIStringEncoding];

    XCTAssertEqual(YES, result, @"Should have stubbed method.");
}

- (void)testAcceptsStubbedMethodWithAnyPointerArgumentForCharPointer
{

    [[[mock stub] andReturnValue:@YES] getCString:[OCMArg anyPointer] maxLength:10 encoding:NSASCIIStringEncoding];

    char buffer[10] = "foo";
    BOOL result = [mock getCString:buffer maxLength:10 encoding:NSASCIIStringEncoding];

    XCTAssertEqual(YES, result, @"Should have stubbed method.");
}


- (void)testAcceptsStubbedMethodWithAnyObjectRefArgument
{
    NSError *error;
    [[[mock stub] andReturnValue:@YES] writeToFile:[OCMArg any] atomically:YES encoding:NSMacOSRomanStringEncoding error:[OCMArg anyObjectRef]];

    XCTAssertTrue([mock writeToFile:@"foo" atomically:YES encoding:NSMacOSRomanStringEncoding error:&error]);
}

- (void)testAcceptsStubbedMethodWithVoidPointerArgument
{
	mock = [OCMockObject mockForClass:[NSMutableData class]];
	[[mock stub] appendBytes:NULL length:0];
	[mock appendBytes:NULL length:0];
}


- (void)testRaisesExceptionWhenMethodWithWrongVoidPointerArgumentIsCalled
{
	mock = [OCMockObject mockForClass:[NSMutableData class]];
	[[mock stub] appendBytes:"foo" length:3];
	XCTAssertThrows([mock appendBytes:"bar" length:3], @"Should have raised an exception.");
}


- (void)testAcceptsStubbedMethodWithPointerPointerArgument
{
	NSError __autoreleasing *error = nil;
    [[mock stub] writeToFile:@"foo.txt" atomically:NO encoding:NSASCIIStringEncoding error:&error];
    [mock writeToFile:@"foo.txt" atomically:NO encoding:NSASCIIStringEncoding error:&error];
}


- (void)testRaisesExceptionWhenMethodWithWrongPointerPointerArgumentIsCalled
{
	NSError *error = nil, *error2;
    [[mock stub] writeToFile:@"foo.txt" atomically:NO encoding:NSASCIIStringEncoding error:&error];
	XCTAssertThrows([mock writeToFile:@"foo.txt" atomically:NO encoding:NSASCIIStringEncoding error:&error2], @"Should have raised.");
}


- (void)testAcceptsStubbedMethodWithStructArgument
{
    NSRange range = NSMakeRange(0,20);
	[[mock stub] substringWithRange:range];
	[mock substringWithRange:range];
}


- (void)testRaisesExceptionWhenMethodWithWrongStructArgumentIsCalled
{
    NSRange range = NSMakeRange(0,20);
    NSRange otherRange = NSMakeRange(0,10);
	[[mock stub] substringWithRange:range];
	XCTAssertThrows([mock substringWithRange:otherRange], @"Should have raised an exception.");
}


- (void)testCanPassMocksAsArguments
{
	id mockArg = [OCMockObject mockForClass:[NSString class]];
	[[mock stub] stringByAppendingString:[OCMArg any]];
	[mock stringByAppendingString:mockArg];
}

- (void)testCanStubWithMockArguments
{
	id mockArg = [OCMockObject mockForClass:[NSString class]];
	[[mock stub] stringByAppendingString:mockArg];
	[mock stringByAppendingString:mockArg];
}

- (void)testRaisesExceptionWhenStubbedMockArgIsNotUsed
{
	id mockArg = [OCMockObject mockForClass:[NSString class]];
	[[mock stub] stringByAppendingString:mockArg];
	XCTAssertThrows([mock stringByAppendingString:@"foo"], @"Should have raised an exception.");
}

- (void)testRaisesExceptionWhenDifferentMockArgumentIsPassed
{
	id expectedArg = [OCMockObject mockForClass:[NSString class]];
	id otherArg = [OCMockObject mockForClass:[NSString class]];
	[[mock stub] stringByAppendingString:otherArg];
	XCTAssertThrows([mock stringByAppendingString:expectedArg], @"Should have raised an exception.");
}


- (void)testAcceptsStubbedMethodWithAnyNonObjectArgument
{
    [[[mock stub] ignoringNonObjectArgs] rangeOfString:@"foo" options:0];
    [mock rangeOfString:@"foo" options:NSRegularExpressionSearch];
}

- (void)testRaisesExceptionWhenMethodWithMixedArgumentsIsCalledWithWrongObjectArgument
{
    [[[mock stub] ignoringNonObjectArgs] rangeOfString:@"foo" options:0];
    XCTAssertThrows([mock rangeOfString:@"bar" options:NSRegularExpressionSearch], @"Should have raised an exception.");
}


// --------------------------------------------------------------------------------------
//	returning values from stubbed methods
// --------------------------------------------------------------------------------------

- (void)testReturnsStubbedReturnValue
{
	[[[mock stub] andReturn:@"megamock"] lowercaseString];
	id returnValue = [mock lowercaseString];

	XCTAssertEqualObjects(@"megamock", returnValue, @"Should have returned stubbed value.");
}

- (void)testReturnsStubbedIntReturnValue
{
	[[[mock stub] andReturnValue:@42] intValue];
	int returnValue = [mock intValue];

	XCTAssertEqual(42, returnValue, @"Should have returned stubbed value.");
}

- (void)testReturnsStubbedUnsignedLongReturnValue
{
    mock = [OCMockObject mockForClass:[NSNumber class]];
    [[[mock expect] andReturnValue:@42LU] unsignedLongValue];
    unsigned long returnValue = [mock unsignedLongValue];
    XCTAssertEqual(returnValue, 42LU, @"Should have returned stubbed value.");

    [[[mock expect] andReturnValue:@42] unsignedLongValue];
    returnValue = [mock unsignedLongValue];
    XCTAssertEqual(returnValue, 42LU, @"Should have returned stubbed value.");

    [[[mock expect] andReturnValue:@42.0] unsignedLongValue];
    returnValue = [mock unsignedLongValue];
    XCTAssertEqual(returnValue, 42LU, @"Should have returned stubbed value.");

    [[[mock expect] andReturnValue:OCMOCK_VALUE((char)42)] unsignedLongValue];
    returnValue = [mock unsignedLongValue];
    XCTAssertEqual(returnValue, 42LU, @"Should have returned stubbed value.");

    [[[mock expect] andReturnValue:OCMOCK_VALUE((float)42)] unsignedLongValue];
    returnValue = [mock unsignedLongValue];
    XCTAssertEqual(returnValue, 42LU, @"Should have returned stubbed value.");

    [[[mock expect] andReturnValue:OCMOCK_VALUE((float)42.5)] unsignedLongValue];
    XCTAssertThrows([mock unsignedLongValue], @"Should not be able to convert non-integer float to long");

#if !__LP64__
    [[[mock expect] andReturnValue:OCMOCK_VALUE((long long)LLONG_MAX)] unsignedLongValue];
    XCTAssertThrows([mock unsignedLongValue], @"Should not be able to convert large long long to long");
#endif
}

- (void)testReturnsStubbedBoolReturnValue
{
    [[[mock expect] andReturnValue:@YES] boolValue];
    BOOL returnValue = [mock boolValue];
    XCTAssertEqual(returnValue, YES, @"Should have returned stubbed value.");

    [[[mock expect] andReturnValue:OCMOCK_VALUE(YES)] boolValue];
    returnValue = [mock boolValue];
    XCTAssertEqual(returnValue, YES, @"Should have returned stubbed value.");

    [[[mock expect] andReturnValue:OCMOCK_VALUE(1)] boolValue];
    returnValue = [mock boolValue];
    XCTAssertEqual(returnValue, YES, @"Should have returned stubbed value.");

    [[[mock expect] andReturnValue:OCMOCK_VALUE(300)] boolValue];
    XCTAssertThrows([mock boolValue], @"Should not be able to convert large integer into BOOL");
}

- (void)testRaisesWhenBoxedValueTypesDoNotMatch
{
	[[[mock stub] andReturnValue:[NSValue valueWithRange:NSMakeRange(0, 0)]] intValue];

	XCTAssertThrows([mock intValue], @"Should have raised an exception.");
}

- (void)testOpaqueStructComparison
{
    TestClassWithOpaquePointerMethod *obj = [TestClassWithOpaquePointerMethod new];
    OpaquePtr val = [obj opaquePtrValue];
    id mockVal = [OCMockObject partialMockForObject:obj];
    [[[mockVal stub] andReturnValue:OCMOCK_VALUE(val)] opaquePtrValue];
    OpaquePtr val2 = [obj opaquePtrValue];
    XCTAssertEqual(val, val2);

    // from https://github.com/erikdoe/ocmock/pull/97
    const char *type1 =
    "r^{GURL={basic_string<char, std::__1::char_traits<char>, std::__1::alloca"
    "tor<char> >={__compressed_pair<std::__1::basic_string<char, std::__1::cha"
    "r_traits<char>, std::__1::allocator<char> >::__rep, std::__1::allocator<c"
    "har> >={__rep}}}B{Parsed={Component=ii}{Component=ii}{Component=ii}{Compo"
    "nent=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}^{Parsed}"
    "}{scoped_ptr<GURL, base::DefaultDeleter<GURL> >={scoped_ptr_impl<GURL, ba"
    "se::DefaultDeleter<GURL> >={Data=^{GURL}}}}}";

    const char *type2 =
    "r^{GURL={basic_string<char, std::__1::char_traits<char>, std::__1::alloca"
    "tor<char> >={__compressed_pair<std::__1::basic_string<char, std::__1::cha"
    "r_traits<char>, std::__1::allocator<char> >::__rep, std::__1::allocator<c"
    "har> >={__rep=(?={__long=II*}{__short=(?=Cc)[11c]}{__raw=[3L]})}}}B{Parse"
    "d={Component=ii}{Component=ii}{Component=ii}{Component=ii}{Component=ii}{"
    "Component=ii}{Component=ii}{Component=ii}^{Parsed}}{scoped_ptr<GURL, base"
    "::DefaultDeleter<GURL> >={scoped_ptr_impl<GURL, base::DefaultDeleter<GURL"
    "> >={Data=^{GURL}}}}}";

    const char *type3 =
    "r^{GURL}";

    OCMBoxedReturnValueProvider *boxed = [OCMBoxedReturnValueProvider new];
    XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type2]);
    XCTAssertTrue([boxed isMethodReturnType:type1 compatibleWithValueType:type3]);
    XCTAssertTrue([boxed isMethodReturnType:type2 compatibleWithValueType:type1]);
    XCTAssertTrue([boxed isMethodReturnType:type2 compatibleWithValueType:type3]);
    XCTAssertTrue([boxed isMethodReturnType:type3 compatibleWithValueType:type1]);
    XCTAssertTrue([boxed isMethodReturnType:type3 compatibleWithValueType:type2]);
}

- (void)testReturnsStubbedNilReturnValue
{
	[[[mock stub] andReturn:nil] uppercaseString];

	id returnValue = [mock uppercaseString];

	XCTAssertNil(returnValue, @"Should have returned stubbed value, which is nil.");
}

- (void)testReturnsStubbedValueForProperty
{
    TestClassWithProperty *myMock = [OCMockObject mockForClass:[TestClassWithProperty class]];

    [[[(id)myMock stub] andReturn:@"stubbed title"] title];

    XCTAssertEqualObjects(@"stubbed title", myMock.title);
}


// --------------------------------------------------------------------------------------
//	beyond stubbing: raising exceptions, posting notifications, etc.
// --------------------------------------------------------------------------------------

- (void)testRaisesExceptionWhenAskedTo
{
	NSException *exception = [NSException exceptionWithName:@"TestException" reason:@"test" userInfo:nil];
	[[[mock expect] andThrow:exception] lowercaseString];

	XCTAssertThrows([mock lowercaseString], @"Should have raised an exception.");
}

- (void)testPostsNotificationWhenAskedTo
{
	NotificationRecorderForTesting *observer = [[NotificationRecorderForTesting alloc] init];
	[[NSNotificationCenter defaultCenter] addObserver:observer selector:@selector(receiveNotification:) name:TestNotification object:nil];

	NSNotification *notification = [NSNotification notificationWithName:TestNotification object:self];
	[[[mock stub] andPost:notification] lowercaseString];

	[mock lowercaseString];

	XCTAssertNotNil(observer->notification, @"Should have sent a notification.");
	XCTAssertEqualObjects(TestNotification, [observer->notification name], @"Name should match posted one.");
	XCTAssertEqualObjects(self, [observer->notification object], @"Object should match posted one.");
}

- (void)testPostsNotificationInAdditionToReturningValue
{
	NotificationRecorderForTesting *observer = [[NotificationRecorderForTesting alloc] init];
	[[NSNotificationCenter defaultCenter] addObserver:observer selector:@selector(receiveNotification:) name:TestNotification object:nil];

	NSNotification *notification = [NSNotification notificationWithName:TestNotification object:self];
	[[[[mock stub] andReturn:@"foo"] andPost:notification] lowercaseString];

	XCTAssertEqualObjects(@"foo", [mock lowercaseString], @"Should have returned stubbed value.");
	XCTAssertNotNil(observer->notification, @"Should have sent a notification.");
}


- (NSString *)valueForString:(NSString *)aString andMask:(NSStringCompareOptions)mask
{
	return [NSString stringWithFormat:@"[%@, %ld]", aString, (long)mask];
}

- (void)testCallsAlternativeMethodAndPassesOriginalArgumentsAndReturnsValue
{
	[[[mock stub] andCall:@selector(valueForString:andMask:) onObject:self] commonPrefixWithString:@"FOO" options:NSCaseInsensitiveSearch];

	NSString *returnValue = [mock commonPrefixWithString:@"FOO" options:NSCaseInsensitiveSearch];

	XCTAssertEqualObjects(@"[FOO, 1]", returnValue, @"Should have passed and returned invocation.");
}


- (void)testCallsBlockWhichCanSetUpReturnValue
{
	void (^theBlock)(NSInvocation *) = ^(NSInvocation *invocation)
		{
			NSString *value;
			[invocation getArgument:&value atIndex:2];
			value = [NSString stringWithFormat:@"MOCK %@", value];
			[invocation setReturnValue:&value];
		};

	[[[mock stub] andDo:theBlock] stringByAppendingString:[OCMArg any]];

	XCTAssertEqualObjects(@"MOCK foo", [mock stringByAppendingString:@"foo"], @"Should have called block.");
	XCTAssertEqualObjects(@"MOCK bar", [mock stringByAppendingString:@"bar"], @"Should have called block.");
}

- (void)testHandlesNilPassedAsBlock
{
    [[[mock stub] andDo:nil] stringByAppendingString:[OCMArg any]];

    XCTAssertNoThrow([mock stringByAppendingString:@"foo"], @"Should have done nothing.");
    XCTAssertNil([mock stringByAppendingString:@"foo"], @"Should have returned default value.");
}


- (void)testThrowsWhenTryingToUseForwardToRealObjectOnNonPartialMock
{
	XCTAssertThrows([[[mock expect] andForwardToRealObject] name], @"Should have raised and exception.");
}


// --------------------------------------------------------------------------------------
//	returning values in pass-by-reference arguments
// --------------------------------------------------------------------------------------

- (void)testReturnsValuesInPassByReferenceArguments
{
	NSString *expectedName = @"Test";
	NSArray *expectedArray = [NSArray array];

	[[mock expect] completePathIntoString:[OCMArg setTo:expectedName] caseSensitive:YES
						 matchesIntoArray:[OCMArg setTo:expectedArray] filterTypes:[OCMArg any]];

	NSString *actualName = nil;
	NSArray *actualArray = nil;
	[mock completePathIntoString:&actualName caseSensitive:YES matchesIntoArray:&actualArray filterTypes:nil];

	XCTAssertNoThrow([mock verify], @"An unexpected exception was thrown");
	XCTAssertEqualObjects(expectedName, actualName, @"The two string objects should be equal");
	XCTAssertEqualObjects(expectedArray, actualArray, @"The two array objects should be equal");
}


- (void)testReturnsValuesInNonObjectPassByReferenceArguments
{
    mock = [OCMockObject mockForClass:[TestClassWithIntPointerMethod class]];
    [[mock stub] returnValueInPointer:[OCMArg setToValue:@1234]];

    int actualValue = 0;
    [mock returnValueInPointer:&actualValue];

    XCTAssertEqual(1234, actualValue, @"Should have returned value via pass by ref argument.");

}


// --------------------------------------------------------------------------------------
//	accepting expected methods
// --------------------------------------------------------------------------------------

- (void)testAcceptsExpectedMethod
{
	[[mock expect] lowercaseString];
	[mock lowercaseString];
}


- (void)testAcceptsExpectedMethodAndReturnsValue
{
	[[[mock expect] andReturn:@"Objective-C"] lowercaseString];
	id returnValue = [mock lowercaseString];

	XCTAssertEqualObjects(@"Objective-C", returnValue, @"Should have returned stubbed value.");
}


- (void)testAcceptsExpectedMethodsInRecordedSequence
{
	[[mock expect] lowercaseString];
	[[mock expect] uppercaseString];

	[mock lowercaseString];
	[mock uppercaseString];
}


- (void)testAcceptsExpectedMethodsInDifferentSequence
{
	[[mock expect] lowercaseString];
	[[mock expect] uppercaseString];

	[mock uppercaseString];
	[mock lowercaseString];
}


// --------------------------------------------------------------------------------------
//	verifying expected methods
// --------------------------------------------------------------------------------------

- (void)testAcceptsAndVerifiesExpectedMethods
{
	[[mock expect] lowercaseString];
	[[mock expect] uppercaseString];

	[mock lowercaseString];
	[mock uppercaseString];

	[mock verify];
}


- (void)testRaisesExceptionOnVerifyWhenNotAllExpectedMethodsWereCalled
{
	[[mock expect] lowercaseString];
	[[mock expect] uppercaseString];

	[mock lowercaseString];

	XCTAssertThrows([mock verify], @"Should have raised an exception.");
}

- (void)testAcceptsAndVerifiesTwoExpectedInvocationsOfSameMethod
{
	[[mock expect] lowercaseString];
	[[mock expect] lowercaseString];

	[mock lowercaseString];
	[mock lowercaseString];

	[mock verify];
}


- (void)testAcceptsAndVerifiesTwoExpectedInvocationsOfSameMethodAndReturnsCorrespondingValues
{
	[[[mock expect] andReturn:@"foo"] lowercaseString];
	[[[mock expect] andReturn:@"bar"] lowercaseString];

	XCTAssertEqualObjects(@"foo", [mock lowercaseString], @"Should have returned first stubbed value");
	XCTAssertEqualObjects(@"bar", [mock lowercaseString], @"Should have returned seconds stubbed value");

	[mock verify];
}

- (void)testReturnsStubbedValuesIndependentOfExpectations
{
	[[mock stub] hasSuffix:@"foo"];
	[[mock expect] hasSuffix:@"bar"];

	[mock hasSuffix:@"foo"];
	[mock hasSuffix:@"bar"];
	[mock hasSuffix:@"foo"]; // Since it's a stub, shouldn't matter how many times we call this

	[mock verify];
}

-(void)testAcceptsAndVerifiesMethodsWithSelectorArgument
{
	[[mock expect] performSelector:@selector(lowercaseString)];
	[mock performSelector:@selector(lowercaseString)];
	[mock verify];
}


// --------------------------------------------------------------------------------------
//	verify with delay
// --------------------------------------------------------------------------------------

- (void)testAcceptsAndVerifiesExpectedMethodsWithDelay
{
	[[mock expect] lowercaseString];
	[[mock expect] uppercaseString];
    
	[mock lowercaseString];
	[mock uppercaseString];
    
	[mock verifyWithDelay:1];
}

- (void)testAcceptsAndVerifiesExpectedMethodsWithDelayBlock
{
    dispatch_async(dispatch_queue_create("mockqueue", nil), ^{
        [NSThread sleepForTimeInterval:0.1];
        [mock lowercaseString];
    });
    
	[[mock expect] lowercaseString];
	[mock verifyWithDelay:1];
}

- (void)testFailsVerifyExpectedMethodsWithoutDelay
{
    dispatch_async(dispatch_queue_create("mockqueue", nil), ^{
        [NSThread sleepForTimeInterval:0.1];
        [mock lowercaseString];
    });
    
	[[mock expect] lowercaseString];
	XCTAssertThrows([mock verify], @"Should have raised an exception because method was not called in time.");
}

- (void)testFailsVerifyExpectedMethodsWithDelay
{
	[[mock expect] lowercaseString];
	XCTAssertThrows([mock verifyWithDelay:0.1], @"Should have raised an exception because method was not called.");
}

- (void)testAcceptsAndVerifiesExpectedMethodsWithDelayBlockTimeout
{
    dispatch_async(dispatch_queue_create("mockqueue", nil), ^{
        [NSThread sleepForTimeInterval:1];
        [mock lowercaseString];
    });
    
	[[mock expect] lowercaseString];
	XCTAssertThrows([mock verifyWithDelay:0.1], @"Should have raised an exception because method was not called.");
}

// --------------------------------------------------------------------------------------
//	ordered expectations
// --------------------------------------------------------------------------------------

- (void)testAcceptsExpectedMethodsInRecordedSequenceWhenOrderMatters
{
	[mock setExpectationOrderMatters:YES];

	[[mock expect] lowercaseString];
	[[mock expect] uppercaseString];

	XCTAssertNoThrow([mock lowercaseString], @"Should have accepted expected method in sequence.");
	XCTAssertNoThrow([mock uppercaseString], @"Should have accepted expected method in sequence.");
}

- (void)testRaisesExceptionWhenSequenceIsWrongAndOrderMatters
{
	[mock setExpectationOrderMatters:YES];

	[[mock expect] lowercaseString];
	[[mock expect] uppercaseString];

	XCTAssertThrows([mock uppercaseString], @"Should have complained about wrong sequence.");
}

- (void)testRejectThenExpectWithExpectationOrdering
{
    [mock setExpectationOrderMatters:YES];
    [[mock reject] lowercaseString];
    [[mock expect] uppercaseString];
    XCTAssertNoThrow([mock uppercaseString], @"Since lowercaseString should be rejected, we shouldn't expect it to be called before uppercaseString.");
}



// --------------------------------------------------------------------------------------
//	nice mocks don't complain about unknown methods, unless told to
// --------------------------------------------------------------------------------------

- (void)testReturnsDefaultValueWhenUnknownMethodIsCalledOnNiceClassMock
{
	mock = [OCMockObject niceMockForClass:[NSString class]];
	XCTAssertNil([mock lowercaseString], @"Should return nil on unexpected method call (for nice mock).");
	[mock verify];
}

- (void)testRaisesAnExceptionWhenAnExpectedMethodIsNotCalledOnNiceClassMock
{
	mock = [OCMockObject niceMockForClass:[NSString class]];
	[[[mock expect] andReturn:@"HELLO!"] uppercaseString];
	XCTAssertThrows([mock verify], @"Should have raised an exception because method was not called.");
}

- (void)testThrowsWhenRejectedMethodIsCalledOnNiceMock
{
    mock = [OCMockObject niceMockForClass:[NSString class]];

    [[mock reject] uppercaseString];
    XCTAssertThrows([mock uppercaseString], @"Should have complained about rejected method being called.");
}

- (void)testUncalledRejectStubDoesNotCountAsExpectation
{
    mock = [OCMockObject niceMockForClass:[NSString class]];

    [[mock expect] lowercaseString];
    [[mock reject] uppercaseString];
    [mock lowercaseString];

    XCTAssertNoThrow([mock verify], @"Should not have any unmet expectations.");

}


// --------------------------------------------------------------------------------------
//  some internal tests
// --------------------------------------------------------------------------------------

- (void)testReRaisesFailFastExceptionsOnVerify
{
	@try
	{
		[mock lowercaseString];
	}
	@catch(NSException *exception)
	{
		// expected
	}
	XCTAssertThrows([mock verify], @"Should have reraised the exception.");
}

- (void)testReRaisesRejectExceptionsOnVerify
{
	mock = [OCMockObject niceMockForClass:[NSString class]];
	[[mock reject] uppercaseString];
	@try
	{
		[mock uppercaseString];
	}
	@catch(NSException *exception)
	{
		// expected
	}
	XCTAssertThrows([mock verify], @"Should have reraised the exception.");
}


- (void)testCanCreateExpectationsAfterInvocations
{
	[[mock expect] lowercaseString];
	[mock lowercaseString];
	[mock expect];
}


- (void)testArgumentConstraintsAreOnlyCalledAsOftenAsTheMethodIsCalled
{
    __block int count = 0;

    [[mock stub] hasSuffix:[OCMArg checkWithBlock:^(id value) { count++; return YES; }]];

    [mock hasSuffix:@"foo"];
    [mock hasSuffix:@"bar"];

    XCTAssertEqual(2, count, @"Should have evaluated constraint only twice");
}


@end


