Permalink
Browse files

Merge pull request #13 from cppforlife/focused_specs

Added ability to run focused specs (fdescribe, fcontext, fit)
  • Loading branch information...
2 parents 35a9989 + 62e8455 commit 4eb0c73ee6adb2aa73716d38badd73708fa01cf9 Pivotal Labs committed Oct 13, 2011
View
162 Cedar.xcodeproj/project.pbxproj
@@ -27,6 +27,11 @@
42064467139B44EC00C85605 /* CDRTeamCityReporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 42064465139B44EC00C85605 /* CDRTeamCityReporter.h */; };
4206446A139B44F600C85605 /* CDRTeamCityReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 42064469139B44F600C85605 /* CDRTeamCityReporter.m */; };
4206446B139B44F600C85605 /* CDRTeamCityReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 42064469139B44F600C85605 /* CDRTeamCityReporter.m */; };
+ 96A07F0313F276640021974D /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE135D3111DEA6A900A922D4 /* OCMock.framework */; };
+ 96A07F0413F276640021974D /* Cedar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEEE1FB611DC271300029872 /* Cedar.framework */; };
+ 96A07F0B13F276B10021974D /* FocusedSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 96A07F0A13F276B10021974D /* FocusedSpec.m */; };
+ 96A07F0F13F27F2F0021974D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96A07F0E13F27F2F0021974D /* main.m */; };
+ 96A07F1113F283E40021974D /* FocusedSpec2.m in Sources */ = {isa = PBXBuildFile; fileRef = 96A07F1013F283E40021974D /* FocusedSpec2.m */; };
AE0AF56513E9C0E300029396 /* CedarMatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF55E13E9C0E300029396 /* CedarMatchers.h */; settings = {ATTRIBUTES = (Public, ); }; };
AE0AF56C13E9C0FB00029396 /* CedarMatchers.h in Copy headers to framework */ = {isa = PBXBuildFile; fileRef = AE0AF55E13E9C0E300029396 /* CedarMatchers.h */; };
AE0AF57D13E9C5B200029396 /* BeInstanceOf.mm in Sources */ = {isa = PBXBuildFile; fileRef = AE0AF57B13E9C5B200029396 /* BeInstanceOf.mm */; };
@@ -164,6 +169,20 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
+ 96A07EF013F276640021974D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = AEEE1FA611DC26EA00029872 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = AEEE1FB511DC271300029872;
+ remoteInfo = Cedar;
+ };
+ 96A07EF213F276640021974D /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = AE135D2611DEA6A900A922D4 /* OCMock.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = 8DC2EF4F0486A6940098B216;
+ remoteInfo = OCMock;
+ };
AE135D3011DEA6A900A922D4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = AE135D2611DEA6A900A922D4 /* OCMock.xcodeproj */;
@@ -261,6 +280,10 @@
/* Begin PBXFileReference section */
42064465139B44EC00C85605 /* CDRTeamCityReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRTeamCityReporter.h; sourceTree = "<group>"; };
42064469139B44F600C85605 /* CDRTeamCityReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRTeamCityReporter.m; sourceTree = "<group>"; };
+ 96A07F0813F276640021974D /* FocusedSpecs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = FocusedSpecs; sourceTree = BUILT_PRODUCTS_DIR; };
+ 96A07F0A13F276B10021974D /* FocusedSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FocusedSpec.m; path = Focused/FocusedSpec.m; sourceTree = "<group>"; };
+ 96A07F0E13F27F2F0021974D /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Focused/main.m; sourceTree = "<group>"; };
+ 96A07F1013F283E40021974D /* FocusedSpec2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FocusedSpec2.m; path = Focused/FocusedSpec2.m; sourceTree = "<group>"; };
AE0AF55E13E9C0E300029396 /* CedarMatchers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CedarMatchers.h; sourceTree = "<group>"; };
AE0AF57913E9C16D00029396 /* MatcherTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatcherTemplate.h; sourceTree = "<group>"; };
AE0AF57B13E9C5B200029396 /* BeInstanceOf.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BeInstanceOf.mm; sourceTree = "<group>"; };
@@ -283,14 +306,14 @@
AEEE1FB611DC271300029872 /* Cedar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cedar.framework; sourceTree = BUILT_PRODUCTS_DIR; };
AEEE1FB811DC271300029872 /* Cedar-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Cedar-Info.plist"; sourceTree = "<group>"; };
AEEE1FC411DC27B800029872 /* CDRDefaultReporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRDefaultReporter.m; sourceTree = "<group>"; };
- AEEE1FC511DC27B800029872 /* CDRExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRExample.m; sourceTree = "<group>"; };
- AEEE1FC611DC27B800029872 /* CDRExampleBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRExampleBase.m; sourceTree = "<group>"; };
- AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRExampleGroup.m; sourceTree = "<group>"; };
- AEEE1FC811DC27B800029872 /* CDRFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRFunctions.m; sourceTree = "<group>"; };
+ AEEE1FC511DC27B800029872 /* CDRExample.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRExample.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
+ AEEE1FC611DC27B800029872 /* CDRExampleBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRExampleBase.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
+ AEEE1FC711DC27B800029872 /* CDRExampleGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRExampleGroup.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
+ AEEE1FC811DC27B800029872 /* CDRFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CDRFunctions.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
AEEE1FC911DC27B800029872 /* CDRSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRSpec.m; sourceTree = "<group>"; };
AEEE1FCB11DC27B800029872 /* CDRDefaultReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRDefaultReporter.h; sourceTree = "<group>"; };
AEEE1FCC11DC27B800029872 /* CDRExample.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExample.h; sourceTree = "<group>"; };
- AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleBase.h; sourceTree = "<group>"; };
+ AEEE1FCD11DC27B800029872 /* CDRExampleBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CDRExampleBase.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
AEEE1FCE11DC27B800029872 /* CDRExampleGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleGroup.h; sourceTree = "<group>"; };
AEEE1FCF11DC27B800029872 /* CDRExampleParent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleParent.h; sourceTree = "<group>"; };
AEEE1FD011DC27B800029872 /* CDRExampleReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDRExampleReporter.h; sourceTree = "<group>"; };
@@ -311,8 +334,8 @@
AEEE1FE111DC27B800029872 /* CDRSpecStatusViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDRSpecStatusViewController.m; sourceTree = "<group>"; };
AEEE1FE211DC27B800029872 /* CedarApplicationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CedarApplicationDelegate.m; sourceTree = "<group>"; };
AEEE1FE611DC27B800029872 /* SpecHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpecHelper.m; sourceTree = "<group>"; };
- AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRExampleGroupSpec.mm; sourceTree = "<group>"; };
- AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRExampleSpec.mm; sourceTree = "<group>"; };
+ AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRExampleGroupSpec.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = CDRExampleSpec.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
AEEE1FEC11DC27B800029872 /* CDRExampleStateMapSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CDRExampleStateMapSpec.mm; sourceTree = "<group>"; };
AEEE1FED11DC27B800029872 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
AEEE1FEE11DC27B800029872 /* SlowSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SlowSpec.m; sourceTree = "<group>"; };
@@ -351,6 +374,15 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
+ 96A07F0213F276640021974D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 96A07F0313F276640021974D /* OCMock.framework in Frameworks */,
+ 96A07F0413F276640021974D /* Cedar.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AEEE1FB411DC271300029872 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -386,6 +418,16 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 96A07F0D13F27ED70021974D /* Focused */ = {
+ isa = PBXGroup;
+ children = (
+ 96A07F0A13F276B10021974D /* FocusedSpec.m */,
+ 96A07F1013F283E40021974D /* FocusedSpec2.m */,
+ 96A07F0E13F27F2F0021974D /* main.m */,
+ );
+ name = Focused;
+ sourceTree = "<group>";
+ };
AE0AF55D13E9C06900029396 /* Matchers */ = {
isa = PBXGroup;
children = (
@@ -462,6 +504,7 @@
AEEE218611DC28E200029872 /* Specs */,
AEEE222911DC2B0600029872 /* libCedar-StaticLib.a */,
AEEE227611DC2CF900029872 /* iPhoneSpecs.app */,
+ 96A07F0813F276640021974D /* FocusedSpecs */,
);
name = Products;
sourceTree = "<group>";
@@ -550,14 +593,15 @@
AEEE1FE711DC27B800029872 /* Spec */ = {
isa = PBXGroup;
children = (
+ 96A07F0D13F27ED70021974D /* Focused */,
AEEE1FEB11DC27B800029872 /* iPhone */,
AE8C879F1362068A006C9305 /* Matchers */,
- AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */,
AEEE1FE911DC27B800029872 /* CDRExampleSpec.mm */,
- AEEE1FEF11DC27B800029872 /* main.m */,
+ AEEE1FE811DC27B800029872 /* CDRExampleGroupSpec.mm */,
AEEE1FF011DC27B800029872 /* GlobalBeforeEachSpec.mm */,
AEEE1FF111DC27B800029872 /* SpecSpec.mm */,
AEEE1FF211DC27B800029872 /* SpecSpec2.m */,
+ AEEE1FEF11DC27B800029872 /* main.m */,
);
path = Spec;
sourceTree = "<group>";
@@ -566,8 +610,8 @@
isa = PBXGroup;
children = (
AEEE1FEC11DC27B800029872 /* CDRExampleStateMapSpec.mm */,
- AEEE1FED11DC27B800029872 /* main.m */,
AEEE1FEE11DC27B800029872 /* SlowSpec.m */,
+ AEEE1FED11DC27B800029872 /* main.m */,
);
path = iPhone;
sourceTree = "<group>";
@@ -689,6 +733,24 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
+ 96A07EEE13F276640021974D /* FocusedSpecs */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 96A07F0513F276640021974D /* Build configuration list for PBXNativeTarget "FocusedSpecs" */;
+ buildPhases = (
+ 96A07EF313F276640021974D /* Sources */,
+ 96A07F0213F276640021974D /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 96A07EEF13F276640021974D /* PBXTargetDependency */,
+ 96A07EF113F276640021974D /* PBXTargetDependency */,
+ );
+ name = FocusedSpecs;
+ productName = Specs;
+ productReference = 96A07F0813F276640021974D /* FocusedSpecs */;
+ productType = "com.apple.product-type.tool";
+ };
AEEE1FB511DC271300029872 /* Cedar */ = {
isa = PBXNativeTarget;
buildConfigurationList = AEEE1FBC11DC271300029872 /* Build configuration list for PBXNativeTarget "Cedar" */;
@@ -789,6 +851,7 @@
targets = (
AEEE1FB511DC271300029872 /* Cedar */,
AEEE218511DC28E200029872 /* Specs */,
+ 96A07EEE13F276640021974D /* FocusedSpecs */,
AEEE222811DC2B0600029872 /* Cedar-StaticLib */,
AEEE224B11DC2BBB00029872 /* Cedar-iPhone */,
AEEE227511DC2CF900029872 /* iPhoneSpecs */,
@@ -869,6 +932,16 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
+ 96A07EF313F276640021974D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 96A07F0B13F276B10021974D /* FocusedSpec.m in Sources */,
+ 96A07F0F13F27F2F0021974D /* main.m in Sources */,
+ 96A07F1113F283E40021974D /* FocusedSpec2.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
AEEE1FB311DC271300029872 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -970,6 +1043,16 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
+ 96A07EEF13F276640021974D /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = AEEE1FB511DC271300029872 /* Cedar */;
+ targetProxy = 96A07EF013F276640021974D /* PBXContainerItemProxy */;
+ };
+ 96A07EF113F276640021974D /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = OCMock;
+ targetProxy = 96A07EF213F276640021974D /* PBXContainerItemProxy */;
+ };
AE135D3C11DEA6D700A922D4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = OCMock;
@@ -993,6 +1076,56 @@
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
+ 96A07F0613F276640021974D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\\\"$(SRCROOT)\\\"",
+ );
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "";
+ INSTALL_PATH = /usr/local/bin;
+ OTHER_LDFLAGS = (
+ "-framework",
+ Foundation,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = FocusedSpecs;
+ };
+ name = Debug;
+ };
+ 96A07F0713F276640021974D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "\\\"$(SRCROOT)\\\"",
+ );
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "";
+ INSTALL_PATH = /usr/local/bin;
+ OTHER_LDFLAGS = (
+ "-framework",
+ Foundation,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = FocusedSpecs;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
AEEE1FA711DC26EA00029872 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -1255,6 +1388,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
+ 96A07F0513F276640021974D /* Build configuration list for PBXNativeTarget "FocusedSpecs" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 96A07F0613F276640021974D /* Debug */,
+ 96A07F0713F276640021974D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
AEEE1FA911DC26EA00029872 /* Build configuration list for PBXProject "Cedar" */ = {
isa = XCConfigurationList;
buildConfigurations = (
View
18 Rakefile
@@ -28,11 +28,12 @@ def output_file(target)
output_file
end
-task :default => [:trim_whitespace, :specs, :uispecs]
+task :default => [:trim_whitespace, :specs, :focused_specs, :uispecs]
task :cruise do
Rake::Task[:clean].invoke
Rake::Task[:build_all].invoke
Rake::Task[:specs].invoke
+ Rake::Task[:focused_specs].invoke
Rake::Task[:uispecs].invoke
end
@@ -45,7 +46,7 @@ task :clean do
end
task :build_specs do
-puts "SYMROOT: #{ENV['SYMROOT']}"
+ puts "SYMROOT: #{ENV['SYMROOT']}"
system_or_exit(%Q[xcodebuild -project #{PROJECT_NAME}.xcodeproj -target #{SPECS_TARGET_NAME} -configuration #{CONFIGURATION} build SYMROOT=#{BUILD_DIR}], output_file("specs"))
end
@@ -65,6 +66,19 @@ task :specs => :build_specs do
system_or_exit(File.join(build_dir, SPECS_TARGET_NAME))
end
+task :focused_specs do
+ # This target was made just for testing focused specs mode
+ # and should not be created in applications that want to use Cedar.
+
+ focused_specs_target_name = "FocusedSpecs"
+ system_or_exit "xcodebuild -project #{PROJECT_NAME}.xcodeproj -target #{focused_specs_target_name} -configuration #{CONFIGURATION} build SYMROOT=#{BUILD_DIR}", output_file("focused_specs")
+
+ build_dir = build_dir("")
+ ENV["DYLD_FRAMEWORK_PATH"] = build_dir
+ ENV["CEDAR_REPORTER_CLASS"] = "CDRColorizedReporter"
+ system_or_exit File.join(build_dir, focused_specs_target_name)
+end
+
require 'tmpdir'
task :uispecs => :build_uispecs do
ENV["DYLD_ROOT_PATH"] = SDK_DIR
View
11 Source/CDRColorizedReporter.m
@@ -1,9 +1,10 @@
#import "CDRColorizedReporter.h"
static const char * const ANSI_NORMAL = "\033[0m";
-static const char * const ANSI_GREEN = "\033[0;40;32m";
static const char * const ANSI_RED = "\033[0;40;31m";
+static const char * const ANSI_GREEN = "\033[0;40;32m";
static const char * const ANSI_YELLOW = "\033[0;40;33m";
+static const char * const ANSI_CYAN = "\033[0;40;36m";
@implementation CDRColorizedReporter
@@ -20,6 +21,14 @@ - (NSString *)pendingMessageForExample:(CDRExample *)example {
return [NSString stringWithFormat:@"%s%@%s", ANSI_YELLOW, [super pendingMessageForExample:example], ANSI_NORMAL];
}
+- (NSString *)skippedToken {
+ return [NSString stringWithFormat:@"%s%@%s", ANSI_CYAN, [super skippedToken], ANSI_NORMAL];
+}
+
+- (NSString *)skippedMessageForExample:(CDRExample *)example {
+ return [NSString stringWithFormat:@"%s%@%s", ANSI_CYAN, [super skippedMessageForExample:example], ANSI_NORMAL];
+}
+
- (NSString *)failureToken {
return [NSString stringWithFormat:@"%s%@%s", ANSI_RED, [super failureToken], ANSI_NORMAL];
}
View
23 Source/CDRDefaultReporter.m
@@ -1,6 +1,7 @@
#import "CDRDefaultReporter.h"
#import "CDRExample.h"
#import "CDRExampleGroup.h"
+#import "SpecHelper.h"
@interface CDRDefaultReporter (private)
- (void)printMessages:(NSArray *)messages;
@@ -16,6 +17,7 @@ @implementation CDRDefaultReporter
- (id)init {
if (self = [super init]) {
pendingMessages_ = [[NSMutableArray alloc] init];
+ skippedMessages_ = [[NSMutableArray alloc] init];
failureMessages_ = [[NSMutableArray alloc] init];
}
return self;
@@ -25,6 +27,7 @@ - (void)dealloc {
[rootGroups_ release];
[startTime_ release];
[failureMessages_ release];
+ [skippedMessages_ release];
[pendingMessages_ release];
[super dealloc];
}
@@ -52,7 +55,7 @@ - (void)runDidComplete {
}
- (int)result {
- if ([failureMessages_ count]) {
+ if ([SpecHelper specHelper].shouldOnlyRunFocused || [failureMessages_ count]) {
return 1;
} else {
return 0;
@@ -72,6 +75,14 @@ - (NSString *)pendingMessageForExample:(CDRExample *)example {
return [NSString stringWithFormat:@"PENDING %@", [example fullText]];
}
+- (NSString *)skippedToken {
+ return @">";
+}
+
+- (NSString *)skippedMessageForExample:(CDRExample *)example {
+ return [NSString stringWithFormat:@"SKIPPED %@", [example fullText]];
+}
+
- (NSString *)failureToken {
return @"F";
}
@@ -127,6 +138,10 @@ - (void)reportOnExample:(CDRExample *)example {
printf("%s", [[self pendingToken] cStringUsingEncoding:NSUTF8StringEncoding]);
[pendingMessages_ addObject:[self pendingMessageForExample:example]];
break;
+ case CDRExampleStateSkipped:
+ printf("%s", [[self skippedToken] cStringUsingEncoding:NSUTF8StringEncoding]);
+ [skippedMessages_ addObject:[self skippedMessageForExample:example]];
+ break;
case CDRExampleStateFailed:
printf("%s", [[self failureToken] cStringUsingEncoding:NSUTF8StringEncoding]);
[failureMessages_ addObject:[self failureMessageForExample:example]];
@@ -143,9 +158,15 @@ - (void)reportOnExample:(CDRExample *)example {
- (void)printStats {
printf("\nFinished in %.4f seconds\n\n", [[NSDate date] timeIntervalSinceDate:startTime_]);
printf("%u examples, %u failures", exampleCount_, (unsigned int)failureMessages_.count);
+
if (pendingMessages_.count) {
printf(", %u pending", (unsigned int)pendingMessages_.count);
}
+
+ if (skippedMessages_.count) {
+ printf(", %u skipped", (unsigned int)skippedMessages_.count);
+ }
+
printf("\n");
}
View
5 Source/CDRExample.m
@@ -1,6 +1,7 @@
#import "CDRExample.h"
#import "CDRExampleReporter.h"
#import "CDRSpecFailure.h"
+#import "SpecHelper.h"
const CDRSpecBlock PENDING = nil;
@@ -51,7 +52,9 @@ - (float)progress {
}
- (void)run {
- if (block_) {
+ if (!self.shouldRun) {
+ self.state = CDRExampleStateSkipped;
+ } else if (block_) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@try {
[parent_ setUp];
View
25 Source/CDRExampleBase.m
@@ -1,19 +1,21 @@
#import "CDRExampleBase.h"
+#import "SpecHelper.h"
@implementation CDRExampleBase
-@synthesize text = text_, parent = parent_;
+@synthesize text = text_, parent = parent_, focused = focused_;
- (id)initWithText:(NSString *)text {
- if (self = [super init]) {
- text_ = [text retain];
- }
- return self;
+ if (self = [super init]) {
+ text_ = [text retain];
+ focused_ = NO;
+ }
+ return self;
}
- (void)dealloc {
- [text_ release];
- [super dealloc];
+ [text_ release];
+ [super dealloc];
}
- (void)setUp {
@@ -25,6 +27,15 @@ - (void)tearDown {
- (void)run {
}
+- (BOOL)shouldRun {
+ BOOL shouldOnlyRunFocused = [SpecHelper specHelper].shouldOnlyRunFocused;
+ return !shouldOnlyRunFocused || (shouldOnlyRunFocused && (self.isFocused || parent_.shouldRun));
+}
+
+- (BOOL)hasFocusedExamples {
+ return self.isFocused;
+}
+
- (BOOL)hasChildren {
return NO;
}
View
12 Source/CDRExampleGroup.m
@@ -87,6 +87,18 @@ - (void)run {
[self stopObservingExamples];
}
+- (BOOL)hasFocusedExamples {
+ if (self.isFocused) {
+ return YES;
+ }
+ for (CDRExampleBase *example in examples_) {
+ if ([example hasFocusedExamples]) {
+ return YES;
+ }
+ }
+ return NO;
+}
+
- (BOOL)hasChildren {
return [examples_ count] > 0;
}
View
4 Source/CDRFunctions.m
@@ -78,6 +78,10 @@ int runSpecsWithCustomExampleReporter(NSArray *specClasses, id<CDRExampleReporte
CDRDefineGlobalBeforeAndAfterEachBlocks();
NSArray *groups = CDRCreateRootGroupsFromSpecClasses(specClasses);
+ for (CDRExampleGroup *group in groups) {
+ [SpecHelper specHelper].shouldOnlyRunFocused |= [group hasFocusedExamples];
+ }
+
[reporter runWillStartWithGroups:groups];
[groups makeObjectsPerformSelector:@selector(run)];
[reporter runDidComplete];
View
59 Source/CDRSpec.m
@@ -6,46 +6,67 @@
CDRSpec *currentSpec;
-void describe(NSString *text, CDRSpecBlock block) {
+void beforeEach(CDRSpecBlock block) {
+ [currentSpec.currentGroup addBefore:block];
+}
+
+void afterEach(CDRSpecBlock block) {
+ [currentSpec.currentGroup addAfter:block];
+}
+
+CDRExampleGroup * describe(NSString *text, CDRSpecBlock block) {
CDRExampleGroup *parentGroup = currentSpec.currentGroup;
- currentSpec.currentGroup = [CDRExampleGroup groupWithText:text];
- [parentGroup add:currentSpec.currentGroup];
+ CDRExampleGroup *group = [CDRExampleGroup groupWithText:text];
+ [parentGroup add:group];
+
+ currentSpec.currentGroup = group;
block();
currentSpec.currentGroup = parentGroup;
-}
-void beforeEach(CDRSpecBlock block) {
- [currentSpec.currentGroup addBefore:block];
+ return group;
}
-void afterEach(CDRSpecBlock block) {
- [currentSpec.currentGroup addAfter:block];
+CDRExampleGroup * context(NSString *text, CDRSpecBlock block) {
+ return describe(text, block);
}
-void it(NSString *text, CDRSpecBlock block) {
+CDRExample * it(NSString *text, CDRSpecBlock block) {
CDRExample *example = [CDRExample exampleWithText:text andBlock:block];
[currentSpec.currentGroup add:example];
+ return example;
}
-void fail(NSString *reason) {
- [[CDRSpecFailure specFailureWithReason:[NSString stringWithFormat:@"Failure: %@", reason]] raise];
+CDRExampleGroup * xdescribe(NSString *text, CDRSpecBlock block) {
+ return describe(text, ^{});
}
-void context(NSString *text, CDRSpecBlock block) {
- describe(text, block);
+CDRExampleGroup * xcontext(NSString *text, CDRSpecBlock block) {
+ return xdescribe(text, block);
}
-void xcontext(NSString *text, CDRSpecBlock block) {
- it(text, PENDING);
+CDRExample * xit(NSString *text, CDRSpecBlock block) {
+ return it(text, PENDING);
}
-void xdescribe(NSString *text, CDRSpecBlock block) {
- it(text, PENDING);
+CDRExampleGroup * fdescribe(NSString *text, CDRSpecBlock block) {
+ CDRExampleGroup *group = describe(text, block);
+ group.focused = YES;
+ return group;
}
-void xit(NSString *text, CDRSpecBlock block) {
- it(text, PENDING);
+CDRExampleGroup * fcontext(NSString *text, CDRSpecBlock block) {
+ return fdescribe(text, block);
+}
+
+CDRExample * fit(NSString *text, CDRSpecBlock block) {
+ CDRExample *example = it(text, block);
+ example.focused = YES;
+ return example;
+}
+
+void fail(NSString *reason) {
+ [[CDRSpecFailure specFailureWithReason:[NSString stringWithFormat:@"Failure: %@", reason]] raise];
}
@implementation CDRSpec
View
8 Source/CDRTeamCityReporter.m
@@ -30,6 +30,10 @@ - (NSString *)pendingMessageForExample:(CDRExample *)example{
return [NSString stringWithFormat:@"##teamcity[testIgnored name='%@']", [self escapeText:example.fullText]];
}
+- (NSString *)skippedMessageForExample:(CDRExample *)example{
+ return [NSString stringWithFormat:@"##teamcity[testIgnored name='%@']", [self escapeText:example.fullText]];
+}
+
- (NSString *)failureMessageForExample:(CDRExample *)example{
return [NSString stringWithFormat:@"##teamcity[testFailed name='%@' message='%@']",
[self escapeText:example.fullText],
@@ -47,6 +51,10 @@ - (void)reportOnExample:(CDRExample *)example {
printf("%s\n", [[self pendingMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding]);
[pendingMessages_ addObject:[super pendingMessageForExample:example]];
break;
+ case CDRExampleStateSkipped:
+ printf("%s\n", [[self skippedMessageForExample:example] cStringUsingEncoding:NSUTF8StringEncoding]);
+ [skippedMessages_ addObject:[super skippedMessageForExample:example]];
+ break;
case CDRExampleStateError:
case CDRExampleStateFailed:
printf("%s\n%s\n%s\n",
View
3 Source/Headers/CDRDefaultReporter.h
@@ -6,6 +6,7 @@
NSArray *rootGroups_;
NSMutableArray *pendingMessages_;
+ NSMutableArray *skippedMessages_;
NSMutableArray *failureMessages_;
NSDate *startTime_;
@@ -17,6 +18,8 @@
- (NSString *)successToken;
- (NSString *)pendingToken;
- (NSString *)pendingMessageForExample:(CDRExample *)example;
+- (NSString *)skippedToken;
+- (NSString *)skippedMessageForExample:(CDRExample *)example;
- (NSString *)failureToken;
- (NSString *)failureMessageForExample:(CDRExample *)example;
- (NSString *)errorToken;
View
15 Source/Headers/CDRExampleBase.h
@@ -7,25 +7,32 @@ typedef void (^CDRSpecBlock)(void);
enum CDRExampleState {
CDRExampleStateIncomplete = 0x00,
- CDRExampleStatePassed = 0x01,
- CDRExampleStatePending = 0x03,
- CDRExampleStateFailed = 0x07,
- CDRExampleStateError = 0x0F
+ CDRExampleStateSkipped = 0x01,
+ CDRExampleStatePassed = 0x03,
+ CDRExampleStatePending = 0x07,
+ CDRExampleStateFailed = 0x0F,
+ CDRExampleStateError = 0x1F
};
typedef enum CDRExampleState CDRExampleState;
@interface CDRExampleBase : NSObject {
NSString *text_;
id<CDRExampleParent> parent_;
+ BOOL focused_;
}
@property (nonatomic, readonly) NSString *text;
@property (nonatomic, assign) id<CDRExampleParent> parent;
+@property (nonatomic, assign, getter=isFocused) BOOL focused;
- (id)initWithText:(NSString *)text;
- (void)run;
+- (BOOL)shouldRun;
+
- (BOOL)hasChildren;
+- (BOOL)hasFocusedExamples;
+
- (NSString *)message;
- (NSString *)fullText;
@end
View
2 Source/Headers/CDRExampleParent.h
@@ -2,6 +2,8 @@
@protocol CDRExampleParent
+- (BOOL)shouldRun;
+
- (void)setUp;
- (void)tearDown;
View
23 Source/Headers/CDRSpec.h
@@ -2,25 +2,32 @@
#import "CDRExampleBase.h"
@protocol CDRExampleReporter;
-@class CDRExampleGroup, SpecHelper;
+@class CDRExampleGroup, CDRExample, SpecHelper;
@protocol CDRSpec
@end
-extern CDRSpecBlock PENDING;
+extern const CDRSpecBlock PENDING;
#ifdef __cplusplus
extern "C" {
#endif
-void describe(NSString *, CDRSpecBlock);
void beforeEach(CDRSpecBlock);
void afterEach(CDRSpecBlock);
-void it(NSString *, CDRSpecBlock);
+
+CDRExampleGroup * describe(NSString *, CDRSpecBlock);
+CDRExampleGroup * context(NSString *, CDRSpecBlock);
+CDRExample * it(NSString *, CDRSpecBlock);
+
+CDRExampleGroup * xcontext(NSString *, CDRSpecBlock);
+CDRExampleGroup * xdescribe(NSString *, CDRSpecBlock);
+CDRExample * xit(NSString *, CDRSpecBlock);
+
+CDRExampleGroup * fdescribe(NSString *, CDRSpecBlock);
+CDRExampleGroup * fcontext(NSString *, CDRSpecBlock);
+CDRExample * fit(NSString *, CDRSpecBlock);
+
void fail(NSString *);
-void context(NSString *, CDRSpecBlock);
-void xcontext(NSString *, CDRSpecBlock);
-void xdescribe(NSString *, CDRSpecBlock);
-void xit(NSString *, CDRSpecBlock);
#ifdef __cplusplus
}
View
3 Source/Headers/SpecHelper.h
@@ -5,11 +5,14 @@
@interface SpecHelper : NSObject <CDRExampleParent> {
NSMutableDictionary *sharedExampleContext_, *sharedExampleGroups_;
NSArray *globalBeforeEachClasses_, *globalAfterEachClasses_;
+ BOOL shouldOnlyRunFocused_;
}
@property (nonatomic, retain, readonly) NSMutableDictionary *sharedExampleContext;
@property (nonatomic, retain) NSArray *globalBeforeEachClasses, *globalAfterEachClasses;
+@property (nonatomic, assign) BOOL shouldOnlyRunFocused;
+
+ (SpecHelper *)specHelper;
@end
View
17 Source/SpecHelper.m
@@ -1,15 +1,19 @@
#import "SpecHelper.h"
+static SpecHelper *specHelper__;
+
@interface SpecHelper ()
@property (nonatomic, retain, readwrite) NSMutableDictionary *sharedExampleGroups, *sharedExampleContext;
@end
-static SpecHelper *specHelper__;
-
@implementation SpecHelper
-@synthesize sharedExampleGroups = sharedExampleGroups_, sharedExampleContext = sharedExampleContext_;
-@synthesize globalBeforeEachClasses = globalBeforeEachClasses_, globalAfterEachClasses = globalAfterEachClasses_;
+@synthesize
+ sharedExampleGroups = sharedExampleGroups_,
+ sharedExampleContext = sharedExampleContext_,
+ globalBeforeEachClasses = globalBeforeEachClasses_,
+ globalAfterEachClasses = globalAfterEachClasses_,
+ shouldOnlyRunFocused = shouldOnlyRunFocused_;
+ (id)specHelper {
if (!specHelper__) {
@@ -22,6 +26,7 @@ - (id)init {
if (self = [super init]) {
self.sharedExampleGroups = [NSMutableDictionary dictionary];
self.sharedExampleContext = [NSMutableDictionary dictionary];
+ self.shouldOnlyRunFocused = NO;
}
return self;
}
@@ -36,6 +41,10 @@ - (void)dealloc {
}
#pragma mark CDRExampleParent
+- (BOOL)shouldRun {
+ return NO;
+}
+
- (void)setUp {
if ([self respondsToSelector:@selector(beforeEach)]) {
NSLog(@"********************************************************************************");
View
11 Source/iPhone/CDRExampleStateMap.m
@@ -2,8 +2,15 @@
static CDRExampleStateMap *sharedInstance__;
-const CDRExampleState exampleStateKeys[] = {CDRExampleStateIncomplete, CDRExampleStatePassed, CDRExampleStatePending, CDRExampleStateFailed, CDRExampleStateError};
-const NSString *exampleStateDescriptions[] = {@"RUNNING", @"PASSED", @"PENDING", @"FAILED", @"ERROR"};
+const CDRExampleState exampleStateKeys[] = {
+ CDRExampleStateIncomplete,
+ CDRExampleStatePassed,
+ CDRExampleStatePending,
+ CDRExampleStateSkipped,
+ CDRExampleStateFailed,
+ CDRExampleStateError
+};
+const NSString *exampleStateDescriptions[] = {@"RUNNING", @"PASSED", @"PENDING", @"SKIPPED", @"FAILED", @"ERROR"};
@implementation CDRExampleStateMap
View
181 Spec/CDRExampleGroupSpec.mm
@@ -15,11 +15,13 @@
using namespace Cedar::Matchers;
+extern void (^runInFocusedSpecsMode)(CDRExampleBase *);
+
SPEC_BEGIN(CDRExampleGroupSpec)
describe(@"CDRExampleGroup", ^{
__block CDRExampleGroup *group;
- __block CDRExample *incompleteExample, *pendingExample, *passingExample, *failingExample, *errorExample;
+ __block CDRExample *incompleteExample, *pendingExample, *passingExample, *failingExample, *errorExample, *nonFocusedExample;
NSString *groupText = @"Group!";
beforeEach(^{
@@ -29,6 +31,7 @@
failingExample = [[CDRExample alloc] initWithText:@"I should fail" andBlock:^{fail(@"I have failed.");}];
pendingExample = [[CDRExample alloc] initWithText:@"I should pend" andBlock:nil];
errorExample = [[CDRExample alloc] initWithText:@"I should raise an error" andBlock:^{ @throw @"wibble"; }];
+ nonFocusedExample = [[CDRExample alloc] initWithText:@"I should not be focused" andBlock:^{}];
});
afterEach(^{
@@ -37,6 +40,7 @@
[failingExample release];
[passingExample release];
[incompleteExample release];
+ [nonFocusedExample release];
[group release];
});
@@ -67,6 +71,74 @@
});
});
+ describe(@"isFocused", ^{
+ it(@"should return false by default", ^{
+ expect([group isFocused]).to_not(be_truthy());
+ });
+
+ it(@"should return false when group is not focused", ^{
+ group.focused = NO;
+ expect([group isFocused]).to_not(be_truthy());
+ });
+
+ it(@"should return true when group is focused", ^{
+ group.focused = YES;
+ expect([group isFocused]).to(be_truthy());
+ });
+ });
+
+ describe(@"hasFocusedExamples", ^{
+ context(@"for a group that is focused", ^{
+ beforeEach(^{
+ group.focused = YES;
+ });
+
+ it(@"should return true", ^{
+ expect([group hasFocusedExamples]).to(be_truthy());
+ });
+ });
+
+ context(@"for a group that is not focused", ^{
+ beforeEach(^{
+ expect([group isFocused]).to_not(be_truthy());
+ });
+
+ it(@"should return false", ^{
+ expect([group hasFocusedExamples]).to_not(be_truthy());
+ });
+
+ context(@"and has at least one focused example", ^{
+ beforeEach(^{
+ [group add:failingExample];
+ [group add:passingExample];
+ passingExample.focused = YES;
+ });
+
+ it(@"should return true", ^{
+ expect([group hasFocusedExamples]).to(be_truthy());
+ });
+ });
+
+ context(@"and has at least one focused group", ^{
+ beforeEach(^{
+ CDRExampleGroup *innerGroup = [[CDRExampleGroup alloc] initWithText:@"Inner group"];
+ innerGroup.focused = YES;
+ [group add:innerGroup];
+
+ CDRExampleGroup *anotherInnerGroup = [[CDRExampleGroup alloc] initWithText:@"Another inner group"];
+ [group add:anotherInnerGroup];
+
+ [innerGroup release];
+ [anotherInnerGroup release];
+ });
+
+ it(@"should return true", ^{
+ expect([group hasFocusedExamples]).to(be_truthy());
+ });
+ });
+ });
+ });
+
describe(@"state", ^{
describe(@"for a group containing no examples", ^{
beforeEach(^{
@@ -128,6 +200,19 @@
});
});
+ describe(@"with only skipped examples", ^{
+ beforeEach(^{
+ [group add:passingExample];
+ passingExample.focused = NO;
+ runInFocusedSpecsMode(group);
+ });
+
+ it(@"should be CDRExampleStateSkipped", ^{
+ CDRExampleState state = group.state;
+ expect(state).to(equal(CDRExampleStateSkipped));
+ });
+ });
+
describe(@"with only error examples", ^{
beforeEach(^{
[group add:errorExample];
@@ -140,6 +225,54 @@
});
});
+ describe(@"with at least one passing example", ^{
+ beforeEach(^{
+ [group add:passingExample];
+ });
+
+ describe(@"with at least one skipped example", ^{
+ beforeEach(^{
+ passingExample.focused = YES;
+ [group add:nonFocusedExample];
+ runInFocusedSpecsMode(group);
+ });
+
+ it(@"should be CDRExampleStatePassed", ^{
+ expect([group state]).to(equal(CDRExampleStatePassed));
+ });
+ });
+ });
+
+ describe(@"with at least one pending example", ^{
+ beforeEach(^{
+ [group add:pendingExample];
+ });
+
+ describe(@"with all other examples passing", ^{
+ beforeEach(^{
+ [group add:passingExample];
+ [group run];
+ });
+
+ it(@"should be CDRExampleStatePending", ^{
+ expect([group state]).to(equal(CDRExampleStatePending));
+ });
+ });
+
+ describe(@"with at least one skipped example", ^{
+ beforeEach(^{
+ pendingExample.focused = YES;
+ [group add:nonFocusedExample];
+ runInFocusedSpecsMode(group);
+ });
+
+ it(@"should be CDRExampleStatePending", ^{
+ CDRExampleState state = group.state;
+ expect([group state]).to(equal(CDRExampleStatePending));
+ });
+ });
+ });
+
describe(@"with at least one failing example", ^{
beforeEach(^{
[group add:failingExample];
@@ -152,8 +285,7 @@
});
it(@"should be CDRExampleStateFailed", ^{
- CDRExampleState state = group.state;
- expect(state).to(equal(CDRExampleStateFailed));
+ expect([group state]).to(equal(CDRExampleStateFailed));
});
});
@@ -164,8 +296,19 @@
});
it(@"should be CDRExampleStateFailed", ^{
- CDRExampleState state = group.state;
- expect(state).to(equal(CDRExampleStateFailed));
+ expect([group state]).to(equal(CDRExampleStateFailed));
+ });
+ });
+
+ describe(@"with at least one skipped example", ^{
+ beforeEach(^{
+ failingExample.focused = YES;
+ [group add:passingExample];
+ runInFocusedSpecsMode(group);
+ });
+
+ it(@"should be CDRExampleStateFailed", ^{
+ expect([group state]).to(equal(CDRExampleStateFailed));
});
});
});
@@ -182,8 +325,7 @@
});
it(@"should be CDRExampleStateError", ^{
- CDRExampleState state = group.state;
- expect(state).to(equal(CDRExampleStateError));
+ expect([group state]).to(equal(CDRExampleStateError));
});
});
@@ -194,8 +336,7 @@
});
it(@"should be CDRExampleStateError", ^{
- CDRExampleState state = group.state;
- expect(state).to(equal(CDRExampleStateError));
+ expect([group state]).to(equal(CDRExampleStateError));
});
});
@@ -206,26 +347,19 @@
});
it(@"should be CDRExampleStateError", ^{
- CDRExampleState state = group.state;
- expect(state).to(equal(CDRExampleStateError));
+ expect([group state]).to(equal(CDRExampleStateError));
});
});
- });
- describe(@"with at least one pending example", ^{
- beforeEach(^{
- [group add:pendingExample];
- });
-
- describe(@"with all other examples passing", ^{
+ describe(@"with at least one skipped example", ^{
beforeEach(^{
- [group add:passingExample];
- [group run];
+ errorExample.focused = YES;
+ [group add:nonFocusedExample];
+ runInFocusedSpecsMode(group);
});
- it(@"should be CDRExampleStatePending", ^{
- CDRExampleState state = group.state;
- expect(state).to(equal(CDRExampleStatePending));
+ it(@"should be CDRExampleStateError", ^{
+ expect([group state]).to(equal(CDRExampleStateError));
});
});
});
@@ -447,7 +581,6 @@
expect(fullText).to(equal(text));
});
});
-
});
});
View
125 Spec/CDRExampleSpec.mm
@@ -15,6 +15,16 @@
using namespace Cedar::Matchers;
+void (^runInFocusedSpecsMode)(CDRExampleBase *) = ^(CDRExampleBase *example){
+ BOOL before = [SpecHelper specHelper].shouldOnlyRunFocused;
+ [SpecHelper specHelper].shouldOnlyRunFocused = YES;
+ @try {
+ [example run];
+ } @finally {
+ [SpecHelper specHelper].shouldOnlyRunFocused = before;
+ }
+};
+
SPEC_BEGIN(CDRExampleSpec)
typedef void (^CDRSharedExampleBlock)(NSDictionary *context);
@@ -85,7 +95,7 @@
beforeEach(^{
rootGroup = [[CDRExampleGroup alloc] initWithText:@"wibble wobble" isRoot:YES];
[rootGroup add:example];
-
+
expect(example.parent).to_not(be_nil());
BOOL hasFullText = example.parent.hasFullText;
expect(hasFullText).to_not(be_truthy());
@@ -116,6 +126,38 @@
});
});
+ describe(@"isFocused", ^{
+ it(@"should return false by default", ^{
+ expect([example isFocused]).to_not(be_truthy());
+ });
+
+ it(@"should return false when example is not focused", ^{
+ example.focused = NO;
+ expect([example isFocused]).to_not(be_truthy());
+ });
+
+ it(@"should return true when example is focused", ^{
+ example.focused = YES;
+ expect([example isFocused]).to(be_truthy());
+ });
+ });
+
+ describe(@"hasFocusedExamples", ^{
+ it(@"should return false by default", ^{
+ expect([example hasFocusedExamples]).to_not(be_truthy());
+ });
+
+ it(@"should return false when example is not focused", ^{
+ example.focused = NO;
+ expect([example hasFocusedExamples]).to_not(be_truthy());
+ });
+
+ it(@"should return true when example is focused", ^{
+ example.focused = YES;
+ expect([example hasFocusedExamples]).to(be_truthy());
+ });
+ });
+
describe(@"state", ^{
context(@"for a newly created example", ^{
it(@"should be CDRExampleStateIncomplete", ^{
@@ -155,7 +197,7 @@
[example run];
});
- it(@"should be CDRExceptionStateError", ^{
+ it(@"should be CDRExampleStateError", ^{
CDRExampleState state = example.state;
expect(state).to(equal(CDRExampleStateError));
});
@@ -168,7 +210,7 @@
[example run];
});
- it(@"should be CDRExceptionStateError", ^{
+ it(@"should be CDRExampleStateError", ^{
CDRExampleState state = example.state;
expect(state).to(equal(CDRExampleStateError));
});
@@ -181,12 +223,72 @@
[example run];
});
- it(@"should be CDRExceptionStatePending", ^{
+ it(@"should be CDRExampleStatePending", ^{
CDRExampleState state = example.state;
expect(state).to(equal(CDRExampleStatePending));
});
});
+ context(@"when running in the focused specs mode", ^{
+ context(@"for an example that was focused", ^{
+ beforeEach(^{
+ example.focused = YES;
+ });
+
+ it(@"should be CDRExampleStatePassed", ^{
+ runInFocusedSpecsMode(example);
+ expect([example state]).to(equal(CDRExampleStatePassed));
+ });
+ });
+
+ context(@"for an example that was not focused", ^{
+ beforeEach(^{
+ example.focused = NO;
+ });
+
+ context(@"and its parent group was focused", ^{
+ beforeEach(^{
+ CDRExampleGroup *parentGroup = [[CDRExampleGroup alloc] initWithText:@"Parent group"];
+ parentGroup.focused = YES;
+ example.parent = parentGroup;
+ });
+
+ it(@"should be CDRExampleStatePassed", ^{
+ runInFocusedSpecsMode(example);
+ expect([example state]).to(equal(CDRExampleStatePassed));
+ });
+ });
+
+ context(@"and its parent group was not focused", ^{
+ __block CDRExampleGroup *parentGroup;
+
+ beforeEach(^{
+ parentGroup = [[CDRExampleGroup alloc] initWithText:@"Parent group"];
+ parentGroup.focused = NO;
+ example.parent = parentGroup;
+ });
+
+ it(@"should be CDRExampleStateSkipped", ^{
+ runInFocusedSpecsMode(example);
+ expect([example state]).to(equal(CDRExampleStateSkipped));
+ });
+
+ context(@"and its parent's parent group was focused", ^{
+ beforeEach(^{
+ CDRExampleGroup *parentsParentGroup = [[CDRExampleGroup alloc] initWithText:@"Parent's parent group"];
+ parentsParentGroup.focused = YES;
+ parentGroup.parent = parentsParentGroup;
+ });
+
+ it(@"should be CDRExampleStatePassed", ^{
+ runInFocusedSpecsMode(example);
+ expect([example state]).to(equal(CDRExampleStatePassed));
+ });
+ });
+ });
+ });
+ });
+
describe(@"KVO", ^{
it(@"should report when the state changes", ^{
id mockObserver = [OCMockObject niceMockForClass:[NSObject class]];
@@ -213,6 +315,7 @@
expect(progress).to(equal(0.0));
});
});
+
describe(@"when the state is passed", ^{
beforeEach(^{
[example run];
@@ -277,6 +380,20 @@
});
});
+ describe(@"for a skipped example", ^{
+ beforeEach(^{
+ [example release];
+ example = [[CDRExample alloc] initWithText:@"I should pend" andBlock:nil];
+ example.focused = NO;
+ runInFocusedSpecsMode(example);
+ });
+
+ it(@"should return an empty string", ^{
+ NSString *message = example.message;
+ expect(message).to(equal(@""));
+ });
+ });
+
describe(@"for a failing example", ^{
__block NSString *failureMessage = @"I should fail";
View
124 Spec/Focused/FocusedSpec.m
@@ -0,0 +1,124 @@
+#if TARGET_OS_IPHONE
+// Normally you would include this file out of the framework. However, we're
+// testing the framework here, so including the file from the framework will
+// conflict with the compiler attempting to include the file from the project.
+#import "SpecHelper.h"
+#import "OCMock.h"
+#else
+#import <Cedar/SpecHelper.h>
+#import <OCMock/OCMock.h>
+#endif
+
+NSMutableArray *calledInFocusedSpec__ = nil;
+NSMutableArray *expectedCallsInFocusedSpec__ = nil;
+
+SPEC_BEGIN(FocusedSpec)
+
+calledInFocusedSpec__ = [[NSMutableArray alloc] init];
+expectedCallsInFocusedSpec__ =
+ [[NSArray alloc] initWithObjects:
+ @"fit",
+ @"describe-fit",
+ @"describe-describe-fit",
+ @"describe-fdescribe-it",
+ @"describe-fdescribe-fit",
+ @"fdescribe-it",
+ @"fdescribe-fit",
+ @"fdescribe-describe-it",
+ @"fdescribe-describe-fit",
+ @"fdescribe-fdescribe-it",
+ @"fdescribe-fdescribe-fit",
+ @"context-fit",
+ @"fcontext-it",
+ @"fcontext-fit",
+ nil];
+
+it(@"should not run non-focused example", ^{
+ [calledInFocusedSpec__ addObject:@"it"];
+});
+
+fit(@"should run focused example", ^{
+ [calledInFocusedSpec__ addObject:@"fit"];
+});
+
+describe(@"inside non-focused describe", ^{
+ it(@"should not run non-focused example", ^{
+ [calledInFocusedSpec__ addObject:@"describe-it"];
+ });
+
+ fit(@"should run focused example", ^{
+ [calledInFocusedSpec__ addObject:@"describe-fit"];
+ });
+
+ describe(@"inside nested non-focused describe", ^{
+ it(@"should not run non-focused example", ^{
+ [calledInFocusedSpec__ addObject:@"describe-describe-it"];
+ });
+
+ fit(@"should run focused example", ^{
+ [calledInFocusedSpec__ addObject:@"describe-describe-fit"];
+ });
+ });
+
+ fdescribe(@"inside nested focused describe", ^{
+ it(@"should run non-focused example", ^{
+ [calledInFocusedSpec__ addObject:@"describe-fdescribe-it"];
+ });
+
+ fit(@"should run focused example", ^{
+ [calledInFocusedSpec__ addObject:@"describe-fdescribe-fit"];
+ });
+ });
+});
+
+fdescribe(@"inside focused describe", ^{
+ it(@"should run non-focused example", ^{
+ [calledInFocusedSpec__ addObject:@"fdescribe-it"];
+ });
+
+ fit(@"should run focused example", ^{
+ [calledInFocusedSpec__ addObject:@"fdescribe-fit"];
+ });
+
+ describe(@"inside nested non-focused describe", ^{
+ it(@"should run non-focused example", ^{
+ [calledInFocusedSpec__ addObject:@"fdescribe-describe-it"];
+ });
+
+ fit(@"should run focused example", ^{
+ [calledInFocusedSpec__ addObject:@"fdescribe-describe-fit"];
+ });
+ });
+
+ fdescribe(@"inside nested focused describe", ^{
+ it(@"should run non-focused example", ^{
+ [calledInFocusedSpec__ addObject:@"fdescribe-fdescribe-it"];
+ });
+
+ fit(@"should run focused example", ^{
+ [calledInFocusedSpec__ addObject:@"fdescribe-fdescribe-fit"];
+ });
+ });
+});
+
+context(@"inside non-focused context", ^{
+ it(@"should not run non-focused example", ^{
+ [calledInFocusedSpec__ addObject:@"context-it"];
+ });
+
+ fit(@"should run focused example", ^{
+ [calledInFocusedSpec__ addObject:@"context-fit"];
+ });
+});
+
+fcontext(@"inside focused context", ^{
+ it(@"should run non-focused example", ^{
+ [calledInFocusedSpec__ addObject:@"fcontext-it"];
+ });
+
+ fit(@"should run focused example", ^{
+ [calledInFocusedSpec__ addObject:@"fcontext-fit"];
+ });
+});
+
+SPEC_END
View
28 Spec/Focused/FocusedSpec2.m
@@ -0,0 +1,28 @@
+#if TARGET_OS_IPHONE
+// Normally you would include this file out of the framework. However, we're
+// testing the framework here, so including the file from the framework will
+// conflict with the compiler attempting to include the file from the project.
+#import "SpecHelper.h"
+#import "OCMock.h"
+#else
+#import <Cedar/SpecHelper.h>
+#import <OCMock/OCMock.h>
+#endif
+
+NSMutableArray *calledInFocusedSpec2__ = nil;
+NSMutableArray *expectedCallsInFocusedSpec2__ = nil;
+
+SPEC_BEGIN(FocusedSpec2)
+
+calledInFocusedSpec2__ = [[NSMutableArray alloc] init];
+expectedCallsInFocusedSpec2__ = [[NSArray alloc] initWithObjects:@"fit", nil];
+
+it(@"should not run non-focused example", ^{
+ [calledInFocusedSpec2__ addObject:@"it"];
+});
+
+fit(@"should run focused example", ^{
+ [calledInFocusedSpec2__ addObject:@"fit"];
+});
+
+SPEC_END
View
43 Spec/Focused/main.m
@@ -0,0 +1,43 @@
+#import <Cedar/Cedar.h>
+
+extern NSMutableArray *calledInFocusedSpec__;
+extern NSMutableArray *expectedCallsInFocusedSpec__;
+
+extern NSMutableArray *calledInFocusedSpec2__;
+extern NSMutableArray *expectedCallsInFocusedSpec2__;
+
+BOOL wereExpectedCallsMade(NSArray *actuallyCalled, NSArray *expectedCalls);
+
+int main (int argc, const char *argv[]) {
+ int result = runAllSpecs();
+
+ BOOL expectedCallsMade =
+ wereExpectedCallsMade(calledInFocusedSpec__, expectedCallsInFocusedSpec__) &&
+ wereExpectedCallsMade(calledInFocusedSpec2__, expectedCallsInFocusedSpec2__);
+
+ [calledInFocusedSpec__ release];
+ [expectedCallsInFocusedSpec__ release];
+
+ [calledInFocusedSpec2__ release];
+ [expectedCallsInFocusedSpec2__ release];
+
+ return expectedCallsMade ? 0 : 1;
+}
+
+BOOL wereExpectedCallsMade(NSArray *callsMade, NSArray *expectedCalls) {
+ BOOL expectedCallsMade = YES;
+
+ for (NSString *callName in expectedCalls) {
+ if (![callsMade containsObject:callName]){
+ NSLog(@"Example '%@' was not ran but should have been.", callName);
+ expectedCallsMade = NO;
+ }
+ }
+
+ if ([callsMade count] > [expectedCalls count]) {
+ NSLog(@"Extra examples were ran but should not have been.");
+ expectedCallsMade = NO;
+ }
+
+ return expectedCallsMade;
+}
View
7 Spec/iPhone/CDRExampleStateMapSpec.mm
@@ -34,6 +34,13 @@
});
});
+ describe(@"for a skipped state", ^{
+ it(@"should return SKIPPED", ^{
+ NSString *descriptionForState = [map descriptionForState:CDRExampleStateSkipped];
+ expect(descriptionForState).to(equal(@"SKIPPED"));
+ });
+ });
+
describe(@"for a failed state", ^{
it(@"should return FAILED", ^{
NSString *descriptionForState = [map descriptionForState:CDRExampleStateFailed];

0 comments on commit 4eb0c73

Please sign in to comment.