Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸ‘©β€πŸ”¬ [Investment Day] - Test Suite Cleanup #731

Merged
merged 10 commits into from
Jul 3, 2019
2 changes: 1 addition & 1 deletion Kickstarter-iOS/ViewModels/RootViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ internal protocol RootViewModelInputs {
/// Call from the controller's `viewDidLoad` method.
func viewDidLoad()

/// Call when voice over is enabled or disabled
/// Call when VoiceOver is enabled or disabled
func voiceOverStatusDidChange()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ final class MessageBannerViewController: UIViewController, NibLoading {
guard let self = self else { return }

if isHidden {
// Tells Voice Over to resign focus of the message banner.
// Tells VoiceOver to resign focus of the message banner.
// This causes the reader to focus on the previously selected element.
if AppEnvironment.current.isVoiceOverRunning() {
UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: nil)
Expand All @@ -130,7 +130,7 @@ final class MessageBannerViewController: UIViewController, NibLoading {
self?.viewModel.inputs.bannerViewAnimationFinished(isHidden: isHidden)

if !isHidden {
// Tells Voice Over to focus on the message banner.
// Tells VoiceOver to focus on the message banner.
// This causes the reader to read the message and allows the user to dismiss the banner.
if AppEnvironment.current.isVoiceOverRunning() {
UIAccessibility.post(
Expand Down
4 changes: 2 additions & 2 deletions Kickstarter-iOS/Views/FundingGraphViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ private let project = .template

private func fundingStats(forProject project: Project, pledgeValues: [Int])
-> [ProjectStatsEnvelope.FundingDateStats] {
return pledgeValues.enumerated().map { idx, pledged in
.template
return pledgeValues.enumerated().map { (idx: Int, pledged: Int) in
ProjectStatsEnvelope.FundingDateStats.template
|> ProjectStatsEnvelope.FundingDateStats.lens.cumulativePledged .~ pledged
|> ProjectStatsEnvelope.FundingDateStats.lens.date
.~ (project.dates.launchedAt + TimeInterval(idx * 60 * 60 * 24))
Expand Down
8 changes: 4 additions & 4 deletions Library/AppEnvironment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public struct AppEnvironment: AppEnvironmentType {
dateType: DateProtocol.Type = AppEnvironment.current.dateType,
debounceInterval: DispatchTimeInterval = AppEnvironment.current.debounceInterval,
device: UIDeviceType = AppEnvironment.current.device,
isOSVersionAvailable: @escaping ((Double) -> Bool) = AppEnvironment.current.isOSVersionAvailable,
is1PasswordSupported: @escaping (() -> Bool) = AppEnvironment.current.is1PasswordSupported,
isVoiceOverRunning: @escaping (() -> Bool) = AppEnvironment.current.isVoiceOverRunning,
koala: Koala = AppEnvironment.current.koala,
language: Language = AppEnvironment.current.language,
Expand Down Expand Up @@ -153,7 +153,7 @@ public struct AppEnvironment: AppEnvironmentType {
dateType: dateType,
debounceInterval: debounceInterval,
device: device,
isOSVersionAvailable: isOSVersionAvailable,
is1PasswordSupported: is1PasswordSupported,
isVoiceOverRunning: isVoiceOverRunning,
koala: koala,
language: language,
Expand Down Expand Up @@ -185,7 +185,7 @@ public struct AppEnvironment: AppEnvironmentType {
dateType: DateProtocol.Type = AppEnvironment.current.dateType,
debounceInterval: DispatchTimeInterval = AppEnvironment.current.debounceInterval,
device: UIDeviceType = AppEnvironment.current.device,
isOSVersionAvailable: @escaping ((Double) -> Bool) = AppEnvironment.current.isOSVersionAvailable,
is1PasswordSupported: @escaping (() -> Bool) = AppEnvironment.current.is1PasswordSupported,
isVoiceOverRunning: @escaping (() -> Bool) = AppEnvironment.current.isVoiceOverRunning,
koala: Koala = AppEnvironment.current.koala,
language: Language = AppEnvironment.current.language,
Expand Down Expand Up @@ -213,7 +213,7 @@ public struct AppEnvironment: AppEnvironmentType {
dateType: dateType,
debounceInterval: debounceInterval,
device: device,
isOSVersionAvailable: isOSVersionAvailable,
is1PasswordSupported: is1PasswordSupported,
isVoiceOverRunning: isVoiceOverRunning,
koala: koala,
language: language,
Expand Down
10 changes: 5 additions & 5 deletions Library/Environment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ public struct Environment {
/// The environment variables
public let environmentVariables: EnvironmentVariables

/// A function that returns whether a specific OS version is available
public let isOSVersionAvailable: (Double) -> Bool
/// A function that returns whether 1Password extension is supported.
public let is1PasswordSupported: () -> Bool

/// A function that returns whether voice over mode is running.
/// A function that returns whether VoiceOver mode is running.
public let isVoiceOverRunning: () -> Bool

/// A type that exposes endpoints for tracking various Kickstarter events.
Expand Down Expand Up @@ -108,7 +108,7 @@ public struct Environment {
debounceInterval: DispatchTimeInterval = .milliseconds(300),
device: UIDeviceType = UIDevice.current,
environmentVariables: EnvironmentVariables = EnvironmentVariables(),
isOSVersionAvailable: @escaping (Double) -> Bool = ksr_isOSVersionAvailable,
is1PasswordSupported: @escaping () -> Bool = { ksr_is1PasswordSupported() },
isVoiceOverRunning: @escaping () -> Bool = { UIAccessibility.isVoiceOverRunning },
koala: Koala = Koala(client: KoalaTrackingClient(endpoint: .production)),
language: Language = Language(languageStrings: Locale.preferredLanguages) ?? Language.en,
Expand All @@ -135,7 +135,7 @@ public struct Environment {
self.debounceInterval = debounceInterval
self.device = device
self.environmentVariables = environmentVariables
self.isOSVersionAvailable = isOSVersionAvailable
self.is1PasswordSupported = is1PasswordSupported
self.isVoiceOverRunning = isVoiceOverRunning
self.koala = koala
self.language = language
Expand Down
8 changes: 2 additions & 6 deletions Library/Koala/KoalaTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,15 @@ final class KoalaTests: TestCase {
let client = MockTrackingClient()
let koala = Koala(client: client)

var isVoiceOverRunning = { true }

withEnvironment(isVoiceOverRunning: isVoiceOverRunning) {
withEnvironment(isVoiceOverRunning: { true }) {
koala.trackAppOpen()

let properties = client.properties.last

XCTAssertEqual(true, properties?["is_voiceover_running"] as? Bool)
}

isVoiceOverRunning = { false }

withEnvironment(isVoiceOverRunning: isVoiceOverRunning) {
withEnvironment(isVoiceOverRunning: { false }) {
koala.trackAppOpen()

let properties = client.properties.last
Expand Down
14 changes: 5 additions & 9 deletions Library/SharedFunctions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,22 +152,18 @@ public func countdownProducer(to date: Date)
}

internal func is1PasswordButtonHidden(_ isHidden: Bool) -> Bool {
if AppEnvironment.current.isOSVersionAvailable(12.0) {
if AppEnvironment.current.is1PasswordSupported() {
return true
} else {
return isHidden
}
}

public func ksr_isOSVersionAvailable(_ version: Double) -> Bool {
switch version {
case 12.0...:
if #available(iOS 12.0, *) { return true }
default:
assertionFailure("OS version-check not supported")
public func ksr_is1PasswordSupported() -> Bool {
if #available(iOS 12.0, *) {
return false
}

return false
return true
}

public func updatedUserWithClearedActivityCountProducer() -> SignalProducer<User, Never> {
Expand Down
13 changes: 2 additions & 11 deletions Library/SharedFunctionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,26 +162,17 @@ final class SharedFunctionsTests: TestCase {
}

func testOnePasswordButtonIsHidden() {
var iOS12: (Double) -> Bool = { _ in true }
withEnvironment(isOSVersionAvailable: iOS12) {
withEnvironment(is1PasswordSupported: { true }) {
XCTAssertTrue(is1PasswordButtonHidden(true))
XCTAssertTrue(is1PasswordButtonHidden(false))
}

iOS12 = { _ in false }
withEnvironment(isOSVersionAvailable: iOS12) {
withEnvironment(is1PasswordSupported: { false }) {
XCTAssertTrue(is1PasswordButtonHidden(true))
XCTAssertFalse(is1PasswordButtonHidden(false))
}
}

func testIsOSVersionAvailable_Supports_iOS12() {
XCTAssertTrue(ksr_isOSVersionAvailable(12.0))
XCTAssertTrue(ksr_isOSVersionAvailable(12.1))
XCTAssertTrue(ksr_isOSVersionAvailable(12.123))
XCTAssertTrue(ksr_isOSVersionAvailable(12.9))
}

func testUpdatedUserWithClearedActivityCountProducer_Success() {
let initialActivitiesCount = 100
let values = TestObserver<User, Never>()
Expand Down
4 changes: 4 additions & 0 deletions Library/TestHelpers/DispatchTimeInterval-Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ extension DispatchTimeInterval {
return .nanoseconds(Int(Float(interval) * scale))
case .never:
return .never
@unknown default:
fatalError()
}
#else
switch self {
Expand Down Expand Up @@ -46,6 +48,8 @@ extension DispatchTimeInterval {
return Int64(ns)
case .never:
return Int64(0)
@unknown default:
fatalError()
}
#else
switch self {
Expand Down
23 changes: 14 additions & 9 deletions Library/TestHelpers/TestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ internal class TestCase: FBSnapshotTestCase {
internal let ubiquitousStore = MockKeyValueStore()
internal let userDefaults = MockKeyValueStore()

override var recordMode: Bool {
willSet(newValue) {
if newValue {
preferredSimulatorCheck()
}
}
}

override func setUp() {
super.setUp()

Expand All @@ -33,8 +41,6 @@ internal class TestCase: FBSnapshotTestCase {
// swiftlint:disable:next force_unwrapping
calendar.timeZone = TimeZone(identifier: "GMT")!

let isVoiceOverRunning = { false }
let isOSVersionAvailable: (Double) -> Bool = { _ in true }
AppEnvironment.pushEnvironment(
apiService: self.apiService,
apiDelayInterval: .seconds(0),
Expand All @@ -49,8 +55,8 @@ internal class TestCase: FBSnapshotTestCase {
dateType: self.dateType,
debounceInterval: .seconds(0),
device: MockDevice(),
isOSVersionAvailable: isOSVersionAvailable,
isVoiceOverRunning: isVoiceOverRunning,
is1PasswordSupported: { true },
isVoiceOverRunning: { false },
koala: Koala(client: self.trackingClient, loggedInUser: nil),
language: .en,
launchedCountries: .init(),
Expand All @@ -71,11 +77,10 @@ internal class TestCase: FBSnapshotTestCase {
}

internal func preferredSimulatorCheck() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep this as:

internal func preferredSimulatorCheck() {
  guard
    let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"],
    ["iPhone10,1", "iPhone10,4"].contains(identifier),
    #available(iOS 12.0, *)
  else {
    fatalError("Please only test and record screenshots on an iPhone 8 simulator running iOS 12")
  }
}

and then can we add this to TestCase:

override var recordMode: Bool {
  willSet(newValue) {
    if newValue {
      preferredSimulatorCheck()
    }
  }
}

This will only perform the preferredSimulatorCheck() when we are actually recording screenshots and not just running unit tests.
You can then remove the line calling preferredSimulatorCheck() from setUp() in TestCase.swift πŸ‘

guard
let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"],
["iPhone10,1", "iPhone10,4"].contains(identifier),
AppEnvironment.current.isOSVersionAvailable(12)
else {
let supportedModels = ["iPhone10,1", "iPhone10,4"] // iPhone 8
let modelKey = "SIMULATOR_MODEL_IDENTIFIER"

guard #available(iOS 12.0, *), supportedModels.contains(ProcessInfo().environment[modelKey] ?? "") else {
fatalError("Please only test and record screenshots on an iPhone 8 simulator running iOS 12")
}
}
4 changes: 2 additions & 2 deletions Library/TestHelpers/XCTestCase+AppEnvironment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension XCTestCase {
dateType: DateProtocol.Type = AppEnvironment.current.dateType,
debounceInterval: DispatchTimeInterval = AppEnvironment.current.debounceInterval,
device: UIDeviceType = AppEnvironment.current.device,
isOSVersionAvailable: @escaping (Double) -> Bool = AppEnvironment.current.isOSVersionAvailable,
is1PasswordSupported: @escaping () -> Bool = AppEnvironment.current.is1PasswordSupported,
isVoiceOverRunning: @escaping () -> Bool = AppEnvironment.current.isVoiceOverRunning,
koala: Koala = AppEnvironment.current.koala,
language: Language = AppEnvironment.current.language,
Expand Down Expand Up @@ -55,7 +55,7 @@ extension XCTestCase {
dateType: dateType,
debounceInterval: debounceInterval,
device: device,
isOSVersionAvailable: isOSVersionAvailable,
is1PasswordSupported: is1PasswordSupported,
isVoiceOverRunning: isVoiceOverRunning,
koala: koala,
language: language,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public protocol ActivitySampleProjectCellViewModelInputs {
}

public protocol ActivitySampleProjectCellViewModelOutputs {
/// Emits the cell accessibility hint for voiceover.
/// Emits the cell accessibility hint for VoiceOver.
var cellAccessibilityHint: Signal<String, Never> { get }

/// Emits when should go to activities screen.
Expand Down
4 changes: 2 additions & 2 deletions Library/ViewModels/ActivityUpdateViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ public protocol ActivityUpdateViewModelOutputs {
/// Emits the update's body to be displayed.
var body: Signal<String, Never> { get }

/// Emits the cell's accessibility label to be read by voiceover.
/// Emits the cell's accessibility label to be read by VoiceOver.
var cellAccessibilityLabel: Signal<String, Never> { get }

/// Emits when we should notify the delegate that the project image button was tapped.
var notifyDelegateTappedProjectImage: Signal<Activity, Never> { get }

/// Emits the project button's accessibility label to be read by voiceover.
/// Emits the project button's accessibility label to be read by VoiceOver.
var projectButtonAccessibilityLabel: Signal<String, Never> { get }

/// Emits the project image URL to be displayed.
Expand Down
3 changes: 1 addition & 2 deletions Library/ViewModels/BackingCellViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ internal final class BackingCellViewModelTests: TestCase {
let reward = .template |> Reward.lens.estimatedDeliveryOn .~ Date().timeIntervalSince1970
let backing = .template |> Backing.lens.reward .~ reward

let isVoiceOverRunning = { true }
withEnvironment(isVoiceOverRunning: isVoiceOverRunning) {
withEnvironment(isVoiceOverRunning: { true }) {
self.vm.inputs.configureWith(backing: backing, project: Project.template, isFromBacking: true)

self.rootStackViewAlignment.assertValues([UIStackView.Alignment.fill])
Expand Down
6 changes: 2 additions & 4 deletions Library/ViewModels/ChangeEmailViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ final class ChangeEmailViewModelTests: TestCase {
func testOnePasswordButtonHidesProperly_OnIOS11AndEarlier() {
self.vm.inputs.viewDidLoad()

let iOS12: (Double) -> Bool = { _ in false }
withEnvironment(isOSVersionAvailable: iOS12) {
withEnvironment(is1PasswordSupported: { false }) {
self.vm.inputs.onePassword(isAvailable: true)

self.onePasswordButtonIsHidden.assertValues([false])
Expand All @@ -129,8 +128,7 @@ final class ChangeEmailViewModelTests: TestCase {
func testOnePasswordButtonHidesProperly_OnIOS12AndLater() {
self.vm.inputs.viewDidLoad()

let iOS12: (Double) -> Bool = { _ in true }
withEnvironment(isOSVersionAvailable: iOS12) {
withEnvironment(is1PasswordSupported: { true }) {
self.vm.inputs.onePassword(isAvailable: true)

self.onePasswordButtonIsHidden.assertValues([true])
Expand Down
17 changes: 5 additions & 12 deletions Library/ViewModels/ChangePasswordViewModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ final class ChangePasswordViewModelTests: TestCase {
}

func testOnePasswordButtonHidesProperly_OnIOS11AndEarlier() {
let iOS12: (Double) -> Bool = { _ in false }
withEnvironment(isOSVersionAvailable: iOS12) {
withEnvironment(is1PasswordSupported: { false }) {
self.vm.inputs.onePassword(isAvailable: true)

self.onePasswordButtonIsHidden.assertValues([false])
Expand All @@ -107,8 +106,7 @@ final class ChangePasswordViewModelTests: TestCase {
}

func testOnePasswordButtonHidesProperly_OnIOS12AndLater() {
let iOS12: (Double) -> Bool = { _ in true }
withEnvironment(isOSVersionAvailable: iOS12) {
withEnvironment(is1PasswordSupported: { true }) {
self.vm.inputs.onePassword(isAvailable: true)

self.onePasswordButtonIsHidden.assertValues([true])
Expand All @@ -121,9 +119,8 @@ final class ChangePasswordViewModelTests: TestCase {

func testOnePasswordAutofill() {
let mockService = MockService(serverConfig: ServerConfig.local)
let iOS12: (Double) -> Bool = { _ in false }

withEnvironment(apiService: mockService, isOSVersionAvailable: iOS12) {
withEnvironment(apiService: mockService, is1PasswordSupported: { false }) {
self.vm.inputs.onePassword(isAvailable: true)
self.vm.inputs.viewDidAppear()

Expand All @@ -141,9 +138,7 @@ final class ChangePasswordViewModelTests: TestCase {
}

func testValidationErrors_VoiceOverON() {
let isVoiceOverRunning = { true }

withEnvironment(isVoiceOverRunning: isVoiceOverRunning) {
withEnvironment(isVoiceOverRunning: { true }) {
self.vm.inputs.viewDidAppear()
self.validationErrorLabelIsHidden.assertValues([true])
self.validationErrorLabelMessage.assertValues([""])
Expand Down Expand Up @@ -251,9 +246,7 @@ final class ChangePasswordViewModelTests: TestCase {
}

func testValidationErrors_VoiceOverOFF() {
let isVoiceOverRunning = { false }

withEnvironment(isVoiceOverRunning: isVoiceOverRunning) {
withEnvironment(isVoiceOverRunning: { false }) {
self.vm.inputs.viewDidAppear()
self.validationErrorLabelIsHidden.assertValues([true])
self.validationErrorLabelMessage.assertValues([""])
Expand Down
Loading