hydra 0.14.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,9 +20,12 @@ In your rakefile:
20
20
  require 'hydra/tasks'
21
21
 
22
22
  Hydra::TestTask.new('hydra') do |t|
23
+ # test unit
23
24
  t.add_files 'test/unit/**/*_test.rb'
24
25
  t.add_files 'test/functional/**/*_test.rb'
25
26
  t.add_files 'test/integration/**/*_test.rb'
27
+ # cucumber
28
+ t.add_files 'features/**/*.feature'
26
29
  end
27
30
 
28
31
  Run:
@@ -32,6 +35,16 @@ Run:
32
35
  Hydra defaults to Single Core mode, so you may want to configure it
33
36
  to use two (or more) of your cores if you have a multi-processing machine.
34
37
 
38
+ == Supported frameworks
39
+
40
+ Right now hydra only supports a few frameworks:
41
+
42
+ * Test::Unit
43
+ * Cucumber
44
+
45
+ We're working on adding more frameworks, and if you'd like to help, please
46
+ send me a message and I'll show you where to code!
47
+
35
48
  == Running Remote Tasks
36
49
 
37
50
  You can run tasks across all of your remote workers easily with Hydra. In your rake file, add:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.14.1
1
+ 0.15.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{hydra}
8
- s.version = "0.14.1"
8
+ s.version = "0.15.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nick Gauthier"]
12
- s.date = %q{2010-03-25}
12
+ s.date = %q{2010-03-30}
13
13
  s.description = %q{Spread your tests over multiple machines to test your code faster.}
14
14
  s.email = %q{nick@smartlogicsolutions.com}
