//
//  MeasurementDurationTests.swift
//  Research
//
//  Copyright © 2018 Sage Bionetworks. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// 1.  Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2.  Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation and/or
// other materials provided with the distribution.
//
// 3.  Neither the name of the copyright holder(s) nor the names of any contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission. No license is granted to the trademarks of
// the copyright holders even if such marks are included in this software.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//


import XCTest

@testable import Research

class MeasurementDurationTests: XCTestCase {
    
    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }
    
    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }
    
    func testMeasurementDuration_ValueAndUnit_3h_15m() {
        let expectedHours = 3
        let expectedMinutes = 15
        let expectedSeconds = 0
        let timeInterval: TimeInterval  = TimeInterval(expectedHours * 3600 + expectedMinutes * 60 + expectedSeconds)
        let ti = Measurement(value: timeInterval, unit: UnitDuration.seconds)
        
        XCTAssertEqual(ti.hours, expectedHours)
        XCTAssertEqual(ti.minutes, expectedMinutes)
        XCTAssertEqual(ti.seconds, expectedSeconds)
        XCTAssertEqual(ti.component(of: .hours), expectedHours)
        XCTAssertEqual(ti.component(of: .minutes), expectedMinutes)
        XCTAssertEqual(ti.component(of: .seconds), expectedSeconds)
        XCTAssertEqual(ti.timeInterval, timeInterval)
    }
    
    func testTimeInterval_ValueAndUnit_2h_15m_20s() {
        let expectedHours = 2
        let expectedMinutes = 15
        let expectedSeconds = 20
        let timeInterval: TimeInterval  = TimeInterval(expectedHours * 3600 + expectedMinutes * 60 + expectedSeconds)
        let ti = Measurement(value: timeInterval, unit: UnitDuration.seconds)
        
        XCTAssertEqual(ti.hours, expectedHours)
        XCTAssertEqual(ti.minutes, expectedMinutes)
        XCTAssertEqual(ti.seconds, expectedSeconds)
        XCTAssertEqual(ti.component(of: .hours), expectedHours)
        XCTAssertEqual(ti.component(of: .minutes), expectedMinutes)
        XCTAssertEqual(ti.component(of: .seconds), expectedSeconds)
        XCTAssertEqual(ti.timeInterval, timeInterval)
    }
    
    func testTimeInterval_ValueAndUnit_10m_20s() {
        let expectedHours = 0
        let expectedMinutes = 10
        let expectedSeconds = 20
        let timeInterval: TimeInterval  = TimeInterval(expectedHours * 3600 + expectedMinutes * 60 + expectedSeconds)
        let ti = Measurement(value: timeInterval, unit: UnitDuration.seconds)
        
        XCTAssertEqual(ti.hours, expectedHours)
        XCTAssertEqual(ti.minutes, expectedMinutes)
        XCTAssertEqual(ti.seconds, expectedSeconds)
        XCTAssertEqual(ti.component(of: .hours), expectedHours)
        XCTAssertEqual(ti.component(of: .minutes), expectedMinutes)
        XCTAssertEqual(ti.component(of: .seconds), expectedSeconds)
        XCTAssertEqual(ti.timeInterval, timeInterval)
    }
    
    func testTimeIntervalUnit_MaxTimeValue() {
        XCTAssertEqual(UnitDuration.hours.maxTimeValue(), 24)
        XCTAssertEqual(UnitDuration.minutes.maxTimeValue(), 60)
        XCTAssertEqual(UnitDuration.seconds.maxTimeValue(), 60)
    }
    
    func testTimeIntervalUnit_Comparable() {
        XCTAssertGreaterThan(UnitDuration.hours, UnitDuration.minutes)
        XCTAssertGreaterThan(UnitDuration.minutes, UnitDuration.seconds)
        XCTAssertGreaterThan(UnitDuration.hours, UnitDuration.seconds)
    }
    
    func testDurationUnitConvertion() {
        XCTAssertEqual(UnitDuration(fromSymbol: "s"), UnitDuration.seconds)
        XCTAssertEqual(UnitDuration(fromSymbol: "seconds"), UnitDuration.seconds)
        XCTAssertEqual(UnitDuration(fromSymbol: "min"), UnitDuration.minutes)
        XCTAssertEqual(UnitDuration(fromSymbol: "minutes"), UnitDuration.minutes)
        XCTAssertEqual(UnitDuration(fromSymbol: "hr"), UnitDuration.hours)
        XCTAssertEqual(UnitDuration(fromSymbol: "hours"), UnitDuration.hours)
    }
}
