uispecrunner 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -31,9 +31,11 @@ to the spec runner. Example:
31
31
  - Will read common arguments from uispec.opts file for easy per project configuration
32
32
  - Includes a sample Rakefile for running your UISpec's
33
33
  - Support for setting arbitrary environment variables on the runner
34
- - Supports running specs via shell (xcodebuild) or AppleScript (osascript)
34
+ - Builds project using xcodebuild
35
+ - Supports running specs via shell or AppleScript (osascript)
35
36
 
36
37
  ## TODO
38
+ - Run via WaxSim
37
39
  - Simulator/device switch...
38
40
  - Auto-detect SDK versions available
39
41
  - Support for running specific files
data/Rakefile CHANGED
@@ -11,6 +11,7 @@ begin
11
11
  gem.homepage = "http://github.com/twotoasters/UISpecRunner"
12
12
  gem.authors = ["Blake Watters"]
13
13
  gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_runtime_dependency "open4", "= 1.0.1"
14
15
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
16
  end
16
17
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.4.0
@@ -10,25 +10,20 @@ class UISpecRunner
10
10
  end
11
11
 
12
12
  def run_specs(env)
13
- if build_project!
14
- run_env = config.env.merge(env)
15
- run_env.merge!('DYLD_ROOT_PATH' => sdk_dir, 'IPHONE_SIMULATOR_ROOT' => sdk_dir, 'CFFIXED_USER_HOME' => Dir.tmpdir)
16
- puts "Setting environment variables: #{run_env.inspect}" if config.verbose?
17
- with_env(run_env) do
18
- start_securityd if config.securityd
19
- command = "#{config.build_dir}/#{config.configuration}-iphonesimulator/#{config.target}.app/#{config.target} -RegisterForSystemEvents"
20
- puts "Executing: #{command}" if config.verbose?
21
- output = `#{command}`
22
- exit_code = $?
23
- unless exit_code == 0
24
- puts "[!] Failed to run UISpec target: #{output}"
25
- exit 1
26
- end
13
+ run_env = config.env.merge(env)
14
+ run_env.merge!('DYLD_ROOT_PATH' => config.sdk_dir, 'IPHONE_SIMULATOR_ROOT' => config.sdk_dir, 'CFFIXED_USER_HOME' => Dir.tmpdir)
15
+ puts "Setting environment variables: #{run_env.inspect}" if config.verbose?
16
+ with_env(run_env) do
17
+ start_securityd if config.securityd
18
+ command = "#{config.app_executable_path} -RegisterForSystemEvents"
19
+ puts "Executing: #{command}" if config.verbose?
20
+ output = `#{command}`
21
+ exit_code = $?
22
+ unless exit_code == 0
23
+ puts "[!] Failed specs running UISpec target (exit code #{exit_code})"
24
+ exit 1
27
25
  end
28
- else
29
- puts "[!] Failed to build UISpecs.app"
30
- exit 1
31
- end
26
+ end
32
27
  end
33
28
 
34
29
  def with_env(env)
@@ -38,24 +33,6 @@ class UISpecRunner
38
33
  ensure
39
34
  before.each { |k, v| ENV[k] = v }
40
35
  end
41
-
42
- def project_switch
43
- "-project #{config.project}" if config.project
44
- end
45
-
46
- def sdk_switch
47
- "-sdk #{sdk_dir}" if config.sdk_version
48
- end
49
-
50
- def sdk_dir
51
- "/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator#{config.sdk_version}.sdk"
52
- end
53
-
54
- def build_project!
55
- command = "xcodebuild #{project_switch} -target #{config.target} -configuration #{config.configuration} #{sdk_switch} > /dev/null"
56
- puts "Building project with: #{command}" if config.verbose?
57
- system(command)
58
- end
59
36
 
60
37
  def run_command(command)
61
38
  puts "Executing: #{command}" if config.verbose?
@@ -63,7 +40,7 @@ class UISpecRunner
63
40
  end
64
41
 
65
42
  def path_to_securityd
66
- "#{sdk_dir}/usr/libexec/securityd"
43
+ "#{config.sdk_dir}/usr/libexec/securityd"
67
44
  end
68
45
 
69
46
  def start_securityd
@@ -14,12 +14,12 @@ class UISpecRunner
14
14
 
15
15
  # Configure default settings
16
16
  self[:run_mode] = :all
17
- self[:target] = 'UISpec'
18
17
  self[:configuration] = 'Debug'
