mirror of
https://github.com/zhigang1992/GitHawk.git
synced 2026-01-12 22:47:34 +08:00
Add merge status tests (#1604)
* Add merge status tests * Introduce containsAll and containsNone * Rename containsAll to containsOnly
This commit is contained in:
@@ -73,7 +73,7 @@ MergeButtonDelegate {
|
||||
|
||||
if object.contexts.count > 0 {
|
||||
let states = object.contexts.map { $0.state }
|
||||
let (state, stateDescription) = combinedMergeStatus(for: states)
|
||||
let (state, stateDescription) = MergeHelper.combinedMergeStatus(for: states)
|
||||
|
||||
viewModels.append(IssueMergeSummaryModel(title: stateDescription, state: state))
|
||||
}
|
||||
@@ -184,28 +184,4 @@ MergeButtonDelegate {
|
||||
viewController?.present(alert, animated: trueUnlessReduceMotionEnabled)
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
private func combinedMergeStatus(for states: [StatusState]) -> (IssueMergeSummaryModel.State, String) {
|
||||
let state: IssueMergeSummaryModel.State
|
||||
let stateDescription: String
|
||||
let failureDescription = NSLocalizedString("Some checks failed", comment: "")
|
||||
switch states {
|
||||
case let states where states.contains(.failure) || states.contains(.error):
|
||||
state = .failure
|
||||
stateDescription = failureDescription
|
||||
case let states where states.contains(.pending):
|
||||
state = .pending
|
||||
stateDescription = NSLocalizedString("Merge status pending", comment: "")
|
||||
case let states where states.reduce(true, { $0 && $1 == .success }):
|
||||
state = .success
|
||||
stateDescription = NSLocalizedString("All checks passed", comment: "")
|
||||
default:
|
||||
assert(false, "This should only occur when any of the `states` are of type `.expected`, which we have no clue of when it is used. The documentation (https://developer.github.com/v4/enum/statusstate/) doesn't answer that question either.")
|
||||
state = .failure
|
||||
stateDescription = failureDescription
|
||||
}
|
||||
|
||||
return (state, stateDescription)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
35
Classes/Issues/Merge/MergeHelper.swift
Normal file
35
Classes/Issues/Merge/MergeHelper.swift
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// MergeHelper.swift
|
||||
// FreetimeTests
|
||||
//
|
||||
// Created by Bas Broek on 03/03/2018.
|
||||
// Copyright © 2018 Ryan Nystrom. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum MergeHelper {
|
||||
static func combinedMergeStatus(for states: [StatusState]) -> (state: IssueMergeSummaryModel.State, description: String) {
|
||||
assert(!states.isEmpty, "Should only check merge status when there is at least one state")
|
||||
let state: IssueMergeSummaryModel.State
|
||||
let stateDescription: String
|
||||
let failureDescription = NSLocalizedString("Some checks failed", comment: "")
|
||||
switch states {
|
||||
case let states where states.contains(.failure) || states.contains(.error):
|
||||
state = .failure
|
||||
stateDescription = failureDescription
|
||||
case let states where states.contains(.pending):
|
||||
state = .pending
|
||||
stateDescription = NSLocalizedString("Merge status pending", comment: "")
|
||||
case let states where states.containsOnly(.success):
|
||||
state = .success
|
||||
stateDescription = NSLocalizedString("All checks passed", comment: "")
|
||||
default:
|
||||
assert(false, "This should only occur when any of the `states` are of type `.expected`, which we have no clue of when it is used. The documentation (https://developer.github.com/v4/enum/statusstate/) doesn't answer that question either.")
|
||||
state = .failure
|
||||
stateDescription = failureDescription
|
||||
}
|
||||
|
||||
return (state, stateDescription)
|
||||
}
|
||||
}
|
||||
57
Classes/Utility/Sequence+Contains.swift
Normal file
57
Classes/Utility/Sequence+Contains.swift
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Sequence+Contains.swift
|
||||
// Freetime
|
||||
//
|
||||
// Created by Bas Broek on 03/03/2018.
|
||||
// Copyright © 2018 Ryan Nystrom. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Sequence where Element: Equatable {
|
||||
|
||||
/// Returns a Boolean value indicating whether every element of the sequence
|
||||
/// is equal to the given element.
|
||||
func containsOnly(_ element: Element) -> Bool {
|
||||
var iterator = self.makeIterator()
|
||||
guard iterator.next() != nil else { return false }
|
||||
return first(where: { $0 != element }) == nil
|
||||
}
|
||||
|
||||
/// Returns a Boolean value indicating whether every element of the sequence
|
||||
/// does not equal to the given element.
|
||||
func containsNone(_ element: Element) -> Bool {
|
||||
return first(where: { $0 == element }) == nil
|
||||
}
|
||||
}
|
||||
|
||||
extension Sequence {
|
||||
|
||||
/// Returns a Boolean value indicating whether every element of the sequence
|
||||
/// satisfies the given predicate.
|
||||
func containsOnly(where predicate: (Element) throws -> Bool) rethrows -> Bool {
|
||||
var iterator = self.makeIterator()
|
||||
var isNotEmpty = false
|
||||
|
||||
while let element = iterator.next() {
|
||||
isNotEmpty = true
|
||||
if try !predicate(element) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return isNotEmpty
|
||||
}
|
||||
|
||||
/// Returns a Boolean value indicating whether every element of the sequence
|
||||
/// does not satisfies the given predicate.
|
||||
func containsNone(where predicate: (Element) throws -> Bool) rethrows -> Bool {
|
||||
var iterator = self.makeIterator()
|
||||
|
||||
while let element = iterator.next() {
|
||||
if try predicate(element) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ extension UIViewController {
|
||||
}
|
||||
|
||||
// dismiss if all text entries are empty
|
||||
let canDismissNow = texts.reduce(true) { $0 && ($1 == nil || $1!.isEmpty) }
|
||||
let canDismissNow = texts.containsOnly { $0 == nil || $0!.isEmpty }
|
||||
if canDismissNow {
|
||||
dismissBlock()
|
||||
} else {
|
||||
|
||||
@@ -360,7 +360,11 @@
|
||||
3E79A2FF1F8A7DA700E1126B /* ShortcutHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E79A2FE1F8A7DA700E1126B /* ShortcutHandler.swift */; };
|
||||
45A9D03A1F9D3D9600FD5AEF /* AttributedStringViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A9D0391F9D3D9600FD5AEF /* AttributedStringViewTests.swift */; };
|
||||
4920F1A81F72E27200131E9D /* UIViewController+UserActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4920F1A71F72E27200131E9D /* UIViewController+UserActivity.swift */; };
|
||||
49AF91B1204B416500DFF325 /* MergeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49AF91B0204B416500DFF325 /* MergeTests.swift */; };
|
||||
49AF91B4204B4B6A00DFF325 /* MergeHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49AF91B2204B4A6000DFF325 /* MergeHelper.swift */; };
|
||||
49D029001F91D90C00E39094 /* ReactionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49D028FF1F91D90C00E39094 /* ReactionTests.swift */; };
|
||||
49FE18FD204B5D32001681E8 /* Sequence+Contains.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FE18FC204B5D32001681E8 /* Sequence+Contains.swift */; };
|
||||
49FE18FF204B6508001681E8 /* SequenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FE18FE204B6508001681E8 /* SequenceTests.swift */; };
|
||||
49FFF4341F9FC83200335568 /* HapticFeedback.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FFF4331F9FC83200335568 /* HapticFeedback.swift */; };
|
||||
54AD5E8E1F24D953004A4BD6 /* FeedSelectionProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54AD5E8D1F24D953004A4BD6 /* FeedSelectionProviding.swift */; };
|
||||
5DB4DD471FC5C10000DF7ABF /* Accessibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DB4DD461FC5C10000DF7ABF /* Accessibility.swift */; };
|
||||
@@ -801,7 +805,11 @@
|
||||
3E79A2FE1F8A7DA700E1126B /* ShortcutHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutHandler.swift; sourceTree = "<group>"; };
|
||||
45A9D0391F9D3D9600FD5AEF /* AttributedStringViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringViewTests.swift; sourceTree = "<group>"; };
|
||||
4920F1A71F72E27200131E9D /* UIViewController+UserActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+UserActivity.swift"; sourceTree = "<group>"; };
|
||||
49AF91B0204B416500DFF325 /* MergeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MergeTests.swift; sourceTree = "<group>"; };
|
||||
49AF91B2204B4A6000DFF325 /* MergeHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MergeHelper.swift; sourceTree = "<group>"; };
|
||||
49D028FF1F91D90C00E39094 /* ReactionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionTests.swift; sourceTree = "<group>"; };
|
||||
49FE18FC204B5D32001681E8 /* Sequence+Contains.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Contains.swift"; sourceTree = "<group>"; };
|
||||
49FE18FE204B6508001681E8 /* SequenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SequenceTests.swift; sourceTree = "<group>"; };
|
||||
49FFF4331F9FC83200335568 /* HapticFeedback.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticFeedback.swift; sourceTree = "<group>"; };
|
||||
516CF27F9258BBD3E034F09D /* Pods_FreetimeTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FreetimeTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
54AD5E8D1F24D953004A4BD6 /* FeedSelectionProviding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedSelectionProviding.swift; sourceTree = "<group>"; };
|
||||
@@ -1340,6 +1348,8 @@
|
||||
DC60C6D21F983BB900241271 /* SignatureTests.swift */,
|
||||
45A9D0381F9D3D6A00FD5AEF /* Snapshot Tests */,
|
||||
29EDFE7B1F65C580005BCCEB /* SplitViewTests.swift */,
|
||||
49AF91B0204B416500DFF325 /* MergeTests.swift */,
|
||||
49FE18FE204B6508001681E8 /* SequenceTests.swift */,
|
||||
295F52A61EF1B9D2000B53CF /* Test.md */,
|
||||
);
|
||||
path = FreetimeTests;
|
||||
@@ -1599,6 +1609,7 @@
|
||||
2999972720310F3100995FFD /* IssueMergeContextModel.swift */,
|
||||
2999972520310E9700995FFD /* IssueMergeModel.swift */,
|
||||
2999972920311B3800995FFD /* IssueMergeSectionController.swift */,
|
||||
49AF91B2204B4A6000DFF325 /* MergeHelper.swift */,
|
||||
2999972B20311DD700995FFD /* IssueMergeSummaryCell.swift */,
|
||||
299997312031242500995FFD /* IssueMergeSummaryModel.swift */,
|
||||
299997372031DEB300995FFD /* IssueMergeType.swift */,
|
||||
@@ -1818,6 +1829,7 @@
|
||||
754488B01F7ADF8D0032D08C /* UIAlertController+Action.swift */,
|
||||
98835BCD1F1965E2005BA24F /* UIDevice+Model.swift */,
|
||||
98B5A0851F6D0FFE000617D6 /* UINavigationController+Replace.swift */,
|
||||
49FE18FC204B5D32001681E8 /* Sequence+Contains.swift */,
|
||||
);
|
||||
path = Utility;
|
||||
sourceTree = "<group>";
|
||||
@@ -2324,6 +2336,7 @@
|
||||
291929551F3FAADF0012067B /* FeedRefresh.swift in Sources */,
|
||||
2993046F1FBA9D31007B9737 /* IssueManagingActionCell.swift in Sources */,
|
||||
54AD5E8E1F24D953004A4BD6 /* FeedSelectionProviding.swift in Sources */,
|
||||
49FE18FD204B5D32001681E8 /* Sequence+Contains.swift in Sources */,
|
||||
291929421F3EA8CD0012067B /* File.swift in Sources */,
|
||||
299E86491EFD9DBB00E5FE70 /* FlexController.m in Sources */,
|
||||
29EB1EEF1F425E5100A200B4 /* ForegroundHandler.swift in Sources */,
|
||||
@@ -2617,6 +2630,7 @@
|
||||
29B94E6F1FCB743900715D7E /* RepositoryFileCell.swift in Sources */,
|
||||
29459A711FE7153500034A04 /* LogEnvironmentInformation.swift in Sources */,
|
||||
295B51441FC26C5400C3993B /* PeopleViewController.swift in Sources */,
|
||||
49AF91B4204B4B6A00DFF325 /* MergeHelper.swift in Sources */,
|
||||
2930F2731F8A27750082BA26 /* WidthCache.swift in Sources */,
|
||||
2971722B1F069E6B005E43AC /* SpinnerSectionController.swift in Sources */,
|
||||
2999972E203120E300995FFD /* IssueMergeButtonCell.swift in Sources */,
|
||||
@@ -2681,6 +2695,7 @@
|
||||
293A45771F296B7E00DD1006 /* ListKitTestCase.swift in Sources */,
|
||||
DC5C02C51F9C6E3500E80B9F /* SearchQueryTests.swift in Sources */,
|
||||
293A457E1F296BD500DD1006 /* API.swift in Sources */,
|
||||
49AF91B1204B416500DFF325 /* MergeTests.swift in Sources */,
|
||||
2986B35F1FD462B300E3CFC6 /* FilePath.swift in Sources */,
|
||||
293A45781F296B7E00DD1006 /* ListTestKit.swift in Sources */,
|
||||
296B4E341F7C80B800C16887 /* GraphQLIDDecodeTests.swift in Sources */,
|
||||
@@ -2688,6 +2703,7 @@
|
||||
DC60C6D31F983BB900241271 /* SignatureTests.swift in Sources */,
|
||||
293A45791F296B7E00DD1006 /* MMMarkdownASTTests.swift in Sources */,
|
||||
DC60C6D51F983DF800241271 /* IssueLabelCellTests.swift in Sources */,
|
||||
49FE18FF204B6508001681E8 /* SequenceTests.swift in Sources */,
|
||||
DC5C02C31F9C6D0B00E80B9F /* SearchRecentStoreTests.swift in Sources */,
|
||||
9870B9081FC74E300009719C /* SecretsTests.swift in Sources */,
|
||||
29EDFE7C1F65C580005BCCEB /* SplitViewTests.swift in Sources */,
|
||||
|
||||
76
FreetimeTests/MergeTests.swift
Normal file
76
FreetimeTests/MergeTests.swift
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// MergeTests.swift
|
||||
// FreetimeTests
|
||||
//
|
||||
// Created by Bas Broek on 03/03/2018.
|
||||
// Copyright © 2018 Ryan Nystrom. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import Freetime
|
||||
|
||||
class MergeTests: XCTestCase {
|
||||
|
||||
func test_mergeStatuses_containsOnlyError() {
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.error, .error, .error]).state,
|
||||
.failure)
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.error]).state,
|
||||
.failure)
|
||||
}
|
||||
|
||||
func test_mergeStatuses_containsError() {
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.error, .failure]).state,
|
||||
.failure)
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.error, .pending]).state,
|
||||
.failure)
|
||||
}
|
||||
|
||||
func test_mergeStatuses_containsOnlyFailure() {
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.failure, .failure, .failure]).state,
|
||||
.failure)
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.failure]).state,
|
||||
.failure)
|
||||
}
|
||||
|
||||
func test_mergeStatuses_containsFailure() {
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.failure, .success]).state,
|
||||
.failure)
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.failure, .pending]).state,
|
||||
.failure)
|
||||
}
|
||||
|
||||
func test_mergeStatuses_containsFailure_andError() {
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.error, .failure]).state,
|
||||
.failure)
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.failure, .error]).state,
|
||||
.failure)
|
||||
}
|
||||
|
||||
func test_mergeStatuses_containsPending_butNoErrorOrFailure() {
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.pending, .pending, .pending]).state,
|
||||
.pending)
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.pending, .success]).state,
|
||||
.pending)
|
||||
}
|
||||
|
||||
func test_mergeStatuses_containsOnlySuccess() {
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.success, .success]).state,
|
||||
.success)
|
||||
XCTAssertEqual(
|
||||
MergeHelper.combinedMergeStatus(for: [.success]).state,
|
||||
.success)
|
||||
}
|
||||
}
|
||||
64
FreetimeTests/SequenceTests.swift
Normal file
64
FreetimeTests/SequenceTests.swift
Normal file
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// SequenceTests.swift
|
||||
// FreetimeTests
|
||||
//
|
||||
// Created by Bas Broek on 04/03/2018.
|
||||
// Copyright © 2018 Ryan Nystrom. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import Freetime
|
||||
|
||||
class SequenceTests: XCTestCase {
|
||||
|
||||
func test_containsAll() {
|
||||
XCTAssertTrue(["a", "a", "a"].containsOnly("a"))
|
||||
XCTAssertFalse(["b", "a", "a"].containsOnly("a"))
|
||||
XCTAssertFalse(["a", "a", "a"].containsOnly("b"))
|
||||
|
||||
XCTAssertTrue(["a", "a", "a"].containsOnly { $0 == "a" })
|
||||
XCTAssertFalse(["b", "a", "a"].containsOnly { $0 == "a" })
|
||||
XCTAssertFalse(["a", "a", "a"].containsOnly { $0 == "b" })
|
||||
|
||||
XCTAssertTrue([1, 1, 1].containsOnly(1))
|
||||
XCTAssertFalse([2, 1, 1].containsOnly(1))
|
||||
XCTAssertFalse([1, 1, 1].containsOnly(2))
|
||||
|
||||
XCTAssertTrue([1, 1, 1].containsOnly { $0 == 1 })
|
||||
XCTAssertFalse([2, 1, 1].containsOnly { $0 == 1 })
|
||||
XCTAssertFalse([1, 1, 1].containsOnly { $0 == 2 })
|
||||
}
|
||||
|
||||
func test_containsNone() {
|
||||
XCTAssertFalse(["a", "a", "a"].containsNone("a"))
|
||||
XCTAssertFalse(["b", "a", "a"].containsNone("a"))
|
||||
XCTAssertTrue(["a", "a", "a"].containsNone("b"))
|
||||
|
||||
XCTAssertFalse(["a", "a", "a"].containsNone { $0 == "a" })
|
||||
XCTAssertFalse(["b", "a", "a"].containsNone { $0 == "a" })
|
||||
XCTAssertTrue(["a", "a", "a"].containsNone { $0 == "b" })
|
||||
|
||||
XCTAssertFalse([1, 1, 1].containsNone(1))
|
||||
XCTAssertFalse([2, 1, 1].containsNone(1))
|
||||
XCTAssertTrue([1, 1, 1].containsNone(2))
|
||||
|
||||
XCTAssertFalse([1, 1, 1].containsNone { $0 == 1 })
|
||||
XCTAssertFalse([2, 1, 1].containsNone { $0 == 1 })
|
||||
XCTAssertTrue([1, 1, 1].containsNone { $0 == 2 })
|
||||
}
|
||||
|
||||
func test_emptySequence() {
|
||||
let emptyStrings: [String] = []
|
||||
let emptyInts: [Int] = []
|
||||
|
||||
XCTAssertTrue(emptyStrings.containsNone("a"))
|
||||
XCTAssertTrue(emptyStrings.containsNone { $0 == "a" })
|
||||
XCTAssertFalse(emptyStrings.containsOnly("a"))
|
||||
XCTAssertFalse(emptyStrings.containsOnly { $0 == "a" })
|
||||
|
||||
XCTAssertTrue(emptyInts.containsNone(1))
|
||||
XCTAssertTrue(emptyInts.containsNone { $0 == 1 })
|
||||
XCTAssertFalse(emptyInts.containsOnly(1))
|
||||
XCTAssertFalse(emptyInts.containsOnly { $0 == 1 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user