Files
GradientLoadingBar/Example/Tests/ViewModel/GradientActivityIndicatorViewModelTestCase.swift
T
Felix Mau 849ef3e945 ♻️ :: Directly access first row of color location matrix instead of having a separate observable
This way we can prevent `colorLocationMatrix` and `colorLocationInitialRow` running out of sync.
2021-10-02 13:43:52 +02:00

244 lines
10 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// GradientActivityIndicatorViewModelTestCase.swift
// GradientLoadingBar_Tests
//
// Created by Felix Mau on 26.08.19.
// Copyright © 2019 Felix Mau. All rights reserved.
//
import XCTest
import LightweightObservable
@testable import GradientLoadingBar
// swiftlint:disable:next type_name
class GradientActivityIndicatorViewModelTestCase: XCTestCase {
// MARK: - Private properties
private var viewModel: GradientActivityIndicatorViewModel!
// MARK: - Public methods
override func setUp() {
super.setUp()
viewModel = GradientActivityIndicatorViewModel()
}
override func tearDown() {
viewModel = nil
super.tearDown()
}
// MARK: - Test initializer
func testInitializerShouldSetGradientLayerColorsToCorrectValue() {
let expectedGradientLayerColors = makeGradientLayerColors()
XCTAssertEqual(viewModel.gradientLayerColors.value, expectedGradientLayerColors)
}
func testInitializerShouldSetColorLocationMatrixToCorrectValue() throws {
let receivedColorLocationMatrix = try XCTUnwrap(viewModel.colorLocationMatrix.value)
let expectedColorLocationMatrix = makeColorLocationMatrix()
// Unfortunately there is no easier way comparing an array of type `NSNumber` / `Double` with a given accuracy.
XCTAssertEqual(receivedColorLocationMatrix.count, expectedColorLocationMatrix.count)
for (receivedColorLocationRow, expectedColorLocationRow) in zip(receivedColorLocationMatrix, expectedColorLocationMatrix) {
XCTAssertEqual(receivedColorLocationRow.count, expectedColorLocationRow.count)
for (receivedColorLocation, expectedColorLocation) in zip(receivedColorLocationRow, expectedColorLocationRow) {
XCTAssertEqual(receivedColorLocation.doubleValue, expectedColorLocation.doubleValue, accuracy: .ulpOfOne)
}
}
}
func testInitializerShouldSetAnimationDurationToStaticConfigurationProperty() {
XCTAssertEqual(viewModel.animationDuration.value, TimeInterval.GradientLoadingBar.progressDuration)
}
func testInitializerShouldSetIsAnimatingToTrue() throws {
XCTAssertTrue(
try XCTUnwrap(viewModel.isAnimating.value)
)
}
func testInitializerShouldSetGradientColorsToStaticConfigurationProperty() {
XCTAssertEqual(viewModel.gradientColors, UIColor.GradientLoadingBar.gradientColors)
}
func testInitializerShouldSetProgressAnimationDurationToStaticConfigurationProperty() {
XCTAssertEqual(viewModel.progressAnimationDuration, TimeInterval.GradientLoadingBar.progressDuration)
}
func testInitializerShouldSetIsHiddenToFalse() {
XCTAssertFalse(viewModel.isHidden)
}
// MARK: - Test property `gradientColors`
func testSettingGradientColorsShouldUpdateGradientLayerColorsObservable() {
// Given
let gradientColors: [UIColor] = [.red, .yellow, .green]
// When
viewModel.gradientColors = gradientColors
// Then
//
// `gradientColors = [.red, .yellow, .green]`
// `gradientLayerColors = [.red, .yellow, .green, .yellow, .red, .yellow, .green]`
//
let expectedGradientColors: [UIColor] = [.red, .yellow, .green, .yellow, .red, .yellow, .green]
let expectedGradientLayerColors = expectedGradientColors.map { $0.cgColor }
XCTAssertEqual(viewModel.gradientLayerColors.value, expectedGradientLayerColors)
}
func testSettingGradientColorsShouldUpdateColorLocationMatrixObservable() {
// Given
let gradientColors: [UIColor] = [.red, .yellow, .green]
// When
viewModel.gradientColors = gradientColors
// Then
//
// `gradientColors = [.red, .yellow, .green]`
// `gradientLayerColors = [.red, .yellow, .green, .yellow, .red, .yellow, .green]`
//
// i | .red | .yellow | .green | .yellow | .red | .yellow | .green
// 0 | 0 | 0 | 0 | 0 | 0 | 0.5 | 1
// 1 | 0 | 0 | 0 | 0 | 0.5 | 1 | 1
// 2 | 0 | 0 | 0 | 0.5 | 1 | 1 | 1
// 3 | 0 | 0 | 0.5 | 1 | 1 | 1 | 1
// 4 | 0 | 0.5 | 1 | 1 | 1 | 1 | 1
//
let colorLocationMatrix = [
[0, 0, 0, 0, 0, 0.5, 1],
[0, 0, 0, 0, 0.5, 1, 1],
[0, 0, 0, 0.5, 1, 1, 1],
[0, 0, 0.5, 1, 1, 1, 1],
[0, 0.5, 1, 1, 1, 1, 1],
]
let expectedColorLocationMatrix = colorLocationMatrix.map {
$0.map { NSNumber(value: $0) }
}
XCTAssertEqual(viewModel.colorLocationMatrix.value, expectedColorLocationMatrix)
}
// MARK: - Test property `progressAnimationDuration`
func testSettingProgressAnimationDurationShouldUpdateAnimationDurationObservable() {
// Given
let progressAnimationDuration: TimeInterval = 123
// When
viewModel.progressAnimationDuration = progressAnimationDuration
// Then
XCTAssertEqual(viewModel.animationDuration.value, progressAnimationDuration)
}
// MARK: - Test property `isHidden`
func testSettingIsHiddenToTrueShouldSetIsAnimatingToFalse() throws {
// When
viewModel.isHidden = true
// Then
XCTAssertFalse(
try XCTUnwrap(viewModel.isAnimating.value)
)
}
func testSettingIsHiddenToFalseShouldSetIsAnimatingToTrue() throws {
// When
viewModel.isHidden = false
// Then
XCTAssertTrue(
try XCTUnwrap(viewModel.isAnimating.value)
)
}
}
// MARK: - Helpers
extension GradientActivityIndicatorViewModelTestCase {
private func makeGradientLayerColors() -> [CGColor] {
let gradientColors = [
#colorLiteral(red: 0.2980392157, green: 0.8509803922, blue: 0.3921568627, alpha: 1), #colorLiteral(red: 0.3529411765, green: 0.7843137255, blue: 0.9803921569, alpha: 1), #colorLiteral(red: 0, green: 0.4784313725, blue: 1, alpha: 1), #colorLiteral(red: 0.2039215686, green: 0.6666666667, blue: 0.862745098, alpha: 1), #colorLiteral(red: 0.3450980392, green: 0.337254902, blue: 0.8392156863, alpha: 1), #colorLiteral(red: 1, green: 0.1764705882, blue: 0.3333333333, alpha: 1),
]
XCTAssertEqual(gradientColors, UIColor.GradientLoadingBar.gradientColors,
"Precondition failed The given gradient colors do not match the current color constant!")
// swiftlint:disable:next identifier_name
let reversedGradientColorsWithoutFirstAndLastValue = [
#colorLiteral(red: 0.3450980392, green: 0.337254902, blue: 0.8392156863, alpha: 1), #colorLiteral(red: 0.2039215686, green: 0.6666666667, blue: 0.862745098, alpha: 1), #colorLiteral(red: 0, green: 0.4784313725, blue: 1, alpha: 1), #colorLiteral(red: 0.3529411765, green: 0.7843137255, blue: 0.9803921569, alpha: 1),
]
let infiniteGradientColors = gradientColors + reversedGradientColorsWithoutFirstAndLastValue + gradientColors
return infiniteGradientColors.map { $0.cgColor }
}
private func makeColorLocationInitialRow() -> ColorLocationRow {
let gradientLocations = [0, 0.2, 0.4, 0.6, 0.8, 1]
XCTAssertEqual(gradientLocations.count, UIColor.GradientLoadingBar.gradientColors.count,
"Precondition failed The given gradient locations do not match for the current color constant!")
// The current constant has 6 value and therefore we expect 16 gradient layer colors in total.
// Ergo we have to fill the first 10 values with "0", before adding the `gradientLocations`.
//
// .green | .malibu | .azure | .curious | .violet | .red | .violet | .curious | .azure | .malibu | .green | .malibu | .azure | .curious | .violet | .red
// 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.2 | 0.4 | 0.6 | 0.8 | 1
//
// swiftlint:disable:next identifier_name
let gradientLocationAnimationMatrixInitialRow = Array(repeating: 0.0, count: 10) + gradientLocations
return gradientLocationAnimationMatrixInitialRow.map {
NSNumber(value: $0)
}
}
private func makeColorLocationMatrix() -> ColorLocationMatrix {
let gradientLocations = [0, 0.2, 0.4, 0.6, 0.8, 1]
XCTAssertEqual(gradientLocations.count, UIColor.GradientLoadingBar.gradientColors.count,
"Precondition failed The given gradient locations do not match for the current color constant!")
// The current constant has 6 value and therefore we expect 16 gradient layer colors in total.
// Ergo we have to fill the first 10 values with "0", before adding the `gradientLocations`.
//
// .green | .malibu | .azure | .curious | .violet | .red | .violet | .curious | .azure | .malibu | .green | .malibu | .azure | .curious | .violet | .red
// 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0.2 | 0.4 | 0.6 | 0.8 | 1
// ...
// 0 | 0 | 0 | 0 | 0 | 0 | 0.2 | 0.4 | 0.6 | 0.8 | 1 | 1 | 1 | 1 | 1 | 1
// ...
// 0 | 0.2 | 0.4 | 0.6 | 0.8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1
//
let colorLocationMatrix = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0.2, 0.4, 0.6, 0.8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
]
return colorLocationMatrix.map {
$0.map { NSNumber(value: $0) }
}
}
}