/*
 *  Copyright (c) 2014-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>


@protocol TestProtocolForMacroTesting
- (NSString *)stringValue;
@end

@interface TestClassForMacroTesting : NSObject <TestProtocolForMacroTesting>

@end

@implementation TestClassForMacroTesting

- (NSString *)stringValue
{
    return @"FOO";
}

@end


@interface TestClassWithDecimalReturnMethod : NSObject

- (NSDecimalNumber*)method;

@end

@implementation TestClassWithDecimalReturnMethod

- (NSDecimalNumber*)method {
    return nil;
}

@end


// implemented in OCMockObjectClassMethodMockingTests

@interface TestClassWithClassMethods : NSObject
+ (NSString *)foo;
+ (NSString *)bar;
- (NSString *)bar;
@end



@interface OCMockObjectMacroTests : XCTestCase
{
    BOOL        shouldCaptureFailure;
    NSString    *reportedDescription;
    NSString    *reportedFile;
    NSUInteger  reportedLine;
}

@end


@implementation OCMockObjectMacroTests

- (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)file atLine:(NSUInteger)line expected:(BOOL)expected
{
    if(shouldCaptureFailure)
    {
        reportedDescription = description;
        reportedFile = file;
        reportedLine = line;
    }
    else
    {
        [super recordFailureWithDescription:description inFile:file atLine:line expected:expected];
    }
}


- (void)testReportsVerifyFailureWithCorrectLocation
{
    id mock = OCMClassMock([NSString class]);
    
    [[mock expect] lowercaseString];
    
    shouldCaptureFailure = YES;
    OCMVerifyAll(mock); const char *expectedFile = __FILE__; int expectedLine = __LINE__;
    shouldCaptureFailure = NO;
    
    XCTAssertNotNil(reportedDescription, @"Should have recorded a failure with description.");
    XCTAssertEqualObjects([NSString stringWithUTF8String:expectedFile], reportedFile, @"Should have reported correct file.");
    XCTAssertEqual(expectedLine, (int)reportedLine, @"Should have reported correct line");
}

- (void)testReportsIgnoredExceptionsAtVerifyLocation
{
    id mock = OCMClassMock([NSString class]);
    
    [[mock reject] lowercaseString];

    @try
    {
        [mock lowercaseString];
    }
    @catch (NSException *exception)
    {
        // ignore; the mock will rethrow this in verify
    }

    shouldCaptureFailure = YES;
    OCMVerifyAll(mock); const char *expectedFile = __FILE__; int expectedLine = __LINE__;
    shouldCaptureFailure = NO;
    
    XCTAssertTrue([reportedDescription rangeOfString:@"ignored"].location != NSNotFound, @"Should have reported ignored exceptions.");
    XCTAssertEqualObjects([NSString stringWithUTF8String:expectedFile], reportedFile, @"Should have reported correct file.");
    XCTAssertEqual(expectedLine, (int)reportedLine, @"Should have reported correct line");
}

- (void)testReportsVerifyWithDelayFailureWithCorrectLocation
{
    id mock = OCMClassMock([NSString class]);

    [[mock expect] lowercaseString];

    shouldCaptureFailure = YES;
    OCMVerifyAllWithDelay(mock, 0.05); const char *expectedFile = __FILE__; int expectedLine = __LINE__;
    shouldCaptureFailure = NO;

    XCTAssertNotNil(reportedDescription, @"Should have recorded a failure with description.");
    XCTAssertEqualObjects([NSString stringWithUTF8String:expectedFile], reportedFile, @"Should have reported correct file.");
    XCTAssertEqual(expectedLine, (int)reportedLine, @"Should have reported correct line");
}


- (void)testSetsUpStubsForCorrectMethods
{
    id mock = OCMStrictClassMock([NSString class]);

    OCMStub([mock uppercaseString]).andReturn(@"TEST_STRING");

    XCTAssertEqualObjects(@"TEST_STRING", [mock uppercaseString], @"Should have returned stubbed value");
    XCTAssertThrows([mock lowercaseString]);
}

- (void)testSetsUpStubsWithNonObjectReturnValues
{
    id mock = OCMStrictClassMock([NSString class]);

    OCMStub([mock boolValue]).andReturn(YES);

    XCTAssertEqual(YES, [mock boolValue], @"Should have returned stubbed value");
}

- (void)testSetsUpStubsWithStructureReturnValues
{
    id mock = OCMStrictClassMock([NSString class]);

    NSRange expected = NSMakeRange(123, 456);
    OCMStub([mock rangeOfString:[OCMArg any]]).andReturn(expected);

    NSRange actual = [mock rangeOfString:@"substring"];
    XCTAssertEqual((NSUInteger)123, actual.location, @"Should have returned stubbed value");
    XCTAssertEqual((NSUInteger)456, actual.length, @"Should have returned stubbed value");
}

- (void)testSetsUpStubReturningNilForIdReturnType
{
    id mock = OCMClassMock([NSString class]);

    OCMStub([mock lowercaseString]).andReturn(nil);

    XCTAssertNil([mock lowercaseString], @"Should have returned stubbed value");
}

- (void)testSetsUpExceptionThrowing
{
    id mock = OCMClassMock([NSString class]);

    OCMStub([mock uppercaseString]).andThrow([NSException exceptionWithName:@"TestException" reason:@"Testing" userInfo:nil]);

    XCTAssertThrowsSpecificNamed([mock uppercaseString], NSException, @"TestException", @"Should have thrown correct exception");
}

- (void)testSetsUpNotificationPostingAndNotificationObserving
{
    id mock = OCMProtocolMock(@protocol(TestProtocolForMacroTesting));

    NSNotification *n = [NSNotification notificationWithName:@"TestNotification" object:nil];

    id observer = OCMObserverMock();
    [[NSNotificationCenter defaultCenter] addMockObserver:observer name:[n name] object:nil];
    OCMExpect([observer notificationWithName:[n name] object:[OCMArg any]]);

    OCMStub([mock stringValue]).andPost(n);

    [mock stringValue];

    OCMVerifyAll(observer);
}

- (void)testSetsUpSubstituteCall
{
    id mock = OCMStrictProtocolMock(@protocol(TestProtocolForMacroTesting));

    OCMStub([mock stringValue]).andCall(self, @selector(stringValueForTesting));

    XCTAssertEqualObjects([mock stringValue], @"TEST_STRING_FROM_TESTCASE", @"Should have called method from test case");
}

- (NSString *)stringValueForTesting
{
    return @"TEST_STRING_FROM_TESTCASE";
}


- (void)testCanChainPropertyBasedActions
{
    id mock = OCMPartialMock([[TestClassForMacroTesting alloc] init]);

    __block BOOL didCallBlock = NO;
    void (^theBlock)(NSInvocation *) = ^(NSInvocation *invocation)
    {
        didCallBlock = YES;
    };

    OCMStub([mock stringValue]).andDo(theBlock).andForwardToRealObject();

    NSString *actual = [mock stringValue];

    XCTAssertTrue(didCallBlock, @"Should have called block");
    XCTAssertEqualObjects(@"FOO", actual, @"Should have forwarded invocation");
}


- (void)testCanUseVariablesInInvocationSpec
{
    id mock = OCMStrictClassMock([NSString class]);

    NSString *expected = @"foo";
    OCMStub([mock rangeOfString:expected]).andReturn(NSMakeRange(0, 3));

    XCTAssertThrows([mock rangeOfString:@"bar"], @"Should not have accepted invocation with non-matching arg.");
}


- (void)testSetsUpExpectations
{
    id mock = OCMClassMock([TestClassForMacroTesting class]);

    OCMExpect([mock stringValue]).andReturn(@"TEST_STRING");

    XCTAssertThrows([mock verify], @"Should have complained about expected method not being invoked");

    XCTAssertEqual([mock stringValue], @"TEST_STRING", @"Should have stubbed method, too");
    XCTAssertNoThrow([mock verify], @"Should have accepted invocation as matching expectation");
}


- (void)testShouldNotReportErrorWhenMethodWasInvoked
{
    id mock = OCMClassMock([NSString class]);

    [mock lowercaseString];

    shouldCaptureFailure = YES;
    OCMVerify([mock lowercaseString]);
    shouldCaptureFailure = NO;

    XCTAssertNil(reportedDescription, @"Should not have recorded a failure.");
}

- (void)testShouldReportErrorWhenMethodWasNotInvoked
{
    id mock = OCMClassMock([NSString class]);

    [mock lowercaseString];

    shouldCaptureFailure = YES;
    OCMVerify([mock uppercaseString]); const char *expectedFile = __FILE__; int expectedLine = __LINE__;
    shouldCaptureFailure = NO;

    XCTAssertNotNil(reportedDescription, @"Should have recorded a failure with description.");
    XCTAssertEqualObjects([NSString stringWithUTF8String:expectedFile], reportedFile, @"Should have reported correct file.");
    XCTAssertEqual(expectedLine, (int)reportedLine, @"Should have reported correct line");
}

- (void)testShouldThrowDescriptiveExceptionWhenTryingToVerifyUnimplementedMethod
{
    id mock = OCMClassMock([NSString class]);

    // have not found a way to report the error; it seems we must throw an
    // exception to get out of the forwarding machinery
    XCTAssertThrowsSpecificNamed(OCMVerify([mock arrayByAddingObject:nil]),
                    NSException,
                    NSInvalidArgumentException,
                    @"should throw NSInvalidArgumentException exception");
}


- (void)testCanExplicitlySelectClassMethodForStubs
{
    id mock = OCMClassMock([TestClassWithClassMethods class]);

    OCMStub(ClassMethod([mock bar])).andReturn(@"mocked-class");
    OCMStub([mock bar]).andReturn(@"mocked-instance");

    XCTAssertEqualObjects(@"mocked-class", [TestClassWithClassMethods bar], @"Should have stubbed class method.");
    XCTAssertEqualObjects(@"mocked-instance", [mock bar], @"Should have stubbed instance method.");
}

- (void)testSelectsInstanceMethodForStubsWhenAmbiguous
{
    id mock = OCMClassMock([TestClassWithClassMethods class]);

    OCMStub([mock bar]).andReturn(@"mocked-instance");

    XCTAssertEqualObjects(@"mocked-instance", [mock bar], @"Should have stubbed instance method.");
}

- (void)testSelectsClassMethodForStubsWhenUnambiguous
{
    id mock = OCMClassMock([TestClassWithClassMethods class]);

    OCMStub([mock foo]).andReturn(@"mocked-class");

    XCTAssertEqualObjects(@"mocked-class", [TestClassWithClassMethods foo], @"Should have stubbed class method.");
}


- (void)testCanExplicitlySelectClassMethodForVerify
{
    id mock = OCMClassMock([TestClassWithClassMethods class]);

    [TestClassWithClassMethods bar];

    OCMVerify(ClassMethod([mock bar]));
}

- (void)testSelectsInstanceMethodForVerifyWhenAmbiguous
{
    id mock = OCMClassMock([TestClassWithClassMethods class]);

    [mock bar];

    OCMVerify([mock bar]);
}

- (void)testSelectsClassMethodForVerifyWhenUnambiguous
{
    id mock = OCMClassMock([TestClassWithClassMethods class]);

    [TestClassWithClassMethods foo];

    OCMVerify([mock foo]);
}


- (void)testCanUseMacroToStubMethodWithDecimalReturnValue
{
    id mock = OCMClassMock([TestClassWithDecimalReturnMethod class]);
    OCMStub([mock method]).andReturn([NSDecimalNumber decimalNumberWithDecimal:[@0 decimalValue]]);
    XCTAssertEqualObjects([mock method], [NSDecimalNumber decimalNumberWithDecimal:[@0 decimalValue]]);
}

@end