15
15
  s.extra_rdoc_files = [
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "hydra.gemspec",
31
31
  "hydra_gray.png",
32
32
  "lib/hydra.rb",
33
+ "lib/hydra/cucumber/formatter.rb",
33
34
  "lib/hydra/hash.rb",
34
35
  "lib/hydra/listener/abstract.rb",
35
36
  "lib/hydra/listener/minimal_output.rb",
@@ -52,6 +53,8 @@ Gem::Specification.new do |s|
52
53
  "lib/hydra/worker.rb",
53
54
  "test/fixtures/assert_true.rb",
54
55
  "test/fixtures/config.yml",
56
+ "test/fixtures/features/step_definitions.rb",
57
+ "test/fixtures/features/write_file.feature",
55
58
  "test/fixtures/hello_world.rb",
56
59
  "test/fixtures/slow.rb",
57
60
  "test/fixtures/sync_test.rb",
@@ -78,6 +81,7 @@ Gem::Specification.new do |s|
78
81
  "test/fixtures/sync_test.rb",
79
82
  "test/fixtures/assert_true.rb",
80
83
  "test/fixtures/hello_world.rb",
84
+ "test/fixtures/features/step_definitions.rb",
81
85
  "test/master_test.rb",
82
86
  "test/worker_test.rb",
83
87
  "test/runner_test.rb",
@@ -0,0 +1,31 @@
1
+ require 'cucumber/formatter/console'
2
+ require 'cucumber/formatter/io'
3
+
4
+ module Cucumber #:nodoc:
5
+ module Formatter #:nodoc:
6
+ # Hydra formatter for cucumber.
7
+ # Stifles all output except error messages
8
+ # Based on the
9
+ class Hydra < Cucumber::Formatter::Progress
10
+ # Removed the extra newlines here
11
+ def after_features(features)
12
+ print_summary(features)
13
+ end
14
+
15
+ private
16
+
17
+ # Removed the file statistics
18
+ def print_summary(features)
19
+ print_steps(:pending)
20
+ print_steps(:failed)
21
+ print_snippets(@options)
22
+ print_passing_wip(@options)
23
+ print_tag_limit_warnings(features)
24
+ end
25
+
26
+ # Removed all progress output
27
+ def progress(status)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -33,29 +33,17 @@ module Hydra #:nodoc:
33
33
  # Run a test file and report the results
34
34
  def run_file(file)
35
35
  trace "Running file: #{file}"
36
- begin
37
- require file
38
- rescue LoadError => ex
39
- trace "#{file} does not exist [#{ex.to_s}]"
40
- @io.write Results.new(:output => ex.to_s, :file => file)
41
- return
42
- end
43
- output = []
44
- @result = Test::Unit::TestResult.new
45
- @result.add_listener(Test::Unit::TestResult::FAULT) do |value|
46
- output << value
47
- end
48
36
 
49
- klasses = Runner.find_classes_in_file(file)
50
- begin
51
- klasses.each{|klass| klass.suite.run(@result){|status, name| ;}}
52
- rescue => ex
53
- output << ex.to_s
37
+ output = ""
38
+ if file =~ /.rb$/
39
+ output = run_ruby_file(file)
40
+ elsif file =~ /.feature$/
41
+ output = run_cucumber_file(file)
54
42
  end
55
43
 
56
- output << '.' if output.empty?
44
+ output = "." if output == ""
57
45
 
58
- @io.write Results.new(:output => output.join("\n"), :file => file)
46
+ @io.write Results.new(:output => output, :file => file)
59
47
  end
60
48
 
61
49
  # Stop running
@@ -86,6 +74,94 @@ module Hydra #:nodoc:
86
74
  end
87
75
  end
88
76
 
77
+ # Run a ruby file (ending in .rb)
78
+ def run_ruby_file(file)
79
+ run_test_unit_file(file) + run_rspec_file(file)
80
+ end
81
+
82
+ # Run all the Test::Unit Suites in a ruby file
83
+ def run_test_unit_file(file)
84
+ begin
85
+ require file
86
+ rescue LoadError => ex
87
+ trace "#{file} does not exist [#{ex.to_s}]"
88
+ return ex.to_s
89
+ end
90
+ output = []
91
+ @result = Test::Unit::TestResult.new
92
+ @result.add_listener(Test::Unit::TestResult::FAULT) do |value|
93
+ output << value
94
+ end
95
+
96
+ klasses = Runner.find_classes_in_file(file)
97
+ begin
98
+ klasses.each{|klass| klass.suite.run(@result){|status, name| ;}}
99
+ rescue => ex
100
+ output << ex.to_s
101
+ end
102
+
103
+ return output.join("\n")
104
+ end
105
+
106
+ # run all the Specs in an RSpec file (NOT IMPLEMENTED)
107
+ def run_rspec_file(file)
108
+ #TODO
109
+ # Given the file
110
+ # return "" if all the tests passed
111
+ # or return the error messages for the entire file
112
+ return ""
113
+ end
114
+
115
+ # run all the scenarios in a cucumber feature file
116
+ def run_cucumber_file(file)
117
+ require 'cucumber'
118
+ require 'cucumber/formatter/progress'
119
+ require 'hydra/cucumber/formatter'
120
+ def tag_excess(features, limits)
121
+ limits.map do |tag_name, tag_limit|
122
+ tag_locations = features.tag_locations(tag_name)
123
+ if tag_limit && (tag_locations.length > tag_limit)
124
+ [tag_name, tag_limit, tag_locations]
125
+ else
126
+ nil
127
+ end
128
+ end.compact
129
+ end
130
+
131
+ files = [file]
132
+ dev_null = StringIO.new
133
+
134
+ options = Cucumber::Cli::Options.new
135
+ configuration = Cucumber::Cli::Configuration.new(dev_null, dev_null)
136
+ configuration.parse!([]+files)
137
+ step_mother = Cucumber::StepMother.new
138
+
139
+ step_mother.options = configuration.options
140
+ step_mother.log = configuration.log
141
+ step_mother.load_code_files(configuration.support_to_load)
142
+ step_mother.after_configuration(configuration)
143
+ features = step_mother.load_plain_text_features(files)
144
+ step_mother.load_code_files(configuration.step_defs_to_load)
145
+
146
+ tag_excess = tag_excess(features, configuration.options[:tag_expression].limits)
147
+ configuration.options[:tag_excess] = tag_excess
148
+
149
+ hydra_response = StringIO.new
150
+ formatter = Cucumber::Formatter::Hydra.new(
151
+ step_mother, hydra_response, configuration.options
152
+ )
153
+
154
+ runner = Cucumber::Ast::TreeWalker.new(
155
+ step_mother, [formatter], configuration.options, dev_null
156
+ )
157
+ step_mother.visitor = runner
158
+ runner.visit_features(features)
159
+
160
+ hydra_response.rewind
161
+ return hydra_response.read
162
+ end
163
+
164
+ # find all the test unit classes in a given file, so we can run their suites
89
165
  def self.find_classes_in_file(f)
90
166
  code = ""
91
167
  File.open(f) {|buffer| code = buffer.read}
@@ -0,0 +1,17 @@
1
+ Given /^a target file$/ do
2
+ @target_file = File.expand_path(File.join(Dir.tmpdir, 'hydra_test.txt'))
3
+ end
4
+
5
+ When /^I write "([^\"]*)" to the file$/ do |text|
6
+ f = File.new(@target_file, 'w')
7
+ f.write text
8
+ f.flush
9
+ f.close
10
+ end
11
+
12
+ Then /^"([^\"]*)" should be written in the file$/ do |text|
13
+ f = File.new(@target_file, 'r')
14
+ raise 'Did not write to file' unless text == f.read
15
+ f.close
16
+ end
17
+
@@ -0,0 +1,7 @@
1
+ Feature: Write a file
2
+
3
+ Scenario: Write to hydra_test.txt
4
+ Given a target file
5
+ When I write "HYDRA" to the file
6
+ Then "HYDRA" should be written in the file
7
+
@@ -18,7 +18,7 @@ class RunnerTest < Test::Unit::TestCase
18
18
  # coverage output
19
19
  pipe = Hydra::Pipe.new
20
20
  parent = Process.fork do
21
- request_a_file_and_verify_completion(pipe)
21
+ request_a_file_and_verify_completion(pipe, test_file)
22
22
  end
23
23
  run_the_runner(pipe)
24
24
  Process.wait(parent)
@@ -31,10 +31,19 @@ class RunnerTest < Test::Unit::TestCase
31
31
  child = Process.fork do
32
32
  run_the_runner(pipe)
33
33
  end
34
- request_a_file_and_verify_completion(pipe)
34
+ request_a_file_and_verify_completion(pipe, test_file)
35
35
  Process.wait(child)
36
36
  end
37
37
 
38
+ should "run a cucumber test" do
39
+ pipe = Hydra::Pipe.new
40
+ parent = Process.fork do
41
+ request_a_file_and_verify_completion(pipe, cucumber_feature_file)
42
+ end
43
+ run_the_runner(pipe)
44
+ Process.wait(parent)
45
+ end
46
+
38
47
  should "be able to run a runner over ssh" do
39
48
  ssh = Hydra::SSH.new(
40
49
  'localhost',
@@ -62,12 +71,12 @@ class RunnerTest < Test::Unit::TestCase
62
71
  end
63
72
 
64
73
  module RunnerTestHelper
65
- def request_a_file_and_verify_completion(pipe)
74
+ def request_a_file_and_verify_completion(pipe, file)
66
75
  pipe.identify_as_parent
67
76
 
68
77
  # make sure it asks for a file, then give it one
69
78
  assert pipe.gets.is_a?(Hydra::Messages::Runner::RequestFile)
70
- pipe.write(Hydra::Messages::Worker::RunFile.new(:file => test_file))
79
+ pipe.write(Hydra::Messages::Worker::RunFile.new(:file => file))
71
80
 
72
81
  # grab its response. This makes us wait for it to finish
73
82
  response = pipe.gets
@@ -18,6 +18,10 @@ class Test::Unit::TestCase
18
18
  def test_file
19
19
  File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file.rb'))
20
20
  end
21
+
22
+ def cucumber_feature_file
23
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'features', 'write_file.feature'))
24
+ end
21
25
  end
