├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Cartfile ├── Cartfile.resolved ├── Carthage-Example ├── Cartfile ├── Cartfile.resolved ├── Carthage-Tests.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Carthage-Tests │ ├── Carthage-Tests.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── Carthage-Tests │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift │ └── Carthage-TestsTests │ ├── ActionsTest.swift │ ├── DelegatesTests.swift │ ├── Helpers │ ├── Helpers.swift │ ├── LeakingViewController.storyboard │ ├── LeakingViewController.swift │ └── Storyboard.swift │ ├── Info.plist │ └── ViewControllersTests.swift ├── Example ├── Podfile ├── Podfile.lock ├── SpecLeaks.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── SpecLeaks-Example.xcscheme ├── SpecLeaks.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── SpecLeaks │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ └── ViewController.swift └── Tests │ ├── ActionsTest.swift │ ├── DelegatesTests.swift │ ├── Helpers │ ├── Helpers.swift │ ├── LeakingViewController.storyboard │ ├── LeakingViewController.swift │ └── Storyboard.swift │ ├── Info.plist │ ├── NotificationsTests.swift │ └── ViewControllersTests.swift ├── LICENSE ├── Package.swift ├── README.md ├── SpecLeaks.podspec ├── SpecLeaks.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── SpecLeaks.xcscheme ├── SpecLeaks ├── Assets │ └── .gitkeep ├── Classes │ ├── .gitkeep │ ├── AnalyzeLeak.swift │ ├── AnalyzeLeakAction.swift │ ├── Expectation+Leaks.swift │ ├── LeakTest.swift │ ├── LeaksAnalyzer.swift │ └── Matchers.swift ├── Info.plist └── SpecLeaks.h ├── SpecLeaksTests ├── Info.plist └── SpecLeaksTests.swift ├── _Pods.xcodeproj └── twitter.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | .build/ 41 | 42 | # CocoaPods 43 | # 44 | # We recommend against adding the Pods directory to your .gitignore. However 45 | # you should judge for yourself, the pros and cons are mentioned at: 46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 47 | # 48 | Pods/ 49 | 50 | # Carthage 51 | # 52 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 53 | # Carthage/Checkouts 54 | 55 | Carthage/Build 56 | 57 | # fastlane 58 | # 59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 60 | # screenshots whenever they are needed. 61 | # For more information about the recommended setup visit: 62 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 63 | 64 | fastlane/report.xml 65 | fastlane/Preview.html 66 | fastlane/screenshots 67 | fastlane/test_output 68 | 69 | Carthage/Build/ 70 | Carthage/Checkouts/ 71 | Carthage-Example/Carthage -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | xcode_project: Example/SpecLeaks.xcodeproj 2 | xcode_scheme: SpecLeaks-Example 3 | xcode_destination: platform=iOS Simulator,OS=12.0,name=iPhone X 4 | 5 | osx_image: xcode10.2 6 | language: objective-c 7 | # cache: cocoapods 8 | podfile: Example/Podfile 9 | before_install: 10 | - gem install cocoapods # Since Travis is not always on latest version 11 | - pod install --repo-update --project-directory=Example 12 | script: 13 | - xcodebuild -showsdks 14 | - xcodebuild test -workspace Example/SpecLeaks.xcworkspace -list 15 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/SpecLeaks.xcworkspace -scheme SpecLeaks-Example -sdk iphonesimulator12.2 -destination 'platform=iOS Simulator,name=iPhone X,OS=12.2' ONLY_ACTIVE_ARCH=NO | xcpretty 16 | - pod lib lint 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## Version 0.1.9: 3 | 4 | ### Release info 5 | - Language version: *Swift 5.0* 6 | - iOS Deployment Target: *10.0* 7 | - Travis CI running XCode Version: *10.2* 8 | 9 | ### Changes 10 | - Upgraded Cartfile quick version to v3.0.0 11 | - Upgraded Cartfile nimble version to v9.0.0-rc.3 12 | - Upgraded Podfile quick version to 3.0.0 13 | - Upgraded Podfile nimble version to 9.0.0-rc.3 14 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "Quick/Quick" "v3.0.0" 2 | github "Quick/Nimble" "v9.0.0-rc.3" 3 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "Quick/Nimble" "v9.0.0-rc.3" 2 | github "Quick/Quick" "v3.0.0" 3 | -------------------------------------------------------------------------------- /Carthage-Example/Cartfile: -------------------------------------------------------------------------------- 1 | github "leandromperez/specleaks" 2 | 3 | -------------------------------------------------------------------------------- /Carthage-Example/Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "Quick/Nimble" "v9.0.0-rc.3" 2 | github "Quick/Quick" "v3.0.0" 3 | github "leandromperez/specleaks" "0.1.9" 4 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9C6B84772292A0CE00F11C5D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6B84762292A0CE00F11C5D /* AppDelegate.swift */; }; 11 | 9C6B84792292A0CE00F11C5D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6B84782292A0CE00F11C5D /* ViewController.swift */; }; 12 | 9C6B847C2292A0CE00F11C5D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C6B847A2292A0CE00F11C5D /* Main.storyboard */; }; 13 | 9C6B847E2292A0CF00F11C5D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9C6B847D2292A0CF00F11C5D /* Assets.xcassets */; }; 14 | 9C6B84812292A0CF00F11C5D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C6B847F2292A0CF00F11C5D /* LaunchScreen.storyboard */; }; 15 | 9C6B84B82292A57000F11C5D /* ActionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6B84AF2292A57000F11C5D /* ActionsTest.swift */; }; 16 | 9C6B84B92292A57000F11C5D /* DelegatesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6B84B02292A57000F11C5D /* DelegatesTests.swift */; }; 17 | 9C6B84BA2292A57000F11C5D /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6B84B22292A57000F11C5D /* Helpers.swift */; }; 18 | 9C6B84BB2292A57000F11C5D /* LeakingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6B84B32292A57000F11C5D /* LeakingViewController.swift */; }; 19 | 9C6B84BC2292A57000F11C5D /* Storyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6B84B42292A57000F11C5D /* Storyboard.swift */; }; 20 | 9C6B84BD2292A57000F11C5D /* LeakingViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C6B84B52292A57000F11C5D /* LeakingViewController.storyboard */; }; 21 | 9C6B84BF2292A57000F11C5D /* ViewControllersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C6B84B72292A57000F11C5D /* ViewControllersTests.swift */; }; 22 | 9C6B84D72292A8B600F11C5D /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C6B84D42292A8B600F11C5D /* Nimble.framework */; }; 23 | 9C6B84D82292A8B600F11C5D /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C6B84D52292A8B600F11C5D /* Quick.framework */; }; 24 | 9C6B84D92292A8B600F11C5D /* SpecLeaks.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C6B84D62292A8B600F11C5D /* SpecLeaks.framework */; }; 25 | 9C6B84DA2292A8C000F11C5D /* Nimble.framework in Carthage */ = {isa = PBXBuildFile; fileRef = 9C6B84D42292A8B600F11C5D /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 26 | 9C6B84DB2292A8C000F11C5D /* Quick.framework in Carthage */ = {isa = PBXBuildFile; fileRef = 9C6B84D52292A8B600F11C5D /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 27 | 9C6B84DC2292A8C000F11C5D /* SpecLeaks.framework in Carthage */ = {isa = PBXBuildFile; fileRef = 9C6B84D62292A8B600F11C5D /* SpecLeaks.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXContainerItemProxy section */ 31 | 9C6B84882292A0CF00F11C5D /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = 9C6B846B2292A0CE00F11C5D /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = 9C6B84722292A0CE00F11C5D; 36 | remoteInfo = "Carthage-Tests"; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXCopyFilesBuildPhase section */ 41 | 9C6B84AA2292A39800F11C5D /* Embed Frameworks */ = { 42 | isa = PBXCopyFilesBuildPhase; 43 | buildActionMask = 2147483647; 44 | dstPath = ""; 45 | dstSubfolderSpec = 10; 46 | files = ( 47 | ); 48 | name = "Embed Frameworks"; 49 | runOnlyForDeploymentPostprocessing = 0; 50 | }; 51 | 9C6B84CD2292A82800F11C5D /* Carthage */ = { 52 | isa = PBXCopyFilesBuildPhase; 53 | buildActionMask = 2147483647; 54 | dstPath = ""; 55 | dstSubfolderSpec = 10; 56 | files = ( 57 | 9C6B84DA2292A8C000F11C5D /* Nimble.framework in Carthage */, 58 | 9C6B84DB2292A8C000F11C5D /* Quick.framework in Carthage */, 59 | 9C6B84DC2292A8C000F11C5D /* SpecLeaks.framework in Carthage */, 60 | ); 61 | name = Carthage; 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXCopyFilesBuildPhase section */ 65 | 66 | /* Begin PBXFileReference section */ 67 | 9C6B84732292A0CE00F11C5D /* Carthage-Tests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Carthage-Tests.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | 9C6B84762292A0CE00F11C5D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 69 | 9C6B84782292A0CE00F11C5D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 70 | 9C6B847B2292A0CE00F11C5D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 71 | 9C6B847D2292A0CF00F11C5D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 72 | 9C6B84802292A0CF00F11C5D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 73 | 9C6B84822292A0CF00F11C5D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 74 | 9C6B84872292A0CF00F11C5D /* Carthage-TestsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Carthage-TestsTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | 9C6B848D2292A0CF00F11C5D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 76 | 9C6B84AF2292A57000F11C5D /* ActionsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionsTest.swift; sourceTree = ""; }; 77 | 9C6B84B02292A57000F11C5D /* DelegatesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DelegatesTests.swift; sourceTree = ""; }; 78 | 9C6B84B22292A57000F11C5D /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; 79 | 9C6B84B32292A57000F11C5D /* LeakingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeakingViewController.swift; sourceTree = ""; }; 80 | 9C6B84B42292A57000F11C5D /* Storyboard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Storyboard.swift; sourceTree = ""; }; 81 | 9C6B84B52292A57000F11C5D /* LeakingViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LeakingViewController.storyboard; sourceTree = ""; }; 82 | 9C6B84B72292A57000F11C5D /* ViewControllersTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllersTests.swift; sourceTree = ""; }; 83 | 9C6B84D42292A8B600F11C5D /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = ../Carthage/Build/iOS/Nimble.framework; sourceTree = ""; }; 84 | 9C6B84D52292A8B600F11C5D /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = ../Carthage/Build/iOS/Quick.framework; sourceTree = ""; }; 85 | 9C6B84D62292A8B600F11C5D /* SpecLeaks.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SpecLeaks.framework; path = ../Carthage/Build/iOS/SpecLeaks.framework; sourceTree = ""; }; 86 | /* End PBXFileReference section */ 87 | 88 | /* Begin PBXFrameworksBuildPhase section */ 89 | 9C6B84702292A0CE00F11C5D /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | ); 94 | runOnlyForDeploymentPostprocessing = 0; 95 | }; 96 | 9C6B84842292A0CF00F11C5D /* Frameworks */ = { 97 | isa = PBXFrameworksBuildPhase; 98 | buildActionMask = 2147483647; 99 | files = ( 100 | 9C6B84D72292A8B600F11C5D /* Nimble.framework in Frameworks */, 101 | 9C6B84D82292A8B600F11C5D /* Quick.framework in Frameworks */, 102 | 9C6B84D92292A8B600F11C5D /* SpecLeaks.framework in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | /* End PBXFrameworksBuildPhase section */ 107 | 108 | /* Begin PBXGroup section */ 109 | 9C6B846A2292A0CE00F11C5D = { 110 | isa = PBXGroup; 111 | children = ( 112 | 9C6B84752292A0CE00F11C5D /* Carthage-Tests */, 113 | 9C6B848A2292A0CF00F11C5D /* Carthage-TestsTests */, 114 | 9C6B84742292A0CE00F11C5D /* Products */, 115 | 9C6B84962292A2C500F11C5D /* Frameworks */, 116 | ); 117 | sourceTree = ""; 118 | }; 119 | 9C6B84742292A0CE00F11C5D /* Products */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 9C6B84732292A0CE00F11C5D /* Carthage-Tests.app */, 123 | 9C6B84872292A0CF00F11C5D /* Carthage-TestsTests.xctest */, 124 | ); 125 | name = Products; 126 | sourceTree = ""; 127 | }; 128 | 9C6B84752292A0CE00F11C5D /* Carthage-Tests */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 9C6B84762292A0CE00F11C5D /* AppDelegate.swift */, 132 | 9C6B84782292A0CE00F11C5D /* ViewController.swift */, 133 | 9C6B847A2292A0CE00F11C5D /* Main.storyboard */, 134 | 9C6B847D2292A0CF00F11C5D /* Assets.xcassets */, 135 | 9C6B847F2292A0CF00F11C5D /* LaunchScreen.storyboard */, 136 | 9C6B84822292A0CF00F11C5D /* Info.plist */, 137 | ); 138 | path = "Carthage-Tests"; 139 | sourceTree = ""; 140 | }; 141 | 9C6B848A2292A0CF00F11C5D /* Carthage-TestsTests */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 9C6B84AF2292A57000F11C5D /* ActionsTest.swift */, 145 | 9C6B84B02292A57000F11C5D /* DelegatesTests.swift */, 146 | 9C6B84B12292A57000F11C5D /* Helpers */, 147 | 9C6B84B72292A57000F11C5D /* ViewControllersTests.swift */, 148 | 9C6B848D2292A0CF00F11C5D /* Info.plist */, 149 | ); 150 | path = "Carthage-TestsTests"; 151 | sourceTree = ""; 152 | }; 153 | 9C6B84962292A2C500F11C5D /* Frameworks */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 9C6B84D42292A8B600F11C5D /* Nimble.framework */, 157 | 9C6B84D52292A8B600F11C5D /* Quick.framework */, 158 | 9C6B84D62292A8B600F11C5D /* SpecLeaks.framework */, 159 | ); 160 | name = Frameworks; 161 | sourceTree = ""; 162 | }; 163 | 9C6B84B12292A57000F11C5D /* Helpers */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 9C6B84B22292A57000F11C5D /* Helpers.swift */, 167 | 9C6B84B32292A57000F11C5D /* LeakingViewController.swift */, 168 | 9C6B84B42292A57000F11C5D /* Storyboard.swift */, 169 | 9C6B84B52292A57000F11C5D /* LeakingViewController.storyboard */, 170 | ); 171 | path = Helpers; 172 | sourceTree = ""; 173 | }; 174 | /* End PBXGroup section */ 175 | 176 | /* Begin PBXNativeTarget section */ 177 | 9C6B84722292A0CE00F11C5D /* Carthage-Tests */ = { 178 | isa = PBXNativeTarget; 179 | buildConfigurationList = 9C6B84902292A0CF00F11C5D /* Build configuration list for PBXNativeTarget "Carthage-Tests" */; 180 | buildPhases = ( 181 | 9C6B846F2292A0CE00F11C5D /* Sources */, 182 | 9C6B84702292A0CE00F11C5D /* Frameworks */, 183 | 9C6B84712292A0CE00F11C5D /* Resources */, 184 | 9C6B84AA2292A39800F11C5D /* Embed Frameworks */, 185 | ); 186 | buildRules = ( 187 | ); 188 | dependencies = ( 189 | ); 190 | name = "Carthage-Tests"; 191 | productName = "Carthage-Tests"; 192 | productReference = 9C6B84732292A0CE00F11C5D /* Carthage-Tests.app */; 193 | productType = "com.apple.product-type.application"; 194 | }; 195 | 9C6B84862292A0CF00F11C5D /* Carthage-TestsTests */ = { 196 | isa = PBXNativeTarget; 197 | buildConfigurationList = 9C6B84932292A0CF00F11C5D /* Build configuration list for PBXNativeTarget "Carthage-TestsTests" */; 198 | buildPhases = ( 199 | 9C6B84CD2292A82800F11C5D /* Carthage */, 200 | 9C6B84832292A0CF00F11C5D /* Sources */, 201 | 9C6B84842292A0CF00F11C5D /* Frameworks */, 202 | 9C6B84852292A0CF00F11C5D /* Resources */, 203 | ); 204 | buildRules = ( 205 | ); 206 | dependencies = ( 207 | 9C6B84892292A0CF00F11C5D /* PBXTargetDependency */, 208 | ); 209 | name = "Carthage-TestsTests"; 210 | productName = "Carthage-TestsTests"; 211 | productReference = 9C6B84872292A0CF00F11C5D /* Carthage-TestsTests.xctest */; 212 | productType = "com.apple.product-type.bundle.unit-test"; 213 | }; 214 | /* End PBXNativeTarget section */ 215 | 216 | /* Begin PBXProject section */ 217 | 9C6B846B2292A0CE00F11C5D /* Project object */ = { 218 | isa = PBXProject; 219 | attributes = { 220 | LastSwiftUpdateCheck = 1020; 221 | LastUpgradeCheck = 1020; 222 | ORGANIZATIONNAME = "Leandro Perez"; 223 | TargetAttributes = { 224 | 9C6B84722292A0CE00F11C5D = { 225 | CreatedOnToolsVersion = 10.2.1; 226 | }; 227 | 9C6B84862292A0CF00F11C5D = { 228 | CreatedOnToolsVersion = 10.2.1; 229 | TestTargetID = 9C6B84722292A0CE00F11C5D; 230 | }; 231 | }; 232 | }; 233 | buildConfigurationList = 9C6B846E2292A0CE00F11C5D /* Build configuration list for PBXProject "Carthage-Tests" */; 234 | compatibilityVersion = "Xcode 9.3"; 235 | developmentRegion = en; 236 | hasScannedForEncodings = 0; 237 | knownRegions = ( 238 | en, 239 | Base, 240 | ); 241 | mainGroup = 9C6B846A2292A0CE00F11C5D; 242 | productRefGroup = 9C6B84742292A0CE00F11C5D /* Products */; 243 | projectDirPath = ""; 244 | projectRoot = ""; 245 | targets = ( 246 | 9C6B84722292A0CE00F11C5D /* Carthage-Tests */, 247 | 9C6B84862292A0CF00F11C5D /* Carthage-TestsTests */, 248 | ); 249 | }; 250 | /* End PBXProject section */ 251 | 252 | /* Begin PBXResourcesBuildPhase section */ 253 | 9C6B84712292A0CE00F11C5D /* Resources */ = { 254 | isa = PBXResourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | 9C6B84812292A0CF00F11C5D /* LaunchScreen.storyboard in Resources */, 258 | 9C6B847E2292A0CF00F11C5D /* Assets.xcassets in Resources */, 259 | 9C6B847C2292A0CE00F11C5D /* Main.storyboard in Resources */, 260 | ); 261 | runOnlyForDeploymentPostprocessing = 0; 262 | }; 263 | 9C6B84852292A0CF00F11C5D /* Resources */ = { 264 | isa = PBXResourcesBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | 9C6B84BD2292A57000F11C5D /* LeakingViewController.storyboard in Resources */, 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | /* End PBXResourcesBuildPhase section */ 272 | 273 | /* Begin PBXSourcesBuildPhase section */ 274 | 9C6B846F2292A0CE00F11C5D /* Sources */ = { 275 | isa = PBXSourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 9C6B84792292A0CE00F11C5D /* ViewController.swift in Sources */, 279 | 9C6B84772292A0CE00F11C5D /* AppDelegate.swift in Sources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | 9C6B84832292A0CF00F11C5D /* Sources */ = { 284 | isa = PBXSourcesBuildPhase; 285 | buildActionMask = 2147483647; 286 | files = ( 287 | 9C6B84B82292A57000F11C5D /* ActionsTest.swift in Sources */, 288 | 9C6B84BF2292A57000F11C5D /* ViewControllersTests.swift in Sources */, 289 | 9C6B84BB2292A57000F11C5D /* LeakingViewController.swift in Sources */, 290 | 9C6B84B92292A57000F11C5D /* DelegatesTests.swift in Sources */, 291 | 9C6B84BC2292A57000F11C5D /* Storyboard.swift in Sources */, 292 | 9C6B84BA2292A57000F11C5D /* Helpers.swift in Sources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | /* End PBXSourcesBuildPhase section */ 297 | 298 | /* Begin PBXTargetDependency section */ 299 | 9C6B84892292A0CF00F11C5D /* PBXTargetDependency */ = { 300 | isa = PBXTargetDependency; 301 | target = 9C6B84722292A0CE00F11C5D /* Carthage-Tests */; 302 | targetProxy = 9C6B84882292A0CF00F11C5D /* PBXContainerItemProxy */; 303 | }; 304 | /* End PBXTargetDependency section */ 305 | 306 | /* Begin PBXVariantGroup section */ 307 | 9C6B847A2292A0CE00F11C5D /* Main.storyboard */ = { 308 | isa = PBXVariantGroup; 309 | children = ( 310 | 9C6B847B2292A0CE00F11C5D /* Base */, 311 | ); 312 | name = Main.storyboard; 313 | sourceTree = ""; 314 | }; 315 | 9C6B847F2292A0CF00F11C5D /* LaunchScreen.storyboard */ = { 316 | isa = PBXVariantGroup; 317 | children = ( 318 | 9C6B84802292A0CF00F11C5D /* Base */, 319 | ); 320 | name = LaunchScreen.storyboard; 321 | sourceTree = ""; 322 | }; 323 | /* End PBXVariantGroup section */ 324 | 325 | /* Begin XCBuildConfiguration section */ 326 | 9C6B848E2292A0CF00F11C5D /* Debug */ = { 327 | isa = XCBuildConfiguration; 328 | buildSettings = { 329 | ALWAYS_SEARCH_USER_PATHS = NO; 330 | CLANG_ANALYZER_NONNULL = YES; 331 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 332 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 333 | CLANG_CXX_LIBRARY = "libc++"; 334 | CLANG_ENABLE_MODULES = YES; 335 | CLANG_ENABLE_OBJC_ARC = YES; 336 | CLANG_ENABLE_OBJC_WEAK = YES; 337 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 338 | CLANG_WARN_BOOL_CONVERSION = YES; 339 | CLANG_WARN_COMMA = YES; 340 | CLANG_WARN_CONSTANT_CONVERSION = YES; 341 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 342 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 343 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 344 | CLANG_WARN_EMPTY_BODY = YES; 345 | CLANG_WARN_ENUM_CONVERSION = YES; 346 | CLANG_WARN_INFINITE_RECURSION = YES; 347 | CLANG_WARN_INT_CONVERSION = YES; 348 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 349 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 350 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 351 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 352 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 353 | CLANG_WARN_STRICT_PROTOTYPES = YES; 354 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 355 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 356 | CLANG_WARN_UNREACHABLE_CODE = YES; 357 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 358 | CODE_SIGN_IDENTITY = "iPhone Developer"; 359 | COPY_PHASE_STRIP = NO; 360 | DEBUG_INFORMATION_FORMAT = dwarf; 361 | ENABLE_STRICT_OBJC_MSGSEND = YES; 362 | ENABLE_TESTABILITY = YES; 363 | GCC_C_LANGUAGE_STANDARD = gnu11; 364 | GCC_DYNAMIC_NO_PIC = NO; 365 | GCC_NO_COMMON_BLOCKS = YES; 366 | GCC_OPTIMIZATION_LEVEL = 0; 367 | GCC_PREPROCESSOR_DEFINITIONS = ( 368 | "DEBUG=1", 369 | "$(inherited)", 370 | ); 371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 373 | GCC_WARN_UNDECLARED_SELECTOR = YES; 374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 375 | GCC_WARN_UNUSED_FUNCTION = YES; 376 | GCC_WARN_UNUSED_VARIABLE = YES; 377 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 378 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 379 | MTL_FAST_MATH = YES; 380 | ONLY_ACTIVE_ARCH = YES; 381 | SDKROOT = iphoneos; 382 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 383 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 384 | SWIFT_VERSION = 5.0; 385 | }; 386 | name = Debug; 387 | }; 388 | 9C6B848F2292A0CF00F11C5D /* Release */ = { 389 | isa = XCBuildConfiguration; 390 | buildSettings = { 391 | ALWAYS_SEARCH_USER_PATHS = NO; 392 | CLANG_ANALYZER_NONNULL = YES; 393 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 394 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 395 | CLANG_CXX_LIBRARY = "libc++"; 396 | CLANG_ENABLE_MODULES = YES; 397 | CLANG_ENABLE_OBJC_ARC = YES; 398 | CLANG_ENABLE_OBJC_WEAK = YES; 399 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 400 | CLANG_WARN_BOOL_CONVERSION = YES; 401 | CLANG_WARN_COMMA = YES; 402 | CLANG_WARN_CONSTANT_CONVERSION = YES; 403 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 404 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 405 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 406 | CLANG_WARN_EMPTY_BODY = YES; 407 | CLANG_WARN_ENUM_CONVERSION = YES; 408 | CLANG_WARN_INFINITE_RECURSION = YES; 409 | CLANG_WARN_INT_CONVERSION = YES; 410 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 411 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 412 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 413 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 414 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 415 | CLANG_WARN_STRICT_PROTOTYPES = YES; 416 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 417 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 418 | CLANG_WARN_UNREACHABLE_CODE = YES; 419 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 420 | CODE_SIGN_IDENTITY = "iPhone Developer"; 421 | COPY_PHASE_STRIP = NO; 422 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 423 | ENABLE_NS_ASSERTIONS = NO; 424 | ENABLE_STRICT_OBJC_MSGSEND = YES; 425 | GCC_C_LANGUAGE_STANDARD = gnu11; 426 | GCC_NO_COMMON_BLOCKS = YES; 427 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 428 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 429 | GCC_WARN_UNDECLARED_SELECTOR = YES; 430 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 431 | GCC_WARN_UNUSED_FUNCTION = YES; 432 | GCC_WARN_UNUSED_VARIABLE = YES; 433 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 434 | MTL_ENABLE_DEBUG_INFO = NO; 435 | MTL_FAST_MATH = YES; 436 | SDKROOT = iphoneos; 437 | SWIFT_COMPILATION_MODE = wholemodule; 438 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 439 | SWIFT_VERSION = 5.0; 440 | VALIDATE_PRODUCT = YES; 441 | }; 442 | name = Release; 443 | }; 444 | 9C6B84912292A0CF00F11C5D /* Debug */ = { 445 | isa = XCBuildConfiguration; 446 | buildSettings = { 447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 448 | CODE_SIGN_STYLE = Automatic; 449 | DEVELOPMENT_TEAM = B3CLFTM242; 450 | INFOPLIST_FILE = "Carthage-Tests/Info.plist"; 451 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 452 | LD_RUNPATH_SEARCH_PATHS = ( 453 | "$(inherited)", 454 | "@executable_path/Frameworks", 455 | ); 456 | PRODUCT_BUNDLE_IDENTIFIER = "com.carthage.specleaks.Carthage-Tests"; 457 | PRODUCT_NAME = "$(TARGET_NAME)"; 458 | SWIFT_VERSION = 5.0; 459 | TARGETED_DEVICE_FAMILY = "1,2"; 460 | }; 461 | name = Debug; 462 | }; 463 | 9C6B84922292A0CF00F11C5D /* Release */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 467 | CODE_SIGN_STYLE = Automatic; 468 | DEVELOPMENT_TEAM = B3CLFTM242; 469 | INFOPLIST_FILE = "Carthage-Tests/Info.plist"; 470 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 471 | LD_RUNPATH_SEARCH_PATHS = ( 472 | "$(inherited)", 473 | "@executable_path/Frameworks", 474 | ); 475 | PRODUCT_BUNDLE_IDENTIFIER = "com.carthage.specleaks.Carthage-Tests"; 476 | PRODUCT_NAME = "$(TARGET_NAME)"; 477 | SWIFT_VERSION = 5.0; 478 | TARGETED_DEVICE_FAMILY = "1,2"; 479 | }; 480 | name = Release; 481 | }; 482 | 9C6B84942292A0CF00F11C5D /* Debug */ = { 483 | isa = XCBuildConfiguration; 484 | buildSettings = { 485 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 486 | BUNDLE_LOADER = "$(TEST_HOST)"; 487 | CODE_SIGN_STYLE = Automatic; 488 | DEVELOPMENT_TEAM = B3CLFTM242; 489 | FRAMEWORK_SEARCH_PATHS = ( 490 | "$(SRCROOT)/**", 491 | "$(SRCROOT)/../**", 492 | ); 493 | INFOPLIST_FILE = "Carthage-TestsTests/Info.plist"; 494 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 495 | LD_RUNPATH_SEARCH_PATHS = ( 496 | "$(inherited)", 497 | "@executable_path/Frameworks", 498 | "@loader_path/Frameworks", 499 | ); 500 | PRODUCT_BUNDLE_IDENTIFIER = "com.carthage.specleaks.Carthage-TestsTests"; 501 | PRODUCT_NAME = "$(TARGET_NAME)"; 502 | SWIFT_VERSION = 5.0; 503 | TARGETED_DEVICE_FAMILY = "1,2"; 504 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Carthage-Tests.app/Carthage-Tests"; 505 | }; 506 | name = Debug; 507 | }; 508 | 9C6B84952292A0CF00F11C5D /* Release */ = { 509 | isa = XCBuildConfiguration; 510 | buildSettings = { 511 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 512 | BUNDLE_LOADER = "$(TEST_HOST)"; 513 | CODE_SIGN_STYLE = Automatic; 514 | DEVELOPMENT_TEAM = B3CLFTM242; 515 | FRAMEWORK_SEARCH_PATHS = ( 516 | "$(SRCROOT)/**", 517 | "$(SRCROOT)/../**", 518 | ); 519 | INFOPLIST_FILE = "Carthage-TestsTests/Info.plist"; 520 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 521 | LD_RUNPATH_SEARCH_PATHS = ( 522 | "$(inherited)", 523 | "@executable_path/Frameworks", 524 | "@loader_path/Frameworks", 525 | ); 526 | PRODUCT_BUNDLE_IDENTIFIER = "com.carthage.specleaks.Carthage-TestsTests"; 527 | PRODUCT_NAME = "$(TARGET_NAME)"; 528 | SWIFT_VERSION = 5.0; 529 | TARGETED_DEVICE_FAMILY = "1,2"; 530 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Carthage-Tests.app/Carthage-Tests"; 531 | }; 532 | name = Release; 533 | }; 534 | /* End XCBuildConfiguration section */ 535 | 536 | /* Begin XCConfigurationList section */ 537 | 9C6B846E2292A0CE00F11C5D /* Build configuration list for PBXProject "Carthage-Tests" */ = { 538 | isa = XCConfigurationList; 539 | buildConfigurations = ( 540 | 9C6B848E2292A0CF00F11C5D /* Debug */, 541 | 9C6B848F2292A0CF00F11C5D /* Release */, 542 | ); 543 | defaultConfigurationIsVisible = 0; 544 | defaultConfigurationName = Release; 545 | }; 546 | 9C6B84902292A0CF00F11C5D /* Build configuration list for PBXNativeTarget "Carthage-Tests" */ = { 547 | isa = XCConfigurationList; 548 | buildConfigurations = ( 549 | 9C6B84912292A0CF00F11C5D /* Debug */, 550 | 9C6B84922292A0CF00F11C5D /* Release */, 551 | ); 552 | defaultConfigurationIsVisible = 0; 553 | defaultConfigurationName = Release; 554 | }; 555 | 9C6B84932292A0CF00F11C5D /* Build configuration list for PBXNativeTarget "Carthage-TestsTests" */ = { 556 | isa = XCConfigurationList; 557 | buildConfigurations = ( 558 | 9C6B84942292A0CF00F11C5D /* Debug */, 559 | 9C6B84952292A0CF00F11C5D /* Release */, 560 | ); 561 | defaultConfigurationIsVisible = 0; 562 | defaultConfigurationName = Release; 563 | }; 564 | /* End XCConfigurationList section */ 565 | }; 566 | rootObject = 9C6B846B2292A0CE00F11C5D /* Project object */; 567 | } 568 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Carthage-Tests 4 | // 5 | // Created by Leandro Perez on 5/20/19. 6 | // Copyright © 2019 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests/Assets.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 | } -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests/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 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests/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 | 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 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-Tests/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Carthage-Tests 4 | // 5 | // Created by Leandro Perez on 5/20/19. 6 | // Copyright © 2019 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view. 16 | } 17 | 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-TestsTests/ActionsTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Actions.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 03/02/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Quick 10 | import Nimble 11 | import SpecLeaks 12 | 13 | class LeakWhenActionCalled { 14 | 15 | var something : AnyObject? = nil 16 | 17 | func dontLeak(){ 18 | print("don't leak") 19 | } 20 | 21 | func leak(){ 22 | self.something = self 23 | } 24 | 25 | func returnLeakingBlock() -> Action{ 26 | return { 27 | self.dontLeak() 28 | print ("I leak because i'm not using weak " ) 29 | } 30 | } 31 | 32 | func returnNotLeakingBlock() -> Action{ 33 | return {[weak self] in 34 | self?.dontLeak() 35 | print ("I don't leak because i'm using weak " ) 36 | } 37 | } 38 | } 39 | 40 | class LeakWhenActionCalledSpec: QuickSpec { 41 | 42 | override func spec() { 43 | 44 | describe("an ObjectThatLeaksWhenActionCalled") { 45 | 46 | let test = LeakTest{ 47 | return LeakWhenActionCalled() 48 | } 49 | 50 | describe("init") { 51 | it("must not leak"){ 52 | expect(test).toNot(leak()) 53 | } 54 | } 55 | 56 | describe("leak with no action"){ 57 | it("must not leak"){ 58 | let leakingAction : Handler = {_ in } 59 | expect(test).toNot(leakWhen(leakingAction)) 60 | } 61 | } 62 | 63 | 64 | describe("leak"){ 65 | it("must leak"){ 66 | let leakingAction : Handler = {leaker in leaker.leak()} 67 | expect(test).to(leakWhen(leakingAction)) 68 | } 69 | } 70 | 71 | describe("dontLeak"){ 72 | it("must not leak"){ 73 | let notLeakingAction : Handler = {leaker in leaker.dontLeak()} 74 | expect(test).toNot(leakWhen(notLeakingAction)) 75 | } 76 | } 77 | 78 | describe("returnLeakingBlock"){ 79 | it("must leak"){ 80 | let leak : (LeakWhenActionCalled)-> Any = {leaker in return leaker.returnLeakingBlock()} 81 | 82 | expect(test).to(leakWhen(leak)) 83 | } 84 | } 85 | 86 | describe("returnNotLeakingBlock"){ 87 | it("must not leak"){ 88 | let leak : (LeakWhenActionCalled)-> Any = {leaker in return leaker.returnNotLeakingBlock()} 89 | 90 | expect(test).toNot(leakWhen(leak)) 91 | } 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-TestsTests/DelegatesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DelegatesTests.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 03/02/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Quick 10 | import Nimble 11 | import SpecLeaks 12 | 13 | //MARK: - Leaking 14 | protocol ServerDelegate : AnyObject{} 15 | 16 | class LeakingServer{ 17 | var delegate : ServerDelegate? = nil 18 | } 19 | 20 | class LeakingClient : ServerDelegate{ 21 | var server : LeakingServer 22 | 23 | init(server: LeakingServer) { 24 | self.server = server 25 | server.delegate = self 26 | } 27 | } 28 | 29 | //MARK: - Not Leaking 30 | class NotLeakingServer{ 31 | weak var delegate : ServerDelegate? = nil 32 | } 33 | 34 | class NotLeakingClient : ServerDelegate{ 35 | var server : NotLeakingServer 36 | 37 | init(server: NotLeakingServer) { 38 | self.server = server 39 | server.delegate = self 40 | } 41 | } 42 | 43 | class SomeObject{ 44 | func doSomething(){ 45 | 46 | } 47 | } 48 | 49 | class SomeOjectTests: QuickSpec { 50 | override func spec() { 51 | describe("a SomeObject") { 52 | describe("init") { 53 | it("must not leak"){ 54 | 55 | let someObject = LeakTest{ 56 | return SomeObject() 57 | } 58 | 59 | let doSomethingIsCalled : (SomeObject) -> () = {obj in obj.doSomething()} 60 | 61 | expect(someObject).toNot(leakWhen(doSomethingIsCalled)) 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | 69 | 70 | class DelegatesTests: QuickSpec { 71 | 72 | override func spec() { 73 | describe("a NotLeakingClient") { 74 | 75 | it("must not leak"){ 76 | 77 | let test = LeakTest{ 78 | return NotLeakingClient(server: NotLeakingServer()) 79 | } 80 | 81 | expect(test).toNot(leak()) 82 | } 83 | } 84 | 85 | describe("a LeakingClient") { 86 | 87 | it("must leak"){ 88 | 89 | let test = LeakTest{ 90 | return LeakingClient(server: LeakingServer()) 91 | } 92 | 93 | expect(test).to(leak()) 94 | } 95 | } 96 | } 97 | } 98 | 99 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-TestsTests/Helpers/Helpers.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Helpers.swift 3 | // SpecLeaks_Example 4 | // 5 | // Created by Leandro Perez on 01/04/2018. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | typealias ErrorHandler = (Error)->() 12 | typealias Action = () -> () 13 | typealias Handler = (T) -> () 14 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-TestsTests/Helpers/LeakingViewController.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-TestsTests/Helpers/LeakingViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeakingViewController.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 10/01/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class LeakingViewController: UIViewController { 12 | 13 | private var anyObject : AnyObject? = nil 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | } 18 | 19 | func cleanLeakedObjects(){ 20 | 21 | self.anyObject = nil 22 | } 23 | 24 | func createLeak(){ 25 | self.anyObject = self 26 | } 27 | 28 | func doSomething(){ 29 | print("doing something") 30 | } 31 | 32 | func createLeakInBlock() -> () -> (){ 33 | return { 34 | self.doSomething() 35 | } 36 | } 37 | 38 | func dontCreateLeakInBlock() -> () -> (){ 39 | return { [weak self] in 40 | self?.doSomething() 41 | } 42 | } 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-TestsTests/Helpers/Storyboard.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Storyboard.swift 3 | // Go24 4 | // 5 | // Created by Leandro Perez on 9/22/17. 6 | // Copyright © 2017 Your Trainer Inc. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | protocol Storyboard { 13 | func initialViewController ()-> T 14 | var name : String {get} 15 | var bundle : Bundle {get} 16 | } 17 | 18 | extension Storyboard { 19 | var storyboard : UIStoryboard{ 20 | return UIStoryboard.init(name: self.name, bundle: self.bundle) 21 | } 22 | 23 | func initialViewController ()-> T { 24 | let vc : T = self.storyboard.instantiateInitialViewController() as! T 25 | 26 | return vc 27 | } 28 | } 29 | 30 | 31 | enum Storyboards : String, Storyboard{ 32 | 33 | case LeakingViewController 34 | 35 | var name : String { 36 | return self.rawValue 37 | } 38 | 39 | var bundle : Bundle{ 40 | return Bundle.main 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-TestsTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Carthage-Example/Carthage-Tests/Carthage-TestsTests/ViewControllersTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeakingViewControllerSpec.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 10/01/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Quick 10 | import Nimble 11 | import SpecLeaks 12 | 13 | class ViewControllersTests: QuickSpec { 14 | 15 | override func spec() { 16 | describe("UIViewController"){ 17 | let test = LeakTest{ 18 | return UIViewController() 19 | } 20 | 21 | describe("init") { 22 | it("must not leak"){ 23 | expect(test).toNot(leak()) 24 | } 25 | } 26 | } 27 | 28 | describe("LeakingViewController") { 29 | let test = LeakTest{ 30 | let storyboard = UIStoryboard.init(name: "LeakingViewController", bundle: Bundle(for: LeakingViewController.self)) 31 | return storyboard.instantiateInitialViewController() as! LeakingViewController 32 | } 33 | 34 | describe("init") { 35 | it("must not leak"){ 36 | expect(test).toNot(leak()) 37 | } 38 | } 39 | 40 | describe("doSomething") { 41 | it("must not leak"){ 42 | let action : (LeakingViewController) -> () = { vc in 43 | 44 | vc.cleanLeakedObjects() 45 | vc.doSomething() 46 | } 47 | 48 | expect(test).toNot(leakWhen(action)) 49 | } 50 | } 51 | 52 | describe("createLeak") { 53 | it("must leak"){ 54 | let action : (LeakingViewController) -> () = { vc in 55 | 56 | vc.cleanLeakedObjects() 57 | vc.createLeak() 58 | } 59 | 60 | expect(test).to(leakWhen(action)) 61 | } 62 | } 63 | 64 | describe("createLeakInBlock") { 65 | it("must leak"){ 66 | let action : (LeakingViewController) -> Any = { vc in 67 | 68 | vc.cleanLeakedObjects() 69 | return vc.createLeakInBlock() 70 | } 71 | 72 | expect(test).to(leakWhen(action)) 73 | } 74 | 75 | it("must leak"){ 76 | let action : (LeakingViewController) -> Any = { vc in 77 | 78 | vc.cleanLeakedObjects() 79 | return vc.createLeakInBlock() 80 | } 81 | 82 | expect(test).to(leakWhen(action)) 83 | } 84 | } 85 | describe("dontCreateLeakInBlock") { 86 | it("must not leak"){ 87 | let action : (LeakingViewController) -> Any = { vc in 88 | 89 | vc.cleanLeakedObjects() 90 | return vc.dontCreateLeakInBlock() 91 | } 92 | 93 | expect(test).toNot(leakWhen(action)) 94 | } 95 | } 96 | } 97 | } 98 | } 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | platform :ios, '10.0' 3 | 4 | target 'SpecLeaks_Example' do 5 | pod 'SpecLeaks', :path => '../' 6 | 7 | 8 | target 'SpecLeaks_Tests' do 9 | inherit! :search_paths 10 | pod 'SpecLeaks', :path => '../' 11 | pod 'RxSwift' 12 | pod 'Quick' 13 | pod 'Nimble' 14 | pod 'RxCocoa' 15 | end 16 | 17 | post_install do |installer| 18 | installer.pods_project.targets.each do |target| 19 | target.build_configurations.each do |config| 20 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '10.0' 21 | config.build_settings['SWIFT_VERSION'] = '5.0' 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Nimble (9.0.0-rc.3) 3 | - Quick (3.0.0) 4 | - RxCocoa (5.1.1): 5 | - RxRelay (~> 5) 6 | - RxSwift (~> 5) 7 | - RxRelay (5.1.1): 8 | - RxSwift (~> 5) 9 | - RxSwift (5.1.1) 10 | - SpecLeaks (0.1.9): 11 | - Nimble (= 9.0.0-rc.3) 12 | - Quick (= 3.0.0) 13 | 14 | DEPENDENCIES: 15 | - Nimble 16 | - Quick 17 | - RxCocoa 18 | - RxSwift 19 | - SpecLeaks (from `../`) 20 | 21 | SPEC REPOS: 22 | trunk: 23 | - Nimble 24 | - Quick 25 | - RxCocoa 26 | - RxRelay 27 | - RxSwift 28 | 29 | EXTERNAL SOURCES: 30 | SpecLeaks: 31 | :path: "../" 32 | 33 | SPEC CHECKSUMS: 34 | Nimble: 1b5fa99320d0d87ed72bb0add38dc696aa77f556 35 | Quick: 6d9559f40647bc4d510103842ef2fdd882d753e2 36 | RxCocoa: 32065309a38d29b5b0db858819b5bf9ef038b601 37 | RxRelay: d77f7d771495f43c556cbc43eebd1bb54d01e8e9 38 | RxSwift: 81470a2074fa8780320ea5fe4102807cb7118178 39 | SpecLeaks: ee49a73e657213d634023e27aa2f59ad63a3d7a6 40 | 41 | PODFILE CHECKSUM: e77a8a079dafceb226f5551c2a283c8f35b87f6a 42 | 43 | COCOAPODS: 1.9.3 44 | -------------------------------------------------------------------------------- /Example/SpecLeaks.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 35911BB6F34A8A5E05E7489E /* Pods_SpecLeaks_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D71A32A31A51F4440ABBA47 /* Pods_SpecLeaks_Tests.framework */; }; 11 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 12 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 13 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 14 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 15 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 16 | 9C2EF69D206E8B7500484633 /* LeakingViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C2EF68C206E8B6D00484633 /* LeakingViewController.storyboard */; }; 17 | 9C2EF69E206E8B7500484633 /* LeakingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C2EF689206E8B6C00484633 /* LeakingViewController.swift */; }; 18 | 9C2EF69F206E8B7500484633 /* ViewControllersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C2EF68A206E8B6D00484633 /* ViewControllersTests.swift */; }; 19 | 9C2EF6A0206E8B7500484633 /* DelegatesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C2EF68B206E8B6D00484633 /* DelegatesTests.swift */; }; 20 | 9C2EF6A1206E8B7500484633 /* NotificationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C2EF68F206E8B6D00484633 /* NotificationsTests.swift */; }; 21 | 9C2EF6A4206E8B7500484633 /* ActionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C2EF690206E8B6D00484633 /* ActionsTest.swift */; }; 22 | 9C2EF6B0206ED5DE00484633 /* Storyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C2EF6AF206ED5DD00484633 /* Storyboard.swift */; }; 23 | 9C2EF6B1206ED67100484633 /* LeakingViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C2EF68C206E8B6D00484633 /* LeakingViewController.storyboard */; }; 24 | 9C2EF6BF207146B100484633 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C2EF6BD2071464300484633 /* Helpers.swift */; }; 25 | E04A1632042CAC31DE717D94 /* Pods_SpecLeaks_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC717699F37163E5D6D3ACB1 /* Pods_SpecLeaks_Example.framework */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 607FACCF1AFB9204008FA782; 34 | remoteInfo = SpecLeaks; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 09FA7FEA47072CAFC2CFD4B5 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 40 | 3BE8795F09E9FE0BF57C24C6 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 41 | 441134F428E141DCD160B572 /* SpecLeaks.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = SpecLeaks.podspec; path = ../SpecLeaks.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 42 | 471B37C22E6643549415F229 /* Pods-SpecLeaks_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SpecLeaks_Tests.release.xcconfig"; path = "Target Support Files/Pods-SpecLeaks_Tests/Pods-SpecLeaks_Tests.release.xcconfig"; sourceTree = ""; }; 43 | 607FACD01AFB9204008FA782 /* SpecLeaks_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpecLeaks_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 46 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 47 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 48 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 49 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 50 | 607FACE51AFB9204008FA782 /* SpecLeaks_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SpecLeaks_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 75B60EB0C7A595251D990B01 /* Pods-SpecLeaks_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SpecLeaks_Tests.debug.xcconfig"; path = "Target Support Files/Pods-SpecLeaks_Tests/Pods-SpecLeaks_Tests.debug.xcconfig"; sourceTree = ""; }; 53 | 8D71A32A31A51F4440ABBA47 /* Pods_SpecLeaks_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SpecLeaks_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 9C2EF689206E8B6C00484633 /* LeakingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeakingViewController.swift; sourceTree = ""; }; 55 | 9C2EF68A206E8B6D00484633 /* ViewControllersTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllersTests.swift; sourceTree = ""; }; 56 | 9C2EF68B206E8B6D00484633 /* DelegatesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DelegatesTests.swift; sourceTree = ""; }; 57 | 9C2EF68C206E8B6D00484633 /* LeakingViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LeakingViewController.storyboard; sourceTree = ""; }; 58 | 9C2EF68F206E8B6D00484633 /* NotificationsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationsTests.swift; sourceTree = ""; }; 59 | 9C2EF690206E8B6D00484633 /* ActionsTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionsTest.swift; sourceTree = ""; }; 60 | 9C2EF6AF206ED5DD00484633 /* Storyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Storyboard.swift; sourceTree = ""; }; 61 | 9C2EF6BD2071464300484633 /* Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; 62 | C002BE515219CC5D660F94E5 /* Pods-SpecLeaks_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SpecLeaks_Example.release.xcconfig"; path = "Target Support Files/Pods-SpecLeaks_Example/Pods-SpecLeaks_Example.release.xcconfig"; sourceTree = ""; }; 63 | E139635B43C77E07D3C0A936 /* Pods-SpecLeaks_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SpecLeaks_Example.debug.xcconfig"; path = "Target Support Files/Pods-SpecLeaks_Example/Pods-SpecLeaks_Example.debug.xcconfig"; sourceTree = ""; }; 64 | FC717699F37163E5D6D3ACB1 /* Pods_SpecLeaks_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SpecLeaks_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | /* End PBXFileReference section */ 66 | 67 | /* Begin PBXFrameworksBuildPhase section */ 68 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | E04A1632042CAC31DE717D94 /* Pods_SpecLeaks_Example.framework in Frameworks */, 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | 607FACE21AFB9204008FA782 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | 35911BB6F34A8A5E05E7489E /* Pods_SpecLeaks_Tests.framework in Frameworks */, 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXFrameworksBuildPhase section */ 85 | 86 | /* Begin PBXGroup section */ 87 | 607FACC71AFB9204008FA782 = { 88 | isa = PBXGroup; 89 | children = ( 90 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 91 | 607FACD21AFB9204008FA782 /* Example for SpecLeaks */, 92 | 607FACE81AFB9204008FA782 /* Tests */, 93 | 607FACD11AFB9204008FA782 /* Products */, 94 | B105A09F95BAE2FD03232E63 /* Pods */, 95 | CCF502EF4ED32BEFC82ED8FB /* Frameworks */, 96 | ); 97 | sourceTree = ""; 98 | }; 99 | 607FACD11AFB9204008FA782 /* Products */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 607FACD01AFB9204008FA782 /* SpecLeaks_Example.app */, 103 | 607FACE51AFB9204008FA782 /* SpecLeaks_Tests.xctest */, 104 | ); 105 | name = Products; 106 | sourceTree = ""; 107 | }; 108 | 607FACD21AFB9204008FA782 /* Example for SpecLeaks */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 112 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 113 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 114 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 115 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 116 | 607FACD31AFB9204008FA782 /* Supporting Files */, 117 | ); 118 | name = "Example for SpecLeaks"; 119 | path = SpecLeaks; 120 | sourceTree = ""; 121 | }; 122 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 607FACD41AFB9204008FA782 /* Info.plist */, 126 | ); 127 | name = "Supporting Files"; 128 | sourceTree = ""; 129 | }; 130 | 607FACE81AFB9204008FA782 /* Tests */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 9C2EF68A206E8B6D00484633 /* ViewControllersTests.swift */, 134 | 9C2EF68B206E8B6D00484633 /* DelegatesTests.swift */, 135 | 9C2EF68F206E8B6D00484633 /* NotificationsTests.swift */, 136 | 9C2EF690206E8B6D00484633 /* ActionsTest.swift */, 137 | 9C8E9DCB2071937100B71448 /* Helpers */, 138 | 607FACE91AFB9204008FA782 /* Supporting Files */, 139 | ); 140 | path = Tests; 141 | sourceTree = ""; 142 | }; 143 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 607FACEA1AFB9204008FA782 /* Info.plist */, 147 | ); 148 | name = "Supporting Files"; 149 | sourceTree = ""; 150 | }; 151 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 441134F428E141DCD160B572 /* SpecLeaks.podspec */, 155 | 09FA7FEA47072CAFC2CFD4B5 /* README.md */, 156 | 3BE8795F09E9FE0BF57C24C6 /* LICENSE */, 157 | ); 158 | name = "Podspec Metadata"; 159 | sourceTree = ""; 160 | }; 161 | 9C8E9DCB2071937100B71448 /* Helpers */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | 9C2EF68C206E8B6D00484633 /* LeakingViewController.storyboard */, 165 | 9C2EF689206E8B6C00484633 /* LeakingViewController.swift */, 166 | 9C2EF6AF206ED5DD00484633 /* Storyboard.swift */, 167 | 9C2EF6BD2071464300484633 /* Helpers.swift */, 168 | ); 169 | path = Helpers; 170 | sourceTree = ""; 171 | }; 172 | B105A09F95BAE2FD03232E63 /* Pods */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | E139635B43C77E07D3C0A936 /* Pods-SpecLeaks_Example.debug.xcconfig */, 176 | C002BE515219CC5D660F94E5 /* Pods-SpecLeaks_Example.release.xcconfig */, 177 | 75B60EB0C7A595251D990B01 /* Pods-SpecLeaks_Tests.debug.xcconfig */, 178 | 471B37C22E6643549415F229 /* Pods-SpecLeaks_Tests.release.xcconfig */, 179 | ); 180 | path = Pods; 181 | sourceTree = ""; 182 | }; 183 | CCF502EF4ED32BEFC82ED8FB /* Frameworks */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | FC717699F37163E5D6D3ACB1 /* Pods_SpecLeaks_Example.framework */, 187 | 8D71A32A31A51F4440ABBA47 /* Pods_SpecLeaks_Tests.framework */, 188 | ); 189 | name = Frameworks; 190 | sourceTree = ""; 191 | }; 192 | /* End PBXGroup section */ 193 | 194 | /* Begin PBXNativeTarget section */ 195 | 607FACCF1AFB9204008FA782 /* SpecLeaks_Example */ = { 196 | isa = PBXNativeTarget; 197 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SpecLeaks_Example" */; 198 | buildPhases = ( 199 | 325DE23FFD59703F1304A00C /* [CP] Check Pods Manifest.lock */, 200 | 607FACCC1AFB9204008FA782 /* Sources */, 201 | 607FACCD1AFB9204008FA782 /* Frameworks */, 202 | 607FACCE1AFB9204008FA782 /* Resources */, 203 | FEACAA3B60066540D67658E9 /* [CP] Embed Pods Frameworks */, 204 | ); 205 | buildRules = ( 206 | ); 207 | dependencies = ( 208 | ); 209 | name = SpecLeaks_Example; 210 | productName = SpecLeaks; 211 | productReference = 607FACD01AFB9204008FA782 /* SpecLeaks_Example.app */; 212 | productType = "com.apple.product-type.application"; 213 | }; 214 | 607FACE41AFB9204008FA782 /* SpecLeaks_Tests */ = { 215 | isa = PBXNativeTarget; 216 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SpecLeaks_Tests" */; 217 | buildPhases = ( 218 | 066399AF80350EBE7F00C67E /* [CP] Check Pods Manifest.lock */, 219 | 607FACE11AFB9204008FA782 /* Sources */, 220 | 607FACE21AFB9204008FA782 /* Frameworks */, 221 | 607FACE31AFB9204008FA782 /* Resources */, 222 | 87646E987F25713353D01C51 /* [CP] Embed Pods Frameworks */, 223 | ); 224 | buildRules = ( 225 | ); 226 | dependencies = ( 227 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */, 228 | ); 229 | name = SpecLeaks_Tests; 230 | productName = Tests; 231 | productReference = 607FACE51AFB9204008FA782 /* SpecLeaks_Tests.xctest */; 232 | productType = "com.apple.product-type.bundle.unit-test"; 233 | }; 234 | /* End PBXNativeTarget section */ 235 | 236 | /* Begin PBXProject section */ 237 | 607FACC81AFB9204008FA782 /* Project object */ = { 238 | isa = PBXProject; 239 | attributes = { 240 | LastSwiftUpdateCheck = 0830; 241 | LastUpgradeCheck = 1020; 242 | ORGANIZATIONNAME = CocoaPods; 243 | TargetAttributes = { 244 | 607FACCF1AFB9204008FA782 = { 245 | CreatedOnToolsVersion = 6.3.1; 246 | LastSwiftMigration = 0900; 247 | }; 248 | 607FACE41AFB9204008FA782 = { 249 | CreatedOnToolsVersion = 6.3.1; 250 | LastSwiftMigration = 0900; 251 | TestTargetID = 607FACCF1AFB9204008FA782; 252 | }; 253 | }; 254 | }; 255 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "SpecLeaks" */; 256 | compatibilityVersion = "Xcode 3.2"; 257 | developmentRegion = English; 258 | hasScannedForEncodings = 0; 259 | knownRegions = ( 260 | English, 261 | en, 262 | Base, 263 | ); 264 | mainGroup = 607FACC71AFB9204008FA782; 265 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 266 | projectDirPath = ""; 267 | projectRoot = ""; 268 | targets = ( 269 | 607FACCF1AFB9204008FA782 /* SpecLeaks_Example */, 270 | 607FACE41AFB9204008FA782 /* SpecLeaks_Tests */, 271 | ); 272 | }; 273 | /* End PBXProject section */ 274 | 275 | /* Begin PBXResourcesBuildPhase section */ 276 | 607FACCE1AFB9204008FA782 /* Resources */ = { 277 | isa = PBXResourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 281 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 282 | 9C2EF6B1206ED67100484633 /* LeakingViewController.storyboard in Resources */, 283 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | 607FACE31AFB9204008FA782 /* Resources */ = { 288 | isa = PBXResourcesBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | 9C2EF69D206E8B7500484633 /* LeakingViewController.storyboard in Resources */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | /* End PBXResourcesBuildPhase section */ 296 | 297 | /* Begin PBXShellScriptBuildPhase section */ 298 | 066399AF80350EBE7F00C67E /* [CP] Check Pods Manifest.lock */ = { 299 | isa = PBXShellScriptBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | ); 303 | inputFileListPaths = ( 304 | ); 305 | inputPaths = ( 306 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 307 | "${PODS_ROOT}/Manifest.lock", 308 | ); 309 | name = "[CP] Check Pods Manifest.lock"; 310 | outputFileListPaths = ( 311 | ); 312 | outputPaths = ( 313 | "$(DERIVED_FILE_DIR)/Pods-SpecLeaks_Tests-checkManifestLockResult.txt", 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | shellPath = /bin/sh; 317 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 318 | showEnvVarsInLog = 0; 319 | }; 320 | 325DE23FFD59703F1304A00C /* [CP] Check Pods Manifest.lock */ = { 321 | isa = PBXShellScriptBuildPhase; 322 | buildActionMask = 2147483647; 323 | files = ( 324 | ); 325 | inputFileListPaths = ( 326 | ); 327 | inputPaths = ( 328 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 329 | "${PODS_ROOT}/Manifest.lock", 330 | ); 331 | name = "[CP] Check Pods Manifest.lock"; 332 | outputFileListPaths = ( 333 | ); 334 | outputPaths = ( 335 | "$(DERIVED_FILE_DIR)/Pods-SpecLeaks_Example-checkManifestLockResult.txt", 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | shellPath = /bin/sh; 339 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 340 | showEnvVarsInLog = 0; 341 | }; 342 | 87646E987F25713353D01C51 /* [CP] Embed Pods Frameworks */ = { 343 | isa = PBXShellScriptBuildPhase; 344 | buildActionMask = 2147483647; 345 | files = ( 346 | ); 347 | inputPaths = ( 348 | "${PODS_ROOT}/Target Support Files/Pods-SpecLeaks_Tests/Pods-SpecLeaks_Tests-frameworks.sh", 349 | "${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework", 350 | "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework", 351 | "${BUILT_PRODUCTS_DIR}/SpecLeaks/SpecLeaks.framework", 352 | "${BUILT_PRODUCTS_DIR}/RxCocoa/RxCocoa.framework", 353 | "${BUILT_PRODUCTS_DIR}/RxRelay/RxRelay.framework", 354 | "${BUILT_PRODUCTS_DIR}/RxSwift/RxSwift.framework", 355 | ); 356 | name = "[CP] Embed Pods Frameworks"; 357 | outputPaths = ( 358 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", 359 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", 360 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SpecLeaks.framework", 361 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxCocoa.framework", 362 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxRelay.framework", 363 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwift.framework", 364 | ); 365 | runOnlyForDeploymentPostprocessing = 0; 366 | shellPath = /bin/sh; 367 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SpecLeaks_Tests/Pods-SpecLeaks_Tests-frameworks.sh\"\n"; 368 | showEnvVarsInLog = 0; 369 | }; 370 | FEACAA3B60066540D67658E9 /* [CP] Embed Pods Frameworks */ = { 371 | isa = PBXShellScriptBuildPhase; 372 | buildActionMask = 2147483647; 373 | files = ( 374 | ); 375 | inputPaths = ( 376 | "${PODS_ROOT}/Target Support Files/Pods-SpecLeaks_Example/Pods-SpecLeaks_Example-frameworks.sh", 377 | "${BUILT_PRODUCTS_DIR}/Nimble/Nimble.framework", 378 | "${BUILT_PRODUCTS_DIR}/Quick/Quick.framework", 379 | "${BUILT_PRODUCTS_DIR}/SpecLeaks/SpecLeaks.framework", 380 | ); 381 | name = "[CP] Embed Pods Frameworks"; 382 | outputPaths = ( 383 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", 384 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", 385 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SpecLeaks.framework", 386 | ); 387 | runOnlyForDeploymentPostprocessing = 0; 388 | shellPath = /bin/sh; 389 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SpecLeaks_Example/Pods-SpecLeaks_Example-frameworks.sh\"\n"; 390 | showEnvVarsInLog = 0; 391 | }; 392 | /* End PBXShellScriptBuildPhase section */ 393 | 394 | /* Begin PBXSourcesBuildPhase section */ 395 | 607FACCC1AFB9204008FA782 /* Sources */ = { 396 | isa = PBXSourcesBuildPhase; 397 | buildActionMask = 2147483647; 398 | files = ( 399 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 400 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 401 | ); 402 | runOnlyForDeploymentPostprocessing = 0; 403 | }; 404 | 607FACE11AFB9204008FA782 /* Sources */ = { 405 | isa = PBXSourcesBuildPhase; 406 | buildActionMask = 2147483647; 407 | files = ( 408 | 9C2EF6A0206E8B7500484633 /* DelegatesTests.swift in Sources */, 409 | 9C2EF69E206E8B7500484633 /* LeakingViewController.swift in Sources */, 410 | 9C2EF6A4206E8B7500484633 /* ActionsTest.swift in Sources */, 411 | 9C2EF6BF207146B100484633 /* Helpers.swift in Sources */, 412 | 9C2EF6B0206ED5DE00484633 /* Storyboard.swift in Sources */, 413 | 9C2EF6A1206E8B7500484633 /* NotificationsTests.swift in Sources */, 414 | 9C2EF69F206E8B7500484633 /* ViewControllersTests.swift in Sources */, 415 | ); 416 | runOnlyForDeploymentPostprocessing = 0; 417 | }; 418 | /* End PBXSourcesBuildPhase section */ 419 | 420 | /* Begin PBXTargetDependency section */ 421 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { 422 | isa = PBXTargetDependency; 423 | target = 607FACCF1AFB9204008FA782 /* SpecLeaks_Example */; 424 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; 425 | }; 426 | /* End PBXTargetDependency section */ 427 | 428 | /* Begin PBXVariantGroup section */ 429 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 430 | isa = PBXVariantGroup; 431 | children = ( 432 | 607FACDA1AFB9204008FA782 /* Base */, 433 | ); 434 | name = Main.storyboard; 435 | sourceTree = ""; 436 | }; 437 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 438 | isa = PBXVariantGroup; 439 | children = ( 440 | 607FACDF1AFB9204008FA782 /* Base */, 441 | ); 442 | name = LaunchScreen.xib; 443 | sourceTree = ""; 444 | }; 445 | /* End PBXVariantGroup section */ 446 | 447 | /* Begin XCBuildConfiguration section */ 448 | 607FACED1AFB9204008FA782 /* Debug */ = { 449 | isa = XCBuildConfiguration; 450 | buildSettings = { 451 | ALWAYS_SEARCH_USER_PATHS = NO; 452 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 453 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 454 | CLANG_CXX_LIBRARY = "libc++"; 455 | CLANG_ENABLE_MODULES = YES; 456 | CLANG_ENABLE_OBJC_ARC = YES; 457 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 458 | CLANG_WARN_BOOL_CONVERSION = YES; 459 | CLANG_WARN_COMMA = YES; 460 | CLANG_WARN_CONSTANT_CONVERSION = YES; 461 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 462 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 463 | CLANG_WARN_EMPTY_BODY = YES; 464 | CLANG_WARN_ENUM_CONVERSION = YES; 465 | CLANG_WARN_INFINITE_RECURSION = YES; 466 | CLANG_WARN_INT_CONVERSION = YES; 467 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 468 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 469 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 470 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 471 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 472 | CLANG_WARN_STRICT_PROTOTYPES = YES; 473 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 474 | CLANG_WARN_UNREACHABLE_CODE = YES; 475 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 476 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 477 | COPY_PHASE_STRIP = NO; 478 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 479 | ENABLE_STRICT_OBJC_MSGSEND = YES; 480 | ENABLE_TESTABILITY = YES; 481 | GCC_C_LANGUAGE_STANDARD = gnu99; 482 | GCC_DYNAMIC_NO_PIC = NO; 483 | GCC_NO_COMMON_BLOCKS = YES; 484 | GCC_OPTIMIZATION_LEVEL = 0; 485 | GCC_PREPROCESSOR_DEFINITIONS = ( 486 | "DEBUG=1", 487 | "$(inherited)", 488 | ); 489 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 490 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 491 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 492 | GCC_WARN_UNDECLARED_SELECTOR = YES; 493 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 494 | GCC_WARN_UNUSED_FUNCTION = YES; 495 | GCC_WARN_UNUSED_VARIABLE = YES; 496 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 497 | MTL_ENABLE_DEBUG_INFO = YES; 498 | ONLY_ACTIVE_ARCH = YES; 499 | SDKROOT = iphoneos; 500 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 501 | SWIFT_VERSION = 5.0; 502 | }; 503 | name = Debug; 504 | }; 505 | 607FACEE1AFB9204008FA782 /* Release */ = { 506 | isa = XCBuildConfiguration; 507 | buildSettings = { 508 | ALWAYS_SEARCH_USER_PATHS = NO; 509 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 510 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 511 | CLANG_CXX_LIBRARY = "libc++"; 512 | CLANG_ENABLE_MODULES = YES; 513 | CLANG_ENABLE_OBJC_ARC = YES; 514 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 515 | CLANG_WARN_BOOL_CONVERSION = YES; 516 | CLANG_WARN_COMMA = YES; 517 | CLANG_WARN_CONSTANT_CONVERSION = YES; 518 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 519 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 520 | CLANG_WARN_EMPTY_BODY = YES; 521 | CLANG_WARN_ENUM_CONVERSION = YES; 522 | CLANG_WARN_INFINITE_RECURSION = YES; 523 | CLANG_WARN_INT_CONVERSION = YES; 524 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 525 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 526 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 527 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 528 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 529 | CLANG_WARN_STRICT_PROTOTYPES = YES; 530 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 531 | CLANG_WARN_UNREACHABLE_CODE = YES; 532 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 533 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 534 | COPY_PHASE_STRIP = NO; 535 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 536 | ENABLE_NS_ASSERTIONS = NO; 537 | ENABLE_STRICT_OBJC_MSGSEND = YES; 538 | GCC_C_LANGUAGE_STANDARD = gnu99; 539 | GCC_NO_COMMON_BLOCKS = YES; 540 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 541 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 542 | GCC_WARN_UNDECLARED_SELECTOR = YES; 543 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 544 | GCC_WARN_UNUSED_FUNCTION = YES; 545 | GCC_WARN_UNUSED_VARIABLE = YES; 546 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 547 | MTL_ENABLE_DEBUG_INFO = NO; 548 | SDKROOT = iphoneos; 549 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 550 | SWIFT_VERSION = 5.0; 551 | VALIDATE_PRODUCT = YES; 552 | }; 553 | name = Release; 554 | }; 555 | 607FACF01AFB9204008FA782 /* Debug */ = { 556 | isa = XCBuildConfiguration; 557 | baseConfigurationReference = E139635B43C77E07D3C0A936 /* Pods-SpecLeaks_Example.debug.xcconfig */; 558 | buildSettings = { 559 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 560 | INFOPLIST_FILE = SpecLeaks/Info.plist; 561 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 562 | MODULE_NAME = ExampleApp; 563 | PRODUCT_BUNDLE_IDENTIFIER = com.lmp.specleaks; 564 | PRODUCT_NAME = "$(TARGET_NAME)"; 565 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 566 | SWIFT_VERSION = 5.0; 567 | }; 568 | name = Debug; 569 | }; 570 | 607FACF11AFB9204008FA782 /* Release */ = { 571 | isa = XCBuildConfiguration; 572 | baseConfigurationReference = C002BE515219CC5D660F94E5 /* Pods-SpecLeaks_Example.release.xcconfig */; 573 | buildSettings = { 574 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 575 | INFOPLIST_FILE = SpecLeaks/Info.plist; 576 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 577 | MODULE_NAME = ExampleApp; 578 | PRODUCT_BUNDLE_IDENTIFIER = com.lmp.specleaks; 579 | PRODUCT_NAME = "$(TARGET_NAME)"; 580 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 581 | SWIFT_VERSION = 5.0; 582 | }; 583 | name = Release; 584 | }; 585 | 607FACF31AFB9204008FA782 /* Debug */ = { 586 | isa = XCBuildConfiguration; 587 | baseConfigurationReference = 75B60EB0C7A595251D990B01 /* Pods-SpecLeaks_Tests.debug.xcconfig */; 588 | buildSettings = { 589 | FRAMEWORK_SEARCH_PATHS = ( 590 | "$(SDKROOT)/Developer/Library/Frameworks", 591 | "$(inherited)", 592 | ); 593 | GCC_PREPROCESSOR_DEFINITIONS = ( 594 | "DEBUG=1", 595 | "$(inherited)", 596 | ); 597 | INFOPLIST_FILE = Tests/Info.plist; 598 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 599 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 600 | PRODUCT_NAME = "$(TARGET_NAME)"; 601 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 602 | SWIFT_VERSION = 5.0; 603 | }; 604 | name = Debug; 605 | }; 606 | 607FACF41AFB9204008FA782 /* Release */ = { 607 | isa = XCBuildConfiguration; 608 | baseConfigurationReference = 471B37C22E6643549415F229 /* Pods-SpecLeaks_Tests.release.xcconfig */; 609 | buildSettings = { 610 | FRAMEWORK_SEARCH_PATHS = ( 611 | "$(SDKROOT)/Developer/Library/Frameworks", 612 | "$(inherited)", 613 | ); 614 | INFOPLIST_FILE = Tests/Info.plist; 615 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 616 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 617 | PRODUCT_NAME = "$(TARGET_NAME)"; 618 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 619 | SWIFT_VERSION = 5.0; 620 | }; 621 | name = Release; 622 | }; 623 | /* End XCBuildConfiguration section */ 624 | 625 | /* Begin XCConfigurationList section */ 626 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "SpecLeaks" */ = { 627 | isa = XCConfigurationList; 628 | buildConfigurations = ( 629 | 607FACED1AFB9204008FA782 /* Debug */, 630 | 607FACEE1AFB9204008FA782 /* Release */, 631 | ); 632 | defaultConfigurationIsVisible = 0; 633 | defaultConfigurationName = Release; 634 | }; 635 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SpecLeaks_Example" */ = { 636 | isa = XCConfigurationList; 637 | buildConfigurations = ( 638 | 607FACF01AFB9204008FA782 /* Debug */, 639 | 607FACF11AFB9204008FA782 /* Release */, 640 | ); 641 | defaultConfigurationIsVisible = 0; 642 | defaultConfigurationName = Release; 643 | }; 644 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SpecLeaks_Tests" */ = { 645 | isa = XCConfigurationList; 646 | buildConfigurations = ( 647 | 607FACF31AFB9204008FA782 /* Debug */, 648 | 607FACF41AFB9204008FA782 /* Release */, 649 | ); 650 | defaultConfigurationIsVisible = 0; 651 | defaultConfigurationName = Release; 652 | }; 653 | /* End XCConfigurationList section */ 654 | }; 655 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 656 | } 657 | -------------------------------------------------------------------------------- /Example/SpecLeaks.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/SpecLeaks.xcodeproj/xcshareddata/xcschemes/SpecLeaks-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /Example/SpecLeaks.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 15 | 16 | 18 | 19 | 21 | 22 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example/SpecLeaks.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/SpecLeaks/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SpecLeaks 4 | // 5 | // Created by leandromperez@gmail.com on 03/30/2018. 6 | // Copyright (c) 2018 leandromperez@gmail.com. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Example/SpecLeaks/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Example/SpecLeaks/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Example/SpecLeaks/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" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/SpecLeaks/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 | 0.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/SpecLeaks/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SpecLeaks 4 | // 5 | // Created by leandromperez@gmail.com on 03/30/2018. 6 | // Copyright (c) 2018 leandromperez@gmail.com. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/ActionsTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Actions.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 03/02/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Nimble 10 | import Quick 11 | 12 | @testable import SpecLeaks 13 | 14 | class LeakWhenActionCalled { 15 | 16 | var something : AnyObject? = nil 17 | 18 | func dontLeak(){ 19 | print("don't leak") 20 | } 21 | 22 | func leak(){ 23 | self.something = self 24 | } 25 | 26 | func returnLeakingBlock() -> Action{ 27 | return { 28 | self.dontLeak() 29 | print ("I leak because i'm not using weak " ) 30 | } 31 | } 32 | 33 | func returnNotLeakingBlock() -> Action{ 34 | return {[weak self] in 35 | self?.dontLeak() 36 | print ("I don't leak because i'm using weak " ) 37 | } 38 | } 39 | } 40 | 41 | class LeakWhenActionCalledSpec: QuickSpec { 42 | 43 | override func spec() { 44 | 45 | describe("an ObjectThatLeaksWhenActionCalled") { 46 | 47 | let test = LeakTest{ 48 | return LeakWhenActionCalled() 49 | } 50 | 51 | describe("init") { 52 | it("must not leak"){ 53 | expect(test).toNot(leak()) 54 | } 55 | } 56 | 57 | describe("leak with no action"){ 58 | it("must not leak"){ 59 | let leakingAction : Handler = {_ in } 60 | expect(test).toNot(leakWhen(leakingAction)) 61 | } 62 | } 63 | 64 | 65 | describe("leak"){ 66 | it("must leak"){ 67 | let leakingAction : Handler = {leaker in leaker.leak()} 68 | expect(test).to(leakWhen(leakingAction)) 69 | } 70 | } 71 | 72 | describe("dontLeak"){ 73 | it("must not leak"){ 74 | let notLeakingAction : Handler = {leaker in leaker.dontLeak()} 75 | expect(test).toNot(leakWhen(notLeakingAction)) 76 | } 77 | } 78 | 79 | describe("returnLeakingBlock"){ 80 | it("must leak"){ 81 | let leak : (LeakWhenActionCalled)-> Any = {leaker in return leaker.returnLeakingBlock()} 82 | 83 | expect(test).to(leakWhen(leak)) 84 | } 85 | } 86 | 87 | describe("returnNotLeakingBlock"){ 88 | it("must not leak"){ 89 | let leak : (LeakWhenActionCalled)-> Any = {leaker in return leaker.returnNotLeakingBlock()} 90 | 91 | expect(test).toNot(leakWhen(leak)) 92 | } 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Example/Tests/DelegatesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DelegatesTests.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 03/02/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Nimble 10 | import Quick 11 | import SpecLeaks 12 | 13 | //MARK: - Leaking 14 | protocol ServerDelegate : AnyObject{} 15 | 16 | class LeakingServer{ 17 | var delegate : ServerDelegate? = nil 18 | } 19 | 20 | class LeakingClient : ServerDelegate{ 21 | var server : LeakingServer 22 | 23 | init(server: LeakingServer) { 24 | self.server = server 25 | server.delegate = self 26 | } 27 | } 28 | 29 | //MARK: - Not Leaking 30 | class NotLeakingServer{ 31 | weak var delegate : ServerDelegate? = nil 32 | } 33 | 34 | class NotLeakingClient : ServerDelegate{ 35 | var server : NotLeakingServer 36 | 37 | init(server: NotLeakingServer) { 38 | self.server = server 39 | server.delegate = self 40 | } 41 | } 42 | 43 | class SomeObject{ 44 | func doSomething(){ 45 | 46 | } 47 | } 48 | 49 | class SomeOjectTests: QuickSpec { 50 | override func spec() { 51 | describe("a SomeObject") { 52 | describe("init") { 53 | it("must not leak"){ 54 | 55 | let someObject = LeakTest{ 56 | return SomeObject() 57 | } 58 | 59 | let doSomethingIsCalled : (SomeObject) -> () = {obj in obj.doSomething()} 60 | 61 | expect(someObject).toNot(leakWhen(doSomethingIsCalled)) 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | 69 | 70 | class DelegatesTests: QuickSpec { 71 | 72 | override func spec() { 73 | describe("a NotLeakingClient") { 74 | 75 | it("must not leak"){ 76 | 77 | let test = LeakTest{ 78 | return NotLeakingClient(server: NotLeakingServer()) 79 | } 80 | 81 | expect(test).toNot(leak()) 82 | } 83 | } 84 | 85 | describe("a LeakingClient") { 86 | 87 | it("must leak"){ 88 | 89 | let test = LeakTest{ 90 | return LeakingClient(server: LeakingServer()) 91 | } 92 | 93 | expect(test).to(leak()) 94 | } 95 | } 96 | } 97 | } 98 | 99 | -------------------------------------------------------------------------------- /Example/Tests/Helpers/Helpers.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Helpers.swift 3 | // SpecLeaks_Example 4 | // 5 | // Created by Leandro Perez on 01/04/2018. 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | typealias ErrorHandler = (Error)->() 12 | typealias Action = () -> () 13 | typealias Handler = (T) -> () 14 | -------------------------------------------------------------------------------- /Example/Tests/Helpers/LeakingViewController.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Example/Tests/Helpers/LeakingViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeakingViewController.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 10/01/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import RxSwift 11 | 12 | class LeakingViewController: UIViewController { 13 | 14 | private var anyObject : AnyObject? = nil 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | } 19 | 20 | func cleanLeakedObjects(){ 21 | 22 | self.anyObject = nil 23 | } 24 | 25 | func createLeak(){ 26 | self.anyObject = self 27 | } 28 | 29 | func doSomething(){ 30 | print("doing something") 31 | } 32 | 33 | func createLeakInBlock() -> () -> (){ 34 | return { 35 | self.doSomething() 36 | } 37 | } 38 | 39 | func dontCreateLeakInBlock() -> () -> (){ 40 | return { [weak self] in 41 | self?.doSomething() 42 | } 43 | } 44 | 45 | func createLeakInFlatMap() -> Observable{ 46 | return Observable.just("hello") 47 | .flatMap { (hello) -> Observable in 48 | self.doSomething() 49 | return .just("goodbye and leak") 50 | } 51 | } 52 | 53 | func dontCreateLeakInFlatMap() -> Observable{ 54 | return Observable.just("hello") 55 | .flatMap { [unowned self] (hello) -> Observable in 56 | self.doSomething() 57 | return .just("goodbye") 58 | } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Example/Tests/Helpers/Storyboard.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Storyboard.swift 3 | // Go24 4 | // 5 | // Created by Leandro Perez on 9/22/17. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | protocol Storyboard { 13 | func initialViewController ()-> T 14 | var name : String {get} 15 | var bundle : Bundle {get} 16 | } 17 | 18 | extension Storyboard { 19 | var storyboard : UIStoryboard{ 20 | return UIStoryboard.init(name: self.name, bundle: self.bundle) 21 | } 22 | 23 | func initialViewController ()-> T { 24 | let vc : T = self.storyboard.instantiateInitialViewController() as! T 25 | 26 | return vc 27 | } 28 | } 29 | 30 | 31 | enum Storyboards : String, Storyboard{ 32 | 33 | case LeakingViewController 34 | 35 | var name : String { 36 | return self.rawValue 37 | } 38 | 39 | var bundle : Bundle{ 40 | return Bundle.main 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/NotificationsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ObjectListeningAppNotificationSpec.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 03/02/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Nimble 11 | import Quick 12 | import RxSwift 13 | import RxCocoa 14 | 15 | @testable import SpecLeaks 16 | 17 | //MARK: - Not Leaking 18 | class NotLeakingWithAppNotification{ 19 | private var disposeBag = DisposeBag() 20 | 21 | var s : Int = 5 22 | 23 | func doSomething(){ 24 | s = Int(arc4random()) 25 | } 26 | 27 | init() { 28 | NotificationCenter.default.rx 29 | .notification(Notification.Name.init("Some notification")) 30 | .observeOn(MainScheduler.instance) 31 | .subscribe(onNext: { [unowned self](_) in 32 | self.doSomething() 33 | }) 34 | .disposed(by: self.disposeBag) 35 | } 36 | } 37 | 38 | //MARK: - Leaking 39 | class LeakingWithAppNotification{ 40 | private var disposeBag = DisposeBag() 41 | 42 | var s : Int = 5 43 | 44 | func doSomething(){ 45 | s = Int(arc4random()) 46 | } 47 | 48 | init() { 49 | NotificationCenter.default.rx 50 | .notification(Notification.Name.init("Some notification")) 51 | .observeOn(MainScheduler.instance) 52 | .subscribe(onNext: { (_) in //NOTICE that [unowned self] was taken out, creating a leak 53 | self.doSomething() 54 | }) 55 | .disposed(by: self.disposeBag) 56 | } 57 | } 58 | 59 | class NotificationsTests: QuickSpec { 60 | 61 | override func spec() { 62 | describe("an NotLeakingWithAppNotification") { 63 | 64 | it("must not leak"){ 65 | let listeningAppNotification = LeakTest{ 66 | return NotLeakingWithAppNotification() 67 | } 68 | 69 | expect(listeningAppNotification).toNot(leak()) 70 | } 71 | } 72 | 73 | describe("a LeakWithAppNotification") { 74 | 75 | it("must leak"){ 76 | let leaker = LeakTest{ 77 | return LeakingWithAppNotification() 78 | } 79 | 80 | expect(leaker).to(leak()) 81 | } 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Example/Tests/ViewControllersTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeakingViewControllerSpec.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 10/01/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Nimble 10 | import Quick 11 | 12 | @testable import SpecLeaks 13 | 14 | class ViewControllersTests: QuickSpec { 15 | 16 | override func spec() { 17 | describe("UIViewController"){ 18 | let test = LeakTest{ 19 | return UIViewController() 20 | } 21 | 22 | describe("init") { 23 | it("must not leak"){ 24 | expect(test).toNot(leak()) 25 | } 26 | } 27 | } 28 | 29 | describe("LeakingViewController") { 30 | let test = LeakTest{ 31 | let storyboard = UIStoryboard.init(name: "LeakingViewController", bundle: Bundle(for: LeakingViewController.self)) 32 | return storyboard.instantiateInitialViewController() as! LeakingViewController 33 | } 34 | 35 | describe("init") { 36 | it("must not leak"){ 37 | expect(test).toNot(leak()) 38 | } 39 | } 40 | 41 | describe("doSomething") { 42 | it("must not leak"){ 43 | let action : (LeakingViewController) -> () = { vc in 44 | 45 | vc.cleanLeakedObjects() 46 | vc.doSomething() 47 | } 48 | 49 | expect(test).toNot(leakWhen(action)) 50 | } 51 | } 52 | 53 | describe("createLeak") { 54 | it("must leak"){ 55 | let action : (LeakingViewController) -> () = { vc in 56 | 57 | vc.cleanLeakedObjects() 58 | vc.createLeak() 59 | } 60 | 61 | expect(test).to(leakWhen(action)) 62 | } 63 | } 64 | 65 | describe("createLeakInBlock") { 66 | it("must leak"){ 67 | let action : (LeakingViewController) -> Any = { vc in 68 | 69 | vc.cleanLeakedObjects() 70 | return vc.createLeakInBlock() 71 | } 72 | 73 | expect(test).to(leakWhen(action)) 74 | } 75 | 76 | it("must leak"){ 77 | let action : (LeakingViewController) -> Any = { vc in 78 | 79 | vc.cleanLeakedObjects() 80 | return vc.createLeakInBlock() 81 | } 82 | 83 | expect(test).to(leakWhen(action)) 84 | } 85 | } 86 | describe("dontCreateLeakInBlock") { 87 | it("must not leak"){ 88 | let action : (LeakingViewController) -> Any = { vc in 89 | 90 | vc.cleanLeakedObjects() 91 | return vc.dontCreateLeakInBlock() 92 | } 93 | 94 | expect(test).toNot(leakWhen(action)) 95 | } 96 | } 97 | 98 | describe("createLeakInFlatMap") { 99 | it("must leak"){ 100 | let action : (LeakingViewController) -> Any = { vc in 101 | 102 | vc.cleanLeakedObjects() 103 | return vc.createLeakInFlatMap() 104 | } 105 | 106 | expect(test).to(leakWhen(action)) 107 | } 108 | } 109 | 110 | describe("dontCreateLeakInFlatMap") { 111 | it("must not leak"){ 112 | let action : (LeakingViewController) -> Any = { vc in 113 | 114 | vc.cleanLeakedObjects() 115 | return vc.dontCreateLeakInFlatMap() 116 | } 117 | 118 | expect(test).toNot(leakWhen(action)) 119 | } 120 | } 121 | } 122 | } 123 | } 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Leandro Perez 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "SpecLeaks", 7 | platforms: [ 8 | .iOS(.v10) 9 | ], 10 | products: [ 11 | .library(name: "SpecLeaks", targets: ["SpecLeaks"]), 12 | ], 13 | dependencies: [ 14 | .package(url: "https://github.com/Quick/Nimble", from: "9.0.0"), 15 | .package(url: "https://github.com/Quick/Quick", from: "3.0.0"), 16 | ], 17 | targets: [ 18 | .target(name: "SpecLeaks", dependencies: ["Quick", "Nimble"], path: "SpecLeaks/Classes/"), 19 | ], 20 | swiftLanguageVersions: [.v5] 21 | ) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SpecLeaks 2 | 3 | [![Version](https://img.shields.io/cocoapods/v/SpecLeaks.svg?style=flat)](http://cocoapods.org/pods/SpecLeaks) 4 | [![License](https://img.shields.io/cocoapods/l/SpecLeaks.svg?style=flat)](http://cocoapods.org/pods/SpecLeaks) 5 | [![Platform](https://img.shields.io/cocoapods/p/SpecLeaks.svg?style=flat)](http://cocoapods.org/pods/SpecLeaks) 6 | [![Build Status](https://travis-ci.org/leandromperez/specleaks.svg?branch=master)](https://travis-ci.org/leandromperez/specleaks) 7 | 8 | Create ***Unit Tests for Memory Leaks*** in Swift. 9 | * ***SpecLeaks*** allows you to create tests using Quick and Nimble. 10 | * Write readable tests for mem leaks easily with these Quick and Nimble extensions. 11 | 12 | 13 | [Quick and Nimble](https://github.com/Quick/Nimble) is a Unit Testing framework that allows you to write tests in a more humanly readable fashion. 14 | 15 | 16 | ## What can you Test? 17 | 18 | * Test if an object is leaking when it is initialized. 19 | * Test if a ViewController is leaking when its view is loaded. 20 | * Test if a particular method is leaking 21 | 22 | 23 | ## Compatibility Notes: 24 | **Release Version: 0.1.8** 25 | * Language version: **Swift 5.0** 26 | * iOS Deployment Target: 10.0 27 | * Travis CI running XCode version: 10.2 28 | 29 | ## Cocoapods Installation 30 | 31 | SpecLeaks is available through [CocoaPods](http://cocoapods.org). To install 32 | it, simply add the following line to your Podfile: 33 | 34 | ```ruby 35 | pod 'SpecLeaks' 36 | ``` 37 | ## Example Cocoapods Project 38 | 39 | The example project contains a few Unit Tests that will let you understand how to use SpecLeaks. 40 | 41 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 42 | 43 | Command+U to run the sample tests. 44 | 45 | 46 | ## Carthage Installation 47 | 48 | Follow this [guideline](https://github.com/Carthage/Carthage#quick-start) and to your Cartfile: 49 | 50 | ```ruby 51 | github "leandromperez/specleaks" 52 | ``` 53 | *Note:* don't forget to modify the framework search path from your testing target to include the folder that contains the compiled .framework files 54 | 55 | 56 | ## Swift Package Manager Installation 57 | 58 | In Xcode choose File | Swift Packages | Add package dependency and enter https://github.com/leandromperez/specleaks. 59 | 60 | ## Example Carthage Project 61 | 62 | There is a folder in the repo *Carthage-Example* that contains a project called *Carthage-Tests* configured to use Carthage. 63 | 64 | * Notice the following config entry in Build Settings: 65 | FRAMEWORK_SEARCH_PATHS = $(SRCROOT)/** $(SRCROOT)/../** 66 | 67 | 68 | ## How to Write Tests 69 | 1. Create a Spec 70 | 2. Define a `it("action")` block 71 | 3. Create a `LeakTest` passing a block that returns the object you want to test 72 | 4. Write your expectations using `toNot(leak())` or `toNot(leakWhen())` 73 | 74 | ### Memory Leaks in initialization of plain Objects 75 | ```swift 76 | 77 | class SomeObject {} 78 | 79 | class SomeOjectTests: QuickSpec { 80 | override func spec() { 81 | describe("SomeObject") { 82 | describe("init") { 83 | it("must not leak"){ 84 | let someObject = LeakTest{ 85 | return SomeObject() 86 | } 87 | 88 | expect(someObject).toNot(leak()) 89 | } 90 | } 91 | } 92 | } 93 | } 94 | ``` 95 | 96 | ### Memory Leaks in viewDidLoad or init of a a UIViewController 97 | 98 | 99 | ```swift 100 | 101 | class SomeViewController : UIViewController {} 102 | 103 | class SomeViewControllerTests: QuickSpec { 104 | 105 | override func spec() { 106 | describe("SomeViewController"){ 107 | describe("viewDidLoad") { 108 | let vc = LeakTest{ 109 | return SomeViewController() 110 | } 111 | it("must not leak"){ 112 | expect(vc).toNot(leak()) 113 | } 114 | } 115 | } 116 | } 117 | } 118 | ``` 119 | 120 | ### Memory Leaks when an action is called 121 | 122 | 123 | ```swift 124 | 125 | class SomeObject{ 126 | func doSomething(){ 127 | 128 | } 129 | } 130 | 131 | class SomeOjectTests: QuickSpec { 132 | override func spec() { 133 | describe("SomeObject") { 134 | describe("doSomething") { 135 | it("must not leak"){ 136 | 137 | let someObject = LeakTest{ 138 | return SomeObject() 139 | } 140 | 141 | let doSomethingIsCalled : (SomeObject) -> () = {obj in 142 | obj.doSomething() 143 | } 144 | 145 | expect(someObject).toNot(leakWhen(doSomethingIsCalled)) 146 | } 147 | } 148 | } 149 | } 150 | } 151 | ``` 152 | ## Author 153 | @bataleandro Leandro Perez 154 | 155 | ## License 156 | 157 | SpecLeaks is available under the MIT license. See the LICENSE file for more info. 158 | -------------------------------------------------------------------------------- /SpecLeaks.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint SpecLeaks.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'SpecLeaks' 11 | s.version = '0.1.9' 12 | s.swift_version = '5.0' 13 | s.summary = 'Unit Tests Memory Leaks in Swift. Write readable tests for mem leaks easily with these Quick and Nimble extensions.' 14 | 15 | s.description = 'Quick and Nimble are tools that form a Unit Testing framework that allows you to write tests in a more humanly readable fashion. SpecLeaks is only a few additions to those tools. It lets you create unit tests to see if objects are leaking. You can test vanilla objects, view controllers, and see if an object or an action leaks' 16 | 17 | s.homepage = 'https://github.com/leandromperez/specleaks' 18 | s.license = { :type => 'MIT', :file => 'LICENSE' } 19 | s.author = { 'Leandro Perez' => 'https://twitter.com/bataleandro' } 20 | s.source = { :git => 'https://github.com/leandromperez/specleaks.git', :tag => s.version.to_s } 21 | s.social_media_url = 'https://twitter.com/bataleandro' 22 | 23 | s.ios.deployment_target = '10.0' 24 | 25 | s.source_files = 'SpecLeaks/Classes/**/*' 26 | 27 | s.frameworks = 'UIKit', 'XCTest' 28 | s.dependency 'Quick', '3.0.0' 29 | s.dependency 'Nimble', '9.0.0-rc.3' 30 | end 31 | -------------------------------------------------------------------------------- /SpecLeaks.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 79D836ED2288AC7D00A5D942 /* SpecLeaks.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79D836E32288AC7D00A5D942 /* SpecLeaks.framework */; }; 11 | 79D836F22288AC7D00A5D942 /* SpecLeaksTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79D836F12288AC7D00A5D942 /* SpecLeaksTests.swift */; }; 12 | 79D836F42288AC7D00A5D942 /* SpecLeaks.h in Headers */ = {isa = PBXBuildFile; fileRef = 79D836E62288AC7D00A5D942 /* SpecLeaks.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 79DFEF412289297F00CF65D5 /* AnalyzeLeak.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DFEF3A2289297F00CF65D5 /* AnalyzeLeak.swift */; }; 14 | 79DFEF432289297F00CF65D5 /* Matchers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DFEF3C2289297F00CF65D5 /* Matchers.swift */; }; 15 | 79DFEF442289297F00CF65D5 /* LeaksAnalyzer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DFEF3D2289297F00CF65D5 /* LeaksAnalyzer.swift */; }; 16 | 79DFEF452289297F00CF65D5 /* LeakTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DFEF3E2289297F00CF65D5 /* LeakTest.swift */; }; 17 | 79DFEF462289297F00CF65D5 /* AnalyzeLeakAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DFEF3F2289297F00CF65D5 /* AnalyzeLeakAction.swift */; }; 18 | 79DFEF472289297F00CF65D5 /* Expectation+Leaks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79DFEF402289297F00CF65D5 /* Expectation+Leaks.swift */; }; 19 | 79DFEF4822892A8900CF65D5 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79DFEF372288B12E00CF65D5 /* Quick.framework */; }; 20 | 79DFEF4922892A8D00CF65D5 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79DFEF352288B12200CF65D5 /* Nimble.framework */; }; 21 | 8C0FEB0B242B6F0700B72A8A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C0FEB0A242B6F0700B72A8A /* XCTest.framework */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 79D836EE2288AC7D00A5D942 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = 79D836DA2288AC7D00A5D942 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = 79D836E22288AC7D00A5D942; 30 | remoteInfo = SpecLeaks; 31 | }; 32 | /* End PBXContainerItemProxy section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 79D836E32288AC7D00A5D942 /* SpecLeaks.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SpecLeaks.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 79D836E62288AC7D00A5D942 /* SpecLeaks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SpecLeaks.h; sourceTree = ""; }; 37 | 79D836E72288AC7D00A5D942 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 38 | 79D836EC2288AC7D00A5D942 /* SpecLeaksTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SpecLeaksTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 79D836F12288AC7D00A5D942 /* SpecLeaksTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpecLeaksTests.swift; sourceTree = ""; }; 40 | 79D836F32288AC7D00A5D942 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | 79DFEF352288B12200CF65D5 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/iOS/Nimble.framework; sourceTree = ""; }; 42 | 79DFEF372288B12E00CF65D5 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/iOS/Quick.framework; sourceTree = ""; }; 43 | 79DFEF3A2289297F00CF65D5 /* AnalyzeLeak.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnalyzeLeak.swift; sourceTree = ""; }; 44 | 79DFEF3C2289297F00CF65D5 /* Matchers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Matchers.swift; sourceTree = ""; }; 45 | 79DFEF3D2289297F00CF65D5 /* LeaksAnalyzer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeaksAnalyzer.swift; sourceTree = ""; }; 46 | 79DFEF3E2289297F00CF65D5 /* LeakTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeakTest.swift; sourceTree = ""; }; 47 | 79DFEF3F2289297F00CF65D5 /* AnalyzeLeakAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnalyzeLeakAction.swift; sourceTree = ""; }; 48 | 79DFEF402289297F00CF65D5 /* Expectation+Leaks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Expectation+Leaks.swift"; sourceTree = ""; }; 49 | 8C0FEB0A242B6F0700B72A8A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 79D836E02288AC7D00A5D942 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 79DFEF4822892A8900CF65D5 /* Quick.framework in Frameworks */, 58 | 8C0FEB0B242B6F0700B72A8A /* XCTest.framework in Frameworks */, 59 | 79DFEF4922892A8D00CF65D5 /* Nimble.framework in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | 79D836E92288AC7D00A5D942 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | 79D836ED2288AC7D00A5D942 /* SpecLeaks.framework in Frameworks */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | /* End PBXFrameworksBuildPhase section */ 72 | 73 | /* Begin PBXGroup section */ 74 | 79D836D92288AC7D00A5D942 = { 75 | isa = PBXGroup; 76 | children = ( 77 | 79DFEF392289297F00CF65D5 /* Classes */, 78 | 79D836E52288AC7D00A5D942 /* SpecLeaks */, 79 | 79D836F02288AC7D00A5D942 /* SpecLeaksTests */, 80 | 79D836E42288AC7D00A5D942 /* Products */, 81 | 79D8370C2288AD7B00A5D942 /* Frameworks */, 82 | ); 83 | sourceTree = ""; 84 | }; 85 | 79D836E42288AC7D00A5D942 /* Products */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 79D836E32288AC7D00A5D942 /* SpecLeaks.framework */, 89 | 79D836EC2288AC7D00A5D942 /* SpecLeaksTests.xctest */, 90 | ); 91 | name = Products; 92 | sourceTree = ""; 93 | }; 94 | 79D836E52288AC7D00A5D942 /* SpecLeaks */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 79D836E62288AC7D00A5D942 /* SpecLeaks.h */, 98 | 79D836E72288AC7D00A5D942 /* Info.plist */, 99 | ); 100 | path = SpecLeaks; 101 | sourceTree = ""; 102 | }; 103 | 79D836F02288AC7D00A5D942 /* SpecLeaksTests */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 79D836F12288AC7D00A5D942 /* SpecLeaksTests.swift */, 107 | 79D836F32288AC7D00A5D942 /* Info.plist */, 108 | ); 109 | path = SpecLeaksTests; 110 | sourceTree = ""; 111 | }; 112 | 79D8370C2288AD7B00A5D942 /* Frameworks */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 8C0FEB0A242B6F0700B72A8A /* XCTest.framework */, 116 | 79DFEF372288B12E00CF65D5 /* Quick.framework */, 117 | 79DFEF352288B12200CF65D5 /* Nimble.framework */, 118 | ); 119 | name = Frameworks; 120 | sourceTree = ""; 121 | }; 122 | 79DFEF392289297F00CF65D5 /* Classes */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 79DFEF3A2289297F00CF65D5 /* AnalyzeLeak.swift */, 126 | 79DFEF3C2289297F00CF65D5 /* Matchers.swift */, 127 | 79DFEF3D2289297F00CF65D5 /* LeaksAnalyzer.swift */, 128 | 79DFEF3E2289297F00CF65D5 /* LeakTest.swift */, 129 | 79DFEF3F2289297F00CF65D5 /* AnalyzeLeakAction.swift */, 130 | 79DFEF402289297F00CF65D5 /* Expectation+Leaks.swift */, 131 | ); 132 | name = Classes; 133 | path = SpecLeaks/Classes; 134 | sourceTree = ""; 135 | }; 136 | /* End PBXGroup section */ 137 | 138 | /* Begin PBXHeadersBuildPhase section */ 139 | 79D836DE2288AC7D00A5D942 /* Headers */ = { 140 | isa = PBXHeadersBuildPhase; 141 | buildActionMask = 2147483647; 142 | files = ( 143 | 79D836F42288AC7D00A5D942 /* SpecLeaks.h in Headers */, 144 | ); 145 | runOnlyForDeploymentPostprocessing = 0; 146 | }; 147 | /* End PBXHeadersBuildPhase section */ 148 | 149 | /* Begin PBXNativeTarget section */ 150 | 79D836E22288AC7D00A5D942 /* SpecLeaks */ = { 151 | isa = PBXNativeTarget; 152 | buildConfigurationList = 79D836F72288AC7D00A5D942 /* Build configuration list for PBXNativeTarget "SpecLeaks" */; 153 | buildPhases = ( 154 | 79D836DE2288AC7D00A5D942 /* Headers */, 155 | 79D836DF2288AC7D00A5D942 /* Sources */, 156 | 79D836E02288AC7D00A5D942 /* Frameworks */, 157 | 79D836E12288AC7D00A5D942 /* Resources */, 158 | ); 159 | buildRules = ( 160 | ); 161 | dependencies = ( 162 | ); 163 | name = SpecLeaks; 164 | productName = SpecLeaks; 165 | productReference = 79D836E32288AC7D00A5D942 /* SpecLeaks.framework */; 166 | productType = "com.apple.product-type.framework"; 167 | }; 168 | 79D836EB2288AC7D00A5D942 /* SpecLeaksTests */ = { 169 | isa = PBXNativeTarget; 170 | buildConfigurationList = 79D836FA2288AC7D00A5D942 /* Build configuration list for PBXNativeTarget "SpecLeaksTests" */; 171 | buildPhases = ( 172 | 79D836E82288AC7D00A5D942 /* Sources */, 173 | 79D836E92288AC7D00A5D942 /* Frameworks */, 174 | 79D836EA2288AC7D00A5D942 /* Resources */, 175 | ); 176 | buildRules = ( 177 | ); 178 | dependencies = ( 179 | 79D836EF2288AC7D00A5D942 /* PBXTargetDependency */, 180 | ); 181 | name = SpecLeaksTests; 182 | productName = SpecLeaksTests; 183 | productReference = 79D836EC2288AC7D00A5D942 /* SpecLeaksTests.xctest */; 184 | productType = "com.apple.product-type.bundle.unit-test"; 185 | }; 186 | /* End PBXNativeTarget section */ 187 | 188 | /* Begin PBXProject section */ 189 | 79D836DA2288AC7D00A5D942 /* Project object */ = { 190 | isa = PBXProject; 191 | attributes = { 192 | LastSwiftUpdateCheck = 1010; 193 | LastUpgradeCheck = 1010; 194 | ORGANIZATIONNAME = com.lmp.specleaks; 195 | TargetAttributes = { 196 | 79D836E22288AC7D00A5D942 = { 197 | CreatedOnToolsVersion = 10.1; 198 | }; 199 | 79D836EB2288AC7D00A5D942 = { 200 | CreatedOnToolsVersion = 10.1; 201 | }; 202 | }; 203 | }; 204 | buildConfigurationList = 79D836DD2288AC7D00A5D942 /* Build configuration list for PBXProject "SpecLeaks" */; 205 | compatibilityVersion = "Xcode 9.3"; 206 | developmentRegion = en; 207 | hasScannedForEncodings = 0; 208 | knownRegions = ( 209 | en, 210 | ); 211 | mainGroup = 79D836D92288AC7D00A5D942; 212 | productRefGroup = 79D836E42288AC7D00A5D942 /* Products */; 213 | projectDirPath = ""; 214 | projectRoot = ""; 215 | targets = ( 216 | 79D836E22288AC7D00A5D942 /* SpecLeaks */, 217 | 79D836EB2288AC7D00A5D942 /* SpecLeaksTests */, 218 | ); 219 | }; 220 | /* End PBXProject section */ 221 | 222 | /* Begin PBXResourcesBuildPhase section */ 223 | 79D836E12288AC7D00A5D942 /* Resources */ = { 224 | isa = PBXResourcesBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | 79D836EA2288AC7D00A5D942 /* Resources */ = { 231 | isa = PBXResourcesBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | /* End PBXResourcesBuildPhase section */ 238 | 239 | /* Begin PBXSourcesBuildPhase section */ 240 | 79D836DF2288AC7D00A5D942 /* Sources */ = { 241 | isa = PBXSourcesBuildPhase; 242 | buildActionMask = 2147483647; 243 | files = ( 244 | 79DFEF442289297F00CF65D5 /* LeaksAnalyzer.swift in Sources */, 245 | 79DFEF472289297F00CF65D5 /* Expectation+Leaks.swift in Sources */, 246 | 79DFEF432289297F00CF65D5 /* Matchers.swift in Sources */, 247 | 79DFEF462289297F00CF65D5 /* AnalyzeLeakAction.swift in Sources */, 248 | 79DFEF452289297F00CF65D5 /* LeakTest.swift in Sources */, 249 | 79DFEF412289297F00CF65D5 /* AnalyzeLeak.swift in Sources */, 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | }; 253 | 79D836E82288AC7D00A5D942 /* Sources */ = { 254 | isa = PBXSourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | 79D836F22288AC7D00A5D942 /* SpecLeaksTests.swift in Sources */, 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | /* End PBXSourcesBuildPhase section */ 262 | 263 | /* Begin PBXTargetDependency section */ 264 | 79D836EF2288AC7D00A5D942 /* PBXTargetDependency */ = { 265 | isa = PBXTargetDependency; 266 | target = 79D836E22288AC7D00A5D942 /* SpecLeaks */; 267 | targetProxy = 79D836EE2288AC7D00A5D942 /* PBXContainerItemProxy */; 268 | }; 269 | /* End PBXTargetDependency section */ 270 | 271 | /* Begin XCBuildConfiguration section */ 272 | 79D836F52288AC7D00A5D942 /* Debug */ = { 273 | isa = XCBuildConfiguration; 274 | buildSettings = { 275 | ALWAYS_SEARCH_USER_PATHS = NO; 276 | CLANG_ANALYZER_NONNULL = YES; 277 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 278 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 279 | CLANG_CXX_LIBRARY = "libc++"; 280 | CLANG_ENABLE_MODULES = YES; 281 | CLANG_ENABLE_OBJC_ARC = YES; 282 | CLANG_ENABLE_OBJC_WEAK = YES; 283 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 284 | CLANG_WARN_BOOL_CONVERSION = YES; 285 | CLANG_WARN_COMMA = YES; 286 | CLANG_WARN_CONSTANT_CONVERSION = YES; 287 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 288 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 289 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 290 | CLANG_WARN_EMPTY_BODY = YES; 291 | CLANG_WARN_ENUM_CONVERSION = YES; 292 | CLANG_WARN_INFINITE_RECURSION = YES; 293 | CLANG_WARN_INT_CONVERSION = YES; 294 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 295 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 296 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 297 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 298 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 299 | CLANG_WARN_STRICT_PROTOTYPES = YES; 300 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 301 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 302 | CLANG_WARN_UNREACHABLE_CODE = YES; 303 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 304 | CODE_SIGN_IDENTITY = "iPhone Developer"; 305 | COPY_PHASE_STRIP = NO; 306 | CURRENT_PROJECT_VERSION = 1; 307 | DEBUG_INFORMATION_FORMAT = dwarf; 308 | ENABLE_BITCODE = NO; 309 | ENABLE_STRICT_OBJC_MSGSEND = YES; 310 | ENABLE_TESTABILITY = YES; 311 | GCC_C_LANGUAGE_STANDARD = gnu11; 312 | GCC_DYNAMIC_NO_PIC = NO; 313 | GCC_NO_COMMON_BLOCKS = YES; 314 | GCC_OPTIMIZATION_LEVEL = 0; 315 | GCC_PREPROCESSOR_DEFINITIONS = ( 316 | "DEBUG=1", 317 | "$(inherited)", 318 | ); 319 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 320 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 321 | GCC_WARN_UNDECLARED_SELECTOR = YES; 322 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 323 | GCC_WARN_UNUSED_FUNCTION = YES; 324 | GCC_WARN_UNUSED_VARIABLE = YES; 325 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 326 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 327 | MTL_FAST_MATH = YES; 328 | ONLY_ACTIVE_ARCH = YES; 329 | SDKROOT = iphoneos; 330 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 331 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 332 | VERSIONING_SYSTEM = "apple-generic"; 333 | VERSION_INFO_PREFIX = ""; 334 | }; 335 | name = Debug; 336 | }; 337 | 79D836F62288AC7D00A5D942 /* Release */ = { 338 | isa = XCBuildConfiguration; 339 | buildSettings = { 340 | ALWAYS_SEARCH_USER_PATHS = NO; 341 | CLANG_ANALYZER_NONNULL = YES; 342 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 343 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 344 | CLANG_CXX_LIBRARY = "libc++"; 345 | CLANG_ENABLE_MODULES = YES; 346 | CLANG_ENABLE_OBJC_ARC = YES; 347 | CLANG_ENABLE_OBJC_WEAK = YES; 348 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 349 | CLANG_WARN_BOOL_CONVERSION = YES; 350 | CLANG_WARN_COMMA = YES; 351 | CLANG_WARN_CONSTANT_CONVERSION = YES; 352 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 354 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 355 | CLANG_WARN_EMPTY_BODY = YES; 356 | CLANG_WARN_ENUM_CONVERSION = YES; 357 | CLANG_WARN_INFINITE_RECURSION = YES; 358 | CLANG_WARN_INT_CONVERSION = YES; 359 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 360 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 361 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 362 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 363 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 364 | CLANG_WARN_STRICT_PROTOTYPES = YES; 365 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 366 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 367 | CLANG_WARN_UNREACHABLE_CODE = YES; 368 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 369 | CODE_SIGN_IDENTITY = "iPhone Developer"; 370 | COPY_PHASE_STRIP = NO; 371 | CURRENT_PROJECT_VERSION = 1; 372 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 373 | ENABLE_BITCODE = NO; 374 | ENABLE_NS_ASSERTIONS = NO; 375 | ENABLE_STRICT_OBJC_MSGSEND = YES; 376 | GCC_C_LANGUAGE_STANDARD = gnu11; 377 | GCC_NO_COMMON_BLOCKS = YES; 378 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 379 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 380 | GCC_WARN_UNDECLARED_SELECTOR = YES; 381 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 382 | GCC_WARN_UNUSED_FUNCTION = YES; 383 | GCC_WARN_UNUSED_VARIABLE = YES; 384 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 385 | MTL_ENABLE_DEBUG_INFO = NO; 386 | MTL_FAST_MATH = YES; 387 | SDKROOT = iphoneos; 388 | SWIFT_COMPILATION_MODE = wholemodule; 389 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 390 | VALIDATE_PRODUCT = YES; 391 | VERSIONING_SYSTEM = "apple-generic"; 392 | VERSION_INFO_PREFIX = ""; 393 | }; 394 | name = Release; 395 | }; 396 | 79D836F82288AC7D00A5D942 /* Debug */ = { 397 | isa = XCBuildConfiguration; 398 | buildSettings = { 399 | CODE_SIGN_IDENTITY = ""; 400 | CODE_SIGN_STYLE = Automatic; 401 | DEFINES_MODULE = YES; 402 | DYLIB_COMPATIBILITY_VERSION = 1; 403 | DYLIB_CURRENT_VERSION = 1; 404 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 405 | ENABLE_BITCODE = NO; 406 | FRAMEWORK_SEARCH_PATHS = ( 407 | "$(inherited)", 408 | "$(PROJECT_DIR)/Carthage/Build/iOS", 409 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 410 | ); 411 | INFOPLIST_FILE = SpecLeaks/Info.plist; 412 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 413 | LD_RUNPATH_SEARCH_PATHS = ( 414 | "$(inherited)", 415 | "@executable_path/Frameworks", 416 | "@loader_path/Frameworks", 417 | ); 418 | PRODUCT_BUNDLE_IDENTIFIER = com.lmp.specleaks.SpecLeaks; 419 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 420 | SKIP_INSTALL = YES; 421 | SWIFT_VERSION = 4.2; 422 | TARGETED_DEVICE_FAMILY = "1,2"; 423 | }; 424 | name = Debug; 425 | }; 426 | 79D836F92288AC7D00A5D942 /* Release */ = { 427 | isa = XCBuildConfiguration; 428 | buildSettings = { 429 | CODE_SIGN_IDENTITY = ""; 430 | CODE_SIGN_STYLE = Automatic; 431 | DEFINES_MODULE = YES; 432 | DYLIB_COMPATIBILITY_VERSION = 1; 433 | DYLIB_CURRENT_VERSION = 1; 434 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 435 | ENABLE_BITCODE = NO; 436 | FRAMEWORK_SEARCH_PATHS = ( 437 | "$(inherited)", 438 | "$(PROJECT_DIR)/Carthage/Build/iOS", 439 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 440 | ); 441 | INFOPLIST_FILE = SpecLeaks/Info.plist; 442 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 443 | LD_RUNPATH_SEARCH_PATHS = ( 444 | "$(inherited)", 445 | "@executable_path/Frameworks", 446 | "@loader_path/Frameworks", 447 | ); 448 | PRODUCT_BUNDLE_IDENTIFIER = com.lmp.specleaks.SpecLeaks; 449 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 450 | SKIP_INSTALL = YES; 451 | SWIFT_VERSION = 4.2; 452 | TARGETED_DEVICE_FAMILY = "1,2"; 453 | }; 454 | name = Release; 455 | }; 456 | 79D836FB2288AC7D00A5D942 /* Debug */ = { 457 | isa = XCBuildConfiguration; 458 | buildSettings = { 459 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 460 | CODE_SIGN_STYLE = Automatic; 461 | INFOPLIST_FILE = SpecLeaksTests/Info.plist; 462 | LD_RUNPATH_SEARCH_PATHS = ( 463 | "$(inherited)", 464 | "@executable_path/Frameworks", 465 | "@loader_path/Frameworks", 466 | ); 467 | PRODUCT_BUNDLE_IDENTIFIER = com.lmp.specleaks.SpecLeaksTests; 468 | PRODUCT_NAME = "$(TARGET_NAME)"; 469 | SWIFT_VERSION = 4.2; 470 | TARGETED_DEVICE_FAMILY = "1,2"; 471 | }; 472 | name = Debug; 473 | }; 474 | 79D836FC2288AC7D00A5D942 /* Release */ = { 475 | isa = XCBuildConfiguration; 476 | buildSettings = { 477 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 478 | CODE_SIGN_STYLE = Automatic; 479 | INFOPLIST_FILE = SpecLeaksTests/Info.plist; 480 | LD_RUNPATH_SEARCH_PATHS = ( 481 | "$(inherited)", 482 | "@executable_path/Frameworks", 483 | "@loader_path/Frameworks", 484 | ); 485 | PRODUCT_BUNDLE_IDENTIFIER = com.lmp.specleaks.SpecLeaksTests; 486 | PRODUCT_NAME = "$(TARGET_NAME)"; 487 | SWIFT_VERSION = 4.2; 488 | TARGETED_DEVICE_FAMILY = "1,2"; 489 | }; 490 | name = Release; 491 | }; 492 | /* End XCBuildConfiguration section */ 493 | 494 | /* Begin XCConfigurationList section */ 495 | 79D836DD2288AC7D00A5D942 /* Build configuration list for PBXProject "SpecLeaks" */ = { 496 | isa = XCConfigurationList; 497 | buildConfigurations = ( 498 | 79D836F52288AC7D00A5D942 /* Debug */, 499 | 79D836F62288AC7D00A5D942 /* Release */, 500 | ); 501 | defaultConfigurationIsVisible = 0; 502 | defaultConfigurationName = Release; 503 | }; 504 | 79D836F72288AC7D00A5D942 /* Build configuration list for PBXNativeTarget "SpecLeaks" */ = { 505 | isa = XCConfigurationList; 506 | buildConfigurations = ( 507 | 79D836F82288AC7D00A5D942 /* Debug */, 508 | 79D836F92288AC7D00A5D942 /* Release */, 509 | ); 510 | defaultConfigurationIsVisible = 0; 511 | defaultConfigurationName = Release; 512 | }; 513 | 79D836FA2288AC7D00A5D942 /* Build configuration list for PBXNativeTarget "SpecLeaksTests" */ = { 514 | isa = XCConfigurationList; 515 | buildConfigurations = ( 516 | 79D836FB2288AC7D00A5D942 /* Debug */, 517 | 79D836FC2288AC7D00A5D942 /* Release */, 518 | ); 519 | defaultConfigurationIsVisible = 0; 520 | defaultConfigurationName = Release; 521 | }; 522 | /* End XCConfigurationList section */ 523 | }; 524 | rootObject = 79D836DA2288AC7D00A5D942 /* Project object */; 525 | } 526 | -------------------------------------------------------------------------------- /SpecLeaks.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SpecLeaks.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SpecLeaks.xcodeproj/xcshareddata/xcschemes/SpecLeaks.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /SpecLeaks/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leandromperez/specleaks/eff9c85401b5fe380ed0faca216fce18b672e641/SpecLeaks/Assets/.gitkeep -------------------------------------------------------------------------------- /SpecLeaks/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leandromperez/specleaks/eff9c85401b5fe380ed0faca216fce18b672e641/SpecLeaks/Classes/.gitkeep -------------------------------------------------------------------------------- /SpecLeaks/Classes/AnalyzeLeak.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnalyzeLeak.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 03/02/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | #if os(iOS) || os(watchOS) || os(tvOS) 12 | import UIKit 13 | public typealias OSViewController = UIViewController 14 | #elseif os(macOS) 15 | import Cocoa 16 | public typealias OSViewController = NSViewController 17 | #endif 18 | 19 | import Quick 20 | import Nimble 21 | 22 | func view(_ vc: AnyObject?) { 23 | if let vc = vc as? OSViewController { 24 | _ = vc.view //To call viewDidLoad on the vc 25 | } 26 | } 27 | 28 | public func getOSViewController() -> OSViewController { 29 | return OSViewController() 30 | } 31 | 32 | struct AnalyzeLeak { 33 | func execute( constructor: LeakTestConstructor, shouldLeak: Bool = false ) { 34 | 35 | var mayBeLeaking: AnyObject? 36 | let leaksAnalyzer = LeaksAnalyzer() 37 | 38 | autoreleasepool { 39 | leaksAnalyzer.leakedObject = nil 40 | 41 | mayBeLeaking = constructor() 42 | 43 | view(mayBeLeaking) 44 | 45 | leaksAnalyzer.analize(mayBeLeaking!) 46 | mayBeLeaking = nil 47 | } 48 | 49 | if shouldLeak { 50 | expect(leaksAnalyzer.leakedObject).toEventuallyNot(beNil()) 51 | } else { 52 | expect(leaksAnalyzer.leakedObject).toEventually(beNil()) 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /SpecLeaks/Classes/AnalyzeLeakAction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnalyzeLeakAction.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 03/02/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | #if os(iOS) || os(watchOS) || os(tvOS) 11 | import UIKit 12 | #elseif os(macOS) 13 | import Cocoa 14 | #endif 15 | 16 | import Quick 17 | import Nimble 18 | 19 | struct AnalyzeLeakAction { 20 | func execute(constructor:() -> T, action: (T)->Void, shouldLeak: Bool = false) where T: AnyObject { 21 | 22 | var mayBeLeaking: T? 23 | let leaksAnalyzer = LeaksAnalyzer() 24 | 25 | autoreleasepool { 26 | 27 | leaksAnalyzer.leakedObject = nil 28 | 29 | //Instantiate the object that will be analyzed 30 | mayBeLeaking = constructor() 31 | 32 | //To call viewDidLoad on the vc 33 | view(mayBeLeaking) 34 | 35 | leaksAnalyzer.analize(mayBeLeaking!) 36 | 37 | //Run the action that will be analyzed 38 | action(mayBeLeaking!) 39 | 40 | //Set to nil. If the analyzer still has an instance, that's a leak 41 | mayBeLeaking = nil 42 | } 43 | 44 | if shouldLeak { 45 | expect(leaksAnalyzer.leakedObject).toEventuallyNot(beNil()) 46 | } else { 47 | expect(leaksAnalyzer.leakedObject).toEventually(beNil()) 48 | } 49 | } 50 | 51 | func execute(constructor:() -> T, action: (T)->Any, shouldLeak: Bool = false) where T: AnyObject { 52 | 53 | var mayBeLeaking: T? 54 | let leaksAnalyzer = LeaksAnalyzer() 55 | 56 | var resultThatMightCauseLeak: Any? = nil 57 | 58 | autoreleasepool { 59 | 60 | leaksAnalyzer.leakedObject = nil 61 | 62 | //Instantiate the object that will be analyzed 63 | mayBeLeaking = constructor() 64 | 65 | //To call viewDidLoad on the vc 66 | view(mayBeLeaking) 67 | 68 | leaksAnalyzer.analize(mayBeLeaking!) 69 | 70 | //Run the action that will be analyzed 71 | 72 | resultThatMightCauseLeak = action(mayBeLeaking!) 73 | 74 | //Set to nil. If the analyzer still has an instance, that's a leak 75 | mayBeLeaking = nil 76 | } 77 | 78 | if shouldLeak { 79 | expect(leaksAnalyzer.leakedObject).toEventuallyNot(beNil()) 80 | } else { 81 | expect(resultThatMightCauseLeak).toNot(beNil()) 82 | expect(leaksAnalyzer.leakedObject).toEventually(beNil()) 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /SpecLeaks/Classes/Expectation+Leaks.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Expectation+Leaks.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 03/02/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Nimble 11 | 12 | public typealias LeakTestConstructor = () -> AnyObject 13 | 14 | extension Expectation where T==LeakTestConstructor { 15 | 16 | public func toNotLeak(timeout: DispatchTimeInterval = AsyncDefaults.timeout, pollInterval: DispatchTimeInterval = AsyncDefaults.pollInterval, description: String? = nil, shouldFail: Bool = false) { 17 | do { 18 | guard let constructor = try expression.evaluate() else { 19 | fail() 20 | return 21 | } 22 | AnalyzeLeak().execute(constructor: constructor, shouldLeak: shouldFail) 23 | } catch { 24 | fail() 25 | } 26 | } 27 | 28 | public func toLeak() { 29 | self.toNotLeak(timeout: AsyncDefaults.timeout, pollInterval: AsyncDefaults.pollInterval, description: nil, shouldFail: true) 30 | } 31 | 32 | public func toNotLeakWhen