19
18
  self[:build_dir] = './build'
20
19
  self[:verbose] = false
21
20
  self[:sdk_version] = '4.0'
22
21
  self[:driver] = :shell
22
+ self[:exit_on_finish] = true
23
23
 
24
24
  require 'optparse'
25
25
  @opts = OptionParser.new do |o|
@@ -53,6 +53,17 @@ class UISpecRunner
53
53
  self[:project] = project
54
54
  end
55
55
 
56
+ o.on('--workspace [WORKSPACE_PATH]',
57
+ 'Run the UISpec scheme in the specified Xcode workspace at the path') do |workspace|
58
+ self[:workspace] = workspace
59
+ end
60
+
61
+ o.on('--scheme [SCHEME_NAME]',
62
+ 'Build and run the specified XCode scheme.',
63
+ 'Default: UISpec (If workspace provided)') do |scheme|
64
+ self[:scheme] = scheme
65
+ end
66
+
56
67
  o.on('--driver [DRIVER]', [:shell, :osascript],
57
68
  "Select driver (shell, osascript)",
58
69
  'Default: shell') do |driver|
@@ -84,23 +95,33 @@ class UISpecRunner
84
95
  end
85
96
 
86
97
  o.on('--securityd',
87
- 'Start the securityd daemon before running specs. This allow interaction with the keychain.') do |securityd|
98
+ 'Start the securityd daemon before running specs. This allows interaction with the keychain.') do |securityd|
88
99
  self[:securityd] = securityd
89
100
  end
90
101
 
102
+ o.on('--no-exit', 'Do not exit the process after running the specs') do |exit_on_finish|
103
+ self[:exit_on_finish] = exit_on_finish
104
+ end
105
+
91
106
  o.on('-v', '--[no-]verbose', "Run verbosely") do |v|
92
107
  self[:verbose] = v
93
108
  end
94
109
 
95
- o.on_tail('-h', '--help', 'display this help and exit') do
110
+ o.on_tail('-h', '--help', 'Display this help and exit') do
96
111
  self[:show_help] = true
97
112
  end
98
113
  end
99
114
 
100
115
  begin
101
116
  @opts.parse!(args)
117
+
118
+ # Set default Scheme name if Workspace was provided
119
+ if self[:workspace]
120
+ self[:scheme] ||= 'UISpec'
121
+ else
122
+ self[:target] ||= 'UISpec'
123
+ end
102
124
  # TODO: Support running specific files
103
- #self[:project_name] = args.shift
104
125
  rescue OptionParser::InvalidOption => e
105
126
  self[:invalid_argument] = e.message
106
127
  end
@@ -0,0 +1,50 @@
1
+ class UISpecRunner
2
+ class XcodeBuilder
3
+ attr_reader :config, :app_path
4
+
5
+ def initialize(config)
6
+ @config = config
7
+ end
8
+
9
+ def build!
10
+ command = "xcodebuild #{workspace_switch} #{scheme_switch} #{project_switch} #{target_switch} -configuration #{config.configuration} #{sdk_switch}"
11
+ puts "Building project with: #{command}" if config.verbose?
12
+ status = Open4::popen4(command) do |pid, stdin, stdout, stderr|
13
+ stdout.each_line do |line|
14
+ if line =~ /^Touch\s/
15
+ @app_path = line.split(/^Touch\s/).last.chomp
16
+ puts "*** Found app path: #{self.app_path}" if config.verbose?
17
+ end
18
+ puts line if config.verbose?
19
+ end
20
+
21
+ stderr.each_line do |line|
22
+ puts line
23
+ end
24
+ end
25
+ puts "Exited with status: #{ status.exitstatus }" if config.verbose? || status.exitstatus != 0
26
+ return status.exitstatus
27
+ end
28
+
29
+ private
30
+ def workspace_switch
31
+ "-workspace #{config.workspace}" if config.workspace
32
+ end
33
+
34
+ def scheme_switch
35
+ "-scheme #{config.scheme}" if config.scheme
36
+ end
37
+
38
+ def project_switch
39
+ "-project #{config.project}" if config.project
40
+ end
41
+
42
+ def target_switch
43
+ "-target #{config.target}" if config.target
44
+ end
45
+
46
+ def sdk_switch
47
+ "-sdk #{config.sdk_dir}" if config.sdk_version
48
+ end
49
+ end
50
+ end
data/lib/uispecrunner.rb CHANGED
@@ -2,22 +2,30 @@
2
2
  # By: Blake Watters <blake@twotoasters.com>
