bumps 0.0.4 → 0.1.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.
@@ -1,3 +1,9 @@
1
+ == 0.1.0 2010-06-30
2
+
3
+ * Change feature pull format to JSON
4
+ * Insert ID and version tags into each feature so that information can be pushed back to server
5
+ * Add JSONFormatter as default formatter - reads ID and version tags and formats push message as JSON
6
+
1
7
  == 0.0.4 2009-10-13
2
8
 
3
9
  * Handle missing connection to push server more gracefully
@@ -17,6 +17,7 @@ lib/bumps.rb
17
17
  lib/bumps/configuration.rb
18
18
  lib/bumps/cucumber_config.rb
19
19
  lib/bumps/feature.rb
20
+ lib/bumps/json_formatter.rb
20
21
  lib/bumps/remote_feature.rb
21
22
  lib/bumps/results_push_formatter.rb
22
23
  lib/bumps_core.rb
@@ -26,6 +27,7 @@ script/generate
26
27
  spec/bumps/configuration_spec.rb
27
28
  spec/bumps/cucumber_config_spec.rb
28
29
  spec/bumps/feature_spec.rb
30
+ spec/bumps/json_formatter_spec.rb
29
31
  spec/bumps/remote_feature_spec.rb
30
32
  spec/bumps/results_push_formatter_spec.rb
31
33
  spec/bumps_spec.rb
@@ -33,5 +35,11 @@ spec/spec.opts
33
35
  spec/spec_helper.rb
34
36
  tasks/rspec.rake
35
37
  tasks/setup.rake
38
+ test_features/json_formatter_spec/describing_a_feature.feature
39
+ test_features/json_formatter_spec/describing_a_scenario.feature
40
+ test_features/json_formatter_spec/describing_a_step.feature
41
+ test_features/json_formatter_spec/propagating_status_from_step_to_scenario.feature
42
+ test_features/json_formatter_spec/steps/steps.rb
43
+ test_features/json_formatter_spec/support/env.rb
36
44
  test_features/remote_content/destroy_dr_thaddeus_venture.feature
37
45
  test_features/requires/support/env.rb
@@ -1,6 +1,7 @@
1
1
  = Bumps
2
2
 
3
3
  * http://github.com/brentsnook/bumps
4
+ * http://github.com/brentsnook/bumpybot
4
5
  * http://groups.google.com/group/bumps-for-cucumber
5
6
  * http://fuglylogic.com/2009/07/20/bumps-remote-features-for-cucumber/
6
7
 
@@ -10,6 +11,8 @@ Remote feature management for Cucumber.
10
11
 
11
12
  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.
12
13
 
