kosmas58-cucumber 0.3.9.4 → 0.3.11.3

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.
Files changed (38) hide show
  1. data/History.txt +45 -7
  2. data/Manifest.txt +403 -0
  3. data/cucumber.yml +4 -3
  4. data/examples/dos_line_endings/features/dos_line_endings.feature +9 -9
  5. data/features/drb_server_integration.feature +114 -0
  6. data/features/html_formatter/a.html +129 -1574
  7. data/features/junit_formatter.feature +11 -2
  8. data/features/step_definitions/cucumber_steps.rb +15 -2
  9. data/features/support/env.rb +35 -1
  10. data/gem_tasks/features.rake +7 -2
  11. data/lib/cucumber/ast/table.rb +6 -6
  12. data/lib/cucumber/cli/configuration.rb +32 -8
  13. data/lib/cucumber/cli/drb_client.rb +20 -0
  14. data/lib/cucumber/cli/main.rb +9 -0
  15. data/lib/cucumber/formatter/color_io.rb +2 -2
  16. data/lib/cucumber/formatter/console.rb +6 -1
  17. data/lib/cucumber/formatter/cucumber.css +106 -48
  18. data/lib/cucumber/formatter/cucumber.sass +121 -31
  19. data/lib/cucumber/formatter/html.rb +14 -3
  20. data/lib/cucumber/formatter/junit.rb +1 -2
  21. data/lib/cucumber/rake/task.rb +1 -1
  22. data/lib/cucumber/version.rb +2 -2
  23. data/rails_generators/cucumber/cucumber_generator.rb +15 -5
  24. data/rails_generators/cucumber/templates/cucumber.rake +5 -5
  25. data/rails_generators/cucumber/templates/de/paths.rb +3 -3
  26. data/rails_generators/cucumber/templates/de/webrat_steps.rb +11 -3
  27. data/rails_generators/cucumber/templates/env.rb +10 -3
  28. data/rails_generators/cucumber/templates/spork_env.rb +36 -0
  29. data/spec/cucumber/cli/configuration_spec.rb +56 -1
  30. data/spec/cucumber/cli/drb_client_spec.rb +43 -0
  31. data/spec/cucumber/cli/main_spec.rb +70 -19
  32. data/spec/spec_helper.rb +2 -0
  33. metadata +8 -9
  34. data/spec/cucumber/formatter/html/cucumber.css +0 -37
  35. data/spec/cucumber/formatter/html/cucumber.js +0 -13
  36. data/spec/cucumber/formatter/html/index.html +0 -45
  37. data/spec/cucumber/formatter/html/jquery-1.3.min.js +0 -19
  38. data/spec/cucumber/formatter/html/jquery.uitableedit.js +0 -100
