<commit_before>//
//  ClientTests.swift
//  Tentacle
//
//  Created by <NAME> on 3/5/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Argo
import OHHTTPStubs
import ReactiveCocoa
import Result
import Tentacle
import XCTest

public func == <T: Equatable, Error: Equatable> (left: Result<[T], Error>, right: Result<[T], Error>) -> Bool {
    if let left = left.value, right = right.value {
        return left == right
    } else if let left = left.error, right = right.error {
        return left == right
    }
    return false
}

public func == <T: Equatable, Error: Equatable> (left: Result<[[T]], Error>, right: Result<[[T]], Error>) -> Bool {
    if let left = left.value, right = right.value {
        guard left.count == right.count else { return false }
        for idx in left.indices {
            if left[idx] != right[idx] {
                return false
            }
        }
        return true
    } else if let left = left.error, right = right.error {
        return left == right
    }
    return false
}

func ExpectResult
    <O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, O), Client.Error>, _ result: Result<[O], Client.Error>, file: String = __FILE__, line: UInt = __LINE__)
{
    let actual = producer.map { $1 }.collect().single()!
    let message: String
    switch result {
    case let .Success(value):
        message = "\(actual) is not equal to \(value)"
    case let .Failure(error):
        message = "\(actual) is not equal to \(error)"
    }
    XCTAssertTrue(actual == result, message, file: file, line: line)
}

func ExpectResult
    <F: FixtureType, O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, O), Client.Error>, _ result: Result<[F], Client.Error>, file: String = __FILE__, line: UInt = __LINE__)
{
    let expected = result.map { fixtures -> [O] in fixtures.map { $0.decode()! } }
    ExpectResult(producer, expected, file: file, line: line)
}

func ExpectResult
    <O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, [O]), Client.Error>, _ result: Result<[[O]], Client.Error>, file: String = __FILE__, line: UInt = __LINE__)
{
    let actual = producer.map { $1 }.collect().single()!
    let message: String
    switch result {
    case let .Success(value):
        message = "\(actual) is not equal to \(value)"
    case let .Failure(error):
        message = "\(actual) is not equal to \(error)"
    }
    XCTAssertTrue(actual == result, message, file: file, line: line)
}

func ExpectResult
    <F: FixtureType, O: ResourceType, C: CollectionType where O.DecodedType == O, C.Generator.Element == F>
    (producer: SignalProducer<(Response, [O]), Client.Error>, _ result: Result<C, Client.Error>, file: String = __FILE__, line: UInt = __LINE__)
{
    let expected = result.map { fixtures -> [[O]] in fixtures.map { $0.decode()! } }
    ExpectResult(producer, expected, file: file, line: line)
}

func ExpectError
    <O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, O), Client.Error>, _ error: Client.Error, file: String = __FILE__, line: UInt = __LINE__)
{
    ExpectResult(producer, Result<[O], Client.Error>.Failure(error), file: file, line: line)
}

func ExpectFixtures
    <F: FixtureType, O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, O), Client.Error>, _ fixtures: F..., file: String = __FILE__, line: UInt = __LINE__)
{
    ExpectResult(producer, Result<[F], Client.Error>.Success(fixtures), file: file, line: line)
}

func ExpectFixtures
    <F: FixtureType, O: ResourceType, C: CollectionType where O.DecodedType == O, C.Generator.Element == F>
    (producer: SignalProducer<(Response, [O]), Client.Error>, _ fixtures: C, file: String = __FILE__, line: UInt = __LINE__)
{
    ExpectResult(producer, .Success(fixtures), file: file, line: line)
}


class ClientTests: XCTestCase {
    private let client = Client(.DotCom)
    
    override func setUp() {
        OHHTTPStubs
            .stubRequestsPassingTest({ request in
                return Fixture.fixtureForURL(request.URL!) != nil
            }, withStubResponse: { request -> OHHTTPStubsResponse in
                let fixture = Fixture.fixtureForURL(request.URL!)!
                let response = fixture.response
                return OHHTTPStubsResponse(fileURL: fixture.dataFileURL, statusCode: Int32(response.statusCode), headers: response.allHeaderFields)
            })
    }
    
    func testReleasesInRepository() {
        let fixtures = Fixture.Releases.Carthage
        ExpectFixtures(
            client.releasesInRepository(fixtures[0].repository),
            [ fixtures[0] ]
        )
    }
    