3
3
  # Portions borrowed from Eloy Duran's Kicker script (http://github.com/alloy/UISpec)
4
4
 
5
+ require 'rubygems'
6
+ gem 'open4', '>= 1.0.1'
7
+ require 'open4'
8
+ require 'uispecrunner/xcode_builder'
5
9
  require 'uispecrunner/drivers/shell'
6
10
  require 'uispecrunner/drivers/osascript'
7
11
 
8
- class UISpecRunner
9
- attr_accessor :project, :target, :configuration, :sdk_version, :build_dir, :verbose, :securityd, :driver, :env
12
+ class UISpecRunner
13
+ # Build Options
14
+ attr_accessor :workspace, :scheme, :project, :target, :configuration, :sdk_version, :build_dir
15
+
16
+ # Run Options
17
+ attr_accessor :verbose, :securityd, :driver, :env, :exit_on_finish, :app_path
10
18
 
11
19
  # private
12
20
  attr_accessor :run_mode, :spec, :example, :protocol
13
21
 
14
22
  def initialize(options = {})
15
23
  options.each { |k,v| self.send("#{k}=", v) }
16
- self.target ||= 'UISpec'
17
24
  self.configuration ||= 'Debug'
18
25
  self.build_dir ||= './build'
19
26
  self.run_mode ||= :all
20
27
  self.driver ||= :shell
28
+ self.exit_on_finish ||= true
21
29
  self.env ||= {}
22
30
  end
23
31
 
@@ -52,12 +60,39 @@ class UISpecRunner
52
60
  run_specs('UISPEC_SPEC' => spec_name, 'UISPEC_EXAMPLE' => example_name)
53
61
  end
54
62
 
63
+ # Configuration Methods
64
+
55
65
  def verbose?
56
66
  self.verbose
57
67
  end
58
68
 
69
+ def exit_on_finish?
70
+ self.exit_on_finish
71
+ end
72
+
73
+ def xcode_root
74
+ @xcode_root ||= "#{`xcode-select -print-path`.chomp}"
75
+ end
76
+
77
+ def sdk_dir
78
+ "#{xcode_root}/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator#{self.sdk_version}.sdk"
79
+ end
80
+
81
+ def app_path
82
+ @app_path || "#{self.build_dir}/#{self.configuration}-iphonesimulator/#{self.target}.app/#{self.target}"
83
+ end
84
+
85
+ def app_executable_name
86
+ File.basename(app_path).gsub(/.app$/, '')
87
+ end
88
+
89
+ def app_executable_path
90
+ File.join(app_path, app_executable_name)
91
+ end
92
+
59
93
  private
60
94
  def driver_class
95
+ # TODO: Add WaxSim...
61
96
  if self.driver == :shell
62
97
  UISpecRunner::Drivers::Shell
63
98
  elsif self.driver == :osascript
@@ -66,8 +101,19 @@ class UISpecRunner
66
101
  end
67
102
 
68
103
  def run_specs(env = {})
69
- puts "Running specs via #{driver}..."
70
- driver = driver_class.new(self)
71
- driver.run_specs(env)
104
+ puts "Building project..."
105
+ builder = UISpecRunner::XcodeBuilder.new(self)
106
+ if builder.build!
107
+ @app_path ||= builder.app_path
108
+ puts "Running specs via #{driver}..."
109
+ env['UISPEC_EXIT_ON_FINISH'] = self.exit_on_finish? ? 'YES' : 'NO'
110
+ driver = driver_class.new(self)
111
+ driver.run_specs(env)
112
+ # TODO: Exit with exit code from the process...
113
+ else
114
+ puts "Failed to build"
115
+ # TODO: Exit with the exit code from xcodebuild...
116
+ exit(-1)
117
+ end
72
118
  end
73
119
  end
@@ -26,6 +26,7 @@
26
26
  * UISPEC_PROTOCOL - Specifies a protocol to run
27
27
  * UISPEC_SPEC - Specifies a spec class to run
28
28
  * UISPEC_METHOD - Specifies an example to run (requires UISPEC_SPEC to be set)
29
+ * UISPEC_EXIT_ON_FINISH - When YES, instructs UISpecRunner to terminate the application when specs run is complete
29
30
  */
30
31
  +(void)runSpecsFromEnvironmentAfterDelay:(int)seconds;
