bumps 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.0.3 2009-09-28
2
+
3
+ * Compatibility with Cucumber 0.3.104 and above
4
+ * Uses new formatter api
5
+
1
6
  == 0.0.2 2009-09-03
2
7
 
3
8
  * Compatibility with Cucumber 0.3.99 and above
data/Manifest.txt CHANGED
@@ -3,6 +3,7 @@ Manifest.txt
3
3
  README.rdoc
4
4
  Rakefile
5
5
  TODO
6
+ environment.rb
6
7
  examples/feature_server
7
8
  features/pull_remote_features.feature
8
9
  features/push_feature_results.feature
@@ -31,5 +32,6 @@ spec/bumps_spec.rb
31
32
  spec/spec.opts
32
33
  spec/spec_helper.rb
33
34
  tasks/rspec.rake
35
+ tasks/setup.rake
34
36
  test_features/remote_content/destroy_dr_thaddeus_venture.feature
35
37
  test_features/requires/support/env.rb
data/README.rdoc CHANGED
@@ -4,6 +4,10 @@
4
4
  * http://groups.google.com/group/bumps-for-cucumber
5
5
  * http://fuglylogic.com/2009/07/20/bumps-remote-features-for-cucumber/
6
6
 
7
+ == Description
8
+
9
+ Remote feature management for Cucumber.
10
+
7
11
  Bumps extends {Cucumber}[http://cukes.info] by allowing you to pull feature content and push run results to and from a remote server. This means that your feature files no longer need to live with your steps and other code. This also means that you can publish the results of a Cucumber run to another system.
8
12
 
9
13
  See the {wiki}[http://wiki.github.com/brentsnook/bumps] for more details.
@@ -12,15 +16,13 @@ See the {wiki}[http://wiki.github.com/brentsnook/bumps] for more details.
12
16
 
13
17
  sudo gem install bumps
14
18
 
15
- === Building the Gem yourself
16
-
17
- Grab the code from github:
19
+ Or grab the code from Github and build yourself:
18
20
 
19
21
  git clone git://github.com/brentsnook/bumps.git
20
22
  cd bumps
21
23
  rake install_gem
22
24
 
23
- == How do I use it?
25
+ == Synopsis
24
26
 
25
27
  First, start up a server that meets the {push/pull contract}[http://wiki.github.com/brentsnook/bumps/push-pull-contract].
26
28
 
@@ -33,7 +35,7 @@ Lastly, just run Cukes as normal.
33
35
 
34
36
  cucumber my_feature_directory
35
37
 
36
- Bumps will pull feature files into the specified feature directory, run cukes and then push the results back to the server.
38
+ Bumps will pull feature files into the specified feature directory, run Cukes and then push the results back to the server.
37
39
 
38
40
  == License
39
41
 
data/Rakefile CHANGED
@@ -1,27 +1,32 @@
1
- %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
- require File.expand_path(File.dirname(__FILE__) + '/lib/bumps_core')
1
+ %w[rubygems rake rake/clean hoe fileutils newgem rubigen].each { |f| require f }
2
+ ['/lib/bumps_core', 'environment'].each do |f|
3
+ require File.expand_path(File.join(File.dirname(__FILE__) , f))
4
+ end
3
5
 
4
- # Generate all the Rake tasks
5
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
- $hoe = Hoe.new('bumps', Bumps::VERSION) do |p|
7
- p.developer 'Brent Snook', 'brent@fuglylogic.com'
8
- p.summary = %q{Remote feature management for Cucumber.}
9
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
- p.rubyforge_name = p.name
11
- p.extra_deps = [
12
- ['cucumber', ">= 0.3.99"],
13
- ['nokogiri','>= 1.1.1'],
6
+ Hoe.spec 'bumps' do
7
+ self.version = Bumps::VERSION
8
+ developer 'Brent Snook', 'brent@fuglylogic.com'
9
+ self.readme_file = 'README.rdoc'
10
+ self.clean_globs |= %w[**/.DS_Store tmp *.log]
11
+ self.rsync_args = '-av --delete --ignore-errors' # is this needed?
12
+
13
+ self.extra_deps = [
14
+ ['cucumber', ">= 0.3.104"],
15
+ ['nokogiri','>= 1.3.3'],
14
16
  ]
15
- p.extra_dev_deps = [
17
+
18
+ self.extra_dev_deps = [
19
+ ['rspec', '>= 1.2.8'],
16
20
  ['newgem', ">= #{::Newgem::VERSION}"],
17
- ['rspec', '>= 1.2.7'],
21
+ ['sinatra', '>=0.9.4'],
18
22
  ]
23
+ end
19
24
 
20
- p.clean_globs |= %w[**/.DS_Store tmp *.log]
21
- path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
22
- p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
23
- p.rsync_args = '-av --delete --ignore-errors'
25
+ require 'cucumber/rake/task'
26
+ Cucumber::Rake::Task.new(:features) do |t|
27
+ t.cucumber_opts = "features --format pretty"
24
28
  end
29
+ task :features => :create_tmp
25
30
 
26
31
  require 'newgem/tasks' # load /tasks/*.rake
27
32
  Dir['tasks/**/*.rake'].each { |t| load t }
data/TODO CHANGED
@@ -1,19 +1,11 @@
1
-
2
- --- 0.3.96 fix
3
-
4
- - test with different ruby versions
5
-
6
- - publish gem
7
- - add to tools page on Cukes wiki
8
- - announce on twitter, Bumps mailing list, Cukes mailing list, Wave list
9
-
10
- - delete fork
11
-
1
+ - release
2
+ - tag
3
+ - release to rubyforge
4
+ - announce on bumps group + twitter
12
5
 
13
6
  --- LATER ---
14
7
 
15
8
  - add validation for config and some nicer messages?
16
- - get rid of treetop gibberish
17
9
  - can it be more of a synch than a straight clobber??? for speed mainly
18
10
  - extract process control logic out into a new gem
19
11
  - support obtaining details for a single feature ???
data/environment.rb ADDED
@@ -0,0 +1 @@
1
+ ENV['BUMPS_TEMP'] = File.expand_path(File.join(File.dirname(__FILE__), 'tmp'))
@@ -1,61 +1,39 @@
1
- require 'webrick'
2
- require 'stringio'
1
+ require 'rubygems'
2
+ require 'sinatra'
3
3
 
4
- include WEBrick
4
+ FEATURE_DIR, RESULTS_FILE = ARGV[0..1]
5
5
 
6
- class PullServlet < HTTPServlet::AbstractServlet
6
+ set :port, 1981
7
7
 
8
- def do_GET(request, response)
9
- response.body = feature_content
10
- response['Content-Type'] = 'text/xml'
11
- end
12
-
13
- private
14
-
15
- def feature_content
16
- content = StringIO.new
17
- content.puts '<?xml version="1.0"?>'
18
- content.puts '<features>'
19
-
20
- Dir.glob(features_pattern).each do |file|
21
- content << feature_within(file) if File.file?(file)
22
- end
8
+ def feature_content
9
+ content = StringIO.new
10
+ content.puts '<?xml version="1.0"?>'
11
+ content.puts '<features>'
23
12
 
24
- content.puts '</features>'
25
-
26
- content.string
27
- end
28
-
29
- def feature_within file
30
- relative_path = file[(@options[0].length)..-1]
31
- "<feature name=\"#{relative_path}\"><![CDATA[#{IO.read(file)}\n]]></feature>"
13
+ Dir.glob(features_pattern).each do |file|
14
+ content << feature_within(file) if File.file?(file)
32
15
  end
33
16
 
34
- def features_pattern
35
- File.join @options[0], '**', '*'
36
- end
17
+ content.puts '</features>'
37
18
 
19
+ content.string
38
20
  end
39
21
 
40
- class PushServlet < HTTPServlet::AbstractServlet
41
-
42
- def do_POST(request, response)
43
- File.open(@options[0], 'w'){ |f| f.write(request.query['results']) }
44
- response['Content-Type'] = 'text/html'
45
- end
46
-
22
+ def feature_within file
23
+ relative_path = file[(FEATURE_DIR.length)..-1]
24
+ "<feature name=\"#{relative_path}\"><![CDATA[#{IO.read(file)}\n]]></feature>"
47
25
  end
48
26
 
49
- server = WEBrick::HTTPServer.new :Port => 1981
50
-
51
- server.mount "/features/content", PullServlet, ARGV[0]
52
- server.mount "/features/results", PushServlet, ARGV[1]
27
+ def features_pattern
28
+ File.join FEATURE_DIR, '**', '*'
29
+ end
53
30
 
54
- %w(INT TERM).each do |signal|
55
- trap signal do
56
- server.shutdown
57
- exit!
58
- end
31
+ get '/features/content' do
32
+ content_type 'text/xml'
33
+ feature_content
59
34
  end
60
35
 
61
- server.start
36
+ post '/features/results' do
37
+ content_type 'text/html'
38
+ File.open(RESULTS_FILE, 'w'){ |f| f.write(params[:results]) }
39
+ end
@@ -46,7 +46,7 @@ class ScenarioProcess
46
46
  private
47
47
 
48
48
  def log
49
- File.expand_path(File.dirname(__FILE__) + "/../../../tmp/#{@name}.log")
49
+ File.expand_path(File.join(ENV['BUMPS_TEMP'], "#{@name}.log"))
50
50
  end
51
51
 
52
52
  def remove file
@@ -1,7 +1,9 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '../../../environment.rb')
2
+
1
3
  module CucumberWorld
2
4
 
3
5
  def feature_report_file
4
- File.expand_path File.join(root, 'tmp', 'cucumber.out')
6
+ File.expand_path File.join(ENV['BUMPS_TEMP'], 'cucumber.out')
5
7
  end
6
8
 
7
9
  def feature_report
@@ -17,7 +19,7 @@ module CucumberWorld
17
19
  end
18
20
 
19
21
  def push_request_file
20
- File.expand_path File.join(root, 'tmp', 'results.xml')
22
+ File.expand_path File.join(ENV['BUMPS_TEMP'], 'results.xml')
21
23
  end
22
24
 
23
25
  def push_request
@@ -29,7 +31,7 @@ module CucumberWorld
29
31
  end
30
32
 
31
33
  def test_features_directory
32
- File.expand_path File.join(root, 'tmp')
34
+ ENV['BUMPS_TEMP']
33
35
  end
34
36
 
35
37
  def feature_server_command
@@ -61,7 +63,7 @@ module CucumberWorld
61
63
  end
62
64
 
63
65
  def command_output_file
64
- File.expand_path File.join(root, 'tmp', 'cucumber.log')
66
+ File.expand_path File.join(ENV['BUMPS_TEMP'], 'cucumber.log')
65
67
  end
66
68
 
67
69
  def remote_features_directory
@@ -1,5 +1,4 @@
1
1
  require 'nokogiri'
2
-
3
2
  require 'open-uri'
4
3
 
5
4
  module Bumps
@@ -2,17 +2,26 @@ require 'cucumber/formatter/html'
2
2
  require 'net/http'
3
3
 
4
4
  module Bumps
5
- class ResultsPushFormatter < Cucumber::Ast::Visitor
5
+ class ResultsPushFormatter
6
+
7
+ attr_reader :formatter, :results
6
8
 
7
9
  def initialize(step_mother, io, options)
8
- super step_mother
9
10
  @step_mother = step_mother
10
11
  @io = io
11
12
  @options = options
12
13
  end
13
-
14
- def visit_features features
15
- push results_of_running(features)
14
+
15
+ def before_features features
16
+ @results = StringIO.open
17
+ @formatter = Bumps::Configuration.results_formatter.new @step_mother, results, @options
18
+ formatter.before_features features
19
+ end
20
+
21
+ def after_features features
22
+ formatter.after_features features
23
+ results.close
24
+ push results.string
16
25
  end
17
26
 
18
27
  def push results
@@ -25,13 +34,13 @@ module Bumps
25
34
  end
26
35
  end
27
36
 
28
- def results_of_running features
29
- StringIO.open do |io|
30
- formatter = Bumps::Configuration.results_formatter.new step_mother, io, options
31
- formatter.visit_features features
32
-
33
- io.string
34
- end
37
+ def method_missing(method, *args, &block)
38
+ formatter.send(method, *args, &block)
39
+ end
40
+
41
+ def respond_to?(message, include_private = false)
42
+ super(message, include_private) || formatter.respond_to?(message, include_private)
35
43
  end
44
+
36
45
  end
37
46
  end
data/lib/bumps_core.rb CHANGED
@@ -14,7 +14,7 @@ require 'cucumber'
14
14
 
15
15
  module Bumps
16
16
 
17
- VERSION = '0.0.2'
17
+ VERSION = '0.0.3'
18
18
 
19
19
  def self.configure &block
20
20
  Configuration.configure(&block)
@@ -18,65 +18,139 @@ describe Bumps::ResultsPushFormatter do
18
18
  )
19
19
  end
20
20
 
21
- it 'should capture results before pushing them' do
22
- results = mock 'results'
23
-
24
- subject.should_receive(:results_of_running).with(@features).and_return results
25
- subject.should_receive(:push).with results
26
-
27
- subject.visit_features @features
28
- end
29
-
30
21
  describe 'when capturing results' do
31
-
22
+
32
23
  before do
33
24
  @formatter_class = mock 'formatter class'
25
+ @formatter = mock('formatter').as_null_object
34
26
  Bumps::Configuration.stub!(:results_formatter).and_return @formatter_class
35
27
  end
36
28
 
37
- it 'should obtain the results formatter from the configuration' do
38
- @formatter_class.stub!(:new).and_return mock('formatter').as_null_object
29
+ describe 'responding to events' do
39
30
 
40
- Bumps::Configuration.should_receive(:results_formatter).and_return @formatter_class
31
+ before do
32
+ @formatter_class.stub!(:new).and_return @formatter
33
+ Bumps::Configuration.stub!(:results_formatter).and_return @formatter_class
34
+ end
35
+
36
+ it 'should recognise events that the wrapped formatter handles' do
37
+ @formatter.stub!(:respond_to?).with('event', anything).and_return true
38
+
39
+ subject.before_features @features
40
+ subject.respond_to?('event').should == true
41
+ end
41
42
 
42
- subject.results_of_running @features
43
+ it 'should recognise events that it handles on its own' do
44
+ @formatter.stub!(:respond_to?).with('after_features', anything).and_return false
45
+
46
+ subject.before_features @features
47
+ subject.respond_to?('after_features').should == true
48
+ end
43
49
  end
44
-
45
- it 'should construct the wrapped formatter using the step mother' do
46
- @formatter_class.should_receive(:new).with(
47
- @step_mother, anything, anything
48
- ).and_return mock('formatter').as_null_object
49
-
50
- subject.results_of_running @features
50
+
51
+ describe 'before the running of features' do
52
+
53
+ it 'should construct the wrapped formatter using the step mother' do
54
+ @formatter_class.should_receive(:new).with(
55
+ @step_mother, anything, anything
56
+ ).and_return @formatter
57
+
58
+ subject.before_features @features
59
+ end
60
+
61
+ it 'should construct the wrapped formatter using the options' do
62
+ @formatter_class.should_receive(:new).with(
63
+ anything, anything, @options
64
+ ).and_return @formatter
65
+
66
+ subject.before_features @features
67
+ end
68
+
69
+ it 'should obtain the results formatter from the configuration' do
70
+ @formatter_class.stub!(:new).and_return @formatter
71
+
72
+ Bumps::Configuration.should_receive(:results_formatter).and_return @formatter_class
73
+
74
+ subject.before_features @features
75
+ end
76
+
77
+ it 'should notify the wrapped formatter of the before_features event' do
78
+ Bumps::Configuration.stub!(:results_formatter).and_return @formatter_class
79
+ @formatter_class.stub!(:new).and_return @formatter
80
+
81
+ @formatter.should_receive(:before_features).with @features
82
+
83
+ subject.before_features @features
84
+ end
85
+
51
86
  end
52
87
 
53
- it 'should construct the wrapped formatter using the options' do
54
- @formatter_class.should_receive(:new).with(
55
- anything, anything, @options
56
- ).and_return mock('formatter').as_null_object
57
-
58
- subject.results_of_running @features
88
+ describe 'during the running of features' do
89
+
90
+ it 'should notify the wrapped formatter of all events' do
91
+ @formatter_class.stub!(:new).and_return @formatter
92
+ Bumps::Configuration.stub!(:results_formatter).and_return @formatter_class
93
+ events = [
94
+ :before_feature, :after_feature, :before_comment, :after_comment,
95
+ :comment_line, :after_tags, :before_background, :after_background,
96
+ # there are more, add as needed
97
+ ]
98
+
99
+ events.each { |event| @formatter.should_receive(event).with('arguments')}
100
+
101
+ subject.before_features @features
102
+ events.each { |event| subject.send(event, 'arguments')}
103
+ end
104
+
59
105
  end
60
106
 
61
- it 'should return results of visiting features with wrapped formatter' do
62
-
63
- class FormatterTestDouble
64
- def initialize io
65
- @io = io
66
- end
67
-
68
- def visit_features features
69
- @io << 'results'
70
- end
107
+ describe 'after the running of features' do
108
+ before do
109
+ @results = mock('results').as_null_object
110
+ subject.stub!(:results).and_return @results
111
+ subject.stub!(:formatter).and_return @formatter
112
+ subject.stub!(:push)
71
113
  end
114
+
115
+ it 'should notify the wrapped formatter after all features have been run' do
116
+ @formatter.should_receive(:after_features).with @features
72
117
 
73
- @formatter_class.stub!(:new) do |step_mother, io, options|
74
- FormatterTestDouble.new(io)
118
+ subject.after_features @features
75
119
  end
120
+
121
+ it 'should ready the captured results for pushing' do
122
+ @results.should_receive :close
76
123
 
77
- subject.results_of_running(@features).should =='results'
124
+ subject.after_features @features
125
+ end
78
126
  end
127
+
128
+ describe 'over the entire run' do
129
+ it 'should capture then push results' do
130
+ class FormatterTestDouble
131
+ def initialize(step_mother, io, options)
132
+ @io = io
133
+ end
134
+
135
+ def before_features features
136
+ end
137
+
138
+ def after_features features
139
+ end
79
140
 
141
+ def after_feature feature
142
+ @io << "After feature: #{feature}"
143
+ end
144
+ end
145
+ Bumps::Configuration.stub(:results_formatter).and_return FormatterTestDouble
146
+
147
+ subject.should_receive(:push).with 'After feature: walk the dog'
148
+
149
+ subject.before_features @features
150
+ subject.after_feature 'walk the dog'
151
+ subject.after_features @features
152
+ end
153
+ end
80
154
  end
81
155
 
82
156
  describe 'when pushing results' do
data/tasks/setup.rake ADDED
@@ -0,0 +1,4 @@
1
+ desc "Create temp directory"
2
+ task :create_tmp do
3
+ mkdir_p ENV['BUMPS_TEMP'], :verbose => false
4
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bumps
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brent Snook
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-03 00:00:00 +01:00
12
+ date: 2009-09-28 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.3.99
23
+ version: 0.3.104
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: nokogiri
@@ -30,7 +30,17 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.1.1
33
+ version: 1.3.3
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.2.8
34
44
  version:
35
45
  - !ruby/object:Gem::Dependency
36
46
  name: newgem
@@ -40,17 +50,17 @@ dependencies:
40
50
  requirements:
41
51
  - - ">="
42
52
  - !ruby/object:Gem::Version
43
- version: 1.2.3
53
+ version: 1.5.2
44
54
  version:
45
55
  - !ruby/object:Gem::Dependency
46
- name: rspec
56
+ name: sinatra
47
57
  type: :development
48
58
  version_requirement:
49
59
  version_requirements: !ruby/object:Gem::Requirement
50
60
  requirements:
51
61
  - - ">="
52
62
  - !ruby/object:Gem::Version
53
- version: 1.2.7
63
+ version: 0.9.4
54
64
  version:
55
65
  - !ruby/object:Gem::Dependency
56
66
  name: hoe
@@ -60,9 +70,14 @@ dependencies:
60
70
  requirements:
61
71
  - - ">="
62
72
  - !ruby/object:Gem::Version
63
- version: 1.8.0
73
+ version: 2.3.3
64
74
  version:
65
- description: ""
75
+ description: |-
76
+ Remote feature management for Cucumber.
77
+
78
+ Bumps extends {Cucumber}[http://cukes.info] by allowing you to pull feature content and push run results to and from a remote server. This means that your feature files no longer need to live with your steps and other code. This also means that you can publish the results of a Cucumber run to another system.
79
+
80
+ See the {wiki}[http://wiki.github.com/brentsnook/bumps] for more details.
66
81
  email:
67
82
  - brent@fuglylogic.com
68
83
  executables: []
@@ -72,13 +87,13 @@ extensions: []
72
87
  extra_rdoc_files:
73
88
  - History.txt
74
89
  - Manifest.txt
75
- - README.rdoc
76
90
  files:
77
91
  - History.txt
78
92
  - Manifest.txt
79
93
  - README.rdoc
80
94
  - Rakefile
81
95
  - TODO
96
+ - environment.rb
82
97
  - examples/feature_server
83
98
  - features/pull_remote_features.feature
84
99
  - features/push_feature_results.feature
@@ -107,6 +122,7 @@ files:
107
122
  - spec/spec.opts
108
123
  - spec/spec_helper.rb
109
124
  - tasks/rspec.rake
125
+ - tasks/setup.rake
110
126
  - test_features/remote_content/destroy_dr_thaddeus_venture.feature
111
127
  - test_features/requires/support/env.rb
112
128
  has_rdoc: true
@@ -137,6 +153,6 @@ rubyforge_project: bumps
137
153
  rubygems_version: 1.3.5
138
154
  signing_key:
139
155
  specification_version: 3
140
- summary: Remote feature management for Cucumber.
156
+ summary: Remote feature management for Cucumber
141
157
  test_files: []
142
158