├── .gitignore ├── Keiko ├── AppDelegate.swift ├── AssetSectionInfo.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── FAMImagePickerNavigationHeader.swift ├── Info.plist ├── MediaPickerCell.swift ├── MediaPickerController.swift ├── MediaPickerHeader.swift ├── MediaPickerProtocol.swift └── ViewController.swift ├── LICENSE ├── Podfile ├── Podfile.lock ├── Pods ├── Manifest.lock ├── NVHTarGzip │ ├── Classes │ │ ├── NSFileManager+NVHFileSize.h │ │ ├── NSFileManager+NVHFileSize.m │ │ ├── NVHFile.h │ │ ├── NVHFile.m │ │ ├── NVHGzipFile.h │ │ ├── NVHGzipFile.m │ │ ├── NVHProgress.h │ │ ├── NVHProgress.m │ │ ├── NVHTarFile.h │ │ ├── NVHTarFile.m │ │ ├── NVHTarGzip.h │ │ └── NVHTarGzip.m │ ├── LICENSE │ └── README.md ├── Nimble │ ├── LICENSE │ ├── README.md │ └── Sources │ │ ├── Lib │ │ └── CwlPreconditionTesting │ │ │ ├── CwlCatchException │ │ │ └── CwlCatchException.swift │ │ │ ├── CwlCatchExceptionSupport │ │ │ ├── CwlCatchException.m │ │ │ └── include │ │ │ │ └── CwlCatchException.h │ │ │ ├── CwlMachBadInstructionHandler │ │ │ ├── CwlMachBadInstructionHandler.m │ │ │ ├── include │ │ │ │ └── CwlMachBadInstructionHandler.h │ │ │ ├── mach_excServer.c │ │ │ └── mach_excServer.h │ │ │ └── CwlPreconditionTesting │ │ │ ├── CwlBadInstructionException.swift │ │ │ ├── CwlCatchBadInstruction.swift │ │ │ ├── CwlDarwinDefinitions.swift │ │ │ └── Mach │ │ │ └── CwlPreconditionTesting.h │ │ ├── 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 │ │ │ ├── ContainElementSatisfying.swift │ │ │ ├── EndWith.swift │ │ │ ├── Equal.swift │ │ │ ├── HaveCount.swift │ │ │ ├── Match.swift │ │ │ ├── MatchError.swift │ │ │ ├── MatcherFunc.swift │ │ │ ├── MatcherProtocols.swift │ │ │ ├── PostNotification.swift │ │ │ ├── RaisesException.swift │ │ │ ├── SatisfyAnyOf.swift │ │ │ ├── ThrowAssertion.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 ├── Quick │ ├── LICENSE │ ├── README.md │ └── Sources │ │ ├── Quick │ │ ├── Callsite.swift │ │ ├── Configuration │ │ │ └── Configuration.swift │ │ ├── DSL │ │ │ ├── DSL.swift │ │ │ └── World+DSL.swift │ │ ├── ErrorUtility.swift │ │ ├── Example.swift │ │ ├── ExampleGroup.swift │ │ ├── ExampleMetadata.swift │ │ ├── Filter.swift │ │ ├── Hooks │ │ │ ├── Closures.swift │ │ │ ├── ExampleHooks.swift │ │ │ ├── HooksPhase.swift │ │ │ └── SuiteHooks.swift │ │ ├── NSBundle+CurrentTestBundle.swift │ │ ├── NSString+C99ExtendedIdentifier.swift │ │ ├── QuickSelectedTestSuiteBuilder.swift │ │ ├── QuickTestSuite.swift │ │ ├── URL+FileName.swift │ │ └── World.swift │ │ ├── QuickObjectiveC │ │ ├── Configuration │ │ │ ├── QuickConfiguration.h │ │ │ └── QuickConfiguration.m │ │ ├── DSL │ │ │ ├── QCKDSL.h │ │ │ ├── QCKDSL.m │ │ │ └── World+DSL.h │ │ ├── Quick.h │ │ ├── QuickSpec.h │ │ ├── QuickSpec.m │ │ ├── World.h │ │ └── XCTestSuite+QuickTestSuiteBuilder.m │ │ └── QuickSpecBase │ │ ├── QuickSpecBase.m │ │ └── include │ │ └── QuickSpecBase.h └── Target Support Files │ ├── NVHTarGzip │ ├── Info.plist │ ├── NVHTarGzip-dummy.m │ ├── NVHTarGzip-prefix.pch │ ├── NVHTarGzip-umbrella.h │ ├── NVHTarGzip.modulemap │ └── NVHTarGzip.xcconfig │ ├── Nimble │ ├── Info.plist │ ├── Nimble-dummy.m │ ├── Nimble-prefix.pch │ ├── Nimble-umbrella.h │ ├── Nimble.modulemap │ └── Nimble.xcconfig │ ├── Pods-Keiko │ ├── Info.plist │ ├── Pods-Keiko-acknowledgements.markdown │ ├── Pods-Keiko-acknowledgements.plist │ ├── Pods-Keiko-dummy.m │ ├── Pods-Keiko-frameworks.sh │ ├── Pods-Keiko-resources.sh │ ├── Pods-Keiko-umbrella.h │ ├── Pods-Keiko.debug.xcconfig │ ├── Pods-Keiko.modulemap │ └── Pods-Keiko.release.xcconfig │ ├── Pods-Sumo │ ├── Info.plist │ ├── Pods-Sumo-acknowledgements.markdown │ ├── Pods-Sumo-acknowledgements.plist │ ├── Pods-Sumo-dummy.m │ ├── Pods-Sumo-resources.sh │ ├── Pods-Sumo-umbrella.h │ ├── Pods-Sumo.debug.xcconfig │ ├── Pods-Sumo.modulemap │ └── Pods-Sumo.release.xcconfig │ ├── Pods-SumoTests │ ├── Info.plist │ ├── Pods-SumoTests-acknowledgements.markdown │ ├── Pods-SumoTests-acknowledgements.plist │ ├── Pods-SumoTests-dummy.m │ ├── Pods-SumoTests-frameworks.sh │ ├── Pods-SumoTests-resources.sh │ ├── Pods-SumoTests-umbrella.h │ ├── Pods-SumoTests.debug.xcconfig │ ├── Pods-SumoTests.modulemap │ └── Pods-SumoTests.release.xcconfig │ └── Quick │ ├── Info.plist │ ├── Quick-dummy.m │ ├── Quick-prefix.pch │ ├── Quick-umbrella.h │ ├── Quick.modulemap │ └── Quick.xcconfig ├── README.md ├── Sumo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── 1amageek.xcuserdatad │ └── xcschemes │ ├── Sumo.xcscheme │ └── xcschememanagement.plist ├── Sumo.xcworkspace └── contents.xcworkspacedata ├── Sumo ├── Data+.swift ├── Info.plist ├── Sumo+FileManager.swift ├── Sumo+Item.swift ├── Sumo+Session.swift ├── Sumo.h └── Sumo.swift ├── SumoTests ├── Info.plist ├── SumoTests.swift ├── TestLibraryManager.swift └── siko.jpg ├── overview.png └── sumo.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | -------------------------------------------------------------------------------- /Keiko/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Keiko 4 | // 5 | // Created by 1amageek on 2017/04/11. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 17 | self.window = UIWindow(frame: UIScreen.main.bounds) 18 | self.window?.rootViewController = UINavigationController(rootViewController: MediaPickerController()) 19 | self.window?.makeKeyAndVisible() 20 | return true 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Keiko/AssetSectionInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AssetSectionInfo.swift 3 | // Sumo 4 | // 5 | // Created by 1amageek on 2017/04/03. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import Photos 10 | 11 | struct SectionInfo { 12 | let fetchResult: PHFetchResult 13 | let assetCollection: PHAssetCollection 14 | init(fetchResult: PHFetchResult, assetCollection: PHAssetCollection) { 15 | self.fetchResult = fetchResult 16 | self.assetCollection = assetCollection 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Keiko/Assets.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 | } -------------------------------------------------------------------------------- /Keiko/Base.lproj/LaunchScreen.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 | -------------------------------------------------------------------------------- /Keiko/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 | -------------------------------------------------------------------------------- /Keiko/FAMImagePickerNavigationHeader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FAMImagePickerNavigationHeader.swift 3 | // Sumo 4 | // 5 | // Created by 1amageek on 2017/04/03. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FAMImagePickerNavigationHeader: UIView { 12 | 13 | override init(frame: CGRect) { 14 | super.init(frame: frame) 15 | self.addSubview(titleLabel) 16 | self.addSubview(detailLabel) 17 | } 18 | 19 | required init?(coder aDecoder: NSCoder) { 20 | fatalError("init(coder:) has not been implemented") 21 | } 22 | 23 | override func layoutSubviews() { 24 | super.layoutSubviews() 25 | titleLabel.sizeToFit() 26 | detailLabel.sizeToFit() 27 | titleLabel.center = CGPoint(x: bounds.width/2, y: bounds.height/2 - titleLabel.bounds.height/2) 28 | detailLabel.center = CGPoint(x: bounds.width/2, y: bounds.height/2 + detailLabel.bounds.height/2 ) 29 | } 30 | 31 | var title: String? { 32 | didSet { 33 | titleLabel.text = title 34 | setNeedsLayout() 35 | } 36 | } 37 | 38 | var detail: String? { 39 | didSet { 40 | detailLabel.text = detail 41 | setNeedsLayout() 42 | } 43 | } 44 | 45 | fileprivate(set) lazy var titleLabel: UILabel = { 46 | var titleLabel: UILabel = UILabel(frame: .zero) 47 | titleLabel.numberOfLines = 1 48 | titleLabel.font = UIFont.systemFont(ofSize: 15) 49 | return titleLabel 50 | }() 51 | 52 | fileprivate(set) lazy var detailLabel: UILabel = { 53 | var detailLabel: UILabel = UILabel(frame: .zero) 54 | detailLabel.numberOfLines = 1 55 | detailLabel.font = UIFont.systemFont(ofSize: 10) 56 | return detailLabel 57 | }() 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Keiko/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | NSPhotoLibraryUsageDescription 8 | Photo Movie 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 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 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Keiko/MediaPickerHeader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MediaPickerHeader.swift 3 | // Sumo 4 | // 5 | // Created by 1amageek on 2017/04/03. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MediaPickerHeader: UICollectionViewCell { 12 | 13 | let contentInset: UIEdgeInsets = UIEdgeInsets(top: 24, left: 8, bottom: 12, right: 8) 14 | 15 | weak var delegate: MediaPickerHeaderDelegate? 16 | 17 | var section: Int = 0 18 | 19 | override init(frame: CGRect) { 20 | super.init(frame: frame) 21 | self.addSubview(selectButton) 22 | self.addSubview(titleLabel) 23 | } 24 | 25 | required init?(coder aDecoder: NSCoder) { 26 | fatalError("init(coder:) has not been implemented") 27 | } 28 | 29 | var title: String? { 30 | didSet { 31 | self.titleLabel.text = title 32 | self.setNeedsLayout() 33 | } 34 | } 35 | 36 | private(set) lazy var titleLabel: UILabel = { 37 | let titleLabel: UILabel = UILabel(frame: .zero) 38 | titleLabel.numberOfLines = 1 39 | titleLabel.textColor = UIColor.black 40 | titleLabel.font = UIFont.systemFont(ofSize: 15) 41 | return titleLabel 42 | }() 43 | 44 | private(set) lazy var selectButton: UIButton = { 45 | let button: UIButton = UIButton(type: UIButtonType.system) 46 | button.setTitle("Select", for: .normal) 47 | return button 48 | }() 49 | 50 | func tapped() { 51 | if self.isSelected { 52 | self.isSelected = !self.isSelected 53 | self.delegate?.header(header: self, didSelected: self.isSelected) 54 | } else { 55 | if (self.delegate?.shouldSelectHeader(header: self) ?? false) { 56 | self.isSelected = !self.isSelected 57 | self.delegate?.header(header: self, didSelected: self.isSelected) 58 | } 59 | } 60 | } 61 | 62 | override var isSelected: Bool { 63 | didSet { 64 | self.selectButton.backgroundColor = isSelected ? UIColor.white : UIColor.white 65 | self.setNeedsDisplay() 66 | } 67 | } 68 | 69 | override func layoutSubviews() { 70 | super.layoutSubviews() 71 | _ = calculateSize() 72 | } 73 | 74 | func calculateSize() -> CGSize { 75 | selectButton.sizeToFit() 76 | titleLabel.sizeToFit() 77 | self.selectButton.frame = CGRect(x: self.bounds.width - contentInset.right - selectButton.bounds.width, 78 | y: contentInset.top, 79 | width: selectButton.bounds.width, 80 | height: selectButton.bounds.height) 81 | let heigth: CGFloat = self.selectButton.frame.maxY + contentInset.bottom 82 | self.titleLabel.frame = CGRect(x: contentInset.left, 83 | y: heigth - contentInset.bottom - titleLabel.bounds.height, 84 | width: titleLabel.bounds.width, 85 | height: titleLabel.bounds.height) 86 | return CGSize(width: self.bounds.width, height: heigth) 87 | } 88 | 89 | } 90 | 91 | protocol MediaPickerHeaderDelegate: class { 92 | func shouldSelectHeader(header: MediaPickerHeader) -> Bool 93 | func header(header: MediaPickerHeader, didSelected selected: Bool) 94 | } 95 | -------------------------------------------------------------------------------- /Keiko/MediaPickerProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MediaPickerProtocol.swift 3 | // Sumo 4 | // 5 | // Created by 1amageek on 2017/04/03. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Photos 11 | 12 | protocol MediaPickerProtocol { 13 | 14 | var countOfPhotos: Int { get set } 15 | var countOfVideos: Int { get set } 16 | 17 | var hasReachedLimitOfPhotos: Bool { get } 18 | var hasReachedLimitOfVideos: Bool { get } 19 | 20 | var limitOfPhotos: Int { get } 21 | var limitOfVidoes: Int { get } 22 | 23 | } 24 | 25 | extension MediaPickerProtocol { 26 | 27 | var hasReachedLimitOfPhotos: Bool { return limitOfPhotos <= countOfPhotos } 28 | var hasReachedLimitOfVideos: Bool { return limitOfVidoes <= countOfVideos } 29 | 30 | var limitOfPhotos: Int { 31 | return 50 32 | } 33 | 34 | var limitOfVidoes: Int { 35 | return 3 36 | } 37 | 38 | mutating func selectWithAsset(asset: PHAsset) { 39 | switch asset.mediaType { 40 | case .image: countOfPhotos += 1 41 | case .video: countOfVideos += 1 42 | default: break 43 | } 44 | } 45 | 46 | mutating func deSelectWithAsset(asset: PHAsset) { 47 | switch asset.mediaType { 48 | case .image: countOfPhotos -= 1 49 | case .video: countOfVideos -= 1 50 | default: break 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Keiko/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Keiko 4 | // 5 | // Created by 1amageek on 2017/04/11. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 1amageek 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 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'Sumo' do 5 | use_frameworks! 6 | pod 'NVHTarGzip' 7 | 8 | target 'SumoTests' do 9 | inherit! :search_paths 10 | pod 'Quick' 11 | pod 'Nimble' 12 | end 13 | 14 | end 15 | target 'Keiko' do 16 | use_frameworks! 17 | pod 'NVHTarGzip' 18 | end 19 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Nimble (6.1.0) 3 | - NVHTarGzip (1.0.1) 4 | - Quick (1.1.0) 5 | 6 | DEPENDENCIES: 7 | - Nimble 8 | - NVHTarGzip 9 | - Quick 10 | 11 | SPEC CHECKSUMS: 12 | Nimble: c53e6903fee94041b90ded74f135820437d8bf59 13 | NVHTarGzip: 74cc227b902e5725900d37eb6d79b57e93005a73 14 | Quick: dafc587e21eed9f4cab3249b9f9015b0b7a7f71d 15 | 16 | PODFILE CHECKSUM: d58fa70b42f9f9d119d9bd77ab6c94880647e48e 17 | 18 | COCOAPODS: 1.1.1 19 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Nimble (6.1.0) 3 | - NVHTarGzip (1.0.1) 4 | - Quick (1.1.0) 5 | 6 | DEPENDENCIES: 7 | - Nimble 8 | - NVHTarGzip 9 | - Quick 10 | 11 | SPEC CHECKSUMS: 12 | Nimble: c53e6903fee94041b90ded74f135820437d8bf59 13 | NVHTarGzip: 74cc227b902e5725900d37eb6d79b57e93005a73 14 | Quick: dafc587e21eed9f4cab3249b9f9015b0b7a7f71d 15 | 16 | PODFILE CHECKSUM: d58fa70b42f9f9d119d9bd77ab6c94880647e48e 17 | 18 | COCOAPODS: 1.1.1 19 | -------------------------------------------------------------------------------- /Pods/NVHTarGzip/Classes/NSFileManager+NVHFileSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+NVHFileSize.h 3 | // Pods 4 | // 5 | // Created by Niels van Hoorn on 03/07/15. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface NSFileManager (NVHFileSize) 12 | 13 | - (unsigned long long)fileSizeOfItemAtPath:(NSString *)path; 14 | 15 | @end -------------------------------------------------------------------------------- /Pods/NVHTarGzip/Classes/NSFileManager+NVHFileSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+NVHFileSize.m 3 | // Pods 4 | // 5 | // Created by Niels van Hoorn on 03/07/15. 6 | // 7 | // 8 | 9 | #import "NSFileManager+NVHFileSize.h" 10 | 11 | @implementation NSFileManager (NVHFileSize) 12 | 13 | - (unsigned long long)fileSizeOfItemAtPath:(NSString *)path { 14 | NSError *error = nil; 15 | NSDictionary* attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error]; 16 | if (error != nil) 17 | { 18 | return 0; 19 | } 20 | return [attributes fileSize]; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Pods/NVHTarGzip/Classes/NVHFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // NVHFile.h 3 | // Pods 4 | // 5 | // Created by Niels van Hoorn on 26/03/14. 6 | // 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface NVHFile : NSObject 13 | 14 | @property (nonatomic, readonly) NSString *filePath; 15 | @property (nonatomic, assign) unsigned long long fileSize; 16 | 17 | - (instancetype)initWithPath:(NSString *)filePath; 18 | 19 | - (void)setupProgress; 20 | - (void)updateProgressVirtualTotalUnitCountWithFileSize; 21 | - (void)updateProgressVirtualTotalUnitCount:(int64_t)virtualUnitCount; 22 | - (void)updateProgressVirtualCompletedUnitCount:(int64_t)virtualUnitCount; 23 | - (void)updateProgressVirtualCompletedUnitCountWithTotal; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Pods/NVHTarGzip/Classes/NVHFile.m: -------------------------------------------------------------------------------- 1 | // 2 | // NVHFile.m 3 | // Pods 4 | // 5 | // Created by Niels van Hoorn on 26/03/14. 6 | // 7 | // 8 | 9 | #import "NVHFile.h" 10 | #import "NSFileManager+NVHFileSize.h" 11 | #import "NVHProgress.h" 12 | 13 | 14 | @interface NVHFile () 15 | 16 | @property (nonatomic) NVHProgress *progress; 17 | @property (nonatomic, strong) NSString *filePath; 18 | 19 | @end 20 | 21 | 22 | @implementation NVHFile 23 | 24 | - (instancetype)initWithPath:(NSString *)filePath { 25 | self = [super init]; 26 | if (self) { 27 | self.filePath = filePath; 28 | } 29 | return self; 30 | } 31 | 32 | - (unsigned long long)fileSize { 33 | return [[NSFileManager defaultManager] fileSizeOfItemAtPath:self.filePath]; 34 | } 35 | 36 | - (void)setupProgress 37 | { 38 | self.progress = [[NVHProgress alloc] init]; 39 | } 40 | 41 | - (void)updateProgressVirtualTotalUnitCount:(int64_t)virtualUnitCount 42 | { 43 | [self.progress setVirtualTotalUnitCount:virtualUnitCount]; 44 | } 45 | 46 | - (void)updateProgressVirtualCompletedUnitCount:(int64_t)virtualUnitCount 47 | { 48 | [self.progress setVirtualCompletedUnitCount:virtualUnitCount]; 49 | } 50 | 51 | - (void)updateProgressVirtualTotalUnitCountWithFileSize 52 | { 53 | [self updateProgressVirtualTotalUnitCount:self.fileSize]; 54 | } 55 | 56 | - (void)updateProgressVirtualCompletedUnitCountWithTotal 57 | { 58 | [self.progress setVirtualCompletedUnitCountToTotal]; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Pods/NVHTarGzip/Classes/NVHGzipFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // NVHGzip.h 3 | // Pods 4 | // 5 | // Created by Niels van Hoorn on 26/03/14. 6 | // 7 | // 8 | 9 | #import 10 | #import "NVHFile.h" 11 | 12 | @interface NVHGzipFile : NVHFile 13 | 14 | - (BOOL)inflateToPath:(NSString *)destinationPath error:(NSError **)error; 15 | - (void)inflateToPath:(NSString *)destinationPath completion:(void(^)(NSError *))completion; 16 | 17 | - (BOOL)deflateFromPath:(NSString *)sourcePath error:(NSError **)error; 18 | - (void)deflateFromPath:(NSString *)sourcePath completion:(void(^)(NSError *))completion; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Pods/NVHTarGzip/Classes/NVHProgress.h: -------------------------------------------------------------------------------- 1 | // 2 | // NVHProgress.h 3 | // Pods 4 | // 5 | // Created by Niels van Hoorn on 03/07/15. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface NVHProgress : NSObject 12 | 13 | - (void)setVirtualTotalUnitCount:(int64_t)virtualTotalUnitCount; 14 | - (void)setVirtualCompletedUnitCount:(int64_t)virtualUnitCount; 15 | - (void)setVirtualCompletedUnitCountToTotal; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Pods/NVHTarGzip/Classes/NVHProgress.m: -------------------------------------------------------------------------------- 1 | // 2 | // NVHProgress.m 3 | // Pods 4 | // 5 | // Created by Niels van Hoorn on 03/07/15. 6 | // 7 | // 8 | 9 | #import "NVHProgress.h" 10 | 11 | /** Using a small maximum total unit count instead of using self.fileSize 12 | * directly is recommended to let it work nicely with parent progress objects 13 | * because of this bug rdar://16444353 (http://openradar.appspot.com/radar?id=5775860476936192) 14 | * 15 | * Default is 100; 16 | */ 17 | const int64_t NVHProgressMaxTotalUnitCount = 100; 18 | 19 | @interface NVHProgress () 20 | 21 | @property (nonatomic) NSProgress *progress; 22 | @property (nonatomic, assign) double countFraction; 23 | 24 | @end 25 | 26 | @implementation NVHProgress 27 | 28 | // Designated initializer; 29 | - (instancetype)init 30 | { 31 | self = [super init]; 32 | if (!self) { return nil; } 33 | 34 | self.progress = [NSProgress progressWithTotalUnitCount:NVHProgressMaxTotalUnitCount]; 35 | self.progress.cancellable = NO; 36 | self.progress.pausable = NO; 37 | 38 | return self; 39 | } 40 | 41 | - (void)setVirtualTotalUnitCount:(int64_t)virtualTotalUnitCount 42 | { 43 | self.countFraction = (double)NVHProgressMaxTotalUnitCount / (double)virtualTotalUnitCount; 44 | } 45 | 46 | - (void)setVirtualCompletedUnitCount:(int64_t)virtualUnitCount 47 | { 48 | self.progress.completedUnitCount = roundf( self.countFraction * virtualUnitCount ); 49 | } 50 | 51 | - (void)setVirtualCompletedUnitCountToTotal 52 | { 53 | self.progress.completedUnitCount = NVHProgressMaxTotalUnitCount; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Pods/NVHTarGzip/Classes/NVHTarFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // NVHTarFile.h 3 | // Pods 4 | // 5 | // Created by Niels van Hoorn on 26/03/14. 6 | // 7 | // 8 | 9 | #import 10 | #import "NVHFile.h" 11 | 12 | @interface NVHTarFile : NVHFile 13 | 14 | - (BOOL)createFilesAndDirectoriesAtPath:(NSString *)destinationPath error:(NSError **)error; 15 | - (void)createFilesAndDirectoriesAtPath:(NSString *)destinationPath completion:(void(^)(NSError*))completion; 16 | 17 | - (BOOL)packFilesAndDirectoriesAtPath:(NSString *)sourcePath error:(NSError **)error; 18 | - (void)packFilesAndDirectoriesAtPath:(NSString *)sourcePath completion:(void (^)(NSError *))completion; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Pods/NVHTarGzip/Classes/NVHTarGzip.h: -------------------------------------------------------------------------------- 1 | // 2 | // NVHTarGzip.h 3 | // Pods 4 | // 5 | // Created by Niels van Hoorn on 26/03/14. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface NVHTarGzip : NSObject 12 | 13 | + (NVHTarGzip *)sharedInstance; 14 | 15 | // Sync API 16 | - (BOOL)unTarFileAtPath:(NSString *)sourcePath toPath:(NSString *)destinationPath error:(NSError **)error; 17 | - (BOOL)unGzipFileAtPath:(NSString *)sourcePath toPath:(NSString *)destinationPath error:(NSError **)error; 18 | - (BOOL)unTarGzipFileAtPath:(NSString*)sourcePath toPath:(NSString*)destinationPath error:(NSError **)error; 19 | - (BOOL)tarFileAtPath:(NSString *)sourcePath toPath:(NSString *)destinationPath error:(NSError**)error; 20 | - (BOOL)gzipFileAtPath:(NSString *)sourcePath toPath:(NSString *)destinationPath error:(NSError **)error; 21 | - (BOOL)tarGzipFileAtPath:(NSString*)sourcePath toPath:(NSString *)destinationPath error:(NSError **)error; 22 | 23 | // Async API 24 | - (void)unTarFileAtPath:(NSString *)sourcePath toPath:(NSString *)destinationPath completion:(void(^)(NSError *))completion; 25 | - (void)unGzipFileAtPath:(NSString *)sourcePath toPath:(NSString *)destinationPath completion:(void(^)(NSError *))completion; 26 | - (void)unTarGzipFileAtPath:(NSString*)sourcePath toPath:(NSString *)destinationPath completion:(void(^)(NSError *))completion; 27 | - (void)tarFileAtPath:(NSString *)sourcePath toPath:(NSString *)destinationPath completion:(void(^)(NSError *))completion; 28 | - (void)gzipFileAtPath:(NSString *)sourcePath toPath:(NSString *)destinationPath completion:(void(^)(NSError *))completion; 29 | - (void)tarGzipFileAtPath:(NSString*)sourcePath toPath:(NSString *)destinationPath completion:(void(^)(NSError*))completion; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Pods/NVHTarGzip/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Niels van Hoorn 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CwlCatchException.swift 3 | // CwlAssertionTesting 4 | // 5 | // Created by Matt Gallagher on 2016/01/10. 6 | // Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. 7 | // 8 | // Permission to use, copy, modify, and/or distribute this software for any 9 | // purpose with or without fee is hereby granted, provided that the above 10 | // copyright notice and this permission notice appear in all copies. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 15 | // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 18 | // IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 | // 20 | 21 | import Foundation 22 | 23 | #if SWIFT_PACKAGE 24 | import CwlCatchExceptionSupport 25 | #endif 26 | 27 | private func catchReturnTypeConverter(_ instance: T, block: () -> Void) -> T? { 28 | // Get the type from an *instance*, instead of a receiving the type directly 29 | return catchExceptionOfKind(T.self, block) as? T 30 | } 31 | 32 | extension NSException { 33 | public static func catchException(in block: () -> Void) -> Self? { 34 | // Use a dummy instance of Self to provide the type 35 | return catchReturnTypeConverter(self.init(), block: block) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchExceptionSupport/CwlCatchException.m: -------------------------------------------------------------------------------- 1 | // 2 | // CwlCatchException.m 3 | // CwlAssertionTesting 4 | // 5 | // Created by Matt Gallagher on 2016/01/10. 6 | // Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. 7 | // 8 | // Permission to use, copy, modify, and/or distribute this software for any 9 | // purpose with or without fee is hereby granted, provided that the above 10 | // copyright notice and this permission notice appear in all copies. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 15 | // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 18 | // IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 | // 20 | 21 | #import "CwlCatchException.h" 22 | 23 | #if !SWIFT_PACKAGE && NON_SWIFT_PACKAGE 24 | __attribute__((visibility("hidden"))) 25 | #endif 26 | NSException* catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)()) { 27 | @try { 28 | inBlock(); 29 | } @catch (NSException *exception) { 30 | if ([exception isKindOfClass:type]) { 31 | return exception; 32 | } else { 33 | @throw; 34 | } 35 | } 36 | return nil; 37 | } 38 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchExceptionSupport/include/CwlCatchException.h: -------------------------------------------------------------------------------- 1 | // 2 | // CwlCatchException.h 3 | // CwlCatchException 4 | // 5 | // Created by Matt Gallagher on 2016/01/10. 6 | // Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. 7 | // 8 | // Permission to use, copy, modify, and/or distribute this software for any 9 | // purpose with or without fee is hereby granted, provided that the above 10 | // copyright notice and this permission notice appear in all copies. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 15 | // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 18 | // IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 | // 20 | 21 | #import 22 | 23 | //! Project version number for CwlCatchException. 24 | FOUNDATION_EXPORT double CwlCatchExceptionVersionNumber; 25 | 26 | //! Project version string for CwlCatchException. 27 | FOUNDATION_EXPORT const unsigned char CwlCatchExceptionVersionString[]; 28 | 29 | #if !SWIFT_PACKAGE && NON_SWIFT_PACKAGE 30 | __attribute__((visibility("hidden"))) 31 | #endif 32 | NSException* __nullable catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)()); 33 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Lib/CwlPreconditionTesting/CwlMachBadInstructionHandler/CwlMachBadInstructionHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // CwlMachBadExceptionHandler.m 3 | // CwlPreconditionTesting 4 | // 5 | // Created by Matt Gallagher on 2016/01/10. 6 | // Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. 7 | // 8 | // Permission to use, copy, modify, and/or distribute this software for any 9 | // purpose with or without fee is hereby granted, provided that the above 10 | // copyright notice and this permission notice appear in all copies. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 15 | // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 18 | // IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 | // 20 | 21 | #if defined(__x86_64__) 22 | 23 | #import "mach_excServer.h" 24 | #import "CwlMachBadInstructionHandler.h" 25 | 26 | @protocol BadInstructionReply 27 | +(NSNumber *)receiveReply:(NSValue *)value; 28 | @end 29 | 30 | /// A basic function that receives callbacks from mach_exc_server and relays them to the Swift implemented BadInstructionException.catch_mach_exception_raise_state. 31 | kern_return_t catch_mach_exception_raise_state(mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, const thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { 32 | bad_instruction_exception_reply_t reply = { exception_port, exception, code, codeCnt, flavor, old_state, old_stateCnt, new_state, new_stateCnt }; 33 | Class badInstructionClass = NSClassFromString(@"BadInstructionException"); 34 | NSValue *value = [NSValue valueWithBytes: &reply objCType: @encode(bad_instruction_exception_reply_t)]; 35 | return [[badInstructionClass performSelector: @selector(receiveReply:) withObject: value] intValue]; 36 | } 37 | 38 | // The mach port should be configured so that this function is never used. 39 | kern_return_t catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt) { 40 | assert(false); 41 | return KERN_FAILURE; 42 | } 43 | 44 | // The mach port should be configured so that this function is never used. 45 | kern_return_t catch_mach_exception_raise_state_identity(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { 46 | assert(false); 47 | return KERN_FAILURE; 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Lib/CwlPreconditionTesting/CwlMachBadInstructionHandler/include/CwlMachBadInstructionHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // CwlMachBadExceptionHandler.h 3 | // CwlPreconditionTesting 4 | // 5 | // Created by Matt Gallagher on 2016/01/10. 6 | // Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. 7 | // 8 | // Permission to use, copy, modify, and/or distribute this software for any 9 | // purpose with or without fee is hereby granted, provided that the above 10 | // copyright notice and this permission notice appear in all copies. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 15 | // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 18 | // IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 | // 20 | 21 | #import 22 | #import 23 | 24 | NS_ASSUME_NONNULL_BEGIN 25 | 26 | extern boolean_t mach_exc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); 27 | 28 | // The request_mach_exception_raise_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. 29 | typedef struct 30 | { 31 | mach_msg_header_t Head; 32 | /* start of the kernel processed data */ 33 | mach_msg_body_t msgh_body; 34 | mach_msg_port_descriptor_t thread; 35 | mach_msg_port_descriptor_t task; 36 | /* end of the kernel processed data */ 37 | NDR_record_t NDR; 38 | exception_type_t exception; 39 | mach_msg_type_number_t codeCnt; 40 | int64_t code[2]; 41 | int flavor; 42 | mach_msg_type_number_t old_stateCnt; 43 | natural_t old_state[224]; 44 | } request_mach_exception_raise_t; 45 | 46 | // The reply_mach_exception_raise_state_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. 47 | typedef struct 48 | { 49 | mach_msg_header_t Head; 50 | NDR_record_t NDR; 51 | kern_return_t RetCode; 52 | int flavor; 53 | mach_msg_type_number_t new_stateCnt; 54 | natural_t new_state[224]; 55 | } reply_mach_exception_raise_state_t; 56 | 57 | typedef struct 58 | { 59 | mach_port_t exception_port; 60 | exception_type_t exception; 61 | mach_exception_data_type_t const * _Nullable code; 62 | mach_msg_type_number_t codeCnt; 63 | int32_t * _Nullable flavor; 64 | natural_t const * _Nullable old_state; 65 | mach_msg_type_number_t old_stateCnt; 66 | thread_state_t _Nullable new_state; 67 | mach_msg_type_number_t * _Nullable new_stateCnt; 68 | } bad_instruction_exception_reply_t; 69 | 70 | NS_ASSUME_NONNULL_END 71 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CwlBadInstructionException.swift 3 | // CwlPreconditionTesting 4 | // 5 | // Created by Matt Gallagher on 2016/01/10. 6 | // Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. 7 | // 8 | // Permission to use, copy, modify, and/or distribute this software for any 9 | // purpose with or without fee is hereby granted, provided that the above 10 | // copyright notice and this permission notice appear in all copies. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 15 | // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 18 | // IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 | // 20 | 21 | import Foundation 22 | 23 | #if SWIFT_PACKAGE 24 | import CwlMachBadInstructionHandler 25 | #endif 26 | 27 | private func raiseBadInstructionException() { 28 | BadInstructionException().raise() 29 | } 30 | 31 | /// A simple NSException subclass. It's not required to subclass NSException (since the exception type is represented in the name) but this helps for identifying the exception through runtime type. 32 | @objc(BadInstructionException) 33 | public class BadInstructionException: NSException { 34 | static var name: String = "com.cocoawithlove.BadInstruction" 35 | 36 | init() { 37 | super.init(name: NSExceptionName(rawValue: BadInstructionException.name), reason: nil, userInfo: nil) 38 | } 39 | 40 | required public init?(coder aDecoder: NSCoder) { 41 | super.init(coder: aDecoder) 42 | } 43 | 44 | /// An Objective-C callable function, invoked from the `mach_exc_server` callback function `catch_mach_exception_raise_state` to push the `raiseBadInstructionException` function onto the stack. 45 | @objc(receiveReply:) 46 | public class func receiveReply(_ value: NSValue) -> NSNumber { 47 | #if arch(x86_64) 48 | var reply = bad_instruction_exception_reply_t(exception_port: 0, exception: 0, code: nil, codeCnt: 0, flavor: nil, old_state: nil, old_stateCnt: 0, new_state: nil, new_stateCnt: nil) 49 | withUnsafeMutablePointer(to: &reply) { value.getValue(UnsafeMutableRawPointer($0)) } 50 | 51 | let old_state: UnsafePointer = reply.old_state! 52 | let old_stateCnt: mach_msg_type_number_t = reply.old_stateCnt 53 | let new_state: thread_state_t = reply.new_state! 54 | let new_stateCnt: UnsafeMutablePointer = reply.new_stateCnt! 55 | 56 | // Make sure we've been given enough memory 57 | if old_stateCnt != x86_THREAD_STATE64_COUNT || new_stateCnt.pointee < x86_THREAD_STATE64_COUNT { 58 | return NSNumber(value: KERN_INVALID_ARGUMENT) 59 | } 60 | 61 | // Read the old thread state 62 | var state = old_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { return $0.pointee } 63 | 64 | // 1. Decrement the stack pointer 65 | state.__rsp -= __uint64_t(MemoryLayout.size) 66 | 67 | // 2. Save the old Instruction Pointer to the stack. 68 | if let pointer = UnsafeMutablePointer<__uint64_t>(bitPattern: UInt(state.__rsp)) { 69 | pointer.pointee = state.__rip 70 | } else { 71 | return NSNumber(value: KERN_INVALID_ARGUMENT) 72 | } 73 | 74 | // 3. Set the Instruction Pointer to the new function's address 75 | var f: @convention(c) () -> Void = raiseBadInstructionException 76 | withUnsafePointer(to: &f) { 77 | state.__rip = $0.withMemoryRebound(to: __uint64_t.self, capacity: 1) { return $0.pointee } 78 | } 79 | 80 | // Write the new thread state 81 | new_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { $0.pointee = state } 82 | new_stateCnt.pointee = x86_THREAD_STATE64_COUNT 83 | 84 | return NSNumber(value: KERN_SUCCESS) 85 | #else 86 | fatalError("Unavailable for this CPU architecture") 87 | #endif 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CwlDarwinDefinitions.swift 3 | // CwlPreconditionTesting 4 | // 5 | // Created by Matt Gallagher on 2016/01/10. 6 | // Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. 7 | // 8 | // Permission to use, copy, modify, and/or distribute this software for any 9 | // purpose with or without fee is hereby granted, provided that the above 10 | // copyright notice and this permission notice appear in all copies. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 15 | // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 18 | // IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 | // 20 | 21 | import Darwin 22 | 23 | #if arch(x86_64) 24 | 25 | // From /usr/include/mach/message.h 26 | // #define MACH_MSG_TYPE_MAKE_SEND 20 /* Must hold receive right */ 27 | // #define MACH_MSGH_BITS_REMOTE(bits) \ 28 | // ((bits) & MACH_MSGH_BITS_REMOTE_MASK) 29 | // #define MACH_MSGH_BITS(remote, local) /* legacy */ \ 30 | // ((remote) | ((local) << 8)) 31 | public let MACH_MSG_TYPE_MAKE_SEND: UInt32 = 20 32 | public func MACH_MSGH_BITS_REMOTE(_ bits: UInt32) -> UInt32 { return bits & UInt32(MACH_MSGH_BITS_REMOTE_MASK) } 33 | public func MACH_MSGH_BITS(_ remote: UInt32, _ local: UInt32) -> UInt32 { return ((remote) | ((local) << 8)) } 34 | 35 | // From /usr/include/mach/exception_types.h 36 | // #define EXC_BAD_INSTRUCTION 2 /* Instruction failed */ 37 | // #define EXC_MASK_BAD_INSTRUCTION (1 << EXC_BAD_INSTRUCTION) 38 | public let EXC_BAD_INSTRUCTION: UInt32 = 2 39 | public let EXC_MASK_BAD_INSTRUCTION: UInt32 = 1 << EXC_BAD_INSTRUCTION 40 | 41 | // From /usr/include/mach/i386/thread_status.h 42 | // #define x86_THREAD_STATE64_COUNT ((mach_msg_type_number_t) \ 43 | // ( sizeof (x86_thread_state64_t) / sizeof (int) )) 44 | public let x86_THREAD_STATE64_COUNT = UInt32(MemoryLayout.size / MemoryLayout.size) 45 | 46 | public let EXC_TYPES_COUNT = 14 47 | public struct execTypesCountTuple { 48 | // From /usr/include/mach/i386/exception.h 49 | // #define EXC_TYPES_COUNT 14 /* incl. illegal exception 0 */ 50 | public var value: (T, T, T, T, T, T, T, T, T, T, T, T, T, T) = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 51 | public init() { 52 | } 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Mach/CwlPreconditionTesting.h: -------------------------------------------------------------------------------- 1 | // 2 | // CwlPreconditionTesting.h 3 | // CwlPreconditionTesting 4 | // 5 | // Created by Matt Gallagher on 2016/01/10. 6 | // Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. 7 | // 8 | // Permission to use, copy, modify, and/or distribute this software for any 9 | // purpose with or without fee is hereby granted, provided that the above 10 | // copyright notice and this permission notice appear in all copies. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 15 | // SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 18 | // IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 | // 20 | 21 | #import 22 | 23 | //! Project version number for CwlUtils. 24 | FOUNDATION_EXPORT double CwlPreconditionTestingVersionNumber; 25 | 26 | //! Project version string for CwlUtils. 27 | FOUNDATION_EXPORT const unsigned char CwlAssertingTestingVersionString[]; 28 | 29 | #include "CwlMachBadInstructionHandler.h" 30 | #include "CwlCatchException.h" 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Adapters/AssertionDispatcher.swift: -------------------------------------------------------------------------------- 1 | /// AssertionDispatcher allows multiple AssertionHandlers to receive 2 | /// assertion messages. 3 | /// 4 | /// @warning Does not fully dispatch if one of the handlers raises an exception. 5 | /// This is possible with XCTest-based assertion handlers. 6 | /// 7 | public class AssertionDispatcher: AssertionHandler { 8 | let handlers: [AssertionHandler] 9 | 10 | public init(handlers: [AssertionHandler]) { 11 | self.handlers = handlers 12 | } 13 | 14 | public func assert(_ assertion: Bool, message: FailureMessage, location: SourceLocation) { 15 | for handler in handlers { 16 | handler.assert(assertion, message: message, location: location) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift: -------------------------------------------------------------------------------- 1 | import Dispatch 2 | import Foundation 3 | 4 | /// "Global" state of Nimble is stored here. Only DSL functions should access / be aware of this 5 | /// class' existance 6 | internal class NimbleEnvironment { 7 | static var activeInstance: NimbleEnvironment { 8 | get { 9 | let env = Thread.current.threadDictionary["NimbleEnvironment"] 10 | if let env = env as? NimbleEnvironment { 11 | return env 12 | } else { 13 | let newEnv = NimbleEnvironment() 14 | self.activeInstance = newEnv 15 | return newEnv 16 | } 17 | } 18 | set { 19 | Thread.current.threadDictionary["NimbleEnvironment"] = newValue 20 | } 21 | } 22 | 23 | // TODO: eventually migrate the global to this environment value 24 | var assertionHandler: AssertionHandler { 25 | get { return NimbleAssertionHandler } 26 | set { NimbleAssertionHandler = newValue } 27 | } 28 | 29 | var suppressTVOSAssertionWarning: Bool = false 30 | var awaiter: Awaiter 31 | 32 | init() { 33 | let timeoutQueue: DispatchQueue 34 | if #available(OSX 10.10, *) { 35 | timeoutQueue = DispatchQueue.global(qos: .userInitiated) 36 | } else { 37 | timeoutQueue = DispatchQueue.global(priority: .high) 38 | } 39 | 40 | awaiter = Awaiter( 41 | waitLock: AssertionWaitLock(), 42 | asyncQueue: .main, 43 | timeoutQueue: timeoutQueue) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /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 !SWIFT_PACKAGE 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 | func isXCTestAvailable() -> Bool { 56 | #if _runtime(_ObjC) 57 | // XCTest is weakly linked and so may not be present 58 | return NSClassFromString("XCTestCase") != nil 59 | #else 60 | return true 61 | #endif 62 | } 63 | 64 | private func recordFailure(_ message: String, location: SourceLocation) { 65 | #if SWIFT_PACKAGE 66 | XCTFail("\(message)", file: location.file, line: location.line) 67 | #else 68 | if let testCase = CurrentTestCaseTracker.sharedInstance.currentTestCase { 69 | testCase.recordFailure(withDescription: message, inFile: location.file, atLine: location.line, expected: true) 70 | } else { 71 | let msg = "Attempted to report a test failure to XCTest while no test case was running. " + 72 | "The failure was:\n\"\(message)\"\nIt occurred at: \(location.file):\(location.line)" 73 | NSException(name: .internalInconsistencyException, reason: msg, userInfo: nil).raise() 74 | } 75 | #endif 76 | } 77 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | let msg = FailureMessage() 6 | msg.userDescription = description 7 | msg.to = to 8 | do { 9 | let pass = try matcher.matches(expression, failureMessage: msg) 10 | if msg.actualValue == "" { 11 | msg.actualValue = "<\(stringify(try expression.evaluate()))>" 12 | } 13 | return (pass, msg) 14 | } catch let error { 15 | msg.actualValue = "an unexpected error thrown: <\(error)>" 16 | return (false, msg) 17 | } 18 | } 19 | 20 | internal func expressionDoesNotMatch(_ expression: Expression, matcher: U, toNot: String, description: String?) -> (Bool, FailureMessage) 21 | where U: Matcher, U.ValueType == T { 22 | let msg = FailureMessage() 23 | msg.userDescription = description 24 | msg.to = toNot 25 | do { 26 | let pass = try matcher.doesNotMatch(expression, failureMessage: msg) 27 | if msg.actualValue == "" { 28 | msg.actualValue = "<\(stringify(try expression.evaluate()))>" 29 | } 30 | return (pass, msg) 31 | } catch let error { 32 | msg.actualValue = "an unexpected error thrown: <\(error)>" 33 | return (false, msg) 34 | } 35 | } 36 | 37 | public struct Expectation { 38 | 39 | public let expression: Expression 40 | 41 | public func verify(_ pass: Bool, _ message: FailureMessage) { 42 | let handler = NimbleEnvironment.activeInstance.assertionHandler 43 | handler.assert(pass, message: message, location: expression.location) 44 | } 45 | 46 | /// Tests the actual value using a matcher to match. 47 | public func to(_ matcher: U, description: String? = nil) 48 | where U: Matcher, U.ValueType == T { 49 | let (pass, msg) = expressionMatches(expression, matcher: matcher, to: "to", description: description) 50 | verify(pass, msg) 51 | } 52 | 53 | /// Tests the actual value using a matcher to not match. 54 | public func toNot(_ matcher: U, description: String? = nil) 55 | where U: Matcher, U.ValueType == T { 56 | let (pass, msg) = expressionDoesNotMatch(expression, matcher: matcher, toNot: "to not", description: description) 57 | verify(pass, msg) 58 | } 59 | 60 | /// Tests the actual value using a matcher to not match. 61 | /// 62 | /// Alias to toNot(). 63 | public func notTo(_ matcher: U, description: String? = nil) 64 | where U: Matcher, U.ValueType == T { 65 | toNot(matcher, description: description) 66 | } 67 | 68 | // see: 69 | // - AsyncMatcherWrapper for extension 70 | // - NMBExpectation for Objective-C interface 71 | } 72 | -------------------------------------------------------------------------------- /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? 16 | public var userDescription: String? 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 | -------------------------------------------------------------------------------- /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 | return allPass("pass a condition", passFunc) 7 | } 8 | 9 | public func allPass 10 | (_ passName: String, _ passFunc: @escaping (T?) -> Bool) -> NonNilMatcherFunc 11 | where U: Sequence, U.Iterator.Element == T { 12 | return createAllPassMatcher { expression, failureMessage in 13 | failureMessage.postfixMessage = passName 14 | return passFunc(try expression.evaluate()) 15 | } 16 | } 17 | 18 | public func allPass 19 | (_ matcher: V) -> NonNilMatcherFunc 20 | where U: Sequence, V: Matcher, U.Iterator.Element == V.ValueType { 21 | return createAllPassMatcher { 22 | try matcher.matches($0, failureMessage: $1) 23 | } 24 | } 25 | 26 | private func createAllPassMatcher 27 | (_ elementEvaluator: @escaping (Expression, FailureMessage) throws -> Bool) -> NonNilMatcherFunc 28 | where U: Sequence, U.Iterator.Element == T { 29 | return NonNilMatcherFunc { actualExpression, failureMessage in 30 | failureMessage.actualValue = nil 31 | if let actualValue = try actualExpression.evaluate() { 32 | for currentElement in actualValue { 33 | let exp = Expression( 34 | expression: {currentElement}, location: actualExpression.location) 35 | if try !elementEvaluator(exp, failureMessage) { 36 | failureMessage.postfixMessage = 37 | "all \(failureMessage.postfixMessage)," 38 | + " but failed first at element <\(stringify(currentElement))>" 39 | + " in <\(stringify(actualValue))>" 40 | return false 41 | } 42 | } 43 | failureMessage.postfixMessage = "all \(failureMessage.postfixMessage)" 44 | } else { 45 | failureMessage.postfixMessage = "all pass (use beNil() to match nils)" 46 | return false 47 | } 48 | 49 | return true 50 | } 51 | } 52 | 53 | #if _runtime(_ObjC) 54 | extension NMBObjCMatcher { 55 | public class func allPassMatcher(_ matcher: NMBObjCMatcher) -> NMBObjCMatcher { 56 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 57 | let location = actualExpression.location 58 | let actualValue = try! actualExpression.evaluate() 59 | var nsObjects = [NSObject]() 60 | 61 | var collectionIsUsable = true 62 | if let value = actualValue as? NSFastEnumeration { 63 | let generator = NSFastEnumerationIterator(value) 64 | while let obj = generator.next() { 65 | if let nsObject = obj as? NSObject { 66 | nsObjects.append(nsObject) 67 | } else { 68 | collectionIsUsable = false 69 | break 70 | } 71 | } 72 | } else { 73 | collectionIsUsable = false 74 | } 75 | 76 | if !collectionIsUsable { 77 | failureMessage.postfixMessage = 78 | "allPass only works with NSFastEnumeration (NSArray, NSSet, ...) of NSObjects" 79 | failureMessage.expected = "" 80 | failureMessage.to = "" 81 | return false 82 | } 83 | 84 | let expr = Expression(expression: ({ nsObjects }), location: location) 85 | let elementEvaluator: (Expression, FailureMessage) -> Bool = { 86 | expression, failureMessage in 87 | return matcher.matches({try! expression.evaluate()}, failureMessage: failureMessage, location: expr.location) 88 | } 89 | return try! createAllPassMatcher(elementEvaluator).matches( 90 | expr, failureMessage: failureMessage) 91 | } 92 | } 93 | } 94 | #endif 95 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Matchers/BeAKindOf.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is an instance of the given class. 4 | public func beAKindOf(_ expectedType: T.Type) -> NonNilMatcherFunc { 5 | return NonNilMatcherFunc {actualExpression, failureMessage in 6 | failureMessage.postfixMessage = "be a kind of \(String(describing: expectedType))" 7 | let instance = try actualExpression.evaluate() 8 | guard let validInstance = instance else { 9 | failureMessage.actualValue = "" 10 | return false 11 | } 12 | 13 | failureMessage.actualValue = "<\(String(describing: type(of: validInstance))) instance>" 14 | 15 | guard validInstance is T else { 16 | return false 17 | } 18 | 19 | return true 20 | } 21 | } 22 | 23 | #if _runtime(_ObjC) 24 | 25 | /// A Nimble matcher that succeeds when the actual value is an instance of the given class. 26 | /// @see beAnInstanceOf if you want to match against the exact class 27 | public func beAKindOf(_ expectedClass: AnyClass) -> NonNilMatcherFunc { 28 | return NonNilMatcherFunc { actualExpression, failureMessage in 29 | let instance = try actualExpression.evaluate() 30 | if let validInstance = instance { 31 | failureMessage.actualValue = "<\(String(describing: type(of: validInstance))) instance>" 32 | } else { 33 | failureMessage.actualValue = "" 34 | } 35 | failureMessage.postfixMessage = "be a kind of \(String(describing: expectedClass))" 36 | return instance != nil && instance!.isKind(of: expectedClass) 37 | } 38 | } 39 | 40 | extension NMBObjCMatcher { 41 | public class func beAKindOfMatcher(_ expected: AnyClass) -> NMBMatcher { 42 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 43 | return try! beAKindOf(expected).matches(actualExpression, failureMessage: failureMessage) 44 | } 45 | } 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Matchers/BeAnInstanceOf.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is an _exact_ instance of the given class. 4 | public func beAnInstanceOf(_ expectedType: T.Type) -> NonNilMatcherFunc { 5 | return NonNilMatcherFunc {actualExpression, failureMessage in 6 | failureMessage.postfixMessage = "be an instance of \(String(describing: expectedType))" 7 | let instance = try actualExpression.evaluate() 8 | guard let validInstance = instance else { 9 | failureMessage.actualValue = "" 10 | return false 11 | } 12 | 13 | failureMessage.actualValue = "<\(String(describing: type(of: validInstance))) instance>" 14 | 15 | if type(of: validInstance) == expectedType { 16 | return true 17 | } 18 | 19 | return false 20 | } 21 | } 22 | 23 | /// A Nimble matcher that succeeds when the actual value is an instance of the given class. 24 | /// @see beAKindOf if you want to match against subclasses 25 | public func beAnInstanceOf(_ expectedClass: AnyClass) -> NonNilMatcherFunc { 26 | return NonNilMatcherFunc { actualExpression, failureMessage in 27 | let instance = try actualExpression.evaluate() 28 | if let validInstance = instance { 29 | failureMessage.actualValue = "<\(String(describing: type(of: validInstance))) instance>" 30 | } else { 31 | failureMessage.actualValue = "" 32 | } 33 | failureMessage.postfixMessage = "be an instance of \(String(describing: expectedClass))" 34 | #if _runtime(_ObjC) 35 | return instance != nil && instance!.isMember(of: expectedClass) 36 | #else 37 | return instance != nil && type(of: instance!) == expectedClass 38 | #endif 39 | } 40 | } 41 | 42 | #if _runtime(_ObjC) 43 | extension NMBObjCMatcher { 44 | public class func beAnInstanceOfMatcher(_ expected: AnyClass) -> NMBMatcher { 45 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 46 | return try! beAnInstanceOf(expected).matches(actualExpression, failureMessage: failureMessage) 47 | } 48 | } 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Matchers/BeGreaterThan.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is greater than the expected value. 4 | public func beGreaterThan(_ expectedValue: T?) -> NonNilMatcherFunc { 5 | return NonNilMatcherFunc { actualExpression, failureMessage in 6 | failureMessage.postfixMessage = "be greater 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 greater than the expected value. 15 | public func beGreaterThan(_ expectedValue: NMBComparable?) -> NonNilMatcherFunc { 16 | return NonNilMatcherFunc { actualExpression, failureMessage in 17 | failureMessage.postfixMessage = "be greater than <\(stringify(expectedValue))>" 18 | let actualValue = try actualExpression.evaluate() 19 | let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) == ComparisonResult.orderedDescending 20 | return matches 21 | } 22 | } 23 | 24 | public func >(lhs: Expectation, rhs: T) { 25 | lhs.to(beGreaterThan(rhs)) 26 | } 27 | 28 | public func > (lhs: Expectation, rhs: NMBComparable?) { 29 | lhs.to(beGreaterThan(rhs)) 30 | } 31 | 32 | #if _runtime(_ObjC) 33 | extension NMBObjCMatcher { 34 | public class func beGreaterThanMatcher(_ expected: NMBComparable?) -> NMBObjCMatcher { 35 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 36 | let expr = actualExpression.cast { $0 as? NMBComparable } 37 | return try! beGreaterThan(expected).matches(expr, failureMessage: failureMessage) 38 | } 39 | } 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Matchers/BeIdenticalTo.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual value is the same instance 4 | /// as the expected instance. 5 | public func beIdenticalTo(_ expected: Any?) -> NonNilMatcherFunc { 6 | return NonNilMatcherFunc { actualExpression, failureMessage in 7 | #if os(Linux) 8 | let actual = try actualExpression.evaluate() as? AnyObject 9 | #else 10 | let actual = try actualExpression.evaluate() as AnyObject? 11 | #endif 12 | failureMessage.actualValue = "\(identityAsString(actual))" 13 | failureMessage.postfixMessage = "be identical to \(identityAsString(expected))" 14 | #if os(Linux) 15 | return actual === (expected as? AnyObject) && actual !== nil 16 | #else 17 | return actual === (expected as AnyObject?) && actual !== nil 18 | #endif 19 | } 20 | } 21 | 22 | public func === (lhs: Expectation, rhs: Any?) { 23 | lhs.to(beIdenticalTo(rhs)) 24 | } 25 | public func !== (lhs: Expectation, rhs: Any?) { 26 | lhs.toNot(beIdenticalTo(rhs)) 27 | } 28 | 29 | /// A Nimble matcher that succeeds when the actual value is the same instance 30 | /// as the expected instance. 31 | /// 32 | /// Alias for "beIdenticalTo". 33 | public func be(_ expected: Any?) -> NonNilMatcherFunc { 34 | return beIdenticalTo(expected) 35 | } 36 | 37 | #if _runtime(_ObjC) 38 | extension NMBObjCMatcher { 39 | public class func beIdenticalToMatcher(_ expected: NSObject?) -> NMBObjCMatcher { 40 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 41 | let aExpr = actualExpression.cast { $0 as Any? } 42 | return try! beIdenticalTo(expected).matches(aExpr, failureMessage: failureMessage) 43 | } 44 | } 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | } 19 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Matchers/BeginWith.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual sequence's first element 4 | /// is equal to the expected value. 5 | public func beginWith(_ startingElement: T) -> NonNilMatcherFunc 6 | where S.Iterator.Element == T { 7 | return NonNilMatcherFunc { actualExpression, failureMessage in 8 | failureMessage.postfixMessage = "begin with <\(startingElement)>" 9 | if let actualValue = try actualExpression.evaluate() { 10 | var actualGenerator = actualValue.makeIterator() 11 | return actualGenerator.next() == startingElement 12 | } 13 | return false 14 | } 15 | } 16 | 17 | /// A Nimble matcher that succeeds when the actual collection's first element 18 | /// is equal to the expected object. 19 | public func beginWith(_ startingElement: Any) -> NonNilMatcherFunc { 20 | return NonNilMatcherFunc { actualExpression, failureMessage in 21 | failureMessage.postfixMessage = "begin with <\(startingElement)>" 22 | guard let collection = try actualExpression.evaluate() else { return false } 23 | guard collection.count > 0 else { return false } 24 | #if os(Linux) 25 | guard let collectionValue = collection.object(at: 0) as? NSObject else { 26 | return false 27 | } 28 | #else 29 | let collectionValue = collection.object(at: 0) as AnyObject 30 | #endif 31 | return collectionValue.isEqual(startingElement) 32 | } 33 | } 34 | 35 | /// A Nimble matcher that succeeds when the actual string contains expected substring 36 | /// where the expected substring's location is zero. 37 | public func beginWith(_ startingSubstring: String) -> NonNilMatcherFunc { 38 | return NonNilMatcherFunc { actualExpression, failureMessage in 39 | failureMessage.postfixMessage = "begin with <\(startingSubstring)>" 40 | if let actual = try actualExpression.evaluate() { 41 | let range = actual.range(of: startingSubstring) 42 | return range != nil && range!.lowerBound == actual.startIndex 43 | } 44 | return false 45 | } 46 | } 47 | 48 | #if _runtime(_ObjC) 49 | extension NMBObjCMatcher { 50 | public class func beginWithMatcher(_ expected: Any) -> NMBObjCMatcher { 51 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 52 | let actual = try! actualExpression.evaluate() 53 | if let _ = actual as? String { 54 | let expr = actualExpression.cast { $0 as? String } 55 | return try! beginWith(expected as! String).matches(expr, failureMessage: failureMessage) 56 | } else { 57 | let expr = actualExpression.cast { $0 as? NMBOrderedCollection } 58 | return try! beginWith(expected).matches(expr, failureMessage: failureMessage) 59 | } 60 | } 61 | } 62 | } 63 | #endif 64 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Matchers/ContainElementSatisfying.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public func containElementSatisfying(_ predicate: @escaping ((T) -> Bool), _ predicateDescription: String = "") -> NonNilMatcherFunc where S.Iterator.Element == T { 4 | 5 | return NonNilMatcherFunc { actualExpression, failureMessage in 6 | failureMessage.actualValue = nil 7 | 8 | if predicateDescription == "" { 9 | failureMessage.postfixMessage = "find object in collection that satisfies predicate" 10 | } else { 11 | failureMessage.postfixMessage = "find object in collection \(predicateDescription)" 12 | } 13 | 14 | if let sequence = try actualExpression.evaluate() { 15 | for object in sequence { 16 | if predicate(object) { 17 | return true 18 | } 19 | } 20 | 21 | return false 22 | } 23 | 24 | return false 25 | } 26 | } 27 | 28 | #if _runtime(_ObjC) 29 | extension NMBObjCMatcher { 30 | public class func containElementSatisfyingMatcher(_ predicate: @escaping ((NSObject) -> Bool)) -> NMBObjCMatcher { 31 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 32 | let value = try! actualExpression.evaluate() 33 | guard let enumeration = value as? NSFastEnumeration else { 34 | failureMessage.postfixMessage = "containElementSatisfying must be provided an NSFastEnumeration object" 35 | failureMessage.actualValue = nil 36 | failureMessage.expected = "" 37 | failureMessage.to = "" 38 | return false 39 | } 40 | 41 | let iterator = NSFastEnumerationIterator(enumeration) 42 | while let item = iterator.next() { 43 | guard let object = item as? NSObject else { 44 | continue 45 | } 46 | 47 | if predicate(object) { 48 | return true 49 | } 50 | } 51 | 52 | failureMessage.actualValue = nil 53 | failureMessage.postfixMessage = "" 54 | failureMessage.to = "to find object in collection that satisfies predicate" 55 | return false 56 | } 57 | } 58 | } 59 | #endif 60 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Matchers/EndWith.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual sequence's last element 4 | /// is equal to the expected value. 5 | public func endWith(_ endingElement: T) -> NonNilMatcherFunc 6 | where S.Iterator.Element == T { 7 | return NonNilMatcherFunc { actualExpression, failureMessage in 8 | failureMessage.postfixMessage = "end with <\(endingElement)>" 9 | 10 | if let actualValue = try actualExpression.evaluate() { 11 | var actualGenerator = actualValue.makeIterator() 12 | var lastItem: T? 13 | var item: T? 14 | repeat { 15 | lastItem = item 16 | item = actualGenerator.next() 17 | } while(item != nil) 18 | 19 | return lastItem == endingElement 20 | } 21 | return false 22 | } 23 | } 24 | 25 | /// A Nimble matcher that succeeds when the actual collection's last element 26 | /// is equal to the expected object. 27 | public func endWith(_ endingElement: Any) -> NonNilMatcherFunc { 28 | return NonNilMatcherFunc { actualExpression, failureMessage in 29 | failureMessage.postfixMessage = "end with <\(endingElement)>" 30 | guard let collection = try actualExpression.evaluate() else { return false } 31 | guard collection.count > 0 else { return false } 32 | #if os(Linux) 33 | guard let collectionValue = collection.object(at: collection.count - 1) as? NSObject else { 34 | return false 35 | } 36 | #else 37 | let collectionValue = collection.object(at: collection.count - 1) as AnyObject 38 | #endif 39 | 40 | return collectionValue.isEqual(endingElement) 41 | } 42 | } 43 | 44 | /// A Nimble matcher that succeeds when the actual string contains the expected substring 45 | /// where the expected substring's location is the actual string's length minus the 46 | /// expected substring's length. 47 | public func endWith(_ endingSubstring: String) -> NonNilMatcherFunc { 48 | return NonNilMatcherFunc { actualExpression, failureMessage in 49 | failureMessage.postfixMessage = "end with <\(endingSubstring)>" 50 | if let collection = try actualExpression.evaluate() { 51 | return collection.hasSuffix(endingSubstring) 52 | } 53 | return false 54 | } 55 | } 56 | 57 | #if _runtime(_ObjC) 58 | extension NMBObjCMatcher { 59 | public class func endWithMatcher(_ expected: Any) -> NMBObjCMatcher { 60 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 61 | let actual = try! actualExpression.evaluate() 62 | if let _ = actual as? String { 63 | let expr = actualExpression.cast { $0 as? String } 64 | return try! endWith(expected as! String).matches(expr, failureMessage: failureMessage) 65 | } else { 66 | let expr = actualExpression.cast { $0 as? NMBOrderedCollection } 67 | return try! endWith(expected).matches(expr, failureMessage: failureMessage) 68 | } 69 | } 70 | } 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Matchers/Match.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A Nimble matcher that succeeds when the actual string satisfies the regular expression 4 | /// described by the expected string. 5 | public func match(_ expectedValue: String?) -> NonNilMatcherFunc { 6 | return NonNilMatcherFunc { actualExpression, failureMessage in 7 | failureMessage.postfixMessage = "match <\(stringify(expectedValue))>" 8 | 9 | if let actual = try actualExpression.evaluate() { 10 | if let regexp = expectedValue { 11 | return actual.range(of: regexp, options: .regularExpression) != nil 12 | } 13 | } 14 | 15 | return false 16 | } 17 | } 18 | 19 | #if _runtime(_ObjC) 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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) { [weak self] n in 19 | // linux-swift gets confused by .append(n) 20 | 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 | -------------------------------------------------------------------------------- /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 | return satisfyAnyOf(matchers) 8 | } 9 | 10 | internal func satisfyAnyOf(_ matchers: [U]) -> NonNilMatcherFunc 11 | where U: Matcher, U.ValueType == T { 12 | return NonNilMatcherFunc { actualExpression, failureMessage in 13 | let postfixMessages = NSMutableArray() 14 | var matches = false 15 | for matcher in matchers { 16 | if try matcher.matches(actualExpression, failureMessage: failureMessage) { 17 | matches = true 18 | } 19 | postfixMessages.add(NSString(string: "{\(failureMessage.postfixMessage)}")) 20 | } 21 | 22 | failureMessage.postfixMessage = "match one of: " + postfixMessages.componentsJoined(by: ", or ") 23 | if let actualValue = try actualExpression.evaluate() { 24 | failureMessage.actualValue = "\(actualValue)" 25 | } 26 | 27 | return matches 28 | } 29 | } 30 | 31 | public func || (left: NonNilMatcherFunc, right: NonNilMatcherFunc) -> NonNilMatcherFunc { 32 | return satisfyAnyOf(left, right) 33 | } 34 | 35 | public func || (left: MatcherFunc, right: MatcherFunc) -> NonNilMatcherFunc { 36 | return satisfyAnyOf(left, right) 37 | } 38 | 39 | #if _runtime(_ObjC) 40 | extension NMBObjCMatcher { 41 | public class func satisfyAnyOfMatcher(_ matchers: [NMBObjCMatcher]) -> NMBObjCMatcher { 42 | return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in 43 | if matchers.isEmpty { 44 | failureMessage.stringValue = "satisfyAnyOf must be called with at least one matcher" 45 | return false 46 | } 47 | 48 | var elementEvaluators = [NonNilMatcherFunc]() 49 | for matcher in matchers { 50 | let elementEvaluator: (Expression, FailureMessage) -> Bool = { 51 | expression, failureMessage in 52 | return matcher.matches({try! expression.evaluate()}, failureMessage: failureMessage, location: actualExpression.location) 53 | } 54 | 55 | elementEvaluators.append(NonNilMatcherFunc(elementEvaluator)) 56 | } 57 | 58 | return try! satisfyAnyOf(elementEvaluators).matches(actualExpression, failureMessage: failureMessage) 59 | } 60 | } 61 | } 62 | #endif 63 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public func throwAssertion() -> MatcherFunc { 4 | return MatcherFunc { actualExpression, failureMessage in 5 | #if arch(x86_64) && _runtime(_ObjC) && !SWIFT_PACKAGE 6 | failureMessage.postfixMessage = "throw an assertion" 7 | failureMessage.actualValue = nil 8 | 9 | var succeeded = true 10 | 11 | let caughtException: BadInstructionException? = catchBadInstruction { 12 | #if os(tvOS) 13 | if !NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning { 14 | print() 15 | print("[Nimble Warning]: If you're getting stuck on a debugger breakpoint for a " + 16 | "fatal error while using throwAssertion(), please disable 'Debug Executable' " + 17 | "in your scheme. Go to 'Edit Scheme > Test > Info' and uncheck " + 18 | "'Debug Executable'. If you've already done that, suppress this warning " + 19 | "by setting `NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning = true`. " + 20 | "This is required because the standard methods of catching assertions " + 21 | "(mach APIs) are unavailable for tvOS. Instead, the same mechanism the " + 22 | "debugger uses is the fallback method for tvOS." 23 | ) 24 | print() 25 | NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning = true 26 | } 27 | #endif 28 | do { 29 | try actualExpression.evaluate() 30 | } catch let error { 31 | succeeded = false 32 | failureMessage.postfixMessage += "; threw error instead <\(error)>" 33 | } 34 | } 35 | 36 | if !succeeded { 37 | return false 38 | } 39 | 40 | if caughtException == nil { 41 | return false 42 | } 43 | 44 | return true 45 | #elseif SWIFT_PACKAGE 46 | fatalError("The throwAssertion Nimble matcher does not currently support Swift CLI." + 47 | " You can silence this error by placing the test case inside an #if !SWIFT_PACKAGE" + 48 | " conditional statement") 49 | #else 50 | fatalError("The throwAssertion Nimble matcher can only run on x86_64 platforms with " + 51 | "Objective-C (e.g. Mac, iPhone 5s or later simulators). You can silence this error " + 52 | "by placing the test case inside an #if arch(x86_64) or _runtime(_ObjC) conditional statement") 53 | #endif 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Pods/Nimble/Sources/Nimble/Nimble.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import "NMBExceptionCapture.h" 3 | #import "NMBStringify.h" 4 | #import "DSL.h" 5 | 6 | #import "CwlPreconditionTesting.h" 7 | 8 | FOUNDATION_EXPORT double NimbleVersionNumber; 9 | FOUNDATION_EXPORT const unsigned char NimbleVersionString[]; 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 SWIFT_PACKAGE 9 | public typealias FileString = StaticString 10 | #else 11 | public typealias FileString = String 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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:(__attribute__((noescape)) void(^ _Nonnull)())unsafeBlock NS_SWIFT_NAME(tryBlock(_:)); 8 | 9 | @end 10 | 11 | typedef void(^NMBSourceCallbackBlock)(BOOL successful); 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Pods/Quick/README.md: -------------------------------------------------------------------------------- 1 | ![](http://f.cl.ly/items/0r1E192C1R0b2g2Q3h2w/QuickLogo_Color.png) 2 | 3 | [![Build Status](https://travis-ci.org/Quick/Quick.svg?branch=master)](https://travis-ci.org/Quick/Quick) 4 | [![CocoaPods](https://img.shields.io/cocoapods/v/Quick.svg)](https://cocoapods.org/pods/Quick) 5 | [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 6 | [![Platforms](https://img.shields.io/cocoapods/p/Quick.svg)](https://cocoapods.org/pods/Quick) 7 | 8 | Quick is a behavior-driven development framework for Swift and Objective-C. 9 | Inspired by [RSpec](https://github.com/rspec/rspec), [Specta](https://github.com/specta/specta), and [Ginkgo](https://github.com/onsi/ginkgo). 10 | 11 | ![](https://raw.githubusercontent.com/Quick/Assets/master/Screenshots/QuickSpec%20screenshot.png) 12 | 13 | ```swift 14 | // Swift 15 | 16 | import Quick 17 | import Nimble 18 | 19 | class TableOfContentsSpec: QuickSpec { 20 | override func spec() { 21 | describe("the 'Documentation' directory") { 22 | it("has everything you need to get started") { 23 | let sections = Directory("Documentation").sections 24 | expect(sections).to(contain("Organized Tests with Quick Examples and Example Groups")) 25 | expect(sections).to(contain("Installing Quick")) 26 | } 27 | 28 | context("if it doesn't have what you're looking for") { 29 | it("needs to be updated") { 30 | let you = You(awesome: true) 31 | expect{you.submittedAnIssue}.toEventually(beTruthy()) 32 | } 33 | } 34 | } 35 | } 36 | } 37 | ``` 38 | #### Nimble 39 | Quick comes together with [Nimble](https://github.com/Quick/Nimble) — a matcher framework for your tests. You can learn why `XCTAssert()` statements make your expectations unclear and how to fix that using Nimble assertions [here](./Documentation/en-us/NimbleAssertions.md). 40 | 41 | ## Swift Version 42 | 43 | Certain versions of Quick and Nimble only support certain versions of Swift. Depending on which version of Swift your project uses, you should use specific versions of Quick and Nimble. Use the table below to determine which versions of Quick and Nimble are compatible with your project. 44 | 45 | |Swift version |Quick version |Nimble version | 46 | |:--------------------|:---------------|:--------------| 47 | |Swift 3 |v1.0.0 or later |v5.0.0 or later| 48 | |Swift 2.2 / Swift 2.3|v0.9.3 |v4.1.0 | 49 | 50 | ## Documentation 51 | 52 | All documentation can be found in the [Documentation folder](./Documentation), including [detailed installation instructions](./Documentation/en-us/InstallingQuick.md) for CocoaPods, Carthage, Git submodules, and more. For example, you can install Quick and [Nimble](https://github.com/Quick/Nimble) using CocoaPods by adding the following to your Podfile: 53 | 54 | ```rb 55 | # Podfile 56 | 57 | use_frameworks! 58 | 59 | target "MyApp" do 60 | # Normal libraries 61 | 62 | abstract_target 'Tests' do 63 | inherit! :search_paths 64 | target "MyAppTests" 65 | target "MyAppUITests" 66 | 67 | pod 'Quick' 68 | pod 'Nimble' 69 | end 70 | end 71 | ``` 72 | 73 | ## Projects using Quick 74 | 75 | Over ten-thousand apps use either Quick and Nimble however, as they are not included in the app binary, neither appear in “Top Used Libraries” blog posts. Therefore, it would be greatly appreciated to remind contributors that their efforts are valued by compiling a list of organizations and projects that use them. 76 | 77 | Does your organization or project use Quick and Nimble? If yes, [please add your project to the list](https://github.com/Quick/Quick/wiki/Projects-using-Quick). 78 | 79 | ## Who uses Quick 80 | 81 | Similar to projects using Quick, it would be nice to hear why people use Quick and Nimble. Are there features you love? Are there features that are just okay? Are there some features we have that no one uses? 82 | 83 | Have something positive to say about Quick (or Nimble)? If yes, [provide a testimonial here](https://github.com/Quick/Quick/wiki/Who-uses-Quick). 84 | 85 | 86 | ## License 87 | 88 | Apache 2.0 license. See the [`LICENSE`](LICENSE) file for details. 89 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/Callsite.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /** 4 | An object encapsulating the file and line number at which 5 | a particular example is defined. 6 | */ 7 | final public class Callsite: NSObject { 8 | /** 9 | The absolute path of the file in which an example is defined. 10 | */ 11 | public let file: String 12 | 13 | /** 14 | The line number on which an example is defined. 15 | */ 16 | public let line: UInt 17 | 18 | internal init(file: String, line: UInt) { 19 | self.file = file 20 | self.line = line 21 | } 22 | } 23 | 24 | extension Callsite { 25 | /** 26 | Returns a boolean indicating whether two Callsite objects are equal. 27 | If two callsites are in the same file and on the same line, they must be equal. 28 | */ 29 | @nonobjc public static func == (lhs: Callsite, rhs: Callsite) -> Bool { 30 | return lhs.file == rhs.file && lhs.line == rhs.line 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/ErrorUtility.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | internal func raiseError(_ message: String) -> Never { 4 | #if _runtime(_ObjC) 5 | NSException(name: .internalInconsistencyException, reason: message, userInfo: nil).raise() 6 | #endif 7 | 8 | // This won't be reached when ObjC is available and the exception above is raisd 9 | fatalError(message) 10 | } 11 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/Example.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | private var numberOfExamplesRun = 0 4 | 5 | /** 6 | Examples, defined with the `it` function, use assertions to 7 | demonstrate how code should behave. These are like "tests" in XCTest. 8 | */ 9 | final public class Example: NSObject { 10 | /** 11 | A boolean indicating whether the example is a shared example; 12 | i.e.: whether it is an example defined with `itBehavesLike`. 13 | */ 14 | public var isSharedExample = false 15 | 16 | /** 17 | The site at which the example is defined. 18 | This must be set correctly in order for Xcode to highlight 19 | the correct line in red when reporting a failure. 20 | */ 21 | public var callsite: Callsite 22 | 23 | weak internal var group: ExampleGroup? 24 | 25 | private let internalDescription: String 26 | private let closure: () -> Void 27 | private let flags: FilterFlags 28 | 29 | internal init(description: String, callsite: Callsite, flags: FilterFlags, closure: @escaping () -> Void) { 30 | self.internalDescription = description 31 | self.closure = closure 32 | self.callsite = callsite 33 | self.flags = flags 34 | } 35 | 36 | public override var description: String { 37 | return internalDescription 38 | } 39 | 40 | /** 41 | The example name. A name is a concatenation of the name of 42 | the example group the example belongs to, followed by the 43 | description of the example itself. 44 | 45 | The example name is used to generate a test method selector 46 | to be displayed in Xcode's test navigator. 47 | */ 48 | public var name: String { 49 | guard let groupName = group?.name else { return description } 50 | return "\(groupName), \(description)" 51 | } 52 | 53 | /** 54 | Executes the example closure, as well as all before and after 55 | closures defined in the its surrounding example groups. 56 | */ 57 | public func run() { 58 | let world = World.sharedWorld 59 | 60 | if numberOfExamplesRun == 0 { 61 | world.suiteHooks.executeBefores() 62 | } 63 | 64 | let exampleMetadata = ExampleMetadata(example: self, exampleIndex: numberOfExamplesRun) 65 | world.currentExampleMetadata = exampleMetadata 66 | 67 | world.exampleHooks.executeBefores(exampleMetadata) 68 | group!.phase = .beforesExecuting 69 | for before in group!.befores { 70 | before(exampleMetadata) 71 | } 72 | group!.phase = .beforesFinished 73 | 74 | closure() 75 | 76 | group!.phase = .aftersExecuting 77 | for after in group!.afters { 78 | after(exampleMetadata) 79 | } 80 | group!.phase = .aftersFinished 81 | world.exampleHooks.executeAfters(exampleMetadata) 82 | 83 | numberOfExamplesRun += 1 84 | 85 | if !world.isRunningAdditionalSuites && numberOfExamplesRun >= world.includedExampleCount { 86 | world.suiteHooks.executeAfters() 87 | } 88 | } 89 | 90 | /** 91 | Evaluates the filter flags set on this example and on the example groups 92 | this example belongs to. Flags set on the example are trumped by flags on 93 | the example group it belongs to. Flags on inner example groups are trumped 94 | by flags on outer example groups. 95 | */ 96 | internal var filterFlags: FilterFlags { 97 | var aggregateFlags = flags 98 | for (key, value) in group!.filterFlags { 99 | aggregateFlags[key] = value 100 | } 101 | return aggregateFlags 102 | } 103 | } 104 | 105 | extension Example { 106 | /** 107 | Returns a boolean indicating whether two Example objects are equal. 108 | If two examples are defined at the exact same callsite, they must be equal. 109 | */ 110 | @nonobjc public static func == (lhs: Example, rhs: Example) -> Bool { 111 | return lhs.callsite == rhs.callsite 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/ExampleGroup.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /** 4 | Example groups are logical groupings of examples, defined with 5 | the `describe` and `context` functions. Example groups can share 6 | setup and teardown code. 7 | */ 8 | final public class ExampleGroup: NSObject { 9 | weak internal var parent: ExampleGroup? 10 | internal let hooks = ExampleHooks() 11 | 12 | internal var phase: HooksPhase = .nothingExecuted 13 | 14 | private let internalDescription: String 15 | private let flags: FilterFlags 16 | private let isInternalRootExampleGroup: Bool 17 | private var childGroups = [ExampleGroup]() 18 | private var childExamples = [Example]() 19 | 20 | internal init(description: String, flags: FilterFlags, isInternalRootExampleGroup: Bool = false) { 21 | self.internalDescription = description 22 | self.flags = flags 23 | self.isInternalRootExampleGroup = isInternalRootExampleGroup 24 | } 25 | 26 | public override var description: String { 27 | return internalDescription 28 | } 29 | 30 | /** 31 | Returns a list of examples that belong to this example group, 32 | or to any of its descendant example groups. 33 | */ 34 | public var examples: [Example] { 35 | var examples = childExamples 36 | for group in childGroups { 37 | examples.append(contentsOf: group.examples) 38 | } 39 | return examples 40 | } 41 | 42 | internal var name: String? { 43 | if let parent = parent { 44 | guard let name = parent.name else { return description } 45 | return "\(name), \(description)" 46 | } else { 47 | return isInternalRootExampleGroup ? nil : description 48 | } 49 | } 50 | 51 | internal var filterFlags: FilterFlags { 52 | var aggregateFlags = flags 53 | walkUp { group in 54 | for (key, value) in group.flags { 55 | aggregateFlags[key] = value 56 | } 57 | } 58 | return aggregateFlags 59 | } 60 | 61 | internal var befores: [BeforeExampleWithMetadataClosure] { 62 | var closures = Array(hooks.befores.reversed()) 63 | walkUp { group in 64 | closures.append(contentsOf: Array(group.hooks.befores.reversed())) 65 | } 66 | return Array(closures.reversed()) 67 | } 68 | 69 | internal var afters: [AfterExampleWithMetadataClosure] { 70 | var closures = hooks.afters 71 | walkUp { group in 72 | closures.append(contentsOf: group.hooks.afters) 73 | } 74 | return closures 75 | } 76 | 77 | internal func walkDownExamples(_ callback: (_ example: Example) -> Void) { 78 | for example in childExamples { 79 | callback(example) 80 | } 81 | for group in childGroups { 82 | group.walkDownExamples(callback) 83 | } 84 | } 85 | 86 | internal func appendExampleGroup(_ group: ExampleGroup) { 87 | group.parent = self 88 | childGroups.append(group) 89 | } 90 | 91 | internal func appendExample(_ example: Example) { 92 | example.group = self 93 | childExamples.append(example) 94 | } 95 | 96 | private func walkUp(_ callback: (_ group: ExampleGroup) -> Void) { 97 | var group = self 98 | while let parent = group.parent { 99 | callback(parent) 100 | group = parent 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/ExampleMetadata.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /** 4 | A class that encapsulates information about an example, 5 | including the index at which the example was executed, as 6 | well as the example itself. 7 | */ 8 | final public class ExampleMetadata: NSObject { 9 | /** 10 | The example for which this metadata was collected. 11 | */ 12 | public let example: Example 13 | 14 | /** 15 | The index at which this example was executed in the 16 | test suite. 17 | */ 18 | public let exampleIndex: Int 19 | 20 | internal init(example: Example, exampleIndex: Int) { 21 | self.example = example 22 | self.exampleIndex = exampleIndex 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/Filter.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /** 4 | A mapping of string keys to booleans that can be used to 5 | filter examples or example groups. For example, a "focused" 6 | example would have the flags [Focused: true]. 7 | */ 8 | public typealias FilterFlags = [String: Bool] 9 | 10 | /** 11 | A namespace for filter flag keys, defined primarily to make the 12 | keys available in Objective-C. 13 | */ 14 | final public class Filter: NSObject { 15 | /** 16 | Example and example groups with [Focused: true] are included in test runs, 17 | excluding all other examples without this flag. Use this to only run one or 18 | two tests that you're currently focusing on. 19 | */ 20 | public class var focused: String { 21 | return "focused" 22 | } 23 | 24 | /** 25 | Example and example groups with [Pending: true] are excluded from test runs. 26 | Use this to temporarily suspend examples that you know do not pass yet. 27 | */ 28 | public class var pending: String { 29 | return "pending" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/Hooks/Closures.swift: -------------------------------------------------------------------------------- 1 | // MARK: Example Hooks 2 | 3 | /** 4 | A closure executed before an example is run. 5 | */ 6 | public typealias BeforeExampleClosure = () -> Void 7 | 8 | /** 9 | A closure executed before an example is run. The closure is given example metadata, 10 | which contains information about the example that is about to be run. 11 | */ 12 | public typealias BeforeExampleWithMetadataClosure = (_ exampleMetadata: ExampleMetadata) -> Void 13 | 14 | /** 15 | A closure executed after an example is run. 16 | */ 17 | public typealias AfterExampleClosure = BeforeExampleClosure 18 | 19 | /** 20 | A closure executed after an example is run. The closure is given example metadata, 21 | which contains information about the example that has just finished running. 22 | */ 23 | public typealias AfterExampleWithMetadataClosure = BeforeExampleWithMetadataClosure 24 | 25 | // MARK: Suite Hooks 26 | 27 | /** 28 | A closure executed before any examples are run. 29 | */ 30 | public typealias BeforeSuiteClosure = () -> Void 31 | 32 | /** 33 | A closure executed after all examples have finished running. 34 | */ 35 | public typealias AfterSuiteClosure = BeforeSuiteClosure 36 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/Hooks/ExampleHooks.swift: -------------------------------------------------------------------------------- 1 | /** 2 | A container for closures to be executed before and after each example. 3 | */ 4 | final internal class ExampleHooks { 5 | internal var befores: [BeforeExampleWithMetadataClosure] = [] 6 | internal var afters: [AfterExampleWithMetadataClosure] = [] 7 | internal var phase: HooksPhase = .nothingExecuted 8 | 9 | internal func appendBefore(_ closure: @escaping BeforeExampleWithMetadataClosure) { 10 | befores.append(closure) 11 | } 12 | 13 | internal func appendBefore(_ closure: @escaping BeforeExampleClosure) { 14 | befores.append { (_: ExampleMetadata) in closure() } 15 | } 16 | 17 | internal func appendAfter(_ closure: @escaping AfterExampleWithMetadataClosure) { 18 | afters.append(closure) 19 | } 20 | 21 | internal func appendAfter(_ closure: @escaping AfterExampleClosure) { 22 | afters.append { (_: ExampleMetadata) in closure() } 23 | } 24 | 25 | internal func executeBefores(_ exampleMetadata: ExampleMetadata) { 26 | phase = .beforesExecuting 27 | for before in befores { 28 | before(exampleMetadata) 29 | } 30 | 31 | phase = .beforesFinished 32 | } 33 | 34 | internal func executeAfters(_ exampleMetadata: ExampleMetadata) { 35 | phase = .aftersExecuting 36 | for after in afters { 37 | after(exampleMetadata) 38 | } 39 | 40 | phase = .aftersFinished 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/Hooks/HooksPhase.swift: -------------------------------------------------------------------------------- 1 | /** 2 | A description of the execution cycle of the current example with 3 | respect to the hooks of that example. 4 | */ 5 | internal enum HooksPhase { 6 | case nothingExecuted 7 | case beforesExecuting 8 | case beforesFinished 9 | case aftersExecuting 10 | case aftersFinished 11 | } 12 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/Hooks/SuiteHooks.swift: -------------------------------------------------------------------------------- 1 | /** 2 | A container for closures to be executed before and after all examples. 3 | */ 4 | final internal class SuiteHooks { 5 | internal var befores: [BeforeSuiteClosure] = [] 6 | internal var afters: [AfterSuiteClosure] = [] 7 | internal var phase: HooksPhase = .nothingExecuted 8 | 9 | internal func appendBefore(_ closure: @escaping BeforeSuiteClosure) { 10 | befores.append(closure) 11 | } 12 | 13 | internal func appendAfter(_ closure: @escaping AfterSuiteClosure) { 14 | afters.append(closure) 15 | } 16 | 17 | internal func executeBefores() { 18 | phase = .beforesExecuting 19 | for before in befores { 20 | before() 21 | } 22 | phase = .beforesFinished 23 | } 24 | 25 | internal func executeAfters() { 26 | phase = .aftersExecuting 27 | for after in afters { 28 | after() 29 | } 30 | phase = .aftersFinished 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/NSBundle+CurrentTestBundle.swift: -------------------------------------------------------------------------------- 1 | #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) 2 | 3 | import Foundation 4 | 5 | extension Bundle { 6 | 7 | /** 8 | Locates the first bundle with a '.xctest' file extension. 9 | */ 10 | internal static var currentTestBundle: Bundle? { 11 | return allBundles.first { $0.bundlePath.hasSuffix(".xctest") } 12 | } 13 | 14 | /** 15 | Return the module name of the bundle. 16 | Uses the bundle filename and transform it to match Xcode's transformation. 17 | Module name has to be a valid "C99 extended identifier". 18 | */ 19 | internal var moduleName: String { 20 | let fileName = bundleURL.fileName as NSString 21 | return fileName.c99ExtendedIdentifier 22 | } 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/NSString+C99ExtendedIdentifier.swift: -------------------------------------------------------------------------------- 1 | #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) 2 | import Foundation 3 | 4 | public extension NSString { 5 | 6 | private static var invalidCharacters: CharacterSet = { 7 | var invalidCharacters = CharacterSet() 8 | 9 | let invalidCharacterSets: [CharacterSet] = [ 10 | .whitespacesAndNewlines, 11 | .illegalCharacters, 12 | .controlCharacters, 13 | .punctuationCharacters, 14 | .nonBaseCharacters, 15 | .symbols, 16 | ] 17 | 18 | for invalidSet in invalidCharacterSets { 19 | invalidCharacters.formUnion(invalidSet) 20 | } 21 | 22 | return invalidCharacters 23 | }() 24 | 25 | @objc(qck_c99ExtendedIdentifier) 26 | var c99ExtendedIdentifier: String { 27 | let validComponents = components(separatedBy: NSString.invalidCharacters) 28 | let result = validComponents.joined(separator: "_") 29 | 30 | return result.isEmpty ? "_" : result 31 | } 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/QuickSelectedTestSuiteBuilder.swift: -------------------------------------------------------------------------------- 1 | #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) 2 | import Foundation 3 | 4 | /** 5 | Responsible for building a "Selected tests" suite. This corresponds to a single 6 | spec, and all its examples. 7 | */ 8 | internal class QuickSelectedTestSuiteBuilder: QuickTestSuiteBuilder { 9 | 10 | /** 11 | The test spec class to run. 12 | */ 13 | let testCaseClass: AnyClass! 14 | 15 | /** 16 | For Objective-C classes, returns the class name. For Swift classes without, 17 | an explicit Objective-C name, returns a module-namespaced class name 18 | (e.g., "FooTests.FooSpec"). 19 | */ 20 | var testSuiteClassName: String { 21 | return NSStringFromClass(testCaseClass) 22 | } 23 | 24 | /** 25 | Given a test case name: 26 | 27 | FooSpec/testFoo 28 | 29 | Optionally constructs a test suite builder for the named test case class 30 | in the running test bundle. 31 | 32 | If no test bundle can be found, or the test case class can't be found, 33 | initialization fails and returns `nil`. 34 | */ 35 | init?(forTestCaseWithName name: String) { 36 | guard let testCaseClass = testCaseClassForTestCaseWithName(name) else { 37 | self.testCaseClass = nil 38 | return nil 39 | } 40 | 41 | self.testCaseClass = testCaseClass 42 | } 43 | 44 | /** 45 | Returns a `QuickTestSuite` that runs the associated test case class. 46 | */ 47 | func buildTestSuite() -> QuickTestSuite { 48 | return QuickTestSuite(forTestCaseClass: testCaseClass) 49 | } 50 | 51 | } 52 | 53 | /** 54 | Searches `Bundle.allBundles()` for an xctest bundle, then looks up the named 55 | test case class in that bundle. 56 | 57 | Returns `nil` if a bundle or test case class cannot be found. 58 | */ 59 | private func testCaseClassForTestCaseWithName(_ name: String) -> AnyClass? { 60 | func extractClassName(_ name: String) -> String? { 61 | return name.components(separatedBy: "/").first 62 | } 63 | 64 | guard let className = extractClassName(name) else { return nil } 65 | guard let bundle = Bundle.currentTestBundle else { return nil } 66 | 67 | if let testCaseClass = bundle.classNamed(className) { return testCaseClass } 68 | 69 | let moduleName = bundle.moduleName 70 | 71 | return NSClassFromString("\(moduleName).\(className)") 72 | } 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/QuickTestSuite.swift: -------------------------------------------------------------------------------- 1 | #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) 2 | 3 | import XCTest 4 | 5 | /** 6 | This protocol defines the role of an object that builds test suites. 7 | */ 8 | internal protocol QuickTestSuiteBuilder { 9 | 10 | /** 11 | Construct a `QuickTestSuite` instance with the appropriate test cases added as tests. 12 | 13 | Subsequent calls to this method should return equivalent test suites. 14 | */ 15 | func buildTestSuite() -> QuickTestSuite 16 | 17 | } 18 | 19 | /** 20 | A base class for a class cluster of Quick test suites, that should correctly 21 | build dynamic test suites for XCTest to execute. 22 | */ 23 | public class QuickTestSuite: XCTestSuite { 24 | 25 | private static var builtTestSuites: Set = Set() 26 | 27 | /** 28 | Construct a test suite for a specific, selected subset of test cases (rather 29 | than the default, which as all test cases). 30 | 31 | If this method is called multiple times for the same test case class, e.g.. 32 | 33 | FooSpec/testFoo 34 | FooSpec/testBar 35 | 36 | It is expected that the first call should return a valid test suite, and 37 | all subsequent calls should return `nil`. 38 | */ 39 | public static func selectedTestSuite(forTestCaseWithName name: String) -> QuickTestSuite? { 40 | guard let builder = QuickSelectedTestSuiteBuilder(forTestCaseWithName: name) else { return nil } 41 | 42 | if builtTestSuites.contains(builder.testSuiteClassName) { 43 | return nil 44 | } else { 45 | builtTestSuites.insert(builder.testSuiteClassName) 46 | return builder.buildTestSuite() 47 | } 48 | } 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/Quick/URL+FileName.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | extension URL { 4 | 5 | /** 6 | Returns the path file name without file extension. 7 | */ 8 | var fileName: String { 9 | return self.deletingPathExtension().lastPathComponent 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickObjectiveC/Configuration/QuickConfiguration.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class Configuration; 4 | 5 | /** 6 | Subclass QuickConfiguration and override the +[QuickConfiguration configure:] 7 | method in order to configure how Quick behaves when running specs, or to define 8 | shared examples that are used across spec files. 9 | */ 10 | @interface QuickConfiguration : NSObject 11 | 12 | /** 13 | This method is executed on each subclass of this class before Quick runs 14 | any examples. You may override this method on as many subclasses as you like, but 15 | there is no guarantee as to the order in which these methods are executed. 16 | 17 | You can override this method in order to: 18 | 19 | 1. Configure how Quick behaves, by modifying properties on the Configuration object. 20 | Setting the same properties in several methods has undefined behavior. 21 | 22 | 2. Define shared examples using `sharedExamples`. 23 | 24 | @param configuration A mutable object that is used to configure how Quick behaves on 25 | a framework level. For details on all the options, see the 26 | documentation in Configuration.swift. 27 | */ 28 | + (void)configure:(Configuration *)configuration; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickObjectiveC/Configuration/QuickConfiguration.m: -------------------------------------------------------------------------------- 1 | #import "QuickConfiguration.h" 2 | #import "World.h" 3 | #import 4 | 5 | typedef void (^QCKClassEnumerationBlock)(Class klass); 6 | 7 | /** 8 | Finds all direct subclasses of the given class and passes them to the block provided. 9 | The classes are iterated over in the order that objc_getClassList returns them. 10 | 11 | @param klass The base class to find subclasses of. 12 | @param block A block that takes a Class. This block will be executed once for each subclass of klass. 13 | */ 14 | void qck_enumerateSubclasses(Class klass, QCKClassEnumerationBlock block) { 15 | Class *classes = NULL; 16 | int classesCount = objc_getClassList(NULL, 0); 17 | 18 | if (classesCount > 0) { 19 | classes = (Class *)calloc(sizeof(Class), classesCount); 20 | classesCount = objc_getClassList(classes, classesCount); 21 | 22 | Class subclass, superclass; 23 | for(int i = 0; i < classesCount; i++) { 24 | subclass = classes[i]; 25 | superclass = class_getSuperclass(subclass); 26 | if (superclass == klass && block) { 27 | block(subclass); 28 | } 29 | } 30 | 31 | free(classes); 32 | } 33 | } 34 | 35 | @implementation QuickConfiguration 36 | 37 | #pragma mark - Object Lifecycle 38 | 39 | /** 40 | QuickConfiguration is not meant to be instantiated; it merely provides a hook 41 | for users to configure how Quick behaves. Raise an exception if an instance of 42 | QuickConfiguration is created. 43 | */ 44 | - (instancetype)init { 45 | NSString *className = NSStringFromClass([self class]); 46 | NSString *selectorName = NSStringFromSelector(@selector(configure:)); 47 | [NSException raise:NSInternalInconsistencyException 48 | format:@"%@ is not meant to be instantiated; " 49 | @"subclass %@ and override %@ to configure Quick.", 50 | className, className, selectorName]; 51 | return nil; 52 | } 53 | 54 | #pragma mark - NSObject Overrides 55 | 56 | /** 57 | Hook into when QuickConfiguration is initialized in the runtime in order to 58 | call +[QuickConfiguration configure:] on each of its subclasses. 59 | */ 60 | + (void)initialize { 61 | // Only enumerate over the subclasses of QuickConfiguration, not any of its subclasses. 62 | if ([self class] == [QuickConfiguration class]) { 63 | 64 | // Only enumerate over subclasses once, even if +[QuickConfiguration initialize] 65 | // were to be called several times. This is necessary because +[QuickSpec initialize] 66 | // manually calls +[QuickConfiguration initialize]. 67 | static dispatch_once_t onceToken; 68 | dispatch_once(&onceToken, ^{ 69 | qck_enumerateSubclasses([QuickConfiguration class], ^(__unsafe_unretained Class klass) { 70 | [[World sharedWorld] configure:^(Configuration *configuration) { 71 | [klass configure:configuration]; 72 | }]; 73 | }); 74 | [[World sharedWorld] finalizeConfiguration]; 75 | }); 76 | } 77 | } 78 | 79 | #pragma mark - Public Interface 80 | 81 | + (void)configure:(Configuration *)configuration { } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickObjectiveC/DSL/QCKDSL.m: -------------------------------------------------------------------------------- 1 | #import "QCKDSL.h" 2 | #import "World.h" 3 | #import "World+DSL.h" 4 | 5 | void qck_beforeSuite(QCKDSLEmptyBlock closure) { 6 | [[World sharedWorld] beforeSuite:closure]; 7 | } 8 | 9 | void qck_afterSuite(QCKDSLEmptyBlock closure) { 10 | [[World sharedWorld] afterSuite:closure]; 11 | } 12 | 13 | void qck_sharedExamples(NSString *name, QCKDSLSharedExampleBlock closure) { 14 | [[World sharedWorld] sharedExamples:name closure:closure]; 15 | } 16 | 17 | void qck_describe(NSString *description, QCKDSLEmptyBlock closure) { 18 | [[World sharedWorld] describe:description flags:@{} closure:closure]; 19 | } 20 | 21 | void qck_context(NSString *description, QCKDSLEmptyBlock closure) { 22 | qck_describe(description, closure); 23 | } 24 | 25 | void qck_beforeEach(QCKDSLEmptyBlock closure) { 26 | [[World sharedWorld] beforeEach:closure]; 27 | } 28 | 29 | void qck_beforeEachWithMetadata(QCKDSLExampleMetadataBlock closure) { 30 | [[World sharedWorld] beforeEachWithMetadata:closure]; 31 | } 32 | 33 | void qck_afterEach(QCKDSLEmptyBlock closure) { 34 | [[World sharedWorld] afterEach:closure]; 35 | } 36 | 37 | void qck_afterEachWithMetadata(QCKDSLExampleMetadataBlock closure) { 38 | [[World sharedWorld] afterEachWithMetadata:closure]; 39 | } 40 | 41 | QCKItBlock qck_it_builder(NSDictionary *flags, NSString *file, NSUInteger line) { 42 | return ^(NSString *description, QCKDSLEmptyBlock closure) { 43 | [[World sharedWorld] itWithDescription:description 44 | flags:flags 45 | file:file 46 | line:line 47 | closure:closure]; 48 | }; 49 | } 50 | 51 | QCKItBehavesLikeBlock qck_itBehavesLike_builder(NSDictionary *flags, NSString *file, NSUInteger line) { 52 | return ^(NSString *name, QCKDSLSharedExampleContext context) { 53 | [[World sharedWorld] itBehavesLikeSharedExampleNamed:name 54 | sharedExampleContext:context 55 | flags:flags 56 | file:file 57 | line:line]; 58 | }; 59 | } 60 | 61 | void qck_pending(NSString *description, QCKDSLEmptyBlock closure) { 62 | [[World sharedWorld] pending:description closure:closure]; 63 | } 64 | 65 | void qck_xdescribe(NSString *description, QCKDSLEmptyBlock closure) { 66 | [[World sharedWorld] xdescribe:description flags:@{} closure:closure]; 67 | } 68 | 69 | void qck_xcontext(NSString *description, QCKDSLEmptyBlock closure) { 70 | qck_xdescribe(description, closure); 71 | } 72 | 73 | void qck_fdescribe(NSString *description, QCKDSLEmptyBlock closure) { 74 | [[World sharedWorld] fdescribe:description flags:@{} closure:closure]; 75 | } 76 | 77 | void qck_fcontext(NSString *description, QCKDSLEmptyBlock closure) { 78 | qck_fdescribe(description, closure); 79 | } 80 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickObjectiveC/DSL/World+DSL.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface World (SWIFT_EXTENSION(Quick)) 4 | - (void)beforeSuite:(void (^ __nonnull)(void))closure; 5 | - (void)afterSuite:(void (^ __nonnull)(void))closure; 6 | - (void)sharedExamples:(NSString * __nonnull)name closure:(void (^ __nonnull)(NSDictionary * __nonnull (^ __nonnull)(void)))closure; 7 | - (void)describe:(NSString * __nonnull)description flags:(NSDictionary * __nonnull)flags closure:(void (^ __nonnull)(void))closure; 8 | - (void)context:(NSString * __nonnull)description flags:(NSDictionary * __nonnull)flags closure:(void (^ __nonnull)(void))closure; 9 | - (void)fdescribe:(NSString * __nonnull)description flags:(NSDictionary * __nonnull)flags closure:(void (^ __nonnull)(void))closure; 10 | - (void)xdescribe:(NSString * __nonnull)description flags:(NSDictionary * __nonnull)flags closure:(void (^ __nonnull)(void))closure; 11 | - (void)beforeEach:(void (^ __nonnull)(void))closure; 12 | - (void)beforeEachWithMetadata:(void (^ __nonnull)(ExampleMetadata * __nonnull))closure; 13 | - (void)afterEach:(void (^ __nonnull)(void))closure; 14 | - (void)afterEachWithMetadata:(void (^ __nonnull)(ExampleMetadata * __nonnull))closure; 15 | - (void)itWithDescription:(NSString * __nonnull)description flags:(NSDictionary * __nonnull)flags file:(NSString * __nonnull)file line:(NSUInteger)line closure:(void (^ __nonnull)(void))closure; 16 | - (void)fitWithDescription:(NSString * __nonnull)description flags:(NSDictionary * __nonnull)flags file:(NSString * __nonnull)file line:(NSUInteger)line closure:(void (^ __nonnull)(void))closure; 17 | - (void)xitWithDescription:(NSString * __nonnull)description flags:(NSDictionary * __nonnull)flags file:(NSString * __nonnull)file line:(NSUInteger)line closure:(void (^ __nonnull)(void))closure; 18 | - (void)itBehavesLikeSharedExampleNamed:(NSString * __nonnull)name sharedExampleContext:(NSDictionary * __nonnull (^ __nonnull)(void))sharedExampleContext flags:(NSDictionary * __nonnull)flags file:(NSString * __nonnull)file line:(NSUInteger)line; 19 | - (void)pending:(NSString * __nonnull)description closure:(void (^ __nonnull)(void))closure; 20 | @end 21 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickObjectiveC/Quick.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | //! Project version number for Quick. 4 | FOUNDATION_EXPORT double QuickVersionNumber; 5 | 6 | //! Project version string for Quick. 7 | FOUNDATION_EXPORT const unsigned char QuickVersionString[]; 8 | 9 | #import "QuickSpec.h" 10 | #import "QCKDSL.h" 11 | #import "QuickConfiguration.h" 12 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickObjectiveC/QuickSpec.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | /** 4 | QuickSpec is a base class all specs written in Quick inherit from. 5 | They need to inherit from QuickSpec, a subclass of XCTestCase, in 6 | order to be discovered by the XCTest framework. 7 | 8 | XCTest automatically compiles a list of XCTestCase subclasses included 9 | in the test target. It iterates over each class in that list, and creates 10 | a new instance of that class for each test method. It then creates an 11 | "invocation" to execute that test method. The invocation is an instance of 12 | NSInvocation, which represents a single message send in Objective-C. 13 | The invocation is set on the XCTestCase instance, and the test is run. 14 | 15 | Most of the code in QuickSpec is dedicated to hooking into XCTest events. 16 | First, when the spec is first loaded and before it is sent any messages, 17 | the +[NSObject initialize] method is called. QuickSpec overrides this method 18 | to call +[QuickSpec spec]. This builds the example group stacks and 19 | registers them with Quick.World, a global register of examples. 20 | 21 | Then, XCTest queries QuickSpec for a list of test methods. Normally, XCTest 22 | automatically finds all methods whose selectors begin with the string "test". 23 | However, QuickSpec overrides this default behavior by implementing the 24 | +[XCTestCase testInvocations] method. This method iterates over each example 25 | registered in Quick.World, defines a new method for that example, and 26 | returns an invocation to call that method to XCTest. Those invocations are 27 | the tests that are run by XCTest. Their selector names are displayed in 28 | the Xcode test navigation bar. 29 | */ 30 | @interface QuickSpec : XCTestCase 31 | 32 | /** 33 | Override this method in your spec to define a set of example groups 34 | and examples. 35 | 36 | @code 37 | override func spec() { 38 | describe("winter") { 39 | it("is coming") { 40 | // ... 41 | } 42 | } 43 | } 44 | @endcode 45 | 46 | See DSL.swift for more information on what syntax is available. 47 | */ 48 | - (void)spec; 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickObjectiveC/World.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class ExampleGroup; 4 | @class ExampleMetadata; 5 | 6 | SWIFT_CLASS("_TtC5Quick5World") 7 | @interface World 8 | 9 | @property (nonatomic) ExampleGroup * __nullable currentExampleGroup; 10 | @property (nonatomic) ExampleMetadata * __nullable currentExampleMetadata; 11 | @property (nonatomic) BOOL isRunningAdditionalSuites; 12 | + (World * __nonnull)sharedWorld; 13 | - (void)configure:(void (^ __nonnull)(Configuration * __nonnull))closure; 14 | - (void)finalizeConfiguration; 15 | - (ExampleGroup * __nonnull)rootExampleGroupForSpecClass:(Class __nonnull)cls; 16 | - (NSArray * __nonnull)examplesForSpecClass:(Class __nonnull)specClass; 17 | - (void)performWithCurrentExampleGroup:(ExampleGroup * __nonnull)group closure:(void (^ __nonnull)(void))closure; 18 | @end 19 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickObjectiveC/XCTestSuite+QuickTestSuiteBuilder.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | @interface XCTestSuite (QuickTestSuiteBuilder) 6 | @end 7 | 8 | @implementation XCTestSuite (QuickTestSuiteBuilder) 9 | 10 | /** 11 | In order to ensure we can correctly build dynamic test suites, we need to 12 | replace some of the default test suite constructors. 13 | */ 14 | + (void)load { 15 | Method testCaseWithName = class_getClassMethod(self, @selector(testSuiteForTestCaseWithName:)); 16 | Method hooked_testCaseWithName = class_getClassMethod(self, @selector(qck_hooked_testSuiteForTestCaseWithName:)); 17 | method_exchangeImplementations(testCaseWithName, hooked_testCaseWithName); 18 | } 19 | 20 | /** 21 | The `+testSuiteForTestCaseWithName:` method is called when a specific test case 22 | class is run from the Xcode test navigator. If the built test suite is `nil`, 23 | Xcode will not run any tests for that test case. 24 | 25 | Given if the following test case class is run from the Xcode test navigator: 26 | 27 | FooSpec 28 | testFoo 29 | testBar 30 | 31 | XCTest will invoke this once per test case, with test case names following this format: 32 | 33 | FooSpec/testFoo 34 | FooSpec/testBar 35 | */ 36 | + (nullable instancetype)qck_hooked_testSuiteForTestCaseWithName:(nonnull NSString *)name { 37 | return [QuickTestSuite selectedTestSuiteForTestCaseWithName:name]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickSpecBase/QuickSpecBase.m: -------------------------------------------------------------------------------- 1 | #import "QuickSpecBase.h" 2 | 3 | #pragma mark - _QuickSelectorWrapper 4 | 5 | @interface _QuickSelectorWrapper () 6 | @property(nonatomic, assign) SEL selector; 7 | @end 8 | 9 | @implementation _QuickSelectorWrapper 10 | 11 | - (instancetype)initWithSelector:(SEL)selector { 12 | self = [super init]; 13 | _selector = selector; 14 | return self; 15 | } 16 | 17 | @end 18 | 19 | 20 | #pragma mark - _QuickSpecBase 21 | 22 | @implementation _QuickSpecBase 23 | 24 | - (instancetype)init { 25 | self = [super initWithInvocation: nil]; 26 | return self; 27 | } 28 | 29 | /** 30 | Invocations for each test method in the test case. QuickSpec overrides this method to define a 31 | new method for each example defined in +[QuickSpec spec]. 32 | 33 | @return An array of invocations that execute the newly defined example methods. 34 | */ 35 | + (NSArray *)testInvocations { 36 | NSArray<_QuickSelectorWrapper *> *wrappers = [self _qck_testMethodSelectors]; 37 | NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:wrappers.count]; 38 | 39 | for (_QuickSelectorWrapper *wrapper in wrappers) { 40 | SEL selector = wrapper.selector; 41 | NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; 42 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 43 | invocation.selector = selector; 44 | 45 | [invocations addObject:invocation]; 46 | } 47 | 48 | return invocations; 49 | } 50 | 51 | + (NSArray<_QuickSelectorWrapper *> *)_qck_testMethodSelectors { 52 | return @[]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Pods/Quick/Sources/QuickSpecBase/include/QuickSpecBase.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import XCTest; 3 | 4 | @interface _QuickSelectorWrapper : NSObject 5 | - (instancetype)initWithSelector:(SEL)selector; 6 | @end 7 | 8 | @interface _QuickSpecBase : XCTestCase 9 | + (NSArray<_QuickSelectorWrapper *> *)_qck_testMethodSelectors; 10 | - (instancetype)init NS_DESIGNATED_INITIALIZER; 11 | @end 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/NVHTarGzip/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.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/NVHTarGzip/NVHTarGzip-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_NVHTarGzip : NSObject 3 | @end 4 | @implementation PodsDummy_NVHTarGzip 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/NVHTarGzip/NVHTarGzip-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/NVHTarGzip/NVHTarGzip-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "NSFileManager+NVHFileSize.h" 6 | #import "NVHFile.h" 7 | #import "NVHGzipFile.h" 8 | #import "NVHProgress.h" 9 | #import "NVHTarFile.h" 10 | #import "NVHTarGzip.h" 11 | 12 | FOUNDATION_EXPORT double NVHTarGzipVersionNumber; 13 | FOUNDATION_EXPORT const unsigned char NVHTarGzipVersionString[]; 14 | 15 | -------------------------------------------------------------------------------- /Pods/Target Support Files/NVHTarGzip/NVHTarGzip.modulemap: -------------------------------------------------------------------------------- 1 | framework module NVHTarGzip { 2 | umbrella header "NVHTarGzip-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/NVHTarGzip/NVHTarGzip.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_LDFLAGS = -l"z" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /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 | 6.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Nimble/Nimble-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Nimble : NSObject 3 | @end 4 | @implementation PodsDummy_Nimble 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Nimble/Nimble-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Nimble/Nimble-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "CwlCatchException.h" 6 | #import "CwlMachBadInstructionHandler.h" 7 | #import "mach_excServer.h" 8 | #import "CwlPreconditionTesting.h" 9 | #import "Nimble.h" 10 | #import "DSL.h" 11 | #import "NMBExceptionCapture.h" 12 | #import "NMBStringify.h" 13 | 14 | FOUNDATION_EXPORT double NimbleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char NimbleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Keiko/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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Keiko/Pods-Keiko-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## NVHTarGzip 5 | 6 | Copyright (c) 2014 Niels van Hoorn 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Keiko/Pods-Keiko-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 | Copyright (c) 2014 Niels van Hoorn <niels@zekerwaar.nl> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | NVHTarGzip 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Keiko/Pods-Keiko-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Keiko : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Keiko 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Keiko/Pods-Keiko-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/NVHTarGzip/NVHTarGzip.framework" 88 | fi 89 | if [[ "$CONFIGURATION" == "Release" ]]; then 90 | install_framework "$BUILT_PRODUCTS_DIR/NVHTarGzip/NVHTarGzip.framework" 91 | fi 92 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Keiko/Pods-Keiko-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | 6 | FOUNDATION_EXPORT double Pods_KeikoVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char Pods_KeikoVersionString[]; 8 | 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Keiko/Pods-Keiko.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip/NVHTarGzip.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "NVHTarGzip" 7 | PODS_BUILD_DIR = $BUILD_DIR 8 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Keiko/Pods-Keiko.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Keiko { 2 | umbrella header "Pods-Keiko-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Keiko/Pods-Keiko.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip/NVHTarGzip.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "NVHTarGzip" 7 | PODS_BUILD_DIR = $BUILD_DIR 8 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sumo/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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sumo/Pods-Sumo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## NVHTarGzip 5 | 6 | Copyright (c) 2014 Niels van Hoorn 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sumo/Pods-Sumo-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 | Copyright (c) 2014 Niels van Hoorn <niels@zekerwaar.nl> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | NVHTarGzip 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sumo/Pods-Sumo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Sumo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Sumo 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sumo/Pods-Sumo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | 6 | FOUNDATION_EXPORT double Pods_SumoVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char Pods_SumoVersionString[]; 8 | 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sumo/Pods-Sumo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip/NVHTarGzip.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "NVHTarGzip" 7 | PODS_BUILD_DIR = $BUILD_DIR 8 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sumo/Pods-Sumo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Sumo { 2 | umbrella header "Pods-Sumo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Sumo/Pods-Sumo.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip/NVHTarGzip.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "NVHTarGzip" 7 | PODS_BUILD_DIR = $BUILD_DIR 8 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SumoTests/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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SumoTests/Pods-SumoTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SumoTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SumoTests 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SumoTests/Pods-SumoTests-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 | install_framework "$BUILT_PRODUCTS_DIR/Quick/Quick.framework" 89 | install_framework "$BUILT_PRODUCTS_DIR/NVHTarGzip/NVHTarGzip.framework" 90 | fi 91 | if [[ "$CONFIGURATION" == "Release" ]]; then 92 | install_framework "$BUILT_PRODUCTS_DIR/Nimble/Nimble.framework" 93 | install_framework "$BUILT_PRODUCTS_DIR/Quick/Quick.framework" 94 | install_framework "$BUILT_PRODUCTS_DIR/NVHTarGzip/NVHTarGzip.framework" 95 | fi 96 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SumoTests/Pods-SumoTests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | 6 | FOUNDATION_EXPORT double Pods_SumoTestsVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char Pods_SumoTestsVersionString[]; 8 | 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SumoTests/Pods-SumoTests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) $(PLATFORM_DIR)/Developer/Library/Frameworks "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip" "$PODS_CONFIGURATION_BUILD_DIR/Nimble" "$PODS_CONFIGURATION_BUILD_DIR/Quick" 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/NVHTarGzip/NVHTarGzip.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Nimble/Nimble.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Quick/Quick.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "NVHTarGzip" -framework "Nimble" -framework "Quick" 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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SumoTests/Pods-SumoTests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_SumoTests { 2 | umbrella header "Pods-SumoTests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-SumoTests/Pods-SumoTests.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) $(PLATFORM_DIR)/Developer/Library/Frameworks "$PODS_CONFIGURATION_BUILD_DIR/NVHTarGzip" "$PODS_CONFIGURATION_BUILD_DIR/Nimble" "$PODS_CONFIGURATION_BUILD_DIR/Quick" 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/NVHTarGzip/NVHTarGzip.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Nimble/Nimble.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Quick/Quick.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "NVHTarGzip" -framework "Nimble" -framework "Quick" 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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Quick/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.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Quick/Quick-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Quick : NSObject 3 | @end 4 | @implementation PodsDummy_Quick 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Quick/Quick-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Quick/Quick-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "QuickConfiguration.h" 6 | #import "QCKDSL.h" 7 | #import "Quick.h" 8 | #import "QuickSpec.h" 9 | 10 | FOUNDATION_EXPORT double QuickVersionNumber; 11 | FOUNDATION_EXPORT const unsigned char QuickVersionString[]; 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Quick/Quick.modulemap: -------------------------------------------------------------------------------- 1 | framework module Quick { 2 | umbrella header "Quick-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Quick/Quick.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Quick 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 = -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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sumo 2 | 3 | 4 | 5 | Sumo is a library that prepares for fast upload for iOS. 6 | It is effective when uploading by selecting images continuously. 7 | Sumo will prepare for uploading immediately after the image is selected. 8 | Multiple selected images are compiled into one file and compressed. 9 | One compressed file can communicate without overhead. 10 | 11 | 12 | 13 | 14 | ## Feature 🎉 15 | - ☑️ Non blocking Main thread. 16 | - ☑️ Fast resizing. 17 | - ☑️ Task is cancelable. 18 | - ☑️ Multi sessions. 19 | 20 | 21 | ## Usage 22 | 23 | Sumo consists of sessions and tasks. 24 | Multiple tasks are associated with one session, and you can obtain obtain artifacts by zip the session. 25 | 26 | ``` swift 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | var options: Sumo.Session.Options = Sumo.Session.Options() 30 |    // Target of image resizing 31 |    options.imageTargetSize = CGSize(width: 500, height: 500) 32 | Sumo.shared.startSession(options: options) 33 | } 34 | ``` 35 | 36 | For example in CollectionView's 37 | 38 | - `func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)` 39 | - `func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath)` 40 | 41 | ``` swift 42 | // Compress and process the image in the background. 43 | func didSelectItem(indexPath: IndexPath, asset: PHAsset) { 44 | Sumo.shared.startWorflow(asset.localIdentifier) { (error) in 45 | if let error = error { 46 | debugPrint(error) 47 | return 48 | } 49 | } 50 | } 51 | 52 | // Cancel the image being compressed. 53 | func didDeselectItem(indexPath: IndexPath, asset: PHAsset) { 54 | Sumo.shared.cancel(asset.localIdentifier) 55 | } 56 | ``` 57 | 58 | ``` swift 59 | // Stop all processing. 60 | @objc private func cancel() { 61 | Sumo.shared.stop() 62 | } 63 | 64 | // Cancel the task being processed. The session will continue to remain. 65 | @objc private func reset() { 66 | Sumo.shared.reset() 67 | } 68 | 69 | // Compress the resized photo to zip. 70 | @objc private func zip() { 71 | Sumo.shared.zip { (url, error) in 72 | // Transfer to any server. 73 | } 74 | } 75 | ``` 76 | 77 | [AssemblyLine](https://github.com/1amageek/AssemblyLine) is generalized to Sumo. 78 | -------------------------------------------------------------------------------- /Sumo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sumo.xcodeproj/xcuserdata/1amageek.xcuserdatad/xcschemes/Sumo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Sumo.xcodeproj/xcuserdata/1amageek.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Keiko.xcscheme 8 | 9 | orderHint 10 | 6 11 | 12 | Sumo.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 124A9D931E9CCD4B000E07E8 21 | 22 | primary 23 | 24 | 25 | 124A9D9C1E9CCD4B000E07E8 26 | 27 | primary 28 | 29 | 30 | 124A9DBB1E9CD028000E07E8 31 | 32 | primary 33 | 34 | 35 | 124A9DCE1E9CD028000E07E8 36 | 37 | primary 38 | 39 | 40 | 124A9DDF1E9CD03F000E07E8 41 | 42 | primary 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Sumo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Sumo/Data+.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Data+.swift 3 | // Sumo 4 | // 5 | // Created by 1amageek on 2017/04/11. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ImageIO 11 | 12 | extension Data { 13 | func resize(_ size: CGSize, comperesionQuality: CGFloat = 0.7) -> Data? { 14 | let cfData: CFData = CFDataCreate(kCFAllocatorDefault, (self as NSData).bytes.bindMemory(to: UInt8.self, capacity: self.count), self.count) 15 | if let imageSource: CGImageSource = CGImageSourceCreateWithData(cfData, nil) { 16 | let options: [NSString: Any] = [ 17 | kCGImageSourceThumbnailMaxPixelSize: Swift.max(size.width, size.height), 18 | kCGImageSourceCreateThumbnailFromImageAlways: true, 19 | kCGImageSourceCreateThumbnailWithTransform: true 20 | ] 21 | let scaledImage: UIImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options as CFDictionary?).flatMap { UIImage(cgImage: $0) }! 22 | return UIImageJPEGRepresentation(scaledImage, comperesionQuality) 23 | } 24 | return nil 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sumo/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 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Sumo/Sumo+Item.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Sumo+Item.swift 3 | // Sumo 4 | // 5 | // Created by 1amageek on 2017/04/11. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Photos 11 | 12 | extension Sumo { 13 | 14 | public class Item: Hashable { 15 | 16 | public enum MediaType { 17 | case image 18 | case video 19 | } 20 | 21 | public enum Status { 22 | case none 23 | case compressed 24 | case saved 25 | case ziped 26 | case completed 27 | } 28 | 29 | let localID: String 30 | 31 | var workItem: DispatchWorkItem? 32 | 33 | private(set) var status: Status = .none 34 | 35 | var asset: PHAsset? { 36 | didSet { 37 | guard let asset: PHAsset = asset else { 38 | return 39 | } 40 | self.name = "\(asset.creationDate!.timeIntervalSince1970)" // TODO: MD5 41 | switch asset.mediaType { 42 | case .image: self.mediaType = .image 43 | case .video: self.mediaType = .video 44 | default: break 45 | } 46 | } 47 | } 48 | 49 | var mediaType: MediaType? 50 | 51 | var name: String? 52 | 53 | // 動画の場合のみ 54 | var exportSession: AVAssetExportSession? 55 | 56 | var data: Data? { 57 | didSet { 58 | self.status = .compressed 59 | } 60 | } 61 | 62 | var urls: [URL] = [] { 63 | didSet { 64 | self.status = .saved 65 | } 66 | } 67 | 68 | init(localID: String) { 69 | if localID.isEmpty { 70 | fatalError("[Sumo] *** error: localID is empty") 71 | } 72 | self.localID = localID 73 | } 74 | 75 | public func cancel() { 76 | debugPrint("[Sumo] cancel :\(self.localID)") 77 | self.exportSession?.cancelExport() 78 | self.workItem?.cancel() 79 | let fileManager: Sumo.FileManager = Sumo.FileManager() 80 | fileManager.remove(item: self) 81 | } 82 | 83 | public var hashValue: Int { 84 | return self.localID.hashValue 85 | } 86 | 87 | } 88 | } 89 | 90 | public func == (lhs: Sumo.Item, rhs: Sumo.Item) -> Bool { 91 | return lhs.localID == rhs.localID 92 | } 93 | -------------------------------------------------------------------------------- /Sumo/Sumo+Session.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Sumo+Session.swift 3 | // Sumo 4 | // 5 | // Created by 1amageek on 2017/04/11. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Sumo { 12 | 13 | public class Session: Hashable { 14 | 15 | public struct Options { 16 | var imageTargetSize: CGSize = CGSize(width: 2000, height: 2000) 17 | var imageComperesionQuality: CGFloat = 0.8 18 | var videoTargetSize: CGSize = CGSize(width: 2000, height: 2000) 19 | var videoComperesionQuality: CGFloat = 0.8 20 | } 21 | 22 | public let sessionID: String 23 | 24 | public let options: Options 25 | 26 | public let queue: DispatchQueue 27 | 28 | public let workGroup: DispatchGroup = DispatchGroup() 29 | 30 | public var url: URL? 31 | 32 | 33 | // zip(tar)化されたファイルのURL 34 | public var packageURL: URL? 35 | 36 | private(set) var items: [Sumo.Item] = [] 37 | 38 | private(set) var isCanceled: Bool = false 39 | 40 | init(sessionID: String, options: Options, queue: DispatchQueue) { 41 | self.sessionID = sessionID 42 | self.options = options 43 | self.queue = queue 44 | } 45 | 46 | public var hashValue: Int { 47 | return self.sessionID.hash 48 | } 49 | 50 | /// アイテムを追加する 51 | public func add(item: Sumo.Item) { 52 | // すでにキャンセルされたSessionは何もしない 53 | if self.isCanceled { 54 | return 55 | } 56 | self.items.append(item) 57 | self.queue.async(group: workGroup, execute: item.workItem!) 58 | } 59 | 60 | /// アイテムを削除する 61 | public func remove(item: Sumo.Item) { 62 | if let index: Int = self.items.index(of: item) { 63 | self.items.remove(at: index) 64 | } 65 | } 66 | 67 | /// セッションを保持したままItemを全て削除する 68 | public func reset() { 69 | self.isCanceled = true 70 | self.items.forEach { (item) in 71 | item.cancel() 72 | } 73 | self.items = [] 74 | self.isCanceled = false 75 | } 76 | 77 | /// セッションを終了させる 78 | public func stop() { 79 | self.isCanceled = true 80 | self.items.forEach { (item) in 81 | item.cancel() 82 | } 83 | self.items = [] 84 | let fileManager: Sumo.FileManager = Sumo.FileManager() 85 | fileManager.remove(session: self) 86 | } 87 | 88 | } 89 | 90 | } 91 | 92 | public func == (lhs: Sumo.Session, rhs: Sumo.Session) -> Bool { 93 | return lhs.sessionID == rhs.sessionID 94 | } 95 | 96 | -------------------------------------------------------------------------------- /Sumo/Sumo.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sumo.h 3 | // Sumo 4 | // 5 | // Created by 1amageek on 2017/04/11. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Sumo. 12 | FOUNDATION_EXPORT double SumoVersionNumber; 13 | 14 | //! Project version string for Sumo. 15 | FOUNDATION_EXPORT const unsigned char SumoVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /SumoTests/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 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SumoTests/SumoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SumoTests.swift 3 | // SumoTests 4 | // 5 | // Created by 1amageek on 2017/04/11. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Sumo 11 | import Quick 12 | import Nimble 13 | import Photos 14 | 15 | class SumoSpec: QuickSpec { 16 | 17 | override func spec() { 18 | describe("Copy") { 19 | it("Start session") { 20 | let session: Sumo.Session = Sumo.shared.startSession(sessionID: "session_id") 21 | expect(session.sessionID).to(equal("session_id")) 22 | } 23 | 24 | it("Start workflow") { 25 | // UnitTestでは無理か。。 26 | PHPhotoLibrary.requestAuthorization({ (status) in 27 | DispatchQueue.main.async { 28 | print(status) 29 | let bundle: Bundle = Bundle(for: SumoSpec.self) 30 | let path: String = bundle.path(forResource: "siko", ofType: "jpg")! 31 | let image: UIImage = UIImage(contentsOfFile: path)! 32 | UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) 33 | let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: nil) 34 | let asset: PHAsset = fetchResult.firstObject! 35 | Sumo.shared.startWorflow(asset.localIdentifier, block: { (error) in 36 | expect(Sumo.shared.currentSession?.items.count).to(equal(1)) 37 | }) 38 | } 39 | }) 40 | waitUntil(timeout: 1, action: {_ in }) 41 | } 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /SumoTests/TestLibraryManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestLibraryManager.swift 3 | // Sumo 4 | // 5 | // Created by 1amageek on 2017/04/12. 6 | // Copyright © 2017年 Stamp Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class TestLibraryManager { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /SumoTests/siko.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1amageek/Sumo/c07d21c42b55b85792726ec1fcc7bfb1e6e1ac49/SumoTests/siko.jpg -------------------------------------------------------------------------------- /overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1amageek/Sumo/c07d21c42b55b85792726ec1fcc7bfb1e6e1ac49/overview.png -------------------------------------------------------------------------------- /sumo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1amageek/Sumo/c07d21c42b55b85792726ec1fcc7bfb1e6e1ac49/sumo.png --------------------------------------------------------------------------------