14
+ Bumps has been designed to work with {Bumpybot}[http://github.com/brentsnook/bumpybot] (a Google Wave robot) but it can be used with any server that meets the {push/pull contract}[http://wiki.github.com/brentsnook/bumps/push-pull-contract].
15
+
13
16
  See the {wiki}[http://wiki.github.com/brentsnook/bumps] for more details.
14
17
 
15
18
  == Installation
@@ -24,6 +27,10 @@ Or grab the code from Github and build yourself:
24
27
 
25
28
  == Synopsis
26
29
 
30
+ To use with Bumpybot, {see the directions}[http://github.com/brentsnook/bumpybot].
31
+
32
+ You can also use Bumps with any other compliant server.
33
+
27
34
  First, start up a server that meets the {push/pull contract}[http://wiki.github.com/brentsnook/bumps/push-pull-contract].
28
35
 
29
36
  Secondly, bung this inside of your <b>support/env.rb</b> (or equivalent, just make sure it is under a directory named <b>support</b> under the feature directory):
@@ -33,15 +40,15 @@ Secondly, bung this inside of your <b>support/env.rb</b> (or equivalent, just ma
33
40
 
34
41
  Lastly, just run Cukes as normal.
35
42
 
36
- cucumber my_feature_directory
43
+ cucumber
37
44
 
38
- Bumps will pull feature files into the specified feature directory, run Cukes and then push the results back to the server.
45
+ Bumps will pull feature files into the feature directory, run Cukes and then push the results back to the server.
39
46
 
40
47
  == License
41
48
 
42
49
  (The MIT License)
43
50
 
44
- Copyright (c) 2009 Brent Snook http://fuglylogic.com
51
+ Copyright (c) 2009, 2010 Brent Snook http://fuglylogic.com
45
52
 
46
53
  Permission is hereby granted, free of charge, to any person obtaining
47
54
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -11,8 +11,8 @@ Hoe.spec 'bumps' do
11
11
  self.rsync_args = '-av --delete --ignore-errors' # is this needed?
12
12
 
13
13
  self.extra_deps = [
14
- ['cucumber', ">= 0.3.104"],
15
- ['nokogiri','>= 1.3.3'],
14
+ ['cucumber', '>= 0.3.104'],
15
+ ['json', '>=1.4.3']
16
16
  ]
17
17
 
18
18
  self.extra_dev_deps = [
@@ -31,6 +31,4 @@ task :features => :create_tmp
31
31
  require 'newgem/tasks' # load /tasks/*.rake
32
32
  Dir['tasks/**/*.rake'].each { |t| load t }
33
33
 
34
- # IS THIS NEEDED?
35
- Rake::Task[:default].clear_prerequisites # clear out test-unit
36
34
  task :default => [:spec, :features]
data/TODO CHANGED
@@ -1,4 +1,7 @@
1
1
 
2
+ - release bumps [][]
3
+ - tag, release, announce (twitter, Bumps list, LRUG list)
4
+
2
5
  --- LATER ---
3
6
 
4
7
  - add validation for config and some nicer messages?
@@ -1,27 +1,29 @@
1
1
  require 'rubygems'
2
2
  require 'sinatra'
3
+ require 'json'
3
4
 
4
5
  FEATURE_DIR, RESULTS_FILE = ARGV[0..1]
5
6
 
6
7
  set :port, 1981
7
8
 
8
9
  def feature_content
9
- content = StringIO.new
10
- content.puts '<?xml version="1.0"?>'
11
- content.puts '<features>'
10
+ features = {}
12
11
 
13
- Dir.glob(features_pattern).each do |file|
14
- content << feature_within(file) if File.file?(file)
12
+ Dir.glob(features_pattern).each_with_index do |file, index|
13
+ features[index] = feature_within(file) if File.file?(file)
15
14
  end
16
15
 
17
- content.puts '</features>'
18
-
19
- content.string
16
+ JSON.generate({'features' => features})
20
17
  end
21
18
 
22
19
  def feature_within file
23
20
  relative_path = file[(FEATURE_DIR.length)..-1]
24
- "<feature name=\"#{relative_path}\"><![CDATA[#{IO.read(file)}\n]]></feature>"
21
+ content = IO.read(file)
22
+ {
23
+ 'name' => content.match(/Feature: (.*)$/)[1],
24
+ 'version' => '1',
25
+ 'content' => content
26
+ }
25
27
  end
26
28
 
27
29
  def features_pattern
@@ -29,7 +31,7 @@ def features_pattern
29
31
  end
30
32
 
31
33
  get '/features/content' do
32
- content_type 'text/xml'
34
+ content_type 'application/json'
33
35
  feature_content
34
36
  end
35
37
 
@@ -7,7 +7,7 @@ Feature: Serve feature results
7
7
  Scenario: Push all feature results after a run
8
8
  Given that a feature server is running
9
9
  When a cucumber run is performed
10
- Then the results of the feature run will be sent to the feature server
10
+ Then JSON formatted feature results will be sent to the server
11
11
 
12
12
  Scenario: Feature server not reachable
13
13
  Given that a feature server is not running
@@ -1,3 +1,5 @@
1
+ require 'json'
2
+
1
3
  Given /^that a feature server is running$/ do
2
4
  ScenarioProcess.run feature_server_command, 'feature_server'
3
5
  end
@@ -6,9 +8,7 @@ Given /^that a feature server is not running$/ do
6
8
  ScenarioProcess.kill feature_server_command
7
9
  end
8
10
 
9
- Then /^the results of the feature run will be sent to the feature server$/ do
10
- each_feature do |feature|
11
- push_request.should match(/#{feature}/)
12
- end
11
+ Then /^JSON formatted feature results will be sent to the server$/ do
12
+ JSON.parse(push_request)['features'].size.should == all_features.size
13
13
  end
14
14
 
@@ -19,7 +19,7 @@ module CucumberWorld
19
19
  end
20
20
 
21
21
  def push_request_file
22
- File.expand_path File.join(ENV['BUMPS_TEMP'], 'results.xml')
22
+ File.expand_path File.join(ENV['BUMPS_TEMP'], 'pushed_results.txt')
23
23
  end
24
24
 
25
25
  def push_request
@@ -38,13 +38,21 @@ module CucumberWorld
38
38
  "ruby #{feature_server_script} #{remote_features_directory} #{push_request_file}"
39
39
  end
40
40
 
41
+ def all_features
42
+ Dir.glob("#{remote_features_directory}/**/*")
43
+ end
44
+
41
45
  def each_feature
42
- Dir.glob("#{remote_features_directory}/**/*") do |feature_file|
46
+ all_features.each do |feature_file|
43
47
  content = IO.read(feature_file).strip
44
48
  yield content.split("\n").first.strip
45
49
  end
46
50
  end
47
51
 
52
+ def feature_count
53
+ Dir.glob("#{remote_features_directory}/**/*").size
54
+ end
55
+
48
56
  def clean
49
57
  FileUtils.remove_entry_secure test_features_directory
50
58
  FileUtils.mkdir test_features_directory
@@ -15,7 +15,7 @@ module Bumps
15
15
  def initialize
16
16
  @config = {
17
17
  :output_stream => STDOUT,
18
- :results_formatter => Cucumber::Formatter::Html
18
+ :results_formatter => Bumps::JSONFormatter
19
19
  }
20
20
  end
21
21
 
@@ -3,9 +3,9 @@ module Bumps
3
3
 
4
4
  attr_accessor :name, :content
5
5
 
6
- def initialize
7
- @name = ''
8
- @content = ''
6
+ def initialize name, content
7
+ @name = name
8
+ @content = content
9
9
  end
10
10
 
11
11
  def self.pull
@@ -34,7 +34,7 @@ module Bumps
34
34
 
35
35
  def absolute_path_under directory
36
36
  expanded_directory = File.expand_path directory
37
- file_path = File.expand_path(File.join(directory, name))
37
+ file_path = File.expand_path(File.join(directory, file_name))
38
38
  unless file_path =~ /^#{expanded_directory}/
39
39
  raise "Could not write feature to path #{file_path}, path is not below #{expanded_directory}"
40
40
  end
@@ -50,5 +50,11 @@ module Bumps
50
50
 
51
51
  true
52
52
  end
53
+
54
+ private
55
+
56
+ def file_name
57
+ "#{name.downcase.strip.gsub(' ', '_')}.feature"
58
+ end
53
59
  end
54
60
  end
@@ -0,0 +1,71 @@
1
+ require 'json'
2
+ require 'time'
3
+
4
+ module Bumps
5
+
6
+ class JSONFormatter
7
+
8
+ def self.now
9
+ Time.now
10
+ end
11
+
12
+ def initialize step_mother, io, options
13
+ @io = io
14
+ @features = {}
15
+ end
16
+
17
+ # required to keep cukes happy
18
+ def before_features(*args);end
19
+
20
+ def tag_name tag
21
+ name, value = tag.split(":", 2)
22
+ instance_variable_set(name, value)
23
+ end
24
+
25
+ def before_feature(feature)
26
+ @feature = {
27
+ 'started' => JSONFormatter.now.iso8601,
28
+ 'scenarios' => []
29
+ }
30
+ end
31
+
32
+ def scenario_name(keyword, name, file_colon_line, source_indent)
33
+ @scenario = {
34
+ 'line' => line(file_colon_line),
35
+ 'steps' => []
36
+ }
37
+ @feature['scenarios'] << @scenario
38
+ end
39
+
40
+ def after_step(step)
41
+ @step = {
42
+ 'status' => step.status,
43
+ 'line' => line(step.file_colon_line)
44
+ }
45
+ @scenario['steps'] << @step
46
+ @scenario['status'] = step.status unless step.status == :skipped
47
+ end
48
+
49
+
50
+ def after_feature(feature)
51
+ @feature.merge!({'finished' => JSONFormatter.now.iso8601, 'version' => @version})
52
+ @features[@id] = @feature
53
+ end
54
+
55
+ def after_features(*args)
56
+ document = {
57
+ 'features' => @features
58
+ }
59
+
60
+ @io.print(document.to_json)
61
+ @io.flush
62
+ end
63
+
64
+ private
65
+
66
+ def line(file_colon_line)
67
+ # ignore first line containing id and version tags
68
+ file_colon_line.split(':')[1].to_i - 1
69
+ end
70
+ end
71
+ end
@@ -1,5 +1,5 @@
1
- require 'nokogiri'
2
1
  require 'open-uri'
2
+ require 'json'
3
3
 
4
4
  module Bumps
5
5
 
@@ -9,15 +9,12 @@ module Bumps
9
9
  parse(open(location){|f| f.read})
10
10
  end
11
11
 
12
- def self.parse xml
13
- document = Nokogiri::XML xml
14
- document.search('feature').collect do |feature_element|
15
- feature = Feature.new
16
- feature.content = feature_element.text.strip
17
- feature.name = feature_element.attribute('name').to_s
18
- feature
19
- end
12
+ def self.parse json
13
+ JSON.parse(json)['features'].collect do |id, feature|
14
+ content = "@id:#{id} @version:#{feature['version']}\n#{feature['content']}"
15
+ Feature.new(feature['name'], content)
16
+ end
20
17
  end
21
18
 
22
19
  end
23
- end
20
+ end
@@ -8,13 +8,14 @@ require 'cucumber'
8
8
  'remote_feature',
9
9
  'feature',
10
10
  'configuration',
11
+ 'json_formatter',
11
12
  'results_push_formatter',
12
13
  'cucumber_config'
13
14
  ].each {|file| require "bumps/#{file}"}
14
15
 
15
16
  module Bumps
16
17
 
17
- VERSION = '0.0.4'
18
+ VERSION = '0.1.0'
18
19
 
19
20
  def self.configure &block
20
21
  Configuration.configure(&block)
@@ -62,8 +62,8 @@ describe Bumps::Configuration do
62
62
  subject.results_formatter.should == formatter_class
63
63
  end
64
64
 
65
- it 'defaults the results formatter to Cucumber HTML formatter' do
66
- subject.results_formatter.should == Cucumber::Formatter::Html
65
+ it 'defaults the results formatter to the Bumps JSON formatter' do
66
+ subject.results_formatter.should == Bumps::JSONFormatter
67
67
  end
68
68
 
69
69
  it 'can have only one instance' do
@@ -61,6 +61,8 @@ describe Bumps::Feature do
61
61
 
62
62
  describe 'writing to file' do
63
63
 
64
+ subject {Bumps::Feature.new('', '')}
65
+
64
66
  it 'uses absolute path' do
65
67
  subject.stub(:absolute_path_under).with('directory').and_return 'path'
66
68
 
@@ -72,14 +74,20 @@ describe Bumps::Feature do
72
74
  it 'uses expanded directory and feature name' do
73
75
  subject.stub!(:name).and_return 'name'
74
76
 
75
- subject.absolute_path_under('/a/b/c/..').should == '/a/b/name'
77
+ subject.absolute_path_under('/a/b/c/..').should match(%r{^/a/b/name})
78
+ end
79
+
80
+ it 'creates a file name using feature name' do
81
+ subject.stub!(:name).and_return ' Do some stuff '
82
+
83
+ subject.absolute_path_under('/').should == '/do_some_stuff.feature'
76
84
  end
77
85
 
78
86
  it 'fails if given path does not resolve to one below the feature directory' do
79
87
  subject.stub!(:name).and_return '../../etc/bashrc'
80
88
  File.stub! :open # just in case
81
89
 
82
- lambda {subject.absolute_path_under '/stuff/features'}.should raise_error('Could not write feature to path /etc/bashrc, path is not below /stuff/features')
90
+ lambda {subject.absolute_path_under '/stuff/features'}.should raise_error('Could not write feature to path /etc/bashrc.feature, path is not below /stuff/features')
83
91
  end
84
92
 
85
93
  it 'overwrites existing files' do
@@ -0,0 +1,116 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+ require 'json'
3
+ require 'time'
4
+ require 'cucumber/cli/main'
5
+
6
+ describe Bumps::JSONFormatter do
7
+
8
+ FEATURES_DIR = File.expand_path File.join(File.dirname(__FILE__), '..', '..', 'test_features', 'json_formatter_spec')
9
+
10
+ before(:all) { run_cucumber }
11
+
12
+ it 'includes all features mapped by id' do
13
+ [
14
+ 'describing_a_feature',
15
+ 'describing_a_scenario',
16
+ 'describing_a_step',
17
+ 'propagating_status_from_step_to_scenario'
18
+ ].each do |id|
19
+ @all_features.keys.should include(id)
20
+ end
21
+ end
22
+
23
+ describe 'propagating status from step to scenario' do
24
+ before(:all) do
25
+ @scenarios = @all_features['propagating_status_from_step_to_scenario']['scenarios']
26
+ end
27
+
28
+ it 'propagates passed, failed, pending and undefined statuses' do
29
+ ['passed', 'failed', 'pending', 'undefined'].each_with_index do |status, index|
30
+ @scenarios[index]['status'].should == status
31
+ end
32
+ end
33
+
34
+ it "doesn't propagate a skipped status" do
35
+ @scenarios.last['status'].should == 'failed'
36
+ end
37
+ end
38
+
39
+ describe 'describing a feature' do
40
+
41
+ before(:all) do
42
+ @feature = @all_features['describing_a_feature']
43
+ end
44
+
45
+ it 'includes version' do
46
+ @feature['version'].should == '456'
47
+ end
48
+
49
+ describe 'timing' do
50
+
51
+ before(:all) do
52
+ start = Time.now
53
+ finish = start + 10
54
+ Bumps::JSONFormatter.stub!(:now).and_return start, finish
55
+
56
+ run_cucumber
57
+
58
+ @feature = @all_features['describing_a_feature']
59
+ end
60
+
61
+ it 'includes the time it started and stopped running in ISO8601 format' do
62
+ iso8601_format = /[\d]{4}-[\d]{2}-[\d]{2}T[\d]{2}:[\d]{2}:[\d]{2}[+-][\d]{2}:[\d]{2}/
63
+ @feature['started'].should match(iso8601_format)
64
+ @feature['finished'].should match(iso8601_format)
65
+ end
66
+
67
+ it 'should include a finish time equal or greater than the start time' do
68
+ # may be equal due to second only precision
69
+ Time.parse(@feature['started']).should be <= Time.parse(@feature['finished'])
70
+ end
71
+ end
72
+
73
+ it 'includes all scenarios' do
74
+ @feature['scenarios'].size.should == 3
75
+ end
76
+ end
77
+
78
+ describe 'describing a scenario' do
79
+
80
+ before(:all) do
81
+ @scenario = @all_features['describing_a_scenario']['scenarios'].first
82
+ end
83
+
84
+ it 'includes the line that it starts on (ignoring the first tag)' do
85
+ @scenario['line'] = 3
86
+ end
87
+
88
+ it 'includes all steps' do
89
+ @scenario['steps'].size == 3
90
+ end
91
+
92
+ end
93
+
94
+ describe 'describing a step' do
95
+
96
+ before(:all) do
97
+ @step = @all_features['describing_a_step']['scenarios'].first['steps'].first
98
+ end
99
+
100
+ it 'includes the feature file line (ignoring the first tag) but not the step file line' do
101
+ @step['line'].should == 4
102
+ end
103
+
104
+ it 'includes the status' do
105
+ @step['status'].should == 'passed'
106
+ end
107
+
108
+ end
109
+
110
+ def run_cucumber
111
+ args = ['-f', 'Bumps::JSONFormatter', FEATURES_DIR]
112
+ output = `cucumber #{args.join(' ')}`
113
+ @all_features = JSON.parse(output)['features']
114
+ end
115
+
116
+ end
@@ -1,10 +1,11 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+ require 'json'
2
3
 
3
4
  describe Bumps::RemoteFeature do
4
5
 
5
6
  subject {Bumps::RemoteFeature}
6
7
 
7
- describe 'fetching' do
8
+ describe 'fetch' do
8
9
  it 'uses the given location' do
9
10
  subject.should_receive(:open).with('location')
10
11
  subject.stub! :parse
@@ -21,63 +22,67 @@ describe Bumps::RemoteFeature do
21
22
  end
22
23
  end
23
24
 
24
- describe 'parsing' do
25
- it 'extracts all features from XML' do
26
- features = (0..1).collect do |idx|
27
- feature = Bumps::Feature.new
28
- feature.name = "feature #{idx}"
29
- feature.content = "I am the content for feature #{idx}"
30
- feature
31
- end
32
-
33
- xml = <<-XML
34
- <?xml version="1.0"?>
35
- <features>
36
- <feature name="feature 0">I am the content for feature 0</feature>
37
- <feature name="feature 1">I am the content for feature 1</feature>
38
- </features>
39
- XML
25
+ describe 'parse' do
26
+
27
+ it 'reads the name of a feature' do
28
+ document = { "features" => {
29
+ "" => {
30
+ "content" => "Feature: do stuff",
31
+ "version" => "",
32
+ "name" => "Feature name"
33
+ }
34
+ }}
40
35
 
41
- subject.parse(xml).should eql(features)
42
- end
36
+ subject.parse(json_from(document)).first.name.should == 'Feature name'
37
+ end
43
38
 
44
- it 'trims leading and trailing whitespace from content' do
45
- xml = <<-XML
46
- <?xml version="1.0"?>
47
- <features>
48
- <feature name="feature 0">
49
-
50
-
51
- I am the content for feature 0
52
-
53
- </feature>
54
- </features>
55
- XML
39
+ it 'reads the content of a feature' do
40
+ document = { "features" => {
41
+ "" => {
42
+ "content" => "Feature: do stuff",
43
+ "version" => "",
44
+ "name" => "feature 0"
45
+ }
46
+ }}
56
47
 
57
- subject.parse(xml).first.content.should == 'I am the content for feature 0'
58
- end
48
+ subject.parse(json_from(document)).first.content.should match(/Feature: do stuff/)
49
+ end
50
+
51
+ it 'reads all features' do
52
+ document = { "features" => {
53
+ "0" => {
54
+ "content" => "Feature: 0\nI am the content for feature 0",
55
+ "version" => "3",
56
+ "name" => "feature 0"
57
+ },
58
+ "1" => {
59
+ "content" => "Feature: 1\nI am the content for feature 1",
60
+ "version" => "3",
61
+ "name" => "feature 1"
62
+ }
63
+ }}
64
+
65
+ subject.parse(json_from(document)).size.should == 2
66
+ end
59
67
 
60
- it 'returns an empty list when no features were found' do
61
- xml = <<-XML
62
- <?xml version="1.0"?>
63
- <features>
64
- </features>
65
- XML
66
- subject.parse(xml).should eql([])
68
+ it 'returns an empty list when no features are found' do
69
+ subject.parse(json_from({ "features" => {}})).size.should == 0
67
70
  end
71
+
72
+ it 'embeds metadata about a feature within its content' do
73
+ document = { "features" => {
74
+ "123" => {
75
+ "content" => "Feature: do stuff",
76
+ "version" => "3",
77
+ "name" => "feature 0"
78
+ }
79
+ }}
68
80
 
69
- it 'preserves CDATA in feature content' do
70
- xml = <<-XML
71
- <?xml version="1.0"?>
72
- <features>
73
- <feature name="feature 0">
74
- <![CDATA[content contains <b>CDATA</b> & it should be preserved]]>
75
- </feature>
76
- </features>
77
- XML
78
-
79
- subject.parse(xml).first.content.should match(%r{content contains <b>CDATA</b> & it should be preserved})
81
+ subject.parse(json_from(document)).first.content.should == "@id:123 @version:3\nFeature: do stuff"
82
+ end
83
+
84
+ def json_from document
85
+ JSON.generate document
80
86
  end
81
-
82
87
  end
83
88
  end
@@ -0,0 +1,8 @@
1
+ @id:describing_a_feature @version:456
2
+ Feature: Feature
3
+
4
+ Scenario: First scenario
5
+
6
+ Scenario: Second scenario
7
+
8
+ Scenario: Third scenario
@@ -0,0 +1,4 @@
1
+ @id:describing_a_scenario
2
+ Feature: Feature
3
+
4
+ Scenario: Success
@@ -0,0 +1,5 @@
1
+ @id:describing_a_step
2
+ Feature: Feature
3
+
4
+ Scenario: Scenario
5
+ Given I passed
@@ -0,0 +1,20 @@
1
+ @id:propagating_status_from_step_to_scenario
2
+ Feature: Feature
3
+
4
+ Scenario: passed
5
+ Given I passed
6
+
7
+ Scenario: failed
8
+ Given I failed
9
+ And I passed
10
+
11
+ Scenario: pending
12
+ Given I am pending
13
+
14
+ Scenario: undefined
15
+ Given I am undefined
16
+
17
+ Scenario: skipped
18
+ Given I failed
19
+ And I passed
20
+
@@ -0,0 +1,10 @@
1
+ Given /I passed/ do
2
+ end
3
+
4
+ Given /I am pending/ do
5
+ pending
6
+ end
7
+
8
+ Given /I failed/ do
9
+ raise 'Kablooey!'
10
+ end
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', '..', 'lib', 'bumps', 'json_formatter')
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bumps
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Brent Snook
@@ -9,74 +15,112 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-10-13 00:00:00 +01:00
18
+ date: 2010-06-30 00:00:00 +10:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: cucumber
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 195
30
+ segments:
31
+ - 0
32
+ - 3
33
+ - 104
23
34
  version: 0.3.104
24
- version:
25
- - !ruby/object:Gem::Dependency
26
- name: nokogiri
27
35
  type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: json
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
33
- version: 1.3.3
34
- version:
45
+ hash: 1
46
+ segments:
47
+ - 1
48
+ - 4
49
+ - 3
50
+ version: 1.4.3
51
+ type: :runtime
52
+ version_requirements: *id002
35
53
  - !ruby/object:Gem::Dependency
36
54
  name: rspec
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
40
58
  requirements:
41
59
  - - ">="
42
60
  - !ruby/object:Gem::Version
61
+ hash: 15
62
+ segments:
63
+ - 1
64
+ - 2
65
+ - 8
43
66
  version: 1.2.8
44
- version:
67
+ type: :development
68
+ version_requirements: *id003
45
69
  - !ruby/object:Gem::Dependency
46
70
  name: newgem
47
- type: :development
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
50
74
  requirements:
51
75
  - - ">="
52
76
  - !ruby/object:Gem::Version
77
+ hash: 7
78
+ segments:
79
+ - 1
80
+ - 5
81
+ - 2
53
82
  version: 1.5.2
54
- version:
83
+ type: :development
84
+ version_requirements: *id004
55
85
  - !ruby/object:Gem::Dependency
56
86
  name: sinatra
57
- type: :development
58
- version_requirement:
59
- version_requirements: !ruby/object:Gem::Requirement
87
+ prerelease: false
88
+ requirement: &id005 !ruby/object:Gem::Requirement
89
+ none: false
60
90
  requirements:
61
91
  - - ">="
62
92
  - !ruby/object:Gem::Version
93
+ hash: 51
94
+ segments:
95
+ - 0
96
+ - 9
97
+ - 4
63
98
  version: 0.9.4
64
- version:
99
+ type: :development
100
+ version_requirements: *id005
65
101
  - !ruby/object:Gem::Dependency
66
102
  name: hoe
67
- type: :development
68
- version_requirement:
69
- version_requirements: !ruby/object:Gem::Requirement
103
+ prerelease: false
104
+ requirement: &id006 !ruby/object:Gem::Requirement
105
+ none: false
70
106
  requirements:
71
107
  - - ">="
72
108
  - !ruby/object:Gem::Version
109
+ hash: 5
110
+ segments:
111
+ - 2
112
+ - 3
113
+ - 3
73
114
  version: 2.3.3
74
- version:
115
+ type: :development
116
+ version_requirements: *id006
75
117
  description: |-
76
118
  Remote feature management for Cucumber.
77
119
 
78
120
  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
121
 
122
+ Bumps has been designed to work with {Bumpybot}[http://github.com/brentsnook/bumpybot] (a Google Wave robot) but it can be used with any server that meets the {push/pull contract}[http://wiki.github.com/brentsnook/bumps/push-pull-contract].
123
+
80
124
  See the {wiki}[http://wiki.github.com/brentsnook/bumps] for more details.
81
125
  email:
82
126
  - brent@fuglylogic.com
@@ -107,6 +151,7 @@ files:
107
151
  - lib/bumps/configuration.rb
108
152
  - lib/bumps/cucumber_config.rb
109
153
  - lib/bumps/feature.rb
154
+ - lib/bumps/json_formatter.rb
110
155
  - lib/bumps/remote_feature.rb
111
156
  - lib/bumps/results_push_formatter.rb
112
157
  - lib/bumps_core.rb
@@ -116,6 +161,7 @@ files:
116
161
  - spec/bumps/configuration_spec.rb
117
162
  - spec/bumps/cucumber_config_spec.rb
118
163
  - spec/bumps/feature_spec.rb
164
+ - spec/bumps/json_formatter_spec.rb
119
165
  - spec/bumps/remote_feature_spec.rb
120
166
  - spec/bumps/results_push_formatter_spec.rb
121
167
  - spec/bumps_spec.rb
@@ -123,6 +169,12 @@ files:
123
169
  - spec/spec_helper.rb
124
170
  - tasks/rspec.rake
125
171
  - tasks/setup.rake
172
+ - test_features/json_formatter_spec/describing_a_feature.feature
173
+ - test_features/json_formatter_spec/describing_a_scenario.feature
174
+ - test_features/json_formatter_spec/describing_a_step.feature
175
+ - test_features/json_formatter_spec/propagating_status_from_step_to_scenario.feature
176
+ - test_features/json_formatter_spec/steps/steps.rb
177
+ - test_features/json_formatter_spec/support/env.rb
126
178
  - test_features/remote_content/destroy_dr_thaddeus_venture.feature
127
179
  - test_features/requires/support/env.rb
128
180
  has_rdoc: true
@@ -136,21 +188,27 @@ rdoc_options:
136
188
  require_paths:
137
189
  - lib
138
190
  required_ruby_version: !ruby/object:Gem::Requirement
191
+ none: false
139
192
  requirements:
140
193
  - - ">="
141
194
  - !ruby/object:Gem::Version
195
+ hash: 3
196
+ segments:
197
+ - 0
142
198
  version: "0"
143
- version:
144
199
  required_rubygems_version: !ruby/object:Gem::Requirement
200
+ none: false
145
201
  requirements:
146
202
  - - ">="
147
203
  - !ruby/object:Gem::Version
204
+ hash: 3
205
+ segments:
206
+ - 0
148
207
  version: "0"
149
- version:
150
208
  requirements: []
151
209
 
152
210
  rubyforge_project: bumps
153
- rubygems_version: 1.3.5
211
+ rubygems_version: 1.3.7
154
212
  signing_key:
155
213
  specification_version: 3
156
214
  summary: Remote feature management for Cucumber