Skip to content

Commit 8ac8570

Browse files
committed
Merge pull request ashfurrow#10 from AshFurrow/issue-7
[WIP] Write Tests
2 parents b3eba82 + 1d978b5 commit 8ac8570

File tree

9 files changed

+445
-286
lines changed

9 files changed

+445
-286
lines changed

C-41.xcodeproj/project.pbxproj

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
251BA020AC1444D3B79A4119 /* libPods-C-41.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CE0365B9C0E4C89BD732392 /* libPods-C-41.a */; };
11+
5E5E69E7187638F0008E9EAE /* CoreDataHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E5E69E6187638F0008E9EAE /* CoreDataHelpers.m */; };
1112
5E93AD3C1866695600795C9E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E93AD3B1866695600795C9E /* Foundation.framework */; };
1213
5E93AD3E1866695600795C9E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E93AD3D1866695600795C9E /* CoreGraphics.framework */; };
1314
5E93AD401866695600795C9E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E93AD3F1866695600795C9E /* UIKit.framework */; };
@@ -63,6 +64,8 @@
6364

6465
/* Begin PBXFileReference section */
6566
3CE0365B9C0E4C89BD732392 /* libPods-C-41.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-C-41.a"; sourceTree = BUILT_PRODUCTS_DIR; };
67+
5E5E69E6187638F0008E9EAE /* CoreDataHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreDataHelpers.m; sourceTree = "<group>"; };
68+
5E5E69E818763906008E9EAE /* CoreDataHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreDataHelpers.h; sourceTree = "<group>"; };
6669
5E93AD381866695600795C9E /* C-41.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "C-41.app"; sourceTree = BUILT_PRODUCTS_DIR; };
6770
5E93AD3B1866695600795C9E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
6871
5E93AD3D1866695600795C9E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
@@ -152,6 +155,15 @@
152155
/* End PBXFrameworksBuildPhase section */
153156