@@ -58,5 +58,14 @@ Feature: JUnit output formatter
58
58
  """
59
59
  And "examples/junit/tmp/TEST-One_passing_scenario__one_failing_scenario.xml" should exist
60
60
  And "examples/junit/tmp/TEST-Pending_step.xml" should exist
61
-
62
-
61
+
62
+ Scenario: show correct error message if no --out is passed
63
+ When I run cucumber --format junit features
64
+ Then STDERR should not match
65
+ """
66
+ can't convert .* into String \(TypeError\)
67
+ """
68
+ And STDERR should match
69
+ """
70
+ You \*must\* specify \-\-out DIR for the junit formatter
71
+ """
@@ -31,6 +31,15 @@ Given /^the following profiles? (?:are|is) defined:$/ do |profiles|
31
31
  create_file('cucumber.yml', profiles)
32
32
  end
33
33
 
34
+ Given /^I am running "([^\"]*)" in the background$/ do |command|
35
+ run_in_background command
36
+ end
37
+
38
+ Given /^I am not running (?:.*) in the background$/ do
39
+ # no-op
40
+ end
41
+
42
+
34
43
  When /^I run cucumber (.*)$/ do |cucumber_opts|
35
44
  run "#{Cucumber::RUBY_BINARY} #{Cucumber::BINARY} --no-color #{cucumber_opts}"
36
45
  end
@@ -88,9 +97,9 @@ end
88
97
 
89
98
  Then /^"([^\"]*)" should have the same contents as "([^\"]*)"$/ do |actual_file, expected_file|
90
99
  actual = IO.read(actual_file)
91
- # Comment out to replace expected file. Use with care! Remember to update duration afterwards.
92
- # File.open(expected_file, "w"){|io| io.write(actual)}
93
100
  actual = replace_duration(actual, '0m30.005s')
101
+ # Comment out to replace expected file. Use with care! Remember to update duration afterwards.
102
+ # File.open(expected_file, "w") {|io| io.write(actual)}
94
103
  actual.should == IO.read(expected_file)
95
104
  end
96
105
 
@@ -98,6 +107,10 @@ Then /^STDERR should match$/ do |text|
98
107
  last_stderr.should =~ /#{text}/
99
108
  end
100
109
 
110
+ Then /^STDERR should not match$/ do |text|
111
+ last_stderr.should_not =~ /#{text}/
112
+ end
113
+
101
114
  Then /^STDERR should be empty$/ do
102
115
  last_stderr.should == ""
103
116
  end
@@ -3,6 +3,11 @@ require 'tempfile'
3
3
  require 'spec/expectations'
4
4
  require 'fileutils'
5
5
  require 'forwardable'
6
+ begin
7
+ gem "spork", ">= 0.5.1" # Ensure correct spork version number to avoid false-negatives.
8
+ rescue Gem::LoadError => ex
9
+ warn "WARNING: #{ex.message} You need to have the spork gem installed to run the DRb feature properly!"
10
+ end
6
11
 
7
12
  class CucumberWorld
8
13
  extend Forwardable
@@ -52,6 +57,10 @@ class CucumberWorld
52
57
  end
53
58
  end
54
59
 
60
+ def background_jobs
61
+ @background_jobs ||= []
62
+ end
63
+
55
64
  def in_current_dir(&block)
56
65
  Dir.chdir(@current_dir, &block)
57
66
  end
@@ -66,6 +75,27 @@ class CucumberWorld
66
75
  @last_stderr = IO.read(stderr_file.path)
67
76
  end
68
77
 
78
+ def run_in_background(command)
79
+ pid = fork
80
+ in_current_dir do
81
+ if pid
82
+ background_jobs << pid
83
+ else
84
+ #STDOUT.close
85
+ #STDERR.close
86
+ exec command
87
+ end
88
+ end
89
+ end
90
+
91
+ def terminate_background_jobs
92
+ if @background_jobs
93
+ @background_jobs.each do |pid|
94
+ Process.kill(Signal.list['TERM'], pid)
95
+ end
96
+ end
97
+ end
98
+
69
99
  end
70
100
 
71
101
  World do
@@ -77,7 +107,11 @@ Before do
77
107
  FileUtils.mkdir CucumberWorld.working_dir
78
108
  end
79
109
 
110
+ After do
111
+ terminate_background_jobs
112
+ end
113
+
80
114
  Before('@diffxml') do
81
115
  `diffxml --version`
82
116
  raise "Please install diffxml from http://diffxml.sourceforge.net/" if $? != 0
83
- end
117
+ end
@@ -3,11 +3,16 @@ require 'cucumber/rake/task'
3
3
 
4
4
  namespace :features do
5
5
  Cucumber::Rake::Task.new(:all) do |t|
6
- t.cucumber_opts = "--format pretty"
6
+ t.cucumber_opts = %w{--format progress}
7
+ end
8
+
9
+ Cucumber::Rake::Task.new(:pretty) do |t|
10
+ t.cucumber_opts = %w{--format pretty}
7
11
  end
8
12
 
9
13
  Cucumber::Rake::Task.new(:cruise) do |t|
10
- t.cucumber_opts = "--format html --out=#{ENV['CC_BUILD_ARTIFACTS']}/CucumberFeatures.html"
14
+ t.cucumber_opts = %w{--format html}
15
+ t.cucumber_opts << %[--out "#{ENV['CC_BUILD_ARTIFACTS']}/CucumberFeatures.html"]
11
16
  t.rcov = true
12
17
  t.rcov_opts = %w{--rails --exclude osx\/objc,gems\/,spec\/}
13
18
  t.rcov_opts << %[-o "#{ENV['CC_BUILD_ARTIFACTS']}/CucumberCoverage"]
@@ -62,7 +62,7 @@ module Cucumber
62
62
  def hashes
63
63
  @hashes ||= cells_rows[1..-1].map do |row|
64
64
  row.to_hash
65
- end
65
+ end.freeze
66
66
  end
67
67
 
68
68
  # Converts this table into a Hash where the first column is
@@ -198,7 +198,7 @@ module Cucumber
198
198
  def cells_rows
199
199
  @rows ||= cell_matrix.map do |cell_row|
200
200
  @cells_class.new(self, cell_row)
201
- end
201
+ end.freeze
202
202
  end
203
203
 
204
204
  def headers
@@ -230,7 +230,7 @@ module Cucumber
230
230
  def columns
231
231
  @columns ||= cell_matrix.transpose.map do |cell_row|
232
232
  @cells_class.new(self, cell_row)
233
- end
233
+ end.freeze
234
234
  end
235
235
 
236
236
  def cell_matrix
@@ -243,7 +243,7 @@ module Cucumber
243
243
  col += 1
244
244
  @cell_class.new(raw_cell, self, row, col, line)
245
245
  end
246
- end
246
+ end.freeze
247
247
  end
248
248
 
249
249
  # Represents a row of cells or columns of cells
@@ -268,7 +268,7 @@ module Cucumber
268
268
  end
269
269
 
270
270
  def to_hash #:nodoc:
271
- @to_hash ||= @table.to_hash(self)
271
+ @to_hash ||= @table.to_hash(self).freeze
272
272
  end
273
273
 
274
274
  def value(n) #:nodoc:
@@ -326,7 +326,7 @@ module Cucumber
326
326
  private
327
327
 
328
328
  def col_width
329
- @col_width ||= @table.__send__(:col_width, @col)
329
+ @col_width ||= @table.__send__(:col_width, @col).freeze
330
330
  end
331
331
  end
332
332
  end
@@ -13,6 +13,9 @@ module Cucumber
13
13
  'junit' => 'Cucumber::Formatter::Junit'
14
14
  }
15
15
  DEFAULT_FORMAT = 'pretty'
16
+ DRB_FLAG = '--drb'
17
+ PROFILE_SHORT_FLAG = '-p'
18
+ PROFILE_LONG_FLAG = '--profile'
16
19
 
17
20
  attr_reader :paths
18
21
  attr_reader :options
@@ -28,8 +31,10 @@ module Cucumber
28
31
  end
29
32
 
30
33
  def parse!(args)
31
- @args = args
32
- return parse_args_from_profile('default') if @args.empty?
34
+ @args = args.empty? ? args_from_profile('default') : args
35
+ expand_profiles_into_args
36
+ return if parse_drb
37
+
33
38
  @args.extend(::OptionParser::Arguable)
34
39
 
35
40
  @args.options do |opts|
@@ -100,8 +105,8 @@ module Cucumber
100
105
  opts.on("-e", "--exclude PATTERN", "Don't run feature files or require ruby files matching PATTERN") do |v|
101
106
  @options[:excludes] << Regexp.new(v)
102
107
  end
103
- opts.on("-p", "--profile PROFILE", "Pull commandline arguments from cucumber.yml.") do |v|
104
- parse_args_from_profile(v)
108
+ opts.on(PROFILE_SHORT_FLAG, "#{PROFILE_LONG_FLAG} PROFILE", "Pull commandline arguments from cucumber.yml.") do |v|
109
+ # Processing of this is done previsouly so that the DRb flag can be detected within profiles.
105
110
  end
106
111
  opts.on("-c", "--[no-]color",
107
112
  "Whether or not to use ANSI color in the output. Cucumber decides",
@@ -158,6 +163,9 @@ module Cucumber
158
163
  opts.on("--no-diff", "Disable diff output on failing expectations.") do
159
164
  @options[:diff_enabled] = false
160
165
  end
166
+ opts.on(DRB_FLAG, "Run features against a DRb server. (i.e. with the spork gem)") do
167
+ # Processing of this is done previsouly in order to short circuit args from being lost.
168
+ end
161
169
  opts.on_tail("--version", "Show version.") do
162
170
  @out_stream.puts VERSION::STRING
163
171
  Kernel.exit
@@ -176,7 +184,7 @@ module Cucumber
176
184
  raise("You can't use both --strict and --wip") if @options[:strict] && @options[:wip]
177
185
 
178
186
  # Whatever is left after option parsing is the FILE arguments
179
- @paths += args
187
+ @paths += @args
180
188
  end
181
189
 
182
190
  def verbose?
@@ -199,6 +207,10 @@ module Cucumber
199
207
  @options[:diff_enabled]
200
208
  end
201
209
 
210
+ def drb?
211
+ @drb
212
+ end
213
+
202
214
  def load_language
203
215
  if Cucumber.language_incomplete?(@options[:lang])
204
216
  list_keywords_and_exit(@options[:lang])
@@ -313,7 +325,15 @@ module Cucumber
313
325
  downcase
314
326
  end
315
327
 
316
- def parse_args_from_profile(profile)
328
+ def expand_profiles_into_args
329
+ while (profile_index = @args.index(PROFILE_SHORT_FLAG) || @args.index(PROFILE_LONG_FLAG)) do
330
+ @args.delete_at(profile_index)
331
+ @args[profile_index] = args_from_profile(@args[profile_index])
332
+ @args.flatten!
333
+ end
334
+ end
335
+
336
+ def args_from_profile(profile)
317
337
  unless cucumber_yml.has_key?(profile)
318
338
  raise(<<-END_OF_ERROR)
319
339
  Could not find profile: '#{profile}'
@@ -334,7 +354,7 @@ Defined profiles in cucumber.yml:
334
354
  else
335
355
  raise "The '#{profile}' profile in cucumber.yml was a #{args_from_yml.class}. It must be a String or Array"
336
356
  end
337
- parse!(args_from_yml)
357
+ args_from_yml
338
358
  end
339
359
 
340
360
  def cucumber_yml
@@ -346,7 +366,7 @@ Defined profiles in cucumber.yml:
346
366
  require 'yaml'
347
367
  begin
348
368
  @cucumber_yml = YAML::load(IO.read('cucumber.yml'))
349
- rescue Exception => e
369
+ rescue StandardError => e
350
370
  raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.\n")
351
371
  end
352
372
 
@@ -370,6 +390,10 @@ Defined profiles in cucumber.yml:
370
390
  Kernel.exit
371
391
  end
372
392
 
393
+ def parse_drb
394
+ @drb = @args.delete(DRB_FLAG) ? true : false
395
+ end
396
+
373
397
  def default_options
374
398
  {
375
399
  :strict => false,
@@ -0,0 +1,20 @@
1
+ require "drb/drb"
2
+ # This code was taken from the RSpec project and slightly modified.
3
+
4
+ module Cucumber
5
+ module Cli
6
+ class DRbClientError < StandardError
7
+ end
8
+ # Runs features on a DRB server, originally created with Spork compatibility in mind.
9
+ class DRbClient
10
+ def self.run(args, error_stream, out_stream)
11
+ # See http://redmine.ruby-lang.org/issues/show/496 as to why we specify localhost:0
12
+ DRb.start_service("druby://localhost:0")
13
+ feature_server = DRbObject.new_with_uri("druby://127.0.0.1:8990")
14
+ feature_server.run(args, error_stream, out_stream)
15
+ rescue DRb::DRbConnError
16
+ raise DRbClientError, "No DRb server is running."
17
+ end
18
+ end
19
+ end
20
+ end
@@ -5,6 +5,7 @@ require 'cucumber/parser'
5
5
  require 'cucumber/formatter/color_io'
6
6
  require 'cucumber/cli/language_help_formatter'
7
7
  require 'cucumber/cli/configuration'
8
+ require 'cucumber/cli/drb_client'
8
9
 
9
10
  module Cucumber
10
11
  module Cli
@@ -32,6 +33,14 @@ module Cucumber
32
33
  end
33
34
 
34
35
  def execute!(step_mother)
36
+ if configuration.drb?
37
+ begin
38
+ return DRbClient.run(@args, @error_stream, @out_stream)
39
+ rescue DRbClientError => e
40
+ @error_stream.puts "WARNING: #{e.message} Running features locally:"
41
+ configuration.parse!(@args)
42
+ end
43
+ end
35
44
  configuration.load_language
36
45
  step_mother.options = configuration.options
37
46
 
@@ -6,7 +6,7 @@ module Cucumber
6
6
  class ColorIO
7
7
  extend Forwardable
8
8
  def_delegators :@kernel, :puts, :print # win32console colours only work when sent to Kernel
9
- def_delegators :@stdout, :flush, :tty?
9
+ def_delegators :@stdout, :flush, :tty?, :write
10
10
 
11
11
  def initialize
12
12
  @kernel = Kernel
@@ -20,4 +20,4 @@ module Cucumber
20
20
  end
21
21
  end
22
22
  end
23
- end
23
+ end
@@ -53,6 +53,11 @@ module Cucumber
53
53
  end
54
54
  end
55
55
 
56
+ def print_counts
57
+ STDERR.puts("The #print_counts method is deprecated and will be removed in 0.4. Use #print_stats instead")
58
+ print_stats(nil)
59
+ end
60
+
56
61
  def print_stats(features)
57
62
  @io.print dump_count(step_mother.scenarios.length, "scenario")
58
63
  print_status_counts{|status| step_mother.scenarios(status)}
@@ -60,7 +65,7 @@ module Cucumber
60
65
  @io.print dump_count(step_mother.steps.length, "step")
61
66
  print_status_counts{|status| step_mother.steps(status)}
62
67
 
63
- @io.puts(format_duration(features.duration))
68
+ @io.puts(format_duration(features.duration)) if features
64
69
 
65
70
  @io.flush
66
71
  end
@@ -1,53 +1,38 @@
1
+
2
+
1
3
  .cucumber {
2
- background: black;
3
- color: white;
4
+ font-family: "Lucida Grande", Helvetica, sans-serif;
5
+ font-size: 0.7em;
6
+ background: white;
4
7
  padding: 1em;
5
8
  }
6
- .cucumber .passed {
7
- color: #008800;
8
- }
9
- .cucumber .undefined {
10
- color: #888800;
9
+ .cucumber h1, .cucumber h2, .cucumber h3, .cucumber h4, .cucumber ol, .cucumber li, .cucumber pre, .cucumber p {
10
+ font-size: 1em;
11
+ padding: 0px;
12
+ margin: 0px;
11
13
  }
12
- .cucumber .pending {
13
- color: #888800;
14
+ .cucumber div.feature {
15
+ border: 1px solid;
16
+ padding: 2px;
17
+ margin: 4px;
14
18
  }
15
- .cucumber .failed {
16
- color: #880000;
19
+ .cucumber div.feature div.background, .cucumber div.feature div.scenario, .cucumber div.feature p {
20
+ padding: 0em 0em 0em 1em;
17
21
  }
18
- .cucumber .skipped {
19
- color: #008888;
20
- }
21
- .cucumber .outline {
22
- color: #008888;
23
- }
24
-
25
- .cucumber .passed_param {
26
- font-weight: bold;
27
- color: #00ff00;
28
- }
29
- .cucumber .undefined_param {
30
- font-weight: bold;
31
- color: #ffff00;
32
- }
33
- .cucumber .pending_param {
34
- font-weight: bold;
35
- color: #ffff00;
22
+ .cucumber div.feature div.background div.examples, .cucumber div.feature div.scenario div.examples, .cucumber div.feature p div.examples {
23
+ padding: 0em 0em 0em 1em;
36
24
  }
37
- .cucumber .failed_param {
38
- font-weight: bold;
39
- font-weight: bold;
40
- color: #ff0000;
25
+ .cucumber .stats {
26
+ margin: 2em;
41
27
  }
42
- .cucumber .skipped_param {
43
- font-weight: bold;
44
- color: #00ffff;
28
+ .cucumber .summary ul.features li {
29
+ display: inline;
45
30
  }
46
- .cucumber .outline_param {
47
- font-weight: bold;
48
- color: #00ffff;
31
+ .cucumber .backtrace {
32
+ margin-top: 0;
33
+ margin-bottom: 0;
34
+ margin-left: 1em;
49
35
  }
50
-
51
36
  .cucumber a {
52
37
  text-decoration: none;
53
38
  color: inherit;
@@ -58,17 +43,90 @@
58
43
  .cucumber a:visited {
59
44
  font-weight: normal;
60
45
  }
46
+ .cucumber a div.examples {
47
+ border: 1px solid;
48
+ padding: 2px;
49
+ margin: 4px;
50
+ }
51
+ .cucumber table {
52
+ border-collapse: collapse;
53
+ }
54
+ .cucumber table td, .cucumber table th {
55
+ font-size: 0.7em;
56
+ border: 1px solid #AAAAAA;
57
+ }
58
+ .cucumber table td.failed {
59
+ background: #FFC0CB;
60
+ color: #8B0000;
61
+ }
62
+ .cucumber table td.passed {
63
+ background: #98FB98;
64
+ color: #001111;
65
+ }
66
+ .cucumber table td.skipped {
67
+ background: #e0ffff;
68
+ color: #001111;
69
+ }
70
+ .cucumber table td.pending {
71
+ background: #FFFFE0;
72
+ color: #111100;
73
+ }
74
+ .cucumber table td.undefined {
75
+ background: #FFFFE0;
76
+ color: #111100;
77
+ }
61
78
  .cucumber ol {
62
79
  list-style: none;
63
80
  }
64
- .cucumber .stats {
65
- margin: 2em;
81
+ .cucumber ol li {
82
+ margin: 0em 0em 0em 1em;
83
+ padding: 0em 0em 0em 0.2em;
66
84
  }
67
- .cucumber .summary ul.features li {
68
- display: inline;
85
+ .cucumber ol li span.param {
86
+ font-weight: bold;
69
87
  }
70
- .cucumber .backtrace {
71
- margin-top: 0;
72
- margin-bottom: 0;
73
- margin-left: 1em;
88
+ .cucumber ol li.failed {
89
+ border-left: 5px solid #ff0000;
90
+ border-bottom: 1px solid #ff0000;
91
+ background: #ffc0cb;
92
+ color: #8b0000;
93
+ }
94
+ .cucumber ol li.failed span.param {
95
+ background: !failed_dark;
96
+ }
97
+ .cucumber ol li.passed {
98
+ border-left: 5px solid #00ff00;
99
+ border-bottom: 1px solid #00ff00;
100
+ background: #98fb98;
101
+ color: #001111;
102
+ }
103
+ .cucumber ol li.passed span.param {
104
+ background: #00ff00;
105
+ }
106
+ .cucumber ol li.skipped {
107
+ border-left: 5px solid #00ffff;
108
+ border-bottom: 1px solid #00ffff;
109
+ background: #e0ffff;
110
+ color: #001111;
111
+ }
112
+ .cucumber ol li.skipped span.param {
113
+ background: #00ffff;
114
+ }
115
+ .cucumber ol li.pending {
116
+ border-left: 5px solid #ff8000;
117
+ border-bottom: 1px solid #ff8000;
118
+ background: #ffff00;
119
+ color: #2a1b0a;
120
+ }
121
+ .cucumber ol li.pending span.param {
122
+ background: #ff8000;
123
+ }
124
+ .cucumber ol li.undefined {
125
+ border-left: 5px solid #ff8000;
126
+ border-bottom: 1px solid #ff8000;
127
+ background: #ffff00;
128
+ color: #2a1b0a;
129
+ }
130
+ .cucumber ol li.undefined span.param {
131
+ background: #ff8000;
74
132
  }