├── .github
└── workflows
│ └── ci.yaml
├── .gitignore
├── BUILD
├── Example
├── PINFuture.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── PINFuture-Example.xcscheme
├── PINFuture.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── PINFuture
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Launch Screen.storyboard
│ ├── Main.storyboard
│ ├── PINAppDelegate.h
│ ├── PINAppDelegate.m
│ ├── PINFuture-Info.plist
│ ├── PINFuture-Prefix.pch
│ ├── PINViewController.h
│ ├── PINViewController.m
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ └── main.m
├── Podfile
├── Podfile.lock
├── Pods
│ ├── Expecta
│ │ ├── Expecta
│ │ │ ├── EXPBlockDefinedMatcher.h
│ │ │ ├── EXPBlockDefinedMatcher.m
│ │ │ ├── EXPDefines.h
│ │ │ ├── EXPDoubleTuple.h
│ │ │ ├── EXPDoubleTuple.m
│ │ │ ├── EXPExpect.h
│ │ │ ├── EXPExpect.m
│ │ │ ├── EXPFloatTuple.h
│ │ │ ├── EXPFloatTuple.m
│ │ │ ├── EXPMatcher.h
│ │ │ ├── EXPUnsupportedObject.h
│ │ │ ├── EXPUnsupportedObject.m
│ │ │ ├── Expecta.h
│ │ │ ├── ExpectaObject.h
│ │ │ ├── ExpectaObject.m
│ │ │ ├── ExpectaSupport.h
│ │ │ ├── ExpectaSupport.m
│ │ │ ├── Matchers
│ │ │ │ ├── EXPMatcherHelpers.h
│ │ │ │ ├── EXPMatcherHelpers.m
│ │ │ │ ├── EXPMatchers+beCloseTo.h
│ │ │ │ ├── EXPMatchers+beCloseTo.m
│ │ │ │ ├── EXPMatchers+beFalsy.h
│ │ │ │ ├── EXPMatchers+beFalsy.m
│ │ │ │ ├── EXPMatchers+beGreaterThan.h
│ │ │ │ ├── EXPMatchers+beGreaterThan.m
│ │ │ │ ├── EXPMatchers+beGreaterThanOrEqualTo.h
│ │ │ │ ├── EXPMatchers+beGreaterThanOrEqualTo.m
│ │ │ │ ├── EXPMatchers+beIdenticalTo.h
│ │ │ │ ├── EXPMatchers+beIdenticalTo.m
│ │ │ │ ├── EXPMatchers+beInTheRangeOf.h
│ │ │ │ ├── EXPMatchers+beInTheRangeOf.m
│ │ │ │ ├── EXPMatchers+beInstanceOf.h
│ │ │ │ ├── EXPMatchers+beInstanceOf.m
│ │ │ │ ├── EXPMatchers+beKindOf.h
│ │ │ │ ├── EXPMatchers+beKindOf.m
│ │ │ │ ├── EXPMatchers+beLessThan.h
│ │ │ │ ├── EXPMatchers+beLessThan.m
│ │ │ │ ├── EXPMatchers+beLessThanOrEqualTo.h
│ │ │ │ ├── EXPMatchers+beLessThanOrEqualTo.m
│ │ │ │ ├── EXPMatchers+beNil.h
│ │ │ │ ├── EXPMatchers+beNil.m
│ │ │ │ ├── EXPMatchers+beSubclassOf.h
│ │ │ │ ├── EXPMatchers+beSubclassOf.m
│ │ │ │ ├── EXPMatchers+beSupersetOf.h
│ │ │ │ ├── EXPMatchers+beSupersetOf.m
│ │ │ │ ├── EXPMatchers+beTruthy.h
│ │ │ │ ├── EXPMatchers+beTruthy.m
│ │ │ │ ├── EXPMatchers+beginWith.h
│ │ │ │ ├── EXPMatchers+beginWith.m
│ │ │ │ ├── EXPMatchers+conformTo.h
│ │ │ │ ├── EXPMatchers+conformTo.m
│ │ │ │ ├── EXPMatchers+contain.h
│ │ │ │ ├── EXPMatchers+contain.m
│ │ │ │ ├── EXPMatchers+endWith.h
│ │ │ │ ├── EXPMatchers+endWith.m
│ │ │ │ ├── EXPMatchers+equal.h
│ │ │ │ ├── EXPMatchers+equal.m
│ │ │ │ ├── EXPMatchers+haveCountOf.h
│ │ │ │ ├── EXPMatchers+haveCountOf.m
│ │ │ │ ├── EXPMatchers+match.h
│ │ │ │ ├── EXPMatchers+match.m
│ │ │ │ ├── EXPMatchers+postNotification.h
│ │ │ │ ├── EXPMatchers+postNotification.m
│ │ │ │ ├── EXPMatchers+raise.h
│ │ │ │ ├── EXPMatchers+raise.m
│ │ │ │ ├── EXPMatchers+raiseWithReason.h
│ │ │ │ ├── EXPMatchers+raiseWithReason.m
│ │ │ │ ├── EXPMatchers+respondTo.h
│ │ │ │ ├── EXPMatchers+respondTo.m
│ │ │ │ └── EXPMatchers.h
│ │ │ ├── NSObject+Expecta.h
│ │ │ ├── NSValue+Expecta.h
│ │ │ └── NSValue+Expecta.m
│ │ ├── LICENSE
│ │ └── README.md
│ ├── Local Podspecs
│ │ └── PINFuture.podspec.json
│ ├── Manifest.lock
│ ├── Pods.xcodeproj
│ │ └── project.pbxproj
│ ├── Specta
│ │ ├── LICENSE
│ │ ├── README.md
│ │ └── Specta
│ │ │ └── Specta
│ │ │ ├── SPTCallSite.h
│ │ │ ├── SPTCallSite.m
│ │ │ ├── SPTCompiledExample.h
│ │ │ ├── SPTCompiledExample.m
│ │ │ ├── SPTExample.h
│ │ │ ├── SPTExample.m
│ │ │ ├── SPTExampleGroup.h
│ │ │ ├── SPTExampleGroup.m
│ │ │ ├── SPTExcludeGlobalBeforeAfterEach.h
│ │ │ ├── SPTGlobalBeforeAfterEach.h
│ │ │ ├── SPTSharedExampleGroups.h
│ │ │ ├── SPTSharedExampleGroups.m
│ │ │ ├── SPTSpec.h
│ │ │ ├── SPTSpec.m
│ │ │ ├── SPTTestSuite.h
│ │ │ ├── SPTTestSuite.m
│ │ │ ├── Specta.h
│ │ │ ├── SpectaDSL.h
│ │ │ ├── SpectaDSL.m
│ │ │ ├── SpectaTypes.h
│ │ │ ├── SpectaUtility.h
│ │ │ ├── SpectaUtility.m
│ │ │ ├── XCTest+Private.h
│ │ │ ├── XCTestCase+Specta.h
│ │ │ └── XCTestCase+Specta.m
│ └── Target Support Files
│ │ ├── Expecta
│ │ ├── Expecta-Info.plist
│ │ ├── Expecta-dummy.m
│ │ ├── Expecta-prefix.pch
│ │ ├── Expecta-umbrella.h
│ │ ├── Expecta.debug.xcconfig
│ │ ├── Expecta.modulemap
│ │ ├── Expecta.release.xcconfig
│ │ ├── Expecta.xcconfig
│ │ └── Info.plist
│ │ ├── PINFuture
│ │ ├── Info.plist
│ │ ├── PINFuture-Info.plist
│ │ ├── PINFuture-dummy.m
│ │ ├── PINFuture-prefix.pch
│ │ ├── PINFuture-umbrella.h
│ │ ├── PINFuture.debug.xcconfig
│ │ ├── PINFuture.modulemap
│ │ ├── PINFuture.release.xcconfig
│ │ └── PINFuture.xcconfig
│ │ ├── Pods-PINFuture_Example
│ │ ├── Info.plist
│ │ ├── Pods-PINFuture_Example-Info.plist
│ │ ├── Pods-PINFuture_Example-acknowledgements.markdown
│ │ ├── Pods-PINFuture_Example-acknowledgements.plist
│ │ ├── Pods-PINFuture_Example-dummy.m
│ │ ├── Pods-PINFuture_Example-frameworks.sh
│ │ ├── Pods-PINFuture_Example-resources.sh
│ │ ├── Pods-PINFuture_Example-umbrella.h
│ │ ├── Pods-PINFuture_Example.debug.xcconfig
│ │ ├── Pods-PINFuture_Example.modulemap
│ │ └── Pods-PINFuture_Example.release.xcconfig
│ │ ├── Pods-PINFuture_Tests
│ │ ├── Info.plist
│ │ ├── Pods-PINFuture_Tests-Info.plist
│ │ ├── Pods-PINFuture_Tests-acknowledgements.markdown
│ │ ├── Pods-PINFuture_Tests-acknowledgements.plist
│ │ ├── Pods-PINFuture_Tests-dummy.m
│ │ ├── Pods-PINFuture_Tests-frameworks.sh
│ │ ├── Pods-PINFuture_Tests-resources.sh
│ │ ├── Pods-PINFuture_Tests-umbrella.h
│ │ ├── Pods-PINFuture_Tests.debug.xcconfig
│ │ ├── Pods-PINFuture_Tests.modulemap
│ │ └── Pods-PINFuture_Tests.release.xcconfig
│ │ └── Specta
│ │ ├── Info.plist
│ │ ├── Specta-Info.plist
│ │ ├── Specta-dummy.m
│ │ ├── Specta-prefix.pch
│ │ ├── Specta-umbrella.h
│ │ ├── Specta.debug.xcconfig
│ │ ├── Specta.modulemap
│ │ ├── Specta.release.xcconfig
│ │ └── Specta.xcconfig
└── Tests
│ ├── PINCancelTokenTests.m
│ ├── PINFuture+ChainSideEffectTests.m
│ ├── PINFuture+CompletionTests.m
│ ├── PINFuture+DelayTests.m
│ ├── PINFuture+DispatchTests.m
│ ├── PINFuture+FlatMapErrorTests.m
│ ├── PINFuture+GatherAllTests.m
│ ├── PINFuture+GatherSomeTests.m
│ ├── PINFuture+MapErrorTests.m
│ ├── PINFuture+MapToValueTests.m
│ ├── PINFuture+NoValueTests.m
│ ├── PINFutureMap+FlatMapTests.m
│ ├── PINFutureMap+MapTests.m
│ ├── PINFutureOnceTests.m
│ ├── PINFuturePendingTests.m
│ ├── PINFutureStressTests.m
│ ├── PINFutureTests.m
│ ├── TestUtil.h
│ ├── TestUtil.m
│ ├── Tests-Info.plist
│ ├── Tests-Prefix.pch
│ └── en.lproj
│ └── InfoPlist.strings
├── LICENSE
├── PINFuture.podspec
├── PINFuture
├── Assets
│ └── .gitkeep
└── Classes
│ ├── .gitkeep
│ ├── Categories
│ ├── NSURLSession+PINFuture.h
│ ├── NSURLSession+PINFuture.m
│ ├── PHImageManager+PINFuture.h
│ ├── PHImageManager+PINFuture.m
│ ├── PINNSURLSessionDataTaskAndResult.h
│ ├── PINNSURLSessionDataTaskAndResult.m
│ ├── PINNSURLSessionDataTaskResult.h
│ ├── PINNSURLSessionDataTaskResult.m
│ ├── PINPHImageManagerImageDataResult.h
│ └── PINPHImageManagerImageDataResult.m
│ ├── PINCancelToken.h
│ ├── PINCancelToken.m
│ ├── PINDefines.h
│ ├── PINExecutor.h
│ ├── PINExecutor.m
│ ├── PINFuture+ChainSideEffect.h
│ ├── PINFuture+ChainSideEffect.m
│ ├── PINFuture+Completion.h
│ ├── PINFuture+Completion.m
│ ├── PINFuture+Delay.h
│ ├── PINFuture+Delay.m
│ ├── PINFuture+Dispatch.h
│ ├── PINFuture+Dispatch.m
│ ├── PINFuture+FlatMapError.h
│ ├── PINFuture+FlatMapError.m
│ ├── PINFuture+GatherAll.h
│ ├── PINFuture+GatherAll.m
│ ├── PINFuture+GatherSome.h
│ ├── PINFuture+GatherSome.m
│ ├── PINFuture+Generated.h
│ ├── PINFuture+Generated.m
│ ├── PINFuture+MapError.h
│ ├── PINFuture+MapError.m
│ ├── PINFuture+MapToValue.h
│ ├── PINFuture+MapToValue.m
│ ├── PINFuture+NoValue.h
│ ├── PINFuture+NoValue.m
│ ├── PINFuture.h
│ ├── PINFutureAndCancelToken.h
│ ├── PINFutureAndCancelToken.m
│ ├── PINFutureDefinition.h
│ ├── PINFutureDefinition.m
│ ├── PINFutureError.h
│ ├── PINFutureError.m
│ ├── PINFutureMap+FlatMap.h
│ ├── PINFutureMap+FlatMap.m
│ ├── PINFutureMap+Map.h
│ ├── PINFutureMap+Map.m
│ ├── PINFutureMap.h
│ ├── PINFutureMap.m
│ ├── PINFutureOnce.h
│ ├── PINFutureOnce.m
│ ├── PINFuturePending.h
│ └── PINFuturePending.m
├── README.md
├── WORKSPACE
└── _Pods.xcodeproj
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: CI
3 |
4 | on:
5 | push:
6 | branches:
7 | - master
8 | - 'releases/*'
9 | pull_request:
10 | branches:
11 | - master
12 |
13 | jobs:
14 | build:
15 | name: Build
16 | runs-on: macOS-latest
17 | strategy:
18 | matrix:
19 | platform: ['iOS Simulator,name=iPhone 8']
20 | steps:
21 | - uses: actions/checkout@v1
22 | - name: Analyze and Test
23 | run: |
24 | xcodebuild clean analyze test \
25 | -destination "platform=${{ matrix.platform }}" \
26 | -sdk "iphonesimulator" \
27 | -workspace Example/PINFuture.xcworkspace \
28 | -scheme PINFuture-Example \
29 | ONLY_ACTIVE_ARCH=NO \
30 | CODE_SIGNING_REQUIRED=NO \
31 | | xcpretty
32 | cocoapods:
33 | name: CocoaPods
34 | runs-on: macOS-latest
35 | steps:
36 | - uses: actions/checkout@v1
37 | - name: Lint
38 | run: pod lib lint
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bazel
23 | bazel-*
24 |
25 | # Bundler
26 | .bundle
27 |
28 | Carthage
29 | # We recommend against adding the Pods directory to your .gitignore. However
30 | # you should judge for yourself, the pros and cons are mentioned at:
31 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
32 | #
33 | # Note: if you ignore the Pods directory, make sure to uncomment
34 | # `pod install` in .travis.yml
35 | #
36 | # Pods/
37 |
--------------------------------------------------------------------------------
/BUILD:
--------------------------------------------------------------------------------
1 | objc_library(
2 | name = "PINFuture",
3 | hdrs = glob(["PINFuture/Classes/**/*.h"]),
4 | srcs = glob(["PINFuture/Classes/**/*.m"]),
5 | includes = [
6 | "PINFuture/Classes",
7 | "PINFuture/Classes/Categories",
8 | ],
9 | copts = ["-w"],
10 | sdk_frameworks = [
11 | "AssetsLibrary",
12 | "Photos"
13 | ],
14 | visibility = ["//visibility:public"]
15 | )
16 |
--------------------------------------------------------------------------------
/Example/PINFuture.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/PINFuture.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/PINFuture.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/PINFuture/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Example/PINFuture/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/PINFuture/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 |
--------------------------------------------------------------------------------
/Example/PINFuture/PINAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINAppDelegate.h
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/02/2016.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface PINAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/PINFuture/PINAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINAppDelegate.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/02/2016.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINAppDelegate.h"
10 |
11 | @implementation PINAppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // 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.
22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // 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.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/Example/PINFuture/PINFuture-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | Launch Screen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Example/PINFuture/PINFuture-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | @import UIKit;
15 | @import Foundation;
16 | #endif
17 |
--------------------------------------------------------------------------------
/Example/PINFuture/PINViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINViewController.h
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/02/2016.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface PINViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/PINFuture/PINViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINViewController.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/02/2016.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINViewController.h"
10 |
11 | @interface PINViewController ()
12 |
13 | @end
14 |
15 | @implementation PINViewController
16 |
17 | - (void)viewDidLoad
18 | {
19 | [super viewDidLoad];
20 | // Do any additional setup after loading the view, typically from a nib.
21 | }
22 |
23 | - (void)didReceiveMemoryWarning
24 | {
25 | [super didReceiveMemoryWarning];
26 | // Dispose of any resources that can be recreated.
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Example/PINFuture/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/PINFuture/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/02/2016.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 | #import "PINAppDelegate.h"
11 |
12 | int main(int argc, char * argv[])
13 | {
14 | @autoreleasepool {
15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([PINAppDelegate class]));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | use_frameworks!
2 |
3 | target 'PINFuture_Example' do
4 | pod 'PINFuture', :path => '../'
5 |
6 | target 'PINFuture_Tests' do
7 | inherit! :search_paths
8 |
9 | pod 'PINFuture', :path => '../'
10 | pod 'Specta'
11 | pod 'Expecta'
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/Example/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Expecta (1.0.6)
3 | - PINFuture (5.2.1)
4 | - Specta (1.0.7)
5 |
6 | DEPENDENCIES:
7 | - Expecta
8 | - PINFuture (from `../`)
9 | - Specta
10 |
11 | SPEC REPOS:
12 | trunk:
13 | - Expecta
14 | - Specta
15 |
16 | EXTERNAL SOURCES:
17 | PINFuture:
18 | :path: "../"
19 |
20 | SPEC CHECKSUMS:
21 | Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5
22 | PINFuture: a3de8180f634e6af833bf8753e7829e4e69e8f9a
23 | Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66
24 |
25 | PODFILE CHECKSUM: 699d06a490a2ae8d8e6dcf963cf46656dad30462
26 |
27 | COCOAPODS: 1.9.1
28 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPBlockDefinedMatcher.h:
--------------------------------------------------------------------------------
1 | //
2 | // EXPRuntimeMatcher.h
3 | // Expecta
4 | //
5 | // Created by Luke Redpath on 26/03/2012.
6 | // Copyright (c) 2012 Peter Jihoon Kim. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "EXPMatcher.h"
11 | #import "EXPDefines.h"
12 |
13 | @interface EXPBlockDefinedMatcher : NSObject {
14 | EXPBoolBlock prerequisiteBlock;
15 | EXPBoolBlock matchBlock;
16 | EXPStringBlock failureMessageForToBlock;
17 | EXPStringBlock failureMessageForNotToBlock;
18 | }
19 |
20 | @property(nonatomic, copy) EXPBoolBlock prerequisiteBlock;
21 | @property(nonatomic, copy) EXPBoolBlock matchBlock;
22 | @property(nonatomic, copy) EXPStringBlock failureMessageForToBlock;
23 | @property(nonatomic, copy) EXPStringBlock failureMessageForNotToBlock;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPBlockDefinedMatcher.m:
--------------------------------------------------------------------------------
1 | //
2 | // EXPRuntimeMatcher.m
3 | // Expecta
4 | //
5 | // Created by Luke Redpath on 26/03/2012.
6 | // Copyright (c) 2012 Peter Jihoon Kim. All rights reserved.
7 | //
8 |
9 | #import "EXPBlockDefinedMatcher.h"
10 |
11 | @implementation EXPBlockDefinedMatcher
12 |
13 | - (void)dealloc
14 | {
15 | self.prerequisiteBlock = nil;
16 | self.matchBlock = nil;
17 | self.failureMessageForToBlock = nil;
18 | self.failureMessageForNotToBlock = nil;
19 |
20 | [super dealloc];
21 | }
22 |
23 | @synthesize prerequisiteBlock;
24 | @synthesize matchBlock;
25 | @synthesize failureMessageForToBlock;
26 | @synthesize failureMessageForNotToBlock;
27 |
28 | - (BOOL)meetsPrerequesiteFor:(id)actual
29 | {
30 | if (self.prerequisiteBlock) {
31 | return self.prerequisiteBlock();
32 | }
33 | return YES;
34 | }
35 |
36 | - (BOOL)matches:(id)actual
37 | {
38 | if (self.matchBlock) {
39 | return self.matchBlock();
40 | }
41 | return YES;
42 | }
43 |
44 | - (NSString *)failureMessageForTo:(id)actual
45 | {
46 | if (self.failureMessageForToBlock) {
47 | return self.failureMessageForToBlock();
48 | }
49 | return nil;
50 | }
51 |
52 | - (NSString *)failureMessageForNotTo:(id)actual
53 | {
54 | if (self.failureMessageForNotToBlock) {
55 | return self.failureMessageForNotToBlock();
56 | }
57 | return nil;
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPDefines.h:
--------------------------------------------------------------------------------
1 | //
2 | // EXPDefines.h
3 | // Expecta
4 | //
5 | // Created by Luke Redpath on 26/03/2012.
6 | // Copyright (c) 2012 Peter Jihoon Kim. All rights reserved.
7 | //
8 |
9 | #ifndef Expecta_EXPDefines_h
10 | #define Expecta_EXPDefines_h
11 |
12 | typedef void (^EXPBasicBlock)(void);
13 | typedef id (^EXPIdBlock)(void);
14 | typedef BOOL (^EXPBoolBlock)(void);
15 | typedef NSString *(^EXPStringBlock)(void);
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPDoubleTuple.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface EXPDoubleTuple : NSObject {
4 | double *_values;
5 | size_t _size;
6 | }
7 |
8 | @property (nonatomic, assign) double *values;
9 | @property (nonatomic, assign) size_t size;
10 |
11 | - (instancetype)initWithDoubleValues:(double *)values size:(size_t)size NS_DESIGNATED_INITIALIZER;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPDoubleTuple.m:
--------------------------------------------------------------------------------
1 | #import "EXPDoubleTuple.h"
2 |
3 | #pragma clang diagnostic push
4 | #pragma clang diagnostic ignored "-Wobjc-designated-initializers"
5 | @implementation EXPDoubleTuple
6 | #pragma clang diagnostic pop
7 |
8 | @synthesize values = _values, size = _size;
9 |
10 | - (instancetype)initWithDoubleValues:(double *)values size:(size_t)size {
11 | if ((self = [super init])) {
12 | self.values = malloc(sizeof(double) * size);
13 | memcpy(self.values, values, sizeof(double) * size);
14 | self.size = size;
15 | }
16 | return self;
17 | }
18 |
19 | - (void)dealloc {
20 | free(self.values);
21 | [super dealloc];
22 | }
23 |
24 | - (BOOL)isEqual:(id)object {
25 | if (![object isKindOfClass:[EXPDoubleTuple class]]) return NO;
26 | EXPDoubleTuple *other = (EXPDoubleTuple *)object;
27 | if (self.size == other.size) {
28 | for (int i = 0; i < self.size; ++i) {
29 | if (self.values[i] != other.values[i]) return NO;
30 | }
31 | return YES;
32 | }
33 | return NO;
34 | }
35 |
36 | - (NSString *)description {
37 | if (self.size == 2) {
38 | return [NSString stringWithFormat:@"Double tuple: {%f, %f}", self.values[0], self.values[1]];
39 | } else if (self.size == 4) {
40 | return [NSString stringWithFormat:@"Double tuple: {%f, %f, %f, %f}", self.values[0], self.values[1], self.values[2], self.values[3]];
41 | }
42 | return [NSString stringWithFormat:@"Double tuple of unexpected size %zd, sadly", self.size];
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPExpect.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "EXPMatcher.h"
3 | #import "EXPDefines.h"
4 |
5 | @interface EXPExpect : NSObject {
6 | EXPIdBlock _actualBlock;
7 | id _testCase;
8 | int _lineNumber;
9 | char *_fileName;
10 | BOOL _negative;
11 | BOOL _asynchronous;
12 | NSTimeInterval _timeout;
13 | }
14 |
15 | @property(nonatomic, copy) EXPIdBlock actualBlock;
16 | @property(nonatomic, readonly) id actual;
17 | @property(nonatomic, assign) id testCase;
18 | @property(nonatomic) int lineNumber;
19 | @property(nonatomic) const char *fileName;
20 | @property(nonatomic) BOOL negative;
21 | @property(nonatomic) BOOL asynchronous;
22 | @property(nonatomic) NSTimeInterval timeout;
23 |
24 | @property(nonatomic, readonly) EXPExpect *to;
25 | @property(nonatomic, readonly) EXPExpect *toNot;
26 | @property(nonatomic, readonly) EXPExpect *notTo;
27 | @property(nonatomic, readonly) EXPExpect *will;
28 | @property(nonatomic, readonly) EXPExpect *willNot;
29 | @property(nonatomic, readonly) EXPExpect *(^after)(NSTimeInterval timeInterval);
30 |
31 | - (instancetype)initWithActualBlock:(id)actualBlock testCase:(id)testCase lineNumber:(int)lineNumber fileName:(const char *)fileName NS_DESIGNATED_INITIALIZER;
32 | + (EXPExpect *)expectWithActualBlock:(id)actualBlock testCase:(id)testCase lineNumber:(int)lineNumber fileName:(const char *)fileName;
33 |
34 | - (void)applyMatcher:(id)matcher;
35 | - (void)applyMatcher:(id)matcher to:(NSObject **)actual;
36 |
37 | @end
38 |
39 | @interface EXPDynamicPredicateMatcher : NSObject {
40 | EXPExpect *_expectation;
41 | SEL _selector;
42 | }
43 | - (instancetype)initWithExpectation:(EXPExpect *)expectation selector:(SEL)selector NS_DESIGNATED_INITIALIZER;
44 | @property (nonatomic, readonly, copy) void (^dispatch)(void);
45 | @end
46 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPFloatTuple.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface EXPFloatTuple : NSObject {
4 | float *_values;
5 | size_t _size;
6 | }
7 |
8 | @property (nonatomic, assign) float *values;
9 | @property (nonatomic, assign) size_t size;
10 |
11 | - (instancetype)initWithFloatValues:(float *)values size:(size_t)size NS_DESIGNATED_INITIALIZER;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPFloatTuple.m:
--------------------------------------------------------------------------------
1 | #import "EXPFloatTuple.h"
2 |
3 | #pragma clang diagnostic push
4 | #pragma clang diagnostic ignored "-Wobjc-designated-initializers"
5 | @implementation EXPFloatTuple
6 | #pragma clang diagnostic pop
7 |
8 | @synthesize values = _values, size = _size;
9 |
10 | - (instancetype)initWithFloatValues:(float *)values size:(size_t)size {
11 | if ((self = [super init])) {
12 | self.values = malloc(sizeof(float) * size);
13 | memcpy(self.values, values, sizeof(float) * size);
14 | self.size = size;
15 | }
16 | return self;
17 | }
18 |
19 | - (void)dealloc {
20 | free(self.values);
21 | [super dealloc];
22 | }
23 |
24 | - (BOOL)isEqual:(id)object {
25 | if (![object isKindOfClass:[EXPFloatTuple class]]) return NO;
26 | EXPFloatTuple *other = (EXPFloatTuple *)object;
27 | if (self.size == other.size) {
28 | for (int i = 0; i < self.size; ++i) {
29 | if (self.values[i] != other.values[i]) return NO;
30 | }
31 | return YES;
32 | }
33 | return NO;
34 | }
35 |
36 | - (NSUInteger)hash
37 | {
38 | NSUInteger prime = 31;
39 | NSUInteger hash = 0;
40 | for (int i=0; i
10 |
11 | @protocol EXPMatcher
12 |
13 | - (BOOL)matches:(id)actual;
14 |
15 | @optional
16 | - (BOOL)meetsPrerequesiteFor:(id)actual;
17 | - (NSString *)failureMessageForTo:(id)actual;
18 | - (NSString *)failureMessageForNotTo:(id)actual;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPUnsupportedObject.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface EXPUnsupportedObject : NSObject {
4 | NSString *_type;
5 | }
6 |
7 | @property (nonatomic, retain) NSString *type;
8 |
9 | - (instancetype)initWithType:(NSString *)type NS_DESIGNATED_INITIALIZER;
10 |
11 | @end
12 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/EXPUnsupportedObject.m:
--------------------------------------------------------------------------------
1 | #import "EXPUnsupportedObject.h"
2 |
3 | #pragma clang diagnostic push
4 | #pragma clang diagnostic ignored "-Wobjc-designated-initializers"
5 | @implementation EXPUnsupportedObject
6 | #pragma clang diagnostic pop
7 |
8 | @synthesize type=_type;
9 |
10 | - (instancetype)initWithType:(NSString *)type {
11 | self = [super init];
12 | if(self) {
13 | self.type = type;
14 | }
15 | return self;
16 | }
17 |
18 | - (void)dealloc {
19 | self.type = nil;
20 | [super dealloc];
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Expecta.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | //! Project version number for Expecta.
4 | FOUNDATION_EXPORT double ExpectaVersionNumber;
5 |
6 | //! Project version string for Expecta.
7 | FOUNDATION_EXPORT const unsigned char ExpectaVersionString[];
8 |
9 | #import
10 | #import
11 | #import
12 |
13 | // Enable shorthand by default
14 | #define expect(...) EXP_expect((__VA_ARGS__))
15 | #define failure(...) EXP_failure((__VA_ARGS__))
16 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/ExpectaObject.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #define EXPObjectify(value) _EXPObjectify(@encode(__typeof__((value))), (value))
4 | #define EXP_expect(actual) _EXP_expect(self, __LINE__, __FILE__, ^id{ __typeof__((actual)) strongActual = (actual); return EXPObjectify(strongActual); })
5 | #define EXPMatcherInterface(matcherName, matcherArguments) _EXPMatcherInterface(matcherName, matcherArguments)
6 | #define EXPMatcherImplementationBegin(matcherName, matcherArguments) _EXPMatcherImplementationBegin(matcherName, matcherArguments)
7 | #define EXPMatcherImplementationEnd _EXPMatcherImplementationEnd
8 | #define EXPMatcherAliasImplementation(newMatcherName, oldMatcherName, matcherArguments) _EXPMatcherAliasImplementation(newMatcherName, oldMatcherName, matcherArguments)
9 |
10 | #define EXP_failure(message) EXPFail(self, __LINE__, __FILE__, message)
11 |
12 |
13 | @interface Expecta : NSObject
14 |
15 | + (NSTimeInterval)asynchronousTestTimeout;
16 | + (void)setAsynchronousTestTimeout:(NSTimeInterval)timeout;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/ExpectaObject.m:
--------------------------------------------------------------------------------
1 | #import "ExpectaObject.h"
2 |
3 | @implementation Expecta
4 |
5 | static NSTimeInterval _asynchronousTestTimeout = 1.0;
6 |
7 | + (NSTimeInterval)asynchronousTestTimeout {
8 | return _asynchronousTestTimeout;
9 | }
10 |
11 | + (void)setAsynchronousTestTimeout:(NSTimeInterval)timeout {
12 | _asynchronousTestTimeout = timeout;
13 | }
14 |
15 | @end
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatcherHelpers.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | BOOL EXPIsValuePointer(NSValue *value);
4 | BOOL EXPIsNumberFloat(NSNumber *number);
5 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatcherHelpers.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatcherHelpers.h"
2 |
3 | BOOL EXPIsValuePointer(NSValue *value) {
4 | return [value objCType][0] == @encode(void *)[0];
5 | }
6 |
7 | BOOL EXPIsNumberFloat(NSNumber *number) {
8 | return strcmp([number objCType], @encode(float)) == 0;
9 | }
10 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beCloseTo.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(_beCloseToWithin, (id expected, id within));
4 | EXPMatcherInterface(beCloseToWithin, (id expected, id within));
5 |
6 | #define beCloseTo(expected) _beCloseToWithin(EXPObjectify((expected)), nil)
7 | #define beCloseToWithin(expected, range) _beCloseToWithin(EXPObjectify((expected)), EXPObjectify((range)))
8 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beCloseTo.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beCloseTo.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(_beCloseToWithin, (id expected, id within)) {
5 | prerequisite(^BOOL{
6 | return [actual isKindOfClass:[NSNumber class]] &&
7 | [expected isKindOfClass:[NSNumber class]] &&
8 | ([within isKindOfClass:[NSNumber class]] || (within == nil));
9 | });
10 |
11 | match(^BOOL{
12 | double actualValue = [actual doubleValue];
13 | double expectedValue = [expected doubleValue];
14 |
15 | if (within != nil) {
16 | double withinValue = [within doubleValue];
17 | double lowerBound = expectedValue - withinValue;
18 | double upperBound = expectedValue + withinValue;
19 | return (actualValue >= lowerBound) && (actualValue <= upperBound);
20 | } else {
21 | double diff = fabs(actualValue - expectedValue);
22 | actualValue = fabs(actualValue);
23 | expectedValue = fabs(expectedValue);
24 | double largest = (expectedValue > actualValue) ? expectedValue : actualValue;
25 | return (diff <= largest * FLT_EPSILON);
26 | }
27 | });
28 |
29 | failureMessageForTo(^NSString *{
30 | if (within) {
31 | return [NSString stringWithFormat:@"expected %@ to be close to %@ within %@",
32 | EXPDescribeObject(actual), EXPDescribeObject(expected), EXPDescribeObject(within)];
33 | } else {
34 | return [NSString stringWithFormat:@"expected %@ to be close to %@",
35 | EXPDescribeObject(actual), EXPDescribeObject(expected)];
36 | }
37 | });
38 |
39 | failureMessageForNotTo(^NSString *{
40 | if (within) {
41 | return [NSString stringWithFormat:@"expected %@ not to be close to %@ within %@",
42 | EXPDescribeObject(actual), EXPDescribeObject(expected), EXPDescribeObject(within)];
43 | } else {
44 | return [NSString stringWithFormat:@"expected %@ not to be close to %@",
45 | EXPDescribeObject(actual), EXPDescribeObject(expected)];
46 | }
47 | });
48 | }
49 | EXPMatcherImplementationEnd
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beFalsy.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(beFalsy, (void));
4 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beFalsy.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beFalsy.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(beFalsy, (void)) {
5 | match(^BOOL{
6 | if([actual isKindOfClass:[NSNumber class]]) {
7 | return ![(NSNumber *)actual boolValue];
8 | } else if([actual isKindOfClass:[NSValue class]]) {
9 | if(EXPIsValuePointer((NSValue *)actual)) {
10 | return ![(NSValue *)actual pointerValue];
11 | }
12 | }
13 | return !actual;
14 | });
15 |
16 | failureMessageForTo(^NSString *{
17 | return [NSString stringWithFormat:@"expected: a falsy value, got: %@, which is truthy", EXPDescribeObject(actual)];
18 | });
19 |
20 | failureMessageForNotTo(^NSString *{
21 | return [NSString stringWithFormat:@"expected: a non-falsy value, got: %@, which is falsy", EXPDescribeObject(actual)];
22 | });
23 | }
24 | EXPMatcherImplementationEnd
25 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThan.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(_beGreaterThan, (id expected));
4 | EXPMatcherInterface(beGreaterThan, (id expected));
5 |
6 | #define beGreaterThan(expected) _beGreaterThan(EXPObjectify((expected)))
7 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThan.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beGreaterThan.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(_beGreaterThan, (id expected)) {
5 | match(^BOOL{
6 | if ([actual respondsToSelector:@selector(compare:)]) {
7 | return [actual compare:expected] == NSOrderedDescending;
8 | }
9 | return NO;
10 | });
11 |
12 | failureMessageForTo(^NSString *{
13 | return [NSString stringWithFormat:@"expected: %@ to be greater than %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
14 | });
15 |
16 | failureMessageForNotTo(^NSString *{
17 | return [NSString stringWithFormat:@"expected: %@ not to be greater than %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
18 | });
19 | }
20 | EXPMatcherImplementationEnd
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(_beGreaterThanOrEqualTo, (id expected));
4 | EXPMatcherInterface(beGreaterThanOrEqualTo, (id expected));
5 |
6 | #define beGreaterThanOrEqualTo(expected) _beGreaterThanOrEqualTo(EXPObjectify((expected)))
7 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beGreaterThanOrEqualTo.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(_beGreaterThanOrEqualTo, (id expected)) {
5 | match(^BOOL{
6 | if ([actual respondsToSelector:@selector(compare:)]) {
7 | return [actual compare:expected] != NSOrderedAscending;
8 | }
9 | return NO;
10 | });
11 |
12 | failureMessageForTo(^NSString *{
13 | return [NSString stringWithFormat:@"expected: %@ to be greater than or equal to %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
14 | });
15 |
16 | failureMessageForNotTo(^NSString *{
17 | return [NSString stringWithFormat:@"expected: %@ not to be greater than or equal to %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
18 | });
19 | }
20 | EXPMatcherImplementationEnd
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beIdenticalTo.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(_beIdenticalTo, (void *expected));
4 | EXPMatcherInterface(beIdenticalTo, (void *expected)); // to aid code completion
5 |
6 | #if __has_feature(objc_arc)
7 | #define beIdenticalTo(expected) _beIdenticalTo((__bridge void*)expected)
8 | #else
9 | #define beIdenticalTo(expected) _beIdenticalTo(expected)
10 | #endif
11 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beIdenticalTo.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+equal.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(_beIdenticalTo, (void *expected)) {
5 | match(^BOOL{
6 | if(actual == expected) {
7 | return YES;
8 | } else if([actual isKindOfClass:[NSValue class]] && EXPIsValuePointer((NSValue *)actual)) {
9 | if([(NSValue *)actual pointerValue] == expected) {
10 | return YES;
11 | }
12 | }
13 | return NO;
14 | });
15 |
16 | failureMessageForTo(^NSString *{
17 | return [NSString stringWithFormat:@"expected: <%p>, got: <%p>", expected, actual];
18 | });
19 |
20 | failureMessageForNotTo(^NSString *{
21 | return [NSString stringWithFormat:@"expected: not <%p>, got: <%p>", expected, actual];
22 | });
23 | }
24 | EXPMatcherImplementationEnd
25 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInTheRangeOf.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(_beInTheRangeOf, (id expectedLowerBound, id expectedUpperBound));
4 | EXPMatcherInterface(beInTheRangeOf, (id expectedLowerBound, id expectedUpperBound));
5 |
6 | #define beInTheRangeOf(expectedLowerBound, expectedUpperBound) _beInTheRangeOf(EXPObjectify((expectedLowerBound)), EXPObjectify((expectedUpperBound)))
7 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInTheRangeOf.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beInTheRangeOf.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(_beInTheRangeOf, (id expectedLowerBound, id expectedUpperBound)) {
5 | match(^BOOL{
6 | if ([actual respondsToSelector:@selector(compare:)]) {
7 | NSComparisonResult compareLowerBound = [expectedLowerBound compare: actual];
8 | NSComparisonResult compareUpperBound = [expectedUpperBound compare: actual];
9 | if (compareLowerBound == NSOrderedSame) {
10 | return YES;
11 | }
12 | if (compareUpperBound == NSOrderedSame) {
13 | return YES;
14 | }
15 | if ((compareLowerBound == NSOrderedAscending) && (compareUpperBound == NSOrderedDescending)) {
16 | return YES;
17 | }
18 | }
19 | return NO;
20 | });
21 |
22 | failureMessageForTo(^NSString *{
23 | return [NSString stringWithFormat:@"expected: %@ to be in the range [%@, %@] (inclusive)", EXPDescribeObject(actual), EXPDescribeObject(expectedLowerBound), EXPDescribeObject(expectedUpperBound)];
24 | });
25 |
26 | failureMessageForNotTo(^NSString *{
27 | return [NSString stringWithFormat:@"expected: %@ not to be in the range [%@, %@] (inclusive)", EXPDescribeObject(actual), EXPDescribeObject(expectedLowerBound), EXPDescribeObject(expectedUpperBound)];
28 | });
29 | }
30 | EXPMatcherImplementationEnd
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInstanceOf.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(beInstanceOf, (Class expected));
4 | EXPMatcherInterface(beAnInstanceOf, (Class expected));
5 | EXPMatcherInterface(beMemberOf, (Class expected));
6 | EXPMatcherInterface(beAMemberOf, (Class expected));
7 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInstanceOf.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beInstanceOf.h"
2 |
3 | EXPMatcherImplementationBegin(beInstanceOf, (Class expected)) {
4 | BOOL actualIsNil = (actual == nil);
5 | BOOL expectedIsNil = (expected == nil);
6 |
7 | prerequisite(^BOOL{
8 | return !(actualIsNil || expectedIsNil);
9 | });
10 |
11 | match(^BOOL{
12 | return [actual isMemberOfClass:expected];
13 | });
14 |
15 | failureMessageForTo(^NSString *{
16 | if(actualIsNil) return @"the actual value is nil/null";
17 | if(expectedIsNil) return @"the expected value is nil/null";
18 | return [NSString stringWithFormat:@"expected: an instance of %@, got: an instance of %@", [expected class], [actual class]];
19 | });
20 |
21 | failureMessageForNotTo(^NSString *{
22 | if(actualIsNil) return @"the actual value is nil/null";
23 | if(expectedIsNil) return @"the expected value is nil/null";
24 | return [NSString stringWithFormat:@"expected: not an instance of %@, got: an instance of %@", [expected class], [actual class]];
25 | });
26 | }
27 | EXPMatcherImplementationEnd
28 |
29 | EXPMatcherAliasImplementation(beAnInstanceOf, beInstanceOf, (Class expected));
30 | EXPMatcherAliasImplementation(beMemberOf, beInstanceOf, (Class expected));
31 | EXPMatcherAliasImplementation(beAMemberOf, beInstanceOf, (Class expected));
32 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beKindOf.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(beKindOf, (Class expected));
4 | EXPMatcherInterface(beAKindOf, (Class expected));
5 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beKindOf.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beKindOf.h"
2 |
3 | EXPMatcherImplementationBegin(beKindOf, (Class expected)) {
4 | BOOL actualIsNil = (actual == nil);
5 | BOOL expectedIsNil = (expected == nil);
6 |
7 | prerequisite(^BOOL{
8 | return !(actualIsNil || expectedIsNil);
9 | });
10 |
11 | match(^BOOL{
12 | return [actual isKindOfClass:expected];
13 | });
14 |
15 | failureMessageForTo(^NSString *{
16 | if(actualIsNil) return @"the actual value is nil/null";
17 | if(expectedIsNil) return @"the expected value is nil/null";
18 | return [NSString stringWithFormat:@"expected: a kind of %@, got: an instance of %@, which is not a kind of %@", [expected class], [actual class], [expected class]];
19 | });
20 |
21 | failureMessageForNotTo(^NSString *{
22 | if(actualIsNil) return @"the actual value is nil/null";
23 | if(expectedIsNil) return @"the expected value is nil/null";
24 | return [NSString stringWithFormat:@"expected: not a kind of %@, got: an instance of %@, which is a kind of %@", [expected class], [actual class], [expected class]];
25 | });
26 | }
27 | EXPMatcherImplementationEnd
28 |
29 | EXPMatcherAliasImplementation(beAKindOf, beKindOf, (Class expected));
30 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThan.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(_beLessThan, (id expected));
4 | EXPMatcherInterface(beLessThan, (id expected));
5 |
6 | #define beLessThan(expected) _beLessThan(EXPObjectify((expected)))
7 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThan.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beLessThan.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(_beLessThan, (id expected)) {
5 | match(^BOOL{
6 | if ([actual respondsToSelector:@selector(compare:)]) {
7 | return [actual compare:expected] == NSOrderedAscending;
8 | }
9 | return NO;
10 | });
11 |
12 | failureMessageForTo(^NSString *{
13 | return [NSString stringWithFormat:@"expected: %@ to be less than %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
14 | });
15 |
16 | failureMessageForNotTo(^NSString *{
17 | return [NSString stringWithFormat:@"expected: %@ not to be less than %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
18 | });
19 | }
20 | EXPMatcherImplementationEnd
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(_beLessThanOrEqualTo, (id expected));
4 | EXPMatcherInterface(beLessThanOrEqualTo, (id expected));
5 |
6 | #define beLessThanOrEqualTo(expected) _beLessThanOrEqualTo(EXPObjectify((expected)))
7 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beLessThanOrEqualTo.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(_beLessThanOrEqualTo, (id expected)) {
5 | match(^BOOL{
6 | if ([actual respondsToSelector:@selector(compare:)]) {
7 | return [actual compare:expected] != NSOrderedDescending;
8 | }
9 | return NO;
10 | });
11 |
12 | failureMessageForTo(^NSString *{
13 | return [NSString stringWithFormat:@"expected: %@ to be less than or equal to %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
14 | });
15 |
16 | failureMessageForNotTo(^NSString *{
17 | return [NSString stringWithFormat:@"expected: %@ not to be less than or equal to %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
18 | });
19 | }
20 | EXPMatcherImplementationEnd
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beNil.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(beNil, (void));
4 | EXPMatcherInterface(beNull, (void));
5 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beNil.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beNil.h"
2 |
3 | EXPMatcherImplementationBegin(beNil, (void)) {
4 | match(^BOOL{
5 | return actual == nil;
6 | });
7 |
8 | failureMessageForTo(^NSString *{
9 | return [NSString stringWithFormat:@"expected: nil/null, got: %@", EXPDescribeObject(actual)];
10 | });
11 |
12 | failureMessageForNotTo(^NSString *{
13 | return [NSString stringWithFormat:@"expected: not nil/null, got: %@", EXPDescribeObject(actual)];
14 | });
15 | }
16 | EXPMatcherImplementationEnd
17 |
18 | EXPMatcherAliasImplementation(beNull, beNil, (void));
19 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSubclassOf.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(beSubclassOf, (Class expected));
4 | EXPMatcherInterface(beASubclassOf, (Class expected));
5 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSubclassOf.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beSubclassOf.h"
2 | #import "NSValue+Expecta.h"
3 | #import
4 |
5 | EXPMatcherImplementationBegin(beSubclassOf, (Class expected)) {
6 | __block BOOL actualIsClass = YES;
7 |
8 | prerequisite(^BOOL {
9 | actualIsClass = class_isMetaClass(object_getClass(actual));
10 | return actualIsClass;
11 | });
12 |
13 | match(^BOOL{
14 | return [actual isSubclassOfClass:expected];
15 | });
16 |
17 | failureMessageForTo(^NSString *{
18 | if(!actualIsClass) return @"the actual value is not a Class";
19 | return [NSString stringWithFormat:@"expected: a subclass of %@, got: a class %@, which is not a subclass of %@", [expected class], actual, [expected class]];
20 | });
21 |
22 | failureMessageForNotTo(^NSString *{
23 | if(!actualIsClass) return @"the actual value is not a Class";
24 | return [NSString stringWithFormat:@"expected: not a subclass of %@, got: a class %@, which is a subclass of %@", [expected class], actual, [expected class]];
25 | });
26 | }
27 | EXPMatcherImplementationEnd
28 |
29 | EXPMatcherAliasImplementation(beASubclassOf, beSubclassOf, (Class expected));
30 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSupersetOf.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(beSupersetOf, (id subset));
4 |
5 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSupersetOf.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+contain.h"
2 |
3 | EXPMatcherImplementationBegin(beSupersetOf, (id subset)) {
4 | BOOL actualIsCompatible = [actual isKindOfClass:[NSDictionary class]] || [actual respondsToSelector:@selector(containsObject:)];
5 | BOOL subsetIsNil = (subset == nil);
6 |
7 | // For some instances the isKindOfClass: method returns false, even though
8 | // they are both actually dictionaries. e.g. Comparing a NSCFDictionary and a
9 | // NSDictionary.
10 | // Or in cases when you compare NSMutableArray (which implementation is __NSArrayM:NSMutableArray:NSArray)
11 | // and NSArray (which implementation is __NSArrayI:NSArray)
12 | BOOL bothAreIdenticalCollectionClasses = ([actual isKindOfClass:[NSDictionary class]] && [subset isKindOfClass:[NSDictionary class]]) ||
13 | ([actual isKindOfClass:[NSArray class]] && [subset isKindOfClass:[NSArray class]]) ||
14 | ([actual isKindOfClass:[NSSet class]] && [subset isKindOfClass:[NSSet class]]) ||
15 | ([actual isKindOfClass:[NSOrderedSet class]] && [subset isKindOfClass:[NSOrderedSet class]]);
16 |
17 | BOOL classMatches = bothAreIdenticalCollectionClasses || [subset isKindOfClass:[actual class]];
18 |
19 | prerequisite(^BOOL{
20 | return actualIsCompatible && !subsetIsNil && classMatches;
21 | });
22 |
23 | match(^BOOL{
24 | if(!actualIsCompatible) return NO;
25 |
26 | if([actual isKindOfClass:[NSDictionary class]]) {
27 | for (id key in subset) {
28 | id actualValue = [actual valueForKey:key];
29 | id subsetValue = [subset valueForKey:key];
30 |
31 | if (![subsetValue isEqual:actualValue]) return NO;
32 | }
33 | } else {
34 | for (id object in subset) {
35 | if (![actual containsObject:object]) return NO;
36 | }
37 | }
38 |
39 | return YES;
40 | });
41 |
42 | failureMessageForTo(^NSString *{
43 | if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSDictionary and does not implement -containsObject:", EXPDescribeObject(actual)];
44 |
45 | if(subsetIsNil) return @"the expected value is nil/null";
46 |
47 | if(!classMatches) return [NSString stringWithFormat:@"%@ does not match the class of %@", EXPDescribeObject(subset), EXPDescribeObject(actual)];
48 |
49 | return [NSString stringWithFormat:@"expected %@ to be a superset of %@", EXPDescribeObject(actual), EXPDescribeObject(subset)];
50 | });
51 |
52 | failureMessageForNotTo(^NSString *{
53 | if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSDictionary and does not implement -containsObject:", EXPDescribeObject(actual)];
54 |
55 | if(subsetIsNil) return @"the expected value is nil/null";
56 |
57 | if(!classMatches) return [NSString stringWithFormat:@"%@ does not match the class of %@", EXPDescribeObject(subset), EXPDescribeObject(actual)];
58 |
59 | return [NSString stringWithFormat:@"expected %@ not to be a superset of %@", EXPDescribeObject(actual), EXPDescribeObject(subset)];
60 | });
61 | }
62 | EXPMatcherImplementationEnd
63 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beTruthy.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(beTruthy, (void));
4 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beTruthy.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beTruthy.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(beTruthy, (void)) {
5 | match(^BOOL{
6 | if([actual isKindOfClass:[NSNumber class]]) {
7 | return !![(NSNumber *)actual boolValue];
8 | } else if([actual isKindOfClass:[NSValue class]]) {
9 | if(EXPIsValuePointer((NSValue *)actual)) {
10 | return !![(NSValue *)actual pointerValue];
11 | }
12 | }
13 | return !!actual;
14 | });
15 |
16 | failureMessageForTo(^NSString *{
17 | return [NSString stringWithFormat:@"expected: a truthy value, got: %@, which is falsy", EXPDescribeObject(actual)];
18 | });
19 |
20 | failureMessageForNotTo(^NSString *{
21 | return [NSString stringWithFormat:@"expected: a non-truthy value, got: %@, which is truthy", EXPDescribeObject(actual)];
22 | });
23 | }
24 | EXPMatcherImplementationEnd
25 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beginWith.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(beginWith, (id expected));
4 | EXPMatcherInterface(startWith, (id expected));
5 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beginWith.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beginWith.h"
2 |
3 | EXPMatcherImplementationBegin(beginWith, (id expected)) {
4 | BOOL actualIsNil = (actual == nil);
5 | BOOL expectedIsNil = (expected == nil);
6 | //This condition allows the comparison of an immutable string or ordered collection to the mutable type of the same
7 | BOOL actualAndExpectedAreCompatible = (([actual isKindOfClass:[NSString class]] && [expected isKindOfClass:[NSString class]])
8 | || ([actual isKindOfClass:[NSArray class]] && [expected isKindOfClass:[NSArray class]])
9 | || ([actual isKindOfClass:[NSOrderedSet class]] && [expected isKindOfClass:[NSOrderedSet class]]));
10 |
11 | prerequisite(^BOOL {
12 | return actualAndExpectedAreCompatible;
13 | });
14 |
15 | match(^BOOL {
16 | if ([actual isKindOfClass:[NSString class]]) {
17 | return [actual hasPrefix:expected];
18 | } else if ([actual isKindOfClass:[NSArray class]]) {
19 | if ([expected count] > [actual count] || [expected count] == 0) {
20 | return NO;
21 | }
22 | NSArray *subArray = [actual subarrayWithRange:NSMakeRange(0, [expected count])];
23 | return [subArray isEqualToArray:expected];
24 | } else {
25 | if ([expected count] > [actual count] || [expected count] == 0) {
26 | return NO;
27 | }
28 |
29 | NSOrderedSet *subset = [NSOrderedSet orderedSetWithOrderedSet:actual range:NSMakeRange(0, [expected count]) copyItems:NO];
30 | return [subset isEqualToOrderedSet:expected];
31 | }
32 | });
33 |
34 | failureMessageForTo(^NSString *{
35 | if (actualIsNil) return @"the object is nil/null";
36 | if (expectedIsNil) return @"the expected value is nil/null";
37 | if (!actualAndExpectedAreCompatible) return [NSString stringWithFormat:@"%@ and %@ are not instances of one of %@, %@, or %@", EXPDescribeObject(actual), EXPDescribeObject(expected), [NSString class], [NSArray class], [NSOrderedSet class]];
38 | return [NSString stringWithFormat:@"expected: %@ to begin with %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
39 | });
40 |
41 | failureMessageForNotTo(^NSString *{
42 | if (actualIsNil) return @"the object is nil/null";
43 | if (expectedIsNil) return @"the expected value is nil/null";
44 | if (!actualAndExpectedAreCompatible) return [NSString stringWithFormat:@"%@ and %@ are not instances of one of %@, %@, or %@", EXPDescribeObject(actual), EXPDescribeObject(expected), [NSString class], [NSArray class], [NSOrderedSet class]];
45 |
46 | return [NSString stringWithFormat:@"expected: %@ not to begin with %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
47 | });
48 | }
49 | EXPMatcherImplementationEnd
50 |
51 | EXPMatcherAliasImplementation(startWith, beginWith, (id expected));
52 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+conformTo.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(conformTo, (Protocol *expected));
4 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+conformTo.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+conformTo.h"
2 | #import "NSValue+Expecta.h"
3 | #import
4 |
5 | EXPMatcherImplementationBegin(conformTo, (Protocol *expected)) {
6 | BOOL actualIsNil = (actual == nil);
7 | BOOL expectedIsNil = (expected == nil);
8 |
9 | prerequisite(^BOOL{
10 | return !(actualIsNil || expectedIsNil);
11 | });
12 |
13 | match(^BOOL{
14 | return [actual conformsToProtocol:expected];
15 | });
16 |
17 | failureMessageForTo(^NSString *{
18 | if(actualIsNil) return @"the object is nil/null";
19 | if(expectedIsNil) return @"the protocol is nil/null";
20 |
21 | NSString *name = NSStringFromProtocol(expected);
22 | return [NSString stringWithFormat:@"expected: %@ to conform to %@", actual, name];
23 | });
24 |
25 | failureMessageForNotTo(^NSString *{
26 | if(actualIsNil) return @"the object is nil/null";
27 | if(expectedIsNil) return @"the protocol is nil/null";
28 |
29 | NSString *name = NSStringFromProtocol(expected);
30 | return [NSString stringWithFormat:@"expected: %@ not to conform to %@", actual, name];
31 | });
32 | }
33 | EXPMatcherImplementationEnd
34 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+contain.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(_contain, (id expected));
4 | EXPMatcherInterface(contain, (id expected)); // to aid code completion
5 | #define contain(expected) _contain(EXPObjectify((expected)))
6 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+contain.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+contain.h"
2 |
3 | EXPMatcherImplementationBegin(_contain, (id expected)) {
4 | BOOL actualIsCompatible = [actual isKindOfClass:[NSString class]] || [actual conformsToProtocol:@protocol(NSFastEnumeration)];
5 | BOOL expectedIsNil = (expected == nil);
6 |
7 | prerequisite(^BOOL{
8 | return actualIsCompatible && !expectedIsNil;
9 | });
10 |
11 | match(^BOOL{
12 | if(actualIsCompatible) {
13 | if([actual isKindOfClass:[NSString class]]) {
14 | return [(NSString *)actual rangeOfString:[expected description]].location != NSNotFound;
15 | } else {
16 | for (id object in actual) {
17 | if ([object isEqual:expected]) {
18 | return YES;
19 | }
20 | }
21 | }
22 | }
23 | return NO;
24 | });
25 |
26 | failureMessageForTo(^NSString *{
27 | if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString or NSFastEnumeration", EXPDescribeObject(actual)];
28 | if(expectedIsNil) return @"the expected value is nil/null";
29 | return [NSString stringWithFormat:@"expected %@ to contain %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
30 | });
31 |
32 | failureMessageForNotTo(^NSString *{
33 | if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString or NSFastEnumeration", EXPDescribeObject(actual)];
34 | if(expectedIsNil) return @"the expected value is nil/null";
35 | return [NSString stringWithFormat:@"expected %@ not to contain %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
36 | });
37 | }
38 | EXPMatcherImplementationEnd
39 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+endWith.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(endWith, (id expected));
4 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+endWith.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+endWith.h"
2 |
3 | EXPMatcherImplementationBegin(endWith, (id expected)) {
4 | BOOL actualIsNil = (actual == nil);
5 | BOOL expectedIsNil = (expected == nil);
6 | //This condition allows the comparison of an immutable string or ordered collection to the mutable type of the same
7 | BOOL actualAndExpectedAreCompatible = (([actual isKindOfClass:[NSString class]] && [expected isKindOfClass:[NSString class]])
8 | || ([actual isKindOfClass:[NSArray class]] && [expected isKindOfClass:[NSArray class]])
9 | || ([actual isKindOfClass:[NSOrderedSet class]] && [expected isKindOfClass:[NSOrderedSet class]]));
10 |
11 | prerequisite(^BOOL {
12 | return actualAndExpectedAreCompatible;
13 | });
14 |
15 | match(^BOOL {
16 | if ([actual isKindOfClass:[NSString class]]) {
17 | return [actual hasSuffix:expected];
18 | } else if ([actual isKindOfClass:[NSArray class]]) {
19 | if ([expected count] > [actual count] || [expected count] == 0) {
20 | return NO;
21 | }
22 | NSArray *subArray = [actual subarrayWithRange:NSMakeRange([actual count] - [expected count], [expected count])];
23 | return [subArray isEqualToArray:expected];
24 | } else {
25 | if ([expected count] > [actual count] || [expected count] == 0) {
26 | return NO;
27 | }
28 |
29 | NSOrderedSet *subset = [NSOrderedSet orderedSetWithOrderedSet:actual range:NSMakeRange([actual count] - [expected count], [expected count]) copyItems:NO];
30 | return [subset isEqualToOrderedSet:expected];
31 | }
32 | });
33 |
34 | failureMessageForTo(^NSString *{
35 | if (actualIsNil) return @"the object is nil/null";
36 | if (expectedIsNil) return @"the expected value is nil/null";
37 | if (!actualAndExpectedAreCompatible) return [NSString stringWithFormat:@"%@ and %@ are not instances of one of %@, %@, or %@", EXPDescribeObject(actual), EXPDescribeObject(expected), [NSString class], [NSArray class], [NSOrderedSet class]];
38 | return [NSString stringWithFormat:@"expected: %@ to end with %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
39 | });
40 |
41 | failureMessageForNotTo(^NSString *{
42 | if (actualIsNil) return @"the object is nil/null";
43 | if (expectedIsNil) return @"the expected value is nil/null";
44 | if (!actualAndExpectedAreCompatible) return [NSString stringWithFormat:@"%@ and %@ are not instances of one of %@, %@, or %@", EXPDescribeObject(actual), EXPDescribeObject(expected), [NSString class], [NSArray class], [NSOrderedSet class]];
45 |
46 | return [NSString stringWithFormat:@"expected: %@ not to end with %@", EXPDescribeObject(actual), EXPDescribeObject(expected)];
47 | });
48 | }
49 | EXPMatcherImplementationEnd
50 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+equal.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(_equal, (id expected));
4 | EXPMatcherInterface(equal, (id expected)); // to aid code completion
5 | #define equal(...) _equal(EXPObjectify((__VA_ARGS__)))
6 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+equal.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+equal.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(_equal, (id expected)) {
5 | match(^BOOL{
6 | if((actual == expected) || [actual isEqual:expected]) {
7 | return YES;
8 | } else if([actual isKindOfClass:[NSNumber class]] && [expected isKindOfClass:[NSNumber class]]) {
9 | if([actual isKindOfClass:[NSDecimalNumber class]] || [expected isKindOfClass:[NSDecimalNumber class]]) {
10 | NSDecimalNumber *actualDecimalNumber = [NSDecimalNumber decimalNumberWithDecimal:[(NSNumber *) actual decimalValue]];
11 | NSDecimalNumber *expectedDecimalNumber = [NSDecimalNumber decimalNumberWithDecimal:[(NSNumber *) expected decimalValue]];
12 | return [actualDecimalNumber isEqualToNumber:expectedDecimalNumber];
13 | }
14 | else {
15 | if(EXPIsNumberFloat((NSNumber *)actual) || EXPIsNumberFloat((NSNumber *)expected)) {
16 | return [(NSNumber *)actual floatValue] == [(NSNumber *)expected floatValue];
17 | }
18 | }
19 | }
20 | return NO;
21 | });
22 |
23 | failureMessageForTo(^NSString *{
24 | NSString *expectedDescription = EXPDescribeObject(expected);
25 | NSString *actualDescription = EXPDescribeObject(actual);
26 |
27 | if (![expectedDescription isEqualToString:actualDescription]) {
28 | return [NSString stringWithFormat:@"expected: %@, got: %@", EXPDescribeObject(expected), EXPDescribeObject(actual)];
29 | } else {
30 | return [NSString stringWithFormat:@"expected (%@): %@, got (%@): %@", NSStringFromClass([expected class]), EXPDescribeObject(expected), NSStringFromClass([actual class]), EXPDescribeObject(actual)];
31 | }
32 | });
33 |
34 | failureMessageForNotTo(^NSString *{
35 | return [NSString stringWithFormat:@"expected: not %@, got: %@", EXPDescribeObject(expected), EXPDescribeObject(actual)];
36 | });
37 | }
38 | EXPMatcherImplementationEnd
39 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+haveCountOf.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(haveCountOf, (NSUInteger expected));
4 | EXPMatcherInterface(haveCount, (NSUInteger expected));
5 | EXPMatcherInterface(haveACountOf, (NSUInteger expected));
6 | EXPMatcherInterface(haveLength, (NSUInteger expected));
7 | EXPMatcherInterface(haveLengthOf, (NSUInteger expected));
8 | EXPMatcherInterface(haveALengthOf, (NSUInteger expected));
9 |
10 | #define beEmpty() haveCountOf(0)
11 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+haveCountOf.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+haveCountOf.h"
2 |
3 | EXPMatcherImplementationBegin(haveCountOf, (NSUInteger expected)) {
4 | BOOL actualIsStringy = [actual isKindOfClass:[NSString class]] || [actual isKindOfClass:[NSAttributedString class]];
5 | BOOL actualIsCompatible = actualIsStringy || [actual respondsToSelector:@selector(count)];
6 |
7 | prerequisite(^BOOL{
8 | return actualIsCompatible;
9 | });
10 |
11 | NSUInteger (^count)(id) = ^(id actual) {
12 | if(actualIsStringy) {
13 | return [actual length];
14 | } else {
15 | return [actual count];
16 | }
17 | };
18 |
19 | match(^BOOL{
20 | if(actualIsCompatible) {
21 | return count(actual) == expected;
22 | }
23 | return NO;
24 | });
25 |
26 | failureMessageForTo(^NSString *{
27 | if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString, NSAttributedString, NSArray, NSSet, NSOrderedSet, or NSDictionary", EXPDescribeObject(actual)];
28 | return [NSString stringWithFormat:@"expected %@ to have a count of %zi but got %zi", EXPDescribeObject(actual), expected, count(actual)];
29 | });
30 |
31 | failureMessageForNotTo(^NSString *{
32 | if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString, NSAttributedString, NSArray, NSSet, NSOrderedSet, or NSDictionary", EXPDescribeObject(actual)];
33 | return [NSString stringWithFormat:@"expected %@ not to have a count of %zi", EXPDescribeObject(actual), expected];
34 | });
35 | }
36 | EXPMatcherImplementationEnd
37 |
38 | EXPMatcherAliasImplementation(haveCount, haveCountOf, (NSUInteger expected));
39 | EXPMatcherAliasImplementation(haveACountOf, haveCountOf, (NSUInteger expected));
40 | EXPMatcherAliasImplementation(haveLength, haveCountOf, (NSUInteger expected));
41 | EXPMatcherAliasImplementation(haveLengthOf, haveCountOf, (NSUInteger expected));
42 | EXPMatcherAliasImplementation(haveALengthOf, haveCountOf, (NSUInteger expected));
43 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+match.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(match, (NSString *expected));
4 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+match.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+match.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(match, (NSString *expected)) {
5 | BOOL actualIsNil = (actual == nil);
6 | BOOL expectedIsNil = (expected == nil);
7 |
8 | __block NSRegularExpression *regex = nil;
9 | __block NSError *regexError = nil;
10 |
11 | prerequisite (^BOOL {
12 | BOOL nilInput = (actualIsNil || expectedIsNil);
13 | if (!nilInput) {
14 | regex = [NSRegularExpression regularExpressionWithPattern:expected options:0 error:®exError];
15 | }
16 | return !nilInput && regex;
17 | });
18 |
19 | match(^BOOL {
20 | NSRange range = [regex rangeOfFirstMatchInString:actual options:0 range:NSMakeRange(0, [actual length])];
21 | return !NSEqualRanges(range, NSMakeRange(NSNotFound, 0));
22 | });
23 |
24 | failureMessageForTo(^NSString *{
25 | if (actualIsNil) return @"the object is nil/null";
26 | if (expectedIsNil) return @"the expression is nil/null";
27 | if (regexError) return [NSString stringWithFormat:@"unable to create regular expression from given parameter: %@", [regexError localizedDescription]];
28 | return [NSString stringWithFormat:@"expected: %@ to match to %@", EXPDescribeObject(actual), expected];
29 | });
30 |
31 | failureMessageForNotTo(^NSString *{
32 | if (actualIsNil) return @"the object is nil/null";
33 | if (expectedIsNil) return @"the expression is nil/null";
34 | if (regexError) return [NSString stringWithFormat:@"unable to create regular expression from given parameter: %@", [regexError localizedDescription]];
35 | return [NSString stringWithFormat:@"expected: %@ not to match to %@", EXPDescribeObject(actual), expected];
36 | });
37 | }
38 | EXPMatcherImplementationEnd
39 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+postNotification.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(postNotification, (id expectedNotification));
4 | EXPMatcherInterface(notify, (id expectedNotification));
5 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raise.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(raise, (NSString *expectedExceptionName));
4 | #define raiseAny() raise(nil)
5 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raise.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+raise.h"
2 | #import "EXPDefines.h"
3 |
4 | EXPMatcherImplementationBegin(raise, (NSString *expectedExceptionName)) {
5 | __block NSException *exceptionCaught = nil;
6 |
7 | match(^BOOL{
8 | BOOL expectedExceptionCaught = NO;
9 | @try {
10 | ((EXPBasicBlock)actual)();
11 | } @catch(NSException *e) {
12 | exceptionCaught = e;
13 | expectedExceptionCaught = (expectedExceptionName == nil) || [[exceptionCaught name] isEqualToString:expectedExceptionName];
14 | }
15 | return expectedExceptionCaught;
16 | });
17 |
18 | failureMessageForTo(^NSString *{
19 | return [NSString stringWithFormat:@"expected: %@, got: %@",
20 | expectedExceptionName ? expectedExceptionName : @"any exception",
21 | exceptionCaught ? [exceptionCaught name] : @"no exception"];
22 | });
23 |
24 | failureMessageForNotTo(^NSString *{
25 | return [NSString stringWithFormat:@"expected: %@, got: %@",
26 | expectedExceptionName ? [NSString stringWithFormat:@"not %@", expectedExceptionName] : @"no exception",
27 | exceptionCaught ? [exceptionCaught name] : @"no exception"];
28 | });
29 | }
30 | EXPMatcherImplementationEnd
31 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raiseWithReason.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(raiseWithReason, (NSString *expectedExceptionName, NSString *expectedReason));
4 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raiseWithReason.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+raiseWithReason.h"
2 | #import "EXPDefines.h"
3 |
4 | EXPMatcherImplementationBegin(raiseWithReason, (NSString *expectedExceptionName, NSString *expectedReason)) {
5 | __block NSException *exceptionCaught = nil;
6 |
7 | match(^BOOL{
8 | BOOL expectedExceptionCaught = NO;
9 | @try {
10 | ((EXPBasicBlock)actual)();
11 | } @catch(NSException *e) {
12 | exceptionCaught = e;
13 | expectedExceptionCaught = (((expectedExceptionName == nil) || [[exceptionCaught name] isEqualToString:expectedExceptionName]) &&
14 | ((expectedReason == nil) || ([[exceptionCaught reason] isEqualToString:expectedReason])));
15 | }
16 | return expectedExceptionCaught;
17 | });
18 |
19 | failureMessageForTo(^NSString *{
20 | return [NSString stringWithFormat:@"expected: %@ (%@), got: %@ (%@)",
21 | expectedExceptionName ?: @"any exception",
22 | expectedReason ?: @"any reason",
23 | exceptionCaught ? [exceptionCaught name] : @"no exception",
24 | exceptionCaught ? [exceptionCaught reason] : @""];
25 | });
26 |
27 | failureMessageForNotTo(^NSString *{
28 | return [NSString stringWithFormat:@"expected: %@ (%@), got: %@ (%@)",
29 | expectedExceptionName ? [NSString stringWithFormat:@"not %@", expectedExceptionName] : @"no exception",
30 | expectedReason ? [NSString stringWithFormat:@"not '%@'", expectedReason] : @"no reason",
31 | exceptionCaught ? [exceptionCaught name] : @"no exception",
32 | exceptionCaught ? [exceptionCaught reason] : @"no reason"];
33 | });
34 | }
35 | EXPMatcherImplementationEnd
36 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+respondTo.h:
--------------------------------------------------------------------------------
1 | #import "Expecta.h"
2 |
3 | EXPMatcherInterface(respondTo, (SEL expected));
4 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+respondTo.m:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+respondTo.h"
2 | #import "EXPMatcherHelpers.h"
3 |
4 | EXPMatcherImplementationBegin(respondTo, (SEL expected)) {
5 | BOOL actualIsNil = (actual == nil);
6 | BOOL expectedIsNull = (expected == NULL);
7 |
8 | prerequisite (^BOOL {
9 | return !(actualIsNil || expectedIsNull);
10 | });
11 |
12 | match(^BOOL {
13 | if ([actual respondsToSelector:@selector(instancesRespondToSelector:)] &&
14 | [actual instancesRespondToSelector:expected]) {
15 | return YES;
16 | }
17 | return [actual respondsToSelector:expected];
18 | });
19 |
20 | failureMessageForTo(^NSString *{
21 | if (actualIsNil) return @"the object is nil/null";
22 | if (expectedIsNull) return @"the selector is null";
23 | return [NSString stringWithFormat:@"expected: %@ to respond to %@", EXPDescribeObject(actual), NSStringFromSelector(expected)];
24 | });
25 |
26 | failureMessageForNotTo(^NSString *{
27 | if (actualIsNil) return @"the object is nil/null";
28 | if (expectedIsNull) return @"the selector is null";
29 | return [NSString stringWithFormat:@"expected: %@ not to respond to %@", EXPDescribeObject(actual), NSStringFromSelector(expected)];
30 | });
31 | }
32 | EXPMatcherImplementationEnd
33 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers.h:
--------------------------------------------------------------------------------
1 | #import "EXPMatchers+beNil.h"
2 | #import "EXPMatchers+equal.h"
3 | #import "EXPMatchers+beInstanceOf.h"
4 | #import "EXPMatchers+beKindOf.h"
5 | #import "EXPMatchers+beSubclassOf.h"
6 | #import "EXPMatchers+conformTo.h"
7 | #import "EXPMatchers+beTruthy.h"
8 | #import "EXPMatchers+beFalsy.h"
9 | #import "EXPMatchers+contain.h"
10 | #import "EXPMatchers+beSupersetOf.h"
11 | #import "EXPMatchers+haveCountOf.h"
12 | #import "EXPMatchers+beIdenticalTo.h"
13 | #import "EXPMatchers+beGreaterThan.h"
14 | #import "EXPMatchers+beGreaterThanOrEqualTo.h"
15 | #import "EXPMatchers+beLessThan.h"
16 | #import "EXPMatchers+beLessThanOrEqualTo.h"
17 | #import "EXPMatchers+beInTheRangeOf.h"
18 | #import "EXPMatchers+beCloseTo.h"
19 | #import "EXPMatchers+raise.h"
20 | #import "EXPMatchers+raiseWithReason.h"
21 | #import "EXPMatchers+respondTo.h"
22 | #import "EXPMatchers+postNotification.h"
23 | #import "EXPMatchers+beginWith.h"
24 | #import "EXPMatchers+endWith.h"
25 | #import "EXPMatchers+match.h"
26 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/NSObject+Expecta.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface NSObject (Expecta)
4 |
5 | - (void)recordFailureWithDescription:(NSString *)description
6 | inFile:(NSString *)filename
7 | atLine:(NSUInteger)lineNumber
8 | expected:(BOOL)expected;
9 |
10 | @end
11 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/NSValue+Expecta.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface NSValue (Expecta)
4 |
5 | @property (nonatomic) const char *_EXP_objCType;
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/Expecta/NSValue+Expecta.m:
--------------------------------------------------------------------------------
1 | #import "NSValue+Expecta.h"
2 | #import
3 | #import "Expecta.h"
4 |
5 | EXPFixCategoriesBug(NSValue_Expecta);
6 |
7 | @implementation NSValue (Expecta)
8 |
9 | static char _EXP_typeKey;
10 |
11 | - (const char *)_EXP_objCType {
12 | return [(NSString *)objc_getAssociatedObject(self, &_EXP_typeKey) cStringUsingEncoding:NSASCIIStringEncoding];
13 | }
14 |
15 | - (void)set_EXP_objCType:(const char *)_EXP_objCType {
16 | objc_setAssociatedObject(self, &_EXP_typeKey,
17 | @(_EXP_objCType),
18 | OBJC_ASSOCIATION_COPY_NONATOMIC);
19 | }
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Example/Pods/Expecta/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011-2015 Specta Team - https://github.com/specta
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 |
--------------------------------------------------------------------------------
/Example/Pods/Local Podspecs/PINFuture.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "PINFuture",
3 | "version": "5.2.1",
4 | "summary": "An Objective C implementation of the Future pattern that aims to provide maximal type safety.",
5 | "description": "An Objective C implementation of the Future async value pattern that aims to provide maximal type safety.",
6 | "homepage": "https://github.com/pinterest/PINFuture",
7 | "license": {
8 | "type": "Apache License, Version 2.0",
9 | "file": "LICENSE"
10 | },
11 | "authors": {
12 | "Chris Danford": "chrisdanford@gmail.com"
13 | },
14 | "source": {
15 | "git": "https://github.com/pinterest/PINFuture.git",
16 | "tag": "5.2.1"
17 | },
18 | "social_media_url": "https://twitter.com/PinterestEng",
19 | "platforms": {
20 | "ios": "8.0"
21 | },
22 | "source_files": "PINFuture/Classes/**/*",
23 | "weak_frameworks": "Photos",
24 | "frameworks": "Foundation"
25 | }
26 |
--------------------------------------------------------------------------------
/Example/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Expecta (1.0.6)
3 | - PINFuture (5.2.1)
4 | - Specta (1.0.7)
5 |
6 | DEPENDENCIES:
7 | - Expecta
8 | - PINFuture (from `../`)
9 | - Specta
10 |
11 | SPEC REPOS:
12 | trunk:
13 | - Expecta
14 | - Specta
15 |
16 | EXTERNAL SOURCES:
17 | PINFuture:
18 | :path: "../"
19 |
20 | SPEC CHECKSUMS:
21 | Expecta: 3b6bd90a64b9a1dcb0b70aa0e10a7f8f631667d5
22 | PINFuture: a3de8180f634e6af833bf8753e7829e4e69e8f9a
23 | Specta: 3e1bd89c3517421982dc4d1c992503e48bd5fe66
24 |
25 | PODFILE CHECKSUM: 699d06a490a2ae8d8e6dcf963cf46656dad30462
26 |
27 | COCOAPODS: 1.9.1
28 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012-2014 Specta Team.
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 |
21 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTCallSite.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface SPTCallSite : NSObject
4 |
5 | @property (nonatomic, copy, readonly) NSString *file;
6 | @property (nonatomic, readonly) NSUInteger line;
7 |
8 | + (instancetype)callSiteWithFile:(NSString *)file line:(NSUInteger)line;
9 |
10 | - (instancetype)initWithFile:(NSString *)file line:(NSUInteger)line;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTCallSite.m:
--------------------------------------------------------------------------------
1 | #import "SPTCallSite.h"
2 |
3 | @implementation SPTCallSite
4 |
5 | + (instancetype)callSiteWithFile:(NSString *)file line:(NSUInteger)line {
6 | return [[self alloc] initWithFile:file line:line];
7 | }
8 |
9 | - (instancetype)initWithFile:(NSString *)file line:(NSUInteger)line {
10 | self = [super init];
11 | if (self) {
12 | _file = file;
13 | _line = line;
14 | }
15 | return self;
16 | }
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTCompiledExample.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "SpectaTypes.h"
3 |
4 | @interface SPTCompiledExample : NSObject
5 |
6 | @property (nonatomic, copy) NSString *name;
7 | @property (nonatomic, copy) NSString *testCaseName;
8 | @property (nonatomic, copy) SPTSpecBlock block;
9 |
10 | @property (nonatomic) BOOL pending;
11 | @property (nonatomic, getter=isFocused) BOOL focused;
12 |
13 | @property (nonatomic) SEL testMethodSelector;
14 |
15 | - (id)initWithName:(NSString *)name testCaseName:(NSString *)testCaseName block:(SPTSpecBlock)block pending:(BOOL)pending focused:(BOOL)focused;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTCompiledExample.m:
--------------------------------------------------------------------------------
1 | #import "SPTCompiledExample.h"
2 |
3 | @implementation SPTCompiledExample
4 |
5 | - (id)initWithName:(NSString *)name testCaseName:(NSString *)testCaseName block:(SPTSpecBlock)block pending:(BOOL)pending focused:(BOOL)focused {
6 | self = [super init];
7 | if (self) {
8 | self.name = name;
9 | self.testCaseName = testCaseName;
10 | self.block = block;
11 | self.pending = pending;
12 | self.focused = focused;
13 | }
14 | return self;
15 | }
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTExample.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import "SpectaTypes.h"
3 |
4 | @class SPTCallSite;
5 |
6 | @interface SPTExample : NSObject
7 |
8 | @property (nonatomic, copy) NSString *name;
9 | @property (nonatomic, retain) SPTCallSite *callSite;
10 | @property (nonatomic, copy) SPTVoidBlock block;
11 |
12 | @property (nonatomic) BOOL pending;
13 | @property (nonatomic, getter=isFocused) BOOL focused;
14 |
15 | - (id)initWithName:(NSString *)name callSite:(SPTCallSite *)callSite focused:(BOOL)focused block:(SPTVoidBlock)block;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTExample.m:
--------------------------------------------------------------------------------
1 | #import "SPTExample.h"
2 |
3 | @implementation SPTExample
4 |
5 | - (id)initWithName:(NSString *)name callSite:(SPTCallSite *)callSite focused:(BOOL)focused block:(SPTVoidBlock)block {
6 | self = [super init];
7 | if (self) {
8 | self.name = name;
9 | self.callSite = callSite;
10 | self.block = block;
11 | self.focused = focused;
12 | self.pending = block == nil;
13 | }
14 | return self;
15 | }
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTExampleGroup.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "SpectaTypes.h"
4 |
5 | @class SPTExample;
6 | @class SPTCallSite;
7 |
8 | @interface SPTExampleGroup : NSObject
9 |
10 | @property (nonatomic, copy) NSString *name;
11 | @property (nonatomic, weak) SPTExampleGroup *root;
12 | @property (nonatomic, weak) SPTExampleGroup *parent;
13 | @property (nonatomic, strong) NSMutableArray *children;
14 | @property (nonatomic, strong) NSMutableArray *beforeAllArray;
15 | @property (nonatomic, strong) NSMutableArray *afterAllArray;
16 | @property (nonatomic, strong) NSMutableArray *beforeEachArray;
17 | @property (nonatomic, strong) NSMutableArray *afterEachArray;
18 | @property (nonatomic, strong) NSMutableDictionary *sharedExamples;
19 | @property (nonatomic) unsigned int exampleCount;
20 | @property (nonatomic) unsigned int ranExampleCount;
21 | @property (nonatomic) unsigned int pendingExampleCount;
22 | @property (nonatomic, getter=isFocused) BOOL focused;
23 |
24 | - (id)initWithName:(NSString *)name parent:(SPTExampleGroup *)parent root:(SPTExampleGroup *)root;
25 |
26 | - (SPTExampleGroup *)addExampleGroupWithName:(NSString *)name focused:(BOOL)focused;
27 | - (SPTExample *)addExampleWithName:(NSString *)name callSite:(SPTCallSite *)callSite focused:(BOOL)focused block:(SPTVoidBlock)block;
28 |
29 | - (void)addBeforeAllBlock:(SPTVoidBlock)block;
30 | - (void)addAfterAllBlock:(SPTVoidBlock)block;
31 | - (void)addBeforeEachBlock:(SPTVoidBlock)block;
32 | - (void)addAfterEachBlock:(SPTVoidBlock)block;
33 |
34 | - (NSArray *)compileExamplesWithStack:(NSArray *)stack;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTExcludeGlobalBeforeAfterEach.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Specta Team. All rights reserved.
3 | */
4 | #import
5 |
6 | // This protocol was used for blacklisting classes for global beforeEach and afterEach blocks.
7 | // Now, instead, classes are whitelisted by implementing the SPTGlobalBeforeAfterEach protocol.
8 | __deprecated_msg("Please whitelist classes instead with the SPTGlobalBeforeAfterEach protocol")
9 | @protocol SPTExcludeGlobalBeforeAfterEach
10 | @end
11 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTGlobalBeforeAfterEach.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Specta Team. All rights reserved.
3 | */
4 | #import
5 |
6 | // This protocol is used for whitelisting classes for global beforeEach and afterEach blocks.
7 | // If you want a class to participate in those just add this protocol to a category and it will be
8 | // included.
9 | @protocol SPTGlobalBeforeAfterEach
10 |
11 | @optional
12 | + (void)beforeEach;
13 | + (void)afterEach;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTSharedExampleGroups.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | @class _XCTestCaseImplementation;
6 |
7 | @class SPTExampleGroup;
8 |
9 | @interface SPTSharedExampleGroups : XCTestCase
10 |
11 | + (void)addSharedExampleGroupWithName:(NSString *)name block:(SPTDictionaryBlock)block exampleGroup:(SPTExampleGroup *)exampleGroup;
12 | + (SPTDictionaryBlock)sharedExampleGroupWithName:(NSString *)name exampleGroup:(SPTExampleGroup *)exampleGroup;
13 |
14 | - (void)sharedExampleGroups;
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTSharedExampleGroups.m:
--------------------------------------------------------------------------------
1 | #import "SPTSharedExampleGroups.h"
2 | #import "SPTExampleGroup.h"
3 | #import "SPTSpec.h"
4 | #import "SpectaUtility.h"
5 | #import
6 |
7 | NSMutableDictionary *globalSharedExampleGroups = nil;
8 | BOOL initialized = NO;
9 |
10 | @implementation SPTSharedExampleGroups
11 |
12 | + (void)initialize {
13 | Class SPTSharedExampleGroupsClass = [SPTSharedExampleGroups class];
14 | if ([self class] == SPTSharedExampleGroupsClass) {
15 | if (!initialized) {
16 | initialized = YES;
17 | globalSharedExampleGroups = [[NSMutableDictionary alloc] init];
18 |
19 | Class *classes = NULL;
20 | int numClasses = objc_getClassList(NULL, 0);
21 |
22 | if (numClasses > 0) {
23 | classes = (Class *)malloc(sizeof(Class) * numClasses);
24 | numClasses = objc_getClassList(classes, numClasses);
25 |
26 | Class klass, superClass;
27 | for(uint i = 0; i < numClasses; i++) {
28 | klass = classes[i];
29 | superClass = class_getSuperclass(klass);
30 | if (superClass == SPTSharedExampleGroupsClass) {
31 | [[[klass alloc] init] sharedExampleGroups];
32 | }
33 | }
34 |
35 | free(classes);
36 | }
37 | }
38 | }
39 | }
40 |
41 | + (void)addSharedExampleGroupWithName:(NSString *)name block:(SPTDictionaryBlock)block exampleGroup:(SPTExampleGroup *)exampleGroup {
42 | (exampleGroup == nil ? globalSharedExampleGroups : exampleGroup.sharedExamples)[name] = [block copy];
43 | }
44 |
45 | + (SPTDictionaryBlock)sharedExampleGroupWithName:(NSString *)name exampleGroup:(SPTExampleGroup *)exampleGroup {
46 | SPTDictionaryBlock sharedExampleGroup = nil;
47 | while (exampleGroup != nil) {
48 | if ((sharedExampleGroup = exampleGroup.sharedExamples[name])) {
49 | return sharedExampleGroup;
50 | }
51 | exampleGroup = exampleGroup.parent;
52 | }
53 | return globalSharedExampleGroups[name];
54 | }
55 |
56 | - (void)sharedExampleGroups {}
57 |
58 | - (void)spt_handleException:(NSException *)exception {
59 | [SPTCurrentSpec spt_handleException:exception];
60 | }
61 |
62 | - (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filename atLine:(NSUInteger)lineNumber expected:(BOOL)expected {
63 | [SPTCurrentSpec recordFailureWithDescription:description inFile:filename atLine:lineNumber expected:expected];
64 | }
65 |
66 | - (void)_recordUnexpectedFailureWithDescription:(NSString *)description exception:(NSException *)exception {
67 | [SPTCurrentSpec _recordUnexpectedFailureWithDescription:description exception:exception];
68 | }
69 |
70 | - (_XCTestCaseImplementation *)internalImplementation {
71 | return [SPTCurrentSpec internalImplementation];
72 | }
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTSpec.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @class
5 | SPTTestSuite
6 | , SPTCompiledExample
7 | ;
8 |
9 | @interface SPTSpec : XCTestCase
10 |
11 | @property (strong) XCTestCaseRun *spt_run;
12 | @property (nonatomic) BOOL spt_pending;
13 | @property (nonatomic) BOOL spt_skipped;
14 |
15 | + (BOOL)spt_isDisabled;
16 | + (void)spt_setDisabled:(BOOL)disabled;
17 | + (BOOL)spt_focusedExamplesExist;
18 | + (SEL)spt_convertToTestMethod:(SPTCompiledExample *)example;
19 | + (SPTTestSuite *)spt_testSuite;
20 | + (void)spt_setCurrentTestSuite;
21 | + (void)spt_unsetCurrentTestSuite;
22 | + (void)spt_setCurrentTestSuiteFileName:(NSString *)fileName lineNumber:(NSUInteger)lineNumber;
23 |
24 | - (void)spec;
25 | - (BOOL)spt_shouldRunExample:(SPTCompiledExample *)example;
26 | - (void)spt_runExample:(SPTCompiledExample *)example;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTTestSuite.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @class
4 | SPTExample
5 | , SPTExampleGroup
6 | ;
7 |
8 | @interface SPTTestSuite : NSObject
9 |
10 | @property (nonatomic, strong) SPTExampleGroup *rootGroup;
11 | @property (nonatomic, strong) NSMutableArray *groupStack;
12 | @property (nonatomic, strong) NSArray *compiledExamples;
13 | @property (nonatomic, copy) NSString *fileName;
14 | @property (nonatomic) NSUInteger lineNumber;
15 | @property (nonatomic, getter = isDisabled) BOOL disabled;
16 | @property (nonatomic) BOOL hasFocusedExamples;
17 |
18 | - (SPTExampleGroup *)currentGroup;
19 | - (void)compile;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SPTTestSuite.m:
--------------------------------------------------------------------------------
1 | #import "SPTTestSuite.h"
2 | #import "SPTExampleGroup.h"
3 | #import "SPTCompiledExample.h"
4 |
5 | @implementation SPTTestSuite
6 |
7 | - (id)init {
8 | self = [super init];
9 | if (self) {
10 | self.rootGroup = [[SPTExampleGroup alloc] init];
11 | self.rootGroup.root = self.rootGroup;
12 | self.groupStack = [NSMutableArray arrayWithObject:self.rootGroup];
13 | }
14 | return self;
15 | }
16 |
17 | - (SPTExampleGroup *)currentGroup {
18 | return [self.groupStack lastObject];
19 | }
20 |
21 | - (void)compile {
22 | self.compiledExamples = [self.rootGroup compileExamplesWithStack:@[]];
23 | for (SPTCompiledExample *example in self.compiledExamples) {
24 | if (example.focused) {
25 | self.hasFocusedExamples = YES;
26 | break;
27 | }
28 | }
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/Specta.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | //! Project version number for Specta.
5 | FOUNDATION_EXPORT double SpectaVersionNumber;
6 |
7 | //! Project version string for Specta.
8 | FOUNDATION_EXPORT const unsigned char SpectaVersionString[];
9 |
10 | // In this header, you should import all the public headers of your framework using statements like #import
11 |
12 | #import
13 | #import
14 | #import
15 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SpectaTypes.h:
--------------------------------------------------------------------------------
1 | @class SPTSpec;
2 |
3 | typedef void (^SPTVoidBlock)(void);
4 | typedef void (^SPTSpecBlock)(SPTSpec *spec);
5 | typedef void (^SPTDictionaryBlock)(NSDictionary *dictionary);
6 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/SpectaUtility.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | extern NSString * const spt_kCurrentTestSuiteKey;
4 | extern NSString * const spt_kCurrentSpecKey;
5 |
6 | #define SPTCurrentTestSuite [[NSThread mainThread] threadDictionary][spt_kCurrentTestSuiteKey]
7 | #define SPTCurrentSpec [[NSThread mainThread] threadDictionary][spt_kCurrentSpecKey]
8 | #define SPTCurrentGroup [SPTCurrentTestSuite currentGroup]
9 | #define SPTGroupStack [SPTCurrentTestSuite groupStack]
10 |
11 | #define SPTReturnUnlessBlockOrNil(block) if ((block) && !SPTIsBlock((block))) return;
12 | #define SPTIsBlock(obj) [(obj) isKindOfClass:NSClassFromString(@"NSBlock")]
13 |
14 | BOOL spt_isSpecClass(Class aClass);
15 | NSString *spt_underscorize(NSString *string);
16 | NSArray *spt_map(NSArray *array, id (^block)(id obj, NSUInteger idx));
17 | NSArray *spt_shuffle(NSArray *array);
18 | unsigned int spt_seed(void);
19 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/XCTest+Private.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
4 |
5 | @interface XCTestObservationCenter (SPTTestSuspention)
6 |
7 | - (void)_suspendObservationForBlock:(void (^)(void))block;
8 |
9 | @end
10 |
11 | #else
12 |
13 | @interface XCTestObservationCenter : NSObject
14 |
15 | + (id)sharedObservationCenter;
16 | - (void)_suspendObservationForBlock:(void (^)(void))block;
17 |
18 | @end
19 |
20 | @protocol XCTestObservation
21 | @end
22 |
23 |
24 | #endif
25 |
26 | @interface _XCTestDriverTestObserver : NSObject
27 |
28 | - (void)stopObserving;
29 | - (void)startObserving;
30 |
31 | @end
32 |
33 | @interface _XCTestCaseImplementation : NSObject
34 | @end
35 |
36 | @interface XCTestCase ()
37 |
38 | - (_XCTestCaseImplementation *)internalImplementation;
39 | - (void)_recordUnexpectedFailureWithDescription:(NSString *)description exception:(NSException *)exception;
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/XCTestCase+Specta.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @interface XCTestCase (Specta)
4 |
5 | - (void)spt_handleException:(NSException *)exception;
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/Example/Pods/Specta/Specta/Specta/XCTestCase+Specta.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import "XCTestCase+Specta.h"
3 | #import "SPTSpec.h"
4 | #import "SPTExample.h"
5 | #import "SPTSharedExampleGroups.h"
6 | #import "SpectaUtility.h"
7 | #import "XCTest+Private.h"
8 |
9 | @interface XCTestCase (xct_allSubclasses)
10 |
11 | - (NSArray *)allSubclasses;
12 | - (void)_dequeueFailures;
13 |
14 | @end
15 |
16 | @implementation XCTestCase (Specta)
17 |
18 | + (void)load {
19 | Method allSubclasses = class_getClassMethod(self, @selector(allSubclasses));
20 | Method allSubclasses_swizzle = class_getClassMethod(self , @selector(spt_allSubclasses_swizzle));
21 | method_exchangeImplementations(allSubclasses, allSubclasses_swizzle);
22 |
23 | Method dequeueFailures = class_getInstanceMethod(self, @selector(_dequeueFailures));
24 | Method dequeueFailures_swizzle = class_getInstanceMethod(self, @selector(spt_dequeueFailures));
25 | method_exchangeImplementations(dequeueFailures, dequeueFailures_swizzle);
26 | }
27 |
28 | + (NSArray *)spt_allSubclasses_swizzle {
29 | NSArray *subclasses = [self spt_allSubclasses_swizzle]; // call original
30 | NSMutableArray *filtered = [NSMutableArray arrayWithCapacity:[subclasses count]];
31 | // exclude SPTSpec base class and all subclasses of SPTSharedExampleGroups
32 | for (id subclass in subclasses) {
33 | if (subclass != [SPTSpec class] && ![subclass isKindOfClass:[SPTSharedExampleGroups class]]) {
34 | [filtered addObject:subclass];
35 | }
36 | }
37 | return spt_shuffle(filtered);
38 | }
39 |
40 | - (void)spt_dequeueFailures {
41 | void(^dequeueFailures)() = ^() {
42 | [self spt_dequeueFailures];
43 | };
44 |
45 | BOOL isMainThread = [NSThread isMainThread];
46 | BOOL isSpectaTest = [self isKindOfClass:[SPTSpec class]];
47 |
48 | if (!isSpectaTest || isMainThread) {
49 | dequeueFailures();
50 | } else {
51 | dispatch_sync(dispatch_get_main_queue(), dequeueFailures);
52 | }
53 | }
54 |
55 | - (void)spt_handleException:(NSException *)exception {
56 | NSString *description = [exception reason];
57 | if ([exception userInfo]) {
58 | id line = [exception userInfo][@"line"];
59 | id file = [exception userInfo][@"file"];
60 | if ([line isKindOfClass:[NSNumber class]] && [file isKindOfClass:[NSString class]]) {
61 | [self recordFailureWithDescription:description inFile:file atLine:[line unsignedIntegerValue] expected:YES];
62 | return;
63 | }
64 | }
65 | [self _recordUnexpectedFailureWithDescription:description exception:exception];
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Expecta/Expecta-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.6
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Expecta/Expecta-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Expecta : NSObject
3 | @end
4 | @implementation PodsDummy_Expecta
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Expecta/Expecta-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Expecta/Expecta-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 | #import "EXPBlockDefinedMatcher.h"
14 | #import "EXPDefines.h"
15 | #import "EXPDoubleTuple.h"
16 | #import "Expecta.h"
17 | #import "ExpectaObject.h"
18 | #import "ExpectaSupport.h"
19 | #import "EXPExpect.h"
20 | #import "EXPFloatTuple.h"
21 | #import "EXPMatcher.h"
22 | #import "EXPUnsupportedObject.h"
23 | #import "EXPMatcherHelpers.h"
24 | #import "EXPMatchers+beCloseTo.h"
25 | #import "EXPMatchers+beFalsy.h"
26 | #import "EXPMatchers+beginWith.h"
27 | #import "EXPMatchers+beGreaterThan.h"
28 | #import "EXPMatchers+beGreaterThanOrEqualTo.h"
29 | #import "EXPMatchers+beIdenticalTo.h"
30 | #import "EXPMatchers+beInstanceOf.h"
31 | #import "EXPMatchers+beInTheRangeOf.h"
32 | #import "EXPMatchers+beKindOf.h"
33 | #import "EXPMatchers+beLessThan.h"
34 | #import "EXPMatchers+beLessThanOrEqualTo.h"
35 | #import "EXPMatchers+beNil.h"
36 | #import "EXPMatchers+beSubclassOf.h"
37 | #import "EXPMatchers+beSupersetOf.h"
38 | #import "EXPMatchers+beTruthy.h"
39 | #import "EXPMatchers+conformTo.h"
40 | #import "EXPMatchers+contain.h"
41 | #import "EXPMatchers+endWith.h"
42 | #import "EXPMatchers+equal.h"
43 | #import "EXPMatchers+haveCountOf.h"
44 | #import "EXPMatchers+match.h"
45 | #import "EXPMatchers+postNotification.h"
46 | #import "EXPMatchers+raise.h"
47 | #import "EXPMatchers+raiseWithReason.h"
48 | #import "EXPMatchers+respondTo.h"
49 | #import "EXPMatchers.h"
50 | #import "NSObject+Expecta.h"
51 | #import "NSValue+Expecta.h"
52 |
53 | FOUNDATION_EXPORT double ExpectaVersionNumber;
54 | FOUNDATION_EXPORT const unsigned char ExpectaVersionString[];
55 |
56 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Expecta/Expecta.debug.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Expecta
2 | ENABLE_BITCODE = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib"
6 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "XCTest"
7 | PODS_BUILD_DIR = ${BUILD_DIR}
8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
9 | PODS_ROOT = ${SRCROOT}
10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Expecta
11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
12 | SKIP_INSTALL = YES
13 | SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib"
14 | SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
16 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Expecta/Expecta.modulemap:
--------------------------------------------------------------------------------
1 | framework module Expecta {
2 | umbrella header "Expecta-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Expecta/Expecta.release.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Expecta
2 | ENABLE_BITCODE = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib"
6 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "XCTest"
7 | PODS_BUILD_DIR = ${BUILD_DIR}
8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
9 | PODS_ROOT = ${SRCROOT}
10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Expecta
11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
12 | SKIP_INSTALL = YES
13 | SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib"
14 | SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
16 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Expecta/Expecta.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Expecta
2 | ENABLE_BITCODE = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
6 | OTHER_LDFLAGS = -framework "Foundation" -framework "XCTest"
7 | PODS_BUILD_DIR = $BUILD_DIR
8 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
9 | PODS_ROOT = ${SRCROOT}
10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Expecta
11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
12 | SKIP_INSTALL = YES
13 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Expecta/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.5
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/PINFuture/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 5.1.1
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/PINFuture/PINFuture-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 5.2.1
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/PINFuture/PINFuture-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_PINFuture : NSObject
3 | @end
4 | @implementation PodsDummy_PINFuture
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/PINFuture/PINFuture-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/PINFuture/PINFuture-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 | #import "NSURLSession+PINFuture.h"
14 | #import "PHImageManager+PINFuture.h"
15 | #import "PINNSURLSessionDataTaskAndResult.h"
16 | #import "PINNSURLSessionDataTaskResult.h"
17 | #import "PINPHImageManagerImageDataResult.h"
18 | #import "PINCancelToken.h"
19 | #import "PINDefines.h"
20 | #import "PINExecutor.h"
21 | #import "PINFuture+ChainSideEffect.h"
22 | #import "PINFuture+Completion.h"
23 | #import "PINFuture+Delay.h"
24 | #import "PINFuture+Dispatch.h"
25 | #import "PINFuture+FlatMapError.h"
26 | #import "PINFuture+GatherAll.h"
27 | #import "PINFuture+GatherSome.h"
28 | #import "PINFuture+Generated.h"
29 | #import "PINFuture+MapError.h"
30 | #import "PINFuture+MapToValue.h"
31 | #import "PINFuture+NoValue.h"
32 | #import "PINFuture.h"
33 | #import "PINFutureAndCancelToken.h"
34 | #import "PINFutureError.h"
35 | #import "PINFutureMap+FlatMap.h"
36 | #import "PINFutureMap+Map.h"
37 | #import "PINFutureMap.h"
38 | #import "PINFutureOnce.h"
39 | #import "PINFuturePending.h"
40 |
41 | FOUNDATION_EXPORT double PINFutureVersionNumber;
42 | FOUNDATION_EXPORT const unsigned char PINFutureVersionString[];
43 |
44 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/PINFuture/PINFuture.debug.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PINFuture
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -weak_framework "Photos"
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/PINFuture/PINFuture.modulemap:
--------------------------------------------------------------------------------
1 | framework module PINFuture {
2 | umbrella header "PINFuture-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/PINFuture/PINFuture.release.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PINFuture
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -weak_framework "Photos"
4 | PODS_BUILD_DIR = ${BUILD_DIR}
5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
6 | PODS_ROOT = ${SRCROOT}
7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/PINFuture/PINFuture.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/PINFuture
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
4 | OTHER_LDFLAGS = -framework "Foundation" -weak_framework "Photos"
5 | PODS_BUILD_DIR = $BUILD_DIR
6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
10 | SKIP_INSTALL = YES
11 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Example/Pods-PINFuture_Example-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Example/Pods-PINFuture_Example-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_PINFuture_Example : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_PINFuture_Example
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Example/Pods-PINFuture_Example-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_PINFuture_ExampleVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_PINFuture_ExampleVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Example/Pods-PINFuture_Example.debug.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINFuture"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINFuture/PINFuture.framework/Headers"
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "PINFuture" -weak_framework "Photos"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Example/Pods-PINFuture_Example.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_PINFuture_Example {
2 | umbrella header "Pods-PINFuture_Example-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Example/Pods-PINFuture_Example.release.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINFuture"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PINFuture/PINFuture.framework/Headers"
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "PINFuture" -weak_framework "Photos"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Tests/Pods-PINFuture_Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Tests/Pods-PINFuture_Tests-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_PINFuture_Tests : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_PINFuture_Tests
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Tests/Pods-PINFuture_Tests-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_PINFuture_TestsVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_PINFuture_TestsVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Tests/Pods-PINFuture_Tests.debug.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/Expecta" "${PODS_CONFIGURATION_BUILD_DIR}/PINFuture" "${PODS_CONFIGURATION_BUILD_DIR}/Specta"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Expecta/Expecta.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINFuture/PINFuture.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Specta/Specta.framework/Headers"
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_LDFLAGS = $(inherited) -framework "Expecta" -framework "Foundation" -framework "PINFuture" -framework "Specta" -framework "XCTest" -weak_framework "Photos"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Tests/Pods-PINFuture_Tests.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_PINFuture_Tests {
2 | umbrella header "Pods-PINFuture_Tests-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-PINFuture_Tests/Pods-PINFuture_Tests.release.xcconfig:
--------------------------------------------------------------------------------
1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/Expecta" "${PODS_CONFIGURATION_BUILD_DIR}/PINFuture" "${PODS_CONFIGURATION_BUILD_DIR}/Specta"
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Expecta/Expecta.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PINFuture/PINFuture.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Specta/Specta.framework/Headers"
4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
5 | OTHER_LDFLAGS = $(inherited) -framework "Expecta" -framework "Foundation" -framework "PINFuture" -framework "Specta" -framework "XCTest" -weak_framework "Photos"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Specta/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.5
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Specta/Specta-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.7
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Specta/Specta-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Specta : NSObject
3 | @end
4 | @implementation PodsDummy_Specta
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Specta/Specta-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Specta/Specta-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 | #import "Specta.h"
14 | #import "SpectaDSL.h"
15 | #import "SpectaTypes.h"
16 | #import "SpectaUtility.h"
17 | #import "SPTCallSite.h"
18 | #import "SPTCompiledExample.h"
19 | #import "SPTExample.h"
20 | #import "SPTExampleGroup.h"
21 | #import "SPTExcludeGlobalBeforeAfterEach.h"
22 | #import "SPTGlobalBeforeAfterEach.h"
23 | #import "SPTSharedExampleGroups.h"
24 | #import "SPTSpec.h"
25 | #import "SPTTestSuite.h"
26 | #import "XCTest+Private.h"
27 | #import "XCTestCase+Specta.h"
28 |
29 | FOUNDATION_EXPORT double SpectaVersionNumber;
30 | FOUNDATION_EXPORT const unsigned char SpectaVersionString[];
31 |
32 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Specta/Specta.debug.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Specta
2 | ENABLE_BITCODE = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib"
6 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "XCTest"
7 | PODS_BUILD_DIR = ${BUILD_DIR}
8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
9 | PODS_ROOT = ${SRCROOT}
10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Specta
11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
12 | SKIP_INSTALL = YES
13 | SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib"
14 | SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
16 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Specta/Specta.modulemap:
--------------------------------------------------------------------------------
1 | framework module Specta {
2 | umbrella header "Specta-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Specta/Specta.release.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Specta
2 | ENABLE_BITCODE = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | LIBRARY_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib"
6 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "XCTest"
7 | PODS_BUILD_DIR = ${BUILD_DIR}
8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
9 | PODS_ROOT = ${SRCROOT}
10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Specta
11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
12 | SKIP_INSTALL = YES
13 | SWIFT_INCLUDE_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/usr/lib"
14 | SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
16 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Specta/Specta.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Specta
2 | ENABLE_BITCODE = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
6 | OTHER_LDFLAGS = -framework "Foundation" -framework "XCTest"
7 | PODS_BUILD_DIR = $BUILD_DIR
8 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
9 | PODS_ROOT = ${SRCROOT}
10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Specta
11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
12 | SKIP_INSTALL = YES
13 |
--------------------------------------------------------------------------------
/Example/Tests/PINCancelTokenTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINCancelTokenTests.m
3 | // PINFuture
4 | //
5 | // Created by Brandon Kase on 12/30/16.
6 | // Copyright © 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "TestUtil.h"
10 |
11 | // TODO: Do real cancel tests
12 | /*SpecBegin(PINCancelTokenSpecs)
13 |
14 | describe(@"cancel tokens", ^{
15 | it(@"cancellation works", ^{
16 | NSNumber *valueA = numberFixture();
17 | NSString *valueB = stringFixture();
18 | PINTask *taskA = [PINTask value:valueA];
19 | PINTask *taskB = [PINTaskMap executor:[PINExecutor immediate] map:taskA success:^PINFuture *(NSNumber *fromValue) {
20 | return [PINFuture withValue:valueB];
21 | }];
22 | runTaskAndExpectToFulfillWith(self, taskB, valueB);
23 | });
24 | });
25 |
26 | SpecEnd*/
27 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+ChainSideEffectTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+ChainSideEffectTests.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 1/27/17.
6 | // Copyright © 2017 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture.h"
10 | #import "TestUtil.h"
11 |
12 | SpecBegin(PINFutureChainSideEffectSpecs)
13 |
14 | describe(@"chainSideEffect", ^{
15 |
16 | // This executor always dispatches to the main queue to ensure that the future won't resolve until the callstack has unwound.
17 | id delayedExecutor = [PINExecutor queue:dispatch_get_main_queue()];
18 |
19 | it(@"expected callbacks called for a fulfilled Future", ^{
20 | NSString *value = stringFixture();
21 | PINFuture *chained = [PINFuture withValue:value];
22 | __block BOOL successCalled = NO;
23 | __block BOOL failureCalled = NO;
24 | __block BOOL completionCalled = NO;
25 | chained = [chained executor:delayedExecutor chainSuccess:^(NSString *value) {
26 | successCalled = YES;
27 | } failure:^(NSError *error) {
28 | failureCalled = YES;
29 | }];
30 | chained = [chained executor:delayedExecutor chainCompletion:^{
31 | completionCalled = YES;
32 | }];
33 | expectFutureToFulfillWith(self, chained, value);
34 | expect(successCalled).to.beTruthy();
35 | expect(failureCalled).to.beFalsy();
36 | expect(completionCalled).to.beTruthy();
37 | });
38 |
39 | it(@"expected callbacks called for a rejected Future", ^{
40 | NSError *error = errorFixture();
41 | PINFuture *chained = [PINFuture withError:error];
42 | __block BOOL successCalled = NO;
43 | __block BOOL failureCalled = NO;
44 | __block BOOL completionCalled = NO;
45 | chained = [chained executor:delayedExecutor chainSuccess:^(NSString *value) {
46 | successCalled = YES;
47 | } failure:^(NSError *error) {
48 | failureCalled = YES;
49 | }];
50 | chained = [chained executor:delayedExecutor chainCompletion:^{
51 | completionCalled = YES;
52 | }];
53 | expectFutureToRejectWith(self, chained, error);
54 | expect(successCalled).to.beFalsy();
55 | expect(failureCalled).to.beTruthy();
56 | expect(completionCalled).to.beTruthy();
57 | });
58 |
59 | it(@"chainSuccess:failure: doesn't blow up if callbacks are nil", ^{
60 | NSString *value = stringFixture();
61 | PINFuture *chained = [PINFuture withValue:value];
62 | chained = [chained executor:delayedExecutor chainSuccess:nil failure:nil];
63 | expectFutureToFulfillWith(self, chained, value);
64 | });
65 | });
66 |
67 | SpecEnd
68 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+CompletionTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+CompletionTests.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 1/28/17.
6 | // Copyright © 2017 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture.h"
10 | #import "TestUtil.h"
11 |
12 | SpecBegin(PINFutureCompletionSpecs)
13 |
14 | describe(@"completion", ^{
15 |
16 | // This executor always dispatches to the main queue to ensure that the future won't resolve until the callstack has unwound.
17 | id delayedExecutor = [PINExecutor queue:dispatch_get_main_queue()];
18 |
19 | it(@"expected callbacks called for a fulfilled Future", ^{
20 | NSString *value = stringFixture();
21 | PINFuture *future = [PINFuture withValue:value];
22 | __block BOOL completionCalled = NO;
23 | [future executor:delayedExecutor completion:^{
24 | completionCalled = YES;
25 | }];
26 | expectFutureToFulfillWith(self, future, value);
27 | expect(completionCalled).to.beTruthy();
28 | });
29 |
30 | it(@"expected callbacks called for a rejected Future", ^{
31 | NSError *error = errorFixture();
32 | PINFuture *future = [PINFuture withError:error];
33 | __block BOOL completionCalled = NO;
34 | [future executor:delayedExecutor completion:^{
35 | completionCalled = YES;
36 | }];
37 | expectFutureToRejectWith(self, future, error);
38 | expect(completionCalled).to.beTruthy();
39 | });
40 | });
41 |
42 | SpecEnd
43 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+DelayTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+Delay.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 1/31/17.
6 | // Copyright © 2018 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture.h"
10 | #import "TestUtil.h"
11 |
12 | SpecBegin(PINFutureDelaySpecs)
13 |
14 | describe(@"Delay", ^{
15 | it(@"can delay", ^{
16 | PINFutureNoValue *delay = [PINFuture delay:0];
17 | expectFutureToFulfillWith(self, delay, [NSNull null]);
18 | });
19 | });
20 |
21 | SpecEnd
22 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+DispatchTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // DispatchTests.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/5/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | // https://github.com/Specta/Specta
10 |
11 | #import "PINFuture.h"
12 |
13 | #import "TestUtil.h"
14 |
15 | dispatch_queue_t backgroundQueue() {
16 | return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
17 | }
18 |
19 | SpecBegin(PINFutureDispatchSpecs)
20 |
21 | describe(@"dispatch", ^{
22 | id executor = [PINExecutor background];
23 |
24 | it(@"resolve on background queue", ^{
25 | NSString *value = stringFixture();
26 | PINFuture *future = [PINFuture executor:executor block:^PINFuture * _Nonnull{
27 | return [PINFuture withValue:value];
28 | }];
29 | expectFutureToFulfillWith(self, future, value);
30 | });
31 |
32 | it(@"reject on background queue", ^{
33 | NSError *error = errorFixture();
34 | PINFuture *future = [PINFuture executor:executor block:^PINFuture * _Nonnull{
35 | return [PINFuture withError:error];
36 | }];
37 | expectFutureToRejectWith(self, future, error);
38 | });
39 | });
40 |
41 | SpecEnd
42 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+FlatMapErrorTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+FlatMapError.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/8/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture.h"
10 | #import "TestUtil.h"
11 |
12 | SpecBegin(PINFutureFlatMapErrorSpecs)
13 |
14 | describe(@"flatMapError", ^{
15 | it(@"can return a resolved future", ^{
16 | NSError *error1 = errorFixture();
17 | NSString *value2 = stringFixture();
18 | PINFuture *source = [PINFuture withError:error1];
19 | PINFuture *mapped = [source executor:[PINExecutor immediate] flatMapError:^PINFuture *(NSError *error) {
20 | return [PINFuture withValue:value2];
21 | }];
22 | expectFutureToFulfillWith(self, mapped, value2);
23 | });
24 |
25 | it(@"can return a rejected future", ^{
26 | NSError *error1 = errorFixture();
27 | NSError *error2 = errorFixture();
28 | PINFuture *source = [PINFuture withError:error1];
29 | PINFuture *mapped = [source executor:[PINExecutor immediate] flatMapError:^PINFuture *(NSError *error) {
30 | return [PINFuture withError:error2];
31 | }];
32 | expectFutureToRejectWith(self, mapped, error2);
33 | });
34 |
35 | it(@"raises exception when nil is returned instead of a PINFuture", ^{
36 | NSError *error1 = errorFixture();
37 | PINFuture *source = [PINFuture withError:error1];
38 | expect(^{
39 | __unused PINFuture *mapped = [source executor:[PINExecutor immediate] flatMapError:^PINFuture *(NSError *error) {
40 | return nil;
41 | }];
42 | }).to.raiseAny();
43 | });
44 | });
45 |
46 | SpecEnd
47 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+GatherAllTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+GatherAllTests.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/5/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | // https://github.com/Specta/Specta
10 |
11 | #import "PINFuture.h"
12 | #import "TestUtil.h"
13 |
14 | SpecBegin(PINFutureGatherAllSpecs)
15 |
16 | describe(@"gatherAll", ^{
17 | it(@"resolves if all source futures resolve", ^{
18 | NSString *value1 = stringFixture();
19 | NSString *value2 = stringFixture();
20 | PINFuture *source1 = [PINFuture withValue:value1];
21 | PINFuture *source2 = [PINFuture withValue:value2];
22 | PINFuture *> *arrayFuture = [PINFuture gatherAll:@[source1, source2]];
23 | expectFutureToFulfillWith(self, arrayFuture, @[value1, value2]);
24 | });
25 |
26 | it(@"rejects if any source future rejects", ^{
27 | NSString *value1 = stringFixture();
28 | NSError *error2 = errorFixture();
29 | PINFuture *source1 = [PINFuture withValue:value1];
30 | PINFuture *source2 = [PINFuture withError:error2];
31 | PINFuture *> *arrayFuture = [PINFuture gatherAll:@[source1, source2]];
32 | expectFutureToRejectWith(self, arrayFuture, error2);
33 | });
34 | });
35 |
36 | SpecEnd
37 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+GatherSomeTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+GatherSomeTests.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 8/16/17.
6 | // Copyright © 2017 Pinterest. All rights reserved.
7 | //
8 |
9 |
10 | // https://github.com/Specta/Specta
11 |
12 | #import "PINFuture.h"
13 | #import "TestUtil.h"
14 |
15 | SpecBegin(PINFutureGatherSomeSpecs)
16 |
17 | describe(@"gatherSome", ^{
18 | it(@"resolves with a mix of resolved and rejected futures ", ^{
19 | NSError *error1 = errorFixture();
20 | NSString *value2 = stringFixture();
21 | PINFuture *source1 = [PINFuture withError:error1];
22 | PINFuture *source2 = [PINFuture withValue:value2];
23 | PINFuture *arrayFuture = [PINFuture gatherSome:@[source1, source2]];
24 | expectFutureToFulfillWith(self, arrayFuture, @[[NSNull null], value2]);
25 | });
26 | });
27 |
28 | SpecEnd
29 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+MapErrorTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+MapError.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/8/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture.h"
10 | #import "TestUtil.h"
11 |
12 | SpecBegin(PINFutureMapErrorSpecs)
13 |
14 | describe(@"mapError", ^{
15 | it(@"can return a new error", ^{
16 | NSError *error = errorFixture();
17 | NSString *value = stringFixture();
18 | PINFuture *source = [PINFuture withError:error];
19 | PINFuture *mapped = [source executor:[PINExecutor immediate] mapError:^NSString *(NSError *error) {
20 | return value;
21 | }];
22 | expectFutureToFulfillWith(self, mapped, value);
23 | });
24 | });
25 |
26 | SpecEnd
27 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+MapToValueTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+MapToValue.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 1/31/17.
6 | // Copyright © 2017 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture.h"
10 | #import "TestUtil.h"
11 |
12 | SpecBegin(PINFutureMapToValueSpecs)
13 |
14 | describe(@"mapToValue", ^{
15 | it(@"can mapToValue", ^{
16 | NSNumber *numberValue = numberFixture();
17 | NSString *stringValue = stringFixture();
18 | PINFuture *source = [PINFuture withValue:numberValue];
19 | PINFuture *mapped = [PINFuture map:source toValue:stringValue];
20 | expectFutureToFulfillWith(self, mapped, stringValue);
21 | });
22 | });
23 |
24 | SpecEnd
25 |
--------------------------------------------------------------------------------
/Example/Tests/PINFuture+NoValueTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+NoValueTests.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 1/31/17.
6 | // Copyright © 2018 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture.h"
10 | #import "TestUtil.h"
11 |
12 | SpecBegin(PINFutureNoValueSpecs)
13 |
14 | describe(@"NoValue", ^{
15 | it(@"can mapToNoValue", ^{
16 | NSString *value = stringFixture();
17 | PINFuture *source = [PINFuture withValue:value];
18 | PINFutureNoValue *mapped = [source mapToNoValue];
19 |
20 | expectFutureToFulfillWith(self, mapped, [NSNull null]);
21 | });
22 |
23 | it(@"can mapToNoValue", ^{
24 | NSString *value = stringFixture();
25 | PINFuture *source = [PINFuture withValue:value];
26 | PINFutureNoValue *mapped = [source mapToNoValue];
27 |
28 | expectFutureToFulfillWith(self, mapped, [NSNull null]);
29 | });
30 | });
31 |
32 | SpecEnd
33 |
--------------------------------------------------------------------------------
/Example/Tests/PINFutureMap+FlatMapTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // FlatMapTests.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/4/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | // https://github.com/Specta/Specta
10 |
11 | #import "PINFuture.h"
12 | #import "TestUtil.h"
13 |
14 | SpecBegin(PINFutureMapFlatMapSpecs)
15 |
16 | describe(@"flatMap", ^{
17 | it(@"can return resolved future", ^{
18 | NSNumber *valueA = numberFixture();
19 | NSString *valueB = stringFixture();
20 | PINFuture *futureA = [PINFuture withValue:valueA];
21 | PINFuture *futureB = [PINFutureMap flatMap:futureA executor:[PINExecutor immediate] transform:^PINFuture * _Nonnull(NSNumber * _Nonnull fromValue) {
22 | return [PINFuture withValue:valueB];
23 | }];
24 | expectFutureToFulfillWith(self, futureB, valueB);
25 | });
26 |
27 | it(@"can return rejected future", ^{
28 | NSString *valueA = stringFixture();
29 | NSError *errorB = errorFixture();
30 | PINFuture *futureA = [PINFuture withValue:valueA];
31 | PINFuture *futureB = [PINFutureMap flatMap:futureA executor:[PINExecutor immediate] transform:^PINFuture * _Nonnull(NSString * _Nonnull fromValue) {
32 | return [PINFuture withError:errorB];
33 | }];
34 | expectFutureToRejectWith(self, futureB, errorB);
35 | });
36 |
37 | it(@"raises exception when nil is returned instead of a PINFuture", ^{
38 | NSString *valueA = stringFixture();
39 | PINFuture *futureA = [PINFuture withValue:valueA];
40 | expect(^{
41 | __unused PINFuture *futureB = [PINFutureMap flatMap:futureA executor:[PINExecutor immediate] transform:^PINFuture * _Nonnull(NSString * _Nonnull fromValue) {
42 | return nil;
43 | }];
44 | }).to.raiseAny();
45 | });
46 | });
47 |
48 | SpecEnd
49 |
--------------------------------------------------------------------------------
/Example/Tests/PINFutureMap+MapTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // MapTests.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/4/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | // https://github.com/Specta/Specta
10 |
11 | #import "PINFuture.h"
12 | #import "TestUtil.h"
13 |
14 | SpecBegin(PINFutureMapMapSpecs)
15 |
16 | describe(@"map", ^{
17 | it(@"can return a value of a different type", ^{
18 | NSNumber *valueA = numberFixture();
19 | NSString *valueB = stringFixture();
20 | PINFuture *futureA = [PINFuture withValue:valueA];
21 | PINFuture *futureB = [PINFutureMap map:futureA executor:[PINExecutor immediate] transform:^NSString * _Nonnull(NSNumber * _Nonnull fromValue) {
22 | return valueB;
23 | }];
24 | expectFutureToFulfillWith(self, futureB, valueB);
25 | });
26 | });
27 |
28 | describe(@"mapToValue", ^{
29 | it(@"can return a value of a different type", ^{
30 | NSNumber *valueA = numberFixture();
31 | NSString *valueB = stringFixture();
32 | PINFuture *futureA = [PINFuture withValue:valueA];
33 | PINFuture *futureB = [PINFutureMap mapToValue:futureA value:valueB];
34 | expectFutureToFulfillWith(self, futureB, valueB);
35 | });
36 | });
37 |
38 | SpecEnd
39 |
--------------------------------------------------------------------------------
/Example/Tests/PINFutureOnceTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFutureOnceTests.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/14/16.
6 | // Copyright © 2016 Chris Danford. All rights reserved.
7 | //
8 |
9 | // https://github.com/Specta/Specta
10 |
11 | #import "PINFutureOnce.h"
12 | #import "TestUtil.h"
13 |
14 | SpecBegin(PINFutureOnceSpecs)
15 |
16 | describe(@"once", ^{
17 | it(@"only calls block once", ^{
18 | PINFutureOnce *once = [PINFutureOnce new];
19 | __block NSUInteger callCount = 0;
20 | [once performOnce:^{
21 | callCount++;
22 | }];
23 | [once performOnce:^{
24 | callCount++;
25 | }];
26 | expect(callCount).to.equal(1);
27 | });
28 | });
29 |
30 | SpecEnd
31 |
--------------------------------------------------------------------------------
/Example/Tests/PINFutureStressTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFutureStressTests.m
3 | // PINFutureTests
4 | //
5 | // Created by Chris Danford on 12/5/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | // https://github.com/Specta/Specta
10 |
11 | #import "PINFuture.h"
12 | #import "TestUtil.h"
13 |
14 | SpecBegin(PINFutureStressSpecs)
15 |
16 | describe(@"stress test", ^{
17 | it(@"handles large numbers of callbacks", ^{
18 | NSUInteger numChildren = 10000;
19 | NSNumber *value = numberFixture();
20 | PINFuture *sourceFuture = [PINFuture withValue:value];
21 |
22 | NSMutableArray *> *sourceFutures = [[NSMutableArray alloc] initWithCapacity:numChildren];
23 | for (NSUInteger i = 0; i < numChildren; i++) {
24 | [sourceFutures addObject:sourceFuture];
25 | }
26 |
27 | PINFuture *> *arrayFuture = [PINFuture gatherAll:sourceFutures];
28 | NSMutableArray *expectedValue = [[NSMutableArray alloc] initWithCapacity:numChildren];
29 | for (NSUInteger i = 0; i < numChildren; i++) {
30 | [expectedValue addObject:value];
31 | }
32 |
33 | expectFutureToFulfillWith(self, arrayFuture, expectedValue);
34 | });
35 | });
36 |
37 | SpecEnd
38 |
--------------------------------------------------------------------------------
/Example/Tests/PINFutureTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFutureTests.m
3 | // PINFutureTests
4 | //
5 | // Created by Chris Danford on 12/02/2016.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | // https://github.com/Specta/Specta
10 |
11 | #import "PINFuture.h"
12 | #import "TestUtil.h"
13 |
14 | SpecBegin(PINFutureSpecs)
15 |
16 | describe(@"future", ^{
17 | it(@"create with value", ^{
18 | NSString *value = stringFixture();
19 | PINFuture *future = [PINFuture withValue:value];
20 | expectFutureToFulfillWith(self, future, value);
21 | });
22 |
23 | it(@"create with error", ^{
24 | NSError *error = errorFixture();
25 | PINFuture *future = [PINFuture withError:error];
26 | expectFutureToRejectWith(self, future, error);
27 | });
28 |
29 | it(@"resolves only once", ^{
30 | NSString *value = stringFixture();
31 | // Calls to resolve or reject after the first should be ignored.
32 | PINFuture *future = [PINFuture withBlock:^(void (^ _Nonnull resolve)(NSString * _Nonnull), void (^ _Nonnull reject)(NSError * _Nonnull)) {
33 | resolve(value);
34 | resolve(value);
35 | reject(errorFixture());
36 | }];
37 | expectFutureToFulfillWith(self, future, value);
38 | });
39 |
40 | it(@"rejects only once", ^{
41 | NSError *error = errorFixture();
42 | // Calls to resolve or reject after the first should be ignored.
43 | PINFuture *future = [PINFuture withBlock:^(void (^ _Nonnull resolve)(NSString * _Nonnull), void (^ _Nonnull reject)(NSError * _Nonnull)) {
44 | reject(error);
45 | reject(error);
46 | resolve(stringFixture());
47 | }];
48 | expectFutureToRejectWith(self, future, error);
49 | });
50 |
51 | it(@"tolerates success callback being NULL when fulfilled", ^{
52 | NSString *value = stringFixture();
53 | PINFuture *future = [PINFuture withValue:value];
54 | [future executor:[PINExecutor immediate] success:NULL failure:NULL];
55 | expectFutureToFulfillWith(self, future, value);
56 | });
57 |
58 | it(@"tolerates failure callback being null when rejected", ^{
59 | NSError *error = errorFixture();
60 | PINFuture *future = [PINFuture withError:error];
61 | [future executor:[PINExecutor immediate] success:NULL failure:NULL];
62 | expectFutureToRejectWith(self, future, error);
63 | });
64 | });
65 |
66 | SpecEnd
67 |
--------------------------------------------------------------------------------
/Example/Tests/TestUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestUtil.h
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/4/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture.h"
10 |
11 | void expectFutureToFulfillWith(id testCase, PINFuture *future, id expectedValue);
12 | void expectFutureToRejectWith(id testCase, PINFuture *future, NSError *expectedError);
13 |
14 | NSNumber *numberFixture(void);
15 | NSString *stringFixture(void);
16 | NSError *errorFixture(void);
17 |
--------------------------------------------------------------------------------
/Example/Tests/TestUtil.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestUtil.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/4/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "TestUtil.h"
10 |
11 | void expectFutureToFulfillWith(id testCase, PINFuture *future, id expectedValue) {
12 | waitUntil(^(DoneCallback done) {
13 | [future executor:[PINExecutor immediate] success:^(id _Nonnull value) {
14 | id self = testCase;
15 | expect(value).to.equal(expectedValue);
16 | done();
17 | } failure:^(NSError * _Nonnull error) {
18 | NSCAssert(NO, @"expected to resolve, not reject");
19 | done();
20 | }];
21 | });
22 | }
23 |
24 | void expectFutureToRejectWith(id testCase, PINFuture *future, NSError *expectedError) {
25 | waitUntil(^(DoneCallback done) {
26 | [future executor:[PINExecutor immediate] success:^(id _Nonnull value) {
27 | NSCAssert(NO, @"expected to reject, not resolve");
28 | done();
29 | } failure:^(NSError * _Nonnull error) {
30 | id self = testCase;
31 | expect(error).to.equal(expectedError);
32 | done();
33 | }];
34 | });
35 | }
36 |
37 | static NSInteger counter = 0;
38 |
39 | NSNumber *numberFixture() {
40 | return @(counter++);
41 | }
42 |
43 | NSString *stringFixture() {
44 | return [NSString stringWithFormat:@"fixture%ld", (long)counter++];
45 | }
46 |
47 | NSError *errorFixture() {
48 | return [NSError errorWithDomain:NSCocoaErrorDomain code:counter++ userInfo:nil];
49 | }
50 |
--------------------------------------------------------------------------------
/Example/Tests/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 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Example/Tests/Tests-Prefix.pch:
--------------------------------------------------------------------------------
1 | // The contents of this file are implicitly included at the beginning of every test case source file.
2 |
3 | #ifdef __OBJC__
4 |
5 | @import Specta;
6 | @import Expecta;
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/Example/Tests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/PINFuture.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod lib lint PINFuture.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 = 'PINFuture'
11 | s.version = '5.2.1'
12 | s.summary = 'An Objective C implementation of the Future pattern that aims to provide maximal type safety.'
13 | s.description = <<-DESC
14 | An Objective C implementation of the Future async value pattern that aims to provide maximal type safety.
15 | DESC
16 |
17 | s.homepage = 'https://github.com/pinterest/PINFuture'
18 | s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE' }
19 | s.author = { 'Chris Danford' => 'chrisdanford@gmail.com' }
20 | s.source = { :git => 'https://github.com/pinterest/PINFuture.git', :tag => s.version.to_s }
21 | s.social_media_url = 'https://twitter.com/PinterestEng'
22 |
23 | s.ios.deployment_target = '8.0'
24 |
25 | s.source_files = 'PINFuture/Classes/**/*'
26 | s.weak_frameworks = 'Photos'
27 | s.frameworks = 'Foundation'
28 | end
29 |
--------------------------------------------------------------------------------
/PINFuture/Assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinterest/PINFuture/45452c873628abe43dd2aa4c03e0b5b0e826c66d/PINFuture/Assets/.gitkeep
--------------------------------------------------------------------------------
/PINFuture/Classes/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinterest/PINFuture/45452c873628abe43dd2aa4c03e0b5b0e826c66d/PINFuture/Classes/.gitkeep
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/NSURLSession+PINFuture.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSURLSession+PINFuture.h
3 | // Pods
4 | //
5 | // Created by Chris Danford on 12/8/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | #import
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | @interface NSURLSession (PINFuture)
17 |
18 | /**
19 | * Returns a Future that never rejects. The value type has an error field.
20 | * that is set in non-exceptional cases such as 4xx response codes.
21 | */
22 | - (PINNSURLSessionDataTaskAndResult *)pinfuture_dataTaskWithRequest:(NSURLRequest *)request;
23 |
24 | /**
25 | * Returns a Future that never rejects. The value type has an error field.
26 | * that is set in non-exceptional cases such as 4xx response codes.
27 | */
28 | - (PINNSURLSessionDataTaskAndResult *)pinfuture_dataTaskWithRequest:(NSURLRequest *)request
29 | priority:(float)priority;
30 |
31 | @end
32 |
33 | NS_ASSUME_NONNULL_END
34 |
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/NSURLSession+PINFuture.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSURLSession+PINFuture.m
3 | // Pods
4 | //
5 | // Created by Chris Danford on 12/8/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "NSURLSession+PINFuture.h"
10 | #import "PINFutureDefinition.h"
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @implementation NSURLSession (PINFuture)
15 |
16 | - (PINNSURLSessionDataTaskAndResult *)pinfuture_dataTaskWithRequest:(NSURLRequest *)request
17 | {
18 | return [self pinfuture_dataTaskWithRequest:request priority:NSURLSessionTaskPriorityDefault];
19 | }
20 |
21 | - (PINNSURLSessionDataTaskAndResult *)pinfuture_dataTaskWithRequest:(NSURLRequest *)request
22 | priority:(float)priority
23 | {
24 | __block NSURLSessionDataTask *task;
25 | PINFuture *future;
26 | future = [PINFuture withBlock:^(void (^ _Nonnull resolve)(id _Nonnull), void (^ _Nonnull reject)(NSError * _Nonnull)) {
27 | task = [self dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
28 | PINNSURLSessionDataTaskResult *result = [PINNSURLSessionDataTaskResult resultWithData:data response:response error:error];
29 | resolve(result);
30 | }];
31 | task.priority = priority;
32 | [task resume];
33 | }];
34 |
35 | return [PINNSURLSessionDataTaskAndResult resultWithTask:task resultFuture:future];
36 | }
37 |
38 | @end
39 |
40 | NS_ASSUME_NONNULL_END
41 |
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/PHImageManager+PINFuture.h:
--------------------------------------------------------------------------------
1 | //
2 | // PHImageManager+PINFuture.h
3 | // Pinterest
4 | //
5 | // Created by Chris Danford on 11/22/16.
6 | // Copyright © 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import
12 | #import
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 |
16 | @interface PHImageManager (PINFuture)
17 |
18 | - (PINFuture *)pinfuture_requestImageDataForAsset:(PHAsset *)asset options:(nullable PHImageRequestOptions *)options;
19 |
20 | @end
21 |
22 | NS_ASSUME_NONNULL_END
23 |
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/PHImageManager+PINFuture.m:
--------------------------------------------------------------------------------
1 | //
2 | // PHImageManager+PINFuture.m
3 | // Pinterest
4 | //
5 | // Created by Chris Danford on 11/22/16.
6 | // Copyright © 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PHImageManager+PINFuture.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @implementation PHImageManager (PINFuture)
14 |
15 | - (PINFuture *)pinfuture_requestImageDataForAsset:(PHAsset *)asset options:(nullable PHImageRequestOptions *)options
16 | {
17 | return [PINFuture withBlock:^(void (^ _Nonnull resolve)(PINPHImageManagerImageDataResult * _Nonnull), void (^ _Nonnull reject)(NSError * _Nonnull)) {
18 | [self requestImageDataForAsset:asset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
19 | if (imageData) {
20 | PINPHImageManagerImageDataResult *result = [PINPHImageManagerImageDataResult resultWithImageData:imageData
21 | dataUTI:dataUTI
22 | orientation:orientation
23 | info:info];
24 | resolve(result);
25 | } else {
26 | NSString *failureReason = NSLocalizedString(@"Invalid Image Data", @"Failure reason for Invalid Image Data");
27 | NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
28 | code:NSFileReadUnknownError
29 | userInfo:@{NSLocalizedFailureReasonErrorKey : failureReason}];
30 | reject(error);
31 | }
32 | }];
33 | }];
34 | }
35 |
36 | @end
37 |
38 | NS_ASSUME_NONNULL_END
39 |
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/PINNSURLSessionDataTaskAndResult.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINNSURLSessionDataTaskAndResult.h
3 | // Pods
4 | //
5 | // Created by Chris Danford on 9/11/17.
6 | //
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface PINNSURLSessionDataTaskAndResult : NSObject
15 |
16 | @property (nonatomic, readonly) NSURLSessionDataTask * task;
17 | @property (nonatomic, readonly) PINFuture * resultFuture;
18 |
19 | + (instancetype)resultWithTask:(NSURLSessionDataTask *)task
20 | resultFuture:(PINFuture *)resultFuture;
21 |
22 | @end
23 |
24 | NS_ASSUME_NONNULL_END
25 |
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/PINNSURLSessionDataTaskAndResult.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINNSURLSessionDataTaskAndResult.m
3 | // Pods
4 | //
5 | // Created by Chris Danford on 9/11/17.
6 | //
7 | //
8 |
9 | #import "PINNSURLSessionDataTaskAndResult.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PINNSURLSessionDataTaskAndResult ()
14 | @property (nonatomic) NSURLSessionDataTask * task;
15 | @property (nonatomic) PINFuture * resultFuture;
16 | @end
17 |
18 | @implementation PINNSURLSessionDataTaskAndResult
19 |
20 | + (instancetype)resultWithTask:(NSURLSessionDataTask *)task
21 | resultFuture:(PINFuture *)resultFuture
22 | {
23 | PINNSURLSessionDataTaskAndResult *taskAndResult = [[PINNSURLSessionDataTaskAndResult alloc] init];
24 | taskAndResult.task = task;
25 | taskAndResult.resultFuture = resultFuture;
26 | return taskAndResult;
27 | }
28 |
29 | @end
30 |
31 | NS_ASSUME_NONNULL_END
32 |
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/PINNSURLSessionDataTaskResult.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINNSURLSessionDataTaskResult.h
3 | // Pods
4 | //
5 | // Created by Chris Danford on 12/8/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface PINNSURLSessionDataTaskResult : NSObject
15 |
16 | @property (nonatomic, copy, readonly) NSData * _Nullable data;
17 | @property (nonatomic, readonly) NSURLResponse * _Nullable response;
18 | @property (nonatomic, readonly) NSError * _Nullable error;
19 |
20 | + (instancetype)resultWithData:(NSData * _Nullable)data
21 | response:(NSURLResponse * _Nullable)response
22 | error:(NSError * _Nullable)error;
23 |
24 | @end
25 |
26 | NS_ASSUME_NONNULL_END
27 |
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/PINNSURLSessionDataTaskResult.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINNSURLSessionDataTaskResult.m
3 | // Pods
4 | //
5 | // Created by Chris Danford on 1/13/17.
6 | //
7 | //
8 |
9 | #import "PINNSURLSessionDataTaskResult.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PINNSURLSessionDataTaskResult ()
14 | @property (nonatomic, copy) NSData * _Nullable data; //intentionally use copy as the network data might be NSMutableData under the hood
15 | @property (nonatomic) NSURLResponse * _Nullable response;
16 | @property (nonatomic) NSError * _Nullable error;
17 | @end
18 |
19 | @implementation PINNSURLSessionDataTaskResult
20 |
21 | + (instancetype)resultWithData:(NSData * _Nullable)data
22 | response:(NSURLResponse * _Nullable)response
23 | error:(NSError * _Nullable)error
24 | {
25 | PINNSURLSessionDataTaskResult *result = [[PINNSURLSessionDataTaskResult alloc] init];
26 | result.data = data;
27 | result.response = response;
28 | result.error = error;
29 | return result;
30 | }
31 |
32 | @end
33 |
34 | NS_ASSUME_NONNULL_END
35 |
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/PINPHImageManagerImageDataResult.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINPHImageManagerImageDataResult.h
3 | // Pods
4 | //
5 | // Created by Chris Danford on 1/13/17.
6 | //
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | /**
16 | * Immutable. Futures need to resolve to a single value, so this struct hold all of the values normally passed to the callback.
17 | */
18 | @interface PINPHImageManagerImageDataResult : NSObject
19 |
20 | // Exposed consumers of PINFuture to write stubs that return fake data.
21 | + (instancetype)resultWithImageData:(NSData *)imageData
22 | dataUTI:(NSString *)dataUTI
23 | orientation:(UIImageOrientation)orientation
24 | info:(NSDictionary *)info;
25 |
26 | @property (nonatomic, readonly) NSData *imageData;
27 | @property (nonatomic, copy, readonly) NSString *dataUTI;
28 | @property (nonatomic, readonly) UIImageOrientation orientation;
29 | @property (nonatomic, readonly) NSDictionary *info;
30 |
31 | @end
32 |
33 | NS_ASSUME_NONNULL_END
34 |
--------------------------------------------------------------------------------
/PINFuture/Classes/Categories/PINPHImageManagerImageDataResult.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINPHImageManagerImageDataResult.m
3 | // Pods
4 | //
5 | // Created by Chris Danford on 1/13/17.
6 | //
7 | //
8 |
9 | #import "PINPHImageManagerImageDataResult.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PINPHImageManagerImageDataResult ()
14 | @property (nonatomic) NSData *imageData;
15 | @property (nonatomic, copy) NSString *dataUTI;
16 | @property (nonatomic) UIImageOrientation orientation;
17 | @property (nonatomic) NSDictionary *info;
18 | @end
19 |
20 | @implementation PINPHImageManagerImageDataResult
21 |
22 | + (instancetype)resultWithImageData:(NSData *)imageData
23 | dataUTI:(NSString *)dataUTI
24 | orientation:(UIImageOrientation)orientation
25 | info:(NSDictionary *)info
26 | {
27 | PINPHImageManagerImageDataResult *result = [[PINPHImageManagerImageDataResult alloc] init];
28 | result.imageData = imageData;
29 | result.dataUTI = dataUTI;
30 | result.orientation = orientation;
31 | result.info = info;
32 | return result;
33 | }
34 |
35 | @end
36 |
37 | NS_ASSUME_NONNULL_END
38 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINCancelToken.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Brandon Kase on 12/21/16.
3 | //
4 |
5 | #import
6 |
7 | #import
8 |
9 | typedef dispatch_block_t PINCancellationBlock;
10 |
11 | @interface PINCancelToken : NSObject
12 |
13 | +(PINCancelToken *)fold:(NSArray *)tokens;
14 |
15 | -(PINCancelToken *)initWithExecutor:(id)executor andBlock:(PINCancellationBlock)block;
16 |
17 | -(PINCancelToken *)and:(PINCancelToken *)other;
18 |
19 | -(void)cancel;
20 |
21 | @end
22 |
23 | // TODO: Why doesn't this work?
24 | // static PINCancelToken * PINCancelTokenIdentity = [[PINCancelToken alloc] initWithContext:[PINExecution immediate] andBlock:^{}];
25 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINCancelToken.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Brandon Kase on 12/21/16.
3 | //
4 |
5 | #import "PINCancelToken.h"
6 | #import "PINExecutor.h"
7 | #import "PINFutureOnce.h"
8 |
9 | @interface PINCancelToken ()
10 | @property (nonatomic, strong) PINCancellationBlock cancellationBlock;
11 | @end
12 |
13 | @implementation PINCancelToken {
14 |
15 | }
16 |
17 | + (PINCancelToken *)fold:(NSArray *)tokens {
18 |
19 | // TODO: replace with identity constant
20 | PINCancelToken * accumulator = [[PINCancelToken alloc] initWithExecutor:[PINExecutor immediate] andBlock:^{}];
21 | if (tokens == nil) {
22 | return accumulator;
23 | }
24 |
25 | for (PINCancelToken * token in tokens) {
26 | accumulator = [accumulator and:token];
27 | }
28 | return accumulator;
29 | }
30 |
31 | - (PINCancelToken *)initWithExecutor:(id)executor andBlock:(PINCancellationBlock)block {
32 | if (self = [super init]) {
33 | PINFutureOnce *once = [[PINFutureOnce alloc] init];
34 | self.cancellationBlock = ^{
35 | [executor execute:^{
36 | [once performOnce:block];
37 | }];
38 | };
39 | }
40 | return self;
41 | }
42 |
43 | // TODO: Reconsider parallel cancellation
44 | // * Downside is an extra async dispatch
45 | - (PINCancelToken *)and:(PINCancelToken *)other {
46 | if (other == nil) {
47 | return self;
48 | }
49 |
50 | __weak typeof(self) weakSelf = self;
51 | return [[PINCancelToken alloc] initWithExecutor:[PINExecutor immediate] andBlock:^{
52 | weakSelf.cancellationBlock();
53 | other.cancellationBlock();
54 | }];
55 | }
56 |
57 | - (void)cancel {
58 | self.cancellationBlock();
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINDefines.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINDefines.h
3 | // Pods
4 | //
5 | // Created by Chris Danford on 12/19/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #define PIN_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
10 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINExecutor.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINExecutor.h
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/7/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @protocol PINExecutor
14 | - (void)execute:(dispatch_block_t)block;
15 | @end
16 |
17 | @interface PINExecutor : NSObject
18 |
19 | /**
20 | * Can't be created. This exists only for class methods.
21 | */
22 | - (instancetype)init NS_UNAVAILABLE;
23 |
24 | /**
25 | * Executes a block on the main thread. The block is executed immediately if the executor is invoked from the Main thread.
26 | * If the executor is not invoked from the Main thread, then the block is dispatched to Main GCD queue.
27 | */
28 | + (id)main;
29 |
30 | /**
31 | * Disaptches to background queue.
32 | */
33 | + (id)background;
34 |
35 | /**
36 | * Executes immediately on whatever the current thread is without trampolining.
37 | * Use this as an optimization only if your block:
38 | * - will execute extremely quickly
39 | * - has no restirctions on where it can be executed from
40 | * - the overhead of executing the block is low compared to the cost of what the Executor does (usually a dispatch_async).
41 | */
42 | + (id)immediate;
43 |
44 | /**
45 | * Disaptches on a specified queue.
46 | */
47 | + (id)queue:(dispatch_queue_t)queue;
48 |
49 | /**
50 | * Disaptches on a specified dispatch queue.
51 | */
52 | + (id)operationQueue:(NSOperationQueue *)operationQueue;
53 |
54 | @end
55 |
56 | NS_ASSUME_NONNULL_END
57 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINExecutor.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINExecutor.m
3 | // PINFuture
4 | //
5 | // Created by Chris Danford on 12/7/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINExecutor.h"
10 |
11 | #import
12 |
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 | static inline BOOL isCurrentThreadMain()
16 | {
17 | return 0 != pthread_main_np();
18 | }
19 |
20 |
21 | @interface PINExecutor ()
22 |
23 | @property (atomic) void (^executorBlock)(dispatch_block_t);
24 |
25 | @end
26 |
27 | // This is very hot code path, so cache where we can to avoid creating Executor garbage.
28 | #define SHARED_INSTANCE(Type, constructorBlock) \
29 | static Type value = nil; \
30 | static dispatch_once_t onceToken; \
31 | dispatch_once(&onceToken, ^{ \
32 | value = constructorBlock(); \
33 | }); \
34 | return value;
35 |
36 | #define SHARED_EXECUTOR(constructorBlock) \
37 | SHARED_INSTANCE(id, constructorBlock);
38 |
39 | @implementation PINExecutor
40 |
41 | - (instancetype)initWithExecutorBlock:(void (^)(dispatch_block_t))executorBlock
42 | {
43 | self = [super init];
44 | if (self) {
45 | _executorBlock = executorBlock;
46 | }
47 | return self;
48 | }
49 |
50 | - (void)execute:(dispatch_block_t)block
51 | {
52 | self.executorBlock(block);
53 | }
54 |
55 | + (id)immediate
56 | {
57 | SHARED_EXECUTOR(^{
58 | return [[PINExecutor alloc] initWithExecutorBlock:^(dispatch_block_t block) {
59 | block();
60 | }];
61 | });
62 | }
63 |
64 | + (id)main
65 | {
66 | SHARED_EXECUTOR(^{
67 | return [[PINExecutor alloc] initWithExecutorBlock:^(dispatch_block_t block) {
68 | if (isCurrentThreadMain()) {
69 | return [[self immediate] execute:block];
70 | } else {
71 | return [[self queue:dispatch_get_main_queue()] execute:block];
72 | }
73 | }];
74 | });
75 | }
76 |
77 | + (id)queue:(dispatch_queue_t)queue
78 | {
79 | return [[PINExecutor alloc] initWithExecutorBlock:^(dispatch_block_t block) {
80 | dispatch_async(queue, block);
81 | }];
82 | }
83 |
84 | + (id)operationQueue:(NSOperationQueue *)operationQueue
85 | {
86 | return [[PINExecutor alloc] initWithExecutorBlock:^(dispatch_block_t block) {
87 | [operationQueue addOperationWithBlock:block];
88 | }];
89 | }
90 |
91 | + (id)background
92 | {
93 | SHARED_EXECUTOR(^{
94 | return [self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
95 | });
96 | }
97 |
98 | @end
99 |
100 | NS_ASSUME_NONNULL_END
101 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+ChainSideEffect.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+ChainSideEffect.h
3 | // Pods
4 | //
5 | // Created by Chris Danford on 1/22/17.
6 | // Copyright (c) 2017 Pinterest. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface PINFuture (ChainSideEffect)
15 |
16 | /**
17 | * Like `executor:success:failure:`, but instead of returning `void` returns a PINFuture with the same value that won't resolve until the supplied callbacks have finished executing.
18 | */
19 | - (PINFuture *)executor:(id)executor chainSuccess:(nullable void(^)(ObjectType value))success failure:(nullable void (^)(NSError * _Nonnull))failure PIN_WARN_UNUSED_RESULT;
20 |
21 | /**
22 | * Like `executor:completion:`, but instead of returning `void` returns a PINFuture with the same value that won't resolve until the supplied callback has finished executing.
23 | */
24 | - (PINFuture *)executor:(id)executor chainCompletion:(void(^)(void))completion PIN_WARN_UNUSED_RESULT;
25 |
26 | @end
27 |
28 | NS_ASSUME_NONNULL_END
29 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+ChainSideEffect.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+ChainSideEffect.m
3 | // Pods
4 | //
5 | // Created by Chris Danford on 1/22/17.
6 | // Copyright (c) 2017 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture+ChainSideEffect.h"
10 |
11 | #import "PINFutureMap+Map.h"
12 | #import "PINFuture+FlatMapError.h"
13 |
14 | @implementation PINFuture (ChainSideEffect)
15 |
16 | - (PINFuture *)executor:(id)executor chainSuccess:(nullable void(^)(id value))success failure:(nullable void (^)(NSError * _Nonnull))failure
17 | {
18 | PINFuture *chained = self;
19 | if (success != nil) {
20 | chained = [PINFutureMap map:chained executor:executor transform:^id _Nonnull(id _Nonnull value) {
21 | success(value);
22 | return value;
23 | }];
24 | };
25 | if (failure != nil) {
26 | chained = [chained executor:executor flatMapError:^PINFuture *(NSError *error) {
27 | failure(error);
28 | return [PINFuture withError:error];
29 | }];
30 | }
31 | return chained;
32 | }
33 |
34 | - (PINFuture *)executor:(id)executor chainCompletion:(void(^)(void))completion
35 | {
36 | NSParameterAssert(completion);
37 | return [self executor:executor chainSuccess:^(id _Nonnull value) {
38 | completion();
39 | } failure:^(NSError * _Nonnull error) {
40 | completion();
41 | }];
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+Completion.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+Completion.h
3 | // Pods
4 | //
5 | // Created by Chris Danford on 1/28/17.
6 | // Copyright (c) 2017 Pinterest. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PINFuture (Completion)
14 |
15 | /**
16 | * Execute a block on success or on failure. Use this if you want to have a side-effect and nothing
17 | * needs to wait on your side-effect to complete.
18 | */
19 | - (void)executor:(id)executor completion:(void(^)(void))completion;
20 |
21 | @end
22 |
23 | NS_ASSUME_NONNULL_END
24 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+Completion.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+Completion.m
3 | // Pods
4 | //
5 | // Created by Chris Danford on 1/28/17.
6 | // Copyright (c) 2017 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture+Completion.h"
10 |
11 | @implementation PINFuture (Completion)
12 |
13 | - (void)executor:(id)executor completion:(void(^)(void))completion
14 | {
15 | return [self executor:executor success:^(id _Nonnull value) {
16 | completion();
17 | } failure:^(NSError * _Nonnull error) {
18 | completion();
19 | }];
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+Delay.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+Delay.h
3 | // Pinterest
4 | //
5 | // Created by Chris Danford on 4/16/18.
6 | //
7 |
8 | #import
9 |
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | typedef PINFuture PINFutureNoValue;
13 |
14 | @interface PINFuture (Delay)
15 |
16 | /** Return a future that resolves after the specified amount of time. */
17 | + (PINFutureNoValue *)delay:(NSTimeInterval)seconds;
18 |
19 | @end
20 |
21 | NS_ASSUME_NONNULL_END
22 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+Delay.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+Delay.m
3 | // Pinterest
4 | //
5 | // Created by Chris Danford on 4/16/18.
6 | //
7 |
8 | #import "PINFuture+Delay.h"
9 |
10 | @implementation PINFuture (Delay)
11 |
12 | + (PINFutureNoValue *)delay:(NSTimeInterval)seconds
13 | {
14 | return [PINFutureNoValue withBlock:^(void (^_Nonnull resolve)(NSNull *_Nonnull), void (^_Nonnull reject)(NSError *_Nonnull)) {
15 |
16 | // Ideally, we'd dispatch to the same dispatch queue that callbacks attached to this future want to be on.
17 | // Since we can't know that though, we'll choose to dispatch to the background queue. This queue is more likely
18 | // to be serviced quickly than tha main queue.
19 | dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
20 |
21 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), queue, ^{
22 | resolve([NSNull null]);
23 | });
24 | }];
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+Dispatch.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+Dispatch.h
3 | // Pods
4 | //
5 | // Created by Chris Danford on 12/5/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface PINFuture (Dispatch)
15 |
16 | /**
17 | * Create a future by executing a block.
18 | */
19 | + (PINFuture *)executor:(id)executor block:(PINFuture * (^)(void))block PIN_WARN_UNUSED_RESULT;
20 |
21 | @end
22 |
23 | NS_ASSUME_NONNULL_END
24 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+Dispatch.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+Dispatch.m
3 | // Pods
4 | //
5 | // Created by Chris Danford on 12/5/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture+Dispatch.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @implementation PINFuture (Dispatch)
14 |
15 | + (PINFuture *)executor:(id)executor block:(PINFuture * (^)(void))block;
16 | {
17 | NSParameterAssert(executor);
18 | return [PINFuture withBlock:^(void (^ _Nonnull resolve)(id _Nonnull), void (^ _Nonnull reject)(NSError * _Nonnull)) {
19 | // contextify, and execute
20 | [executor execute:^{
21 | PINFuture *future = block();
22 | [future executor:[PINExecutor immediate] success:^(id _Nonnull value) {
23 | resolve(value);
24 | } failure:^(NSError * _Nonnull error) {
25 | reject(error);
26 | }];
27 | }];
28 | }];
29 | }
30 |
31 | @end
32 |
33 | NS_ASSUME_NONNULL_END
34 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+FlatMapError.h:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+FlatMapError.h
3 | // Pods
4 | //
5 | // Created by Chris Danford on 12/8/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface PINFuture (FlatMapError)
13 |
14 | - (PINFuture *)executor:(id)executor flatMapError:(PINFuture *(^)(NSError *error))flatMapError PIN_WARN_UNUSED_RESULT;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/PINFuture/Classes/PINFuture+FlatMapError.m:
--------------------------------------------------------------------------------
1 | //
2 | // PINFuture+FlatMapError.m
3 | // Pods
4 | //
5 | // Created by Chris Danford on 12/8/16.
6 | // Copyright (c) 2016 Pinterest. All rights reserved.
7 | //
8 |
9 | #import "PINFuture+FlatMapError.h"
10 |
11 | #import "PINFutureError.h"
12 |
13 | @implementation PINFuture (FlatMapError)
14 |
15 | - (PINFuture *)executor:(id)executor flatMapError:(PINFuture *(^)(NSError *error))flatMapError
16 | {
17 | return [PINFuture