├── .gitignore ├── .slather.yml ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.txt ├── MockUIAlertController.podspec ├── README.md ├── SampleObjC ├── MockUIAlertControllerSample.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── MockUIAlertControllerSample.xcscheme ├── SampleApp │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── CodeNextViewController.h │ ├── CodeNextViewController.m │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── StoryboardNextViewController.h │ ├── StoryboardNextViewController.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m └── Tests │ ├── Info.plist │ ├── QCOMockAlertVerifierTests.m │ ├── ViewControllerAlertTests.m │ └── ViewControllerPresentationTests.m ├── SampleSwift ├── MockUIAlertControllerSampleSwift.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── MockUIAlertControllerSampleSwift.xcscheme ├── SampleApp │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── CodeNextViewController.swift │ ├── Info.plist │ ├── StoryboardNextViewController.swift │ └── ViewController.swift └── Tests │ ├── Info.plist │ ├── MockUIAlertControllerSampleSwiftTests-Bridging-Header.h │ ├── ViewControllerAlertTests.swift │ └── ViewControllerPresentationTests.swift └── Source ├── Info.plist ├── MakeDistribution.sh ├── MockUIAlertController.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── MockUIAlertController.xcscheme ├── MockUIAlertController ├── MockUIAlertController.h ├── NSObject+QCOMockAlerts.h ├── NSObject+QCOMockAlerts.m ├── QCOMockAlertVerifier.h ├── QCOMockAlertVerifier.m ├── QCOMockPopoverPresentationController.h ├── QCOMockPopoverPresentationController.m ├── QCOMockPresentationVerifier.h ├── QCOMockPresentationVerifier.m ├── UIAlertAction+QCOMock.h ├── UIAlertAction+QCOMock.m ├── UIAlertController+QCOMock.h ├── UIAlertController+QCOMock.m ├── UIViewController+QCOMock.h └── UIViewController+QCOMock.m └── XcodeWarnings.xcconfig /.gitignore: -------------------------------------------------------------------------------- 1 | # Added by hand 2 | *.gcda 3 | *.gcno 4 | 5 | 6 | # Created by https://www.gitignore.io 7 | 8 | ### Xcode ### 9 | build/ 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | *.xccheckout 20 | *.moved-aside 21 | DerivedData 22 | *.xcuserstate 23 | 24 | 25 | ### AppCode ### 26 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 27 | 28 | *.iml 29 | 30 | ## Directory-based project format: 31 | .idea/ 32 | # if you remove the above rule, at least ignore the following: 33 | 34 | # User-specific stuff: 35 | # .idea/workspace.xml 36 | # .idea/tasks.xml 37 | # .idea/dictionaries 38 | 39 | # Sensitive or high-churn files: 40 | # .idea/dataSources.ids 41 | # .idea/dataSources.xml 42 | # .idea/sqlDataSources.xml 43 | # .idea/dynamic.xml 44 | # .idea/uiDesigner.xml 45 | 46 | # Gradle: 47 | # .idea/gradle.xml 48 | # .idea/libraries 49 | 50 | # Mongo Explorer plugin: 51 | # .idea/mongoSettings.xml 52 | 53 | ## File-based project format: 54 | *.ipr 55 | *.iws 56 | 57 | ## Plugin-specific files: 58 | 59 | # IntelliJ 60 | /out/ 61 | 62 | # mpeltonen/sbt-idea plugin 63 | .idea_modules/ 64 | 65 | # JIRA plugin 66 | atlassian-ide-plugin.xml 67 | 68 | # Crashlytics plugin (for Android Studio and IntelliJ) 69 | com_crashlytics_export_strings.xml 70 | crashlytics.properties 71 | crashlytics-build.properties 72 | 73 | 74 | ### OSX ### 75 | .DS_Store 76 | .AppleDouble 77 | .LSOverride 78 | 79 | # Icon must end with two \r 80 | Icon 81 | 82 | 83 | # Thumbnails 84 | ._* 85 | 86 | # Files that might appear in the root of a volume 87 | .DocumentRevisions-V100 88 | .fseventsd 89 | .Spotlight-V100 90 | .TemporaryItems 91 | .Trashes 92 | .VolumeIcon.icns 93 | 94 | # Directories potentially created on remote AFP share 95 | .AppleDB 96 | .AppleDesktop 97 | Network Trash Folder 98 | Temporary Items 99 | .apdisk 100 | -------------------------------------------------------------------------------- /.slather.yml: -------------------------------------------------------------------------------- 1 | coverage_service: coveralls 2 | xcodeproj: ./SampleObjC/MockUIAlertControllerSample.xcodeproj 3 | scheme: MockUIAlertControllerSample 4 | binary_file: /Users/travis/Library/Developer/Xcode/DerivedData/MockUIAlertControllerSample-fzpnwcxasbqkdqfgenrbrufzymgx/Build/Products/Debug-iphonesimulator/MockUIAlertControllerSample.app/PlugIns/MockUIAlertControllerSampleTests.xctest/MockUIAlertControllerSampleTests 5 | ignore: 6 | - SampleObjC/* 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode10.2 3 | 4 | before_install: 5 | - gem install slather 6 | 7 | script: 8 | - set -o pipefail; 9 | - xcodebuild test -project SampleSwift/MockUIAlertControllerSampleSwift.xcodeproj -scheme MockUIAlertControllerSampleSwift -sdk iphonesimulator -destination "platform=iOS Simulator,OS=latest,name=iPhone 7" | xcpretty 10 | - xcodebuild test -project SampleObjC/MockUIAlertControllerSample.xcodeproj -scheme MockUIAlertControllerSample -sdk iphonesimulator -destination "platform=iOS Simulator,OS=latest,name=iPhone 7" | xcpretty 11 | - xcodebuild test -project SampleObjC/MockUIAlertControllerSample.xcodeproj -scheme MockUIAlertControllerSample -sdk iphonesimulator -destination "platform=iOS Simulator,OS=latest,name=iPad Air" | xcpretty 12 | - pod spec lint --quick 13 | 14 | after_success: 15 | - slather 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Version 3.2.0 2 | ------------- 3 | _10 Feb 2019_ 4 | 5 | - Added `completion` closure invoked when alert is presented. If you present an alert from `DispatchQueue.main.async`, you can use this to fulfill an XCTestExpectation for async testing. 6 | - Improved README instructions on bridging header for Swift. 7 | 8 | 9 | Version 3.1.0 10 | ------------- 11 | _01 Jan 2019_ 12 | 13 | - Added `actions` which greatly simplify Swift tests. Instead of `alertVerifier.actionsTitles[0] as? String`, use `alertVerifier.actions[0].title` 14 | - Added `preferredAction` 15 | - Added `textFields` 16 | - Share scheme for Carthage builds. _Thanks to: Kevin Donnelly_ 17 | 18 | **Deprecated:** 19 | 20 | - Deprecated `actionTitles` and `-styleForButtonWithTitle:`. Use `actions` instead. 21 | 22 | 23 | Version 3.0.0 24 | ------------ 25 | _02 Feb 2018_ 26 | 27 | - Changed `animated` from NSNumber to BOOL. 28 | - Added `presentingViewController` 29 | 30 | 31 | Version 2.0.2 32 | ------------- 33 | _30 Jan 2018_ 34 | 35 | - Fixed crash when presenting UIDocumentMenuViewController while mocking UIAlertController. _Thanks to: Andrei Tulai_ 36 | 37 | 38 | Version 2.0.1 39 | ------------- 40 | _06 Mar 2017_ 41 | 42 | - Fixed nullability mistake: actionTitles are non-null. 43 | - Add shared scheme to satisfy latest version of Carthage. 44 | 45 | 46 | Version 2.0.0 47 | ------------- 48 | _19 Feb 2017_ 49 | 50 | - Annotate nullability. The QCOMockAlertVerifier initializer is now non-null, which changes Swift use. 51 | - Added Swift sample app. 52 | - Updated example tests to put QCOMockAlertVerifier in test fixture. This is now recommended, to avoid tests which accidentally present real alerts. 53 | 54 | 55 | Version 1.1.1 56 | ------------- 57 | _11 Sep 2016_ 58 | 59 | - Change UIAlertController's actual `preferredStyle` instead of keeping it in an associated 60 | property, to avoid UIKit consistency exceptions. _Thanks to: nirgin_ 61 | - Allow `executeActionForButtonWithTitle:` even when no handler was set. _Thanks to: John Foulkes_ 62 | - Don't record presentation of non-alerts. _Thanks to: Tom Bates_ 63 | - Quiet runtime warning about attempting to load view controller while deallocating. 64 | _Thanks to: Marcelo Fabri_ 65 | 66 | 67 | Version 1.1.0 68 | ------------- 69 | _24 Dec 2015_ 70 | 71 | - Repackage as Cocoa Touch Framework project. 72 | - Support Carthage. 73 | - CocoaPods: Distinguish between public headers and private headers. 74 | 75 | 76 | Version 1.0.0 77 | ------------- 78 | _23 Aug 2015_ 79 | 80 | - Initial release. Thanks to Victor Ilyukevich for suggestions, testing, and 81 | cleanup. 82 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | Copyright 2019 Jonathan M. Reid 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of 5 | this software and associated documentation files (the "Software"), to deal in 6 | the Software without restriction, including without limitation the rights to 7 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 8 | the Software, and to permit persons to whom the Software is furnished to do so, 9 | subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 17 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 18 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | (MIT License) 22 | -------------------------------------------------------------------------------- /MockUIAlertController.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'MockUIAlertController' 3 | s.version = '3.2.0' 4 | s.summary = 'Mock alerts and action sheets for iOS unit tests' 5 | s.description = <<-DESC 6 | MockUIAlertController lets you mock iOS alerts and action sheets for unit tests. 7 | 8 | No actual alerts are presented. This means: 9 | 10 | * The workflow doesn't pause for an action to be selected. 11 | * Tests are blazing fast. 12 | DESC 13 | s.homepage = 'https://github.com/jonreid/MockUIAlertController' 14 | s.license = 'MIT' 15 | s.author = { 'Jon Reid' => 'jon@qualitycoding.org' } 16 | s.social_media_url = 'https://twitter.com/qcoding' 17 | 18 | s.ios.deployment_target = '9.0' 19 | s.source = { :git => 'https://github.com/jonreid/MockUIAlertController.git', :tag => 'v3.2.0' } 20 | s.source_files = 'Source/MockUIAlertController/*.{h,m}' 21 | s.public_header_files = 'Source/MockUIAlertController/QCOMockAlertVerifier.h', 'Source/MockUIAlertController/QCOMockPopoverPresentationController.h' 22 | s.requires_arc = true 23 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated… Come over to ViewControllerPresentationSpy 2 | 3 | This library has been renamed to [ViewControllerPresentationSpy](https://github.com/jonreid/ViewControllerPresentationSpy). 4 | 5 | * It introduces a new verifier to capture any presented view controller, including segues. 6 | * The verifiers are written in Swift, so you no longer need a bridging header. 7 | * Other compatibility-breaking changes. You're welcome to stick with MockUIAlertController, but all improvements will be made in the new library. 8 | 9 | --- 10 | 11 | # MockUIAlertController 12 | 13 | [![Build Status](https://travis-ci.org/jonreid/MockUIAlertController.svg?branch=master)](https://travis-ci.org/jonreid/MockUIAlertController) 14 | [![Coverage Status](https://coveralls.io/repos/jonreid/MockUIAlertController/badge.svg?branch=master&service=github)](https://coveralls.io/github/jonreid/MockUIAlertController?branch=master) 15 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 16 | [![CocoaPods Version](https://cocoapod-badges.herokuapp.com/v/MockUIAlertController/badge.png)](https://cocoapods.org/pods/MockUIAlertController) 17 | [![Twitter Follow](https://img.shields.io/twitter/follow/qcoding.svg?style=social)](https://twitter.com/qcoding) 18 | 19 | MockUIAlertController lets you mock iOS alerts and action sheets for unit tests. It works for Swift as well as Objective-C. 20 | 21 | (For old UIAlertView or UIActionSheet mocking, use 22 | [MockUIAlertViewActionSheet](https://github.com/jonreid/MockUIAlertViewActionSheet).) 23 | 24 | No actual alerts are presented. This means: 25 | 26 | * The workflow doesn't pause for an action to be selected 27 | * Tests are blazing fast. 28 | 29 | For more discussion, see my blog post [How to Test UIAlertControllers and Control Swizzling](http://qualitycoding.org/testing-uialertcontrollers/). 30 | 31 | 32 | ## Writing Tests 33 | 34 | ### What do I need to change in production code? 35 | 36 | Nothing. 37 | 38 | ### How do I test an alert controller? 39 | 40 | 1. `@import MockUIAlertController.h;` or add it to your Swift test target's bridging header. 41 | 2. Instantiate a `QCOMockAlertVerifier` before the Act phase of the test. 42 | 3. Invoke the code to create and present your alert or action sheet. 43 | 44 | Information about the alert or action sheet is then available through the 45 | [QCOMockAlertVerifier](https://github.com/jonreid/MockUIAlertController/blob/master/Source/MockUIAlertController/QCOMockAlertVerifier.h). 46 | 47 | For example, here's a test verifying the title (and that the alert is presented exactly once). `sut` is the System Under Test 48 | in the test fixture. 49 | 50 | ```swift 51 | func test_showAlert_alertShouldHaveTitle() { 52 | let alertVerifier = QCOMockAlertVerifier() 53 | 54 | sut.showAlert() // Whatever triggers the alert 55 | 56 | XCTAssertEqual(alertVerifier.presentedCount, 1, "presented count") 57 | XCTAssertEqual(alertVerifier.title, "Hello!", "title") 58 | } 59 | ``` 60 | 61 | ```obj-c 62 | - (void)test_showAlert_alertShouldHaveTitle { 63 | QCOMockAlertVerifier *alertVerifier = [[QCOMockAlertVerifier alloc] init]; 64 | 65 | [sut showAlert]; // Whatever triggers the alert 66 | 67 | XCTAssertEqual(alertVerifier.presentedCount, 1, @"presented count"); 68 | XCTAssertEqualObjects(alertVerifier.title, @"Hello!", @"title"); 69 | } 70 | ``` 71 | 72 | To guard against tests which accidentally present real alerts, I recommend placing the alert verifier in the test fixture with `setUp()`/`tearDown()`: 73 | 74 | ```swift 75 | private var alertVerifier: QCOMockAlertVerifier! 76 | 77 | override func setUp() { 78 | super.setUp() 79 | alertVerifier = QCOMockAlertVerifier() 80 | } 81 | 82 | override func setUp() { 83 | alertVerifier = nil 84 | super.tearDown() 85 | } 86 | ``` 87 | 88 | ### How can I invoke the block associated with a UIAlertAction? 89 | 90 | Go through the steps above to present your alert or action sheet using `QCOMockAlertController`. 91 | Then call `executeActionForButton(withTitle:)` on your `QCOMockAlertVerifier` with the button title. 92 | For example: 93 | 94 | ```swift 95 | func test_executingActionForOKButton_shouldDoSomething() { 96 | let alertVerifier = QCOMockAlertVerifier() 97 | sut.showAlert() 98 | 99 | alertVerifier.executeActionForButton(withTitle: "OK") 100 | 101 | // Now assert what you want 102 | } 103 | ``` 104 | 105 | ```obj-c 106 | - (void)test_executingActionForOKButton_shouldDoSomething { 107 | QCOMockAlertVerifier *alertVerifier = [[QCOMockAlertVerifier alloc] init]; 108 | [sut showAlert]; 109 | 110 | [alertVerifier executeActionForButtonWithTitle:@"OK"]; 111 | 112 | // Now assert what you want 113 | } 114 | ``` 115 | 116 | ### How can I test an alert that's presented using DispatchQueue.main? 117 | 118 | Create an expectation in your test case. Fulfill it in the alert verifier's completion block. Add a short wait at the start of the Assert phase. 119 | 120 | ```swift 121 | func test_showAlertOnMainDispatchQueue_shouldDoSomething() { 122 | let alertVerifier = QCOMockAlertVerifier() 123 | let expectation = self.expectation(description: "alert presented") 124 | alertVerifier.closure = { expectation.fulfill() } 125 | 126 | sut.showAlert() 127 | 128 | waitForExpectations(timeout: 0.001) 129 | // Now assert what you want 130 | } 131 | ``` 132 | 133 | ### Can I see some examples? 134 | 135 | There are sample apps in both Swift and Objective-C. Run them on both phone & pad to see what they do, then read the ViewController tests. 136 | 137 | 138 | ## Adding it to your project 139 | 140 | ### Swift use 141 | 142 | For Swift, add 143 | 144 | ```obj-c 145 | @import MockUIAlertController; 146 | ``` 147 | 148 | to the bridging header of your test target. If you don't have it as a separate module, then `#import "MockUIAlertController/MockUIAlertController.h"` 149 | 150 | ### CocoaPods 151 | 152 | Add the following to your Podfile, changing "MyTests" to the name of your test target: 153 | 154 | ```ruby 155 | target 'MyTests' do 156 | inherit! :search_paths 157 | pod 'MockUIAlertController', '~> 3.0' 158 | end 159 | ``` 160 | 161 | ### Carthage 162 | 163 | Add the following to your Cartfile: 164 | 165 | ``` 166 | github "jonreid/MockUIAlertController" ~> 3.0 167 | ``` 168 | 169 | ### Building It Yourself 170 | 171 | Make sure to take everything from Source/MockUIAlertController. 172 | -------------------------------------------------------------------------------- /SampleObjC/MockUIAlertControllerSample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0E748F971B6543A000B29AED /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E748F961B6543A000B29AED /* main.m */; }; 11 | 0E748F9A1B6543A000B29AED /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E748F991B6543A000B29AED /* AppDelegate.m */; }; 12 | 0E748F9D1B6543A000B29AED /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E748F9C1B6543A000B29AED /* ViewController.m */; }; 13 | 0E748FA01B6543A000B29AED /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E748F9E1B6543A000B29AED /* Main.storyboard */; }; 14 | 0E748FA21B6543A000B29AED /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E748FA11B6543A000B29AED /* Images.xcassets */; }; 15 | 48007CA62079ACCF007A4AB0 /* MockUIAlertController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48007CA32079AC94007A4AB0 /* MockUIAlertController.framework */; }; 16 | 4804BCA622E16949000130AD /* XcodeWarnings.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 4804BCA522E16949000130AD /* XcodeWarnings.xcconfig */; }; 17 | 483E05421DE80ACF00B5E4E4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 483E05401DE80ACF00B5E4E4 /* LaunchScreen.storyboard */; }; 18 | 48A6B5E222E03E4D00356685 /* StoryboardNextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 48A6B5E122E03E4D00356685 /* StoryboardNextViewController.m */; }; 19 | 609E9B6130BB35372D63FC0F /* QCOMockAlertVerifierTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 609E95F254C2B32C24D9C980 /* QCOMockAlertVerifierTests.m */; }; 20 | 609E9F1E2EC677BB9B797C36 /* ViewControllerAlertTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 609E96C55D81BBE28BD81748 /* ViewControllerAlertTests.m */; }; 21 | BB1700CDA7D976FD6DEFFF9F /* ViewControllerPresentationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BB1701F5D7FE936FC3672B61 /* ViewControllerPresentationTests.m */; }; 22 | BB170BE1D1582E79335462E0 /* CodeNextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BB170E0975163F7C4AFB7973 /* CodeNextViewController.m */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 0E748FAB1B6543A000B29AED /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 0E748F891B6543A000B29AED /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 0E748F901B6543A000B29AED; 31 | remoteInfo = MockAlertsExample; 32 | }; 33 | 48007CA22079AC94007A4AB0 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 48007C9E2079AC94007A4AB0 /* MockUIAlertController.xcodeproj */; 36 | proxyType = 2; 37 | remoteGlobalIDString = 48007C792079A76E007A4AB0; 38 | remoteInfo = MockUIAlertController; 39 | }; 40 | 48007CA42079ACB5007A4AB0 /* PBXContainerItemProxy */ = { 41 | isa = PBXContainerItemProxy; 42 | containerPortal = 48007C9E2079AC94007A4AB0 /* MockUIAlertController.xcodeproj */; 43 | proxyType = 1; 44 | remoteGlobalIDString = 48007C782079A76E007A4AB0; 45 | remoteInfo = MockUIAlertController; 46 | }; 47 | /* End PBXContainerItemProxy section */ 48 | 49 | /* Begin PBXFileReference section */ 50 | 0E748F911B6543A000B29AED /* MockUIAlertControllerSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MockUIAlertControllerSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 0E748F951B6543A000B29AED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 0E748F961B6543A000B29AED /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 53 | 0E748F981B6543A000B29AED /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 54 | 0E748F991B6543A000B29AED /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 55 | 0E748F9B1B6543A000B29AED /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 56 | 0E748F9C1B6543A000B29AED /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 57 | 0E748F9F1B6543A000B29AED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 58 | 0E748FA11B6543A000B29AED /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 59 | 0E748FAA1B6543A000B29AED /* MockUIAlertControllerSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MockUIAlertControllerSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | 0E748FAF1B6543A000B29AED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61 | 48007C9E2079AC94007A4AB0 /* MockUIAlertController.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MockUIAlertController.xcodeproj; path = ../../Source/MockUIAlertController.xcodeproj; sourceTree = ""; }; 62 | 4804BCA522E16949000130AD /* XcodeWarnings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = XcodeWarnings.xcconfig; path = ../../Source/XcodeWarnings.xcconfig; sourceTree = ""; }; 63 | 483E05411DE80ACF00B5E4E4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 64 | 4885FDCB1DE8A32200A9F923 /* MockUIAlertController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MockUIAlertController.framework; path = "../Source/build/Debug-iphoneos/MockUIAlertController.framework"; sourceTree = ""; }; 65 | 48A6B5E022E03E4D00356685 /* StoryboardNextViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StoryboardNextViewController.h; sourceTree = ""; }; 66 | 48A6B5E122E03E4D00356685 /* StoryboardNextViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StoryboardNextViewController.m; sourceTree = ""; }; 67 | 609E95F254C2B32C24D9C980 /* QCOMockAlertVerifierTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QCOMockAlertVerifierTests.m; sourceTree = ""; }; 68 | 609E96C55D81BBE28BD81748 /* ViewControllerAlertTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllerAlertTests.m; sourceTree = ""; }; 69 | BB1701F5D7FE936FC3672B61 /* ViewControllerPresentationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewControllerPresentationTests.m; sourceTree = ""; }; 70 | BB170D49D0E4E646298833B3 /* CodeNextViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeNextViewController.h; sourceTree = ""; }; 71 | BB170E0975163F7C4AFB7973 /* CodeNextViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodeNextViewController.m; sourceTree = ""; }; 72 | /* End PBXFileReference section */ 73 | 74 | /* Begin PBXFrameworksBuildPhase section */ 75 | 0E748F8E1B6543A000B29AED /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | 0E748FA71B6543A000B29AED /* Frameworks */ = { 83 | isa = PBXFrameworksBuildPhase; 84 | buildActionMask = 2147483647; 85 | files = ( 86 | 48007CA62079ACCF007A4AB0 /* MockUIAlertController.framework in Frameworks */, 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | /* End PBXFrameworksBuildPhase section */ 91 | 92 | /* Begin PBXGroup section */ 93 | 0E748F881B6543A000B29AED = { 94 | isa = PBXGroup; 95 | children = ( 96 | 0E748F931B6543A000B29AED /* SampleApp */, 97 | 0E748FAD1B6543A000B29AED /* Tests */, 98 | 0E748F921B6543A000B29AED /* Products */, 99 | 4885FDCA1DE8A32200A9F923 /* Frameworks */, 100 | ); 101 | sourceTree = ""; 102 | }; 103 | 0E748F921B6543A000B29AED /* Products */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 0E748F911B6543A000B29AED /* MockUIAlertControllerSample.app */, 107 | 0E748FAA1B6543A000B29AED /* MockUIAlertControllerSampleTests.xctest */, 108 | ); 109 | name = Products; 110 | sourceTree = ""; 111 | }; 112 | 0E748F931B6543A000B29AED /* SampleApp */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 0E748F9B1B6543A000B29AED /* ViewController.h */, 116 | 0E748F9C1B6543A000B29AED /* ViewController.m */, 117 | BB170D49D0E4E646298833B3 /* CodeNextViewController.h */, 118 | BB170E0975163F7C4AFB7973 /* CodeNextViewController.m */, 119 | 48A6B5E022E03E4D00356685 /* StoryboardNextViewController.h */, 120 | 48A6B5E122E03E4D00356685 /* StoryboardNextViewController.m */, 121 | 0E748F9E1B6543A000B29AED /* Main.storyboard */, 122 | 0E748F981B6543A000B29AED /* AppDelegate.h */, 123 | 0E748F991B6543A000B29AED /* AppDelegate.m */, 124 | 0E748FA11B6543A000B29AED /* Images.xcassets */, 125 | 483E05401DE80ACF00B5E4E4 /* LaunchScreen.storyboard */, 126 | 0E748F941B6543A000B29AED /* Supporting Files */, 127 | ); 128 | path = SampleApp; 129 | sourceTree = ""; 130 | }; 131 | 0E748F941B6543A000B29AED /* Supporting Files */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 0E748F951B6543A000B29AED /* Info.plist */, 135 | 0E748F961B6543A000B29AED /* main.m */, 136 | ); 137 | name = "Supporting Files"; 138 | sourceTree = ""; 139 | }; 140 | 0E748FAD1B6543A000B29AED /* Tests */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 609E96C55D81BBE28BD81748 /* ViewControllerAlertTests.m */, 144 | BB1701F5D7FE936FC3672B61 /* ViewControllerPresentationTests.m */, 145 | 609E95F254C2B32C24D9C980 /* QCOMockAlertVerifierTests.m */, 146 | 48007C9E2079AC94007A4AB0 /* MockUIAlertController.xcodeproj */, 147 | 0E748FAF1B6543A000B29AED /* Info.plist */, 148 | 4804BCA522E16949000130AD /* XcodeWarnings.xcconfig */, 149 | ); 150 | path = Tests; 151 | sourceTree = ""; 152 | }; 153 | 48007C9F2079AC94007A4AB0 /* Products */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 48007CA32079AC94007A4AB0 /* MockUIAlertController.framework */, 157 | ); 158 | name = Products; 159 | sourceTree = ""; 160 | }; 161 | 4885FDCA1DE8A32200A9F923 /* Frameworks */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | 4885FDCB1DE8A32200A9F923 /* MockUIAlertController.framework */, 165 | ); 166 | name = Frameworks; 167 | sourceTree = ""; 168 | }; 169 | /* End PBXGroup section */ 170 | 171 | /* Begin PBXNativeTarget section */ 172 | 0E748F901B6543A000B29AED /* MockUIAlertControllerSample */ = { 173 | isa = PBXNativeTarget; 174 | buildConfigurationList = 0E748FB41B6543A000B29AED /* Build configuration list for PBXNativeTarget "MockUIAlertControllerSample" */; 175 | buildPhases = ( 176 | 0E748F8D1B6543A000B29AED /* Sources */, 177 | 0E748F8E1B6543A000B29AED /* Frameworks */, 178 | 0E748F8F1B6543A000B29AED /* Resources */, 179 | ); 180 | buildRules = ( 181 | ); 182 | dependencies = ( 183 | ); 184 | name = MockUIAlertControllerSample; 185 | productName = MockAlertsExample; 186 | productReference = 0E748F911B6543A000B29AED /* MockUIAlertControllerSample.app */; 187 | productType = "com.apple.product-type.application"; 188 | }; 189 | 0E748FA91B6543A000B29AED /* MockUIAlertControllerSampleTests */ = { 190 | isa = PBXNativeTarget; 191 | buildConfigurationList = 0E748FB71B6543A000B29AED /* Build configuration list for PBXNativeTarget "MockUIAlertControllerSampleTests" */; 192 | buildPhases = ( 193 | 0E748FA61B6543A000B29AED /* Sources */, 194 | 0E748FA71B6543A000B29AED /* Frameworks */, 195 | 0E748FA81B6543A000B29AED /* Resources */, 196 | ); 197 | buildRules = ( 198 | ); 199 | dependencies = ( 200 | 48007CA52079ACB5007A4AB0 /* PBXTargetDependency */, 201 | 0E748FAC1B6543A000B29AED /* PBXTargetDependency */, 202 | ); 203 | name = MockUIAlertControllerSampleTests; 204 | productName = MockAlertsExampleTests; 205 | productReference = 0E748FAA1B6543A000B29AED /* MockUIAlertControllerSampleTests.xctest */; 206 | productType = "com.apple.product-type.bundle.unit-test"; 207 | }; 208 | /* End PBXNativeTarget section */ 209 | 210 | /* Begin PBXProject section */ 211 | 0E748F891B6543A000B29AED /* Project object */ = { 212 | isa = PBXProject; 213 | attributes = { 214 | LastUpgradeCheck = 1020; 215 | ORGANIZATIONNAME = "Jon Reid"; 216 | TargetAttributes = { 217 | 0E748F901B6543A000B29AED = { 218 | CreatedOnToolsVersion = 6.4; 219 | LastSwiftMigration = 1020; 220 | }; 221 | 0E748FA91B6543A000B29AED = { 222 | CreatedOnToolsVersion = 6.4; 223 | TestTargetID = 0E748F901B6543A000B29AED; 224 | }; 225 | }; 226 | }; 227 | buildConfigurationList = 0E748F8C1B6543A000B29AED /* Build configuration list for PBXProject "MockUIAlertControllerSample" */; 228 | compatibilityVersion = "Xcode 3.2"; 229 | developmentRegion = en; 230 | hasScannedForEncodings = 0; 231 | knownRegions = ( 232 | en, 233 | Base, 234 | ); 235 | mainGroup = 0E748F881B6543A000B29AED; 236 | productRefGroup = 0E748F921B6543A000B29AED /* Products */; 237 | projectDirPath = ""; 238 | projectReferences = ( 239 | { 240 | ProductGroup = 48007C9F2079AC94007A4AB0 /* Products */; 241 | ProjectRef = 48007C9E2079AC94007A4AB0 /* MockUIAlertController.xcodeproj */; 242 | }, 243 | ); 244 | projectRoot = ""; 245 | targets = ( 246 | 0E748F901B6543A000B29AED /* MockUIAlertControllerSample */, 247 | 0E748FA91B6543A000B29AED /* MockUIAlertControllerSampleTests */, 248 | ); 249 | }; 250 | /* End PBXProject section */ 251 | 252 | /* Begin PBXReferenceProxy section */ 253 | 48007CA32079AC94007A4AB0 /* MockUIAlertController.framework */ = { 254 | isa = PBXReferenceProxy; 255 | fileType = wrapper.framework; 256 | path = MockUIAlertController.framework; 257 | remoteRef = 48007CA22079AC94007A4AB0 /* PBXContainerItemProxy */; 258 | sourceTree = BUILT_PRODUCTS_DIR; 259 | }; 260 | /* End PBXReferenceProxy section */ 261 | 262 | /* Begin PBXResourcesBuildPhase section */ 263 | 0E748F8F1B6543A000B29AED /* Resources */ = { 264 | isa = PBXResourcesBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | 483E05421DE80ACF00B5E4E4 /* LaunchScreen.storyboard in Resources */, 268 | 4804BCA622E16949000130AD /* XcodeWarnings.xcconfig in Resources */, 269 | 0E748FA01B6543A000B29AED /* Main.storyboard in Resources */, 270 | 0E748FA21B6543A000B29AED /* Images.xcassets in Resources */, 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | 0E748FA81B6543A000B29AED /* Resources */ = { 275 | isa = PBXResourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | /* End PBXResourcesBuildPhase section */ 282 | 283 | /* Begin PBXSourcesBuildPhase section */ 284 | 0E748F8D1B6543A000B29AED /* Sources */ = { 285 | isa = PBXSourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | 0E748F9D1B6543A000B29AED /* ViewController.m in Sources */, 289 | 0E748F9A1B6543A000B29AED /* AppDelegate.m in Sources */, 290 | 0E748F971B6543A000B29AED /* main.m in Sources */, 291 | BB170BE1D1582E79335462E0 /* CodeNextViewController.m in Sources */, 292 | 48A6B5E222E03E4D00356685 /* StoryboardNextViewController.m in Sources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | 0E748FA61B6543A000B29AED /* Sources */ = { 297 | isa = PBXSourcesBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | 609E9B6130BB35372D63FC0F /* QCOMockAlertVerifierTests.m in Sources */, 301 | 609E9F1E2EC677BB9B797C36 /* ViewControllerAlertTests.m in Sources */, 302 | BB1700CDA7D976FD6DEFFF9F /* ViewControllerPresentationTests.m in Sources */, 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | }; 306 | /* End PBXSourcesBuildPhase section */ 307 | 308 | /* Begin PBXTargetDependency section */ 309 | 0E748FAC1B6543A000B29AED /* PBXTargetDependency */ = { 310 | isa = PBXTargetDependency; 311 | target = 0E748F901B6543A000B29AED /* MockUIAlertControllerSample */; 312 | targetProxy = 0E748FAB1B6543A000B29AED /* PBXContainerItemProxy */; 313 | }; 314 | 48007CA52079ACB5007A4AB0 /* PBXTargetDependency */ = { 315 | isa = PBXTargetDependency; 316 | name = MockUIAlertController; 317 | targetProxy = 48007CA42079ACB5007A4AB0 /* PBXContainerItemProxy */; 318 | }; 319 | /* End PBXTargetDependency section */ 320 | 321 | /* Begin PBXVariantGroup section */ 322 | 0E748F9E1B6543A000B29AED /* Main.storyboard */ = { 323 | isa = PBXVariantGroup; 324 | children = ( 325 | 0E748F9F1B6543A000B29AED /* Base */, 326 | ); 327 | name = Main.storyboard; 328 | sourceTree = ""; 329 | }; 330 | 483E05401DE80ACF00B5E4E4 /* LaunchScreen.storyboard */ = { 331 | isa = PBXVariantGroup; 332 | children = ( 333 | 483E05411DE80ACF00B5E4E4 /* Base */, 334 | ); 335 | name = LaunchScreen.storyboard; 336 | sourceTree = ""; 337 | }; 338 | /* End PBXVariantGroup section */ 339 | 340 | /* Begin XCBuildConfiguration section */ 341 | 0E748FB21B6543A000B29AED /* Debug */ = { 342 | isa = XCBuildConfiguration; 343 | baseConfigurationReference = 4804BCA522E16949000130AD /* XcodeWarnings.xcconfig */; 344 | buildSettings = { 345 | ALWAYS_SEARCH_USER_PATHS = NO; 346 | CLANG_ENABLE_MODULES = YES; 347 | CLANG_ENABLE_OBJC_ARC = YES; 348 | COPY_PHASE_STRIP = NO; 349 | DEBUG_INFORMATION_FORMAT = dwarf; 350 | ENABLE_STRICT_OBJC_MSGSEND = YES; 351 | ENABLE_TESTABILITY = YES; 352 | GCC_C_LANGUAGE_STANDARD = gnu99; 353 | GCC_DYNAMIC_NO_PIC = NO; 354 | GCC_GENERATE_TEST_COVERAGE_FILES = YES; 355 | GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; 356 | GCC_NO_COMMON_BLOCKS = YES; 357 | GCC_OPTIMIZATION_LEVEL = 0; 358 | GCC_PREPROCESSOR_DEFINITIONS = ( 359 | "DEBUG=1", 360 | "$(inherited)", 361 | ); 362 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 363 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 364 | ONLY_ACTIVE_ARCH = YES; 365 | SDKROOT = iphoneos; 366 | TARGETED_DEVICE_FAMILY = "1,2"; 367 | }; 368 | name = Debug; 369 | }; 370 | 0E748FB31B6543A000B29AED /* Release */ = { 371 | isa = XCBuildConfiguration; 372 | baseConfigurationReference = 4804BCA522E16949000130AD /* XcodeWarnings.xcconfig */; 373 | buildSettings = { 374 | ALWAYS_SEARCH_USER_PATHS = NO; 375 | CLANG_ENABLE_MODULES = YES; 376 | CLANG_ENABLE_OBJC_ARC = YES; 377 | COPY_PHASE_STRIP = NO; 378 | DEBUG_INFORMATION_FORMAT = dwarf; 379 | ENABLE_NS_ASSERTIONS = NO; 380 | ENABLE_STRICT_OBJC_MSGSEND = YES; 381 | GCC_C_LANGUAGE_STANDARD = gnu99; 382 | GCC_GENERATE_TEST_COVERAGE_FILES = YES; 383 | GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES; 384 | GCC_NO_COMMON_BLOCKS = YES; 385 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 386 | SDKROOT = iphoneos; 387 | TARGETED_DEVICE_FAMILY = "1,2"; 388 | VALIDATE_PRODUCT = YES; 389 | }; 390 | name = Release; 391 | }; 392 | 0E748FB51B6543A000B29AED /* Debug */ = { 393 | isa = XCBuildConfiguration; 394 | buildSettings = { 395 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 396 | CLANG_ENABLE_MODULES = YES; 397 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 398 | INFOPLIST_FILE = SampleApp/Info.plist; 399 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 400 | OTHER_LDFLAGS = ( 401 | "-framework", 402 | Foundation, 403 | "-framework", 404 | UIKit, 405 | ); 406 | PRODUCT_BUNDLE_IDENTIFIER = "org.qualitycoding.$(PRODUCT_NAME:rfc1034identifier)"; 407 | PRODUCT_NAME = MockUIAlertControllerSample; 408 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 409 | SWIFT_VERSION = 5.0; 410 | }; 411 | name = Debug; 412 | }; 413 | 0E748FB61B6543A000B29AED /* Release */ = { 414 | isa = XCBuildConfiguration; 415 | buildSettings = { 416 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 417 | CLANG_ENABLE_MODULES = YES; 418 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 419 | INFOPLIST_FILE = SampleApp/Info.plist; 420 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 421 | OTHER_LDFLAGS = ( 422 | "-framework", 423 | Foundation, 424 | "-framework", 425 | UIKit, 426 | ); 427 | PRODUCT_BUNDLE_IDENTIFIER = "org.qualitycoding.$(PRODUCT_NAME:rfc1034identifier)"; 428 | PRODUCT_NAME = MockUIAlertControllerSample; 429 | SWIFT_VERSION = 5.0; 430 | }; 431 | name = Release; 432 | }; 433 | 0E748FB81B6543A000B29AED /* Debug */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 437 | BUNDLE_LOADER = "$(TEST_HOST)"; 438 | GCC_PREPROCESSOR_DEFINITIONS = ( 439 | "DEBUG=1", 440 | "$(inherited)", 441 | ); 442 | HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../Source\""; 443 | INFOPLIST_FILE = Tests/Info.plist; 444 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 445 | OTHER_LDFLAGS = ( 446 | "-ObjC", 447 | "-framework", 448 | Foundation, 449 | "-framework", 450 | UIKit, 451 | "-framework", 452 | XCTest, 453 | ); 454 | PRODUCT_BUNDLE_IDENTIFIER = "org.qualitycoding.$(PRODUCT_NAME:rfc1034identifier)"; 455 | PRODUCT_NAME = MockUIAlertControllerSampleTests; 456 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MockUIAlertControllerSample.app/MockUIAlertControllerSample"; 457 | }; 458 | name = Debug; 459 | }; 460 | 0E748FB91B6543A000B29AED /* Release */ = { 461 | isa = XCBuildConfiguration; 462 | buildSettings = { 463 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 464 | BUNDLE_LOADER = "$(TEST_HOST)"; 465 | HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../Source\""; 466 | INFOPLIST_FILE = Tests/Info.plist; 467 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 468 | OTHER_LDFLAGS = ( 469 | "-ObjC", 470 | "-framework", 471 | Foundation, 472 | "-framework", 473 | UIKit, 474 | "-framework", 475 | XCTest, 476 | ); 477 | PRODUCT_BUNDLE_IDENTIFIER = "org.qualitycoding.$(PRODUCT_NAME:rfc1034identifier)"; 478 | PRODUCT_NAME = MockUIAlertControllerSampleTests; 479 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MockUIAlertControllerSample.app/MockUIAlertControllerSample"; 480 | }; 481 | name = Release; 482 | }; 483 | /* End XCBuildConfiguration section */ 484 | 485 | /* Begin XCConfigurationList section */ 486 | 0E748F8C1B6543A000B29AED /* Build configuration list for PBXProject "MockUIAlertControllerSample" */ = { 487 | isa = XCConfigurationList; 488 | buildConfigurations = ( 489 | 0E748FB21B6543A000B29AED /* Debug */, 490 | 0E748FB31B6543A000B29AED /* Release */, 491 | ); 492 | defaultConfigurationIsVisible = 0; 493 | defaultConfigurationName = Release; 494 | }; 495 | 0E748FB41B6543A000B29AED /* Build configuration list for PBXNativeTarget "MockUIAlertControllerSample" */ = { 496 | isa = XCConfigurationList; 497 | buildConfigurations = ( 498 | 0E748FB51B6543A000B29AED /* Debug */, 499 | 0E748FB61B6543A000B29AED /* Release */, 500 | ); 501 | defaultConfigurationIsVisible = 0; 502 | defaultConfigurationName = Release; 503 | }; 504 | 0E748FB71B6543A000B29AED /* Build configuration list for PBXNativeTarget "MockUIAlertControllerSampleTests" */ = { 505 | isa = XCConfigurationList; 506 | buildConfigurations = ( 507 | 0E748FB81B6543A000B29AED /* Debug */, 508 | 0E748FB91B6543A000B29AED /* Release */, 509 | ); 510 | defaultConfigurationIsVisible = 0; 511 | defaultConfigurationName = Release; 512 | }; 513 | /* End XCConfigurationList section */ 514 | }; 515 | rootObject = 0E748F891B6543A000B29AED /* Project object */; 516 | } 517 | -------------------------------------------------------------------------------- /SampleObjC/MockUIAlertControllerSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SampleObjC/MockUIAlertControllerSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SampleObjC/MockUIAlertControllerSample.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SampleObjC/MockUIAlertControllerSample.xcodeproj/xcshareddata/xcschemes/MockUIAlertControllerSample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 84 | 86 | 92 | 93 | 94 | 95 | 97 | 98 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface AppDelegate : UIResponder 6 | @property (nonatomic, strong) UIWindow *window; 7 | @end 8 | 9 | NS_ASSUME_NONNULL_END 10 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | @end 5 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/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 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/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 | 33 | 42 | 49 | 56 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/CodeNextViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface CodeNextViewController : UIViewController 6 | 7 | @property (nonatomic, strong) UIColor *backgroundColor; 8 | 9 | - (instancetype)initWithBackgroundColor:(UIColor *)backgroundColor; 10 | 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/CodeNextViewController.m: -------------------------------------------------------------------------------- 1 | #import "CodeNextViewController.h" 2 | 3 | @implementation CodeNextViewController 4 | 5 | - (instancetype)initWithBackgroundColor:(UIColor *)backgroundColor 6 | { 7 | self = [super init]; 8 | if (self) 9 | { 10 | _backgroundColor = backgroundColor; 11 | } 12 | return self; 13 | } 14 | 15 | - (void)viewDidLoad 16 | { 17 | [super viewDidLoad]; 18 | self.view.backgroundColor = self.backgroundColor; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /SampleObjC/SampleApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/StoryboardNextViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface StoryboardNextViewController : UIViewController 6 | @property (nonatomic, strong) UIColor *backgroundColor; 7 | @end 8 | 9 | NS_ASSUME_NONNULL_END 10 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/StoryboardNextViewController.m: -------------------------------------------------------------------------------- 1 | #import "StoryboardNextViewController.h" 2 | 3 | @implementation StoryboardNextViewController 4 | 5 | - (void)viewDidLoad 6 | { 7 | [super viewDidLoad]; 8 | self.view.backgroundColor = self.backgroundColor; 9 | } 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/ViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | NS_ASSUME_NONNULL_BEGIN 4 | 5 | @interface ViewController : UIViewController 6 | 7 | @property (nonatomic, strong) IBOutlet UIButton *showAlertButton; 8 | @property (nonatomic, strong) IBOutlet UIButton *showActionSheetButton; 9 | @property (nonatomic, strong) IBOutlet UIButton *seguePresentModalButton; 10 | @property (nonatomic, strong) IBOutlet UIButton *segueShowButton; 11 | @property (nonatomic, strong) IBOutlet UIButton *codeModalButton; 12 | 13 | @property (nonatomic, assign) BOOL alertDefaultActionExecuted; 14 | @property (nonatomic, assign) BOOL alertCancelActionExecuted; 15 | @property (nonatomic, assign) BOOL alertDestroyActionExecuted; 16 | 17 | - (void)presentNonAlert; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/ViewController.m: -------------------------------------------------------------------------------- 1 | #import "ViewController.h" 2 | 3 | #import "CodeNextViewController.h" 4 | #import "StoryboardNextViewController.h" 5 | 6 | @implementation ViewController 7 | 8 | - (IBAction)showAlert 9 | { 10 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" 11 | message:@"Message" 12 | preferredStyle:UIAlertControllerStyleAlert]; 13 | [self setUpActionsForAlertController:alertController]; 14 | [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { 15 | textField.placeholder = @"Placeholder"; 16 | }]; 17 | [self presentViewController:alertController animated:YES completion:^{}]; 18 | } 19 | 20 | - (IBAction)showActionSheet:(id)sender 21 | { 22 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" 23 | message:@"Message" 24 | preferredStyle:UIAlertControllerStyleActionSheet]; 25 | [self setUpActionsForAlertController:alertController]; 26 | 27 | UIPopoverPresentationController *popover = alertController.popoverPresentationController; 28 | if (popover) 29 | { 30 | popover.sourceView = sender; 31 | popover.sourceRect = [sender bounds]; 32 | popover.permittedArrowDirections = UIPopoverArrowDirectionAny; 33 | } 34 | 35 | [self presentViewController:alertController animated:YES completion:NULL]; 36 | } 37 | 38 | - (void)setUpActionsForAlertController:(UIAlertController *)alertController 39 | { 40 | self.alertDefaultActionExecuted = NO; 41 | self.alertCancelActionExecuted = NO; 42 | self.alertDestroyActionExecuted = NO; 43 | 44 | UIAlertAction *actionWithoutHandler = [UIAlertAction actionWithTitle:@"No Handler" 45 | style:UIAlertActionStyleDefault 46 | handler:nil]; 47 | UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"Default" 48 | style:UIAlertActionStyleDefault 49 | handler:^(UIAlertAction *action) { 50 | self.alertDefaultActionExecuted = YES; 51 | }]; 52 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" 53 | style:UIAlertActionStyleCancel 54 | handler:^(UIAlertAction *action) { 55 | self.alertCancelActionExecuted = YES; 56 | }]; 57 | UIAlertAction *destroyAction = [UIAlertAction actionWithTitle:@"Destroy" 58 | style:UIAlertActionStyleDestructive 59 | handler:^(UIAlertAction *action) { 60 | self.alertDestroyActionExecuted = YES; 61 | }]; 62 | [alertController addAction:actionWithoutHandler]; 63 | [alertController addAction:defaultAction]; 64 | [alertController addAction:cancelAction]; 65 | [alertController addAction:destroyAction]; 66 | alertController.preferredAction = defaultAction; 67 | } 68 | 69 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender 70 | { 71 | [super prepareForSegue:segue sender:sender]; 72 | if ([segue.identifier isEqualToString:@"presentModal"]) 73 | { 74 | StoryboardNextViewController *nextVC = segue.destinationViewController; 75 | nextVC.backgroundColor = UIColor.greenColor; 76 | } 77 | else if ([segue.identifier isEqualToString:@"show"]) 78 | { 79 | StoryboardNextViewController *nextVC = segue.destinationViewController; 80 | nextVC.backgroundColor = UIColor.redColor; 81 | } 82 | } 83 | 84 | - (IBAction)showModal 85 | { 86 | UIViewController *nextVC = [[CodeNextViewController alloc] initWithBackgroundColor:UIColor.purpleColor]; 87 | [self presentViewController:nextVC animated:YES completion:NULL]; 88 | } 89 | 90 | - (void)presentNonAlert 91 | { 92 | [self presentViewController:[[UIViewController alloc] init] animated:NO completion:nil]; 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /SampleObjC/SampleApp/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import "AppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /SampleObjC/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SampleObjC/Tests/QCOMockAlertVerifierTests.m: -------------------------------------------------------------------------------- 1 | @import MockUIAlertController; 2 | 3 | #import "ViewController.h" 4 | 5 | @import XCTest; 6 | 7 | @interface QCOMockAlertVerifierTests : XCTestCase 8 | @end 9 | 10 | @implementation QCOMockAlertVerifierTests 11 | { 12 | QCOMockAlertVerifier *sut; 13 | ViewController *vc; 14 | } 15 | 16 | - (void)setUp 17 | { 18 | [super setUp]; 19 | sut = [[QCOMockAlertVerifier alloc] init]; 20 | UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 21 | vc = [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass([ViewController class])]; 22 | [vc loadViewIfNeeded]; 23 | } 24 | 25 | - (void)tearDown 26 | { 27 | sut = nil; 28 | vc = nil; 29 | [super tearDown]; 30 | } 31 | 32 | - (void)showAlert 33 | { 34 | [vc.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 35 | } 36 | 37 | - (void)test_styleForButtonWithTitle_withNonexistentTitle_shouldThrowException 38 | { 39 | [self showAlert]; 40 | 41 | @try { 42 | [sut styleForButtonWithTitle:@"NO SUCH BUTTON"]; 43 | XCTFail(@"Expected exception to be thrown"); 44 | } @catch (NSException *exception) { 45 | XCTAssertEqual(exception.name, NSInternalInconsistencyException, @"name"); 46 | XCTAssertEqualObjects(exception.reason, @"Button not found", @"reason"); 47 | } 48 | } 49 | 50 | - (void)test_executeActionForButtonWithTitle_withNonexistentTitle_shouldThrowException 51 | { 52 | [self showAlert]; 53 | 54 | @try { 55 | [sut executeActionForButtonWithTitle:@"NO SUCH BUTTON"]; 56 | XCTFail(@"Expected exception to be thrown"); 57 | } @catch (NSException *exception) { 58 | XCTAssertEqual(exception.name, NSInternalInconsistencyException, @"name"); 59 | XCTAssertEqualObjects(exception.reason, @"Button not found", @"reason"); 60 | } 61 | } 62 | 63 | - (void)test_executeActionForButtonWithTitle_withoutHandler_shouldNotCrash 64 | { 65 | [self showAlert]; 66 | 67 | [sut executeActionForButtonWithTitle:@"No Handler"]; 68 | } 69 | 70 | - (void)test_presentingNonAlertViewController_shouldNotTriggerVerifier 71 | { 72 | [vc presentNonAlert]; 73 | 74 | XCTAssertEqual(sut.presentedCount, 0); 75 | } 76 | 77 | - (void)test_showingAlert_shouldExecuteCompletionBlock 78 | { 79 | __block int completionCallCount = 0; 80 | sut.completion = ^{ 81 | completionCallCount += 1; 82 | }; 83 | 84 | [self showAlert]; 85 | 86 | XCTAssertEqual(completionCallCount, 1); 87 | } 88 | 89 | - (void)test_notShowingAlert_shouldNotExecuteCompletionBlock 90 | { 91 | __block int completionCallCount = 0; 92 | sut.completion = ^{ 93 | completionCallCount += 1; 94 | }; 95 | 96 | XCTAssertEqual(completionCallCount, 0); 97 | } 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /SampleObjC/Tests/ViewControllerAlertTests.m: -------------------------------------------------------------------------------- 1 | #import "ViewController.h" 2 | 3 | @import MockUIAlertController; 4 | @import XCTest; 5 | 6 | @interface ViewControllerAlertTests : XCTestCase 7 | @end 8 | 9 | @implementation ViewControllerAlertTests 10 | { 11 | QCOMockAlertVerifier *alertVerifier; 12 | ViewController *sut; 13 | } 14 | 15 | - (void)setUp 16 | { 17 | [super setUp]; 18 | alertVerifier = [[QCOMockAlertVerifier alloc] init]; 19 | UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 20 | sut = [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass([ViewController class])]; 21 | [sut loadViewIfNeeded]; 22 | } 23 | 24 | - (void)tearDown 25 | { 26 | alertVerifier = nil; 27 | sut = nil; 28 | [super tearDown]; 29 | } 30 | 31 | - (void)test_outlets_shouldBeConnected 32 | { 33 | XCTAssertNotNil(sut.showAlertButton); 34 | XCTAssertNotNil(sut.showActionSheetButton); 35 | } 36 | 37 | - (void)test_tappingShowAlertButton_shouldPresentAlert 38 | { 39 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 40 | 41 | XCTAssertEqual(alertVerifier.presentedCount, 1, @"presented count"); 42 | XCTAssertEqual(alertVerifier.preferredStyle, UIAlertControllerStyleAlert, @"preferred style"); 43 | XCTAssertEqual(alertVerifier.presentingViewController, sut, @"presenting view controller"); 44 | XCTAssertTrue(alertVerifier.animated, @"animated"); 45 | XCTAssertEqualObjects(alertVerifier.title, @"Title", @"title"); 46 | XCTAssertEqualObjects(alertVerifier.message, @"Message", @"message"); 47 | } 48 | 49 | - (void)test_tappingShowActionSheetButton_shouldPresentActionSheet 50 | { 51 | [sut.showActionSheetButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 52 | 53 | XCTAssertEqual(alertVerifier.presentedCount, 1, @"presented count"); 54 | XCTAssertEqual(alertVerifier.preferredStyle, UIAlertControllerStyleActionSheet, @"preferred style"); 55 | XCTAssertEqual(alertVerifier.presentingViewController, sut, @"presenting view controller"); 56 | XCTAssertTrue(alertVerifier.animated, @"animated"); 57 | XCTAssertEqualObjects(alertVerifier.title, @"Title", @"title"); 58 | XCTAssertEqualObjects(alertVerifier.message, @"Message", @"message"); 59 | } 60 | 61 | - (void)test_popoverForActionSheet 62 | { 63 | [sut.showActionSheetButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 64 | 65 | QCOMockPopoverPresentationController *popover = alertVerifier.popover; 66 | 67 | XCTAssertEqual(popover.sourceView, sut.showActionSheetButton, @"source view"); 68 | XCTAssertEqualObjects( 69 | NSStringFromCGRect(popover.sourceRect), 70 | NSStringFromCGRect(sut.showActionSheetButton.bounds), 71 | @"source rect"); 72 | XCTAssertEqual(popover.permittedArrowDirections, UIPopoverArrowDirectionAny, @"permitted arrow directions"); 73 | } 74 | 75 | - (void)test_actionsForAlert 76 | { 77 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 78 | 79 | NSArray *actions = alertVerifier.actions; 80 | 81 | XCTAssertEqual(actions.count, 4); 82 | XCTAssertEqualObjects(actions[0].title, @"No Handler"); 83 | XCTAssertEqualObjects(actions[1].title, @"Default"); 84 | XCTAssertEqual(actions[1].style, UIAlertActionStyleDefault); 85 | XCTAssertEqualObjects(actions[2].title, @"Cancel"); 86 | XCTAssertEqual(actions[2].style, UIAlertActionStyleCancel); 87 | XCTAssertEqualObjects(actions[3].title, @"Destroy"); 88 | XCTAssertEqual(actions[3].style, UIAlertActionStyleDestructive); 89 | } 90 | 91 | - (void)test_preferredActionForAlert 92 | { 93 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 94 | 95 | XCTAssertEqualObjects(alertVerifier.preferredAction.title, @"Default"); 96 | } 97 | 98 | - (void)test_actionsForActionSheet 99 | { 100 | [sut.showActionSheetButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 101 | 102 | NSArray *actions = alertVerifier.actions; 103 | 104 | XCTAssertEqual(actions.count, 4); 105 | XCTAssertEqualObjects(actions[1].title, @"Default"); 106 | XCTAssertEqual(actions[1].style, UIAlertActionStyleDefault); 107 | XCTAssertEqualObjects(actions[2].title, @"Cancel"); 108 | XCTAssertEqual(actions[2].style, UIAlertActionStyleCancel); 109 | XCTAssertEqualObjects(actions[3].title, @"Destroy"); 110 | XCTAssertEqual(actions[3].style, UIAlertActionStyleDestructive); 111 | } 112 | 113 | - (void)test_actionTitlesForAlert 114 | { 115 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 116 | 117 | XCTAssertEqual(alertVerifier.actionTitles.count, 4); 118 | XCTAssertEqualObjects(alertVerifier.actionTitles[0], @"No Handler"); 119 | XCTAssertEqualObjects(alertVerifier.actionTitles[1], @"Default"); 120 | XCTAssertEqualObjects(alertVerifier.actionTitles[2], @"Cancel"); 121 | XCTAssertEqualObjects(alertVerifier.actionTitles[3], @"Destroy"); 122 | } 123 | 124 | - (void)test_actionTitlesForActionSheet 125 | { 126 | [sut.showActionSheetButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 127 | 128 | XCTAssertEqual(alertVerifier.actionTitles.count, 4); 129 | XCTAssertEqualObjects(alertVerifier.actionTitles[0], @"No Handler"); 130 | XCTAssertEqualObjects(alertVerifier.actionTitles[1], @"Default"); 131 | XCTAssertEqualObjects(alertVerifier.actionTitles[2], @"Cancel"); 132 | XCTAssertEqualObjects(alertVerifier.actionTitles[3], @"Destroy"); 133 | } 134 | 135 | - (void)test_styleForButtonWithTitle_withDefaultButton_shouldHaveDefaultStyle 136 | { 137 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 138 | 139 | XCTAssertEqual([alertVerifier styleForButtonWithTitle:@"Default"], UIAlertActionStyleDefault); 140 | } 141 | 142 | - (void)test_styleForButtonWithTitle_withCancelButton_shouldHaveCancelStyle 143 | { 144 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 145 | 146 | XCTAssertEqual([alertVerifier styleForButtonWithTitle:@"Cancel"], UIAlertActionStyleCancel); 147 | } 148 | 149 | - (void)test_styleForButtonWithTitle_withDestroyButton_shouldHaveDestructiveStyle 150 | { 151 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 152 | 153 | XCTAssertEqual([alertVerifier styleForButtonWithTitle:@"Destroy"], UIAlertActionStyleDestructive); 154 | } 155 | 156 | - (void)test_executeActionForButtonWithTitle_withDefaultButton_shouldExecuteDefaultAction 157 | { 158 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 159 | 160 | [alertVerifier executeActionForButtonWithTitle:@"Default"]; 161 | 162 | XCTAssertTrue(sut.alertDefaultActionExecuted); 163 | } 164 | 165 | - (void)test_executeActionForButtonWithTitle_withCancelButton_shouldExecuteCancelAction 166 | { 167 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 168 | 169 | [alertVerifier executeActionForButtonWithTitle:@"Cancel"]; 170 | 171 | XCTAssertTrue(sut.alertCancelActionExecuted); 172 | } 173 | 174 | - (void)test_executeActionForButtonWithTitle_withDestroyButton_shouldExecuteDestroyAction 175 | { 176 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 177 | 178 | [alertVerifier executeActionForButtonWithTitle:@"Destroy"]; 179 | 180 | XCTAssertTrue(sut.alertDestroyActionExecuted); 181 | } 182 | 183 | - (void)test_textFieldsForAlert 184 | { 185 | [sut.showAlertButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 186 | 187 | XCTAssertEqual(alertVerifier.textFields.count, 1); 188 | XCTAssertEqualObjects(alertVerifier.textFields[0].placeholder, @"Placeholder"); 189 | } 190 | 191 | - (void)test_textFields_shouldNotBeAddedToActionSheets 192 | { 193 | [sut.showActionSheetButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 194 | 195 | XCTAssertEqual(alertVerifier.textFields.count, 0); 196 | } 197 | 198 | @end 199 | -------------------------------------------------------------------------------- /SampleObjC/Tests/ViewControllerPresentationTests.m: -------------------------------------------------------------------------------- 1 | #import "CodeNextViewController.h" 2 | 3 | #import "StoryboardNextViewController.h" 4 | #import "ViewController.h" 5 | 6 | @import MockUIAlertController; 7 | @import XCTest; 8 | 9 | @interface ViewControllerPresentationTests : XCTestCase 10 | @end 11 | 12 | @implementation ViewControllerPresentationTests 13 | 14 | { 15 | QCOMockPresentationVerifier *presentationVerifier; 16 | ViewController *sut; 17 | } 18 | 19 | - (void)setUp 20 | { 21 | [super setUp]; 22 | presentationVerifier = [[QCOMockPresentationVerifier alloc] init]; 23 | UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 24 | sut = [storyboard instantiateViewControllerWithIdentifier:NSStringFromClass([ViewController class])]; 25 | [sut loadViewIfNeeded]; 26 | } 27 | 28 | - (void)tearDown 29 | { 30 | [NSRunLoop.currentRunLoop runUntilDate:NSDate.date]; // Free objects after segue show 31 | presentationVerifier = nil; 32 | sut = nil; 33 | [super tearDown]; 34 | } 35 | 36 | - (void)test_outlets_shouldBeConnected 37 | { 38 | XCTAssertNotNil(sut.seguePresentModalButton); 39 | XCTAssertNotNil(sut.segueShowButton); 40 | XCTAssertNotNil(sut.codeModalButton); 41 | } 42 | 43 | - (void)test_tappingSeguePresentModalButton_shouldPresentNextViewControllerWithGreenBackground 44 | { 45 | [sut.seguePresentModalButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 46 | 47 | XCTAssertEqual(presentationVerifier.presentedCount, 1, @"presented count"); 48 | XCTAssertEqual(presentationVerifier.presentingViewController, sut, @"presenting view controller"); 49 | XCTAssertTrue(presentationVerifier.animated, @"animated"); 50 | if (![presentationVerifier.presentedViewController isKindOfClass:[StoryboardNextViewController class]]) { 51 | XCTFail(@"Expected presented view controller to be %@, but was %@", 52 | [StoryboardNextViewController class], presentationVerifier.presentedViewController); 53 | return; 54 | } 55 | StoryboardNextViewController *nextVC = (StoryboardNextViewController *)presentationVerifier.presentedViewController; 56 | XCTAssertEqual(nextVC.backgroundColor, UIColor.greenColor, @"Background color passed in"); 57 | } 58 | 59 | - (void)test_tappingSegueShowButton_shouldShowNextViewControllerWithRedBackground 60 | { 61 | UIWindow *window = [[UIWindow alloc] init]; 62 | window.rootViewController = sut; 63 | window.hidden = NO; 64 | 65 | [sut.segueShowButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 66 | 67 | XCTAssertEqual(presentationVerifier.presentedCount, 1, @"presented count"); 68 | XCTAssertEqual(presentationVerifier.presentingViewController, sut, @"presenting view controller"); 69 | XCTAssertTrue(presentationVerifier.animated, @"animated"); 70 | if (![presentationVerifier.presentedViewController isKindOfClass:[StoryboardNextViewController class]]) { 71 | XCTFail(@"Expected presented view controller to be %@, but was %@", 72 | [StoryboardNextViewController class], presentationVerifier.presentedViewController); 73 | return; 74 | } 75 | StoryboardNextViewController *nextVC = (StoryboardNextViewController *)presentationVerifier.presentedViewController; 76 | XCTAssertEqual(nextVC.backgroundColor, UIColor.redColor, @"Background color passed in"); 77 | } 78 | 79 | - (void)test_tappingCodeModalButton_shouldPresentNextViewControllerWithPurpleBackground 80 | { 81 | [sut.codeModalButton sendActionsForControlEvents:UIControlEventTouchUpInside]; 82 | 83 | XCTAssertEqual(presentationVerifier.presentedCount, 1, @"presented count"); 84 | XCTAssertEqual(presentationVerifier.presentingViewController, sut, @"presenting view controller"); 85 | XCTAssertTrue(presentationVerifier.animated, @"animated"); 86 | if (![presentationVerifier.presentedViewController isKindOfClass:[CodeNextViewController class]]) { 87 | XCTFail(@"Expected presented view controller to be %@, but was %@", 88 | [ViewController class], presentationVerifier.presentedViewController); 89 | return; 90 | } 91 | CodeNextViewController *nextVC = (CodeNextViewController *)presentationVerifier.presentedViewController; 92 | XCTAssertEqual(nextVC.backgroundColor, UIColor.purpleColor, @"Background color passed in"); 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /SampleSwift/MockUIAlertControllerSampleSwift.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 48007CAF2079B1BC007A4AB0 /* MockUIAlertController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 48007CAC2079B1A2007A4AB0 /* MockUIAlertController.framework */; }; 11 | 483E05211DE8064D00B5E4E4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 483E05201DE8064D00B5E4E4 /* AppDelegate.swift */; }; 12 | 483E05231DE8064D00B5E4E4 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 483E05221DE8064D00B5E4E4 /* ViewController.swift */; }; 13 | 483E05261DE8064D00B5E4E4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 483E05241DE8064D00B5E4E4 /* Main.storyboard */; }; 14 | 483E05281DE8064D00B5E4E4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 483E05271DE8064D00B5E4E4 /* Assets.xcassets */; }; 15 | 483E052B1DE8064D00B5E4E4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 483E05291DE8064D00B5E4E4 /* LaunchScreen.storyboard */; }; 16 | 483E05361DE8064D00B5E4E4 /* ViewControllerAlertTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 483E05351DE8064D00B5E4E4 /* ViewControllerAlertTests.swift */; }; 17 | BB17009B68161DEF4B893859 /* ViewControllerPresentationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB170641301DFD266F710CFF /* ViewControllerPresentationTests.swift */; }; 18 | BB170DCA39689C21DAC49039 /* CodeNextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB17059942E490E7CB29AF72 /* CodeNextViewController.swift */; }; 19 | BB170E252AEE5E0EAF396717 /* StoryboardNextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB170ED7810BEA2800855367 /* StoryboardNextViewController.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 48007CAB2079B1A2007A4AB0 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 48007CA72079B1A2007A4AB0 /* MockUIAlertController.xcodeproj */; 26 | proxyType = 2; 27 | remoteGlobalIDString = 48007C792079A76E007A4AB0; 28 | remoteInfo = MockUIAlertController; 29 | }; 30 | 48007CAD2079B1B6007A4AB0 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 48007CA72079B1A2007A4AB0 /* MockUIAlertController.xcodeproj */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 48007C782079A76E007A4AB0; 35 | remoteInfo = MockUIAlertController; 36 | }; 37 | 483E05321DE8064D00B5E4E4 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 483E05151DE8064D00B5E4E4 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 483E051C1DE8064D00B5E4E4; 42 | remoteInfo = MockUIAlertControllerSampleSwift; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | 48007CA72079B1A2007A4AB0 /* MockUIAlertController.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MockUIAlertController.xcodeproj; path = ../../Source/MockUIAlertController.xcodeproj; sourceTree = ""; }; 48 | 4804BCA822E169A9000130AD /* XcodeWarnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = XcodeWarnings.xcconfig; path = ../../Source/XcodeWarnings.xcconfig; sourceTree = ""; }; 49 | 48105E3A1DE810F2000C8EB7 /* MockUIAlertControllerSampleSwiftTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MockUIAlertControllerSampleSwiftTests-Bridging-Header.h"; sourceTree = ""; }; 50 | 48105E721DE81450000C8EB7 /* MockUIAlertController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MockUIAlertController.framework; path = "../Source/build/Debug-iphoneos/MockUIAlertController.framework"; sourceTree = ""; }; 51 | 483E051D1DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MockUIAlertControllerSampleSwift.app; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 483E05201DE8064D00B5E4E4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 53 | 483E05221DE8064D00B5E4E4 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 54 | 483E05251DE8064D00B5E4E4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | 483E05271DE8064D00B5E4E4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 483E052A1DE8064D00B5E4E4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | 483E052C1DE8064D00B5E4E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | 483E05311DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwiftTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MockUIAlertControllerSampleSwiftTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 483E05351DE8064D00B5E4E4 /* ViewControllerAlertTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerAlertTests.swift; sourceTree = ""; }; 60 | 483E05371DE8064D00B5E4E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61 | BB17059942E490E7CB29AF72 /* CodeNextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeNextViewController.swift; sourceTree = ""; }; 62 | BB170641301DFD266F710CFF /* ViewControllerPresentationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllerPresentationTests.swift; sourceTree = ""; }; 63 | BB170ED7810BEA2800855367 /* StoryboardNextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardNextViewController.swift; sourceTree = ""; }; 64 | /* End PBXFileReference section */ 65 | 66 | /* Begin PBXFrameworksBuildPhase section */ 67 | 483E051A1DE8064D00B5E4E4 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | 483E052E1DE8064D00B5E4E4 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | 48007CAF2079B1BC007A4AB0 /* MockUIAlertController.framework in Frameworks */, 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | /* End PBXFrameworksBuildPhase section */ 83 | 84 | /* Begin PBXGroup section */ 85 | 48007CA82079B1A2007A4AB0 /* Products */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 48007CAC2079B1A2007A4AB0 /* MockUIAlertController.framework */, 89 | ); 90 | name = Products; 91 | sourceTree = ""; 92 | }; 93 | 48105E711DE81450000C8EB7 /* Frameworks */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 48105E721DE81450000C8EB7 /* MockUIAlertController.framework */, 97 | ); 98 | name = Frameworks; 99 | sourceTree = ""; 100 | }; 101 | 483E05141DE8064D00B5E4E4 = { 102 | isa = PBXGroup; 103 | children = ( 104 | 483E051F1DE8064D00B5E4E4 /* SampleApp */, 105 | 483E05341DE8064D00B5E4E4 /* Tests */, 106 | 483E051E1DE8064D00B5E4E4 /* Products */, 107 | 48105E711DE81450000C8EB7 /* Frameworks */, 108 | ); 109 | sourceTree = ""; 110 | }; 111 | 483E051E1DE8064D00B5E4E4 /* Products */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 483E051D1DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwift.app */, 115 | 483E05311DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwiftTests.xctest */, 116 | ); 117 | name = Products; 118 | sourceTree = ""; 119 | }; 120 | 483E051F1DE8064D00B5E4E4 /* SampleApp */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 483E05221DE8064D00B5E4E4 /* ViewController.swift */, 124 | BB17059942E490E7CB29AF72 /* CodeNextViewController.swift */, 125 | BB170ED7810BEA2800855367 /* StoryboardNextViewController.swift */, 126 | 483E05241DE8064D00B5E4E4 /* Main.storyboard */, 127 | 483E05201DE8064D00B5E4E4 /* AppDelegate.swift */, 128 | 483E05271DE8064D00B5E4E4 /* Assets.xcassets */, 129 | 483E05291DE8064D00B5E4E4 /* LaunchScreen.storyboard */, 130 | 483E052C1DE8064D00B5E4E4 /* Info.plist */, 131 | ); 132 | path = SampleApp; 133 | sourceTree = ""; 134 | }; 135 | 483E05341DE8064D00B5E4E4 /* Tests */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 483E05351DE8064D00B5E4E4 /* ViewControllerAlertTests.swift */, 139 | BB170641301DFD266F710CFF /* ViewControllerPresentationTests.swift */, 140 | 48105E3A1DE810F2000C8EB7 /* MockUIAlertControllerSampleSwiftTests-Bridging-Header.h */, 141 | 48007CA72079B1A2007A4AB0 /* MockUIAlertController.xcodeproj */, 142 | 483E05371DE8064D00B5E4E4 /* Info.plist */, 143 | 4804BCA822E169A9000130AD /* XcodeWarnings.xcconfig */, 144 | ); 145 | path = Tests; 146 | sourceTree = ""; 147 | }; 148 | /* End PBXGroup section */ 149 | 150 | /* Begin PBXNativeTarget section */ 151 | 483E051C1DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwift */ = { 152 | isa = PBXNativeTarget; 153 | buildConfigurationList = 483E053A1DE8064D00B5E4E4 /* Build configuration list for PBXNativeTarget "MockUIAlertControllerSampleSwift" */; 154 | buildPhases = ( 155 | 483E05191DE8064D00B5E4E4 /* Sources */, 156 | 483E051A1DE8064D00B5E4E4 /* Frameworks */, 157 | 483E051B1DE8064D00B5E4E4 /* Resources */, 158 | ); 159 | buildRules = ( 160 | ); 161 | dependencies = ( 162 | ); 163 | name = MockUIAlertControllerSampleSwift; 164 | productName = MockUIAlertControllerSampleSwift; 165 | productReference = 483E051D1DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwift.app */; 166 | productType = "com.apple.product-type.application"; 167 | }; 168 | 483E05301DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwiftTests */ = { 169 | isa = PBXNativeTarget; 170 | buildConfigurationList = 483E053D1DE8064D00B5E4E4 /* Build configuration list for PBXNativeTarget "MockUIAlertControllerSampleSwiftTests" */; 171 | buildPhases = ( 172 | 483E052D1DE8064D00B5E4E4 /* Sources */, 173 | 483E052E1DE8064D00B5E4E4 /* Frameworks */, 174 | 483E052F1DE8064D00B5E4E4 /* Resources */, 175 | ); 176 | buildRules = ( 177 | ); 178 | dependencies = ( 179 | 48007CAE2079B1B6007A4AB0 /* PBXTargetDependency */, 180 | 483E05331DE8064D00B5E4E4 /* PBXTargetDependency */, 181 | ); 182 | name = MockUIAlertControllerSampleSwiftTests; 183 | productName = MockUIAlertControllerSampleSwiftTests; 184 | productReference = 483E05311DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwiftTests.xctest */; 185 | productType = "com.apple.product-type.bundle.unit-test"; 186 | }; 187 | /* End PBXNativeTarget section */ 188 | 189 | /* Begin PBXProject section */ 190 | 483E05151DE8064D00B5E4E4 /* Project object */ = { 191 | isa = PBXProject; 192 | attributes = { 193 | LastSwiftUpdateCheck = 0900; 194 | LastUpgradeCheck = 1020; 195 | ORGANIZATIONNAME = "Quality Coding"; 196 | TargetAttributes = { 197 | 483E051C1DE8064D00B5E4E4 = { 198 | CreatedOnToolsVersion = 8.1; 199 | LastSwiftMigration = 1020; 200 | ProvisioningStyle = Automatic; 201 | }; 202 | 483E05301DE8064D00B5E4E4 = { 203 | CreatedOnToolsVersion = 8.1; 204 | LastSwiftMigration = 1020; 205 | ProvisioningStyle = Automatic; 206 | TestTargetID = 483E051C1DE8064D00B5E4E4; 207 | }; 208 | }; 209 | }; 210 | buildConfigurationList = 483E05181DE8064D00B5E4E4 /* Build configuration list for PBXProject "MockUIAlertControllerSampleSwift" */; 211 | compatibilityVersion = "Xcode 3.2"; 212 | developmentRegion = en; 213 | hasScannedForEncodings = 0; 214 | knownRegions = ( 215 | en, 216 | Base, 217 | ); 218 | mainGroup = 483E05141DE8064D00B5E4E4; 219 | productRefGroup = 483E051E1DE8064D00B5E4E4 /* Products */; 220 | projectDirPath = ""; 221 | projectReferences = ( 222 | { 223 | ProductGroup = 48007CA82079B1A2007A4AB0 /* Products */; 224 | ProjectRef = 48007CA72079B1A2007A4AB0 /* MockUIAlertController.xcodeproj */; 225 | }, 226 | ); 227 | projectRoot = ""; 228 | targets = ( 229 | 483E051C1DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwift */, 230 | 483E05301DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwiftTests */, 231 | ); 232 | }; 233 | /* End PBXProject section */ 234 | 235 | /* Begin PBXReferenceProxy section */ 236 | 48007CAC2079B1A2007A4AB0 /* MockUIAlertController.framework */ = { 237 | isa = PBXReferenceProxy; 238 | fileType = wrapper.framework; 239 | path = MockUIAlertController.framework; 240 | remoteRef = 48007CAB2079B1A2007A4AB0 /* PBXContainerItemProxy */; 241 | sourceTree = BUILT_PRODUCTS_DIR; 242 | }; 243 | /* End PBXReferenceProxy section */ 244 | 245 | /* Begin PBXResourcesBuildPhase section */ 246 | 483E051B1DE8064D00B5E4E4 /* Resources */ = { 247 | isa = PBXResourcesBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | 483E052B1DE8064D00B5E4E4 /* LaunchScreen.storyboard in Resources */, 251 | 483E05281DE8064D00B5E4E4 /* Assets.xcassets in Resources */, 252 | 483E05261DE8064D00B5E4E4 /* Main.storyboard in Resources */, 253 | ); 254 | runOnlyForDeploymentPostprocessing = 0; 255 | }; 256 | 483E052F1DE8064D00B5E4E4 /* Resources */ = { 257 | isa = PBXResourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | ); 261 | runOnlyForDeploymentPostprocessing = 0; 262 | }; 263 | /* End PBXResourcesBuildPhase section */ 264 | 265 | /* Begin PBXSourcesBuildPhase section */ 266 | 483E05191DE8064D00B5E4E4 /* Sources */ = { 267 | isa = PBXSourcesBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | 483E05231DE8064D00B5E4E4 /* ViewController.swift in Sources */, 271 | 483E05211DE8064D00B5E4E4 /* AppDelegate.swift in Sources */, 272 | BB170DCA39689C21DAC49039 /* CodeNextViewController.swift in Sources */, 273 | BB170E252AEE5E0EAF396717 /* StoryboardNextViewController.swift in Sources */, 274 | ); 275 | runOnlyForDeploymentPostprocessing = 0; 276 | }; 277 | 483E052D1DE8064D00B5E4E4 /* Sources */ = { 278 | isa = PBXSourcesBuildPhase; 279 | buildActionMask = 2147483647; 280 | files = ( 281 | 483E05361DE8064D00B5E4E4 /* ViewControllerAlertTests.swift in Sources */, 282 | BB17009B68161DEF4B893859 /* ViewControllerPresentationTests.swift in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXSourcesBuildPhase section */ 287 | 288 | /* Begin PBXTargetDependency section */ 289 | 48007CAE2079B1B6007A4AB0 /* PBXTargetDependency */ = { 290 | isa = PBXTargetDependency; 291 | name = MockUIAlertController; 292 | targetProxy = 48007CAD2079B1B6007A4AB0 /* PBXContainerItemProxy */; 293 | }; 294 | 483E05331DE8064D00B5E4E4 /* PBXTargetDependency */ = { 295 | isa = PBXTargetDependency; 296 | target = 483E051C1DE8064D00B5E4E4 /* MockUIAlertControllerSampleSwift */; 297 | targetProxy = 483E05321DE8064D00B5E4E4 /* PBXContainerItemProxy */; 298 | }; 299 | /* End PBXTargetDependency section */ 300 | 301 | /* Begin PBXVariantGroup section */ 302 | 483E05241DE8064D00B5E4E4 /* Main.storyboard */ = { 303 | isa = PBXVariantGroup; 304 | children = ( 305 | 483E05251DE8064D00B5E4E4 /* Base */, 306 | ); 307 | name = Main.storyboard; 308 | sourceTree = ""; 309 | }; 310 | 483E05291DE8064D00B5E4E4 /* LaunchScreen.storyboard */ = { 311 | isa = PBXVariantGroup; 312 | children = ( 313 | 483E052A1DE8064D00B5E4E4 /* Base */, 314 | ); 315 | name = LaunchScreen.storyboard; 316 | sourceTree = ""; 317 | }; 318 | /* End PBXVariantGroup section */ 319 | 320 | /* Begin XCBuildConfiguration section */ 321 | 483E05381DE8064D00B5E4E4 /* Debug */ = { 322 | isa = XCBuildConfiguration; 323 | baseConfigurationReference = 4804BCA822E169A9000130AD /* XcodeWarnings.xcconfig */; 324 | buildSettings = { 325 | ALWAYS_SEARCH_USER_PATHS = NO; 326 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 327 | CLANG_CXX_LIBRARY = "libc++"; 328 | CLANG_ENABLE_MODULES = YES; 329 | CLANG_ENABLE_OBJC_ARC = YES; 330 | COPY_PHASE_STRIP = NO; 331 | DEBUG_INFORMATION_FORMAT = dwarf; 332 | ENABLE_TESTABILITY = YES; 333 | GCC_C_LANGUAGE_STANDARD = gnu99; 334 | GCC_DYNAMIC_NO_PIC = NO; 335 | GCC_NO_COMMON_BLOCKS = YES; 336 | GCC_OPTIMIZATION_LEVEL = 0; 337 | GCC_PREPROCESSOR_DEFINITIONS = ( 338 | "DEBUG=1", 339 | "$(inherited)", 340 | ); 341 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 342 | ONLY_ACTIVE_ARCH = YES; 343 | SDKROOT = iphoneos; 344 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 345 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 346 | SWIFT_SWIFT3_OBJC_INFERENCE = Off; 347 | SWIFT_VERSION = 4.2; 348 | TARGETED_DEVICE_FAMILY = "1,2"; 349 | }; 350 | name = Debug; 351 | }; 352 | 483E05391DE8064D00B5E4E4 /* Release */ = { 353 | isa = XCBuildConfiguration; 354 | baseConfigurationReference = 4804BCA822E169A9000130AD /* XcodeWarnings.xcconfig */; 355 | buildSettings = { 356 | ALWAYS_SEARCH_USER_PATHS = NO; 357 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 358 | CLANG_CXX_LIBRARY = "libc++"; 359 | CLANG_ENABLE_MODULES = YES; 360 | CLANG_ENABLE_OBJC_ARC = YES; 361 | COPY_PHASE_STRIP = NO; 362 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 363 | GCC_C_LANGUAGE_STANDARD = gnu99; 364 | GCC_NO_COMMON_BLOCKS = YES; 365 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 366 | SDKROOT = iphoneos; 367 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 368 | SWIFT_SWIFT3_OBJC_INFERENCE = Off; 369 | SWIFT_VERSION = 4.2; 370 | TARGETED_DEVICE_FAMILY = "1,2"; 371 | VALIDATE_PRODUCT = YES; 372 | }; 373 | name = Release; 374 | }; 375 | 483E053B1DE8064D00B5E4E4 /* Debug */ = { 376 | isa = XCBuildConfiguration; 377 | buildSettings = { 378 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 379 | INFOPLIST_FILE = SampleApp/Info.plist; 380 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 381 | PRODUCT_BUNDLE_IDENTIFIER = org.qualitycoding.MockUIAlertControllerSampleSwift; 382 | PRODUCT_NAME = "$(TARGET_NAME)"; 383 | SWIFT_VERSION = 5.0; 384 | }; 385 | name = Debug; 386 | }; 387 | 483E053C1DE8064D00B5E4E4 /* Release */ = { 388 | isa = XCBuildConfiguration; 389 | buildSettings = { 390 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 391 | INFOPLIST_FILE = SampleApp/Info.plist; 392 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 393 | PRODUCT_BUNDLE_IDENTIFIER = org.qualitycoding.MockUIAlertControllerSampleSwift; 394 | PRODUCT_NAME = "$(TARGET_NAME)"; 395 | SWIFT_VERSION = 5.0; 396 | }; 397 | name = Release; 398 | }; 399 | 483E053E1DE8064D00B5E4E4 /* Debug */ = { 400 | isa = XCBuildConfiguration; 401 | buildSettings = { 402 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 403 | BUNDLE_LOADER = "$(TEST_HOST)"; 404 | HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../Source\""; 405 | INFOPLIST_FILE = Tests/Info.plist; 406 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 407 | PRODUCT_BUNDLE_IDENTIFIER = org.qualitycoding.MockUIAlertControllerSampleSwiftTests; 408 | PRODUCT_NAME = "$(TARGET_NAME)"; 409 | SWIFT_OBJC_BRIDGING_HEADER = "./Tests/MockUIAlertControllerSampleSwiftTests-Bridging-Header.h"; 410 | SWIFT_VERSION = 5.0; 411 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MockUIAlertControllerSampleSwift.app/MockUIAlertControllerSampleSwift"; 412 | }; 413 | name = Debug; 414 | }; 415 | 483E053F1DE8064D00B5E4E4 /* Release */ = { 416 | isa = XCBuildConfiguration; 417 | buildSettings = { 418 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 419 | BUNDLE_LOADER = "$(TEST_HOST)"; 420 | HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../Source\""; 421 | INFOPLIST_FILE = Tests/Info.plist; 422 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 423 | PRODUCT_BUNDLE_IDENTIFIER = org.qualitycoding.MockUIAlertControllerSampleSwiftTests; 424 | PRODUCT_NAME = "$(TARGET_NAME)"; 425 | SWIFT_OBJC_BRIDGING_HEADER = "./Tests/MockUIAlertControllerSampleSwiftTests-Bridging-Header.h"; 426 | SWIFT_VERSION = 5.0; 427 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MockUIAlertControllerSampleSwift.app/MockUIAlertControllerSampleSwift"; 428 | }; 429 | name = Release; 430 | }; 431 | /* End XCBuildConfiguration section */ 432 | 433 | /* Begin XCConfigurationList section */ 434 | 483E05181DE8064D00B5E4E4 /* Build configuration list for PBXProject "MockUIAlertControllerSampleSwift" */ = { 435 | isa = XCConfigurationList; 436 | buildConfigurations = ( 437 | 483E05381DE8064D00B5E4E4 /* Debug */, 438 | 483E05391DE8064D00B5E4E4 /* Release */, 439 | ); 440 | defaultConfigurationIsVisible = 0; 441 | defaultConfigurationName = Release; 442 | }; 443 | 483E053A1DE8064D00B5E4E4 /* Build configuration list for PBXNativeTarget "MockUIAlertControllerSampleSwift" */ = { 444 | isa = XCConfigurationList; 445 | buildConfigurations = ( 446 | 483E053B1DE8064D00B5E4E4 /* Debug */, 447 | 483E053C1DE8064D00B5E4E4 /* Release */, 448 | ); 449 | defaultConfigurationIsVisible = 0; 450 | defaultConfigurationName = Release; 451 | }; 452 | 483E053D1DE8064D00B5E4E4 /* Build configuration list for PBXNativeTarget "MockUIAlertControllerSampleSwiftTests" */ = { 453 | isa = XCConfigurationList; 454 | buildConfigurations = ( 455 | 483E053E1DE8064D00B5E4E4 /* Debug */, 456 | 483E053F1DE8064D00B5E4E4 /* Release */, 457 | ); 458 | defaultConfigurationIsVisible = 0; 459 | defaultConfigurationName = Release; 460 | }; 461 | /* End XCConfigurationList section */ 462 | }; 463 | rootObject = 483E05151DE8064D00B5E4E4 /* Project object */; 464 | } 465 | -------------------------------------------------------------------------------- /SampleSwift/MockUIAlertControllerSampleSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SampleSwift/MockUIAlertControllerSampleSwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SampleSwift/MockUIAlertControllerSampleSwift.xcodeproj/xcshareddata/xcschemes/MockUIAlertControllerSampleSwift.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 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /SampleSwift/SampleApp/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | @UIApplicationMain 4 | class AppDelegate: UIResponder, UIApplicationDelegate { 5 | var window: UIWindow? 6 | } 7 | -------------------------------------------------------------------------------- /SampleSwift/SampleApp/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /SampleSwift/SampleApp/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 | -------------------------------------------------------------------------------- /SampleSwift/SampleApp/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 | 31 | 38 | 45 | 52 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /SampleSwift/SampleApp/CodeNextViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | final class CodeNextViewController: UIViewController { 4 | let backgroundColor: UIColor 5 | 6 | init(backgroundColor: UIColor) { 7 | self.backgroundColor = backgroundColor 8 | super.init(nibName: nil, bundle: nil) 9 | } 10 | 11 | required init?(coder aDecoder: NSCoder) { 12 | fatalError("init(coder:) has not been implemented") 13 | } 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | view.backgroundColor = backgroundColor 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /SampleSwift/SampleApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SampleSwift/SampleApp/StoryboardNextViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | final class StoryboardNextViewController: UIViewController { 4 | var backgroundColor: UIColor! 5 | 6 | override func viewDidLoad() { 7 | super.viewDidLoad() 8 | view.backgroundColor = backgroundColor 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /SampleSwift/SampleApp/ViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | final class ViewController: UIViewController { 4 | @IBOutlet private(set) var showAlertButton: UIButton! 5 | @IBOutlet private(set) var showActionSheetButton: UIButton! 6 | @IBOutlet private(set) var seguePresentModalButton: UIButton! 7 | @IBOutlet private(set) var segueShowButton: UIButton! 8 | @IBOutlet private(set) var codePresentModalButton: UIButton! 9 | 10 | var alertDefaultActionExecuted = false 11 | var alertCancelActionExecuted = false 12 | var alertDestroyActionExecuted = false 13 | 14 | deinit { 15 | print(">> ViewController.deinit") 16 | } 17 | 18 | override func viewWillAppear(_ animated: Bool) { 19 | super.viewWillAppear(animated) 20 | print(">> ViewController.viewWillAppear") 21 | } 22 | 23 | override func viewDidAppear(_ animated: Bool) { 24 | super.viewDidAppear(animated) 25 | print(">> ViewController.viewDidAppear") 26 | } 27 | 28 | @IBAction private func showAlert() { 29 | let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert) 30 | setUpActions(for: alertController) 31 | alertController.addTextField { textField in 32 | textField.placeholder = "Placeholder" 33 | } 34 | self.present(alertController, animated: true) 35 | } 36 | 37 | @IBAction private func showActionSheet(sender: AnyObject) { 38 | let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .actionSheet) 39 | setUpActions(for: alertController) 40 | 41 | let popover = alertController.popoverPresentationController 42 | if let popover = popover { 43 | popover.sourceView = sender as? UIView 44 | popover.sourceRect = sender.bounds 45 | popover.permittedArrowDirections = .any 46 | } 47 | 48 | self.present(alertController, animated: true) 49 | } 50 | 51 | private func setUpActions(for alertController: UIAlertController) { 52 | alertDefaultActionExecuted = false 53 | alertCancelActionExecuted = false 54 | alertDestroyActionExecuted = false 55 | 56 | let actionWithoutHandler = UIAlertAction.init(title: "No Handler", style: .default) 57 | let defaultAction = UIAlertAction.init(title: "Default", style: .default) { _ in 58 | self.alertDefaultActionExecuted = true 59 | } 60 | let cancelAction = UIAlertAction.init(title: "Cancel", style: .cancel) { _ in 61 | self.alertCancelActionExecuted = true 62 | } 63 | let destroyAction = UIAlertAction.init(title: "Destroy", style: .destructive) { _ in 64 | self.alertDestroyActionExecuted = true 65 | } 66 | 67 | alertController.addAction(actionWithoutHandler) 68 | alertController.addAction(defaultAction) 69 | alertController.addAction(cancelAction) 70 | alertController.addAction(destroyAction) 71 | alertController.preferredAction = defaultAction 72 | } 73 | 74 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 75 | super.prepare(for: segue, sender: sender) 76 | switch segue.identifier { 77 | case "presentModal"?: 78 | guard let nextVC = segue.destination as? StoryboardNextViewController else { return } 79 | nextVC.backgroundColor = .green 80 | case "show"?: 81 | guard let nextVC = segue.destination as? StoryboardNextViewController else { return } 82 | nextVC.backgroundColor = .red 83 | default: 84 | return 85 | } 86 | } 87 | 88 | 89 | @IBAction private func showModal() { 90 | let nextVC = CodeNextViewController(backgroundColor: .purple) 91 | self.present(nextVC, animated: true) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /SampleSwift/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SampleSwift/Tests/MockUIAlertControllerSampleSwiftTests-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | @import MockUIAlertController; 2 | -------------------------------------------------------------------------------- /SampleSwift/Tests/ViewControllerAlertTests.swift: -------------------------------------------------------------------------------- 1 | @testable import MockUIAlertControllerSampleSwift 2 | import XCTest 3 | 4 | final class ViewControllerAlertTests: XCTestCase { 5 | private var alertVerifier: QCOMockAlertVerifier! 6 | private var sut: ViewController! 7 | 8 | override func setUp() { 9 | super.setUp() 10 | alertVerifier = QCOMockAlertVerifier() 11 | let storyboard = UIStoryboard.init(name: "Main", bundle: nil) 12 | sut = storyboard.instantiateViewController(withIdentifier: String(describing: ViewController.self)) as? ViewController 13 | sut.loadViewIfNeeded() 14 | } 15 | 16 | override func tearDown() { 17 | alertVerifier = nil 18 | sut = nil 19 | super.tearDown() 20 | } 21 | 22 | func test_outlets_shouldBeConnected() { 23 | XCTAssertNotNil(sut.showAlertButton) 24 | XCTAssertNotNil(sut.showActionSheetButton) 25 | } 26 | 27 | func test_tappingShowAlertButton_shouldShowAlert() { 28 | sut.showAlertButton.sendActions(for: .touchUpInside) 29 | 30 | XCTAssertEqual(alertVerifier.presentedCount, 1, "presented count") 31 | XCTAssertEqual(alertVerifier.preferredStyle, UIAlertController.Style.alert, "preferred style") 32 | XCTAssertTrue(alertVerifier.presentingViewController === sut, 33 | "Expected presenting view controller to be \(String(describing: sut)), but was \(alertVerifier.presentingViewController)") 34 | XCTAssertTrue(alertVerifier.animated, "animated") 35 | XCTAssertEqual(alertVerifier.title, "Title", "title") 36 | XCTAssertEqual(alertVerifier.message, "Message", "message") 37 | } 38 | 39 | func test_tappingShowActionSheetButton_shouldShowActionSheet() { 40 | sut.showActionSheetButton.sendActions(for: .touchUpInside) 41 | 42 | XCTAssertEqual(alertVerifier.presentedCount, 1, "presented count") 43 | XCTAssertEqual(alertVerifier.preferredStyle, UIAlertController.Style.actionSheet, "preferred style") 44 | XCTAssertTrue(alertVerifier.presentingViewController === sut, 45 | "Expected presenting view controller to be \(String(describing: sut)), but was \(alertVerifier.presentingViewController)") 46 | XCTAssertTrue(alertVerifier.animated, "animated") 47 | XCTAssertEqual(alertVerifier.title, "Title", "title") 48 | XCTAssertEqual(alertVerifier.message, "Message", "message") 49 | } 50 | 51 | func test_popoverForActionSheet() { 52 | sut.showActionSheetButton.sendActions(for: .touchUpInside) 53 | 54 | let popover = alertVerifier.popover! 55 | 56 | XCTAssertEqual(popover.sourceView, sut.showActionSheetButton, "source view") 57 | XCTAssertEqual("\(popover.sourceRect)", "\(sut.showActionSheetButton.bounds)", "source rect") 58 | XCTAssertEqual(popover.permittedArrowDirections, UIPopoverArrowDirection.any, "permitted arrow directions") 59 | } 60 | 61 | func test_actionsForAlert() { 62 | sut.showAlertButton.sendActions(for: .touchUpInside) 63 | 64 | XCTAssertEqual(alertVerifier.actions.count, 4) 65 | XCTAssertEqual(alertVerifier.actions[0].title, "No Handler") 66 | XCTAssertEqual(alertVerifier.actions[1].title, "Default") 67 | XCTAssertEqual(alertVerifier.actions[1].style, .default) 68 | XCTAssertEqual(alertVerifier.actions[2].title, "Cancel") 69 | XCTAssertEqual(alertVerifier.actions[2].style, .cancel) 70 | XCTAssertEqual(alertVerifier.actions[3].title, "Destroy") 71 | XCTAssertEqual(alertVerifier.actions[3].style, .destructive) 72 | } 73 | 74 | func test_preferredActionForAlert() { 75 | sut.showAlertButton.sendActions(for: .touchUpInside) 76 | 77 | XCTAssertEqual(alertVerifier.preferredAction?.title, "Default") 78 | } 79 | 80 | func test_actionsForActionSheet() { 81 | sut.showActionSheetButton.sendActions(for: .touchUpInside) 82 | 83 | XCTAssertEqual(alertVerifier.actions.count, 4) 84 | XCTAssertEqual(alertVerifier.actions[0].title, "No Handler") 85 | XCTAssertEqual(alertVerifier.actions[1].title, "Default") 86 | XCTAssertEqual(alertVerifier.actions[1].style, .default) 87 | XCTAssertEqual(alertVerifier.actions[2].title, "Cancel") 88 | XCTAssertEqual(alertVerifier.actions[2].style, .cancel) 89 | XCTAssertEqual(alertVerifier.actions[3].title, "Destroy") 90 | XCTAssertEqual(alertVerifier.actions[3].style, .destructive) 91 | } 92 | 93 | func test_executeActionForButton_withDefaultButton_shouldExecuteDefaultAction() { 94 | sut.showAlertButton.sendActions(for: .touchUpInside) 95 | 96 | alertVerifier.executeActionForButton(withTitle: "Default") 97 | 98 | XCTAssertTrue(sut.alertDefaultActionExecuted) 99 | } 100 | 101 | func test_executeActionForButton_withCancelButton_shouldExecuteCancelAction() { 102 | sut.showAlertButton.sendActions(for: .touchUpInside) 103 | 104 | alertVerifier.executeActionForButton(withTitle: "Cancel") 105 | 106 | XCTAssertTrue(sut.alertCancelActionExecuted) 107 | } 108 | 109 | func test_executeActionForButton_withDestroyButton_shouldExecuteDestroyAction() { 110 | sut.showAlertButton.sendActions(for: .touchUpInside) 111 | 112 | alertVerifier.executeActionForButton(withTitle: "Destroy") 113 | 114 | XCTAssertTrue(sut.alertDestroyActionExecuted) 115 | } 116 | 117 | func test_textFieldsForAlert() { 118 | sut.showAlertButton.sendActions(for: .touchUpInside) 119 | 120 | XCTAssertEqual(alertVerifier.textFields?.count, 1) 121 | XCTAssertEqual(alertVerifier.textFields?[0].placeholder, "Placeholder") 122 | } 123 | 124 | func test_textFields_shouldNotBeAddedToActionSheets() { 125 | sut.showActionSheetButton.sendActions(for: .touchUpInside) 126 | 127 | XCTAssertEqual(alertVerifier.textFields?.count, 0) 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /SampleSwift/Tests/ViewControllerPresentationTests.swift: -------------------------------------------------------------------------------- 1 | @testable import MockUIAlertControllerSampleSwift 2 | import XCTest 3 | 4 | final class ViewControllerPresentationTests: XCTestCase { 5 | private var presentationVerifier: QCOMockPresentationVerifier! 6 | private var sut: ViewController! 7 | 8 | override func setUp() { 9 | super.setUp() 10 | presentationVerifier = QCOMockPresentationVerifier() 11 | let storyboard = UIStoryboard.init(name: "Main", bundle: nil) 12 | sut = storyboard.instantiateViewController(withIdentifier: String(describing: ViewController.self)) as? ViewController 13 | sut.loadViewIfNeeded() 14 | } 15 | 16 | override func tearDown() { 17 | RunLoop.current.run(until: Date()) // Free objects after segue show 18 | presentationVerifier = nil 19 | sut = nil 20 | super.tearDown() 21 | } 22 | 23 | func test_outlets_shouldBeConnected() { 24 | XCTAssertNotNil(sut.seguePresentModalButton) 25 | XCTAssertNotNil(sut.segueShowButton) 26 | XCTAssertNotNil(sut.codePresentModalButton) 27 | } 28 | 29 | func test_tappingSeguePresentModalButton_shouldPresentNextViewControllerWithGreenBackground() { 30 | sut.seguePresentModalButton.sendActions(for: .touchUpInside) 31 | 32 | XCTAssertEqual(presentationVerifier.presentedCount, 1, "presented count") 33 | XCTAssertTrue(presentationVerifier.animated, "animated") 34 | XCTAssertTrue(presentationVerifier.presentingViewController === sut, 35 | """ 36 | Expected presenting view controller to be \(String(describing: sut)), \ 37 | but was \(presentationVerifier.presentingViewController) 38 | """) 39 | guard let nextVC = presentationVerifier.presentedViewController as? StoryboardNextViewController else { 40 | XCTFail(""" 41 | Expected presented view controller to be \(String(describing: StoryboardNextViewController.self)), \ 42 | but was \(presentationVerifier.presentedViewController) 43 | """) 44 | return 45 | } 46 | XCTAssertEqual(nextVC.backgroundColor, UIColor.green, "Background color passed in") 47 | } 48 | 49 | func test_tappingSegueShowButton_shouldShowNextViewControllerWithGreenBackground() { 50 | let window = UIWindow() 51 | window.rootViewController = sut 52 | window.isHidden = false 53 | 54 | sut.segueShowButton.sendActions(for: .touchUpInside) 55 | 56 | XCTAssertEqual(presentationVerifier.presentedCount, 1, "presented count") 57 | XCTAssertTrue(presentationVerifier.animated, "animated") 58 | XCTAssertTrue(presentationVerifier.presentingViewController === sut, 59 | """ 60 | Expected presenting view controller to be \(String(describing: sut)), \ 61 | but was \(presentationVerifier.presentingViewController) 62 | """) 63 | guard let nextVC = presentationVerifier.presentedViewController as? StoryboardNextViewController else { 64 | XCTFail(""" 65 | Expected presented view controller to be \(String(describing: StoryboardNextViewController.self)), \ 66 | but was \(presentationVerifier.presentedViewController) 67 | """) 68 | return 69 | } 70 | XCTAssertEqual(nextVC.backgroundColor, UIColor.red, "Background color passed in") 71 | } 72 | 73 | func test_tappingCodeModalButton_shouldPresentNextViewControllerWithPurpleBackground() { 74 | sut.codePresentModalButton.sendActions(for: .touchUpInside) 75 | 76 | XCTAssertEqual(presentationVerifier.presentedCount, 1, "presented count") 77 | XCTAssertTrue(presentationVerifier.animated, "animated") 78 | XCTAssertTrue(presentationVerifier.presentingViewController === sut, 79 | """ 80 | Expected presenting view controller to be \(String(describing: sut)), \ 81 | but was \(presentationVerifier.presentingViewController) 82 | """) 83 | guard let nextVC = presentationVerifier.presentedViewController as? CodeNextViewController else { 84 | XCTFail(""" 85 | Expected presented view controller to be \(String(describing: CodeNextViewController.self)), \ 86 | but was \(presentationVerifier.presentedViewController) 87 | """) 88 | return 89 | } 90 | XCTAssertEqual(nextVC.backgroundColor, UIColor.purple, "Background color passed in") 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Source/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | 3.1.0 19 | CFBundleVersion 20 | 3.1.0 21 | NSHumanReadableCopyright 22 | Copyright © 2018 Jonathan M. Reid 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Source/MakeDistribution.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION=3.1.0 4 | DISTFILE=MockUIAlertController-${VERSION} 5 | DISTPATH=build/${DISTFILE} 6 | PROJECTROOT=.. 7 | 8 | echo Preparing clean build 9 | 10 | rm -rf build 11 | mkdir build 12 | 13 | echo Building MockUIAlertController - Release 14 | xcodebuild -configuration Release -target MockUIAlertController 15 | OUT=$? 16 | if [ "${OUT}" -ne "0" ]; then 17 | echo MockUIAlertController release build failed 18 | exit ${OUT} 19 | fi 20 | 21 | 22 | echo Assembling Distribution 23 | rm -rf "${DISTPATH}" 24 | mkdir "${DISTPATH}" 25 | cp -R "build/Release-iphoneos/MockUIAlertController.framework" "${DISTPATH}" 26 | cp "${PROJECTROOT}/README.md" "${DISTPATH}" 27 | cp "${PROJECTROOT}/CHANGELOG.md" "${DISTPATH}" 28 | cp "${PROJECTROOT}/LICENSE.txt" "${DISTPATH}" 29 | 30 | pushd build 31 | zip --recurse-paths --symlinks ${DISTFILE}.zip ${DISTFILE} 32 | open . 33 | popd 34 | -------------------------------------------------------------------------------- /Source/MockUIAlertController.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 48007C7E2079A76E007A4AB0 /* MockUIAlertController.h in Headers */ = {isa = PBXBuildFile; fileRef = 48007C7C2079A76E007A4AB0 /* MockUIAlertController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 48007C902079A7E3007A4AB0 /* QCOMockAlertVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 48007C842079A7E2007A4AB0 /* QCOMockAlertVerifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | 48007C912079A7E3007A4AB0 /* UIAlertController+QCOMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 48007C852079A7E2007A4AB0 /* UIAlertController+QCOMock.h */; }; 13 | 48007C922079A7E3007A4AB0 /* UIAlertController+QCOMock.m in Sources */ = {isa = PBXBuildFile; fileRef = 48007C862079A7E2007A4AB0 /* UIAlertController+QCOMock.m */; }; 14 | 48007C932079A7E3007A4AB0 /* UIViewController+QCOMock.m in Sources */ = {isa = PBXBuildFile; fileRef = 48007C872079A7E2007A4AB0 /* UIViewController+QCOMock.m */; }; 15 | 48007C942079A7E3007A4AB0 /* NSObject+QCOMockAlerts.h in Headers */ = {isa = PBXBuildFile; fileRef = 48007C882079A7E2007A4AB0 /* NSObject+QCOMockAlerts.h */; }; 16 | 48007C952079A7E3007A4AB0 /* QCOMockAlertVerifier.m in Sources */ = {isa = PBXBuildFile; fileRef = 48007C892079A7E2007A4AB0 /* QCOMockAlertVerifier.m */; }; 17 | 48007C962079A7E3007A4AB0 /* UIAlertAction+QCOMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 48007C8A2079A7E2007A4AB0 /* UIAlertAction+QCOMock.h */; }; 18 | 48007C972079A7E3007A4AB0 /* NSObject+QCOMockAlerts.m in Sources */ = {isa = PBXBuildFile; fileRef = 48007C8B2079A7E2007A4AB0 /* NSObject+QCOMockAlerts.m */; }; 19 | 48007C982079A7E3007A4AB0 /* QCOMockPopoverPresentationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 48007C8C2079A7E2007A4AB0 /* QCOMockPopoverPresentationController.m */; }; 20 | 48007C992079A7E3007A4AB0 /* UIAlertAction+QCOMock.m in Sources */ = {isa = PBXBuildFile; fileRef = 48007C8D2079A7E2007A4AB0 /* UIAlertAction+QCOMock.m */; }; 21 | 48007C9A2079A7E3007A4AB0 /* QCOMockPopoverPresentationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 48007C8E2079A7E3007A4AB0 /* QCOMockPopoverPresentationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | 48007C9B2079A7E3007A4AB0 /* UIViewController+QCOMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 48007C8F2079A7E3007A4AB0 /* UIViewController+QCOMock.h */; }; 23 | BB170E6CEBAF3168166B40B6 /* QCOMockPresentationVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = BB170A5F3402862D7AD0DEA6 /* QCOMockPresentationVerifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24 | BB170E93560E370864D3150D /* QCOMockPresentationVerifier.m in Sources */ = {isa = PBXBuildFile; fileRef = BB170F19D9000ECAA626B5EF /* QCOMockPresentationVerifier.m */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 48007C792079A76E007A4AB0 /* MockUIAlertController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MockUIAlertController.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 48007C7C2079A76E007A4AB0 /* MockUIAlertController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockUIAlertController.h; sourceTree = ""; }; 30 | 48007C7D2079A76E007A4AB0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | 48007C842079A7E2007A4AB0 /* QCOMockAlertVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QCOMockAlertVerifier.h; sourceTree = ""; }; 32 | 48007C852079A7E2007A4AB0 /* UIAlertController+QCOMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertController+QCOMock.h"; sourceTree = ""; }; 33 | 48007C862079A7E2007A4AB0 /* UIAlertController+QCOMock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertController+QCOMock.m"; sourceTree = ""; }; 34 | 48007C872079A7E2007A4AB0 /* UIViewController+QCOMock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+QCOMock.m"; sourceTree = ""; }; 35 | 48007C882079A7E2007A4AB0 /* NSObject+QCOMockAlerts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+QCOMockAlerts.h"; sourceTree = ""; }; 36 | 48007C892079A7E2007A4AB0 /* QCOMockAlertVerifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QCOMockAlertVerifier.m; sourceTree = ""; }; 37 | 48007C8A2079A7E2007A4AB0 /* UIAlertAction+QCOMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertAction+QCOMock.h"; sourceTree = ""; }; 38 | 48007C8B2079A7E2007A4AB0 /* NSObject+QCOMockAlerts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+QCOMockAlerts.m"; sourceTree = ""; }; 39 | 48007C8C2079A7E2007A4AB0 /* QCOMockPopoverPresentationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QCOMockPopoverPresentationController.m; sourceTree = ""; }; 40 | 48007C8D2079A7E2007A4AB0 /* UIAlertAction+QCOMock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertAction+QCOMock.m"; sourceTree = ""; }; 41 | 48007C8E2079A7E3007A4AB0 /* QCOMockPopoverPresentationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QCOMockPopoverPresentationController.h; sourceTree = ""; }; 42 | 48007C8F2079A7E3007A4AB0 /* UIViewController+QCOMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+QCOMock.h"; sourceTree = ""; }; 43 | 48007C9D2079A8D4007A4AB0 /* XcodeWarnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = XcodeWarnings.xcconfig; sourceTree = ""; }; 44 | BB170A5F3402862D7AD0DEA6 /* QCOMockPresentationVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QCOMockPresentationVerifier.h; sourceTree = ""; }; 45 | BB170F19D9000ECAA626B5EF /* QCOMockPresentationVerifier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QCOMockPresentationVerifier.m; sourceTree = ""; }; 46 | /* End PBXFileReference section */ 47 | 48 | /* Begin PBXFrameworksBuildPhase section */ 49 | 48007C752079A76E007A4AB0 /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXFrameworksBuildPhase section */ 57 | 58 | /* Begin PBXGroup section */ 59 | 48007C6F2079A76E007A4AB0 = { 60 | isa = PBXGroup; 61 | children = ( 62 | 48007C7B2079A76E007A4AB0 /* MockUIAlertController */, 63 | 48007C9C2079A8AF007A4AB0 /* Supporting Files */, 64 | 48007C7A2079A76E007A4AB0 /* Products */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | 48007C7A2079A76E007A4AB0 /* Products */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 48007C792079A76E007A4AB0 /* MockUIAlertController.framework */, 72 | ); 73 | name = Products; 74 | sourceTree = ""; 75 | }; 76 | 48007C7B2079A76E007A4AB0 /* MockUIAlertController */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 48007C7C2079A76E007A4AB0 /* MockUIAlertController.h */, 80 | 48007C882079A7E2007A4AB0 /* NSObject+QCOMockAlerts.h */, 81 | 48007C8B2079A7E2007A4AB0 /* NSObject+QCOMockAlerts.m */, 82 | 48007C842079A7E2007A4AB0 /* QCOMockAlertVerifier.h */, 83 | 48007C892079A7E2007A4AB0 /* QCOMockAlertVerifier.m */, 84 | 48007C8E2079A7E3007A4AB0 /* QCOMockPopoverPresentationController.h */, 85 | 48007C8C2079A7E2007A4AB0 /* QCOMockPopoverPresentationController.m */, 86 | BB170A5F3402862D7AD0DEA6 /* QCOMockPresentationVerifier.h */, 87 | BB170F19D9000ECAA626B5EF /* QCOMockPresentationVerifier.m */, 88 | 48007C8A2079A7E2007A4AB0 /* UIAlertAction+QCOMock.h */, 89 | 48007C8D2079A7E2007A4AB0 /* UIAlertAction+QCOMock.m */, 90 | 48007C852079A7E2007A4AB0 /* UIAlertController+QCOMock.h */, 91 | 48007C862079A7E2007A4AB0 /* UIAlertController+QCOMock.m */, 92 | 48007C8F2079A7E3007A4AB0 /* UIViewController+QCOMock.h */, 93 | 48007C872079A7E2007A4AB0 /* UIViewController+QCOMock.m */, 94 | ); 95 | path = MockUIAlertController; 96 | sourceTree = ""; 97 | }; 98 | 48007C9C2079A8AF007A4AB0 /* Supporting Files */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 48007C7D2079A76E007A4AB0 /* Info.plist */, 102 | 48007C9D2079A8D4007A4AB0 /* XcodeWarnings.xcconfig */, 103 | ); 104 | name = "Supporting Files"; 105 | sourceTree = ""; 106 | }; 107 | /* End PBXGroup section */ 108 | 109 | /* Begin PBXHeadersBuildPhase section */ 110 | 48007C762079A76E007A4AB0 /* Headers */ = { 111 | isa = PBXHeadersBuildPhase; 112 | buildActionMask = 2147483647; 113 | files = ( 114 | 48007C7E2079A76E007A4AB0 /* MockUIAlertController.h in Headers */, 115 | 48007C902079A7E3007A4AB0 /* QCOMockAlertVerifier.h in Headers */, 116 | 48007C962079A7E3007A4AB0 /* UIAlertAction+QCOMock.h in Headers */, 117 | 48007C9B2079A7E3007A4AB0 /* UIViewController+QCOMock.h in Headers */, 118 | 48007C9A2079A7E3007A4AB0 /* QCOMockPopoverPresentationController.h in Headers */, 119 | 48007C942079A7E3007A4AB0 /* NSObject+QCOMockAlerts.h in Headers */, 120 | 48007C912079A7E3007A4AB0 /* UIAlertController+QCOMock.h in Headers */, 121 | BB170E6CEBAF3168166B40B6 /* QCOMockPresentationVerifier.h in Headers */, 122 | ); 123 | runOnlyForDeploymentPostprocessing = 0; 124 | }; 125 | /* End PBXHeadersBuildPhase section */ 126 | 127 | /* Begin PBXNativeTarget section */ 128 | 48007C782079A76E007A4AB0 /* MockUIAlertController */ = { 129 | isa = PBXNativeTarget; 130 | buildConfigurationList = 48007C812079A76E007A4AB0 /* Build configuration list for PBXNativeTarget "MockUIAlertController" */; 131 | buildPhases = ( 132 | 48007C742079A76E007A4AB0 /* Sources */, 133 | 48007C752079A76E007A4AB0 /* Frameworks */, 134 | 48007C762079A76E007A4AB0 /* Headers */, 135 | ); 136 | buildRules = ( 137 | ); 138 | dependencies = ( 139 | ); 140 | name = MockUIAlertController; 141 | productName = MockUIAlertController; 142 | productReference = 48007C792079A76E007A4AB0 /* MockUIAlertController.framework */; 143 | productType = "com.apple.product-type.framework"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | 48007C702079A76E007A4AB0 /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastUpgradeCheck = 0930; 152 | ORGANIZATIONNAME = "Quality Coding"; 153 | TargetAttributes = { 154 | 48007C782079A76E007A4AB0 = { 155 | CreatedOnToolsVersion = 9.3; 156 | }; 157 | }; 158 | }; 159 | buildConfigurationList = 48007C732079A76E007A4AB0 /* Build configuration list for PBXProject "MockUIAlertController" */; 160 | compatibilityVersion = "Xcode 9.3"; 161 | developmentRegion = en; 162 | hasScannedForEncodings = 0; 163 | knownRegions = ( 164 | en, 165 | Base, 166 | ); 167 | mainGroup = 48007C6F2079A76E007A4AB0; 168 | productRefGroup = 48007C7A2079A76E007A4AB0 /* Products */; 169 | projectDirPath = ""; 170 | projectRoot = ""; 171 | targets = ( 172 | 48007C782079A76E007A4AB0 /* MockUIAlertController */, 173 | ); 174 | }; 175 | /* End PBXProject section */ 176 | 177 | /* Begin PBXSourcesBuildPhase section */ 178 | 48007C742079A76E007A4AB0 /* Sources */ = { 179 | isa = PBXSourcesBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | 48007C982079A7E3007A4AB0 /* QCOMockPopoverPresentationController.m in Sources */, 183 | 48007C932079A7E3007A4AB0 /* UIViewController+QCOMock.m in Sources */, 184 | 48007C922079A7E3007A4AB0 /* UIAlertController+QCOMock.m in Sources */, 185 | 48007C972079A7E3007A4AB0 /* NSObject+QCOMockAlerts.m in Sources */, 186 | 48007C992079A7E3007A4AB0 /* UIAlertAction+QCOMock.m in Sources */, 187 | 48007C952079A7E3007A4AB0 /* QCOMockAlertVerifier.m in Sources */, 188 | BB170E93560E370864D3150D /* QCOMockPresentationVerifier.m in Sources */, 189 | ); 190 | runOnlyForDeploymentPostprocessing = 0; 191 | }; 192 | /* End PBXSourcesBuildPhase section */ 193 | 194 | /* Begin XCBuildConfiguration section */ 195 | 48007C7F2079A76E007A4AB0 /* Debug */ = { 196 | isa = XCBuildConfiguration; 197 | baseConfigurationReference = 48007C9D2079A8D4007A4AB0 /* XcodeWarnings.xcconfig */; 198 | buildSettings = { 199 | ALWAYS_SEARCH_USER_PATHS = NO; 200 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 201 | CLANG_CXX_LIBRARY = "libc++"; 202 | CLANG_ENABLE_MODULES = YES; 203 | CLANG_ENABLE_OBJC_ARC = YES; 204 | CLANG_ENABLE_OBJC_WEAK = YES; 205 | CODE_SIGN_IDENTITY = "iPhone Developer"; 206 | COPY_PHASE_STRIP = NO; 207 | CURRENT_PROJECT_VERSION = 1; 208 | DEBUG_INFORMATION_FORMAT = dwarf; 209 | DEFINES_MODULE = YES; 210 | ENABLE_TESTABILITY = YES; 211 | GCC_C_LANGUAGE_STANDARD = gnu11; 212 | GCC_DYNAMIC_NO_PIC = NO; 213 | GCC_NO_COMMON_BLOCKS = YES; 214 | GCC_OPTIMIZATION_LEVEL = 0; 215 | GCC_PREPROCESSOR_DEFINITIONS = ( 216 | "DEBUG=1", 217 | "$(inherited)", 218 | ); 219 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 220 | ONLY_ACTIVE_ARCH = YES; 221 | SDKROOT = iphoneos; 222 | TARGETED_DEVICE_FAMILY = "1,2"; 223 | VERSIONING_SYSTEM = "apple-generic"; 224 | VERSION_INFO_PREFIX = ""; 225 | }; 226 | name = Debug; 227 | }; 228 | 48007C802079A76E007A4AB0 /* Release */ = { 229 | isa = XCBuildConfiguration; 230 | baseConfigurationReference = 48007C9D2079A8D4007A4AB0 /* XcodeWarnings.xcconfig */; 231 | buildSettings = { 232 | ALWAYS_SEARCH_USER_PATHS = NO; 233 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 234 | CLANG_CXX_LIBRARY = "libc++"; 235 | CLANG_ENABLE_MODULES = YES; 236 | CLANG_ENABLE_OBJC_ARC = YES; 237 | CLANG_ENABLE_OBJC_WEAK = YES; 238 | CODE_SIGN_IDENTITY = "iPhone Developer"; 239 | COPY_PHASE_STRIP = NO; 240 | CURRENT_PROJECT_VERSION = 1; 241 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 242 | DEFINES_MODULE = YES; 243 | ENABLE_NS_ASSERTIONS = NO; 244 | GCC_C_LANGUAGE_STANDARD = gnu11; 245 | GCC_NO_COMMON_BLOCKS = YES; 246 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 247 | SDKROOT = iphoneos; 248 | TARGETED_DEVICE_FAMILY = "1,2"; 249 | VERSIONING_SYSTEM = "apple-generic"; 250 | VERSION_INFO_PREFIX = ""; 251 | }; 252 | name = Release; 253 | }; 254 | 48007C822079A76E007A4AB0 /* Debug */ = { 255 | isa = XCBuildConfiguration; 256 | buildSettings = { 257 | CODE_SIGN_IDENTITY = ""; 258 | CODE_SIGN_STYLE = Manual; 259 | DEVELOPMENT_TEAM = ""; 260 | DYLIB_COMPATIBILITY_VERSION = 1; 261 | DYLIB_CURRENT_VERSION = 1; 262 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 263 | INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; 264 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 265 | LD_RUNPATH_SEARCH_PATHS = ( 266 | "$(inherited)", 267 | "@executable_path/Frameworks", 268 | "@loader_path/Frameworks", 269 | ); 270 | PRODUCT_BUNDLE_IDENTIFIER = org.qualitycoding.MockUIAlertController; 271 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 272 | PROVISIONING_PROFILE_SPECIFIER = ""; 273 | SKIP_INSTALL = YES; 274 | }; 275 | name = Debug; 276 | }; 277 | 48007C832079A76E007A4AB0 /* Release */ = { 278 | isa = XCBuildConfiguration; 279 | buildSettings = { 280 | CODE_SIGN_IDENTITY = ""; 281 | CODE_SIGN_STYLE = Manual; 282 | DEVELOPMENT_TEAM = ""; 283 | DYLIB_COMPATIBILITY_VERSION = 1; 284 | DYLIB_CURRENT_VERSION = 1; 285 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 286 | INFOPLIST_FILE = "$(SRCROOT)/Info.plist"; 287 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 288 | LD_RUNPATH_SEARCH_PATHS = ( 289 | "$(inherited)", 290 | "@executable_path/Frameworks", 291 | "@loader_path/Frameworks", 292 | ); 293 | PRODUCT_BUNDLE_IDENTIFIER = org.qualitycoding.MockUIAlertController; 294 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 295 | PROVISIONING_PROFILE_SPECIFIER = ""; 296 | SKIP_INSTALL = YES; 297 | }; 298 | name = Release; 299 | }; 300 | /* End XCBuildConfiguration section */ 301 | 302 | /* Begin XCConfigurationList section */ 303 | 48007C732079A76E007A4AB0 /* Build configuration list for PBXProject "MockUIAlertController" */ = { 304 | isa = XCConfigurationList; 305 | buildConfigurations = ( 306 | 48007C7F2079A76E007A4AB0 /* Debug */, 307 | 48007C802079A76E007A4AB0 /* Release */, 308 | ); 309 | defaultConfigurationIsVisible = 0; 310 | defaultConfigurationName = Release; 311 | }; 312 | 48007C812079A76E007A4AB0 /* Build configuration list for PBXNativeTarget "MockUIAlertController" */ = { 313 | isa = XCConfigurationList; 314 | buildConfigurations = ( 315 | 48007C822079A76E007A4AB0 /* Debug */, 316 | 48007C832079A76E007A4AB0 /* Release */, 317 | ); 318 | defaultConfigurationIsVisible = 0; 319 | defaultConfigurationName = Release; 320 | }; 321 | /* End XCConfigurationList section */ 322 | }; 323 | rootObject = 48007C702079A76E007A4AB0 /* Project object */; 324 | } 325 | -------------------------------------------------------------------------------- /Source/MockUIAlertController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Source/MockUIAlertController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Source/MockUIAlertController.xcodeproj/xcshareddata/xcschemes/MockUIAlertController.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/MockUIAlertController.h: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import 5 | 6 | FOUNDATION_EXPORT double MockUIAlertControllerVersionNumber; 7 | FOUNDATION_EXPORT const unsigned char MockUIAlertControllerVersionString[]; 8 | 9 | #import "QCOMockAlertVerifier.h" 10 | #import "QCOMockPresentationVerifier.h" 11 | #import "QCOMockPopoverPresentationController.h" 12 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/NSObject+QCOMockAlerts.h: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | @interface NSObject (QCOMockAlerts) 9 | + (void)qcoMockAlerts_replaceClassMethod:(SEL)originalSelector withMethod:(SEL)swizzledSelector; 10 | + (void)qcoMockAlerts_replaceInstanceMethod:(SEL)originalSelector withMethod:(SEL)swizzledSelector; 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/NSObject+QCOMockAlerts.m: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import "NSObject+QCOMockAlerts.h" 5 | 6 | #import 7 | 8 | @implementation NSObject (QCOMockAlerts) 9 | 10 | + (void)qcoMockAlerts_replaceClassMethod:(SEL)originalSelector withMethod:(SEL)swizzledSelector 11 | { 12 | Method originalMethod = class_getClassMethod(self, originalSelector); 13 | Method swizzledMethod = class_getClassMethod(self, swizzledSelector); 14 | method_exchangeImplementations(originalMethod, swizzledMethod); 15 | } 16 | 17 | + (void)qcoMockAlerts_replaceInstanceMethod:(SEL)originalSelector withMethod:(SEL)swizzledSelector 18 | { 19 | Method originalMethod = class_getInstanceMethod(self, originalSelector); 20 | Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector); 21 | method_exchangeImplementations(originalMethod, swizzledMethod); 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/QCOMockAlertVerifier.h: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import 5 | 6 | #import "QCOMockPopoverPresentationController.h" // Convenience import instead of @class 7 | 8 | NS_ASSUME_NONNULL_BEGIN 9 | 10 | /*! 11 | * @abstract Captures mocked UIAlertController arguments. 12 | * @discussion Instantiate a QCOMockAlertVerifier before the execution phase of the test. Then 13 | * invoke the code to create and present your alert. Information about the alert is then available 14 | * through the QCOMockAlertVerifier. 15 | */ 16 | @interface QCOMockAlertVerifier : NSObject 17 | 18 | @property (nonatomic, assign) NSUInteger presentedCount; 19 | @property (nonatomic, strong) UIViewController *presentingViewController; 20 | @property (nonatomic, assign) BOOL animated; 21 | @property (nullable, nonatomic, copy) NSString *title; 22 | @property (nullable, nonatomic, copy) NSString *message; 23 | @property (nonatomic, assign) UIAlertControllerStyle preferredStyle; 24 | @property (nonatomic, copy) NSArray *actions; 25 | @property (nullable, nonatomic, strong) UIAlertAction *preferredAction; 26 | @property (nonatomic, readonly) NSArray *actionTitles DEPRECATED_MSG_ATTRIBUTE("Use actions"); 27 | @property (nullable, nonatomic, strong) QCOMockPopoverPresentationController *popover; 28 | @property (nullable, nonatomic, copy) NSArray *textFields; 29 | @property (nullable, nonatomic, copy) void (^completion)(void); 30 | 31 | /*! 32 | * @abstract Initializes a newly allocated verifier. 33 | * @discussion Instantiating a QCOMockAlertVerifier swizzles UIAlertController. It remains swizzled 34 | * until the QCOMockAlertVerifier is deallocated. 35 | */ 36 | - (instancetype)init NS_DESIGNATED_INITIALIZER; 37 | 38 | /*! 39 | * @abstract Returns the UIAlertActionStyle for the button with the specified title. 40 | * @discussion Throws an exception if no button with that title is found. 41 | */ 42 | - (UIAlertActionStyle)styleForButtonWithTitle:(NSString *)title DEPRECATED_MSG_ATTRIBUTE("Use actions"); 43 | 44 | /*! 45 | * @abstract Executes the action for the button with the specified title. 46 | * @discussion Throws an exception if no button with that title is found. 47 | */ 48 | - (void)executeActionForButtonWithTitle:(NSString *)title; 49 | 50 | @end 51 | 52 | NS_ASSUME_NONNULL_END 53 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/QCOMockAlertVerifier.m: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import "QCOMockAlertVerifier.h" 5 | 6 | #import "UIAlertAction+QCOMock.h" 7 | #import "UIAlertController+QCOMock.h" 8 | #import "UIViewController+QCOMock.h" 9 | 10 | static void swizzleMocks(void) 11 | { 12 | [UIAlertAction qcoMock_swizzle]; 13 | [UIAlertController qcoMock_swizzle]; 14 | [UIViewController qcoMock_swizzleCaptureAlert]; 15 | } 16 | 17 | @implementation QCOMockAlertVerifier 18 | 19 | - (instancetype)init 20 | { 21 | self = [super init]; 22 | if (self) 23 | { 24 | [[NSNotificationCenter defaultCenter] addObserver:self 25 | selector:@selector(alertControllerWasPresented:) 26 | name:QCOMockAlertControllerPresentedNotification 27 | object:nil]; 28 | swizzleMocks(); 29 | } 30 | return self; 31 | } 32 | 33 | - (void)dealloc 34 | { 35 | swizzleMocks(); 36 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 37 | } 38 | 39 | - (void)alertControllerWasPresented:(NSNotification *)notification 40 | { 41 | UIAlertController *alertController = notification.object; 42 | self.presentedCount += 1; 43 | self.presentingViewController = notification.userInfo[QCOMockViewControllerPresentingViewControllerKey]; 44 | self.animated = [notification.userInfo[QCOMockViewControllerAnimatedKey] boolValue]; 45 | self.title = alertController.title; 46 | self.message = alertController.message; 47 | self.preferredStyle = alertController.preferredStyle; 48 | self.actions = alertController.actions; 49 | self.preferredAction = alertController.preferredAction; 50 | self.popover = (id)alertController.popoverPresentationController; 51 | self.textFields = alertController.textFields; 52 | if (self.completion) 53 | self.completion(); 54 | } 55 | 56 | - (NSArray *)actionTitles 57 | { 58 | NSMutableArray *array = [[NSMutableArray alloc] init]; 59 | for (UIAlertAction *action in self.actions) 60 | [array addObject: action.title ? action.title : [NSNull null]]; 61 | return [array copy]; 62 | } 63 | 64 | - (UIAlertActionStyle)styleForButtonWithTitle:(NSString *)title 65 | { 66 | UIAlertAction *action = [self actionWithTitle:title]; 67 | return action.style; 68 | } 69 | 70 | - (void)executeActionForButtonWithTitle:(NSString *)title 71 | { 72 | UIAlertAction *action = [self actionWithTitle:title]; 73 | void (^handler)(UIAlertAction *) = [action qcoMock_handler]; 74 | if (handler) 75 | handler(action); 76 | } 77 | 78 | - (UIAlertAction *)actionWithTitle:(NSString *)title 79 | { 80 | for (UIAlertAction *action in self.actions) 81 | if ([action.title isEqualToString:title]) 82 | return action; 83 | 84 | @throw [NSException exceptionWithName:NSInternalInconsistencyException 85 | reason:@"Button not found" 86 | userInfo:nil]; 87 | } 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/QCOMockPopoverPresentationController.h: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | /*! 9 | * @abstract Same as UIPopoverPresentationController, but changing arrowDirection to readwrite. 10 | */ 11 | @interface QCOMockPopoverPresentationController : NSObject 12 | 13 | @property (nullable, nonatomic, weak) id delegate; 14 | 15 | @property (nonatomic, assign) UIPopoverArrowDirection permittedArrowDirections; 16 | 17 | @property (nullable, nonatomic, strong) UIView *sourceView; 18 | @property (nonatomic, assign) CGRect sourceRect; 19 | 20 | // By default, a popover is not allowed to overlap its source view rect. 21 | // When this is set to YES, popovers with more content than available space are allowed to overlap the source view rect in order to accommodate the content. 22 | @property (nonatomic, assign) BOOL canOverlapSourceViewRect NS_AVAILABLE_IOS(9_0); 23 | 24 | @property (nullable, nonatomic, strong) UIBarButtonItem *barButtonItem; 25 | 26 | // Returns the direction the arrow is pointing on a presented popover. Before presentation, this returns UIPopoverArrowDirectionUnknown. 27 | @property (nonatomic, readwrite) UIPopoverArrowDirection arrowDirection; 28 | 29 | // By default, a popover disallows interaction with any view outside of the popover while the popover is presented. 30 | // This property allows the specification of an array of UIView instances which the user is allowed to interact with 31 | // while the popover is up. 32 | @property (nullable, nonatomic, copy) NSArray *passthroughViews; 33 | 34 | // Set popover background color. Set to nil to use default background color. Default is nil. 35 | @property (nullable, nonatomic, copy) UIColor *backgroundColor; 36 | 37 | // Clients may wish to change the available area for popover display. The default implementation of this method always 38 | // returns insets which define 10 points from the edges of the display, and presentation of popovers always accounts 39 | // for the status bar. The rectangle being inset is always expressed in terms of the current device orientation; (0, 0) 40 | // is always in the upper-left of the device. This may require insets to change on device rotation. 41 | @property (nonatomic, readwrite) UIEdgeInsets popoverLayoutMargins; 42 | 43 | // Clients may customize the popover background chrome by providing a class which subclasses `UIPopoverBackgroundView` 44 | // and which implements the required instance and class methods on that class. 45 | @property (nullable, nonatomic, readwrite, strong) Class popoverBackgroundViewClass; 46 | 47 | @end 48 | 49 | NS_ASSUME_NONNULL_END 50 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/QCOMockPopoverPresentationController.m: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import "QCOMockPopoverPresentationController.h" 5 | 6 | @implementation QCOMockPopoverPresentationController 7 | @end 8 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/QCOMockPresentationVerifier.h: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import 5 | 6 | #import "QCOMockPopoverPresentationController.h" // Convenience import instead of @class 7 | 8 | NS_ASSUME_NONNULL_BEGIN 9 | 10 | /*! 11 | * @abstract Captures mocked presented view controllers. 12 | * @discussion Instantiate a QCOMockPresentationVerifier before the execution phase of the test. Then 13 | * invoke the code to create and present your view controller. Information about the view controller 14 | * is then available through the QCOMockPresentationVerifier. 15 | */ 16 | @interface QCOMockPresentationVerifier : NSObject 17 | 18 | @property (nonatomic, assign) NSUInteger presentedCount; 19 | @property (nonatomic, strong) UIViewController *presentedViewController; 20 | @property (nonatomic, strong) UIViewController *presentingViewController; 21 | @property (nonatomic, assign) BOOL animated; 22 | @property (nullable, nonatomic, copy) void (^completion)(void); 23 | 24 | /*! 25 | * @abstract Initializes a newly allocated verifier. 26 | * @discussion Instantiating a QCOMockPresentationVerifier swizzles UIViewController. It remains swizzled 27 | * until the QCOMockPresentationVerifier is deallocated. 28 | */ 29 | - (instancetype)init NS_DESIGNATED_INITIALIZER; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/QCOMockPresentationVerifier.m: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import "QCOMockPresentationVerifier.h" 5 | 6 | #import "UIViewController+QCOMock.h" 7 | 8 | static void swizzleMocks(void) 9 | { 10 | [UIViewController qcoMock_swizzleCaptureViewController]; 11 | } 12 | 13 | @implementation QCOMockPresentationVerifier 14 | 15 | - (instancetype)init 16 | { 17 | self = [super init]; 18 | if (self) 19 | { 20 | [[NSNotificationCenter defaultCenter] addObserver:self 21 | selector:@selector(viewControllerWasPresented:) 22 | name:QCOMockViewControllerPresentedNotification 23 | object:nil]; 24 | swizzleMocks(); 25 | } 26 | return self; 27 | } 28 | 29 | - (void)dealloc 30 | { 31 | swizzleMocks(); 32 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 33 | } 34 | 35 | - (void)viewControllerWasPresented:(NSNotification *)notification 36 | { 37 | self.presentedCount += 1; 38 | self.presentedViewController = notification.object; 39 | self.presentingViewController = notification.userInfo[QCOMockViewControllerPresentingViewControllerKey]; 40 | self.animated = [notification.userInfo[QCOMockViewControllerAnimatedKey] boolValue]; 41 | if (self.completion) 42 | self.completion(); 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/UIAlertAction+QCOMock.h: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | @interface UIAlertAction (QCOMock) 9 | + (void)qcoMock_swizzle; 10 | - (void (^)(UIAlertAction *action))qcoMock_handler; 11 | @end 12 | 13 | NS_ASSUME_NONNULL_END 14 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/UIAlertAction+QCOMock.m: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import "UIAlertAction+QCOMock.h" 5 | 6 | #import "NSObject+QCOMockAlerts.h" 7 | #import 8 | 9 | @implementation UIAlertAction (QCOMock) 10 | 11 | + (void)qcoMock_swizzle 12 | { 13 | [self qcoMockAlerts_replaceClassMethod:@selector(actionWithTitle:style:handler:) 14 | withMethod:@selector(qcoMock_actionWithTitle:style:handler:)]; 15 | } 16 | 17 | + (instancetype)qcoMock_actionWithTitle:(NSString *)title 18 | style:(UIAlertActionStyle)style 19 | handler:(void (^)(UIAlertAction *action))handler 20 | { 21 | UIAlertAction *action = [self qcoMock_actionWithTitle:title style:style handler:handler]; 22 | objc_setAssociatedObject(action, @selector(qcoMock_handler), handler, OBJC_ASSOCIATION_COPY_NONATOMIC); 23 | return action; 24 | } 25 | 26 | - (void (^)(UIAlertAction *action))qcoMock_handler 27 | { 28 | return objc_getAssociatedObject(self, @selector(qcoMock_handler)); 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/UIAlertController+QCOMock.h: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | extern NSString *const QCOMockAlertControllerPresentedNotification; 9 | 10 | @interface UIAlertController (QCOMock) 11 | + (void)qcoMock_swizzle; 12 | @end 13 | 14 | NS_ASSUME_NONNULL_END 15 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/UIAlertController+QCOMock.m: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import "UIAlertController+QCOMock.h" 5 | 6 | #import "NSObject+QCOMockAlerts.h" 7 | #import "QCOMockPopoverPresentationController.h" 8 | #import 9 | 10 | NSString *const QCOMockAlertControllerPresentedNotification = @"QCOMockAlertControllerPresentedNotification"; 11 | 12 | @interface UIAlertController () 13 | @property (nonatomic, strong) QCOMockPopoverPresentationController *qcoMock_mockPopover; 14 | @property (nonatomic, readwrite) UIAlertControllerStyle preferredStyle; 15 | @end 16 | 17 | @implementation UIAlertController (QCOMock) 18 | 19 | + (void)qcoMock_swizzle 20 | { 21 | [self qcoMockAlerts_replaceClassMethod:@selector(alertControllerWithTitle:message:preferredStyle:) 22 | withMethod:@selector(qcoMock_alertControllerWithTitle:message:preferredStyle:)]; 23 | [self qcoMockAlerts_replaceInstanceMethod:@selector(popoverPresentationController) 24 | withMethod:@selector(qcoMock_popoverPresentationController)]; 25 | } 26 | 27 | + (instancetype)qcoMock_alertControllerWithTitle:(NSString *)title 28 | message:(NSString *)message 29 | preferredStyle:(UIAlertControllerStyle)preferredStyle 30 | { 31 | return [[self alloc] initQCOMockWithTitle:title message:message preferredStyle:preferredStyle]; 32 | } 33 | 34 | - (instancetype)initQCOMockWithTitle:(NSString *)title 35 | message:(NSString *)message 36 | preferredStyle:(UIAlertControllerStyle)style 37 | { 38 | self = [super init]; 39 | if (self) 40 | { 41 | self.title = title; 42 | self.message = message; 43 | self.preferredStyle = style; 44 | self.qcoMock_mockPopover = [[QCOMockPopoverPresentationController alloc] init]; 45 | } 46 | return self; 47 | } 48 | 49 | - (UIPopoverPresentationController *)qcoMock_popoverPresentationController 50 | { 51 | if ([self respondsToSelector:@selector(qcoMock_mockPopover)]) { 52 | return (id)self.qcoMock_mockPopover; 53 | } 54 | return nil; 55 | } 56 | 57 | - (QCOMockPopoverPresentationController *)qcoMock_mockPopover 58 | { 59 | return objc_getAssociatedObject(self, @selector(qcoMock_mockPopover)); 60 | } 61 | 62 | - (void)setQcoMock_mockPopover:(QCOMockPopoverPresentationController *)popover 63 | { 64 | objc_setAssociatedObject(self, @selector(qcoMock_mockPopover), popover, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/UIViewController+QCOMock.h: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import 5 | 6 | NS_ASSUME_NONNULL_BEGIN 7 | 8 | extern NSString *const QCOMockViewControllerPresentingViewControllerKey; 9 | extern NSString *const QCOMockViewControllerAnimatedKey; 10 | extern NSString *const QCOMockViewControllerPresentedNotification; 11 | 12 | @interface UIViewController (QCOMock) 13 | + (void)qcoMock_swizzleCaptureAlert; 14 | + (void)qcoMock_swizzleCaptureViewController; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Source/MockUIAlertController/UIViewController+QCOMock.m: -------------------------------------------------------------------------------- 1 | // MockUIAlertController by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | 4 | #import "UIViewController+QCOMock.h" 5 | 6 | #import "NSObject+QCOMockAlerts.h" 7 | #import "UIAlertController+QCOMock.h" 8 | 9 | NSString *const QCOMockViewControllerPresentingViewControllerKey = @"QCOMockViewControllerPresentingViewControllerKey"; 10 | NSString *const QCOMockViewControllerAnimatedKey = @"QCOMockViewControllerAnimatedKey"; 11 | NSString *const QCOMockViewControllerPresentedNotification = @"QCOMockViewControllerPresentedNotification"; 12 | 13 | @implementation UIViewController (QCOMock) 14 | 15 | + (void)qcoMock_swizzleCaptureAlert 16 | { 17 | [self qcoMockAlerts_replaceInstanceMethod:@selector(presentViewController:animated:completion:) 18 | withMethod:@selector(qcoMock_presentViewControllerCapturingAlert:animated:completion:)]; 19 | } 20 | 21 | + (void)qcoMock_swizzleCaptureViewController 22 | { 23 | [self qcoMockAlerts_replaceInstanceMethod:@selector(presentViewController:animated:completion:) 24 | withMethod:@selector(qcoMock_presentViewControllerCapturingIt:animated:completion:)]; 25 | } 26 | 27 | - (void)qcoMock_presentViewControllerCapturingAlert:(UIViewController *)viewControllerToPresent 28 | animated:(BOOL)flag 29 | completion:(void (^ __nullable)(void))completion 30 | { 31 | if (![viewControllerToPresent isKindOfClass:[UIAlertController class]]) 32 | return; 33 | 34 | [viewControllerToPresent loadViewIfNeeded]; 35 | NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 36 | [nc postNotificationName:QCOMockAlertControllerPresentedNotification 37 | object:viewControllerToPresent 38 | userInfo:@{ 39 | QCOMockViewControllerPresentingViewControllerKey : self, 40 | QCOMockViewControllerAnimatedKey : @(flag), 41 | }]; 42 | if (completion) 43 | completion(); 44 | } 45 | 46 | - (void)qcoMock_presentViewControllerCapturingIt:(UIViewController *)viewControllerToPresent 47 | animated:(BOOL)flag 48 | completion:(void (^ __nullable)(void))completion 49 | { 50 | [viewControllerToPresent loadViewIfNeeded]; 51 | NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 52 | [nc postNotificationName:QCOMockViewControllerPresentedNotification 53 | object:viewControllerToPresent 54 | userInfo:@{ 55 | QCOMockViewControllerPresentingViewControllerKey : self, 56 | QCOMockViewControllerAnimatedKey : @(flag), 57 | }]; 58 | if (completion) 59 | completion(); 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Source/XcodeWarnings.xcconfig: -------------------------------------------------------------------------------- 1 | // XcodeWarnings by Jon Reid, https://qualitycoding.org/ 2 | // Copyright 2019 Jonathan M. Reid. See LICENSE.txt 3 | // Source: https://github.com/jonreid/XcodeWarnings 4 | 5 | // Apple Clang - Address Sanitizer 6 | CLANG_ADDRESS_SANITIZER_CONTAINER_OVERFLOW = YES 7 | 8 | // Apple Clang - Code Generation 9 | GCC_STRICT_ALIASING = YES 10 | GCC_REUSE_STRINGS = YES 11 | GCC_NO_COMMON_BLOCKS = YES 12 | 13 | // Apple Clang - Language 14 | GCC_ENABLE_TRIGRAPHS = NO 15 | 16 | // Apple Clang - Preprocessing 17 | ENABLE_STRICT_OBJC_MSGSEND = YES 18 | 19 | // Apple Clang - Undefined Behavior Sanitizer 20 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_INTEGER = YES 21 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 22 | 23 | // Apple Clang - Warning Policies 24 | //GCC_WARN_PEDANTIC = YES 25 | //GCC_TREAT_WARNINGS_AS_ERRORS = YES 26 | 27 | // Apple Clang - Warnings - All languages 28 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES 29 | GCC_WARN_CHECK_SWITCH_STATEMENTS = YES 30 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES 31 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES 32 | CLANG_WARN_EMPTY_BODY = YES 33 | GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES 34 | GCC_WARN_SHADOW = YES 35 | CLANG_WARN_BOOL_CONVERSION = YES 36 | CLANG_WARN_CONSTANT_CONVERSION = YES 37 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES 38 | CLANG_WARN_ENUM_CONVERSION = YES 39 | CLANG_WARN_FLOAT_CONVERSION = YES 40 | CLANG_WARN_INT_CONVERSION = YES 41 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES 42 | CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES 43 | CLANG_WARN_INFINITE_RECURSION = YES 44 | GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES 45 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR 46 | GCC_WARN_MISSING_PARENTHESES = YES 47 | GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES 48 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES 49 | GCC_WARN_ABOUT_MISSING_NEWLINE = YES 50 | CLANG_WARN_ASSIGN_ENUM = YES 51 | CLANG_WARN_PRIVATE_MODULE = YES 52 | GCC_WARN_ABOUT_POINTER_SIGNEDNESS = YES 53 | //MockUIAlertController: CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES 54 | CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES 55 | GCC_WARN_SIGN_COMPARE = YES 56 | CLANG_WARN_STRICT_PROTOTYPES = YES 57 | CLANG_WARN_COMMA = YES 58 | CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES 59 | CLANG_WARN_PRAGMA_PACK = YES 60 | GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES 61 | GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES 62 | GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES 63 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 64 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE 65 | GCC_WARN_UNKNOWN_PRAGMAS = YES 66 | CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE 67 | GCC_WARN_UNUSED_FUNCTION = YES 68 | GCC_WARN_UNUSED_LABEL = YES 69 | //GCC_WARN_UNUSED_PARAMETER = YES 70 | GCC_WARN_UNUSED_VALUE = YES 71 | GCC_WARN_UNUSED_VARIABLE = YES 72 | 73 | // Apple Clang - Warnings - C++ 74 | CLANG_WARN_VEXING_PARSE = YES 75 | CLANG_WARN_DELETE_NON_VIRTUAL_DTOR = YES 76 | CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES 77 | GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES 78 | GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES 79 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES 80 | CLANG_WARN_SUSPICIOUS_MOVE = YES 81 | GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = YES 82 | CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES 83 | CLANG_WARN_CXX0X_EXTENSIONS = YES 84 | 85 | // Apple Clang - Warnings - Objective-C 86 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR 87 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 88 | CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES 89 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES 90 | GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = YES 91 | CLANG_WARN_OBJC_INTERFACE_IVARS = YES 92 | CLANG_WARN_MISSING_NOESCAPE = YES 93 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES 94 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 95 | GCC_WARN_UNDECLARED_SELECTOR = YES 96 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR 97 | 98 | // Apple LLVM 9.0 - Warnings - Objective-C and ARC 99 | CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES 100 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 101 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES_AGGRESSIVE 102 | CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES 103 | 104 | // Static Analyzer - Analysis Policy 105 | RUN_CLANG_STATIC_ANALYZER = YES 106 | CLANG_STATIC_ANALYZER_MODE_ON_ANALYZE_ACTION = Deep 107 | CLANG_STATIC_ANALYZER_MODE = Deep 108 | 109 | // Static Analyzer - Generic Issues 110 | CLANG_ANALYZER_DEADCODE_DEADSTORES = YES 111 | CLANG_ANALYZER_MEMORY_MANAGEMENT = YES 112 | CLANG_ANALYZER_NONNULL = YES 113 | CLANG_ANALYZER_USE_AFTER_MOVE = YES_AGGRESSIVE 114 | 115 | // Static Analyzer - Issues - Apple APIs 116 | CLANG_ANALYZER_OBJC_NSCFERROR = YES 117 | //MockUIAlertController: CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES 118 | CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = YES 119 | CLANG_ANALYZER_OBJC_COLLECTIONS = YES 120 | CLANG_ANALYZER_GCD = YES 121 | CLANG_ANALYZER_GCD_PERFORMANCE = YES 122 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE 123 | CLANG_ANALYZER_LIBKERN_RETAIN_COUNT = YES 124 | 125 | // Static Analyzer - Issues - Objective-C 126 | CLANG_ANALYZER_OBJC_ATSYNC = YES 127 | CLANG_ANALYZER_OBJC_DEALLOC = YES 128 | CLANG_ANALYZER_OBJC_INCOMP_METHOD_TYPES = YES 129 | CLANG_ANALYZER_OBJC_GENERICS = YES 130 | CLANG_ANALYZER_OBJC_UNUSED_IVARS = YES 131 | CLANG_ANALYZER_OBJC_SELF_INIT = YES 132 | CLANG_ANALYZER_OBJC_RETAIN_COUNT = YES 133 | 134 | // Static Analyzer - Issues - Security 135 | CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES 136 | CLANG_ANALYZER_SECURITY_KEYCHAIN_API = YES 137 | CLANG_ANALYZER_SECURITY_INSECUREAPI_UNCHECKEDRETURN = YES 138 | CLANG_ANALYZER_SECURITY_INSECUREAPI_GETPW_GETS = YES 139 | CLANG_ANALYZER_SECURITY_INSECUREAPI_MKSTEMP = YES 140 | CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES 141 | CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES 142 | CLANG_ANALYZER_SECURITY_INSECUREAPI_VFORK = YES 143 | 144 | // Swift Compiler - Code Generation 145 | SWIFT_ENFORCE_EXCLUSIVE_ACCESS = on 146 | --------------------------------------------------------------------------------