Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Focused specs #13

Merged
merged 2 commits into from

2 participants

@cppforlife
Owner

Added fdescribe, fcontext, and fit to be able to mark specific examples as focused. This is useful when developing a feature and you only want to run specific subset of your test suite.

cppforlife added some commits
@cppforlife cppforlife Added ability to run focused specs. fdescribe, fcontext, and fit mark…
… examples as focused.
0d6d16e
@cppforlife cppforlife Added FocusedSpecs target that has specs with several focused example…
…s. FocusedSpecs target tests that only focused examples run when there is at least one focused example present in all running specs.
62e8455
@pivotal pivotal merged commit 4eb0c73 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 13, 2011
  1. @cppforlife
  2. @cppforlife

    Added FocusedSpecs target that has specs with several focused example…

    cppforlife authored
    …s. FocusedSpecs target tests that only focused examples run when there is at least one focused example present in all running specs.
This page is out of date. Refresh to see the latest.
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, ); }; };
AE0AF56613E9C0E300029396 /* Base.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF55F13E9C0E300029396 /* Base.h */; settings = {ATTRIBUTES = (Public, ); }; };
AE0AF56713E9C0E300029396 /* BeCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = AE0AF56013E9C0E300029396 /* BeCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -148,6 +153,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 */;
@@ -239,6 +258,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>"; };
AE0AF55F13E9C0E300029396 /* Base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base.h; sourceTree = "<group>"; };
AE0AF56013E9C0E300029396 /* BeCloseTo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BeCloseTo.h; sourceTree = "<group>"; };
@@ -271,14 +294,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>"; };
@@ -299,8 +322,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>"; };
@@ -321,6 +344,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;
@@ -356,6 +388,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 = (
@@ -431,6 +473,7 @@
AEEE218611DC28E200029872 /* Specs */,
AEEE222911DC2B0600029872 /* libCedar-StaticLib.a */,
AEEE227611DC2CF900029872 /* iPhoneSpecs.app */,
+ 96A07F0813F276640021974D /* FocusedSpecs */,
);
name = Products;
sourceTree = "<group>";
@@ -519,14 +562,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>";
@@ -535,8 +579,8 @@
isa = PBXGroup;
children = (
AEEE1FEC11DC27B800029872 /* CDRExampleStateMapSpec.mm */,
- AEEE1FED11DC27B800029872 /* main.m */,
AEEE1FEE11DC27B800029872 /* SlowSpec.m */,
+ AEEE1FED11DC27B800029872 /* main.m */,
);
path = iPhone;
sourceTree = "<group>";
@@ -597,6 +641,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" */;
@@ -697,6 +759,7 @@
targets = (
AEEE1FB511DC271300029872 /* Cedar */,
AEEE218511DC28E200029872 /* Specs */,
+ 96A07EEE13F276640021974D /* FocusedSpecs */,
AEEE222811DC2B0600029872 /* Cedar-StaticLib */,
AEEE224B11DC2BBB00029872 /* Cedar-iPhone */,
AEEE227511DC2CF900029872 /* iPhoneSpecs */,
@@ -777,6 +840,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;
@@ -874,6 +947,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;
@@ -897,6 +980,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 = {
@@ -1159,6 +1292,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
@@ -71,6 +71,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 {
[self.sharedExampleContext removeAllObjects];
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];
Something went wrong with that request. Please try again.