( shouldFail: Bool = false, _ action: (P)->Void) where P: AnyObject { 33 | do { 34 | guard let constructor = try expression.evaluate() else { 35 | fail() 36 | return 37 | } 38 | let castedConstructor : () -> P = { constructor() as! P } 39 | 40 | AnalyzeLeakAction().execute(constructor: castedConstructor, action: action, shouldLeak: shouldFail) 41 | } catch { 42 | fail() 43 | } 44 | } 45 | 46 | public func toLeakWhen

(shouldFail: Bool = false, _ action: (P)->Void) where P: AnyObject { 47 | self.toNotLeakWhen(shouldFail: true, action) 48 | } 49 | 50 | public func toNotLeakWhen

( shouldFail: Bool = false, _ action: (P)->Any) where P: AnyObject { 51 | do { 52 | guard let constructor = try expression.evaluate() else { 53 | fail() 54 | return 55 | } 56 | let castedConstructor : () -> P = { constructor() as! P } 57 | 58 | AnalyzeLeakAction().execute(constructor: castedConstructor, action: action, shouldLeak: shouldFail) 59 | } catch { 60 | fail() 61 | } 62 | } 63 | 64 | public func toLeakWhen

(shouldFail: Bool = false, _ action: (P)->Any) where P: AnyObject { 65 | self.toNotLeakWhen(shouldFail: true, action) 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /SpecLeaks/Classes/LeakTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeakTest.swift 3 | // Nimble 4 | // 5 | // Created by Leandro Perez on 01/04/2018. 6 | // 7 | 8 | import Foundation 9 | import Quick 10 | import Nimble 11 | 12 | //public typealias LeakTestConstructor = () -> AnyObject 13 | 14 | public struct LeakTest { 15 | let constructor: LeakTestConstructor 16 | 17 | public init(constructor:@escaping LeakTestConstructor) { 18 | self.constructor = constructor 19 | } 20 | 21 | internal func isLeaking() -> Bool { 22 | weak var leaked: AnyObject? = nil 23 | 24 | autoreleasepool { 25 | 26 | var evaluated: AnyObject? = self.constructor() 27 | 28 | //To call viewDidLoad on the vc 29 | view(evaluated) 30 | 31 | leaked = evaluated 32 | evaluated = nil 33 | } 34 | 35 | return leaked != nil 36 | } 37 | 38 | internal func isLeaking

( when action: (P) -> Any) -> PredicateStatus where P: AnyObject { 39 | weak var leaked: AnyObject? = nil 40 | 41 | var failed = false 42 | var actionResult: Any? = nil 43 | 44 | autoreleasepool { 45 | 46 | var evaluated: P? = self.constructor() as? P 47 | 48 | if evaluated == nil { 49 | failed = true 50 | } else { 51 | actionResult = action(evaluated!) 52 | 53 | //To call viewDidLoad on the vc 54 | view(evaluated) 55 | 56 | leaked = evaluated 57 | evaluated = nil 58 | } 59 | } 60 | 61 | if failed || actionResult == nil { 62 | return PredicateStatus.fail 63 | } 64 | 65 | return PredicateStatus.init(bool: leaked != nil) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /SpecLeaks/Classes/LeaksAnalyzer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LeaksAnalyzer.swift 3 | // UnitTestLeaks 4 | // 5 | // Created by Leandro Perez on 03/02/2018. 6 | // Copyright © 2018 Leandro Perez. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class LeaksAnalyzer { 12 | weak var leakedObject: AnyObject? 13 | 14 | func analize(_ leakingObject: AnyObject) { 15 | self.leakedObject = leakingObject 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SpecLeaks/Classes/Matchers.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Matchers.swift 3 | // Nimble 4 | // 5 | // Created by Leandro Perez on 01/04/2018. 6 | // 7 | 8 | import Foundation 9 | import Quick 10 | import Nimble 11 | 12 | public func leak() -> Predicate { 13 | 14 | return Predicate.simple("leak") { expression in 15 | 16 | guard let leakTest = try expression.evaluate() else { 17 | return PredicateStatus.fail 18 | } 19 | 20 | return PredicateStatus(bool: leakTest.isLeaking()) 21 | } 22 | } 23 | 24 | public func leakWhen

(_ action : @escaping (P) -> Any) -> Predicate where P: AnyObject { 25 | 26 | return Predicate.simple("leak when") { expression in 27 | 28 | guard let leakTest = try expression.evaluate() else { 29 | return PredicateStatus.fail 30 | } 31 | 32 | return leakTest.isLeaking(when: action) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SpecLeaks/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 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /SpecLeaks/SpecLeaks.h: -------------------------------------------------------------------------------- 1 | // 2 | // SpecLeaks.h 3 | // SpecLeaks 4 | // 5 | // Created by Ruiz, Josué on 5/12/19. 6 | // Copyright © 2019 com.lmp.specleaks. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SpecLeaks. 12 | FOUNDATION_EXPORT double SpecLeaksVersionNumber; 13 | 14 | //! Project version string for SpecLeaks. 15 | FOUNDATION_EXPORT const unsigned char SpecLeaksVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /SpecLeaksTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SpecLeaksTests/SpecLeaksTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpecLeaksTests.swift 3 | // SpecLeaksTests 4 | // 5 | // Created by Ruiz, Josué on 5/12/19. 6 | // Copyright © 2019 com.lmp.specleaks. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import SpecLeaks 11 | 12 | class SpecLeaksTests: XCTestCase { 13 | 14 | override func setUp() { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leandromperez/specleaks/eff9c85401b5fe380ed0faca216fce18b672e641/twitter.png --------------------------------------------------------------------------------