154157
/* Begin PBXGroup section */
158+
5E5E69E91876390B008E9EAE /* Helpers */ = {
159+
isa = PBXGroup;
160+
children = (
161+
5E5E69E818763906008E9EAE /* CoreDataHelpers.h */,
162+
5E5E69E6187638F0008E9EAE /* CoreDataHelpers.m */,
163+
);
164+
name = Helpers;
165+
sourceTree = "<group>";
166+
};
155167
5E93AD2F1866695600795C9E = {
156168
isa = PBXGroup;
157169
children = (
@@ -195,12 +207,12 @@
195207
children = (
196208
5E93AD4C1866695600795C9E /* ASHAppDelegate.h */,
197209
5E93AD4D1866695600795C9E /* ASHAppDelegate.m */,
210+
C02D7C5F186814F9002E9D79 /* ASHCoreDataStack.h */,
211+
C02D7C60186814F9002E9D79 /* ASHCoreDataStack.m */,
198212
5E93AD5B1866695600795C9E /* Images.xcassets */,
199213
5E93AD801866718700795C9E /* View Controllers */,
200214
5E93AD7F1866717D00795C9E /* Models */,
201215
5E93AD441866695600795C9E /* Supporting Files */,
202-
C02D7C5F186814F9002E9D79 /* ASHCoreDataStack.h */,
203-
C02D7C60186814F9002E9D79 /* ASHCoreDataStack.m */,
204216
);
205217
path = "C-41";
206218
sourceTree = "<group>";
@@ -219,6 +231,7 @@
219231
5E93AD691866695600795C9E /* C-41Tests */ = {
220232
isa = PBXGroup;
221233
children = (
234+
5E5E69E91876390B008E9EAE /* Helpers */,
222235
5E93AD851866782600795C9E /* ASHMasterViewModelTests.m */,
223236
5EC0E85B186FBE3200289440 /* ASHDetailViewModelTests.m */,
224237
5EC0E85D186FBE3E00289440 /* ASHTimerViewModelTests.m */,
@@ -518,6 +531,7 @@
518531
5E93AD861866782600795C9E /* ASHMasterViewModelTests.m in Sources */,
519532
5EC0E860186FBE4E00289440 /* ASHEditStepViewModelTests.m in Sources */,
520533
5EC0E85E186FBE3E00289440 /* ASHTimerViewModelTests.m in Sources */,
534+
5E5E69E7187638F0008E9EAE /* CoreDataHelpers.m in Sources */,
521535
5E93AD8818672BE200795C9E /* ASHRecipe.m in Sources */,
522536
5EC0E85C186FBE3200289440 /* ASHDetailViewModelTests.m in Sources */,
523537
5E93AD8718672BA200795C9E /* ASHMasterViewModel.m in Sources */,

C-41/ASHAppDelegate.m

Lines changed: 1 addition & 271 deletions
Large diffs are not rendered by default.

C-41/ASHCoreDataStack.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
1818

1919
- (void)saveContext;
20+
- (void)ensureInitialLoad;
2021

2122
@end

C-41/ASHCoreDataStack.m

Lines changed: 270 additions & 0 deletions
Large diffs are not rendered by default.

C-41Tests/ASHDetailViewModelTests.m

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,47 @@
1111
#define EXP_SHORTHAND
1212
#import <Expecta/Expecta.h>
1313
#import <OCMock/OCMock.h>
14+
#import "CoreDataHelpers.h"
1415

1516
#import "ASHDetailViewModel.h"
17+
#import "ASHTimerViewModel.h"
18+
1619

1720
SpecBegin(ASHDetailViewModel)
1821

1922
describe(@"ASHDetailViewModel", ^{
20-
pending (@"should have the correctly mapped properties", ^{
23+
static ASHRecipe *recipe;
24+
25+
beforeEach(^{
26+
NSManagedObjectContext *context = [[ASHCoreDataStack defaultStack] managedObjectContext];
27+
[context reset];
2128

29+
recipe = setupRecipe(context);
2230
});
2331

24-
pending (@"should return the correct title/subtitle for steps", ^{
32+
it (@"should have the correctly mapped properties", ^{
33+
ASHDetailViewModel *viewModel = [[ASHDetailViewModel alloc] initWithModel:recipe];
2534

35+
expect(viewModel.recipeName).to.equal(recipe.name);
36+
expect(viewModel.recipeDescription).to.equal(recipe.blurb);
37+
expect(viewModel.recipeFilmTypeString).to.equal(@"Colour Negative");
2638
});
2739

28-
pending (@"should return a correctly instantiated timer view model", ^{
40+
it (@"should return the correct title/subtitle for steps", ^{
41+
ASHDetailViewModel *viewModel = [[ASHDetailViewModel alloc] initWithModel:recipe];
42+
43+
NSString *durationString = @"1:00";
44+
45+
expect([viewModel titleForStepAtIndex:0]).to.equal([recipe.steps[0] name]);
46+
expect([viewModel subtitleForStepAtIndex:0]).to.equal(durationString);
47+
});
48+
49+
it (@"should return a correctly instantiated timer view model", ^{
50+
ASHDetailViewModel *viewModel = [[ASHDetailViewModel alloc] initWithModel:recipe];
51+
52+
ASHTimerViewModel *timerViewModel = [viewModel timerViewModel];
2953

54+
expect(timerViewModel.model).to.equal(viewModel.model);
3055
});
3156
});
3257

C-41Tests/ASHTimerViewModelTests.m

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,63 @@
1313
#import <OCMock/OCMock.h>
1414

1515
#import "ASHTimerViewModel.h"
16+
#import "CoreDataHelpers.h"
17+
18+
@interface ASHTimerViewModel ()
19+
20+
-(void)clockTick:(NSTimer *)timer;
21+
22+
@property (nonatomic, assign) NSInteger currentStepIndex;
23+
@property (nonatomic, assign) CFTimeInterval currentStepTimeRemaining;
24+
25+
@property (nonatomic, weak) NSTimer *timer;
26+
27+
@end
1628

1729
SpecBegin(ASHTimerViewModel)
1830

1931
describe(@"ASHTimerViewModel", ^{
20-
pending(@"should map recipeName correctly", ^{
32+
static ASHRecipe *recipe;
33+
34+
beforeEach(^{
35+
NSManagedObjectContext *context = [[ASHCoreDataStack defaultStack] managedObjectContext];
36+
[context reset];
37+
38+
recipe = setupRecipe(context);
39+
});
40+
41+
it(@"should map recipeName correctly", ^{
42+
ASHTimerViewModel *viewModel = [[ASHTimerViewModel alloc] initWithModel:recipe];
43+
44+
expect(viewModel.currentStepIndex).to.equal(0);
45+
expect(viewModel.currentStepTimeRemaining).to.equal([(ASHStep *)[[recipe steps] objectAtIndex:0] duration]);
46+
expect(viewModel.recipeName).to.equal(recipe.name);
47+
expect(viewModel.currentStepString).to.equal(@"Prewash – 39℃");
48+
expect(viewModel.nextStepString).to.equal(@"Developer");
49+
expect(viewModel.timeRemainingString).to.equal(@"1:00");
50+
expect(viewModel.complete).to.beFalsy();
51+
expect(viewModel.running).to.beFalsy();
52+
});
53+
54+
it(@"perform math correctly", ^{
55+
ASHTimerViewModel *viewModel = [[ASHTimerViewModel alloc] initWithModel:recipe];
56+
57+
expect(viewModel.timer).to.beNil();
58+
[viewModel resume];
59+
expect(viewModel.timer).notTo.beNil();
60+
[viewModel pause];
61+
expect(viewModel.timer).to.beNil();
62+
63+
viewModel.currentStepTimeRemaining = 60;
64+
viewModel.currentStepIndex = 0;
65+
[viewModel clockTick:viewModel.timer];
66+
67+
expect(viewModel.currentStepTimeRemaining).to.equal(60 - 1);
2168

69+
viewModel.currentStepTimeRemaining = 0;
70+
[viewModel clockTick:viewModel.timer];
71+
expect(viewModel.currentStepIndex).to.equal(1);
72+
expect(viewModel.currentStepTimeRemaining).to.equal([(ASHStep *)(recipe.steps[1]) duration]);
2273
});
2374
});
2475

C-41Tests/CoreDataHelpers.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// CoreDataHelpers.h
3+
// C-41
4+
//
5+
// Created by Ash Furrow on 1/2/2014.
6+
// Copyright (c) 2014 Ash Furrow. All rights reserved.
7+
//
8+
9+
#import "ASHCoreDataStack.h"
10+
#import "ASHRecipe.h"
11+
#import "ASHStep.h"
12+
13+
ASHRecipe *setupRecipe (NSManagedObjectContext *context);

C-41Tests/CoreDataHelpers.m

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//
2+
// CoreDataHelpers.c
3+
// C-41
4+
//
5+
// Created by Ash Furrow on 1/2/2014.
6+
// Copyright (c) 2014 Ash Furrow. All rights reserved.
7+
//
8+
9+
#import "CoreDataHelpers.h"
10+
11+
ASHRecipe *setupRecipe (NSManagedObjectContext *context) {
12+
13+
ASHRecipe *c41Recipe = [NSEntityDescription insertNewObjectForEntityForName:@"ASHRecipe" inManagedObjectContext:context];
14+
c41Recipe.name = NSLocalizedString(@"C-41 Colour Process", @"Initial setup title");
15+
c41Recipe.blurb = NSLocalizedString(@"Standard C-41 colour negative film recipe.", @"Initial setup subtitle");
16+
c41Recipe.filmType = ASHRecipeFilmTypeColourNegative;
17+
18+
ASHStep *prewashStep = [NSEntityDescription insertNewObjectForEntityForName:@"ASHStep" inManagedObjectContext:context];
19+
prewashStep.recipe = c41Recipe;
20+
prewashStep.name = NSLocalizedString(@"Prewash", @"C-41 Prewash step name");
21+
prewashStep.blurb = NSLocalizedString(@"Water", @"C-41 prewas step description");
22+
prewashStep.temperatureC = 39;
23+
prewashStep.duration = 60;
24+
25+
ASHStep *developerStep = [NSEntityDescription insertNewObjectForEntityForName:@"ASHStep" inManagedObjectContext:context];
26+
developerStep.recipe = c41Recipe;
27+
developerStep.name = NSLocalizedString(@"Developer", @"C-41 developer step name");
28+
developerStep.temperatureC = 39;
29+
developerStep.agitationDuration = 10;
30+
developerStep.agitationFrequency = 60;
31+
developerStep.duration = 210;
32+
33+
ASHStep *blixStep = [NSEntityDescription insertNewObjectForEntityForName:@"ASHStep" inManagedObjectContext:context];
34+
blixStep.recipe = c41Recipe;
35+
blixStep.name = NSLocalizedString(@"Blix", @"C-41 blix step name");
36+
blixStep.temperatureC = 39;
37+
blixStep.agitationDuration = 10;
38+
blixStep.agitationFrequency = 60;
39+
blixStep.duration = 390;
40+
41+
ASHStep *washStep = [NSEntityDescription insertNewObjectForEntityForName:@"ASHStep" inManagedObjectContext:context];
42+
washStep.recipe = c41Recipe;
43+
washStep.name = NSLocalizedString(@"Wash", @"C-41 wash step name");
44+
washStep.blurb = NSLocalizedString(@"Water", @"C-41 was step description");
45+
washStep.temperatureC = 23;
46+
washStep.agitationDuration = 0;
47+
washStep.agitationFrequency = 0;
48+
washStep.duration = 180;
49+
50+
ASHStep *stabilizerStep = [NSEntityDescription insertNewObjectForEntityForName:@"ASHStep" inManagedObjectContext:context];
51+
stabilizerStep.recipe = c41Recipe;
52+
stabilizerStep.name = NSLocalizedString(@"Stabilizer", @"C-41 stabilizer step name");
53+
stabilizerStep.temperatureC = 23;
54+
stabilizerStep.agitationDuration = 15;
55+
stabilizerStep.agitationFrequency = 60;
56+
stabilizerStep.duration = 60;
57+
58+
c41Recipe.steps = [NSOrderedSet orderedSetWithArray:@[prewashStep, developerStep, blixStep, washStep, stabilizerStep]];
59+
60+
return c41Recipe;
61+
}

Podfile

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
# Uncomment this line to define a global platform for your project
22
# platform :ios, "6.0"
33

4-
def import_pods
5-
pod 'libextobjc', '0.3'
6-
pod 'ReactiveCocoa', '2.1.8'
7-
pod 'ReactiveViewModel', '0.1.1'
8-
end
94

105
target "C-41" do
116

12-
import_pods
13-
7+
pod 'ReactiveCocoa', '2.1.8'
8+
pod 'libextobjc', '0.3'
9+
pod 'ReactiveViewModel', '0.1.1'
1410
pod 'UIColor-Utilities', '1.0.1'
1511

1612
inhibit_all_warnings!
@@ -19,8 +15,6 @@ end
1915

2016
target "C-41Tests" do
2117

22-
import_pods
23-
2418
pod 'Specta', '~> 0.2.1'
2519
pod 'Expecta', '~> 0.2.3'
2620
pod 'OCMock', '~> 2.2.1'

0 commit comments

Comments
 (0)