31
32
 
@@ -8,6 +8,40 @@
8
8
 
9
9
  #import "UISpec+UISpecRunner.h"
10
10
  #import <objc/runtime.h>
11
+ #import "UIConsoleLog.h"
12
+ #import "UISpec.h"
13
+
14
+ @interface UISpecRunnerLog : UIConsoleLog {
15
+ BOOL _exitOnFinish;
16
+ }
17
+
18
+ // When YES, the application will terminate after specs finish running
19
+ @property (nonatomic, assign) BOOL exitOnFinish;
20
+
21
+ @end
22
+
23
+ @implementation UISpecRunnerLog
24
+
25
+ @synthesize exitOnFinish = _exitOnFinish;
26
+
27
+ - (id)init {
28
+ self = [super init];
29
+ if (self) {
30
+ _exitOnFinish = NO;
31
+ }
32
+
33
+ return self;
34
+ }
35
+
36
+ -(void)onFinish:(int)count {
37
+ [super onFinish:count];
38
+
39
+ if (self.exitOnFinish) {
40
+ exit(errors.count);
41
+ }
42
+ }
43
+
44
+ @end
11
45
 
12
46
  @interface UISpec ()
13
47
 
@@ -94,6 +128,15 @@
94
128
  char* protocolName = getenv("UISPEC_PROTOCOL");
95
129
  char* specName = getenv("UISPEC_SPEC");
96
130
  char* exampleName = getenv("UISPEC_EXAMPLE");
131
+ char* exitOnFinish = getenv("UISPEC_EXIT_ON_FINISH");
132
+
133
+ UISpecRunnerLog* log = [[UISpecRunnerLog alloc] init];
134
+ [UISpec setLog:(UILog*)log];
135
+
136
+ if (NULL == exitOnFinish || [[NSString stringWithUTF8String:exitOnFinish] isEqualToString:@"YES"]) {
137
+ log.exitOnFinish = YES;
138
+ }
139
+
97
140
  if (protocolName) {
98
141
  Protocol* protocol = NSProtocolFromString([NSString stringWithUTF8String:protocolName]);
99
142
  NSLog(@"[UISpecRunner] Running Specs conforming to Protocol: %@", [NSString stringWithUTF8String:protocolName]);
@@ -110,7 +153,7 @@
110
153
  [UISpec runSpecsInheritingFromClass:class afterDelay:seconds];
111
154
  } else {
112
155
  [UISpec runSpecsAfterDelay:seconds];
113
- }
156
+ }
114
157
  }
115
158
 
116
159
  @end
data/src/main.m CHANGED
@@ -7,15 +7,13 @@
7
7
  //
8
8
 
9
9
  #import <UIKit/UIKit.h>
10
- #import <UISpec.h>
11
10
  #import "UISpec+UISpecRunner.h"
12
11
 
