├── Gemfile
├── .travis.yml
├── NSDate+SRGFekable.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ └── NSDate+SRGFekable.xcscheme
└── project.pbxproj
├── Rakefile
├── NSDate+SRGFekable
├── ViewController.h
├── AppDelegate.h
├── main.m
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── ViewController.m
├── Info.plist
├── AppDelegate.m
└── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
├── Classes
├── SRGFakableViewController.h
├── NSDate+SRGFekable.h
├── SRGFakableViewController.m
├── NSDate+SRGFekable.m
└── SRGFakableViewController.xib
├── NSDate+SRGFekable.podspec
├── .gitignore
├── NSDate+SRGFekableTests
├── Info.plist
└── NSDate_SRGFekableTests.m
├── LICENSE
└── README.md
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | gem 'xcpretty'
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 |
3 | script:
4 | - bundle exec rake default
5 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | SCHEME = "NSDate+SRGFekable"
2 | DESTINATION = "name=iPhone 5,OS=8.1"
3 |
4 | desc "unit test"
5 | task :default do
6 | sh "xcodebuild test -scheme #{SCHEME} -destination \"#{DESTINATION}\" -configuration Debug | bundle exec xcpretty -c && exit ${PIPESTATUS[0]}"
7 | end
8 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // NSDate+SRGFekable
4 | //
5 | // Created by nori0620 on 2015/01/01.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // NSDate+SRGFekable
4 | //
5 | // Created by nori0620 on 2015/01/01.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/Classes/SRGFakableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SRGFakableViewController.h
3 | // NSDate+SRGFekable
4 | //
5 | // Created by nori0620 on 2015/01/02.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SRGFakableViewController : UIViewController
12 |
13 | + (void) showOn:(UIViewController *)below
14 | freezeOnFake:(BOOL)freezeOnFake;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // NSDate+SRGFekable
4 | //
5 | // Created by nori0620 on 2015/01/01.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable.podspec:
--------------------------------------------------------------------------------
1 |
2 | Pod::Spec.new do |s|
3 |
4 | s.name = "NSDate+SRGFekable"
5 | s.version = "0.0.2"
6 | s.summary = "A category to fake current date for unit tests."
7 | s.homepage = "https://github.com/soragoto/NSDate-SRGFekable"
8 | s.license = "MIT"
9 | s.author = { "Norihiro Sakamoto" => "nori0620@gmail.com" }
10 | s.source = { :git => "https://github.com/soragoto/NSDate-SRGFekable.git", :tag => "0.0.2" }
11 | s.platform = :ios, '6.0'
12 | s.source_files = "Classes", "Classes/**/*.{h,m}"
13 | s.resources = ['Classes/SRGFakableViewController.xib']
14 | s.requires_arc = true
15 |
16 | end
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | # Ruby
21 | #
22 | vendor
23 | Gemfile.lock
24 | .bundle
25 |
26 | # CocoaPods
27 | #
28 | # We recommend against adding the Pods directory to your .gitignore. However
29 | # you should judge for yourself, the pros and cons are mentioned at:
30 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
31 | #
32 | # Pods/
33 |
--------------------------------------------------------------------------------
/NSDate+SRGFekableTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | info.soragoto.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Classes/NSDate+SRGFekable.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate+SRGFekable.h
3 | // NSDate+SRGFekable
4 | //
5 | // Created by nori0620 on 2015/01/01.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSDate (SRGFakable)
12 |
13 | + (instancetype) now;
14 | + (BOOL) doFaking;
15 | + (void) stopFaking;
16 | + (void) fakeWithDate:(NSDate *)date;
17 | + (void) fakeWithDate:(NSDate *)date
18 | freeze:(BOOL)freeze
19 | ;
20 | + (void) fakeWithString:(NSString *)dateString;
21 | + (void) fakeWithString:(NSString *)dateString
22 | freeze:(BOOL)freeze
23 | ;
24 | + (void) fakeWithString:(NSString *)dateString
25 | timeZone:(NSTimeZone *)timeZone
26 | ;
27 | + (void) fakeWithString:(NSString *)dateString
28 | timeZone:(NSTimeZone *)timeZone
29 | freeze:(BOOL)freeze
30 | ;
31 | + (void) fakeWithDelta:(NSTimeInterval)delta;
32 | + (void) fakeWithDelta:(NSTimeInterval)delta
33 | freeze:(BOOL)freeze
34 | ;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 soragoto
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/NSDate+SRGFekable/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // NSDate+SRGFekable
4 | //
5 | // Created by nori0620 on 2015/01/01.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "SRGFakableViewController.h"
11 |
12 | @interface ViewController ()
13 |
14 | @property (nonatomic) IBOutlet UILabel *currentDateLabel;
15 | @property NSTimer *timer;
16 |
17 | @end
18 |
19 | @implementation ViewController
20 |
21 | - (NSString *)title {
22 | return @"NSDate+SRGFakable";
23 | }
24 |
25 | - (void)viewDidLoad {
26 | [super viewDidLoad];
27 | [self p_updateDateLabel];
28 | }
29 |
30 | - (void)didReceiveMemoryWarning {
31 | [super didReceiveMemoryWarning];
32 | }
33 |
34 | - (void)viewWillAppear:(BOOL)animated {
35 | [super viewWillAppear:animated];
36 | self.timer = [NSTimer scheduledTimerWithTimeInterval:1
37 | target:self
38 | selector:@selector(p_updateDateLabel)
39 | userInfo:nil
40 | repeats:YES];
41 | }
42 |
43 | - (void)viewDidDisappear:(BOOL)animated {
44 | [super viewDidDisappear:animated];
45 | [self.timer invalidate];
46 | }
47 |
48 | - (IBAction)didTapLaunchFaker:(id)sender {
49 | [SRGFakableViewController showOn:self
50 | freezeOnFake:NO
51 | ];
52 | }
53 |
54 | - (void) p_updateDateLabel {
55 | self.currentDateLabel.text = [NSString stringWithFormat:@"now:%@",[NSDate date]];
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | info.soragoto.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 0.0.2
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // NSDate+SRGFekable
4 | //
5 | // Created by nori0620 on 2015/01/01.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
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 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | NSDate+SRGFekable
2 | ===========
3 |
4 |
5 | [](https://travis-ci.org/soragoto/NSDate-SRGFekable)
6 | [](https://github.com/soragoto/NSDate-SRGFekable)
7 | [](https://github.com/soragoto/NSDate-SRGFekable)
8 | [](https://github.com/soragoto/NSDate-SRGFekable)
9 |
10 | NSDate+SRGFekable is a category to fake results of NSDate. You can test your app features that depend on date more easily.
11 |
12 | ## Installation
13 |
14 | Add the following line to your podfile and run `pod update`.
15 |
16 | ```ruby
17 | pod 'NSDate+SRGFekable'
18 | ```
19 |
20 | ## Usage
21 |
22 | At first you need to include header file.
23 |
24 | ```objc
25 | #import 'NSDate+SRGFekable'
26 | ```
27 |
28 | You can fake NSDate simply
29 |
30 |
31 | ```objc
32 | // You can fake result of NSDate.
33 | [NSDate fakeWithString:@"2014/12/27 10:00:00"];
34 |
35 | // On this process, NSDate behave as if current-time is "2014/12/27 10:00:00"
36 | NSLog(@"now:%@",[NSDate date]); // -> now:2014/12/27 10:00:00
37 | ````
38 |
39 | By using this category , you can write unit tests easily.
40 |
41 | ```objc
42 | ....
43 | - (void)testIsXmas {
44 | SeasonalEvent *seasonalEvent = [SeasonalEvent new];
45 |
46 | [NSDate fakeWithString:@"2014/12/20 10:00:00"];
47 | XCTAssertFalse( seasonalEvent.isXmas );
48 |
49 | [NSDate fakeWithString:@"2014/12/25 10:00:00"];
50 | XCTAssertTrue( seasonalEvent.isXmas );
51 | }
52 | ...
53 | ````
54 |
55 | ## All methods
56 |
57 | ### fakeWithDate
58 |
59 | You can fake from another NSDate instance..
60 |
61 |
62 | ```objc
63 | NSDate *aDate = [NSDate dateWithTimeIntervalSinceNow:100];
64 | [NSDate fakeWithDate:aDate];
65 |
66 | // NSDate behave as if current-time is aDate
67 | ````
68 |
69 | ### fakeWithDelta
70 |
71 |
72 | ```objc
73 | // NSDate behave as if current-time is 60 seconds latter of real date.
74 | [NSDate fakeWithDelta:100];
75 |
76 | // NSDate behave as if current-time is 180(=120+60) seconds latter of real date.
77 | [NSDate fakeWithDelta:120];
78 |
79 | //// NSDate behave as if current-time is 150(=180-30) seconds latter of real date.
80 | [NSDate fakeWithDelta:-30];
81 | ````
82 |
83 | ### Stop stopFaking
84 |
85 | ```objc
86 | // You can stop faking.
87 | [NSDate stopFaking];
88 |
89 | // You can get status of faking or not.
90 | BOOL doFaking = [NSDate doFaking];
91 | ````
92 |
93 | ### freeze option
94 |
95 | Each `fakeXXX` methods have `freeze` option. (Default is `YES`)
96 |
97 | * If `freeze` is `YES`、faked date is completely stop.
98 | * If `freeze` is `NO`, faked date go on.
99 |
100 | This option may be useful when you fake date on Main Project(not Test Project) for manually test.
101 |
102 |
103 | ```objc
104 | // YES is default.
105 | [NSDate fakeWithString:@"2014/12/27 10:00:00" freeze:YES];
106 | // -> [NSDate date] always return @"2014/12/27 10:00:00"
107 |
108 | // freeze:NO
109 | [NSDate fakeWithString:@"2014/12/27 10:00:00" freeze:NO];
110 | // -> If elapsed 10 seconds after call above, [NSDate date] returns @"2014/12/27 10:00:10"
111 | ````
112 |
113 | ## LICENSE
114 |
115 | NSDate+SRGFekable is released under the MIT license. See LICENSE for details.
116 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable.xcodeproj/xcshareddata/xcschemes/NSDate+SRGFekable.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/NSDate+SRGFekableTests/NSDate_SRGFekableTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate_SRGFekableTests.m
3 | // NSDate+SRGFekableTests
4 | //
5 | // Created by nori0620 on 2015/01/01.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "NSDate+SRGFekable.h"
12 |
13 | @interface NSDate_SRGFekableTests : XCTestCase
14 |
15 | @end
16 |
17 | @implementation NSDate_SRGFekableTests
18 |
19 | - (void)setUp {
20 | [NSDate stopFaking];
21 | [super setUp];
22 | }
23 |
24 | - (void)tearDown {
25 | [super tearDown];
26 | }
27 |
28 | - (void)testDate {
29 | NSDate *realDate = [NSDate date];
30 | XCTAssertFalse([NSDate doFaking]);
31 |
32 | [NSDate fakeWithDate:[NSDate dateWithTimeIntervalSinceNow:100] ];
33 | NSDate *fakedDate = [NSDate date];
34 | XCTAssertTrue([NSDate doFaking]);
35 |
36 | XCTAssertEqual((int)[fakedDate timeIntervalSinceDate:realDate],100);
37 | XCTAssertTrue([NSDate doFaking]);
38 |
39 | [NSDate stopFaking];
40 | NSDate *realDate2 = [NSDate date];
41 | XCTAssertFalse([NSDate doFaking]);
42 | XCTAssertEqual((int)[realDate2 timeIntervalSinceDate:realDate],0);
43 | }
44 |
45 | - (void)testInit{
46 | NSDate *realDate = [[NSDate alloc] init];
47 |
48 | [NSDate fakeWithDate:[NSDate dateWithTimeIntervalSinceNow:100]
49 | freeze:YES
50 | ];
51 | NSDate *fakedDate = [[NSDate alloc] init];
52 |
53 | XCTAssertEqual((int)[fakedDate timeIntervalSinceDate:realDate],100);
54 |
55 | [NSDate stopFaking];
56 | NSDate *realDate2 = [[NSDate alloc] init];
57 | XCTAssertEqual((int)[realDate2 timeIntervalSinceDate:realDate],0);
58 | }
59 |
60 | - (void)testInitWithTimeIntervalSinceNow{
61 |
62 | NSDate *realDate = [NSDate new];
63 | NSDate *realDate60 = [[NSDate alloc] initWithTimeIntervalSinceNow:60];
64 | NSTimeInterval realDiff = [realDate60 timeIntervalSinceDate:realDate];
65 |
66 | [NSDate fakeWithString:@"2014/11/11 11:11:11"];
67 |
68 | NSDate *fakeDate = [NSDate date];
69 | NSDate *fakeDate60 = [[NSDate alloc] initWithTimeIntervalSinceNow:60];
70 | NSTimeInterval fakeDiff = [fakeDate60 timeIntervalSinceDate:fakeDate];
71 |
72 | XCTAssertEqual(
73 | (int)realDiff,
74 | (int)fakeDiff
75 | );
76 |
77 | }
78 |
79 | - (void)testNow {
80 | NSDate *realDate = [NSDate now];
81 |
82 | [NSDate fakeWithDate:[NSDate dateWithTimeIntervalSinceNow:100]
83 | freeze:YES
84 | ];
85 | NSDate *fakedDate = [NSDate now];
86 |
87 | XCTAssertEqual((int)[fakedDate timeIntervalSinceDate:realDate],100);
88 |
89 | [NSDate stopFaking];
90 | NSDate *realDate2 = [NSDate now];
91 | XCTAssertEqual((int)[realDate2 timeIntervalSinceDate:realDate],0);
92 | }
93 |
94 |
95 | - (void) testDateWithTimeIntervalSinceNow {
96 |
97 | NSDate *realDate = [NSDate dateWithTimeIntervalSinceNow:300];
98 |
99 | [NSDate fakeWithDate:
100 | [NSDate dateWithTimeIntervalSinceNow:100]
101 | freeze:YES
102 | ];
103 |
104 | NSDate *fakedDate = [NSDate dateWithTimeIntervalSinceNow:300];
105 | XCTAssertEqual((int)[fakedDate timeIntervalSinceDate:realDate],100);
106 |
107 | [NSDate stopFaking];
108 | NSDate *realDate2 = [NSDate dateWithTimeIntervalSinceNow:300];
109 | XCTAssertEqual((int)[realDate2 timeIntervalSinceDate:realDate],0);
110 |
111 | }
112 |
113 | - (void) testTimeIntervalSinceNow {
114 |
115 | NSDate *aDate = [NSDate date];
116 |
117 | NSTimeInterval realInterval = [aDate timeIntervalSinceNow];
118 |
119 | [NSDate fakeWithDate: [NSDate dateWithTimeIntervalSinceNow:-100]
120 | freeze:YES
121 | ];
122 |
123 | NSTimeInterval fakeInterval = [aDate timeIntervalSinceNow];
124 |
125 | NSTimeInterval diff = fakeInterval - realInterval;
126 | BOOL expected = diff >= 99.0 && diff <= 100.0;
127 | XCTAssertTrue( expected );
128 |
129 | [NSDate stopFaking];
130 | NSTimeInterval realInterval2 = [aDate timeIntervalSinceNow];
131 | XCTAssertEqual( (int)realInterval2 - (int)realInterval,0);
132 |
133 | }
134 |
135 | - (void) testFakeWithString{
136 |
137 | [NSDate fakeWithString:@"2014/01/05 11:32:00"
138 | timeZone:[NSTimeZone timeZoneWithName:@"Asia/Tokyo"]
139 | freeze:YES
140 | ];
141 | NSTimeInterval intervalSince1970 = [[NSDate date] timeIntervalSince1970];
142 | XCTAssertEqual(intervalSince1970, 1388889120 );
143 |
144 | }
145 |
146 | - (void) testFakeWithDelta {
147 | NSDate *realDate = [NSDate date];
148 |
149 | [NSDate fakeWithDelta:60];
150 |
151 | NSDate *fakedDate = [NSDate date];
152 | XCTAssertEqual((int)[fakedDate timeIntervalSinceDate:realDate],60);
153 |
154 | [NSDate fakeWithDelta:120];
155 | NSDate *fakedDate2 = [NSDate date];
156 |
157 | XCTAssertEqual((int)[fakedDate2 timeIntervalSinceDate:realDate],180);
158 |
159 | [NSDate fakeWithDelta:-60];
160 | NSDate *fakedDate3 = [NSDate date];
161 | XCTAssertEqual((int)[fakedDate3 timeIntervalSinceDate:realDate],120);
162 |
163 | [NSDate stopFaking];
164 | NSDate *realDate2 = [NSDate date];
165 | XCTAssertEqual((int)[realDate2 timeIntervalSinceDate:realDate],0);
166 |
167 | }
168 |
169 |
170 | @end
171 |
--------------------------------------------------------------------------------
/Classes/SRGFakableViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SRGFakableViewController.m
3 | // NSDate+SRGFekable
4 | //
5 | // Created by nori0620 on 2015/01/02.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import "SRGFakableViewController.h"
10 | #import "NSDate+SRGFekable.h"
11 |
12 | @interface SRGFakableViewController ()
13 |
14 | @property BOOL freezeOnFake;
15 | @property NSTimer *timer;
16 | @property (nonatomic) IBOutlet UIDatePicker *datePicker;
17 | @property (nonatomic) IBOutlet UILabel *titleLabel;
18 | @property (nonatomic) IBOutlet UILabel *dateResultLabel;
19 | @property (nonatomic) IBOutlet UIButton *startFakingButton;
20 | @property (nonatomic) IBOutlet UIButton *stopFakingButton;
21 | @property (nonatomic) IBOutlet UIButton *doFakeButton;
22 | @property (nonatomic) IBOutlet NSLayoutConstraint *pickerHeight;
23 | @property (nonatomic) BOOL doSelectiongDate;
24 |
25 | @end
26 |
27 | @implementation SRGFakableViewController
28 |
29 | + (void)showOn:(UIViewController *)below
30 | freezeOnFake:(BOOL)freezeOnFake
31 | {
32 | SRGFakableViewController *controller = [[[self class] alloc] initWithNibName:NSStringFromClass([self class])
33 |
34 | bundle:nil];
35 | controller.freezeOnFake = freezeOnFake;
36 | UINavigationController *navigationController = [UINavigationController new];
37 | [navigationController pushViewController:controller animated:NO];
38 | [below presentViewController:navigationController
39 | animated:YES
40 | completion:nil];
41 |
42 | }
43 |
44 | # pragma mark - Life cycle events
45 |
46 | - (void)viewDidLoad {
47 | [super viewDidLoad];
48 | self.title = @"Fake NSDate";
49 | if ([self respondsToSelector:@selector(edgesForExtendedLayout)]){
50 | self.edgesForExtendedLayout = UIRectEdgeNone;
51 | }
52 | [self showDoneToNavigation];
53 | [self updateVisibility];
54 | [self updateLabels];
55 | [self updateButtonEnability];
56 | }
57 |
58 | - (void)viewWillAppear:(BOOL)animated {
59 | [super viewWillAppear:animated];
60 | self.timer = [NSTimer scheduledTimerWithTimeInterval:1
61 | target:self
62 | selector:@selector(updateLabels)
63 | userInfo:nil
64 | repeats:YES];
65 | }
66 |
67 | - (void)viewDidDisappear:(BOOL)animated {
68 | [super viewDidDisappear:animated];
69 | [self.timer invalidate];
70 | }
71 |
72 | - (void)updateViewConstraints {
73 | [super updateViewConstraints];
74 | self.pickerHeight.constant = _doSelectiongDate ? 100 : 0 ;
75 | }
76 |
77 | #pragma mark - Tap Handlers
78 |
79 |
80 | - (IBAction)didTapStartFakingDate:(id)sender {
81 | self.datePicker.date = [NSDate date];
82 | self.doSelectiongDate = YES;
83 | }
84 |
85 | - (IBAction)didTapStopFakingDate:(id)sender {
86 | [NSDate stopFaking];
87 | [self updateLabels];
88 | [self updateButtonEnability];
89 | }
90 |
91 | - (IBAction)didTapDoFake:(id)sender {
92 | [NSDate fakeWithDate: _datePicker.date
93 | freeze: self.freezeOnFake
94 | ];
95 | [self updateLabels];
96 | [self updateButtonEnability];
97 | self.doSelectiongDate = NO;
98 | }
99 |
100 | - (void) didTapDone {
101 | [self.navigationController dismissViewControllerAnimated:YES completion:nil];
102 | }
103 |
104 | # pragma mark - Status Updater
105 |
106 | - (void) updateVisibility {
107 | self.dateResultLabel.alpha = !_doSelectiongDate;
108 | self.startFakingButton.alpha = !_doSelectiongDate;
109 | self.stopFakingButton.alpha = !_doSelectiongDate;
110 | self.datePicker.alpha = _doSelectiongDate;
111 | self.doFakeButton.alpha = _doSelectiongDate;
112 | }
113 |
114 | - (void) updateLabels{
115 | self.dateResultLabel.text = [self stringFromDate:[NSDate date]];
116 | self.titleLabel.text = [NSDate doFaking]
117 | ? @"Result of NSDate.date(!Faking!)"
118 | : @"Result of NSDate.date(original)";
119 | self.titleLabel.textColor = [NSDate doFaking]
120 | ? [UIColor redColor]
121 | : [UIColor colorWithRed:83.0f/255.0f
122 | green:181.0f/255.0f
123 | blue:26.0f/255.0f
124 | alpha:1.0f];
125 | }
126 |
127 | - (void) updateButtonEnability {
128 | self.stopFakingButton.enabled = [NSDate doFaking];
129 | self.startFakingButton.enabled = ![NSDate doFaking];
130 | }
131 |
132 |
133 | - (void)setDoSelectiongDate:(BOOL)doSelectiongDate {
134 | _doSelectiongDate = doSelectiongDate;
135 | __weak typeof(self) wSlef = self;
136 | [UIView animateWithDuration:0.3f delay:0 options:UIViewAnimationOptionCurveEaseIn
137 | animations:^{
138 | [wSlef updateVisibility];
139 | [wSlef.view setNeedsUpdateConstraints];
140 | [wSlef.view layoutIfNeeded];
141 | }
142 | completion:nil
143 | ];
144 | }
145 |
146 | # pragma mark - Utils
147 |
148 | - (void) showDoneToNavigation {
149 | UIBarButtonItem *done = [[UIBarButtonItem alloc]
150 | initWithBarButtonSystemItem:UIBarButtonSystemItemDone
151 | target:self
152 | action:@selector(didTapDone)];
153 | self.navigationItem.leftBarButtonItem = done;
154 | }
155 |
156 | - (NSString *) stringFromDate:(NSDate *)date {
157 | NSDateFormatter *df = [[NSDateFormatter alloc] init];
158 | [df setLocale:[NSLocale currentLocale]];
159 | [df setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
160 | return [df stringFromDate:date];
161 | }
162 |
163 | @end
164 |
--------------------------------------------------------------------------------
/Classes/NSDate+SRGFekable.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate+SRGFekable.m
3 | // NSDate+SRGFekable
4 | //
5 | // Created by nori0620 on 2015/01/01.
6 | // Copyright (c) 2015年 soragoto. All rights reserved.
7 | //
8 |
9 | #import "NSDate+SRGFekable.h"
10 | #import
11 |
12 | @interface NSDate (SRGFakable_Private)
13 | + (instancetype) p_swizzledDate ;
14 | +(void) p_swizzleMethods ;
15 | +(NSDate *) p_dateFromString:(NSString *)dateString
16 | timeZone:(NSTimeZone *)timeZone;
17 | @end
18 |
19 | #pragma mark - Public methods
20 |
21 | @implementation NSDate (SRGFakable)
22 |
23 | static NSDate *fakedNow = nil;
24 | static NSTimeInterval fakeDiff = 0;
25 | static BOOL isSwizzledDateMehtods = NO;
26 | static BOOL doFreeze = NO;
27 |
28 | + (instancetype)now {
29 | return [[self class] date];
30 | }
31 |
32 | + (BOOL)doFaking{
33 | return !!fakedNow;
34 | }
35 |
36 | + (void)stopFaking {
37 | fakedNow = nil;
38 | }
39 |
40 |
41 | + (void)fakeWithDate:(NSDate *)date {
42 | return[self fakeWithDate:date freeze:YES];
43 | }
44 |
45 | + (void)fakeWithDate:(NSDate *)date
46 | freeze:(BOOL)freeze
47 | {
48 | fakedNow = date;
49 | doFreeze = freeze;
50 | [self p_swizzleMethods];
51 | fakeDiff = [[[self class] p_swizzledDate] timeIntervalSinceDate:fakedNow];
52 | }
53 |
54 | + (void)fakeWithString:(NSString *)dateString
55 | timeZone:(NSTimeZone *)timeZone
56 | freeze:(BOOL)freeze
57 | {
58 | NSDate *date = [[self class] p_dateFromString:dateString
59 | timeZone:timeZone ];
60 | [self fakeWithDate:date
61 | freeze:freeze
62 | ];
63 | }
64 |
65 | + (void)fakeWithString:(NSString *)dateString
66 | timeZone:(NSTimeZone *)timeZone
67 | {
68 | return [[self class] fakeWithString:dateString
69 | timeZone:[NSTimeZone systemTimeZone]
70 | freeze:YES];
71 | }
72 |
73 | + (void)fakeWithString:(NSString *)dateString
74 | freeze:(BOOL)freeze
75 | {
76 | return [[self class] fakeWithString:dateString
77 | timeZone:[NSTimeZone systemTimeZone]
78 | freeze:freeze];
79 | }
80 |
81 | + (void)fakeWithString:(NSString *)dateString {
82 | return [self fakeWithString:dateString freeze:YES];
83 | }
84 |
85 |
86 | + (void)fakeWithDelta:(NSTimeInterval)delta {
87 | return [self fakeWithDelta:delta freeze:YES];
88 | }
89 |
90 | + (void)fakeWithDelta:(NSTimeInterval)delta
91 | freeze:(BOOL)freeze {
92 | [self fakeWithDate:[[NSDate date] dateByAddingTimeInterval:delta]
93 | freeze:freeze];
94 | }
95 |
96 | @end
97 |
98 |
99 | #pragma mark - Private methods
100 |
101 | @implementation NSDate (SRGFakable_Private)
102 |
103 | + (NSDate *) p_reloadFakedNow {
104 | if( !fakedNow ){ return nil; }
105 | if( doFreeze ){ return fakedNow; }
106 |
107 | NSTimeInterval latestDiff = [[NSDate p_swizzledDate] timeIntervalSinceDate:fakedNow];
108 | return [fakedNow dateByAddingTimeInterval: latestDiff - fakeDiff ];
109 | }
110 |
111 | #pragma mark Swizzing Targets
112 |
113 | + (instancetype) p_swizzledDate {
114 | NSDate *faked = [[self class] p_reloadFakedNow];
115 | if( faked ){ return faked; }
116 | return [self p_swizzledDate];
117 | }
118 |
119 | + (instancetype) p_swizzledDateWithTimeIntervalSinceNow:(NSTimeInterval)secs{
120 | NSDate *faked = [[self class] p_reloadFakedNow];
121 | if( faked ){
122 | return [NSDate dateWithTimeInterval:secs sinceDate:faked];
123 | }
124 | return [self p_swizzledDateWithTimeIntervalSinceNow:secs];
125 | }
126 |
127 | - (id) p_swizzledInit {
128 | if( [NSDate doFaking] ){
129 | return [[NSDate alloc] p_swizzledInitWithTimeIntervalSinceNow:-fakeDiff];
130 | }
131 | return [self p_swizzledInit];
132 | }
133 |
134 | - (id) p_swizzledInitWithTimeIntervalSinceNow:(NSTimeInterval)secs {
135 | NSDate *faked = [[self class] p_reloadFakedNow];
136 | if( faked ){
137 | return [self p_swizzledInitWithTimeIntervalSinceNow:secs - fakeDiff];
138 | }
139 | return [self p_swizzledInitWithTimeIntervalSinceNow:secs];
140 | }
141 |
142 | - (NSTimeInterval) p_swizzledTimeIntervalSinceNow {
143 | NSDate *faked = [[self class] p_reloadFakedNow];
144 | if( faked ){
145 | return [ self timeIntervalSinceDate:faked];
146 | }
147 | return [self p_swizzledTimeIntervalSinceNow];
148 | }
149 |
150 | #pragma mark Execute Swizzing
151 |
152 | + (void)p_swizzleMethods {
153 | if( isSwizzledDateMehtods ){ return; }
154 |
155 | /* sizzle class methods */ {
156 | [self p_swizzleClassMethodWithOriginal:@selector(date)
157 | new:@selector(p_swizzledDate)
158 | ];
159 | [self p_swizzleClassMethodWithOriginal:@selector(dateWithTimeIntervalSinceNow:)
160 | new:@selector(p_swizzledDateWithTimeIntervalSinceNow:)
161 | ];
162 | }
163 |
164 | /* sizzle instance methods */ {
165 | [self p_swizzleInstanceMethodWithOriginal:@selector(timeIntervalSinceNow)
166 | new:@selector(p_swizzledTimeIntervalSinceNow)
167 | ];
168 | [self p_swizzleInstanceMethodWithOriginal:@selector(init)
169 | new:@selector(p_swizzledInit)
170 | originalClass:NSClassFromString(@"__NSPlaceholderDate")
171 | ];
172 | [self p_swizzleInstanceMethodWithOriginal:@selector(initWithTimeIntervalSinceNow:)
173 | new:@selector(p_swizzledInitWithTimeIntervalSinceNow:)
174 | originalClass:NSClassFromString(@"__NSPlaceholderDate")
175 | ];
176 | }
177 |
178 |
179 | isSwizzledDateMehtods = YES;
180 | }
181 |
182 | +(void) p_swizzleClassMethodWithOriginal:(SEL)original
183 | new:(SEL)new
184 | {
185 | Method originalMethod = class_getClassMethod([self class], original);
186 | Method newMethod = class_getClassMethod([self class], new);
187 | method_exchangeImplementations(originalMethod, newMethod);
188 | }
189 |
190 | +(void) p_swizzleInstanceMethodWithOriginal:(SEL)original
191 | new:(SEL)new
192 | {
193 | return [self p_swizzleInstanceMethodWithOriginal:original
194 | new:new
195 | originalClass:[self class] ];
196 | }
197 |
198 | +(void) p_swizzleInstanceMethodWithOriginal:(SEL)original
199 | new:(SEL)new
200 | originalClass:(Class)originalClass
201 | {
202 | Method originalMethod = class_getInstanceMethod(originalClass, original);
203 | Method newMethod = class_getInstanceMethod([self class], new);
204 | method_exchangeImplementations(originalMethod, newMethod);
205 | }
206 |
207 | #pragma mark Utils
208 |
209 | + (NSDate *) p_dateFromString:(NSString *)dateString
210 | timeZone:(NSTimeZone *)timeZone
211 | {
212 | NSDateFormatter *formatter = [NSDateFormatter new];
213 | NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
214 | [formatter setLocale:locale];
215 | [formatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
216 | [formatter setTimeZone:timeZone];
217 | return [formatter dateFromString:dateString];
218 | }
219 |
220 | @end
221 |
--------------------------------------------------------------------------------
/Classes/SRGFakableViewController.xib:
--------------------------------------------------------------------------------
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 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
60 |
70 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/NSDate+SRGFekable.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | CC367D8C1A55348300B87159 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CC367D8B1A55348300B87159 /* main.m */; };
11 | CC367D8F1A55348300B87159 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CC367D8E1A55348300B87159 /* AppDelegate.m */; };
12 | CC367D921A55348300B87159 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC367D911A55348300B87159 /* ViewController.m */; };
13 | CC367D951A55348300B87159 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CC367D931A55348300B87159 /* Main.storyboard */; };
14 | CC367D971A55348300B87159 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CC367D961A55348300B87159 /* Images.xcassets */; };
15 | CC367D9A1A55348300B87159 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC367D981A55348300B87159 /* LaunchScreen.xib */; };
16 | CC367DA61A55348400B87159 /* NSDate_SRGFekableTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC367DA51A55348400B87159 /* NSDate_SRGFekableTests.m */; };
17 | CC367DB81A55359E00B87159 /* NSDate+SRGFekable.m in Sources */ = {isa = PBXBuildFile; fileRef = CC367DB71A55359E00B87159 /* NSDate+SRGFekable.m */; };
18 | CC367DBC1A55BCBF00B87159 /* SRGFakableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC367DBA1A55BCBF00B87159 /* SRGFakableViewController.m */; };
19 | CC367DBD1A55BCBF00B87159 /* SRGFakableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC367DBB1A55BCBF00B87159 /* SRGFakableViewController.xib */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXContainerItemProxy section */
23 | CC367DA01A55348400B87159 /* PBXContainerItemProxy */ = {
24 | isa = PBXContainerItemProxy;
25 | containerPortal = CC367D7E1A55348300B87159 /* Project object */;
26 | proxyType = 1;
27 | remoteGlobalIDString = CC367D851A55348300B87159;
28 | remoteInfo = "NSDate+SRGFekable";
29 | };
30 | /* End PBXContainerItemProxy section */
31 |
32 | /* Begin PBXFileReference section */
33 | CC367D861A55348300B87159 /* NSDate+SRGFekable.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "NSDate+SRGFekable.app"; sourceTree = BUILT_PRODUCTS_DIR; };
34 | CC367D8A1A55348300B87159 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
35 | CC367D8B1A55348300B87159 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
36 | CC367D8D1A55348300B87159 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
37 | CC367D8E1A55348300B87159 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
38 | CC367D901A55348300B87159 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
39 | CC367D911A55348300B87159 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
40 | CC367D941A55348300B87159 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
41 | CC367D961A55348300B87159 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
42 | CC367D991A55348300B87159 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
43 | CC367D9F1A55348400B87159 /* NSDate+SRGFekableTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "NSDate+SRGFekableTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
44 | CC367DA41A55348400B87159 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
45 | CC367DA51A55348400B87159 /* NSDate_SRGFekableTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSDate_SRGFekableTests.m; sourceTree = ""; };
46 | CC367DB61A55359E00B87159 /* NSDate+SRGFekable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+SRGFekable.h"; sourceTree = ""; };
47 | CC367DB71A55359E00B87159 /* NSDate+SRGFekable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+SRGFekable.m"; sourceTree = ""; };
48 | CC367DB91A55BCBF00B87159 /* SRGFakableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRGFakableViewController.h; sourceTree = ""; };
49 | CC367DBA1A55BCBF00B87159 /* SRGFakableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SRGFakableViewController.m; sourceTree = ""; };
50 | CC367DBB1A55BCBF00B87159 /* SRGFakableViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SRGFakableViewController.xib; sourceTree = ""; };
51 | /* End PBXFileReference section */
52 |
53 | /* Begin PBXFrameworksBuildPhase section */
54 | CC367D831A55348300B87159 /* Frameworks */ = {
55 | isa = PBXFrameworksBuildPhase;
56 | buildActionMask = 2147483647;
57 | files = (
58 | );
59 | runOnlyForDeploymentPostprocessing = 0;
60 | };
61 | CC367D9C1A55348400B87159 /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | /* End PBXFrameworksBuildPhase section */
69 |
70 | /* Begin PBXGroup section */
71 | CC367D7D1A55348300B87159 = {
72 | isa = PBXGroup;
73 | children = (
74 | CC367DAF1A5534E800B87159 /* Classes */,
75 | CC367D881A55348300B87159 /* NSDate+SRGFekable */,
76 | CC367DA21A55348400B87159 /* NSDate+SRGFekableTests */,
77 | CC367D871A55348300B87159 /* Products */,
78 | );
79 | sourceTree = "";
80 | };
81 | CC367D871A55348300B87159 /* Products */ = {
82 | isa = PBXGroup;
83 | children = (
84 | CC367D861A55348300B87159 /* NSDate+SRGFekable.app */,
85 | CC367D9F1A55348400B87159 /* NSDate+SRGFekableTests.xctest */,
86 | );
87 | name = Products;
88 | sourceTree = "";
89 | };
90 | CC367D881A55348300B87159 /* NSDate+SRGFekable */ = {
91 | isa = PBXGroup;
92 | children = (
93 | CC367D8D1A55348300B87159 /* AppDelegate.h */,
94 | CC367D8E1A55348300B87159 /* AppDelegate.m */,
95 | CC367D901A55348300B87159 /* ViewController.h */,
96 | CC367D911A55348300B87159 /* ViewController.m */,
97 | CC367D931A55348300B87159 /* Main.storyboard */,
98 | CC367D961A55348300B87159 /* Images.xcassets */,
99 | CC367D981A55348300B87159 /* LaunchScreen.xib */,
100 | CC367D891A55348300B87159 /* Supporting Files */,
101 | );
102 | path = "NSDate+SRGFekable";
103 | sourceTree = "";
104 | };
105 | CC367D891A55348300B87159 /* Supporting Files */ = {
106 | isa = PBXGroup;
107 | children = (
108 | CC367D8A1A55348300B87159 /* Info.plist */,
109 | CC367D8B1A55348300B87159 /* main.m */,
110 | );
111 | name = "Supporting Files";
112 | sourceTree = "";
113 | };
114 | CC367DA21A55348400B87159 /* NSDate+SRGFekableTests */ = {
115 | isa = PBXGroup;
116 | children = (
117 | CC367DA51A55348400B87159 /* NSDate_SRGFekableTests.m */,
118 | CC367DA31A55348400B87159 /* Supporting Files */,
119 | );
120 | path = "NSDate+SRGFekableTests";
121 | sourceTree = "";
122 | };
123 | CC367DA31A55348400B87159 /* Supporting Files */ = {
124 | isa = PBXGroup;
125 | children = (
126 | CC367DA41A55348400B87159 /* Info.plist */,
127 | );
128 | name = "Supporting Files";
129 | sourceTree = "";
130 | };
131 | CC367DAF1A5534E800B87159 /* Classes */ = {
132 | isa = PBXGroup;
133 | children = (
134 | CC367DB61A55359E00B87159 /* NSDate+SRGFekable.h */,
135 | CC367DB71A55359E00B87159 /* NSDate+SRGFekable.m */,
136 | CC367DB91A55BCBF00B87159 /* SRGFakableViewController.h */,
137 | CC367DBA1A55BCBF00B87159 /* SRGFakableViewController.m */,
138 | CC367DBB1A55BCBF00B87159 /* SRGFakableViewController.xib */,
139 | );
140 | path = Classes;
141 | sourceTree = "";
142 | };
143 | /* End PBXGroup section */
144 |
145 | /* Begin PBXNativeTarget section */
146 | CC367D851A55348300B87159 /* NSDate+SRGFekable */ = {
147 | isa = PBXNativeTarget;
148 | buildConfigurationList = CC367DA91A55348400B87159 /* Build configuration list for PBXNativeTarget "NSDate+SRGFekable" */;
149 | buildPhases = (
150 | CC367D821A55348300B87159 /* Sources */,
151 | CC367D831A55348300B87159 /* Frameworks */,
152 | CC367D841A55348300B87159 /* Resources */,
153 | );
154 | buildRules = (
155 | );
156 | dependencies = (
157 | );
158 | name = "NSDate+SRGFekable";
159 | productName = "NSDate+SRGFekable";
160 | productReference = CC367D861A55348300B87159 /* NSDate+SRGFekable.app */;
161 | productType = "com.apple.product-type.application";
162 | };
163 | CC367D9E1A55348400B87159 /* NSDate+SRGFekableTests */ = {
164 | isa = PBXNativeTarget;
165 | buildConfigurationList = CC367DAC1A55348400B87159 /* Build configuration list for PBXNativeTarget "NSDate+SRGFekableTests" */;
166 | buildPhases = (
167 | CC367D9B1A55348400B87159 /* Sources */,
168 | CC367D9C1A55348400B87159 /* Frameworks */,
169 | CC367D9D1A55348400B87159 /* Resources */,
170 | );
171 | buildRules = (
172 | );
173 | dependencies = (
174 | CC367DA11A55348400B87159 /* PBXTargetDependency */,
175 | );
176 | name = "NSDate+SRGFekableTests";
177 | productName = "NSDate+SRGFekableTests";
178 | productReference = CC367D9F1A55348400B87159 /* NSDate+SRGFekableTests.xctest */;
179 | productType = "com.apple.product-type.bundle.unit-test";
180 | };
181 | /* End PBXNativeTarget section */
182 |
183 | /* Begin PBXProject section */
184 | CC367D7E1A55348300B87159 /* Project object */ = {
185 | isa = PBXProject;
186 | attributes = {
187 | LastUpgradeCheck = 0610;
188 | ORGANIZATIONNAME = soragoto;
189 | TargetAttributes = {
190 | CC367D851A55348300B87159 = {
191 | CreatedOnToolsVersion = 6.1;
192 | };
193 | CC367D9E1A55348400B87159 = {
194 | CreatedOnToolsVersion = 6.1;
195 | TestTargetID = CC367D851A55348300B87159;
196 | };
197 | };
198 | };
199 | buildConfigurationList = CC367D811A55348300B87159 /* Build configuration list for PBXProject "NSDate+SRGFekable" */;
200 | compatibilityVersion = "Xcode 3.2";
201 | developmentRegion = English;
202 | hasScannedForEncodings = 0;
203 | knownRegions = (
204 | en,
205 | Base,
206 | );
207 | mainGroup = CC367D7D1A55348300B87159;
208 | productRefGroup = CC367D871A55348300B87159 /* Products */;
209 | projectDirPath = "";
210 | projectRoot = "";
211 | targets = (
212 | CC367D851A55348300B87159 /* NSDate+SRGFekable */,
213 | CC367D9E1A55348400B87159 /* NSDate+SRGFekableTests */,
214 | );
215 | };
216 | /* End PBXProject section */
217 |
218 | /* Begin PBXResourcesBuildPhase section */
219 | CC367D841A55348300B87159 /* Resources */ = {
220 | isa = PBXResourcesBuildPhase;
221 | buildActionMask = 2147483647;
222 | files = (
223 | CC367D951A55348300B87159 /* Main.storyboard in Resources */,
224 | CC367D9A1A55348300B87159 /* LaunchScreen.xib in Resources */,
225 | CC367DBD1A55BCBF00B87159 /* SRGFakableViewController.xib in Resources */,
226 | CC367D971A55348300B87159 /* Images.xcassets in Resources */,
227 | );
228 | runOnlyForDeploymentPostprocessing = 0;
229 | };
230 | CC367D9D1A55348400B87159 /* Resources */ = {
231 | isa = PBXResourcesBuildPhase;
232 | buildActionMask = 2147483647;
233 | files = (
234 | );
235 | runOnlyForDeploymentPostprocessing = 0;
236 | };
237 | /* End PBXResourcesBuildPhase section */
238 |
239 | /* Begin PBXSourcesBuildPhase section */
240 | CC367D821A55348300B87159 /* Sources */ = {
241 | isa = PBXSourcesBuildPhase;
242 | buildActionMask = 2147483647;
243 | files = (
244 | CC367D921A55348300B87159 /* ViewController.m in Sources */,
245 | CC367D8F1A55348300B87159 /* AppDelegate.m in Sources */,
246 | CC367DB81A55359E00B87159 /* NSDate+SRGFekable.m in Sources */,
247 | CC367D8C1A55348300B87159 /* main.m in Sources */,
248 | CC367DBC1A55BCBF00B87159 /* SRGFakableViewController.m in Sources */,
249 | );
250 | runOnlyForDeploymentPostprocessing = 0;
251 | };
252 | CC367D9B1A55348400B87159 /* Sources */ = {
253 | isa = PBXSourcesBuildPhase;
254 | buildActionMask = 2147483647;
255 | files = (
256 | CC367DA61A55348400B87159 /* NSDate_SRGFekableTests.m in Sources */,
257 | );
258 | runOnlyForDeploymentPostprocessing = 0;
259 | };
260 | /* End PBXSourcesBuildPhase section */
261 |
262 | /* Begin PBXTargetDependency section */
263 | CC367DA11A55348400B87159 /* PBXTargetDependency */ = {
264 | isa = PBXTargetDependency;
265 | target = CC367D851A55348300B87159 /* NSDate+SRGFekable */;
266 | targetProxy = CC367DA01A55348400B87159 /* PBXContainerItemProxy */;
267 | };
268 | /* End PBXTargetDependency section */
269 |
270 | /* Begin PBXVariantGroup section */
271 | CC367D931A55348300B87159 /* Main.storyboard */ = {
272 | isa = PBXVariantGroup;
273 | children = (
274 | CC367D941A55348300B87159 /* Base */,
275 | );
276 | name = Main.storyboard;
277 | sourceTree = "";
278 | };
279 | CC367D981A55348300B87159 /* LaunchScreen.xib */ = {
280 | isa = PBXVariantGroup;
281 | children = (
282 | CC367D991A55348300B87159 /* Base */,
283 | );
284 | name = LaunchScreen.xib;
285 | sourceTree = "";
286 | };
287 | /* End PBXVariantGroup section */
288 |
289 | /* Begin XCBuildConfiguration section */
290 | CC367DA71A55348400B87159 /* Debug */ = {
291 | isa = XCBuildConfiguration;
292 | buildSettings = {
293 | ALWAYS_SEARCH_USER_PATHS = NO;
294 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
295 | CLANG_CXX_LIBRARY = "libc++";
296 | CLANG_ENABLE_MODULES = YES;
297 | CLANG_ENABLE_OBJC_ARC = YES;
298 | CLANG_WARN_BOOL_CONVERSION = YES;
299 | CLANG_WARN_CONSTANT_CONVERSION = YES;
300 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
301 | CLANG_WARN_EMPTY_BODY = YES;
302 | CLANG_WARN_ENUM_CONVERSION = YES;
303 | CLANG_WARN_INT_CONVERSION = YES;
304 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
305 | CLANG_WARN_UNREACHABLE_CODE = YES;
306 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
307 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
308 | COPY_PHASE_STRIP = NO;
309 | ENABLE_STRICT_OBJC_MSGSEND = YES;
310 | GCC_C_LANGUAGE_STANDARD = gnu99;
311 | GCC_DYNAMIC_NO_PIC = NO;
312 | GCC_OPTIMIZATION_LEVEL = 0;
313 | GCC_PREPROCESSOR_DEFINITIONS = (
314 | "DEBUG=1",
315 | "$(inherited)",
316 | );
317 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
318 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
319 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
320 | GCC_WARN_UNDECLARED_SELECTOR = YES;
321 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
322 | GCC_WARN_UNUSED_FUNCTION = YES;
323 | GCC_WARN_UNUSED_VARIABLE = YES;
324 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
325 | MTL_ENABLE_DEBUG_INFO = YES;
326 | ONLY_ACTIVE_ARCH = YES;
327 | SDKROOT = iphoneos;
328 | TARGETED_DEVICE_FAMILY = "1,2";
329 | };
330 | name = Debug;
331 | };
332 | CC367DA81A55348400B87159 /* Release */ = {
333 | isa = XCBuildConfiguration;
334 | buildSettings = {
335 | ALWAYS_SEARCH_USER_PATHS = NO;
336 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
337 | CLANG_CXX_LIBRARY = "libc++";
338 | CLANG_ENABLE_MODULES = YES;
339 | CLANG_ENABLE_OBJC_ARC = YES;
340 | CLANG_WARN_BOOL_CONVERSION = YES;
341 | CLANG_WARN_CONSTANT_CONVERSION = YES;
342 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
343 | CLANG_WARN_EMPTY_BODY = YES;
344 | CLANG_WARN_ENUM_CONVERSION = YES;
345 | CLANG_WARN_INT_CONVERSION = YES;
346 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
347 | CLANG_WARN_UNREACHABLE_CODE = YES;
348 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
349 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
350 | COPY_PHASE_STRIP = YES;
351 | ENABLE_NS_ASSERTIONS = NO;
352 | ENABLE_STRICT_OBJC_MSGSEND = YES;
353 | GCC_C_LANGUAGE_STANDARD = gnu99;
354 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
355 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
356 | GCC_WARN_UNDECLARED_SELECTOR = YES;
357 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
358 | GCC_WARN_UNUSED_FUNCTION = YES;
359 | GCC_WARN_UNUSED_VARIABLE = YES;
360 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
361 | MTL_ENABLE_DEBUG_INFO = NO;
362 | SDKROOT = iphoneos;
363 | TARGETED_DEVICE_FAMILY = "1,2";
364 | VALIDATE_PRODUCT = YES;
365 | };
366 | name = Release;
367 | };
368 | CC367DAA1A55348400B87159 /* Debug */ = {
369 | isa = XCBuildConfiguration;
370 | buildSettings = {
371 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
372 | INFOPLIST_FILE = "NSDate+SRGFekable/Info.plist";
373 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
374 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
375 | PRODUCT_NAME = "$(TARGET_NAME)";
376 | };
377 | name = Debug;
378 | };
379 | CC367DAB1A55348400B87159 /* Release */ = {
380 | isa = XCBuildConfiguration;
381 | buildSettings = {
382 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
383 | INFOPLIST_FILE = "NSDate+SRGFekable/Info.plist";
384 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
385 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
386 | PRODUCT_NAME = "$(TARGET_NAME)";
387 | };
388 | name = Release;
389 | };
390 | CC367DAD1A55348400B87159 /* Debug */ = {
391 | isa = XCBuildConfiguration;
392 | buildSettings = {
393 | BUNDLE_LOADER = "$(TEST_HOST)";
394 | FRAMEWORK_SEARCH_PATHS = (
395 | "$(SDKROOT)/Developer/Library/Frameworks",
396 | "$(inherited)",
397 | );
398 | GCC_PREPROCESSOR_DEFINITIONS = (
399 | "DEBUG=1",
400 | "$(inherited)",
401 | );
402 | INFOPLIST_FILE = "NSDate+SRGFekableTests/Info.plist";
403 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
404 | PRODUCT_NAME = "$(TARGET_NAME)";
405 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NSDate+SRGFekable.app/NSDate+SRGFekable";
406 | };
407 | name = Debug;
408 | };
409 | CC367DAE1A55348400B87159 /* Release */ = {
410 | isa = XCBuildConfiguration;
411 | buildSettings = {
412 | BUNDLE_LOADER = "$(TEST_HOST)";
413 | FRAMEWORK_SEARCH_PATHS = (
414 | "$(SDKROOT)/Developer/Library/Frameworks",
415 | "$(inherited)",
416 | );
417 | INFOPLIST_FILE = "NSDate+SRGFekableTests/Info.plist";
418 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
419 | PRODUCT_NAME = "$(TARGET_NAME)";
420 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NSDate+SRGFekable.app/NSDate+SRGFekable";
421 | };
422 | name = Release;
423 | };
424 | /* End XCBuildConfiguration section */
425 |
426 | /* Begin XCConfigurationList section */
427 | CC367D811A55348300B87159 /* Build configuration list for PBXProject "NSDate+SRGFekable" */ = {
428 | isa = XCConfigurationList;
429 | buildConfigurations = (
430 | CC367DA71A55348400B87159 /* Debug */,
431 | CC367DA81A55348400B87159 /* Release */,
432 | );
433 | defaultConfigurationIsVisible = 0;
434 | defaultConfigurationName = Release;
435 | };
436 | CC367DA91A55348400B87159 /* Build configuration list for PBXNativeTarget "NSDate+SRGFekable" */ = {
437 | isa = XCConfigurationList;
438 | buildConfigurations = (
439 | CC367DAA1A55348400B87159 /* Debug */,
440 | CC367DAB1A55348400B87159 /* Release */,
441 | );
442 | defaultConfigurationIsVisible = 0;
443 | defaultConfigurationName = Release;
444 | };
445 | CC367DAC1A55348400B87159 /* Build configuration list for PBXNativeTarget "NSDate+SRGFekableTests" */ = {
446 | isa = XCConfigurationList;
447 | buildConfigurations = (
448 | CC367DAD1A55348400B87159 /* Debug */,
449 | CC367DAE1A55348400B87159 /* Release */,
450 | );
451 | defaultConfigurationIsVisible = 0;
452 | defaultConfigurationName = Release;
453 | };
454 | /* End XCConfigurationList section */
455 | };
456 | rootObject = CC367D7E1A55348300B87159 /* Project object */;
457 | }
458 |
--------------------------------------------------------------------------------