Upgraded to UISpecRunner 0.4.0. Added Rakefile for running all the specs.

This commit is contained in:
Blake Watters
2011-03-09 15:07:20 -05:00
parent 0d9da22844
commit 0a93b377d6
9 changed files with 153 additions and 94 deletions

5
Gemfile Normal file
View File

@@ -0,0 +1,5 @@
source "http://rubygems.org"
gem "rake"
gem "uispecrunner", ">= 0.4.0"
gem "bundler", "~> 1.0.0"

18
Gemfile.lock Normal file
View File

@@ -0,0 +1,18 @@
GEM
remote: http://rubygems.org/
specs:
open4 (1.0.1)
rake (0.8.7)
uispecrunner (0.4.0)
open4 (= 1.0.1)
PLATFORMS
ruby
DEPENDENCIES
bundler (~> 1.0.0)
rake
uispecrunner (>= 0.4.0)
METADATA
version: 1.0.6

35
Rakefile Normal file
View File

@@ -0,0 +1,35 @@
require 'rubygems'
begin
gem 'uispecrunner'
require 'uispecrunner'
require 'uispecrunner/options'
rescue LoadError => error
puts "Unable to load UISpecRunner: #{error}"
end
namespace :uispec do
desc "Run all specs"
task :all do
options = UISpecRunner::Options.from_file('uispec.opts') rescue {}
uispec_runner = UISpecRunner.new(options)
uispec_runner.run_all!
end
desc "Run all unit specs (those that implement UISpecUnit)"
task :units do
options = UISpecRunner::Options.from_file('uispec.opts') rescue {}
uispec_runner = UISpecRunner.new(options)
uispec_runner.run_protocol!('UISpecUnit')
end
desc "Run all integration specs (those that implement UISpecIntegration)"
task :integration do
options = UISpecRunner::Options.from_file('uispec.opts') rescue {}
uispec_runner = UISpecRunner.new(options)
uispec_runner.run_protocol!('UISpecIntegration')
end
end
desc "Run all specs"
task :default => 'uispec:all'

View File

@@ -995,7 +995,7 @@
25956992126DF283004BAC4C /* Products */ = {
isa = PBXGroup;
children = (
25956999126DF283004BAC4C /* UISpec_Simulator.a */,
25956999126DF283004BAC4C /* libUISpec.a */,
2595699D126DF283004BAC4C /* Specs.app */,
);
name = Products;
@@ -1342,10 +1342,10 @@
remoteRef = 250BC43611F6260100F3FE5A /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
25956999126DF283004BAC4C /* UISpec_Simulator.a */ = {
25956999126DF283004BAC4C /* libUISpec.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = UISpec_Simulator.a;
path = libUISpec.a;
remoteRef = 25956998126DF283004BAC4C /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
@@ -1925,7 +1925,6 @@
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/Specs/Support/UISpec/bin/UISpec\"",
"\"$(SRCROOT)/Specs/Support/OCMock\"",
"\"$(SRCROOT)\"",
);
@@ -1965,7 +1964,6 @@
IPHONEOS_DEPLOYMENT_TARGET = 3.2;
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/Specs/Support/UISpec/bin/UISpec\"",
"\"$(SRCROOT)/Specs/Support/OCMock\"",
"\"$(SRCROOT)\"",
);

View File

@@ -16,11 +16,17 @@
*/
+(void)runSpecsConformingToProtocol:(Protocol *)protocol afterDelay:(NSTimeInterval)delay;
/**
* Run all UISpec classes inheriting from a given base class
*/
+(void)runSpecsInheritingFromClass:(Class)class afterDelay:(NSTimeInterval)delay;
/**
* Infers which set of UISpec classes to run from the following environment variables:
* UISPEC_PROTOCOL - Specifies a protocol to run
* UISPEC_SPEC - Specifies a spec class to run
* UISPEC_METHOD - Specifies an example to run (requires UISPEC_SPEC to be set)
* UISPEC_EXIT_ON_FINISH - When YES, instructs UISpecRunner to terminate the application when specs run is complete
*/
+(void)runSpecsFromEnvironmentAfterDelay:(int)seconds;

View File

@@ -6,8 +6,42 @@
// Copyright 2010 Two Toasters. All rights reserved.
//
#import <objc/runtime.h>
#import "UISpec+UISpecRunner.h"
#import <objc/runtime.h>
#import "UIConsoleLog.h"
#import "UISpec.h"
@interface UISpecRunnerLog : UIConsoleLog {
BOOL _exitOnFinish;
}
// When YES, the application will terminate after specs finish running
@property (nonatomic, assign) BOOL exitOnFinish;
@end
@implementation UISpecRunnerLog
@synthesize exitOnFinish = _exitOnFinish;
- (id)init {
self = [super init];
if (self) {
_exitOnFinish = NO;
}
return self;
}
-(void)onFinish:(int)count {
[super onFinish:count];
if (self.exitOnFinish) {
exit(errors.count);
}
}
@end
@interface UISpec ()
@@ -53,10 +87,56 @@
[self performSelector:@selector(runSpecClasses:) withObject:specClasses afterDelay:delay];
}
+(NSArray*)specClassesInheritingFromClass:(Class)parentClass {
int numClasses = objc_getClassList(NULL, 0);
Class *classes = NULL;
classes = malloc(sizeof(Class) * numClasses);
numClasses = objc_getClassList(classes, numClasses);
NSMutableArray *result = [NSMutableArray arrayWithObject:parentClass];
for (NSInteger i = 0; i < numClasses; i++)
{
Class superClass = classes[i];
do
{
superClass = class_getSuperclass(superClass);
} while(superClass && superClass != parentClass);
if (superClass == nil)
{
continue;
}
if ([self isASpec:classes[i]]) {
[result addObject:classes[i]];
}
}
free(classes);
return result;
}
+(void)runSpecsInheritingFromClass:(Class)class afterDelay:(NSTimeInterval)delay {
NSArray* specClasses = [self specClassesInheritingFromClass:class];
NSLog(@"Executing Specs: %@", specClasses);
[self performSelector:@selector(runSpecClasses:) withObject:specClasses afterDelay:delay];
}
+(void)runSpecsFromEnvironmentAfterDelay:(int)seconds {
char* protocolName = getenv("UISPEC_PROTOCOL");
char* specName = getenv("UISPEC_SPEC");
char* exampleName = getenv("UISPEC_EXAMPLE");
char* exitOnFinish = getenv("UISPEC_EXIT_ON_FINISH");
UISpecRunnerLog* log = [[UISpecRunnerLog alloc] init];
[UISpec setLog:(UILog*)log];
if (NULL == exitOnFinish || [[NSString stringWithUTF8String:exitOnFinish] isEqualToString:@"YES"]) {
log.exitOnFinish = YES;
}
if (protocolName) {
Protocol* protocol = NSProtocolFromString([NSString stringWithUTF8String:protocolName]);
NSLog(@"[UISpecRunner] Running Specs conforming to Protocol: %@", [NSString stringWithUTF8String:protocolName]);
@@ -68,11 +148,12 @@
NSLog(@"[UISpecRunner] Running Examples %s on Spec %s", exampleName, specName);
[UISpec runSpec:[NSString stringWithUTF8String:specName] example:[NSString stringWithUTF8String:exampleName] afterDelay:seconds];
} else if (specName) {
NSLog(@"[UISpecRunner] Running Spec %s", specName);
[UISpec runSpec:[NSString stringWithUTF8String:specName] afterDelay:seconds];
NSLog(@"[UISpecRunner] Running Spec classes inheriting from %s", specName);
Class class = NSClassFromString([NSString stringWithUTF8String:specName]);
[UISpec runSpecsInheritingFromClass:class afterDelay:seconds];
} else {
[UISpec runSpecsAfterDelay:seconds];
}
}
}
@end

View File

@@ -7,7 +7,6 @@
//
#import <UIKit/UIKit.h>
#import "UISpec.h"
#import "UISpec+UISpecRunner.h"
int main(int argc, char *argv[]) {

84
uispec
View File

@@ -1,84 +0,0 @@
#!/bin/zsh
# UISpec CLI Runner
# By Blake Watters <blake@twotoasters.com>
# Base code taken from: http://stackoverflow.com/questions/1514302/build-and-run-an-xcode-project-via-applescript
BUILD_PATH=$(dirname $0)
while [[ -z $BUILD_FILE && $BUILD_PATH != "/" ]]; do
BUILD_FILE=$(find $BUILD_PATH -name '*.xcodeproj' -maxdepth 1)
BUILD_PATH=$(dirname $BUILD_PATH)
done
if [[ -z $BUILD_FILE ]]; then
echo "Couldn't find an xcode project file in directory"
exit 1
fi
# Applescript likes's : instead of / (because it's insane)
BUILD_FILE=${BUILD_FILE//\//:}
# Find the latest Simulator SDK
SIMULATOR_SDKS=( /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/*.sdk )
SIMULATOR_SDK=${SIMULATOR_SDKS[-1]}
SIMULATOR_SDK_STRING=$(basename ${(L)SIMULATOR_SDK%.[a-z]*})
if [[ -z $SIMULATOR_SDK ]]; then
echo "Couldn't find a simulator SDK"
exit 1
fi
# Use the first arg as the spec to run...
UISPEC_RUN_SPEC=$1
osascript <<SCRIPT
on setEnvironmentVariable(variableName, variableValue)
tell application "Xcode"
tell active project document
set executableName to name of executable of active target as string
tell executable executableName
-- Check to see if the fallback path already exists
set hasVariable to false as boolean
repeat with environmentVariable in environment variables
if name of environmentVariable is equal to variableName then
-- Overwrite any value
set value of environmentVariable to variableValue
set active of environmentVariable to yes
set hasVariable to true as boolean
exit repeat
end if
end repeat
-- Since the fallback path doesn't exist yet, create it
if not hasVariable then
make new environment variable with properties {name:variableName, value:variableValue, active:yes}
end if
end tell -- executable
end tell -- active project document
end tell -- Xcode
end setEnvironmentVariable
application "iPhone Simulator" quit
application "iPhone Simulator" activate
tell application "Xcode"
open "$BUILD_FILE"
set targetProject to project of active project document
my setEnvironmentVariable("UISPEC_RUN_SPEC", "$UISPEC_RUN_SPEC")
tell targetProject
set active build configuration type to build configuration type "Debug"
set active SDK to "$SIMULATOR_SDK_STRING"
set the active target to the target named "UISpec"
set value of build setting "SDKROOT" of build configuration "Debug" of active target to "$SIMULATOR_SDK"
build targetProject
launch targetProject
end tell
end tell
SCRIPT

1
uispec.opts Normal file
View File

@@ -0,0 +1 @@
--workspace RestKit.xcodeproj/project.xcworkspace