13
- int main(int argc, char *argv[]) {
14
-
15
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
12
+ int main(int argc, char *argv[]) {
13
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
16
14
 
17
- // Run the specs
18
- [UISpec runSpecsFromEnvironmentAfterDelay:0.5];
15
+ // Run the specs
16
+ [UISpec runSpecsFromEnvironmentAfterDelay:0.5];
19
17
 
20
18
  int retVal = UIApplicationMain(argc, argv, nil, nil);
21
19
  [pool release];
data/uispecrunner.gemspec CHANGED
@@ -1,55 +1,54 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{uispecrunner}
8
- s.version = "0.3.3"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Blake Watters"]
12
- s.date = %q{2011-02-15}
12
+ s.date = %q{2011-03-09}
13
13
  s.default_executable = %q{uispec}
14
14
  s.description = %q{Provides a simple Ruby interface for running UISpec iPhone tests}
15
15
  s.email = %q{blake@twotoasters.com}
16
16
  s.executables = ["uispec"]
17
17
  s.extra_rdoc_files = [
18
18
  "LICENSE",
19
- "README.md"
19
+ "README.md"
20
20
  ]
21
21
  s.files = [
22
- ".gitignore",
23
- "CHANGELOG",
24
- "LICENSE",
25
- "README.md",
26
- "Rakefile",
27
- "VERSION",
28
- "bin/uispec",
29
- "lib/uispecrunner.rb",
30
- "lib/uispecrunner/application.rb",
31
- "lib/uispecrunner/drivers/osascript.rb",
32
- "lib/uispecrunner/drivers/shell.rb",
33
- "lib/uispecrunner/options.rb",
34
- "spec/options_spec.rb",
35
- "spec/spec.opts",
36
- "spec/spec_helper.rb",
37
- "spec/uispecrunner_spec.rb",
38
- "src/UISpec+UISpecRunner.h",
39
- "src/UISpec+UISpecRunner.m",
40
- "src/main.m",
41
- "tasks/uispec.rake",
42
- "uispecrunner.gemspec"
22
+ "CHANGELOG",
23
+ "LICENSE",
24
+ "README.md",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "bin/uispec",
28
+ "lib/uispecrunner.rb",
29
+ "lib/uispecrunner/application.rb",
30
+ "lib/uispecrunner/drivers/osascript.rb",
31
+ "lib/uispecrunner/drivers/shell.rb",
32
+ "lib/uispecrunner/options.rb",
33
+ "lib/uispecrunner/xcode_builder.rb",
34
+ "spec/options_spec.rb",
35
+ "spec/spec.opts",
36
+ "spec/spec_helper.rb",
37
+ "spec/uispecrunner_spec.rb",
38
+ "src/UISpec+UISpecRunner.h",
39
+ "src/UISpec+UISpecRunner.m",
40
+ "src/main.m",
41
+ "tasks/uispec.rake",
42
+ "uispecrunner.gemspec"
43
43
  ]
44
44
  s.homepage = %q{http://github.com/twotoasters/UISpecRunner}
45
- s.rdoc_options = ["--charset=UTF-8"]
46
45
  s.require_paths = ["lib"]
47
46
  s.rubygems_version = %q{1.3.7}
48
47
  s.summary = %q{Flexible spec runner for UISpec on iOS}
49
48
  s.test_files = [
50
49
  "spec/options_spec.rb",
51
- "spec/spec_helper.rb",
52
- "spec/uispecrunner_spec.rb"
50
+ "spec/spec_helper.rb",
51
+ "spec/uispecrunner_spec.rb"
53
52
  ]
54
53
 
55
54
  if s.respond_to? :specification_version then
@@ -58,11 +57,14 @@ Gem::Specification.new do |s|
58
57
 
59
58
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
60
59
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
60
+ s.add_runtime_dependency(%q<open4>, ["= 1.0.1"])
61
61
  else
62
62
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
63
+ s.add_dependency(%q<open4>, ["= 1.0.1"])
63
64
  end
64
65
  else
65
66
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
67
+ s.add_dependency(%q<open4>, ["= 1.0.1"])
66
68
  end
67
69
  end
68
70
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uispecrunner
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
- - 3
10
- version: 0.3.3
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Blake Watters
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-15 00:00:00 -05:00
18
+ date: 2011-03-09 00:00:00 -05:00
19
19
  default_executable: uispec
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -34,6 +34,22 @@ dependencies:
34
34
  version: 1.2.9
35
35
  type: :development
36
36
  version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: open4
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - "="
44
+ - !ruby/object:Gem::Version
45
+ hash: 21
46
+ segments:
47
+ - 1
48
+ - 0
49
+ - 1
50
+ version: 1.0.1
51
+ type: :runtime
52
+ version_requirements: *id002
37
53
  description: Provides a simple Ruby interface for running UISpec iPhone tests
38
54
  email: blake@twotoasters.com
39
55
  executables:
@@ -44,7 +60,6 @@ extra_rdoc_files:
44
60
  - LICENSE
45
61
  - README.md
46
62
  files:
47
- - .gitignore
48
63
  - CHANGELOG
49
64
  - LICENSE
50
65
  - README.md
@@ -56,6 +71,7 @@ files:
56
71
  - lib/uispecrunner/drivers/osascript.rb
57
72
  - lib/uispecrunner/drivers/shell.rb
58
73
  - lib/uispecrunner/options.rb
74
+ - lib/uispecrunner/xcode_builder.rb
59
75
  - spec/options_spec.rb
60
76
  - spec/spec.opts
61
77
  - spec/spec_helper.rb
@@ -70,8 +86,8 @@ homepage: http://github.com/twotoasters/UISpecRunner
70
86
  licenses: []
71
87
 
72
88
  post_install_message:
73
- rdoc_options:
74
- - --charset=UTF-8
89
+ rdoc_options: []
90
+
75
91
  require_paths:
76
92
  - lib
77
93
  required_ruby_version: !ruby/object:Gem::Requirement
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC