├── .gitignore ├── .swift-version ├── .travis.yml ├── CheckmarkSegmentedControl.podspec ├── Example ├── CheckmarkSegmentedControl.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── CheckmarkSegmentedControl-Example.xcscheme ├── CheckmarkSegmentedControl.xcworkspace │ └── contents.xcworkspacedata ├── CheckmarkSegmentedControl │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ └── ViewController.swift ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── CheckmarkSegmentedControl.podspec.json │ ├── Manifest.lock │ ├── Nimble │ │ ├── LICENSE.md │ │ ├── README.md │ │ └── Sources │ │ │ ├── Nimble │ │ │ ├── Adapters │ │ │ │ ├── AdapterProtocols.swift │ │ │ │ ├── AssertionDispatcher.swift │ │ │ │ ├── AssertionRecorder.swift │ │ │ │ ├── NMBExpectation.swift │ │ │ │ ├── NMBObjCMatcher.swift │ │ │ │ ├── NimbleEnvironment.swift │ │ │ │ └── NimbleXCTestHandler.swift │ │ │ ├── DSL+Wait.swift │ │ │ ├── DSL.swift │ │ │ ├── Expectation.swift │ │ │ ├── Expression.swift │ │ │ ├── FailureMessage.swift │ │ │ ├── Matchers │ │ │ │ ├── AllPass.swift │ │ │ │ ├── AsyncMatcherWrapper.swift │ │ │ │ ├── BeAKindOf.swift │ │ │ │ ├── BeAnInstanceOf.swift │ │ │ │ ├── BeCloseTo.swift │ │ │ │ ├── BeEmpty.swift │ │ │ │ ├── BeGreaterThan.swift │ │ │ │ ├── BeGreaterThanOrEqualTo.swift │ │ │ │ ├── BeIdenticalTo.swift │ │ │ │ ├── BeLessThan.swift │ │ │ │ ├── BeLessThanOrEqual.swift │ │ │ │ ├── BeLogical.swift │ │ │ │ ├── BeNil.swift │ │ │ │ ├── BeVoid.swift │ │ │ │ ├── BeginWith.swift │ │ │ │ ├── Contain.swift │ │ │ │ ├── EndWith.swift │ │ │ │ ├── Equal.swift │ │ │ │ ├── HaveCount.swift │ │ │ │ ├── Match.swift │ │ │ │ ├── MatchError.swift │ │ │ │ ├── MatcherFunc.swift │ │ │ │ ├── MatcherProtocols.swift │ │ │ │ ├── PostNotification.swift │ │ │ │ ├── RaisesException.swift │ │ │ │ ├── SatisfyAnyOf.swift │ │ │ │ └── ThrowError.swift │ │ │ ├── Nimble.h │ │ │ └── Utils │ │ │ │ ├── Async.swift │ │ │ │ ├── Errors.swift │ │ │ │ ├── Functional.swift │ │ │ │ ├── SourceLocation.swift │ │ │ │ └── Stringers.swift │ │ │ └── NimbleObjectiveC │ │ │ ├── CurrentTestCaseTracker.h │ │ │ ├── DSL.h │ │ │ ├── DSL.m │ │ │ ├── NMBExceptionCapture.h │ │ │ ├── NMBExceptionCapture.m │ │ │ ├── NMBStringify.h │ │ │ ├── NMBStringify.m │ │ │ └── XCTestObservationCenter+Register.m │ ├── Pods.xcodeproj │ │ └── project.pbxproj │ └── Target Support Files │ │ ├── CheckmarkSegmentedControl │ │ ├── CheckmarkSegmentedControl-dummy.m │ │ ├── CheckmarkSegmentedControl-prefix.pch │ │ ├── CheckmarkSegmentedControl-umbrella.h │ │ ├── CheckmarkSegmentedControl.modulemap │ │ ├── CheckmarkSegmentedControl.xcconfig │ │ ├── Info.plist │ │ └── ResourceBundle-CheckmarkSegmentedControl-Info.plist │ │ ├── Nimble │ │ ├── Info.plist │ │ ├── Nimble-dummy.m │ │ ├── Nimble-prefix.pch │ │ ├── Nimble-umbrella.h │ │ ├── Nimble.modulemap │ │ └── Nimble.xcconfig │ │ ├── Pods-CheckmarkSegmentedControl_Example │ │ ├── Info.plist │ │ ├── Pods-CheckmarkSegmentedControl_Example-acknowledgements.markdown │ │ ├── Pods-CheckmarkSegmentedControl_Example-acknowledgements.plist │ │ ├── Pods-CheckmarkSegmentedControl_Example-dummy.m │ │ ├── Pods-CheckmarkSegmentedControl_Example-frameworks.sh │ │ ├── Pods-CheckmarkSegmentedControl_Example-resources.sh │ │ ├── Pods-CheckmarkSegmentedControl_Example-umbrella.h │ │ ├── Pods-CheckmarkSegmentedControl_Example.debug.xcconfig │ │ ├── Pods-CheckmarkSegmentedControl_Example.modulemap │ │ └── Pods-CheckmarkSegmentedControl_Example.release.xcconfig │ │ └── Pods-CheckmarkSegmentedControl_Tests │ │ ├── Info.plist │ │ ├── Pods-CheckmarkSegmentedControl_Tests-acknowledgements.markdown │ │ ├── Pods-CheckmarkSegmentedControl_Tests-acknowledgements.plist │ │ ├── Pods-CheckmarkSegmentedControl_Tests-dummy.m │ │ ├── Pods-CheckmarkSegmentedControl_Tests-frameworks.sh │ │ ├── Pods-CheckmarkSegmentedControl_Tests-resources.sh │ │ ├── Pods-CheckmarkSegmentedControl_Tests-umbrella.h │ │ ├── Pods-CheckmarkSegmentedControl_Tests.debug.xcconfig │ │ ├── Pods-CheckmarkSegmentedControl_Tests.modulemap │ │ └── Pods-CheckmarkSegmentedControl_Tests.release.xcconfig └── Tests │ ├── CheckmarkSegmentedControlTests.swift │ └── Info.plist ├── LICENSE ├── Pod ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ └── CheckmarkSegmentedControl.swift ├── README.md └── preview.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | podfile: Example/Podfile 3 | osx_image: xcode8 4 | before_install: 5 | - gem install cocoapods --pre 6 | - gem install xcpretty --no-rdoc --no-ri --no-document --quiet 7 | script: 8 | - set -o pipefail && xcodebuild test -workspace Example/CheckmarkSegmentedControl.xcworkspace -scheme CheckmarkSegmentedControl-Example -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.0' ONLY_ACTIVE_ARCH=NO | xcpretty -c 9 | - pod lib lint --quick 10 | -------------------------------------------------------------------------------- /CheckmarkSegmentedControl.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "CheckmarkSegmentedControl" 3 | s.version = "0.2.0" 4 | s.summary = "CheckmarkSegmentedControl is a customisable alternative to UISegmentedControl." 5 | s.description = "CheckmarkSegmentedControl is a customisable alternative to UISegmentedControl. Visually it looks like radio buttons group with checkmark sign in the middle and animated border on selection. Each option can be fully customised." 6 | 7 | s.homepage = "https://github.com/gregttn/CheckmarkSegmentedControl" 8 | s.license = 'MIT' 9 | s.author = { "gregttn" => "gregttn@gmail.com" } 10 | s.source = { :git => "https://github.com/gregttn/CheckmarkSegmentedControl.git", :tag => s.version.to_s } 11 | s.social_media_url = 'https://twitter.com/gregttn' 12 | 13 | s.ios.deployment_target = '8.3' 14 | 15 | s.source_files = 'Pod/Classes/*.swift' 16 | end 17 | -------------------------------------------------------------------------------- /Example/CheckmarkSegmentedControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/CheckmarkSegmentedControl.xcodeproj/xcshareddata/xcschemes/CheckmarkSegmentedControl-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /Example/CheckmarkSegmentedControl.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/CheckmarkSegmentedControl/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CheckmarkSegmentedControl 4 | // 5 | // Created by gregttn on 08/20/2015. 6 | // Copyright (c) 2015 gregttn. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/CheckmarkSegmentedControl/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/CheckmarkSegmentedControl/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/CheckmarkSegmentedControl/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/CheckmarkSegmentedControl/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/CheckmarkSegmentedControl/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // CheckmarkSegmentedControl 4 | // 5 | // Created by Grzegorz Tatarzyn on 27/04/2015. 6 | // Copyright (c) 2015 gregttn. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CheckmarkSegmentedControl 11 | 12 | class ViewController: UIViewController { 13 | @IBOutlet weak var checkmark: CheckmarkSegmentedControl! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | // Do any additional setup after loading the view, typically from a nib. 18 | checkmark.options = [ 19 | CheckmarkOption(title:"Option 1"), // by default black border and light gray colour as background 20 | CheckmarkOption(title: "Option 2", borderColor: UIColor.orange, fillColor: UIColor.brown), 21 | CheckmarkOption(title: "Option 3", borderColor: UIColor.brown, fillColor: UIColor.orange), 22 | CheckmarkOption(title: "Option 4", borderColor: UIColor.green, fillColor: UIColor.blue) 23 | ] 24 | 25 | } 26 | 27 | override func didReceiveMemoryWarning() { 28 | super.didReceiveMemoryWarning() 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | @IBAction func optionSelected(_ sender: AnyObject) { 33 | print("Selected option: \(checkmark.options[checkmark.selectedIndex])") 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | use_frameworks! 3 | 4 | target 'CheckmarkSegmentedControl_Example' do 5 | pod 'CheckmarkSegmentedControl', :path => '../' 6 | 7 | target 'CheckmarkSegmentedControl_Tests' do 8 | inherit! :search_paths 9 | pod 'Nimble', '~> 5.0' 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - CheckmarkSegmentedControl (0.1.1) 3 | - Nimble (5.0.0) 4 | 5 | DEPENDENCIES: 6 | - CheckmarkSegmentedControl (from `../`) 7 | - Nimble (~> 5.0) 8 | 9 | EXTERNAL SOURCES: 10 | CheckmarkSegmentedControl: 11 | :path: ../ 12 | 13 | SPEC CHECKSUMS: 14 | CheckmarkSegmentedControl: ce70c9fb699b623cef8e72c2b8578b505fbf2f48 15 | Nimble: 56fc9f5020effa2206de22c3dd910f4fb011b92f 16 | 17 | PODFILE CHECKSUM: b63d85f208ece5f9273f6001eda1394a0b58aeb9 18 | 19 | COCOAPODS: 1.1.0.rc.2 20 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/CheckmarkSegmentedControl.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CheckmarkSegmentedControl", 3 | "version": "0.1.1", 4 | "summary": "CheckmarkSegmentedControl is a customisable alternative to UISegmentedControl.", 5 | "description": "CheckmarkSegmentedControl is a customisable alternative to UISegmentedControl. Visually it looks like radio buttons group with checkmark sign in the middle and animated border on selection. Each option can be fully customised.", 6 | "homepage": "https://github.com/gregttn/CheckmarkSegmentedControl", 7 | "license": "MIT", 8 | "authors": { 9 | "gregttn": "gregttn@gmail.com" 10 | }, 11 | "source": { 12 | "git": "https://github.com/gregttn/CheckmarkSegmentedControl.git", 13 | "tag": "0.1.1" 14 | }, 15 | "social_media_url": "https://twitter.com/gregttn", 16 | "platforms": { 17 | "ios": "9.0" 18 | }, 19 | "requires_arc": true, 20 | "source_files": "Pod/Classes/*.swift", 21 | "resource_bundles": { 22 | "CheckmarkSegmentedControl": [ 23 | "Pod/Assets/*.png" 24 | ] 25 | }, 26 | "frameworks": "UIKit" 27 | } 28 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - CheckmarkSegmentedControl (0.1.1) 3 | - Nimble (5.0.0) 4 | 5 | DEPENDENCIES: 6 | - CheckmarkSegmentedControl (from `../`) 7 | - Nimble (~> 5.0) 8 | 9 | EXTERNAL SOURCES: 10 | CheckmarkSegmentedControl: 11 | :path: ../ 12 | 13 | SPEC CHECKSUMS: 14 | CheckmarkSegmentedControl: ce70c9fb699b623cef8e72c2b8578b505fbf2f48 15 | Nimble: 56fc9f5020effa2206de22c3dd910f4fb011b92f 16 | 17 | PODFILE CHECKSUM: b63d85f208ece5f9273f6001eda1394a0b58aeb9 18 | 19 | COCOAPODS: 1.1.0.rc.2 20 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Adapters/AdapterProtocols.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Protocol for the assertion handler that Nimble uses for all expectations. 4 | public protocol AssertionHandler { 5 | func assert(_ assertion: Bool, message: FailureMessage, location: SourceLocation) 6 | } 7 | 8 | /// Global backing interface for assertions that Nimble creates. 9 | /// Defaults to a private test handler that passes through to XCTest. 10 | /// 11 | /// If XCTest is not available, you must assign your own assertion handler 12 | /// before using any matchers, otherwise Nimble will abort the program. 13 | /// 14 | /// @see AssertionHandler 15 | public var NimbleAssertionHandler: AssertionHandler = { () -> AssertionHandler in 16 | return isXCTestAvailable() ? NimbleXCTestHandler() : NimbleXCTestUnavailableHandler() 17 | }() 18 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Adapters/AssertionDispatcher.swift: -------------------------------------------------------------------------------- 1 | 2 | /// AssertionDispatcher allows multiple AssertionHandlers to receive 3 | /// assertion messages. 4 | /// 5 | /// @warning Does not fully dispatch if one of the handlers raises an exception. 6 | /// This is possible with XCTest-based assertion handlers. 7 | /// 8 | public class AssertionDispatcher: AssertionHandler { 9 | let handlers: [AssertionHandler] 10 | 11 | public init(handlers: [AssertionHandler]) { 12 | self.handlers = handlers 13 | } 14 | 15 | public func assert(_ assertion: Bool, message: FailureMessage, location: SourceLocation) { 16 | for handler in handlers { 17 | handler.assert(assertion, message: message, location: location) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Adapters/AssertionRecorder.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A data structure that stores information about an assertion when 4 | /// AssertionRecorder is set as the Nimble assertion handler. 5 | /// 6 | /// @see AssertionRecorder 7 | /// @see AssertionHandler 8 | public struct AssertionRecord: CustomStringConvertible { 9 | /// Whether the assertion succeeded or failed 10 | public let success: Bool 11 | /// The failure message the assertion would display on failure. 12 | public let message: FailureMessage 13 | /// The source location the expectation occurred on. 14 | public let location: SourceLocation 15 | 16 | public var description: String { 17 | return "AssertionRecord { success=\(success), message='\(message.stringValue)', location=\(location) }" 18 | } 19 | } 20 | 21 | /// An AssertionHandler that silently records assertions that Nimble makes. 22 | /// This is useful for testing failure messages for matchers. 23 | /// 24 | /// @see AssertionHandler 25 | public class AssertionRecorder : AssertionHandler { 26 | /// All the assertions that were captured by this recorder 27 | public var assertions = [AssertionRecord]() 28 | 29 | public init() {} 30 | 31 | public func assert(_ assertion: Bool, message: FailureMessage, location: SourceLocation) { 32 | assertions.append( 33 | AssertionRecord( 34 | success: assertion, 35 | message: message, 36 | location: location)) 37 | } 38 | } 39 | 40 | /// Allows you to temporarily replace the current Nimble assertion handler with 41 | /// the one provided for the scope of the closure. 42 | /// 43 | /// Once the closure finishes, then the original Nimble assertion handler is restored. 44 | /// 45 | /// @see AssertionHandler 46 | public func withAssertionHandler(_ tempAssertionHandler: AssertionHandler, closure: @escaping () throws -> Void) { 47 | let environment = NimbleEnvironment.activeInstance 48 | let oldRecorder = environment.assertionHandler 49 | let capturer = NMBExceptionCapture(handler: nil, finally: ({ 50 | environment.assertionHandler = oldRecorder 51 | })) 52 | environment.assertionHandler = tempAssertionHandler 53 | capturer.tryBlock { 54 | try! closure() 55 | } 56 | } 57 | 58 | /// Captures expectations that occur in the given closure. Note that all 59 | /// expectations will still go through to the default Nimble handler. 60 | /// 61 | /// This can be useful if you want to gather information about expectations 62 | /// that occur within a closure. 63 | /// 64 | /// @param silently expectations are no longer send to the default Nimble 65 | /// assertion handler when this is true. Defaults to false. 66 | /// 67 | /// @see gatherFailingExpectations 68 | public func gatherExpectations(silently: Bool = false, closure: @escaping () -> Void) -> [AssertionRecord] { 69 | let previousRecorder = NimbleEnvironment.activeInstance.assertionHandler 70 | let recorder = AssertionRecorder() 71 | let handlers: [AssertionHandler] 72 | 73 | if silently { 74 | handlers = [recorder] 75 | } else { 76 | handlers = [recorder, previousRecorder] 77 | } 78 | 79 | let dispatcher = AssertionDispatcher(handlers: handlers) 80 | withAssertionHandler(dispatcher, closure: closure) 81 | return recorder.assertions 82 | } 83 | 84 | /// Captures failed expectations that occur in the given closure. Note that all 85 | /// expectations will still go through to the default Nimble handler. 86 | /// 87 | /// This can be useful if you want to gather information about failed 88 | /// expectations that occur within a closure. 89 | /// 90 | /// @param silently expectations are no longer send to the default Nimble 91 | /// assertion handler when this is true. Defaults to false. 92 | /// 93 | /// @see gatherExpectations 94 | /// @see raiseException source for an example use case. 95 | public func gatherFailingExpectations(silently: Bool = false, closure: @escaping () -> Void) -> [AssertionRecord] { 96 | let assertions = gatherExpectations(silently: silently, closure: closure) 97 | return assertions.filter { assertion in 98 | !assertion.success 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Adapters/NMBExpectation.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | #if _runtime(_ObjC) 4 | 5 | internal struct ObjCMatcherWrapper : Matcher { 6 | let matcher: NMBMatcher 7 | 8 | func matches(_ actualExpression: Expression, failureMessage: FailureMessage) -> Bool { 9 | return matcher.matches( 10 | ({ try! actualExpression.evaluate() }), 11 | failureMessage: failureMessage, 12 | location: actualExpression.location) 13 | } 14 | 15 | func doesNotMatch(_ actualExpression: Expression, failureMessage: FailureMessage) -> Bool { 16 | return matcher.doesNotMatch( 17 | ({ try! actualExpression.evaluate() }), 18 | failureMessage: failureMessage, 19 | location: actualExpression.location) 20 | } 21 | } 22 | 23 | // Equivalent to Expectation, but for Nimble's Objective-C interface 24 | public class NMBExpectation : NSObject { 25 | internal let _actualBlock: () -> NSObject! 26 | internal var _negative: Bool 27 | internal let _file: FileString 28 | internal let _line: UInt 29 | internal var _timeout: TimeInterval = 1.0 30 | 31 | public init(actualBlock: @escaping () -> NSObject!, negative: Bool, file: FileString, line: UInt) { 32 | self._actualBlock = actualBlock 33 | self._negative = negative 34 | self._file = file 35 | self._line = line 36 | } 37 | 38 | private var expectValue: Expectation { 39 | return expect(_file, line: _line){ 40 | self._actualBlock() as NSObject? 41 | } 42 | } 43 | 44 | public var withTimeout: (TimeInterval) -> NMBExpectation { 45 | return ({ timeout in self._timeout = timeout 46 | return self 47 | }) 48 | } 49 | 50 | public var to: (NMBMatcher) -> Void { 51 | return ({ matcher in 52 | self.expectValue.to(ObjCMatcherWrapper(matcher: matcher)) 53 | }) 54 | } 55 | 56 | public var toWithDescription: (NMBMatcher, String) -> Void { 57 | return ({ matcher, description in 58 | self.expectValue.to(ObjCMatcherWrapper(matcher: matcher), description: description) 59 | }) 60 | } 61 | 62 | public var toNot: (NMBMatcher) -> Void { 63 | return ({ matcher in 64 | self.expectValue.toNot( 65 | ObjCMatcherWrapper(matcher: matcher) 66 | ) 67 | }) 68 | } 69 | 70 | public var toNotWithDescription: (NMBMatcher, String) -> Void { 71 | return ({ matcher, description in 72 | self.expectValue.toNot( 73 | ObjCMatcherWrapper(matcher: matcher), description: description 74 | ) 75 | }) 76 | } 77 | 78 | public var notTo: (NMBMatcher) -> Void { return toNot } 79 | 80 | public var notToWithDescription: (NMBMatcher, String) -> Void { return toNotWithDescription } 81 | 82 | public var toEventually: (NMBMatcher) -> Void { 83 | return ({ matcher in 84 | self.expectValue.toEventually( 85 | ObjCMatcherWrapper(matcher: matcher), 86 | timeout: self._timeout, 87 | description: nil 88 | ) 89 | }) 90 | } 91 | 92 | public var toEventuallyWithDescription: (NMBMatcher, String) -> Void { 93 | return ({ matcher, description in 94 | self.expectValue.toEventually( 95 | ObjCMatcherWrapper(matcher: matcher), 96 | timeout: self._timeout, 97 | description: description 98 | ) 99 | }) 100 | } 101 | 102 | public var toEventuallyNot: (NMBMatcher) -> Void { 103 | return ({ matcher in 104 | self.expectValue.toEventuallyNot( 105 | ObjCMatcherWrapper(matcher: matcher), 106 | timeout: self._timeout, 107 | description: nil 108 | ) 109 | }) 110 | } 111 | 112 | public var toEventuallyNotWithDescription: (NMBMatcher, String) -> Void { 113 | return ({ matcher, description in 114 | self.expectValue.toEventuallyNot( 115 | ObjCMatcherWrapper(matcher: matcher), 116 | timeout: self._timeout, 117 | description: description 118 | ) 119 | }) 120 | } 121 | 122 | public var toNotEventually: (NMBMatcher) -> Void { return toEventuallyNot } 123 | 124 | public var toNotEventuallyWithDescription: (NMBMatcher, String) -> Void { return toEventuallyNotWithDescription } 125 | 126 | public class func failWithMessage(_ message: String, file: FileString, line: UInt) { 127 | fail(message, location: SourceLocation(file: file, line: line)) 128 | } 129 | } 130 | 131 | #endif 132 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Adapters/NMBObjCMatcher.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | #if _runtime(_ObjC) 4 | 5 | public typealias MatcherBlock = (_ actualExpression: Expression, _ failureMessage: FailureMessage) -> Bool 6 | public typealias FullMatcherBlock = (_ actualExpression: Expression, _ failureMessage: FailureMessage, _ shouldNotMatch: Bool) -> Bool 7 | 8 | public class NMBObjCMatcher : NSObject, NMBMatcher { 9 | let _match: MatcherBlock 10 | let _doesNotMatch: MatcherBlock 11 | let canMatchNil: Bool 12 | 13 | public init(canMatchNil: Bool, matcher: @escaping MatcherBlock, notMatcher: @escaping MatcherBlock) { 14 | self.canMatchNil = canMatchNil 15 | self._match = matcher 16 | self._doesNotMatch = notMatcher 17 | } 18 | 19 | public convenience init(matcher: @escaping MatcherBlock) { 20 | self.init(canMatchNil: true, matcher: matcher) 21 | } 22 | 23 | public convenience init(canMatchNil: Bool, matcher: @escaping MatcherBlock) { 24 | self.init(canMatchNil: canMatchNil, matcher: matcher, notMatcher: ({ actualExpression, failureMessage in 25 | return !matcher(actualExpression, failureMessage) 26 | })) 27 | } 28 | 29 | public convenience init(matcher: @escaping FullMatcherBlock) { 30 | self.init(canMatchNil: true, matcher: matcher) 31 | } 32 | 33 | public convenience init(canMatchNil: Bool, matcher: @escaping FullMatcherBlock) { 34 | self.init(canMatchNil: canMatchNil, matcher: ({ actualExpression, failureMessage in 35 | return matcher(actualExpression, failureMessage, false) 36 | }), notMatcher: ({ actualExpression, failureMessage in 37 | return matcher(actualExpression, failureMessage, true) 38 | })) 39 | } 40 | 41 | private func canMatch(_ actualExpression: Expression, failureMessage: FailureMessage) -> Bool { 42 | do { 43 | if !canMatchNil { 44 | if try actualExpression.evaluate() == nil { 45 | failureMessage.postfixActual = " (use beNil() to match nils)" 46 | return false 47 | } 48 | } 49 | } catch let error { 50 | failureMessage.actualValue = "an unexpected error thrown: \(error)" 51 | return false 52 | } 53 | return true 54 | } 55 | 56 | public func matches(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { 57 | let expr = Expression(expression: actualBlock, location: location) 58 | let result = _match( 59 | expr, 60 | failureMessage) 61 | if self.canMatch(Expression(expression: actualBlock, location: location), failureMessage: failureMessage) { 62 | return result 63 | } else { 64 | return false 65 | } 66 | } 67 | 68 | public func doesNotMatch(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { 69 | let expr = Expression(expression: actualBlock, location: location) 70 | let result = _doesNotMatch( 71 | expr, 72 | failureMessage) 73 | if self.canMatch(Expression(expression: actualBlock, location: location), failureMessage: failureMessage) { 74 | return result 75 | } else { 76 | return false 77 | } 78 | } 79 | } 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// "Global" state of Nimble is stored here. Only DSL functions should access / be aware of this 4 | /// class' existance 5 | internal class NimbleEnvironment { 6 | static var activeInstance: NimbleEnvironment { 7 | get { 8 | let env = Thread.current.threadDictionary["NimbleEnvironment"] 9 | if let env = env as? NimbleEnvironment { 10 | return env 11 | } else { 12 | let newEnv = NimbleEnvironment() 13 | self.activeInstance = newEnv 14 | return newEnv 15 | } 16 | } 17 | set { 18 | Thread.current.threadDictionary["NimbleEnvironment"] = newValue 19 | } 20 | } 21 | 22 | // TODO: eventually migrate the global to this environment value 23 | var assertionHandler: AssertionHandler { 24 | get { return NimbleAssertionHandler } 25 | set { NimbleAssertionHandler = newValue } 26 | } 27 | 28 | #if _runtime(_ObjC) 29 | var awaiter: Awaiter 30 | 31 | init() { 32 | let timeoutQueue: DispatchQueue 33 | if #available(OSX 10.10, *) { 34 | timeoutQueue = DispatchQueue.global(qos: .userInitiated) 35 | } else { 36 | timeoutQueue = DispatchQueue.global(priority: .high) 37 | } 38 | 39 | awaiter = Awaiter( 40 | waitLock: AssertionWaitLock(), 41 | asyncQueue: .main, 42 | timeoutQueue: timeoutQueue) 43 | } 44 | #endif 45 | } 46 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Adapters/NimbleXCTestHandler.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import XCTest 3 | 4 | /// Default handler for Nimble. This assertion handler passes failures along to 5 | /// XCTest. 6 | public class NimbleXCTestHandler : AssertionHandler { 7 | public func assert(_ assertion: Bool, message: FailureMessage, location: SourceLocation) { 8 | if !assertion { 9 | recordFailure("\(message.stringValue)\n", location: location) 10 | } 11 | } 12 | } 13 | 14 | /// Alternative handler for Nimble. This assertion handler passes failures along 15 | /// to XCTest by attempting to reduce the failure message size. 16 | public class NimbleShortXCTestHandler: AssertionHandler { 17 | public func assert(_ assertion: Bool, message: FailureMessage, location: SourceLocation) { 18 | if !assertion { 19 | let msg: String 20 | if let actual = message.actualValue { 21 | msg = "got: \(actual) \(message.postfixActual)" 22 | } else { 23 | msg = "expected \(message.to) \(message.postfixMessage)" 24 | } 25 | recordFailure("\(msg)\n", location: location) 26 | } 27 | } 28 | } 29 | 30 | /// Fallback handler in case XCTest is unavailable. This assertion handler will abort 31 | /// the program if it is invoked. 32 | class NimbleXCTestUnavailableHandler : AssertionHandler { 33 | func assert(_ assertion: Bool, message: FailureMessage, location: SourceLocation) { 34 | fatalError("XCTest is not available and no custom assertion handler was configured. Aborting.") 35 | } 36 | } 37 | 38 | #if _runtime(_ObjC) 39 | /// Helper class providing access to the currently executing XCTestCase instance, if any 40 | @objc final internal class CurrentTestCaseTracker: NSObject, XCTestObservation { 41 | @objc static let sharedInstance = CurrentTestCaseTracker() 42 | 43 | private(set) var currentTestCase: XCTestCase? 44 | 45 | @objc func testCaseWillStart(_ testCase: XCTestCase) { 46 | currentTestCase = testCase 47 | } 48 | 49 | @objc func testCaseDidFinish(_ testCase: XCTestCase) { 50 | currentTestCase = nil 51 | } 52 | } 53 | #endif 54 | 55 | 56 | func isXCTestAvailable() -> Bool { 57 | #if _runtime(_ObjC) 58 | // XCTest is weakly linked and so may not be present 59 | return NSClassFromString("XCTestCase") != nil 60 | #else 61 | return true 62 | #endif 63 | } 64 | 65 | private func recordFailure(_ message: String, location: SourceLocation) { 66 | #if _runtime(_ObjC) 67 | if let testCase = CurrentTestCaseTracker.sharedInstance.currentTestCase { 68 | testCase.recordFailure(withDescription: message, inFile: location.file, atLine: location.line, expected: true) 69 | } else { 70 | let msg = "Attempted to report a test failure to XCTest while no test case was running. " + 71 | "The failure was:\n\"\(message)\"\nIt occurred at: \(location.file):\(location.line)" 72 | NSException(name: .internalInconsistencyException, reason: msg, userInfo: nil).raise() 73 | } 74 | #else 75 | XCTFail("\(message)\n", file: location.file, line: location.line) 76 | #endif 77 | } 78 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/DSL+Wait.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | #if _runtime(_ObjC) 4 | private enum ErrorResult { 5 | case exception(NSException) 6 | case error(Error) 7 | case none 8 | } 9 | 10 | /// Only classes, protocols, methods, properties, and subscript declarations can be 11 | /// bridges to Objective-C via the @objc keyword. This class encapsulates callback-style 12 | /// asynchronous waiting logic so that it may be called from Objective-C and Swift. 13 | internal class NMBWait: NSObject { 14 | internal class func until( 15 | timeout: TimeInterval, 16 | file: FileString = #file, 17 | line: UInt = #line, 18 | action: @escaping (@escaping () -> Void) -> Void) -> Void { 19 | return throwableUntil(timeout: timeout, file: file, line: line) { done in 20 | action(done) 21 | } 22 | } 23 | 24 | // Using a throwable closure makes this method not objc compatible. 25 | internal class func throwableUntil( 26 | timeout: TimeInterval, 27 | file: FileString = #file, 28 | line: UInt = #line, 29 | action: @escaping (@escaping () -> Void) throws -> Void) -> Void { 30 | let awaiter = NimbleEnvironment.activeInstance.awaiter 31 | let leeway = timeout / 2.0 32 | let result = awaiter.performBlock { (done: @escaping (ErrorResult) -> Void) throws -> Void in 33 | DispatchQueue.main.async { 34 | let capture = NMBExceptionCapture( 35 | handler: ({ exception in 36 | done(.exception(exception)) 37 | }), 38 | finally: ({ }) 39 | ) 40 | capture.tryBlock { 41 | do { 42 | try action() { 43 | done(.none) 44 | } 45 | } catch let e { 46 | done(.error(e)) 47 | } 48 | } 49 | } 50 | }.timeout(timeout, forcefullyAbortTimeout: leeway).wait("waitUntil(...)", file: file, line: line) 51 | 52 | switch result { 53 | case .incomplete: internalError("Reached .incomplete state for waitUntil(...).") 54 | case .blockedRunLoop: 55 | fail(blockedRunLoopErrorMessageFor("-waitUntil()", leeway: leeway), 56 | file: file, line: line) 57 | case .timedOut: 58 | let pluralize = (timeout == 1 ? "" : "s") 59 | fail("Waited more than \(timeout) second\(pluralize)", file: file, line: line) 60 | case let .raisedException(exception): 61 | fail("Unexpected exception raised: \(exception)") 62 | case let .errorThrown(error): 63 | fail("Unexpected error thrown: \(error)") 64 | case .completed(.exception(let exception)): 65 | fail("Unexpected exception raised: \(exception)") 66 | case .completed(.error(let error)): 67 | fail("Unexpected error thrown: \(error)") 68 | case .completed(.none): // success 69 | break 70 | } 71 | } 72 | 73 | @objc(untilFile:line:action:) 74 | internal class func until(_ file: FileString = #file, line: UInt = #line, action: @escaping (() -> Void) -> Void) -> Void { 75 | until(timeout: 1, file: file, line: line, action: action) 76 | } 77 | } 78 | 79 | internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: TimeInterval) -> String { 80 | return "\(fnName) timed out but was unable to run the timeout handler because the main thread is unresponsive (\(leeway) seconds is allow after the wait times out). Conditions that may cause this include processing blocking IO on the main thread, calls to sleep(), deadlocks, and synchronous IPC. Nimble forcefully stopped run loop which may cause future failures in test run." 81 | } 82 | 83 | /// Wait asynchronously until the done closure is called or the timeout has been reached. 84 | /// 85 | /// @discussion 86 | /// Call the done() closure to indicate the waiting has completed. 87 | /// 88 | /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function 89 | /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. 90 | public func waitUntil(timeout: TimeInterval = 1, file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) -> Void { 91 | NMBWait.until(timeout: timeout, file: file, line: line, action: action) 92 | } 93 | #endif 94 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/DSL.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Make an expectation on a given actual value. The value given is lazily evaluated. 4 | public func expect(_ expression: @autoclosure @escaping () throws -> T?, file: FileString = #file, line: UInt = #line) -> Expectation { 5 | return Expectation( 6 | expression: Expression( 7 | expression: expression, 8 | location: SourceLocation(file: file, line: line), 9 | isClosure: true)) 10 | } 11 | 12 | /// Make an expectation on a given actual value. The closure is lazily invoked. 13 | public func expect(_ file: FileString = #file, line: UInt = #line, expression: @escaping () throws -> T?) -> Expectation { 14 | return Expectation( 15 | expression: Expression( 16 | expression: expression, 17 | location: SourceLocation(file: file, line: line), 18 | isClosure: true)) 19 | } 20 | 21 | /// Always fails the test with a message and a specified location. 22 | public func fail(_ message: String, location: SourceLocation) { 23 | let handler = NimbleEnvironment.activeInstance.assertionHandler 24 | handler.assert(false, message: FailureMessage(stringValue: message), location: location) 25 | } 26 | 27 | /// Always fails the test with a message. 28 | public func fail(_ message: String, file: FileString = #file, line: UInt = #line) { 29 | fail(message, location: SourceLocation(file: file, line: line)) 30 | } 31 | 32 | /// Always fails the test. 33 | public func fail(_ file: FileString = #file, line: UInt = #line) { 34 | fail("fail() always fails", file: file, line: line) 35 | } 36 | 37 | /// Like Swift's precondition(), but raises NSExceptions instead of sigaborts 38 | internal func nimblePrecondition( 39 | _ expr: @autoclosure() -> Bool, 40 | _ name: @autoclosure() -> String, 41 | _ message: @autoclosure() -> String, 42 | file: StaticString = #file, 43 | line: UInt = #line) { 44 | let result = expr() 45 | if !result { 46 | #if _runtime(_ObjC) 47 | let e = NSException( 48 | name: NSExceptionName(name()), 49 | reason: message(), 50 | userInfo: nil) 51 | e.raise() 52 | #else 53 | preconditionFailure("\(name()) - \(message())", file: file, line: line) 54 | #endif 55 | } 56 | } 57 | 58 | internal func internalError(_ msg: String, file: FileString = #file, line: UInt = #line) -> Never { 59 | fatalError( 60 | "Nimble Bug Found: \(msg) at \(file):\(line).\n" + 61 | "Please file a bug to Nimble: https://github.com/Quick/Nimble/issues with the " + 62 | "code snippet that caused this error." 63 | ) 64 | } 65 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Expectation.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | internal func expressionMatches(_ expression: Expression, matcher: U, to: String, description: String?) -> (Bool, FailureMessage) 4 | where U: Matcher, U.ValueType == T 5 | { 6 | let msg = FailureMessage() 7 | msg.userDescription = description 8 | msg.to = to 9 | do { 10 | let pass = try matcher.matches(expression, failureMessage: msg) 11 | if msg.actualValue == "" { 12 | msg.actualValue = "<\(stringify(try expression.evaluate()))>" 13 | } 14 | return (pass, msg) 15 | } catch let error { 16 | msg.actualValue = "an unexpected error thrown: <\(error)>" 17 | return (false, msg) 18 | } 19 | } 20 | 21 | internal func expressionDoesNotMatch(_ expression: Expression, matcher: U, toNot: String, description: String?) -> (Bool, FailureMessage) 22 | where U: Matcher, U.ValueType == T 23 | { 24 | let msg = FailureMessage() 25 | msg.userDescription = description 26 | msg.to = toNot 27 | do { 28 | let pass = try matcher.doesNotMatch(expression, failureMessage: msg) 29 | if msg.actualValue == "" { 30 | msg.actualValue = "<\(stringify(try expression.evaluate()))>" 31 | } 32 | return (pass, msg) 33 | } catch let error { 34 | msg.actualValue = "an unexpected error thrown: <\(error)>" 35 | return (false, msg) 36 | } 37 | } 38 | 39 | public struct Expectation { 40 | 41 | public let expression: Expression 42 | 43 | public func verify(_ pass: Bool, _ message: FailureMessage) { 44 | let handler = NimbleEnvironment.activeInstance.assertionHandler 45 | handler.assert(pass, message: message, location: expression.location) 46 | } 47 | 48 | /// Tests the actual value using a matcher to match. 49 | public func to(_ matcher: U, description: String? = nil) 50 | where U: Matcher, U.ValueType == T 51 | { 52 | let (pass, msg) = expressionMatches(expression, matcher: matcher, to: "to", description: description) 53 | verify(pass, msg) 54 | } 55 | 56 | /// Tests the actual value using a matcher to not match. 57 | public func toNot(_ matcher: U, description: String? = nil) 58 | where U: Matcher, U.ValueType == T 59 | { 60 | let (pass, msg) = expressionDoesNotMatch(expression, matcher: matcher, toNot: "to not", description: description) 61 | verify(pass, msg) 62 | } 63 | 64 | /// Tests the actual value using a matcher to not match. 65 | /// 66 | /// Alias to toNot(). 67 | public func notTo(_ matcher: U, description: String? = nil) 68 | where U: Matcher, U.ValueType == T 69 | { 70 | toNot(matcher, description: description) 71 | } 72 | 73 | // see: 74 | // - AsyncMatcherWrapper for extension 75 | // - NMBExpectation for Objective-C interface 76 | } 77 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Expression.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // Memoizes the given closure, only calling the passed 4 | // closure once; even if repeat calls to the returned closure 5 | internal func memoizedClosure(_ closure: @escaping () throws -> T) -> (Bool) throws -> T { 6 | var cache: T? 7 | return ({ withoutCaching in 8 | if (withoutCaching || cache == nil) { 9 | cache = try closure() 10 | } 11 | return cache! 12 | }) 13 | } 14 | 15 | /// Expression represents the closure of the value inside expect(...). 16 | /// Expressions are memoized by default. This makes them safe to call 17 | /// evaluate() multiple times without causing a re-evaluation of the underlying 18 | /// closure. 19 | /// 20 | /// @warning Since the closure can be any code, Objective-C code may choose 21 | /// to raise an exception. Currently, Expression does not memoize 22 | /// exception raising. 23 | /// 24 | /// This provides a common consumable API for matchers to utilize to allow 25 | /// Nimble to change internals to how the captured closure is managed. 26 | public struct Expression { 27 | internal let _expression: (Bool) throws -> T? 28 | internal let _withoutCaching: Bool 29 | public let location: SourceLocation 30 | public let isClosure: Bool 31 | 32 | /// Creates a new expression struct. Normally, expect(...) will manage this 33 | /// creation process. The expression is memoized. 34 | /// 35 | /// @param expression The closure that produces a given value. 36 | /// @param location The source location that this closure originates from. 37 | /// @param isClosure A bool indicating if the captured expression is a 38 | /// closure or internally produced closure. Some matchers 39 | /// may require closures. For example, toEventually() 40 | /// requires an explicit closure. This gives Nimble 41 | /// flexibility if @autoclosure behavior changes between 42 | /// Swift versions. Nimble internals always sets this true. 43 | public init(expression: @escaping () throws -> T?, location: SourceLocation, isClosure: Bool = true) { 44 | self._expression = memoizedClosure(expression) 45 | self.location = location 46 | self._withoutCaching = false 47 | self.isClosure = isClosure 48 | } 49 | 50 | /// Creates a new expression struct. Normally, expect(...) will manage this 51 | /// creation process. 52 | /// 53 | /// @param expression The closure that produces a given value. 54 | /// @param location The source location that this closure originates from. 55 | /// @param withoutCaching Indicates if the struct should memoize the given 56 | /// closure's result. Subsequent evaluate() calls will 57 | /// not call the given closure if this is true. 58 | /// @param isClosure A bool indicating if the captured expression is a 59 | /// closure or internally produced closure. Some matchers 60 | /// may require closures. For example, toEventually() 61 | /// requires an explicit closure. This gives Nimble 62 | /// flexibility if @autoclosure behavior changes between 63 | /// Swift versions. Nimble internals always sets this true. 64 | public init(memoizedExpression: @escaping (Bool) throws -> T?, location: SourceLocation, withoutCaching: Bool, isClosure: Bool = true) { 65 | self._expression = memoizedExpression 66 | self.location = location 67 | self._withoutCaching = withoutCaching 68 | self.isClosure = isClosure 69 | } 70 | 71 | /// Returns a new Expression from the given expression. Identical to a map() 72 | /// on this type. This should be used only to typecast the Expression's 73 | /// closure value. 74 | /// 75 | /// The returned expression will preserve location and isClosure. 76 | /// 77 | /// @param block The block that can cast the current Expression value to a 78 | /// new type. 79 | public func cast(_ block: @escaping (T?) throws -> U?) -> Expression { 80 | return Expression(expression: ({ try block(self.evaluate()) }), location: self.location, isClosure: self.isClosure) 81 | } 82 | 83 | public func evaluate() throws -> T? { 84 | return try self._expression(_withoutCaching) 85 | } 86 | 87 | public func withoutCaching() -> Expression { 88 | return Expression(memoizedExpression: self._expression, location: location, withoutCaching: true, isClosure: isClosure) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/FailureMessage.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Encapsulates the failure message that matchers can report to the end user. 4 | /// 5 | /// This is shared state between Nimble and matchers that mutate this value. 6 | public class FailureMessage: NSObject { 7 | public var expected: String = "expected" 8 | public var actualValue: String? = "" // empty string -> use default; nil -> exclude 9 | public var to: String = "to" 10 | public var postfixMessage: String = "match" 11 | public var postfixActual: String = "" 12 | /// An optional message that will be appended as a new line and provides additional details 13 | /// about the failure. This message will only be visible in the issue navigator / in logs but 14 | /// not directly in the source editor since only a single line is presented there. 15 | public var extendedMessage: String? = nil 16 | public var userDescription: String? = nil 17 | 18 | public var stringValue: String { 19 | get { 20 | if let value = _stringValueOverride { 21 | return value 22 | } else { 23 | return computeStringValue() 24 | } 25 | } 26 | set { 27 | _stringValueOverride = newValue 28 | } 29 | } 30 | 31 | internal var _stringValueOverride: String? 32 | 33 | public override init() { 34 | } 35 | 36 | public init(stringValue: String) { 37 | _stringValueOverride = stringValue 38 | } 39 | 40 | internal func stripNewlines(_ str: String) -> String { 41 | let whitespaces = CharacterSet.whitespacesAndNewlines 42 | return str 43 | .components(separatedBy: "\n") 44 | .map { line in line.trimmingCharacters(in: whitespaces) } 45 | .joined(separator: "") 46 | } 47 | 48 | internal func computeStringValue() -> String { 49 | var value = "\(expected) \(to) \(postfixMessage)" 50 | if let actualValue = actualValue { 51 | value = "\(expected) \(to) \(postfixMessage), got \(actualValue)\(postfixActual)" 52 | } 53 | value = stripNewlines(value) 54 | 55 | if let extendedMessage = extendedMessage { 56 | value += "\n\(stripNewlines(extendedMessage))" 57 | } 58 | 59 | if let userDescription = userDescription { 60 | return "\(userDescription)\n\(value)" 61 | } 62 | 63 | return value 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/AllPass.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public func allPass 4 | (_ passFunc: @escaping (T?) -> Bool) -> NonNilMatcherFunc 5 | where U: Sequence, U.Iterator.Element == T 6 | { 7 | return allPass("pass a condition", passFunc) 8 | } 9 | 10 | public func allPass 11 | (_ passName: String, _ passFunc: @escaping (T?) -> Bool) -> NonNilMatcherFunc 12 | where U: Sequence, U.Iterator.Element == T 13 | { 14 | return createAllPassMatcher() { 15 | expression, failureMessage in 16 | failureMessage.postfixMessage = passName 17 | return passFunc(try expression.evaluate()) 18 | } 19 | } 20 | 21 | public func allPass 22 | (_ matcher: V) -> NonNilMatcherFunc 23 | where U: Sequence, V: Matcher, U.Iterator.Element == V.ValueType 24 | { 25 | return createAllPassMatcher() { 26 | try matcher.matches($0, failureMessage: $1) 27 | } 28 | } 29 | 30 | private func createAllPassMatcher 31 | (_ elementEvaluator: @escaping (Expression, FailureMessage) throws -> Bool) -> NonNilMatcherFunc 32 | where U: Sequence, U.Iterator.Element == T 33 | { 34 | return NonNilMatcherFunc { actualExpression, failureMessage in 35 | failureMessage.actualValue = nil 36 | if let actualValue = try actualExpression.evaluate() { 37 | for currentElement in actualValue { 38 | let exp = Expression( 39 | expression: {currentElement}, location: actualExpression.location) 40 | if try !elementEvaluator(exp, failureMessage) { 41 | failureMessage.postfixMessage = 42 | "all \(failureMessage.postfixMessage)," 43 | + " but failed first at element <\(stringify(currentElement))>" 44 | + " in <\(stringify(actualValue))>" 45 | return false 46 | } 47 | } 48 | failureMessage.postfixMessage = "all \(failureMessage.postfixMessage)" 49 | } else { 50 | failureMessage.postfixMessage = "all pass (use beNil() to match nils)" 51 | return false 52 | } 53 | 54 | return true 55 | } 56 | } 57 | 58 | #if _runtime(_ObjC) 59 | extension NMBObjCMatcher { 60 | public class func allPassMatcher(_ matcher: NMBObjCMatcher) -> NMBObjCMatcher { 61 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 62 | let location = actualExpression.location 63 | let actualValue = try! actualExpression.evaluate() 64 | var nsObjects = [NSObject]() 65 | 66 | var collectionIsUsable = true 67 | if let value = actualValue as? NSFastEnumeration { 68 | let generator = NSFastEnumerationIterator(value) 69 | while let obj = generator.next() { 70 | if let nsObject = obj as? NSObject { 71 | nsObjects.append(nsObject) 72 | } else { 73 | collectionIsUsable = false 74 | break 75 | } 76 | } 77 | } else { 78 | collectionIsUsable = false 79 | } 80 | 81 | if !collectionIsUsable { 82 | failureMessage.postfixMessage = 83 | "allPass only works with NSFastEnumeration (NSArray, NSSet, ...) of NSObjects" 84 | failureMessage.expected = "" 85 | failureMessage.to = "" 86 | return false 87 | } 88 | 89 | let expr = Expression(expression: ({ nsObjects }), location: location) 90 | let elementEvaluator: (Expression, FailureMessage) -> Bool = { 91 | expression, failureMessage in 92 | return matcher.matches( 93 | {try! expression.evaluate()}, failureMessage: failureMessage, location: expr.location) 94 | } 95 | return try! createAllPassMatcher(elementEvaluator).matches( 96 | expr, failureMessage: failureMessage) 97 | } 98 | } 99 | } 100 | #endif 101 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | #if _runtime(_ObjC) 4 | 5 | public struct AsyncDefaults { 6 | public static var Timeout: TimeInterval = 1 7 | public static var PollInterval: TimeInterval = 0.01 8 | } 9 | 10 | internal struct AsyncMatcherWrapper: Matcher 11 | where U: Matcher, U.ValueType == T 12 | { 13 | let fullMatcher: U 14 | let timeoutInterval: TimeInterval 15 | let pollInterval: TimeInterval 16 | 17 | init(fullMatcher: U, timeoutInterval: TimeInterval = AsyncDefaults.Timeout, pollInterval: TimeInterval = AsyncDefaults.PollInterval) { 18 | self.fullMatcher = fullMatcher 19 | self.timeoutInterval = timeoutInterval 20 | self.pollInterval = pollInterval 21 | } 22 | 23 | func matches(_ actualExpression: Expression, failureMessage: FailureMessage) -> Bool { 24 | let uncachedExpression = actualExpression.withoutCaching() 25 | let fnName = "expect(...).toEventually(...)" 26 | let result = pollBlock( 27 | pollInterval: pollInterval, 28 | timeoutInterval: timeoutInterval, 29 | file: actualExpression.location.file, 30 | line: actualExpression.location.line, 31 | fnName: fnName) { 32 | try self.fullMatcher.matches(uncachedExpression, failureMessage: failureMessage) 33 | } 34 | switch (result) { 35 | case let .completed(isSuccessful): return isSuccessful 36 | case .timedOut: return false 37 | case let .errorThrown(error): 38 | failureMessage.actualValue = "an unexpected error thrown: <\(error)>" 39 | return false 40 | case let .raisedException(exception): 41 | failureMessage.actualValue = "an unexpected exception thrown: <\(exception)>" 42 | return false 43 | case .blockedRunLoop: 44 | failureMessage.postfixMessage += " (timed out, but main thread was unresponsive)." 45 | return false 46 | case .incomplete: 47 | internalError("Reached .incomplete state for toEventually(...).") 48 | } 49 | } 50 | 51 | func doesNotMatch(_ actualExpression: Expression, failureMessage: FailureMessage) -> Bool { 52 | let uncachedExpression = actualExpression.withoutCaching() 53 | let result = pollBlock( 54 | pollInterval: pollInterval, 55 | timeoutInterval: timeoutInterval, 56 | file: actualExpression.location.file, 57 | line: actualExpression.location.line, 58 | fnName: "expect(...).toEventuallyNot(...)") { 59 | try self.fullMatcher.doesNotMatch(uncachedExpression, failureMessage: failureMessage) 60 | } 61 | switch (result) { 62 | case let .completed(isSuccessful): return isSuccessful 63 | case .timedOut: return false 64 | case let .errorThrown(error): 65 | failureMessage.actualValue = "an unexpected error thrown: <\(error)>" 66 | return false 67 | case let .raisedException(exception): 68 | failureMessage.actualValue = "an unexpected exception thrown: <\(exception)>" 69 | return false 70 | case .blockedRunLoop: 71 | failureMessage.postfixMessage += " (timed out, but main thread was unresponsive)." 72 | return false 73 | case .incomplete: 74 | internalError("Reached .incomplete state for toEventuallyNot(...).") 75 | } 76 | } 77 | } 78 | 79 | private let toEventuallyRequiresClosureError = FailureMessage(stringValue: "expect(...).toEventually(...) requires an explicit closure (eg - expect { ... }.toEventually(...) )\nSwift 1.2 @autoclosure behavior has changed in an incompatible way for Nimble to function") 80 | 81 | 82 | extension Expectation { 83 | /// Tests the actual value using a matcher to match by checking continuously 84 | /// at each pollInterval until the timeout is reached. 85 | /// 86 | /// @discussion 87 | /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function 88 | /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. 89 | public func toEventually(_ matcher: U, timeout: TimeInterval = AsyncDefaults.Timeout, pollInterval: TimeInterval = AsyncDefaults.PollInterval, description: String? = nil) 90 | where U: Matcher, U.ValueType == T 91 | { 92 | if expression.isClosure { 93 | let (pass, msg) = expressionMatches( 94 | expression, 95 | matcher: AsyncMatcherWrapper( 96 | fullMatcher: matcher, 97 | timeoutInterval: timeout, 98 | pollInterval: pollInterval), 99 | to: "to eventually", 100 | description: description 101 | ) 102 | verify(pass, msg) 103 | } else { 104 | verify(false, toEventuallyRequiresClosureError) 105 | } 106 | } 107 | 108 | /// Tests the actual value using a matcher to not match by checking 109 | /// continuously at each pollInterval until the timeout is reached. 110 | /// 111 | /// @discussion 112 | /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function 113 | /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. 114 | public func toEventuallyNot(_ matcher: U, timeout: TimeInterval = AsyncDefaults.Timeout, pollInterval: TimeInterval = AsyncDefaults.PollInterval, description: String? = nil) 115 | where U: Matcher, U.ValueType == T 116 | { 117 | if expression.isClosure { 118 | let (pass, msg) = expressionDoesNotMatch( 119 | expression, 120 | matcher: AsyncMatcherWrapper( 121 | fullMatcher: matcher, 122 | timeoutInterval: timeout, 123 | pollInterval: pollInterval), 124 | toNot: "to eventually not", 125 | description: description 126 | ) 127 | verify(pass, msg) 128 | } else { 129 | verify(false, toEventuallyRequiresClosureError) 130 | } 131 | } 132 | 133 | /// Tests the actual value using a matcher to not match by checking 134 | /// continuously at each pollInterval until the timeout is reached. 135 | /// 136 | /// Alias of toEventuallyNot() 137 | /// 138 | /// @discussion 139 | /// This function manages the main run loop (`NSRunLoop.mainRunLoop()`) while this function 140 | /// is executing. Any attempts to touch the run loop may cause non-deterministic behavior. 141 | public func toNotEventually(_ matcher: U, timeout: TimeInterval = AsyncDefaults.Timeout, pollInterval: TimeInterval = AsyncDefaults.PollInterval, description: String? = nil) 142 | where U: Matcher, U.ValueType == T 143 | { 144 | return toEventuallyNot(matcher, timeout: timeout, pollInterval: pollInterval, description: description) 145 | } 146 | } 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeAKindOf.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | #if _runtime(_ObjC) 4 | 5 | // A Nimble matcher that catches attempts to use beAKindOf with non Objective-C types 6 | public func beAKindOf(_ expectedClass: Any) -> NonNilMatcherFunc { 7 | return NonNilMatcherFunc {actualExpression, failureMessage in 8 | failureMessage.stringValue = "beAKindOf only works on Objective-C types since" 9 | + " the Swift compiler will automatically type check Swift-only types." 10 | + " This expectation is redundant." 11 | return false 12 | } 13 | } 14 | 15 | /// A Nimble matcher that succeeds when the actual value is an instance of the given class. 16 | /// @see beAnInstanceOf if you want to match against the exact class 17 | public func beAKindOf(_ expectedClass: AnyClass) -> NonNilMatcherFunc { 18 | return NonNilMatcherFunc { actualExpression, failureMessage in 19 | let instance = try actualExpression.evaluate() 20 | if let validInstance = instance { 21 | failureMessage.actualValue = "<\(String(describing: type(of: validInstance))) instance>" 22 | } else { 23 | failureMessage.actualValue = "" 24 | } 25 | failureMessage.postfixMessage = "be a kind of \(String(describing: expectedClass))" 26 | return instance != nil && instance!.isKind(of: expectedClass) 27 | } 28 | } 29 | 30 | extension NMBObjCMatcher { 31 | public class func beAKindOfMatcher(_ expected: AnyClass) -> NMBMatcher { 32 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 33 | return try! beAKindOf(expected).matches(actualExpression, failureMessage: failureMessage) 34 | } 35 | } 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeAnInstanceOf.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // A Nimble matcher that catches attempts to use beAnInstanceOf with non Objective-C types 4 | public func beAnInstanceOf(_ expectedClass: Any) -> NonNilMatcherFunc { 5 | return NonNilMatcherFunc {actualExpression, failureMessage in 6 | failureMessage.stringValue = "beAnInstanceOf only works on Objective-C types since" 7 | + " the Swift compiler will automatically type check Swift-only types." 8 | + " This expectation is redundant." 9 | return false 10 | } 11 | } 12 | 13 | /// A Nimble matcher that succeeds when the actual value is an instance of the given class. 14 | /// @see beAKindOf if you want to match against subclasses 15 | public func beAnInstanceOf(_ expectedClass: AnyClass) -> NonNilMatcherFunc { 16 | return NonNilMatcherFunc { actualExpression, failureMessage in 17 | let instance = try actualExpression.evaluate() 18 | if let validInstance = instance { 19 | failureMessage.actualValue = "<\(String(describing: type(of: validInstance))) instance>" 20 | } else { 21 | failureMessage.actualValue = "" 22 | } 23 | failureMessage.postfixMessage = "be an instance of \(String(describing: expectedClass))" 24 | #if _runtime(_ObjC) 25 | return instance != nil && instance!.isMember(of: expectedClass) 26 | #else 27 | return instance != nil && type(of: instance!) == expectedClass 28 | #endif 29 | } 30 | } 31 | 32 | #if _runtime(_ObjC) 33 | extension NMBObjCMatcher { 34 | public class func beAnInstanceOfMatcher(_ expected: AnyClass) -> NMBMatcher { 35 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 36 | return try! beAnInstanceOf(expected).matches(actualExpression, failureMessage: failureMessage) 37 | } 38 | } 39 | } 40 | #endif 41 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeCloseTo.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | internal let DefaultDelta = 0.0001 4 | 5 | internal func isCloseTo(_ actualValue: NMBDoubleConvertible?, expectedValue: NMBDoubleConvertible, delta: Double, failureMessage: FailureMessage) -> Bool { 6 | failureMessage.postfixMessage = "be close to <\(stringify(expectedValue))> (within \(stringify(delta)))" 7 | failureMessage.actualValue = "<\(stringify(actualValue))>" 8 | return actualValue != nil && abs(actualValue!.doubleValue - expectedValue.doubleValue) < delta 9 | } 10 | 11 | /// A Nimble matcher that succeeds when a value is close to another. This is used for floating 12 | /// point values which can have imprecise results when doing arithmetic on them. 13 | /// 14 | /// @see equal 15 | public func beCloseTo(_ expectedValue: Double, within delta: Double = DefaultDelta) -> NonNilMatcherFunc { 16 | return NonNilMatcherFunc { actualExpression, failureMessage in 17 | return isCloseTo(try actualExpression.evaluate(), expectedValue: expectedValue, delta: delta, failureMessage: failureMessage) 18 | } 19 | } 20 | 21 | /// A Nimble matcher that succeeds when a value is close to another. This is used for floating 22 | /// point values which can have imprecise results when doing arithmetic on them. 23 | /// 24 | /// @see equal 25 | public func beCloseTo(_ expectedValue: NMBDoubleConvertible, within delta: Double = DefaultDelta) -> NonNilMatcherFunc { 26 | return NonNilMatcherFunc { actualExpression, failureMessage in 27 | return isCloseTo(try actualExpression.evaluate(), expectedValue: expectedValue, delta: delta, failureMessage: failureMessage) 28 | } 29 | } 30 | 31 | #if _runtime(_ObjC) 32 | public class NMBObjCBeCloseToMatcher : NSObject, NMBMatcher { 33 | var _expected: NSNumber 34 | var _delta: CDouble 35 | init(expected: NSNumber, within: CDouble) { 36 | _expected = expected 37 | _delta = within 38 | } 39 | 40 | public func matches(_ actualExpression: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { 41 | let actualBlock: () -> NMBDoubleConvertible? = ({ 42 | return actualExpression() as? NMBDoubleConvertible 43 | }) 44 | let expr = Expression(expression: actualBlock, location: location) 45 | let matcher = beCloseTo(self._expected, within: self._delta) 46 | return try! matcher.matches(expr, failureMessage: failureMessage) 47 | } 48 | 49 | public func doesNotMatch(_ actualExpression: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { 50 | let actualBlock: () -> NMBDoubleConvertible? = ({ 51 | return actualExpression() as? NMBDoubleConvertible 52 | }) 53 | let expr = Expression(expression: actualBlock, location: location) 54 | let matcher = beCloseTo(self._expected, within: self._delta) 55 | return try! matcher.doesNotMatch(expr, failureMessage: failureMessage) 56 | } 57 | 58 | public var within: (CDouble) -> NMBObjCBeCloseToMatcher { 59 | return ({ delta in 60 | return NMBObjCBeCloseToMatcher(expected: self._expected, within: delta) 61 | }) 62 | } 63 | } 64 | 65 | extension NMBObjCMatcher { 66 | public class func beCloseToMatcher(_ expected: NSNumber, within: CDouble) -> NMBObjCBeCloseToMatcher { 67 | return NMBObjCBeCloseToMatcher(expected: expected, within: within) 68 | } 69 | } 70 | #endif 71 | 72 | public func beCloseTo(_ expectedValues: [Double], within delta: Double = DefaultDelta) -> NonNilMatcherFunc <[Double]> { 73 | return NonNilMatcherFunc { actualExpression, failureMessage in 74 | failureMessage.postfixMessage = "be close to <\(stringify(expectedValues))> (each within \(stringify(delta)))" 75 | if let actual = try actualExpression.evaluate() { 76 | failureMessage.actualValue = "<\(stringify(actual))>" 77 | 78 | if actual.count != expectedValues.count { 79 | return false 80 | } else { 81 | for (index, actualItem) in actual.enumerated() { 82 | if fabs(actualItem - expectedValues[index]) > delta { 83 | return false 84 | } 85 | } 86 | return true 87 | } 88 | } 89 | return false 90 | } 91 | } 92 | 93 | // MARK: - Operators 94 | 95 | infix operator ≈ : ComparisonPrecedence 96 | 97 | public func ≈(lhs: Expectation<[Double]>, rhs: [Double]) { 98 | lhs.to(beCloseTo(rhs)) 99 | } 100 | 101 | public func ≈(lhs: Expectation, rhs: NMBDoubleConvertible) { 102 | lhs.to(beCloseTo(rhs)) 103 | } 104 | 105 | public func ≈(lhs: Expectation, rhs: (expected: NMBDoubleConvertible, delta: Double)) { 106 | lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) 107 | } 108 | 109 | public func ==(lhs: Expectation, rhs: (expected: NMBDoubleConvertible, delta: Double)) { 110 | lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) 111 | } 112 | 113 | // make this higher precedence than exponents so the Doubles either end aren't pulled in 114 | // unexpectantly 115 | precedencegroup PlusMinusOperatorPrecedence { 116 | higherThan: BitwiseShiftPrecedence 117 | } 118 | 119 | infix operator ± : PlusMinusOperatorPrecedence 120 | public func ±(lhs: NMBDoubleConvertible, rhs: Double) -> (expected: NMBDoubleConvertible, delta: Double) { 121 | return (expected: lhs, delta: rhs) 122 | } 123 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeEmpty.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | /// A Nimble matcher that succeeds when a value is "empty". For collections, this 5 | /// means the are no items in that collection. For strings, it is an empty string. 6 | public func beEmpty() -> NonNilMatcherFunc { 7 | return NonNilMatcherFunc { actualExpression, failureMessage in 8 | failureMessage.postfixMessage = "be empty" 9 | let actualSeq = try actualExpression.evaluate() 10 | if actualSeq == nil { 11 | return true 12 | } 13 | var generator = actualSeq!.makeIterator() 14 | return generator.next() == nil 15 | } 16 | } 17 | 18 | /// A Nimble matcher that succeeds when a value is "empty". For collections, this 19 | /// means the are no items in that collection. For strings, it is an empty string. 20 | public func beEmpty() -> NonNilMatcherFunc { 21 | return NonNilMatcherFunc { actualExpression, failureMessage in 22 | failureMessage.postfixMessage = "be empty" 23 | let actualString = try actualExpression.evaluate() 24 | return actualString == nil || NSString(string: actualString!).length == 0 25 | } 26 | } 27 | 28 | /// A Nimble matcher that succeeds when a value is "empty". For collections, this 29 | /// means the are no items in that collection. For NSString instances, it is an empty string. 30 | public func beEmpty() -> NonNilMatcherFunc { 31 | return NonNilMatcherFunc { actualExpression, failureMessage in 32 | failureMessage.postfixMessage = "be empty" 33 | let actualString = try actualExpression.evaluate() 34 | return actualString == nil || actualString!.length == 0 35 | } 36 | } 37 | 38 | // Without specific overrides, beEmpty() is ambiguous for NSDictionary, NSArray, 39 | // etc, since they conform to Sequence as well as NMBCollection. 40 | 41 | /// A Nimble matcher that succeeds when a value is "empty". For collections, this 42 | /// means the are no items in that collection. For strings, it is an empty string. 43 | public func beEmpty() -> NonNilMatcherFunc { 44 | return NonNilMatcherFunc { actualExpression, failureMessage in 45 | failureMessage.postfixMessage = "be empty" 46 | let actualDictionary = try actualExpression.evaluate() 47 | return actualDictionary == nil || actualDictionary!.count == 0 48 | } 49 | } 50 | 51 | /// A Nimble matcher that succeeds when a value is "empty". For collections, this 52 | /// means the are no items in that collection. For strings, it is an empty string. 53 | public func beEmpty() -> NonNilMatcherFunc { 54 | return NonNilMatcherFunc { actualExpression, failureMessage in 55 | failureMessage.postfixMessage = "be empty" 56 | let actualArray = try actualExpression.evaluate() 57 | return actualArray == nil || actualArray!.count == 0 58 | } 59 | } 60 | 61 | /// A Nimble matcher that succeeds when a value is "empty". For collections, this 62 | /// means the are no items in that collection. For strings, it is an empty string. 63 | public func beEmpty() -> NonNilMatcherFunc { 64 | return NonNilMatcherFunc { actualExpression, failureMessage in 65 | failureMessage.postfixMessage = "be empty" 66 | let actual = try actualExpression.evaluate() 67 | return actual == nil || actual!.count == 0 68 | } 69 | } 70 | 71 | #if _runtime(_ObjC) 72 | extension NMBObjCMatcher { 73 | public class func beEmptyMatcher() -> NMBObjCMatcher { 74 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 75 | let location = actualExpression.location 76 | let actualValue = try! actualExpression.evaluate() 77 | failureMessage.postfixMessage = "be empty" 78 | if let value = actualValue as? NMBCollection { 79 | let expr = Expression(expression: ({ value as NMBCollection }), location: location) 80 | return try! beEmpty().matches(expr, failureMessage: failureMessage) 81 | } else if let value = actualValue as? NSString { 82 | let expr = Expression(expression: ({ value as String }), location: location) 83 | return try! beEmpty().matches(expr, failureMessage: failureMessage) 84 | } else if let actualValue = actualValue { 85 | failureMessage.postfixMessage = "be empty (only works for NSArrays, NSSets, NSIndexSets, NSDictionaries, NSHashTables, and NSStrings)" 86 | failureMessage.actualValue = "\(String(describing: type(of: actualValue))) type" 87 | } 88 | return false 89 | } 90 | } 91 | } 92 | #endif 93 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThan.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | /// A Nimble matcher that succeeds when the actual value is greater than the expected value. 5 | public func beGreaterThan(_ expectedValue: T?) -> NonNilMatcherFunc { 6 | return NonNilMatcherFunc { actualExpression, failureMessage in 7 | failureMessage.postfixMessage = "be greater than <\(stringify(expectedValue))>" 8 | if let actual = try actualExpression.evaluate(), let expected = expectedValue { 9 | return actual > expected 10 | } 11 | return false 12 | } 13 | } 14 | 15 | /// A Nimble matcher that succeeds when the actual value is greater than the expected value. 16 | public func beGreaterThan(_ expectedValue: NMBComparable?) -> NonNilMatcherFunc { 17 | return NonNilMatcherFunc { actualExpression, failureMessage in 18 | failureMessage.postfixMessage = "be greater than <\(stringify(expectedValue))>" 19 | let actualValue = try actualExpression.evaluate() 20 | let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) == ComparisonResult.orderedDescending 21 | return matches 22 | } 23 | } 24 | 25 | public func >(lhs: Expectation, rhs: T) { 26 | lhs.to(beGreaterThan(rhs)) 27 | } 28 | 29 | public func >(lhs: Expectation, rhs: NMBComparable?) { 30 | lhs.to(beGreaterThan(rhs)) 31 | } 32 | 33 | #if _runtime(_ObjC) 34 | extension NMBObjCMatcher { 35 | public class func beGreaterThanMatcher(_ expected: NMBComparable?) -> NMBObjCMatcher { 36 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 37 | let expr = actualExpression.cast { $0 as? NMBComparable } 38 | return try! beGreaterThan(expected).matches(expr, failureMessage: failureMessage) 39 | } 40 | } 41 | } 42 | #endif 43 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThanOrEqualTo.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is greater than 4 | /// or equal to the expected value. 5 | public func beGreaterThanOrEqualTo(_ expectedValue: T?) -> NonNilMatcherFunc { 6 | return NonNilMatcherFunc { actualExpression, failureMessage in 7 | failureMessage.postfixMessage = "be greater than or equal to <\(stringify(expectedValue))>" 8 | let actualValue = try actualExpression.evaluate() 9 | if let actual = actualValue, let expected = expectedValue { 10 | return actual >= expected 11 | } 12 | return false 13 | } 14 | } 15 | 16 | /// A Nimble matcher that succeeds when the actual value is greater than 17 | /// or equal to the expected value. 18 | public func beGreaterThanOrEqualTo(_ expectedValue: T?) -> NonNilMatcherFunc { 19 | return NonNilMatcherFunc { actualExpression, failureMessage in 20 | failureMessage.postfixMessage = "be greater than or equal to <\(stringify(expectedValue))>" 21 | let actualValue = try actualExpression.evaluate() 22 | let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) != ComparisonResult.orderedAscending 23 | return matches 24 | } 25 | } 26 | 27 | public func >=(lhs: Expectation, rhs: T) { 28 | lhs.to(beGreaterThanOrEqualTo(rhs)) 29 | } 30 | 31 | public func >=(lhs: Expectation, rhs: T) { 32 | lhs.to(beGreaterThanOrEqualTo(rhs)) 33 | } 34 | 35 | #if _runtime(_ObjC) 36 | extension NMBObjCMatcher { 37 | public class func beGreaterThanOrEqualToMatcher(_ expected: NMBComparable?) -> NMBObjCMatcher { 38 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 39 | let expr = actualExpression.cast { $0 as? NMBComparable } 40 | return try! beGreaterThanOrEqualTo(expected).matches(expr, failureMessage: failureMessage) 41 | } 42 | } 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeIdenticalTo.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | /// A Nimble matcher that succeeds when the actual value is the same instance 5 | /// as the expected instance. 6 | public func beIdenticalTo(_ expected: Any?) -> NonNilMatcherFunc { 7 | return NonNilMatcherFunc { actualExpression, failureMessage in 8 | #if os(Linux) 9 | let actual = try actualExpression.evaluate() as? AnyObject 10 | #else 11 | let actual = try actualExpression.evaluate() as AnyObject? 12 | #endif 13 | failureMessage.actualValue = "\(identityAsString(actual))" 14 | failureMessage.postfixMessage = "be identical to \(identityAsString(expected))" 15 | #if os(Linux) 16 | return actual === (expected as? AnyObject) && actual !== nil 17 | #else 18 | return actual === (expected as AnyObject?) && actual !== nil 19 | #endif 20 | } 21 | } 22 | 23 | public func ===(lhs: Expectation, rhs: Any?) { 24 | lhs.to(beIdenticalTo(rhs)) 25 | } 26 | public func !==(lhs: Expectation, rhs: Any?) { 27 | lhs.toNot(beIdenticalTo(rhs)) 28 | } 29 | 30 | /// A Nimble matcher that succeeds when the actual value is the same instance 31 | /// as the expected instance. 32 | /// 33 | /// Alias for "beIdenticalTo". 34 | public func be(_ expected: Any?) -> NonNilMatcherFunc { 35 | return beIdenticalTo(expected) 36 | } 37 | 38 | #if _runtime(_ObjC) 39 | extension NMBObjCMatcher { 40 | public class func beIdenticalToMatcher(_ expected: NSObject?) -> NMBObjCMatcher { 41 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 42 | let aExpr = actualExpression.cast { $0 as Any? } 43 | return try! beIdenticalTo(expected).matches(aExpr, failureMessage: failureMessage) 44 | } 45 | } 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeLessThan.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is less than the expected value. 4 | public func beLessThan(_ expectedValue: T?) -> NonNilMatcherFunc { 5 | return NonNilMatcherFunc { actualExpression, failureMessage in 6 | failureMessage.postfixMessage = "be less than <\(stringify(expectedValue))>" 7 | if let actual = try actualExpression.evaluate(), let expected = expectedValue { 8 | return actual < expected 9 | } 10 | return false 11 | } 12 | } 13 | 14 | /// A Nimble matcher that succeeds when the actual value is less than the expected value. 15 | public func beLessThan(_ expectedValue: NMBComparable?) -> NonNilMatcherFunc { 16 | return NonNilMatcherFunc { actualExpression, failureMessage in 17 | failureMessage.postfixMessage = "be less than <\(stringify(expectedValue))>" 18 | let actualValue = try actualExpression.evaluate() 19 | let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) == ComparisonResult.orderedAscending 20 | return matches 21 | } 22 | } 23 | 24 | public func <(lhs: Expectation, rhs: T) { 25 | lhs.to(beLessThan(rhs)) 26 | } 27 | 28 | public func <(lhs: Expectation, rhs: NMBComparable?) { 29 | lhs.to(beLessThan(rhs)) 30 | } 31 | 32 | #if _runtime(_ObjC) 33 | extension NMBObjCMatcher { 34 | public class func beLessThanMatcher(_ expected: NMBComparable?) -> NMBObjCMatcher { 35 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 36 | let expr = actualExpression.cast { $0 as! NMBComparable? } 37 | return try! beLessThan(expected).matches(expr, failureMessage: failureMessage) 38 | } 39 | } 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeLessThanOrEqual.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is less than 4 | /// or equal to the expected value. 5 | public func beLessThanOrEqualTo(_ expectedValue: T?) -> NonNilMatcherFunc { 6 | return NonNilMatcherFunc { actualExpression, failureMessage in 7 | failureMessage.postfixMessage = "be less than or equal to <\(stringify(expectedValue))>" 8 | if let actual = try actualExpression.evaluate(), let expected = expectedValue { 9 | return actual <= expected 10 | } 11 | return false 12 | } 13 | } 14 | 15 | /// A Nimble matcher that succeeds when the actual value is less than 16 | /// or equal to the expected value. 17 | public func beLessThanOrEqualTo(_ expectedValue: T?) -> NonNilMatcherFunc { 18 | return NonNilMatcherFunc { actualExpression, failureMessage in 19 | failureMessage.postfixMessage = "be less than or equal to <\(stringify(expectedValue))>" 20 | let actualValue = try actualExpression.evaluate() 21 | return actualValue != nil && actualValue!.NMB_compare(expectedValue) != ComparisonResult.orderedDescending 22 | } 23 | } 24 | 25 | public func <=(lhs: Expectation, rhs: T) { 26 | lhs.to(beLessThanOrEqualTo(rhs)) 27 | } 28 | 29 | public func <=(lhs: Expectation, rhs: T) { 30 | lhs.to(beLessThanOrEqualTo(rhs)) 31 | } 32 | 33 | #if _runtime(_ObjC) 34 | extension NMBObjCMatcher { 35 | public class func beLessThanOrEqualToMatcher(_ expected: NMBComparable?) -> NMBObjCMatcher { 36 | return NMBObjCMatcher(canMatchNil:false) { actualExpression, failureMessage in 37 | let expr = actualExpression.cast { $0 as? NMBComparable } 38 | return try! beLessThanOrEqualTo(expected).matches(expr, failureMessage: failureMessage) 39 | } 40 | } 41 | } 42 | #endif 43 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeLogical.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Int8: ExpressibleByBooleanLiteral { 4 | public init(booleanLiteral value: Bool) { 5 | self = NSNumber(value: value).int8Value 6 | } 7 | } 8 | 9 | extension UInt8: ExpressibleByBooleanLiteral { 10 | public init(booleanLiteral value: Bool) { 11 | self = NSNumber(value: value).uint8Value 12 | } 13 | } 14 | 15 | extension Int16: ExpressibleByBooleanLiteral { 16 | public init(booleanLiteral value: Bool) { 17 | self = NSNumber(value: value).int16Value 18 | } 19 | } 20 | 21 | extension UInt16: ExpressibleByBooleanLiteral { 22 | public init(booleanLiteral value: Bool) { 23 | self = NSNumber(value: value).uint16Value 24 | } 25 | } 26 | 27 | extension Int32: ExpressibleByBooleanLiteral { 28 | public init(booleanLiteral value: Bool) { 29 | self = NSNumber(value: value).int32Value 30 | } 31 | } 32 | 33 | extension UInt32: ExpressibleByBooleanLiteral { 34 | public init(booleanLiteral value: Bool) { 35 | self = NSNumber(value: value).uint32Value 36 | } 37 | } 38 | 39 | extension Int64: ExpressibleByBooleanLiteral { 40 | public init(booleanLiteral value: Bool) { 41 | self = NSNumber(value: value).int64Value 42 | } 43 | } 44 | 45 | extension UInt64: ExpressibleByBooleanLiteral { 46 | public init(booleanLiteral value: Bool) { 47 | self = NSNumber(value: value).uint64Value 48 | } 49 | } 50 | 51 | extension Float: ExpressibleByBooleanLiteral { 52 | public init(booleanLiteral value: Bool) { 53 | self = NSNumber(value: value).floatValue 54 | } 55 | } 56 | 57 | extension Double: ExpressibleByBooleanLiteral { 58 | public init(booleanLiteral value: Bool) { 59 | self = NSNumber(value: value).doubleValue 60 | } 61 | } 62 | 63 | extension Int: ExpressibleByBooleanLiteral { 64 | public init(booleanLiteral value: Bool) { 65 | self = NSNumber(value: value).intValue 66 | } 67 | } 68 | 69 | extension UInt: ExpressibleByBooleanLiteral { 70 | public init(booleanLiteral value: Bool) { 71 | self = NSNumber(value: value).uintValue 72 | } 73 | } 74 | 75 | internal func matcherWithFailureMessage(_ matcher: NonNilMatcherFunc, postprocessor: @escaping (FailureMessage) -> Void) -> NonNilMatcherFunc { 76 | return NonNilMatcherFunc { actualExpression, failureMessage in 77 | defer { postprocessor(failureMessage) } 78 | return try matcher.matcher(actualExpression, failureMessage) 79 | } 80 | } 81 | 82 | // MARK: beTrue() / beFalse() 83 | 84 | /// A Nimble matcher that succeeds when the actual value is exactly true. 85 | /// This matcher will not match against nils. 86 | public func beTrue() -> NonNilMatcherFunc { 87 | return matcherWithFailureMessage(equal(true)) { failureMessage in 88 | failureMessage.postfixMessage = "be true" 89 | } 90 | } 91 | 92 | /// A Nimble matcher that succeeds when the actual value is exactly false. 93 | /// This matcher will not match against nils. 94 | public func beFalse() -> NonNilMatcherFunc { 95 | return matcherWithFailureMessage(equal(false)) { failureMessage in 96 | failureMessage.postfixMessage = "be false" 97 | } 98 | } 99 | 100 | // MARK: beTruthy() / beFalsy() 101 | 102 | /// A Nimble matcher that succeeds when the actual value is not logically false. 103 | public func beTruthy() -> MatcherFunc { 104 | return MatcherFunc { actualExpression, failureMessage in 105 | failureMessage.postfixMessage = "be truthy" 106 | let actualValue = try actualExpression.evaluate() 107 | if let actualValue = actualValue { 108 | // FIXME: This is a workaround to SR-2290. 109 | // See: 110 | // - https://bugs.swift.org/browse/SR-2290 111 | // - https://github.com/norio-nomura/Nimble/pull/5#issuecomment-237835873 112 | if let number = actualValue as? NSNumber { 113 | return number.boolValue == true 114 | } 115 | 116 | return actualValue == (true as T) 117 | } 118 | return actualValue != nil 119 | } 120 | } 121 | 122 | /// A Nimble matcher that succeeds when the actual value is logically false. 123 | /// This matcher will match against nils. 124 | public func beFalsy() -> MatcherFunc { 125 | return MatcherFunc { actualExpression, failureMessage in 126 | failureMessage.postfixMessage = "be falsy" 127 | let actualValue = try actualExpression.evaluate() 128 | if let actualValue = actualValue { 129 | // FIXME: This is a workaround to SR-2290. 130 | // See: 131 | // - https://bugs.swift.org/browse/SR-2290 132 | // - https://github.com/norio-nomura/Nimble/pull/5#issuecomment-237835873 133 | if let number = actualValue as? NSNumber { 134 | return number.boolValue == false 135 | } 136 | 137 | return actualValue == (false as T) 138 | } 139 | return actualValue == nil 140 | } 141 | } 142 | 143 | #if _runtime(_ObjC) 144 | extension NMBObjCMatcher { 145 | public class func beTruthyMatcher() -> NMBObjCMatcher { 146 | return NMBObjCMatcher { actualExpression, failureMessage in 147 | let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as Bool? } 148 | return try! beTruthy().matches(expr, failureMessage: failureMessage) 149 | } 150 | } 151 | 152 | public class func beFalsyMatcher() -> NMBObjCMatcher { 153 | return NMBObjCMatcher { actualExpression, failureMessage in 154 | let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as Bool? } 155 | return try! beFalsy().matches(expr, failureMessage: failureMessage) 156 | } 157 | } 158 | 159 | public class func beTrueMatcher() -> NMBObjCMatcher { 160 | return NMBObjCMatcher { actualExpression, failureMessage in 161 | let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as Bool? } 162 | return try! beTrue().matches(expr, failureMessage: failureMessage) 163 | } 164 | } 165 | 166 | public class func beFalseMatcher() -> NMBObjCMatcher { 167 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 168 | let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as Bool? } 169 | return try! beFalse().matches(expr, failureMessage: failureMessage) 170 | } 171 | } 172 | } 173 | #endif 174 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeNil.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is nil. 4 | public func beNil() -> MatcherFunc { 5 | return MatcherFunc { actualExpression, failureMessage in 6 | failureMessage.postfixMessage = "be nil" 7 | let actualValue = try actualExpression.evaluate() 8 | return actualValue == nil 9 | } 10 | } 11 | 12 | #if _runtime(_ObjC) 13 | extension NMBObjCMatcher { 14 | public class func beNilMatcher() -> NMBObjCMatcher { 15 | return NMBObjCMatcher { actualExpression, failureMessage in 16 | return try! beNil().matches(actualExpression, failureMessage: failureMessage) 17 | } 18 | } 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeVoid.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is Void. 4 | public func beVoid() -> MatcherFunc<()> { 5 | return MatcherFunc { actualExpression, failureMessage in 6 | failureMessage.postfixMessage = "be void" 7 | let actualValue: ()? = try actualExpression.evaluate() 8 | return actualValue != nil 9 | } 10 | } 11 | 12 | public func ==(lhs: Expectation<()>, rhs: ()) { 13 | lhs.to(beVoid()) 14 | } 15 | 16 | public func !=(lhs: Expectation<()>, rhs: ()) { 17 | lhs.toNot(beVoid()) 18 | } -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/BeginWith.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | /// A Nimble matcher that succeeds when the actual sequence's first element 5 | /// is equal to the expected value. 6 | public func beginWith(_ startingElement: T) -> NonNilMatcherFunc 7 | where S.Iterator.Element == T 8 | { 9 | return NonNilMatcherFunc { actualExpression, failureMessage in 10 | failureMessage.postfixMessage = "begin with <\(startingElement)>" 11 | if let actualValue = try actualExpression.evaluate() { 12 | var actualGenerator = actualValue.makeIterator() 13 | return actualGenerator.next() == startingElement 14 | } 15 | return false 16 | } 17 | } 18 | 19 | /// A Nimble matcher that succeeds when the actual collection's first element 20 | /// is equal to the expected object. 21 | public func beginWith(_ startingElement: Any) -> NonNilMatcherFunc { 22 | return NonNilMatcherFunc { actualExpression, failureMessage in 23 | failureMessage.postfixMessage = "begin with <\(startingElement)>" 24 | guard let collection = try actualExpression.evaluate() else { return false } 25 | guard collection.count > 0 else { return false } 26 | #if os(Linux) 27 | guard let collectionValue = collection.object(at: 0) as? NSObject else { 28 | return false 29 | } 30 | #else 31 | let collectionValue = collection.object(at: 0) as AnyObject 32 | #endif 33 | return collectionValue.isEqual(startingElement) 34 | } 35 | } 36 | 37 | /// A Nimble matcher that succeeds when the actual string contains expected substring 38 | /// where the expected substring's location is zero. 39 | public func beginWith(_ startingSubstring: String) -> NonNilMatcherFunc { 40 | return NonNilMatcherFunc { actualExpression, failureMessage in 41 | failureMessage.postfixMessage = "begin with <\(startingSubstring)>" 42 | if let actual = try actualExpression.evaluate() { 43 | let range = actual.range(of: startingSubstring) 44 | return range != nil && range!.lowerBound == actual.startIndex 45 | } 46 | return false 47 | } 48 | } 49 | 50 | #if _runtime(_ObjC) 51 | extension NMBObjCMatcher { 52 | public class func beginWithMatcher(_ expected: Any) -> NMBObjCMatcher { 53 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 54 | let actual = try! actualExpression.evaluate() 55 | if let _ = actual as? String { 56 | let expr = actualExpression.cast { $0 as? String } 57 | return try! beginWith(expected as! String).matches(expr, failureMessage: failureMessage) 58 | } else { 59 | let expr = actualExpression.cast { $0 as? NMBOrderedCollection } 60 | return try! beginWith(expected).matches(expr, failureMessage: failureMessage) 61 | } 62 | } 63 | } 64 | } 65 | #endif 66 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/Contain.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual sequence contains the expected value. 4 | public func contain(_ items: T...) -> NonNilMatcherFunc 5 | where S.Iterator.Element == T 6 | { 7 | return contain(items) 8 | } 9 | 10 | public func contain(_ items: [T]) -> NonNilMatcherFunc 11 | where S.Iterator.Element == T 12 | { 13 | return NonNilMatcherFunc { actualExpression, failureMessage in 14 | failureMessage.postfixMessage = "contain <\(arrayAsString(items))>" 15 | if let actual = try actualExpression.evaluate() { 16 | return items.all { 17 | return actual.contains($0) 18 | } 19 | } 20 | return false 21 | } 22 | } 23 | 24 | /// A Nimble matcher that succeeds when the actual string contains the expected substring. 25 | public func contain(_ substrings: String...) -> NonNilMatcherFunc { 26 | return contain(substrings) 27 | } 28 | 29 | public func contain(_ substrings: [String]) -> NonNilMatcherFunc { 30 | return NonNilMatcherFunc { actualExpression, failureMessage in 31 | failureMessage.postfixMessage = "contain <\(arrayAsString(substrings))>" 32 | if let actual = try actualExpression.evaluate() { 33 | return substrings.all { 34 | let range = actual.range(of: $0) 35 | return range != nil && !range!.isEmpty 36 | } 37 | } 38 | return false 39 | } 40 | } 41 | 42 | /// A Nimble matcher that succeeds when the actual string contains the expected substring. 43 | public func contain(_ substrings: NSString...) -> NonNilMatcherFunc { 44 | return contain(substrings) 45 | } 46 | 47 | public func contain(_ substrings: [NSString]) -> NonNilMatcherFunc { 48 | return NonNilMatcherFunc { actualExpression, failureMessage in 49 | failureMessage.postfixMessage = "contain <\(arrayAsString(substrings))>" 50 | if let actual = try actualExpression.evaluate() { 51 | return substrings.all { actual.range(of: $0.description).length != 0 } 52 | } 53 | return false 54 | } 55 | } 56 | 57 | /// A Nimble matcher that succeeds when the actual collection contains the expected object. 58 | public func contain(_ items: Any?...) -> NonNilMatcherFunc { 59 | return contain(items) 60 | } 61 | 62 | public func contain(_ items: [Any?]) -> NonNilMatcherFunc { 63 | return NonNilMatcherFunc { actualExpression, failureMessage in 64 | failureMessage.postfixMessage = "contain <\(arrayAsString(items))>" 65 | guard let actual = try actualExpression.evaluate() else { return false } 66 | return items.all { item in 67 | return item != nil && actual.contains(item!) 68 | } 69 | } 70 | } 71 | 72 | #if _runtime(_ObjC) 73 | extension NMBObjCMatcher { 74 | public class func containMatcher(_ expected: [NSObject]) -> NMBObjCMatcher { 75 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 76 | let location = actualExpression.location 77 | let actualValue = try! actualExpression.evaluate() 78 | if let value = actualValue as? NMBContainer { 79 | let expr = Expression(expression: ({ value as NMBContainer }), location: location) 80 | 81 | // A straightforward cast on the array causes this to crash, so we have to cast the individual items 82 | let expectedOptionals: [Any?] = expected.map({ $0 as Any? }) 83 | return try! contain(expectedOptionals).matches(expr, failureMessage: failureMessage) 84 | } else if let value = actualValue as? NSString { 85 | let expr = Expression(expression: ({ value as String }), location: location) 86 | return try! contain(expected as! [String]).matches(expr, failureMessage: failureMessage) 87 | } else if actualValue != nil { 88 | failureMessage.postfixMessage = "contain <\(arrayAsString(expected))> (only works for NSArrays, NSSets, NSHashTables, and NSStrings)" 89 | } else { 90 | failureMessage.postfixMessage = "contain <\(arrayAsString(expected))>" 91 | } 92 | return false 93 | } 94 | } 95 | } 96 | #endif 97 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/EndWith.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | 4 | /// A Nimble matcher that succeeds when the actual sequence's last element 5 | /// is equal to the expected value. 6 | public func endWith(_ endingElement: T) -> NonNilMatcherFunc 7 | where S.Iterator.Element == T 8 | { 9 | return NonNilMatcherFunc { actualExpression, failureMessage in 10 | failureMessage.postfixMessage = "end with <\(endingElement)>" 11 | 12 | if let actualValue = try actualExpression.evaluate() { 13 | var actualGenerator = actualValue.makeIterator() 14 | var lastItem: T? 15 | var item: T? 16 | repeat { 17 | lastItem = item 18 | item = actualGenerator.next() 19 | } while(item != nil) 20 | 21 | return lastItem == endingElement 22 | } 23 | return false 24 | } 25 | } 26 | 27 | /// A Nimble matcher that succeeds when the actual collection's last element 28 | /// is equal to the expected object. 29 | public func endWith(_ endingElement: Any) -> NonNilMatcherFunc { 30 | return NonNilMatcherFunc { actualExpression, failureMessage in 31 | failureMessage.postfixMessage = "end with <\(endingElement)>" 32 | guard let collection = try actualExpression.evaluate() else { return false } 33 | guard collection.count > 0 else { return false } 34 | #if os(Linux) 35 | guard let collectionValue = collection.object(at: collection.count - 1) as? NSObject else { 36 | return false 37 | } 38 | #else 39 | let collectionValue = collection.object(at: collection.count - 1) as AnyObject 40 | #endif 41 | 42 | return collectionValue.isEqual(endingElement) 43 | } 44 | } 45 | 46 | 47 | /// A Nimble matcher that succeeds when the actual string contains the expected substring 48 | /// where the expected substring's location is the actual string's length minus the 49 | /// expected substring's length. 50 | public func endWith(_ endingSubstring: String) -> NonNilMatcherFunc { 51 | return NonNilMatcherFunc { actualExpression, failureMessage in 52 | failureMessage.postfixMessage = "end with <\(endingSubstring)>" 53 | if let collection = try actualExpression.evaluate() { 54 | return collection.hasSuffix(endingSubstring) 55 | } 56 | return false 57 | } 58 | } 59 | 60 | #if _runtime(_ObjC) 61 | extension NMBObjCMatcher { 62 | public class func endWithMatcher(_ expected: Any) -> NMBObjCMatcher { 63 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 64 | let actual = try! actualExpression.evaluate() 65 | if let _ = actual as? String { 66 | let expr = actualExpression.cast { $0 as? String } 67 | return try! endWith(expected as! String).matches(expr, failureMessage: failureMessage) 68 | } else { 69 | let expr = actualExpression.cast { $0 as? NMBOrderedCollection } 70 | return try! endWith(expected).matches(expr, failureMessage: failureMessage) 71 | } 72 | } 73 | } 74 | } 75 | #endif 76 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/Equal.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is equal to the expected value. 4 | /// Values can support equal by supporting the Equatable protocol. 5 | /// 6 | /// @see beCloseTo if you want to match imprecise types (eg - floats, doubles). 7 | public func equal(_ expectedValue: T?) -> NonNilMatcherFunc { 8 | return NonNilMatcherFunc { actualExpression, failureMessage in 9 | failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>" 10 | let actualValue = try actualExpression.evaluate() 11 | let matches = actualValue == expectedValue && expectedValue != nil 12 | if expectedValue == nil || actualValue == nil { 13 | if expectedValue == nil { 14 | failureMessage.postfixActual = " (use beNil() to match nils)" 15 | } 16 | return false 17 | } 18 | return matches 19 | } 20 | } 21 | 22 | /// A Nimble matcher that succeeds when the actual value is equal to the expected value. 23 | /// Values can support equal by supporting the Equatable protocol. 24 | /// 25 | /// @see beCloseTo if you want to match imprecise types (eg - floats, doubles). 26 | public func equal(_ expectedValue: [T: C]?) -> NonNilMatcherFunc<[T: C]> { 27 | return NonNilMatcherFunc { actualExpression, failureMessage in 28 | failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>" 29 | let actualValue = try actualExpression.evaluate() 30 | if expectedValue == nil || actualValue == nil { 31 | if expectedValue == nil { 32 | failureMessage.postfixActual = " (use beNil() to match nils)" 33 | } 34 | return false 35 | } 36 | return expectedValue! == actualValue! 37 | } 38 | } 39 | 40 | /// A Nimble matcher that succeeds when the actual collection is equal to the expected collection. 41 | /// Items must implement the Equatable protocol. 42 | public func equal(_ expectedValue: [T]?) -> NonNilMatcherFunc<[T]> { 43 | return NonNilMatcherFunc { actualExpression, failureMessage in 44 | failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>" 45 | let actualValue = try actualExpression.evaluate() 46 | if expectedValue == nil || actualValue == nil { 47 | if expectedValue == nil { 48 | failureMessage.postfixActual = " (use beNil() to match nils)" 49 | } 50 | return false 51 | } 52 | return expectedValue! == actualValue! 53 | } 54 | } 55 | 56 | /// A Nimble matcher allowing comparison of collection with optional type 57 | public func equal(_ expectedValue: [T?]) -> NonNilMatcherFunc<[T?]> { 58 | return NonNilMatcherFunc { actualExpression, failureMessage in 59 | failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>" 60 | if let actualValue = try actualExpression.evaluate() { 61 | if expectedValue.count != actualValue.count { 62 | return false 63 | } 64 | 65 | for (index, item) in actualValue.enumerated() { 66 | let otherItem = expectedValue[index] 67 | if item == nil && otherItem == nil { 68 | continue 69 | } else if item == nil && otherItem != nil { 70 | return false 71 | } else if item != nil && otherItem == nil { 72 | return false 73 | } else if item! != otherItem! { 74 | return false 75 | } 76 | } 77 | 78 | return true 79 | } else { 80 | failureMessage.postfixActual = " (use beNil() to match nils)" 81 | } 82 | 83 | return false 84 | } 85 | } 86 | 87 | /// A Nimble matcher that succeeds when the actual set is equal to the expected set. 88 | public func equal(_ expectedValue: Set?) -> NonNilMatcherFunc> { 89 | return equal(expectedValue, stringify: { stringify($0) }) 90 | } 91 | 92 | /// A Nimble matcher that succeeds when the actual set is equal to the expected set. 93 | public func equal(_ expectedValue: Set?) -> NonNilMatcherFunc> { 94 | return equal(expectedValue, stringify: { 95 | if let set = $0 { 96 | return stringify(Array(set).sorted { $0 < $1 }) 97 | } else { 98 | return "nil" 99 | } 100 | }) 101 | } 102 | 103 | private func equal(_ expectedValue: Set?, stringify: @escaping (Set?) -> String) -> NonNilMatcherFunc> { 104 | return NonNilMatcherFunc { actualExpression, failureMessage in 105 | failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>" 106 | 107 | if let expectedValue = expectedValue { 108 | if let actualValue = try actualExpression.evaluate() { 109 | failureMessage.actualValue = "<\(stringify(actualValue))>" 110 | 111 | if expectedValue == actualValue { 112 | return true 113 | } 114 | 115 | let missing = expectedValue.subtracting(actualValue) 116 | if missing.count > 0 { 117 | failureMessage.postfixActual += ", missing <\(stringify(missing))>" 118 | } 119 | 120 | let extra = actualValue.subtracting(expectedValue) 121 | if extra.count > 0 { 122 | failureMessage.postfixActual += ", extra <\(stringify(extra))>" 123 | } 124 | } 125 | } else { 126 | failureMessage.postfixActual = " (use beNil() to match nils)" 127 | } 128 | 129 | return false 130 | } 131 | } 132 | 133 | public func ==(lhs: Expectation, rhs: T?) { 134 | lhs.to(equal(rhs)) 135 | } 136 | 137 | public func !=(lhs: Expectation, rhs: T?) { 138 | lhs.toNot(equal(rhs)) 139 | } 140 | 141 | public func ==(lhs: Expectation<[T]>, rhs: [T]?) { 142 | lhs.to(equal(rhs)) 143 | } 144 | 145 | public func !=(lhs: Expectation<[T]>, rhs: [T]?) { 146 | lhs.toNot(equal(rhs)) 147 | } 148 | 149 | public func ==(lhs: Expectation>, rhs: Set?) { 150 | lhs.to(equal(rhs)) 151 | } 152 | 153 | public func !=(lhs: Expectation>, rhs: Set?) { 154 | lhs.toNot(equal(rhs)) 155 | } 156 | 157 | public func ==(lhs: Expectation>, rhs: Set?) { 158 | lhs.to(equal(rhs)) 159 | } 160 | 161 | public func !=(lhs: Expectation>, rhs: Set?) { 162 | lhs.toNot(equal(rhs)) 163 | } 164 | 165 | public func ==(lhs: Expectation<[T: C]>, rhs: [T: C]?) { 166 | lhs.to(equal(rhs)) 167 | } 168 | 169 | public func !=(lhs: Expectation<[T: C]>, rhs: [T: C]?) { 170 | lhs.toNot(equal(rhs)) 171 | } 172 | 173 | #if _runtime(_ObjC) 174 | extension NMBObjCMatcher { 175 | public class func equalMatcher(_ expected: NSObject) -> NMBMatcher { 176 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 177 | return try! equal(expected).matches(actualExpression, failureMessage: failureMessage) 178 | } 179 | } 180 | } 181 | #endif 182 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/HaveCount.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // The `haveCount` matchers do not print the full string representation of the collection value, 4 | // instead they only print the type name and the expected count. This makes it easier to understand 5 | // the reason for failed expectations. See: https://github.com/Quick/Nimble/issues/308. 6 | // The representation of the collection content is provided in a new line as an `extendedMessage`. 7 | 8 | /// A Nimble matcher that succeeds when the actual Collection's count equals 9 | /// the expected value 10 | public func haveCount(_ expectedValue: T.IndexDistance) -> NonNilMatcherFunc { 11 | return NonNilMatcherFunc { actualExpression, failureMessage in 12 | if let actualValue = try actualExpression.evaluate() { 13 | failureMessage.postfixMessage = "have \(prettyCollectionType(actualValue)) with count \(stringify(expectedValue))" 14 | let result = expectedValue == actualValue.count 15 | failureMessage.actualValue = "\(actualValue.count)" 16 | failureMessage.extendedMessage = "Actual Value: \(stringify(actualValue))" 17 | return result 18 | } else { 19 | return false 20 | } 21 | } 22 | } 23 | 24 | /// A Nimble matcher that succeeds when the actual collection's count equals 25 | /// the expected value 26 | public func haveCount(_ expectedValue: Int) -> MatcherFunc { 27 | return MatcherFunc { actualExpression, failureMessage in 28 | if let actualValue = try actualExpression.evaluate() { 29 | failureMessage.postfixMessage = "have \(prettyCollectionType(actualValue)) with count \(stringify(expectedValue))" 30 | let result = expectedValue == actualValue.count 31 | failureMessage.actualValue = "\(actualValue.count)" 32 | failureMessage.extendedMessage = "Actual Value: \(stringify(actualValue))" 33 | return result 34 | } else { 35 | return false 36 | } 37 | } 38 | } 39 | 40 | #if _runtime(_ObjC) 41 | extension NMBObjCMatcher { 42 | public class func haveCountMatcher(_ expected: NSNumber) -> NMBObjCMatcher { 43 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 44 | let location = actualExpression.location 45 | let actualValue = try! actualExpression.evaluate() 46 | if let value = actualValue as? NMBCollection { 47 | let expr = Expression(expression: ({ value as NMBCollection}), location: location) 48 | return try! haveCount(expected.intValue).matches(expr, failureMessage: failureMessage) 49 | } else if let actualValue = actualValue { 50 | failureMessage.postfixMessage = "get type of NSArray, NSSet, NSDictionary, or NSHashTable" 51 | failureMessage.actualValue = "\(String(describing: type(of: actualValue)))" 52 | } 53 | return false 54 | } 55 | } 56 | } 57 | #endif 58 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/Match.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | #if _runtime(_ObjC) 4 | 5 | /// A Nimble matcher that succeeds when the actual string satisfies the regular expression 6 | /// described by the expected string. 7 | public func match(_ expectedValue: String?) -> NonNilMatcherFunc { 8 | return NonNilMatcherFunc { actualExpression, failureMessage in 9 | failureMessage.postfixMessage = "match <\(stringify(expectedValue))>" 10 | 11 | if let actual = try actualExpression.evaluate() { 12 | if let regexp = expectedValue { 13 | return actual.range(of: regexp, options: .regularExpression) != nil 14 | } 15 | } 16 | 17 | return false 18 | } 19 | } 20 | 21 | extension NMBObjCMatcher { 22 | public class func matchMatcher(_ expected: NSString) -> NMBMatcher { 23 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 24 | let actual = actualExpression.cast { $0 as? String } 25 | return try! match(expected.description).matches(actual, failureMessage: failureMessage) 26 | } 27 | } 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/MatchError.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual expression evaluates to an 4 | /// error from the specified case. 5 | /// 6 | /// Errors are tried to be compared by their implementation of Equatable, 7 | /// otherwise they fallback to comparision by _domain and _code. 8 | public func matchError(_ error: T) -> NonNilMatcherFunc { 9 | return NonNilMatcherFunc { actualExpression, failureMessage in 10 | let actualError: Error? = try actualExpression.evaluate() 11 | 12 | setFailureMessageForError(failureMessage, postfixMessageVerb: "match", actualError: actualError, error: error) 13 | return errorMatchesNonNilFieldsOrClosure(actualError, error: error) 14 | } 15 | } 16 | 17 | /// A Nimble matcher that succeeds when the actual expression evaluates to an 18 | /// error of the specified type 19 | public func matchError(_ errorType: T.Type) -> NonNilMatcherFunc { 20 | return NonNilMatcherFunc { actualExpression, failureMessage in 21 | let actualError: Error? = try actualExpression.evaluate() 22 | 23 | setFailureMessageForError(failureMessage, postfixMessageVerb: "match", actualError: actualError, errorType: errorType) 24 | return errorMatchesNonNilFieldsOrClosure(actualError, errorType: errorType) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/MatcherFunc.swift: -------------------------------------------------------------------------------- 1 | /// A convenience API to build matchers that don't need special negation 2 | /// behavior. The toNot() behavior is the negation of to(). 3 | /// 4 | /// @see NonNilMatcherFunc if you prefer to have this matcher fail when nil 5 | /// values are recieved in an expectation. 6 | /// 7 | /// You may use this when implementing your own custom matchers. 8 | /// 9 | /// Use the Matcher protocol instead of this type to accept custom matchers as 10 | /// input parameters. 11 | /// @see allPass for an example that uses accepts other matchers as input. 12 | public struct MatcherFunc: Matcher { 13 | public let matcher: (Expression, FailureMessage) throws -> Bool 14 | 15 | public init(_ matcher: @escaping (Expression, FailureMessage) throws -> Bool) { 16 | self.matcher = matcher 17 | } 18 | 19 | public func matches(_ actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { 20 | return try matcher(actualExpression, failureMessage) 21 | } 22 | 23 | public func doesNotMatch(_ actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { 24 | return try !matcher(actualExpression, failureMessage) 25 | } 26 | } 27 | 28 | /// A convenience API to build matchers that don't need special negation 29 | /// behavior. The toNot() behavior is the negation of to(). 30 | /// 31 | /// Unlike MatcherFunc, this will always fail if an expectation contains nil. 32 | /// This applies regardless of using to() or toNot(). 33 | /// 34 | /// You may use this when implementing your own custom matchers. 35 | /// 36 | /// Use the Matcher protocol instead of this type to accept custom matchers as 37 | /// input parameters. 38 | /// @see allPass for an example that uses accepts other matchers as input. 39 | public struct NonNilMatcherFunc: Matcher { 40 | public let matcher: (Expression, FailureMessage) throws -> Bool 41 | 42 | public init(_ matcher: @escaping (Expression, FailureMessage) throws -> Bool) { 43 | self.matcher = matcher 44 | } 45 | 46 | public func matches(_ actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { 47 | let pass = try matcher(actualExpression, failureMessage) 48 | if try attachNilErrorIfNeeded(actualExpression, failureMessage: failureMessage) { 49 | return false 50 | } 51 | return pass 52 | } 53 | 54 | public func doesNotMatch(_ actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { 55 | let pass = try !matcher(actualExpression, failureMessage) 56 | if try attachNilErrorIfNeeded(actualExpression, failureMessage: failureMessage) { 57 | return false 58 | } 59 | return pass 60 | } 61 | 62 | internal func attachNilErrorIfNeeded(_ actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { 63 | if try actualExpression.evaluate() == nil { 64 | failureMessage.postfixActual = " (use beNil() to match nils)" 65 | return true 66 | } 67 | return false 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/MatcherProtocols.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | // `CGFloat` is in Foundation (swift-corelibs-foundation) on Linux. 3 | #if _runtime(_ObjC) 4 | import CoreGraphics 5 | #endif 6 | 7 | /// Implement this protocol to implement a custom matcher for Swift 8 | public protocol Matcher { 9 | associatedtype ValueType 10 | func matches(_ actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool 11 | func doesNotMatch(_ actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool 12 | } 13 | 14 | #if _runtime(_ObjC) 15 | /// Objective-C interface to the Swift variant of Matcher. 16 | @objc public protocol NMBMatcher { 17 | func matches(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool 18 | func doesNotMatch(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool 19 | } 20 | #endif 21 | 22 | #if _runtime(_ObjC) 23 | /// Protocol for types that support contain() matcher. 24 | @objc public protocol NMBContainer { 25 | @objc(containsObject:) 26 | func contains(_ anObject: Any) -> Bool 27 | } 28 | 29 | // FIXME: NSHashTable can not conform to NMBContainer since swift-DEVELOPMENT-SNAPSHOT-2016-04-25-a 30 | //extension NSHashTable : NMBContainer {} // Corelibs Foundation does not include this class yet 31 | #else 32 | public protocol NMBContainer { 33 | func contains(_ anObject: Any) -> Bool 34 | } 35 | #endif 36 | 37 | extension NSArray : NMBContainer {} 38 | extension NSSet : NMBContainer {} 39 | 40 | #if _runtime(_ObjC) 41 | /// Protocol for types that support only beEmpty(), haveCount() matchers 42 | @objc public protocol NMBCollection { 43 | var count: Int { get } 44 | } 45 | 46 | extension NSHashTable : NMBCollection {} // Corelibs Foundation does not include these classes yet 47 | extension NSMapTable : NMBCollection {} 48 | #else 49 | public protocol NMBCollection { 50 | var count: Int { get } 51 | } 52 | #endif 53 | 54 | extension NSSet : NMBCollection {} 55 | extension NSIndexSet : NMBCollection {} 56 | extension NSDictionary : NMBCollection {} 57 | 58 | #if _runtime(_ObjC) 59 | /// Protocol for types that support beginWith(), endWith(), beEmpty() matchers 60 | @objc public protocol NMBOrderedCollection : NMBCollection { 61 | @objc(objectAtIndex:) 62 | func object(at index: Int) -> Any 63 | } 64 | #else 65 | public protocol NMBOrderedCollection : NMBCollection { 66 | func object(at index: Int) -> Any 67 | } 68 | #endif 69 | 70 | extension NSArray : NMBOrderedCollection {} 71 | 72 | public protocol NMBDoubleConvertible { 73 | var doubleValue: CDouble { get } 74 | } 75 | 76 | extension Double : NMBDoubleConvertible { 77 | public var doubleValue: CDouble { 78 | return self 79 | } 80 | } 81 | 82 | extension Float : NMBDoubleConvertible { 83 | public var doubleValue: CDouble { 84 | return CDouble(self) 85 | } 86 | } 87 | 88 | extension CGFloat: NMBDoubleConvertible { 89 | public var doubleValue: CDouble { 90 | return CDouble(self) 91 | } 92 | } 93 | 94 | extension NSNumber : NMBDoubleConvertible { 95 | } 96 | 97 | private let dateFormatter: DateFormatter = { 98 | let formatter = DateFormatter() 99 | formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSS" 100 | formatter.locale = Locale(identifier: "en_US_POSIX") 101 | 102 | return formatter 103 | }() 104 | 105 | extension Date: NMBDoubleConvertible { 106 | public var doubleValue: CDouble { 107 | return self.timeIntervalSinceReferenceDate 108 | } 109 | } 110 | 111 | extension NSDate: NMBDoubleConvertible { 112 | public var doubleValue: CDouble { 113 | return self.timeIntervalSinceReferenceDate 114 | } 115 | } 116 | 117 | extension Date: TestOutputStringConvertible { 118 | public var testDescription: String { 119 | return dateFormatter.string(from: self) 120 | } 121 | } 122 | 123 | extension NSDate: TestOutputStringConvertible { 124 | public var testDescription: String { 125 | return dateFormatter.string(from: Date(timeIntervalSinceReferenceDate: self.timeIntervalSinceReferenceDate)) 126 | } 127 | } 128 | 129 | /// Protocol for types to support beLessThan(), beLessThanOrEqualTo(), 130 | /// beGreaterThan(), beGreaterThanOrEqualTo(), and equal() matchers. 131 | /// 132 | /// Types that conform to Swift's Comparable protocol will work implicitly too 133 | #if _runtime(_ObjC) 134 | @objc public protocol NMBComparable { 135 | func NMB_compare(_ otherObject: NMBComparable!) -> ComparisonResult 136 | } 137 | #else 138 | // This should become obsolete once Corelibs Foundation adds Comparable conformance to NSNumber 139 | public protocol NMBComparable { 140 | func NMB_compare(_ otherObject: NMBComparable!) -> ComparisonResult 141 | } 142 | #endif 143 | 144 | extension NSNumber : NMBComparable { 145 | public func NMB_compare(_ otherObject: NMBComparable!) -> ComparisonResult { 146 | return compare(otherObject as! NSNumber) 147 | } 148 | } 149 | extension NSString : NMBComparable { 150 | public func NMB_compare(_ otherObject: NMBComparable!) -> ComparisonResult { 151 | return compare(otherObject as! String) 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/PostNotification.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | internal class NotificationCollector { 4 | private(set) var observedNotifications: [Notification] 5 | private let notificationCenter: NotificationCenter 6 | #if _runtime(_ObjC) 7 | private var token: AnyObject? 8 | #else 9 | private var token: NSObjectProtocol? 10 | #endif 11 | 12 | required init(notificationCenter: NotificationCenter) { 13 | self.notificationCenter = notificationCenter 14 | self.observedNotifications = [] 15 | } 16 | 17 | func startObserving() { 18 | self.token = self.notificationCenter.addObserver(forName: nil, object: nil, queue: nil) { 19 | // linux-swift gets confused by .append(n) 20 | [weak self] n in self?.observedNotifications.append(n) 21 | } 22 | } 23 | 24 | deinit { 25 | #if _runtime(_ObjC) 26 | if let token = self.token { 27 | self.notificationCenter.removeObserver(token) 28 | } 29 | #else 30 | if let token = self.token as? AnyObject { 31 | self.notificationCenter.removeObserver(token) 32 | } 33 | #endif 34 | } 35 | } 36 | 37 | private let mainThread = pthread_self() 38 | 39 | let notificationCenterDefault = NotificationCenter.default 40 | 41 | public func postNotifications( 42 | _ notificationsMatcher: T, 43 | fromNotificationCenter center: NotificationCenter = notificationCenterDefault) 44 | -> MatcherFunc 45 | where T: Matcher, T.ValueType == [Notification] 46 | { 47 | let _ = mainThread // Force lazy-loading of this value 48 | let collector = NotificationCollector(notificationCenter: center) 49 | collector.startObserving() 50 | var once: Bool = false 51 | return MatcherFunc { actualExpression, failureMessage in 52 | let collectorNotificationsExpression = Expression(memoizedExpression: { _ in 53 | return collector.observedNotifications 54 | }, location: actualExpression.location, withoutCaching: true) 55 | 56 | assert(pthread_equal(mainThread, pthread_self()) != 0, "Only expecting closure to be evaluated on main thread.") 57 | if !once { 58 | once = true 59 | _ = try actualExpression.evaluate() 60 | } 61 | 62 | let match = try notificationsMatcher.matches(collectorNotificationsExpression, failureMessage: failureMessage) 63 | if collector.observedNotifications.isEmpty { 64 | failureMessage.actualValue = "no notifications" 65 | } else { 66 | failureMessage.actualValue = "<\(stringify(collector.observedNotifications))>" 67 | } 68 | return match 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/RaisesException.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // This matcher requires the Objective-C, and being built by Xcode rather than the Swift Package Manager 4 | #if _runtime(_ObjC) && !SWIFT_PACKAGE 5 | 6 | /// A Nimble matcher that succeeds when the actual expression raises an 7 | /// exception with the specified name, reason, and/or userInfo. 8 | /// 9 | /// Alternatively, you can pass a closure to do any arbitrary custom matching 10 | /// to the raised exception. The closure only gets called when an exception 11 | /// is raised. 12 | /// 13 | /// nil arguments indicates that the matcher should not attempt to match against 14 | /// that parameter. 15 | public func raiseException( 16 | named: String? = nil, 17 | reason: String? = nil, 18 | userInfo: NSDictionary? = nil, 19 | closure: ((NSException) -> Void)? = nil) -> MatcherFunc { 20 | return MatcherFunc { actualExpression, failureMessage in 21 | 22 | var exception: NSException? 23 | let capture = NMBExceptionCapture(handler: ({ e in 24 | exception = e 25 | }), finally: nil) 26 | 27 | capture.tryBlock { 28 | _ = try! actualExpression.evaluate() 29 | return 30 | } 31 | 32 | setFailureMessageForException(failureMessage, exception: exception, named: named, reason: reason, userInfo: userInfo, closure: closure) 33 | return exceptionMatchesNonNilFieldsOrClosure(exception, named: named, reason: reason, userInfo: userInfo, closure: closure) 34 | } 35 | } 36 | 37 | internal func setFailureMessageForException( 38 | _ failureMessage: FailureMessage, 39 | exception: NSException?, 40 | named: String?, 41 | reason: String?, 42 | userInfo: NSDictionary?, 43 | closure: ((NSException) -> Void)?) { 44 | failureMessage.postfixMessage = "raise exception" 45 | 46 | if let named = named { 47 | failureMessage.postfixMessage += " with name <\(named)>" 48 | } 49 | if let reason = reason { 50 | failureMessage.postfixMessage += " with reason <\(reason)>" 51 | } 52 | if let userInfo = userInfo { 53 | failureMessage.postfixMessage += " with userInfo <\(userInfo)>" 54 | } 55 | if let _ = closure { 56 | failureMessage.postfixMessage += " that satisfies block" 57 | } 58 | if named == nil && reason == nil && userInfo == nil && closure == nil { 59 | failureMessage.postfixMessage = "raise any exception" 60 | } 61 | 62 | if let exception = exception { 63 | failureMessage.actualValue = "\(String(describing: type(of: exception))) { name=\(exception.name), reason='\(stringify(exception.reason))', userInfo=\(stringify(exception.userInfo)) }" 64 | } else { 65 | failureMessage.actualValue = "no exception" 66 | } 67 | } 68 | 69 | internal func exceptionMatchesNonNilFieldsOrClosure( 70 | _ exception: NSException?, 71 | named: String?, 72 | reason: String?, 73 | userInfo: NSDictionary?, 74 | closure: ((NSException) -> Void)?) -> Bool { 75 | var matches = false 76 | 77 | if let exception = exception { 78 | matches = true 79 | 80 | if let named = named, exception.name.rawValue != named { 81 | matches = false 82 | } 83 | if reason != nil && exception.reason != reason { 84 | matches = false 85 | } 86 | if let userInfo = userInfo, let exceptionUserInfo = exception.userInfo, 87 | (exceptionUserInfo as NSDictionary) != userInfo { 88 | matches = false 89 | } 90 | if let closure = closure { 91 | let assertions = gatherFailingExpectations { 92 | closure(exception) 93 | } 94 | let messages = assertions.map { $0.message } 95 | if messages.count > 0 { 96 | matches = false 97 | } 98 | } 99 | } 100 | 101 | return matches 102 | } 103 | 104 | public class NMBObjCRaiseExceptionMatcher : NSObject, NMBMatcher { 105 | internal var _name: String? 106 | internal var _reason: String? 107 | internal var _userInfo: NSDictionary? 108 | internal var _block: ((NSException) -> Void)? 109 | 110 | internal init(name: String?, reason: String?, userInfo: NSDictionary?, block: ((NSException) -> Void)?) { 111 | _name = name 112 | _reason = reason 113 | _userInfo = userInfo 114 | _block = block 115 | } 116 | 117 | public func matches(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { 118 | let block: () -> Any? = ({ _ = actualBlock(); return nil }) 119 | let expr = Expression(expression: block, location: location) 120 | 121 | return try! raiseException( 122 | named: _name, 123 | reason: _reason, 124 | userInfo: _userInfo, 125 | closure: _block 126 | ).matches(expr, failureMessage: failureMessage) 127 | } 128 | 129 | public func doesNotMatch(_ actualBlock: @escaping () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { 130 | return !matches(actualBlock, failureMessage: failureMessage, location: location) 131 | } 132 | 133 | public var named: (_ name: String) -> NMBObjCRaiseExceptionMatcher { 134 | return ({ name in 135 | return NMBObjCRaiseExceptionMatcher( 136 | name: name, 137 | reason: self._reason, 138 | userInfo: self._userInfo, 139 | block: self._block 140 | ) 141 | }) 142 | } 143 | 144 | public var reason: (_ reason: String?) -> NMBObjCRaiseExceptionMatcher { 145 | return ({ reason in 146 | return NMBObjCRaiseExceptionMatcher( 147 | name: self._name, 148 | reason: reason, 149 | userInfo: self._userInfo, 150 | block: self._block 151 | ) 152 | }) 153 | } 154 | 155 | public var userInfo: (_ userInfo: NSDictionary?) -> NMBObjCRaiseExceptionMatcher { 156 | return ({ userInfo in 157 | return NMBObjCRaiseExceptionMatcher( 158 | name: self._name, 159 | reason: self._reason, 160 | userInfo: userInfo, 161 | block: self._block 162 | ) 163 | }) 164 | } 165 | 166 | public var satisfyingBlock: (_ block: ((NSException) -> Void)?) -> NMBObjCRaiseExceptionMatcher { 167 | return ({ block in 168 | return NMBObjCRaiseExceptionMatcher( 169 | name: self._name, 170 | reason: self._reason, 171 | userInfo: self._userInfo, 172 | block: block 173 | ) 174 | }) 175 | } 176 | } 177 | 178 | extension NMBObjCMatcher { 179 | public class func raiseExceptionMatcher() -> NMBObjCRaiseExceptionMatcher { 180 | return NMBObjCRaiseExceptionMatcher(name: nil, reason: nil, userInfo: nil, block: nil) 181 | } 182 | } 183 | #endif 184 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/SatisfyAnyOf.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value matches with any of the matchers 4 | /// provided in the variable list of matchers. 5 | public func satisfyAnyOf(_ matchers: U...) -> NonNilMatcherFunc 6 | where U: Matcher, U.ValueType == T 7 | { 8 | return satisfyAnyOf(matchers) 9 | } 10 | 11 | internal func satisfyAnyOf(_ matchers: [U]) -> NonNilMatcherFunc 12 | where U: Matcher, U.ValueType == T 13 | { 14 | return NonNilMatcherFunc { actualExpression, failureMessage in 15 | let postfixMessages = NSMutableArray() 16 | var matches = false 17 | for matcher in matchers { 18 | if try matcher.matches(actualExpression, failureMessage: failureMessage) { 19 | matches = true 20 | } 21 | postfixMessages.add(NSString(string: "{\(failureMessage.postfixMessage)}")) 22 | } 23 | 24 | failureMessage.postfixMessage = "match one of: " + postfixMessages.componentsJoined(by: ", or ") 25 | if let actualValue = try actualExpression.evaluate() { 26 | failureMessage.actualValue = "\(actualValue)" 27 | } 28 | 29 | return matches 30 | } 31 | } 32 | 33 | public func ||(left: NonNilMatcherFunc, right: NonNilMatcherFunc) -> NonNilMatcherFunc { 34 | return satisfyAnyOf(left, right) 35 | } 36 | 37 | public func ||(left: MatcherFunc, right: MatcherFunc) -> NonNilMatcherFunc { 38 | return satisfyAnyOf(left, right) 39 | } 40 | 41 | #if _runtime(_ObjC) 42 | extension NMBObjCMatcher { 43 | public class func satisfyAnyOfMatcher(_ matchers: [NMBObjCMatcher]) -> NMBObjCMatcher { 44 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 45 | if matchers.isEmpty { 46 | failureMessage.stringValue = "satisfyAnyOf must be called with at least one matcher" 47 | return false 48 | } 49 | 50 | var elementEvaluators = [NonNilMatcherFunc]() 51 | for matcher in matchers { 52 | let elementEvaluator: (Expression, FailureMessage) -> Bool = { 53 | expression, failureMessage in 54 | return matcher.matches( 55 | {try! expression.evaluate()}, failureMessage: failureMessage, location: actualExpression.location) 56 | } 57 | 58 | elementEvaluators.append(NonNilMatcherFunc(elementEvaluator)) 59 | } 60 | 61 | return try! satisfyAnyOf(elementEvaluators).matches(actualExpression, failureMessage: failureMessage) 62 | } 63 | } 64 | } 65 | #endif 66 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Matchers/ThrowError.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual expression throws an 4 | /// error of the specified type or from the specified case. 5 | /// 6 | /// Errors are tried to be compared by their implementation of Equatable, 7 | /// otherwise they fallback to comparision by _domain and _code. 8 | /// 9 | /// Alternatively, you can pass a closure to do any arbitrary custom matching 10 | /// to the thrown error. The closure only gets called when an error was thrown. 11 | /// 12 | /// nil arguments indicates that the matcher should not attempt to match against 13 | /// that parameter. 14 | public func throwError( 15 | _ error: T? = nil, 16 | errorType: T.Type? = nil, 17 | closure: ((T) -> Void)? = nil) -> MatcherFunc { 18 | return MatcherFunc { actualExpression, failureMessage in 19 | 20 | var actualError: Error? 21 | do { 22 | _ = try actualExpression.evaluate() 23 | } catch let catchedError { 24 | actualError = catchedError 25 | } 26 | 27 | setFailureMessageForError(failureMessage, actualError: actualError, error: error, errorType: errorType, closure: closure) 28 | return errorMatchesNonNilFieldsOrClosure(actualError, error: error, errorType: errorType, closure: closure) 29 | } 30 | } 31 | 32 | /// A Nimble matcher that succeeds when the actual expression throws any 33 | /// error or when the passed closures' arbitrary custom matching succeeds. 34 | /// 35 | /// This duplication to it's generic adequate is required to allow to receive 36 | /// values of the existential type `Error` in the closure. 37 | /// 38 | /// The closure only gets called when an error was thrown. 39 | public func throwError( 40 | closure: ((Error) -> Void)? = nil) -> MatcherFunc { 41 | return MatcherFunc { actualExpression, failureMessage in 42 | 43 | var actualError: Error? 44 | do { 45 | _ = try actualExpression.evaluate() 46 | } catch let catchedError { 47 | actualError = catchedError 48 | } 49 | 50 | setFailureMessageForError(failureMessage, actualError: actualError, closure: closure) 51 | return errorMatchesNonNilFieldsOrClosure(actualError, closure: closure) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Nimble.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "NMBExceptionCapture.h" 3 | #import "NMBStringify.h" 4 | #import "DSL.h" 5 | 6 | FOUNDATION_EXPORT double NimbleVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char NimbleVersionString[]; 8 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Utils/Errors.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // Generic 4 | 5 | internal func setFailureMessageForError( 6 | _ failureMessage: FailureMessage, 7 | postfixMessageVerb: String = "throw", 8 | actualError: Error?, 9 | error: T? = nil, 10 | errorType: T.Type? = nil, 11 | closure: ((T) -> Void)? = nil) { 12 | failureMessage.postfixMessage = "\(postfixMessageVerb) error" 13 | 14 | if let error = error { 15 | if let error = error as? CustomDebugStringConvertible { 16 | failureMessage.postfixMessage += " <\(error.debugDescription)>" 17 | } else { 18 | failureMessage.postfixMessage += " <\(error)>" 19 | } 20 | } else if errorType != nil || closure != nil { 21 | failureMessage.postfixMessage += " from type <\(T.self)>" 22 | } 23 | if let _ = closure { 24 | failureMessage.postfixMessage += " that satisfies block" 25 | } 26 | if error == nil && errorType == nil && closure == nil { 27 | failureMessage.postfixMessage = "\(postfixMessageVerb) any error" 28 | } 29 | 30 | if let actualError = actualError { 31 | failureMessage.actualValue = "<\(actualError)>" 32 | } else { 33 | failureMessage.actualValue = "no error" 34 | } 35 | } 36 | 37 | internal func errorMatchesExpectedError( 38 | _ actualError: Error, 39 | expectedError: T) -> Bool { 40 | return actualError._domain == expectedError._domain 41 | && actualError._code == expectedError._code 42 | } 43 | 44 | internal func errorMatchesExpectedError( 45 | _ actualError: Error, 46 | expectedError: T) -> Bool 47 | where T: Equatable 48 | { 49 | if let actualError = actualError as? T { 50 | return actualError == expectedError 51 | } 52 | return false 53 | } 54 | 55 | internal func errorMatchesNonNilFieldsOrClosure( 56 | _ actualError: Error?, 57 | error: T? = nil, 58 | errorType: T.Type? = nil, 59 | closure: ((T) -> Void)? = nil) -> Bool { 60 | var matches = false 61 | 62 | if let actualError = actualError { 63 | matches = true 64 | 65 | if let error = error { 66 | if !errorMatchesExpectedError(actualError, expectedError: error) { 67 | matches = false 68 | } 69 | } 70 | if let actualError = actualError as? T { 71 | if let closure = closure { 72 | let assertions = gatherFailingExpectations { 73 | closure(actualError as T) 74 | } 75 | let messages = assertions.map { $0.message } 76 | if messages.count > 0 { 77 | matches = false 78 | } 79 | } 80 | } else if errorType != nil && closure != nil { 81 | // The closure expects another ErrorProtocol as argument, so this 82 | // is _supposed_ to fail, so that it becomes more obvious. 83 | let assertions = gatherExpectations { 84 | expect(actualError is T).to(equal(true)) 85 | } 86 | precondition(assertions.map { $0.message }.count > 0) 87 | matches = false 88 | } 89 | } 90 | 91 | return matches 92 | } 93 | 94 | // Non-generic 95 | 96 | internal func setFailureMessageForError( 97 | _ failureMessage: FailureMessage, 98 | actualError: Error?, 99 | closure: ((Error) -> Void)?) { 100 | failureMessage.postfixMessage = "throw error" 101 | 102 | if let _ = closure { 103 | failureMessage.postfixMessage += " that satisfies block" 104 | } else { 105 | failureMessage.postfixMessage = "throw any error" 106 | } 107 | 108 | if let actualError = actualError { 109 | failureMessage.actualValue = "<\(actualError)>" 110 | } else { 111 | failureMessage.actualValue = "no error" 112 | } 113 | } 114 | 115 | internal func errorMatchesNonNilFieldsOrClosure( 116 | _ actualError: Error?, 117 | closure: ((Error) -> Void)?) -> Bool { 118 | var matches = false 119 | 120 | if let actualError = actualError { 121 | matches = true 122 | 123 | if let closure = closure { 124 | let assertions = gatherFailingExpectations { 125 | closure(actualError) 126 | } 127 | let messages = assertions.map { $0.message } 128 | if messages.count > 0 { 129 | matches = false 130 | } 131 | } 132 | } 133 | 134 | return matches 135 | } 136 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Utils/Functional.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension Sequence { 4 | internal func all(_ fn: (Iterator.Element) -> Bool) -> Bool { 5 | for item in self { 6 | if !fn(item) { 7 | return false 8 | } 9 | } 10 | return true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/Nimble/Utils/SourceLocation.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // Ideally we would always use `StaticString` as the type for tracking the file name 4 | // that expectations originate from, for consistency with `assert` etc. from the 5 | // stdlib, and because recent versions of the XCTest overlay require `StaticString` 6 | // when calling `XCTFail`. Under the Objective-C runtime (i.e. building on Mac), we 7 | // have to use `String` instead because StaticString can't be generated from Objective-C 8 | #if _runtime(_ObjC) 9 | public typealias FileString = String 10 | #else 11 | public typealias FileString = StaticString 12 | #endif 13 | 14 | public final class SourceLocation : NSObject { 15 | public let file: FileString 16 | public let line: UInt 17 | 18 | override init() { 19 | file = "Unknown File" 20 | line = 0 21 | } 22 | 23 | init(file: FileString, line: UInt) { 24 | self.file = file 25 | self.line = line 26 | } 27 | 28 | override public var description: String { 29 | return "\(file):\(line)" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/NimbleObjectiveC/CurrentTestCaseTracker.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | SWIFT_CLASS("_TtC6Nimble22CurrentTestCaseTracker") 5 | @interface CurrentTestCaseTracker : NSObject 6 | + (CurrentTestCaseTracker *)sharedInstance; 7 | @end 8 | 9 | @interface CurrentTestCaseTracker (Register) @end 10 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/NimbleObjectiveC/DSL.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class NMBExpectation; 4 | @class NMBObjCBeCloseToMatcher; 5 | @class NMBObjCRaiseExceptionMatcher; 6 | @protocol NMBMatcher; 7 | 8 | 9 | #define NIMBLE_EXPORT FOUNDATION_EXPORT 10 | 11 | #ifdef NIMBLE_DISABLE_SHORT_SYNTAX 12 | #define NIMBLE_SHORT(PROTO, ORIGINAL) 13 | #else 14 | #define NIMBLE_SHORT(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE PROTO { return (ORIGINAL); } 15 | #endif 16 | 17 | NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line); 18 | NIMBLE_EXPORT NMBExpectation *NMB_expectAction(void(^actualBlock)(), NSString *file, NSUInteger line); 19 | 20 | NIMBLE_EXPORT id NMB_equal(id expectedValue); 21 | NIMBLE_SHORT(id equal(id expectedValue), 22 | NMB_equal(expectedValue)); 23 | 24 | NIMBLE_EXPORT id NMB_haveCount(id expectedValue); 25 | NIMBLE_SHORT(id haveCount(id expectedValue), 26 | NMB_haveCount(expectedValue)); 27 | 28 | NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue); 29 | NIMBLE_SHORT(NMBObjCBeCloseToMatcher *beCloseTo(id expectedValue), 30 | NMB_beCloseTo(expectedValue)); 31 | 32 | NIMBLE_EXPORT id NMB_beAnInstanceOf(Class expectedClass); 33 | NIMBLE_SHORT(id beAnInstanceOf(Class expectedClass), 34 | NMB_beAnInstanceOf(expectedClass)); 35 | 36 | NIMBLE_EXPORT id NMB_beAKindOf(Class expectedClass); 37 | NIMBLE_SHORT(id beAKindOf(Class expectedClass), 38 | NMB_beAKindOf(expectedClass)); 39 | 40 | NIMBLE_EXPORT id NMB_beginWith(id itemElementOrSubstring); 41 | NIMBLE_SHORT(id beginWith(id itemElementOrSubstring), 42 | NMB_beginWith(itemElementOrSubstring)); 43 | 44 | NIMBLE_EXPORT id NMB_beGreaterThan(NSNumber *expectedValue); 45 | NIMBLE_SHORT(id beGreaterThan(NSNumber *expectedValue), 46 | NMB_beGreaterThan(expectedValue)); 47 | 48 | NIMBLE_EXPORT id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue); 49 | NIMBLE_SHORT(id beGreaterThanOrEqualTo(NSNumber *expectedValue), 50 | NMB_beGreaterThanOrEqualTo(expectedValue)); 51 | 52 | NIMBLE_EXPORT id NMB_beIdenticalTo(id expectedInstance); 53 | NIMBLE_SHORT(id beIdenticalTo(id expectedInstance), 54 | NMB_beIdenticalTo(expectedInstance)); 55 | 56 | NIMBLE_EXPORT id NMB_be(id expectedInstance); 57 | NIMBLE_SHORT(id be(id expectedInstance), 58 | NMB_be(expectedInstance)); 59 | 60 | NIMBLE_EXPORT id NMB_beLessThan(NSNumber *expectedValue); 61 | NIMBLE_SHORT(id beLessThan(NSNumber *expectedValue), 62 | NMB_beLessThan(expectedValue)); 63 | 64 | NIMBLE_EXPORT id NMB_beLessThanOrEqualTo(NSNumber *expectedValue); 65 | NIMBLE_SHORT(id beLessThanOrEqualTo(NSNumber *expectedValue), 66 | NMB_beLessThanOrEqualTo(expectedValue)); 67 | 68 | NIMBLE_EXPORT id NMB_beTruthy(void); 69 | NIMBLE_SHORT(id beTruthy(void), 70 | NMB_beTruthy()); 71 | 72 | NIMBLE_EXPORT id NMB_beFalsy(void); 73 | NIMBLE_SHORT(id beFalsy(void), 74 | NMB_beFalsy()); 75 | 76 | NIMBLE_EXPORT id NMB_beTrue(void); 77 | NIMBLE_SHORT(id beTrue(void), 78 | NMB_beTrue()); 79 | 80 | NIMBLE_EXPORT id NMB_beFalse(void); 81 | NIMBLE_SHORT(id beFalse(void), 82 | NMB_beFalse()); 83 | 84 | NIMBLE_EXPORT id NMB_beNil(void); 85 | NIMBLE_SHORT(id beNil(void), 86 | NMB_beNil()); 87 | 88 | NIMBLE_EXPORT id NMB_beEmpty(void); 89 | NIMBLE_SHORT(id beEmpty(void), 90 | NMB_beEmpty()); 91 | 92 | NIMBLE_EXPORT id NMB_containWithNilTermination(id itemOrSubstring, ...) NS_REQUIRES_NIL_TERMINATION; 93 | #define NMB_contain(...) NMB_containWithNilTermination(__VA_ARGS__, nil) 94 | #ifndef NIMBLE_DISABLE_SHORT_SYNTAX 95 | #define contain(...) NMB_contain(__VA_ARGS__) 96 | #endif 97 | 98 | NIMBLE_EXPORT id NMB_endWith(id itemElementOrSubstring); 99 | NIMBLE_SHORT(id endWith(id itemElementOrSubstring), 100 | NMB_endWith(itemElementOrSubstring)); 101 | 102 | NIMBLE_EXPORT NMBObjCRaiseExceptionMatcher *NMB_raiseException(void); 103 | NIMBLE_SHORT(NMBObjCRaiseExceptionMatcher *raiseException(void), 104 | NMB_raiseException()); 105 | 106 | NIMBLE_EXPORT id NMB_match(id expectedValue); 107 | NIMBLE_SHORT(id match(id expectedValue), 108 | NMB_match(expectedValue)); 109 | 110 | NIMBLE_EXPORT id NMB_allPass(id matcher); 111 | NIMBLE_SHORT(id allPass(id matcher), 112 | NMB_allPass(matcher)); 113 | 114 | NIMBLE_EXPORT id NMB_satisfyAnyOfWithMatchers(id matchers); 115 | #define NMB_satisfyAnyOf(...) NMB_satisfyAnyOfWithMatchers(@[__VA_ARGS__]) 116 | #ifndef NIMBLE_DISABLE_SHORT_SYNTAX 117 | #define satisfyAnyOf(...) NMB_satisfyAnyOf(__VA_ARGS__) 118 | #endif 119 | 120 | // In order to preserve breakpoint behavior despite using macros to fill in __FILE__ and __LINE__, 121 | // define a builder that populates __FILE__ and __LINE__, and returns a block that takes timeout 122 | // and action arguments. See https://github.com/Quick/Quick/pull/185 for details. 123 | typedef void (^NMBWaitUntilTimeoutBlock)(NSTimeInterval timeout, void (^action)(void (^)(void))); 124 | typedef void (^NMBWaitUntilBlock)(void (^action)(void (^)(void))); 125 | 126 | NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line); 127 | 128 | NIMBLE_EXPORT NMBWaitUntilTimeoutBlock NMB_waitUntilTimeoutBuilder(NSString *file, NSUInteger line); 129 | NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger line); 130 | 131 | NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line); 132 | 133 | #define NMB_waitUntilTimeout NMB_waitUntilTimeoutBuilder(@(__FILE__), __LINE__) 134 | #define NMB_waitUntil NMB_waitUntilBuilder(@(__FILE__), __LINE__) 135 | 136 | #ifndef NIMBLE_DISABLE_SHORT_SYNTAX 137 | #define expect(...) NMB_expect(^id{ return (__VA_ARGS__); }, @(__FILE__), __LINE__) 138 | #define expectAction(BLOCK) NMB_expectAction((BLOCK), @(__FILE__), __LINE__) 139 | #define failWithMessage(msg) NMB_failWithMessage(msg, @(__FILE__), __LINE__) 140 | #define fail() failWithMessage(@"fail() always fails") 141 | 142 | 143 | #define waitUntilTimeout NMB_waitUntilTimeout 144 | #define waitUntil NMB_waitUntil 145 | #endif 146 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/NimbleObjectiveC/DSL.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | SWIFT_CLASS("_TtC6Nimble7NMBWait") 5 | @interface NMBWait : NSObject 6 | 7 | + (void)untilTimeout:(NSTimeInterval)timeout file:(NSString *)file line:(NSUInteger)line action:(void(^)())action; 8 | + (void)untilFile:(NSString *)file line:(NSUInteger)line action:(void(^)())action; 9 | 10 | @end 11 | 12 | NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line) { 13 | return [[NMBExpectation alloc] initWithActualBlock:actualBlock 14 | negative:NO 15 | file:file 16 | line:line]; 17 | } 18 | 19 | NIMBLE_EXPORT NMBExpectation *NMB_expectAction(void(^actualBlock)(), NSString *file, NSUInteger line) { 20 | return NMB_expect(^id{ 21 | actualBlock(); 22 | return nil; 23 | }, file, line); 24 | } 25 | 26 | NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line) { 27 | return [NMBExpectation failWithMessage:msg file:file line:line]; 28 | } 29 | 30 | NIMBLE_EXPORT id NMB_beAnInstanceOf(Class expectedClass) { 31 | return [NMBObjCMatcher beAnInstanceOfMatcher:expectedClass]; 32 | } 33 | 34 | NIMBLE_EXPORT id NMB_beAKindOf(Class expectedClass) { 35 | return [NMBObjCMatcher beAKindOfMatcher:expectedClass]; 36 | } 37 | 38 | NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue) { 39 | return [NMBObjCMatcher beCloseToMatcher:expectedValue within:0.001]; 40 | } 41 | 42 | NIMBLE_EXPORT id NMB_beginWith(id itemElementOrSubstring) { 43 | return [NMBObjCMatcher beginWithMatcher:itemElementOrSubstring]; 44 | } 45 | 46 | NIMBLE_EXPORT id NMB_beGreaterThan(NSNumber *expectedValue) { 47 | return [NMBObjCMatcher beGreaterThanMatcher:expectedValue]; 48 | } 49 | 50 | NIMBLE_EXPORT id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { 51 | return [NMBObjCMatcher beGreaterThanOrEqualToMatcher:expectedValue]; 52 | } 53 | 54 | NIMBLE_EXPORT id NMB_beIdenticalTo(id expectedInstance) { 55 | return [NMBObjCMatcher beIdenticalToMatcher:expectedInstance]; 56 | } 57 | 58 | NIMBLE_EXPORT id NMB_be(id expectedInstance) { 59 | return [NMBObjCMatcher beIdenticalToMatcher:expectedInstance]; 60 | } 61 | 62 | NIMBLE_EXPORT id NMB_beLessThan(NSNumber *expectedValue) { 63 | return [NMBObjCMatcher beLessThanMatcher:expectedValue]; 64 | } 65 | 66 | NIMBLE_EXPORT id NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { 67 | return [NMBObjCMatcher beLessThanOrEqualToMatcher:expectedValue]; 68 | } 69 | 70 | NIMBLE_EXPORT id NMB_beTruthy() { 71 | return [NMBObjCMatcher beTruthyMatcher]; 72 | } 73 | 74 | NIMBLE_EXPORT id NMB_beFalsy() { 75 | return [NMBObjCMatcher beFalsyMatcher]; 76 | } 77 | 78 | NIMBLE_EXPORT id NMB_beTrue() { 79 | return [NMBObjCMatcher beTrueMatcher]; 80 | } 81 | 82 | NIMBLE_EXPORT id NMB_beFalse() { 83 | return [NMBObjCMatcher beFalseMatcher]; 84 | } 85 | 86 | NIMBLE_EXPORT id NMB_beNil() { 87 | return [NMBObjCMatcher beNilMatcher]; 88 | } 89 | 90 | NIMBLE_EXPORT id NMB_beEmpty() { 91 | return [NMBObjCMatcher beEmptyMatcher]; 92 | } 93 | 94 | NIMBLE_EXPORT id NMB_containWithNilTermination(id itemOrSubstring, ...) { 95 | NSMutableArray *itemOrSubstringArray = [NSMutableArray array]; 96 | 97 | if (itemOrSubstring) { 98 | [itemOrSubstringArray addObject:itemOrSubstring]; 99 | 100 | va_list args; 101 | va_start(args, itemOrSubstring); 102 | id next; 103 | while ((next = va_arg(args, id))) { 104 | [itemOrSubstringArray addObject:next]; 105 | } 106 | va_end(args); 107 | } 108 | 109 | return [NMBObjCMatcher containMatcher:itemOrSubstringArray]; 110 | } 111 | 112 | NIMBLE_EXPORT id NMB_endWith(id itemElementOrSubstring) { 113 | return [NMBObjCMatcher endWithMatcher:itemElementOrSubstring]; 114 | } 115 | 116 | NIMBLE_EXPORT id NMB_equal(id expectedValue) { 117 | return [NMBObjCMatcher equalMatcher:expectedValue]; 118 | } 119 | 120 | NIMBLE_EXPORT id NMB_haveCount(id expectedValue) { 121 | return [NMBObjCMatcher haveCountMatcher:expectedValue]; 122 | } 123 | 124 | NIMBLE_EXPORT id NMB_match(id expectedValue) { 125 | return [NMBObjCMatcher matchMatcher:expectedValue]; 126 | } 127 | 128 | NIMBLE_EXPORT id NMB_allPass(id expectedValue) { 129 | return [NMBObjCMatcher allPassMatcher:expectedValue]; 130 | } 131 | 132 | NIMBLE_EXPORT id NMB_satisfyAnyOfWithMatchers(id matchers) { 133 | return [NMBObjCMatcher satisfyAnyOfMatcher:matchers]; 134 | } 135 | 136 | NIMBLE_EXPORT NMBObjCRaiseExceptionMatcher *NMB_raiseException() { 137 | return [NMBObjCMatcher raiseExceptionMatcher]; 138 | } 139 | 140 | NIMBLE_EXPORT NMBWaitUntilTimeoutBlock NMB_waitUntilTimeoutBuilder(NSString *file, NSUInteger line) { 141 | return ^(NSTimeInterval timeout, void (^action)(void (^)(void))) { 142 | [NMBWait untilTimeout:timeout file:file line:line action:action]; 143 | }; 144 | } 145 | 146 | NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger line) { 147 | return ^(void (^action)(void (^)(void))) { 148 | [NMBWait untilFile:file line:line action:action]; 149 | }; 150 | } 151 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/NimbleObjectiveC/NMBExceptionCapture.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface NMBExceptionCapture : NSObject 5 | 6 | - (nonnull instancetype)initWithHandler:(void(^ _Nullable)(NSException * _Nonnull))handler finally:(void(^ _Nullable)())finally; 7 | - (void)tryBlock:(void(^ _Nonnull)())unsafeBlock NS_SWIFT_NAME(tryBlock(_:)); 8 | 9 | @end 10 | 11 | typedef void(^NMBSourceCallbackBlock)(BOOL successful); 12 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/NimbleObjectiveC/NMBExceptionCapture.m: -------------------------------------------------------------------------------- 1 | #import "NMBExceptionCapture.h" 2 | 3 | @interface NMBExceptionCapture () 4 | @property (nonatomic, copy) void(^ _Nullable handler)(NSException * _Nullable); 5 | @property (nonatomic, copy) void(^ _Nullable finally)(); 6 | @end 7 | 8 | @implementation NMBExceptionCapture 9 | 10 | - (nonnull instancetype)initWithHandler:(void(^ _Nullable)(NSException * _Nonnull))handler finally:(void(^ _Nullable)())finally { 11 | self = [super init]; 12 | if (self) { 13 | self.handler = handler; 14 | self.finally = finally; 15 | } 16 | return self; 17 | } 18 | 19 | - (void)tryBlock:(void(^ _Nonnull)())unsafeBlock { 20 | @try { 21 | unsafeBlock(); 22 | } 23 | @catch (NSException *exception) { 24 | if (self.handler) { 25 | self.handler(exception); 26 | } 27 | } 28 | @finally { 29 | if (self.finally) { 30 | self.finally(); 31 | } 32 | } 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/NimbleObjectiveC/NMBStringify.h: -------------------------------------------------------------------------------- 1 | @class NSString; 2 | 3 | /** 4 | * Returns a string appropriate for displaying in test output 5 | * from the provided value. 6 | * 7 | * @param value A value that will show up in a test's output. 8 | * 9 | * @return The string that is returned can be 10 | * customized per type by conforming a type to the `TestOutputStringConvertible` 11 | * protocol. When stringifying a non-`TestOutputStringConvertible` type, this 12 | * function will return the value's debug description and then its 13 | * normal description if available and in that order. Otherwise it 14 | * will return the result of constructing a string from the value. 15 | * 16 | * @see `TestOutputStringConvertible` 17 | */ 18 | extern NSString *_Nonnull NMBStringify(id _Nullable anyObject) __attribute__((warn_unused_result)); 19 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/NimbleObjectiveC/NMBStringify.m: -------------------------------------------------------------------------------- 1 | #import "NMBStringify.h" 2 | #import 3 | 4 | NSString *_Nonnull NMBStringify(id _Nullable anyObject) { 5 | return [NMBStringer stringify:anyObject]; 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Nimble/Sources/NimbleObjectiveC/XCTestObservationCenter+Register.m: -------------------------------------------------------------------------------- 1 | #import "CurrentTestCaseTracker.h" 2 | #import 3 | #import 4 | 5 | #pragma mark - Method Swizzling 6 | 7 | /// Swaps the implementations between two instance methods. 8 | /// 9 | /// @param class The class containing `originalSelector`. 10 | /// @param originalSelector Original method to replace. 11 | /// @param replacementSelector Replacement method. 12 | void swizzleSelectors(Class class, SEL originalSelector, SEL replacementSelector) { 13 | Method originalMethod = class_getInstanceMethod(class, originalSelector); 14 | Method replacementMethod = class_getInstanceMethod(class, replacementSelector); 15 | 16 | BOOL didAddMethod = 17 | class_addMethod(class, 18 | originalSelector, 19 | method_getImplementation(replacementMethod), 20 | method_getTypeEncoding(replacementMethod)); 21 | 22 | if (didAddMethod) { 23 | class_replaceMethod(class, 24 | replacementSelector, 25 | method_getImplementation(originalMethod), 26 | method_getTypeEncoding(originalMethod)); 27 | } else { 28 | method_exchangeImplementations(originalMethod, replacementMethod); 29 | } 30 | } 31 | 32 | #pragma mark - Private 33 | 34 | @interface XCTestObservationCenter (Private) 35 | - (void)_addLegacyTestObserver:(id)observer; 36 | @end 37 | 38 | @implementation XCTestObservationCenter (Register) 39 | 40 | /// Uses objc method swizzling to register `CurrentTestCaseTracker` as a test observer. This is necessary 41 | /// because Xcode 7.3 introduced timing issues where if a custom `XCTestObservation` is registered too early 42 | /// it suppresses all console output (generated by `XCTestLog`), breaking any tools that depend on this output. 43 | /// This approach waits to register our custom test observer until XCTest adds its first "legacy" observer, 44 | /// falling back to registering after the first normal observer if this private method ever changes. 45 | + (void)load { 46 | if (class_getInstanceMethod([self class], @selector(_addLegacyTestObserver:))) { 47 | // Swizzle -_addLegacyTestObserver: 48 | swizzleSelectors([self class], @selector(_addLegacyTestObserver:), @selector(NMB_original__addLegacyTestObserver:)); 49 | } else { 50 | // Swizzle -addTestObserver:, only if -_addLegacyTestObserver: is not implemented 51 | swizzleSelectors([self class], @selector(addTestObserver:), @selector(NMB_original_addTestObserver:)); 52 | } 53 | } 54 | 55 | #pragma mark - Replacement Methods 56 | 57 | /// Registers `CurrentTestCaseTracker` as a test observer after `XCTestLog` has been added. 58 | - (void)NMB_original__addLegacyTestObserver:(id)observer { 59 | [self NMB_original__addLegacyTestObserver:observer]; 60 | 61 | static dispatch_once_t onceToken; 62 | dispatch_once(&onceToken, ^{ 63 | [self addTestObserver:[CurrentTestCaseTracker sharedInstance]]; 64 | }); 65 | } 66 | 67 | /// Registers `CurrentTestCaseTracker` as a test observer after `XCTestLog` has been added. 68 | /// This method is only used if `-_addLegacyTestObserver:` is not impelemented. (added in Xcode 7.3) 69 | - (void)NMB_original_addTestObserver:(id)observer { 70 | [self NMB_original_addTestObserver:observer]; 71 | 72 | static dispatch_once_t onceToken; 73 | dispatch_once(&onceToken, ^{ 74 | [self NMB_original_addTestObserver:[CurrentTestCaseTracker sharedInstance]]; 75 | }); 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CheckmarkSegmentedControl/CheckmarkSegmentedControl-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_CheckmarkSegmentedControl : NSObject 3 | @end 4 | @implementation PodsDummy_CheckmarkSegmentedControl 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CheckmarkSegmentedControl/CheckmarkSegmentedControl-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CheckmarkSegmentedControl/CheckmarkSegmentedControl-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double CheckmarkSegmentedControlVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char CheckmarkSegmentedControlVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CheckmarkSegmentedControl/CheckmarkSegmentedControl.modulemap: -------------------------------------------------------------------------------- 1 | framework module CheckmarkSegmentedControl { 2 | umbrella header "CheckmarkSegmentedControl-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CheckmarkSegmentedControl/CheckmarkSegmentedControl.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/CheckmarkSegmentedControl 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_LDFLAGS = -framework "UIKit" 5 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CheckmarkSegmentedControl/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.1.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/CheckmarkSegmentedControl/ResourceBundle-CheckmarkSegmentedControl-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleIdentifier 8 | ${PRODUCT_BUNDLE_IDENTIFIER} 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | ${PRODUCT_NAME} 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 0.1.1 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Nimble/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 5.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Nimble/Nimble-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Nimble : NSObject 3 | @end 4 | @implementation PodsDummy_Nimble 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Nimble/Nimble-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Nimble/Nimble-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "Nimble.h" 4 | #import "DSL.h" 5 | #import "NMBExceptionCapture.h" 6 | #import "NMBStringify.h" 7 | 8 | FOUNDATION_EXPORT double NimbleVersionNumber; 9 | FOUNDATION_EXPORT const unsigned char NimbleVersionString[]; 10 | 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Nimble/Nimble.modulemap: -------------------------------------------------------------------------------- 1 | framework module Nimble { 2 | umbrella header "Nimble-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Nimble/Nimble.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Nimble 2 | ENABLE_BITCODE = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 6 | OTHER_LDFLAGS = -weak-lswiftXCTest -weak_framework "XCTest" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_ROOT = ${SRCROOT} 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Pods-CheckmarkSegmentedControl_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## CheckmarkSegmentedControl 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 Pham Ba Tho 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Pods-CheckmarkSegmentedControl_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2015 Pham Ba Tho 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | CheckmarkSegmentedControl 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Pods-CheckmarkSegmentedControl_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_CheckmarkSegmentedControl_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_CheckmarkSegmentedControl_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Pods-CheckmarkSegmentedControl_Example-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | 86 | if [[ "$CONFIGURATION" == "Debug" ]]; then 87 | install_framework "$BUILT_PRODUCTS_DIR/CheckmarkSegmentedControl/CheckmarkSegmentedControl.framework" 88 | fi 89 | if [[ "$CONFIGURATION" == "Release" ]]; then 90 | install_framework "$BUILT_PRODUCTS_DIR/CheckmarkSegmentedControl/CheckmarkSegmentedControl.framework" 91 | fi 92 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Pods-CheckmarkSegmentedControl_Example-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | *) 22 | TARGET_DEVICE_ARGS="--target-device mac" 23 | ;; 24 | esac 25 | 26 | realpath() { 27 | DIRECTORY="$(cd "${1%/*}" && pwd)" 28 | FILENAME="${1##*/}" 29 | echo "$DIRECTORY/$FILENAME" 30 | } 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 48 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 49 | ;; 50 | *.xib) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Pods-CheckmarkSegmentedControl_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_CheckmarkSegmentedControl_ExampleVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_CheckmarkSegmentedControl_ExampleVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Pods-CheckmarkSegmentedControl_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/CheckmarkSegmentedControl" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/CheckmarkSegmentedControl/CheckmarkSegmentedControl.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "CheckmarkSegmentedControl" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Pods-CheckmarkSegmentedControl_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_CheckmarkSegmentedControl_Example { 2 | umbrella header "Pods-CheckmarkSegmentedControl_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Example/Pods-CheckmarkSegmentedControl_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/CheckmarkSegmentedControl" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/CheckmarkSegmentedControl/CheckmarkSegmentedControl.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "CheckmarkSegmentedControl" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Tests/Pods-CheckmarkSegmentedControl_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_CheckmarkSegmentedControl_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_CheckmarkSegmentedControl_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Tests/Pods-CheckmarkSegmentedControl_Tests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | 86 | if [[ "$CONFIGURATION" == "Debug" ]]; then 87 | install_framework "$BUILT_PRODUCTS_DIR/Nimble/Nimble.framework" 88 | fi 89 | if [[ "$CONFIGURATION" == "Release" ]]; then 90 | install_framework "$BUILT_PRODUCTS_DIR/Nimble/Nimble.framework" 91 | fi 92 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Tests/Pods-CheckmarkSegmentedControl_Tests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | *) 22 | TARGET_DEVICE_ARGS="--target-device mac" 23 | ;; 24 | esac 25 | 26 | realpath() { 27 | DIRECTORY="$(cd "${1%/*}" && pwd)" 28 | FILENAME="${1##*/}" 29 | echo "$DIRECTORY/$FILENAME" 30 | } 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 48 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 49 | ;; 50 | *.xib) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Tests/Pods-CheckmarkSegmentedControl_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_CheckmarkSegmentedControl_TestsVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_CheckmarkSegmentedControl_TestsVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Tests/Pods-CheckmarkSegmentedControl_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Nimble" "$PODS_CONFIGURATION_BUILD_DIR/CheckmarkSegmentedControl" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Nimble/Nimble.framework/Headers" $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/CheckmarkSegmentedControl/CheckmarkSegmentedControl.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "Nimble" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Tests/Pods-CheckmarkSegmentedControl_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_CheckmarkSegmentedControl_Tests { 2 | umbrella header "Pods-CheckmarkSegmentedControl_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-CheckmarkSegmentedControl_Tests/Pods-CheckmarkSegmentedControl_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Nimble" "$PODS_CONFIGURATION_BUILD_DIR/CheckmarkSegmentedControl" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Nimble/Nimble.framework/Headers" $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/CheckmarkSegmentedControl/CheckmarkSegmentedControl.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "Nimble" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = $BUILD_DIR 10 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Pham Ba Tho 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pod/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregttn/CheckmarkSegmentedControl/9aaf202b55db1c330a216ba32ec5daa002a33dc4/Pod/Assets/.gitkeep -------------------------------------------------------------------------------- /Pod/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregttn/CheckmarkSegmentedControl/9aaf202b55db1c330a216ba32ec5daa002a33dc4/Pod/Classes/.gitkeep -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/gregttn/CheckmarkSegmentedControl.svg?branch=master)](https://travis-ci.org/gregttn/CheckmarkSegmentedControl) 2 | [![Pod Version](https://img.shields.io/cocoapods/v/CheckmarkSegmentedControl.svg?style=flat)](https://cocoapods.org/pods/CheckmarkSegmentedControl) 3 | 4 | # CheckmarkSegmentedControl 5 | 6 | CheckmarkSegmentedControl is a customisable alternative to UISegmentedControl. 7 | Visually it looks like radio buttons group with checkmark sign in the middle and animated border on selection. Each option can be fully customised. 8 | 9 | ![Preview](https://raw.githubusercontent.com/gregttn/CheckmarkSegmentedControl/master/preview.gif) 10 | 11 | ### Features 12 | * creation of segmented control with look of radio buttons 13 | * selection of a new option is animated 14 | * each option can have border, background and font customized 15 | 16 | ### Installation 17 | 18 | #### CocoaPods 19 | Include the following in your Podfile: 20 | 21 | ```ruby 22 | use_frameworks! 23 | pod 'CheckmarkSegmentedControl', '0.2.0' 24 | ``` 25 | 26 | #### Manual 27 | You need to copy CheckmarkSegmentedControl.swift to your project. 28 | 29 | ### Usage 30 | 31 | ```swift 32 | var checkmark: CheckmarkSegmentedControl = CheckmarkSegmentedControl(frame: frame) 33 | checkmark.options = [ 34 | CheckmarkOption(title:"Option 1"), // by default black border and light gray colour as background 35 | CheckmarkOption(title: "Option 2", borderColor: UIColor.orange, fillColor: UIColor.brown), 36 | CheckmarkOption(title: "Option 3", borderColor: UIColor.brown, fillColor: UIColor.orange), 37 | CheckmarkOption(title: "Option 4", borderColor: UIColor.green, fillColor: UIColor.blue) 38 | ] 39 | 40 | ``` 41 | 42 | Get notified when new option is selected: 43 | 44 | ```swift 45 | checkmark.addTarget(self, action: #selector(ViewController.optionSelected(_:)), for: UIControlEvents.valueChanged) 46 | 47 | func optionSelected(_ sender: AnyObject) { 48 | print("Selected option: \(checkmark.options[checkmark.selectedIndex])") 49 | } 50 | 51 | ``` 52 | 53 | ### Licence 54 | 55 | MIT licence 56 | -------------------------------------------------------------------------------- /preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregttn/CheckmarkSegmentedControl/9aaf202b55db1c330a216ba32ec5daa002a33dc4/preview.gif --------------------------------------------------------------------------------