22
26
 
23
27
  module Hydra #:nodoc:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.1
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Gauthier
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-25 00:00:00 -04:00
12
+ date: 2010-03-30 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -45,6 +45,7 @@ files:
45
45
  - hydra.gemspec
46
46
  - hydra_gray.png
47
47
  - lib/hydra.rb
48
+ - lib/hydra/cucumber/formatter.rb
48
49
  - lib/hydra/hash.rb
49
50
  - lib/hydra/listener/abstract.rb
50
51
  - lib/hydra/listener/minimal_output.rb
@@ -67,6 +68,8 @@ files:
67
68
  - lib/hydra/worker.rb
68
69
  - test/fixtures/assert_true.rb
69
70
  - test/fixtures/config.yml
71
+ - test/fixtures/features/step_definitions.rb
72
+ - test/fixtures/features/write_file.feature
70
73
  - test/fixtures/hello_world.rb
71
74
  - test/fixtures/slow.rb
72
75
  - test/fixtures/sync_test.rb
@@ -115,6 +118,7 @@ test_files:
115
118
  - test/fixtures/sync_test.rb
116
119
  - test/fixtures/assert_true.rb
117
120
  - test/fixtures/hello_world.rb
121
+ - test/fixtures/features/step_definitions.rb
118
122
  - test/master_test.rb
119
123
  - test/worker_test.rb
120
124
  - test/runner_test.rb