    func testReleaseForTagInRepository() {
        let fixture = Fixture.Release.Carthage0_15
        ExpectFixtures(
            client.releaseForTag(fixture.tag, inRepository: fixture.repository),
            fixture<commit_msg>Add a test for page 2 of releasesInRepository<commit_after>//
//  ClientTests.swift
//  Tentacle
//
//  Created by <NAME> on 3/5/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Argo
import OHHTTPStubs
import ReactiveCocoa
import Result
import Tentacle
import XCTest

public func == <T: Equatable, Error: Equatable> (left: Result<[T], Error>, right: Result<[T], Error>) -> Bool {
    if let left = left.value, right = right.value {
        return left == right
    } else if let left = left.error, right = right.error {
        return left == right
    }
    return false
}

public func == <T: Equatable, Error: Equatable> (left: Result<[[T]], Error>, right: Result<[[T]], Error>) -> Bool {
    if let left = left.value, right = right.value {
        guard left.count == right.count else { return false }
        for idx in left.indices {
            if left[idx] != right[idx] {
                return false
            }
        }
        return true
    } else if let left = left.error, right = right.error {
        return left == right
    }
    return false
}

func ExpectResult
    <O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, O), Client.Error>, _ result: Result<[O], Client.Error>, file: String = __FILE__, line: UInt = __LINE__)
{
    let actual = producer.map { $1 }.collect().single()!
    let message: String
    switch result {
    case let .Success(value):
        message = "\(actual) is not equal to \(value)"
    case let .Failure(error):
        message = "\(actual) is not equal to \(error)"
    }
    XCTAssertTrue(actual == result, message, file: file, line: line)
}

func ExpectResult
    <F: FixtureType, O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, O), Client.Error>, _ result: Result<[F], Client.Error>, file: String = __FILE__, line: UInt = __LINE__)
{
    let expected = result.map { fixtures -> [O] in fixtures.map { $0.decode()! } }
    ExpectResult(producer, expected, file: file, line: line)
}

func ExpectResult
    <O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, [O]), Client.Error>, _ result: Result<[[O]], Client.Error>, file: String = __FILE__, line: UInt = __LINE__)
{
    let actual = producer.map { $1 }.collect().single()!
    let message: String
    switch result {
    case let .Success(value):
        message = "\(actual) is not equal to \(value)"
    case let .Failure(error):
        message = "\(actual) is not equal to \(error)"
    }
    XCTAssertTrue(actual == result, message, file: file, line: line)
}

func ExpectResult
    <F: FixtureType, O: ResourceType, C: CollectionType where O.DecodedType == O, C.Generator.Element == F>
    (producer: SignalProducer<(Response, [O]), Client.Error>, _ result: Result<C, Client.Error>, file: String = __FILE__, line: UInt = __LINE__)
{
    let expected = result.map { fixtures -> [[O]] in fixtures.map { $0.decode()! } }
    ExpectResult(producer, expected, file: file, line: line)
}

func ExpectError
    <O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, O), Client.Error>, _ error: Client.Error, file: String = __FILE__, line: UInt = __LINE__)
{
    ExpectResult(producer, Result<[O], Client.Error>.Failure(error), file: file, line: line)
}

func ExpectFixtures
    <F: FixtureType, O: ResourceType where O.DecodedType == O>
    (producer: SignalProducer<(Response, O), Client.Error>, _ fixtures: F..., file: String = __FILE__, line: UInt = __LINE__)
{
    ExpectResult(producer, Result<[F], Client.Error>.Success(fixtures), file: file, line: line)
}

func ExpectFixtures
    <F: FixtureType, O: ResourceType, C: CollectionType where O.DecodedType == O, C.Generator.Element == F>
    (producer: SignalProducer<(Response, [O]), Client.Error>, _ fixtures: C, file: String = __FILE__, line: UInt = __LINE__)
{
    ExpectResult(producer, .Success(fixtures), file: file, line: line)
}


class ClientTests: XCTestCase {
    private let client = Client(.DotCom)
    
    override func setUp() {
        OHHTTPStubs
            .stubRequestsPassingTest({ request in
                return Fixture.fixtureForURL(request.URL!) != nil
            }, withStubResponse: { request -> OHHTTPStubsResponse in
                let fixture = Fixture.fixtureForURL(request.URL!)!
                let response = fixture.response
                return OHHTTPStubsResponse(fileURL: fixture.dataFileURL, statusCode: Int32(response.statusCode), headers: response.allHeaderFields)
            })
    }
    
    func testReleasesInRepository() {
        let fixtures = Fixture.Releases.Carthage
        ExpectFixtures(
            client.releasesInRepository(fixtures[0].repository),
            [ fixtures[0] ]
        )
    }
    
    func testReleasesInRepositoryPage2() {
        let fixtures = Fixture.Releases.Carthage
        ExpectFixtures(
            client.releasesInRepository(fixtures[0].repository, page: 2),
            fixtures.dropFirst()
        )
    }
    
    func testReleaseForTagInRepository() {
        let fixture = Fixture.Release.Carthage0_15
        ExpectFixtures(
            client.releaseForTag(fixture.tag, inRepository: fixture.repository),
            fixture
{'fraction_non_alphanumeric': 0.1292256289308176, 'fraction_numerical': 0.004127358490566038, 'mean_word_length': 3.0066929133858267, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2190148', 'n_tokens_mistral': 3142, 'n_tokens_neox': 3072, 'n_words': 888}