aslakhellesoy-cucumber 0.3.3.4 → 0.3.3.5

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,11 +1,13 @@
1
1
  == 0.3.4 (In Git)
2
2
 
3
- Hooray - speed improvements when using Rake!
3
+ A couple of great new features in this release. Running with Rake is faster than before,
4
+ and there is a brand new JUnit formatter - great for Continuous Integration reports!
4
5
 
5
6
  === Bugfixes
6
7
  * Problem with multiple terms in languages.yml (#321 Aslak Hellesøy)
7
8
 
8
9
  === New features
10
+ * New JUnit formatter (Gareth Jones)
9
11
  * Support for Vietnamese (Ngoc Dao)
10
12
  * Added aliases for Feature and But in Japanese (Leonard Chin)
11
13
  * Support for Catalan (Francesc Esplugas)
@@ -157,6 +157,9 @@ examples/java/features/step_definitons/hello_steps.rb
157
157
  examples/java/features/step_definitons/tree_steps.rb
158
158
  examples/java/features/tree.feature
159
159
  examples/java/src/cucumber/demo/Hello.java
160
+ examples/junit/features/one_passing_one_failing.feature
161
+ examples/junit/features/pending.feature
162
+ examples/junit/features/step_definitions/steps.rb
160
163
  examples/pure_java/README.textile
161
164
  examples/selenium/Rakefile
162
165
  examples/selenium/features/search.feature
@@ -241,6 +244,7 @@ features/cucumber_cli_diff_disabled.feature
241
244
  features/cucumber_cli_outlines.feature
242
245
  features/custom_formatter.feature
243
246
  features/exclude_files.feature
247
+ features/junit_formatter.feature
244
248
  features/multiline_names.feature
245
249
  features/rake_task.feature
246
250
  features/report_called_undefined_steps.feature
@@ -296,6 +300,7 @@ lib/cucumber/formatter/console.rb
296
300
  lib/cucumber/formatter/cucumber.css
297
301
  lib/cucumber/formatter/cucumber.sass
298
302
  lib/cucumber/formatter/html.rb
303
+ lib/cucumber/formatter/junit.rb
299
304
  lib/cucumber/formatter/pretty.rb
300
305
  lib/cucumber/formatter/profile.rb
301
306
  lib/cucumber/formatter/progress.rb
@@ -0,0 +1,8 @@
1
+ Feature: One passing scenario, one failing scenario
2
+
3
+ Scenario: Passing
4
+ Given a passing scenario
5
+
6
+ Scenario: Failing
7
+ Given a failing scenario
8
+
@@ -0,0 +1,5 @@
1
+ Feature: Pending step
2
+
3
+ Scenario: Pending
4
+ Given a pending step
5
+
@@ -0,0 +1,11 @@
1
+ Given /a passing scenario/ do
2
+ #does nothing
3
+ end
4
+
5
+ Given /a failing scenario/ do
6
+ fail
7
+ end
8
+
9
+ Given /a pending step/ do
10
+ pending
11
+ end
@@ -1,29 +1,29 @@
1
- Users want to know that nobody can masquerade as them. We want to extend trust
2
- only to visitors who present the appropriate credentials. Everyone wants this
3
- identity verification to be as secure and convenient as possible.
4
-
5
- Feature: Logging in
6
- As an anonymous user with an account
7
- I want to log in to my account
8
- So that I can be myself
9
-
10
- #
11
- # Log in: get form
12
- #
13
- Scenario: Anonymous user can get a login form.
14
- Given I am logged out
15
- When I go to "/login"
16
- Then I should be at the "sessions/new" page
17
-
18
- #
19
- # Log in successfully, but don't remember me
20
- #
21
- Scenario: Anonymous user can log in
22
- Given an "activated" user named "reggie" exists
23
- And I am logged out
24
- When I go to "/login"
25
- And I fill in "Login" with "reggie"
26
- And I fill in "Password" with "password"
27
- And I press "Log in"
28
- Then I should be at the "dashboard/index" page
29
-
1
+ Users want to know that nobody can masquerade as them. We want to extend trust
2
+ only to visitors who present the appropriate credentials. Everyone wants this
3
+ identity verification to be as secure and convenient as possible.
4
+
5
+ Feature: Logging in
6
+ As an anonymous user with an account
7
+ I want to log in to my account
8
+ So that I can be myself
9
+
10
+ #
11
+ # Log in: get form
12
+ #
13
+ Scenario: Anonymous user can get a login form.
14
+ Given I am logged out
15
+ When I go to "/login"
16
+ Then I should be at the "sessions/new" page
17
+
18
+ #
19
+ # Log in successfully, but don't remember me
20
+ #
21
+ Scenario: Anonymous user can log in
22
+ Given an "activated" user named "reggie" exists
23
+ And I am logged out
24
+ When I go to "/login"
25
+ And I fill in "Login" with "reggie"
26
+ And I fill in "Password" with "password"
27
+ And I press "Log in"
28
+ Then I should be at the "dashboard/index" page
29
+
@@ -1,21 +1,21 @@
1
- Visitors may create an account, but for those who are not already in the
2
- system an someone must activate the account for them before it can be used.
3
-
4
- Feature: Activating an account
5
- As a registered, but not yet activated, user
6
- I want to be able to activate my account
7
- So that I can log in to the site
8
-
9
- Scenario: Not-yet-activated user can activate her account
10
- Given a registered user named 'Reggie' # need to rewrite
11
- # And the user has activation_code: 'activate_me', activated_at: nil!
12
- # And we try hard to remember the user's updated_at, and created_at
13
- # When she goes to /activate/activate_me
14
- # Then she should be redirected to 'login'
15
- # When she follows that redirect!
16
- # Then she should see a notice message 'Signup complete!'
17
- # And a user with login: 'reggie' should exist
18
- # And the user should have login: 'reggie', and email: 'registered@example.com'
19
- # And the user's activation_code should be nil
20
- # And the user's activated_at should not be nil
1
+ Visitors may create an account, but for those who are not already in the
2
+ system an someone must activate the account for them before it can be used.
3
+
4
+ Feature: Activating an account
5
+ As a registered, but not yet activated, user
6
+ I want to be able to activate my account
7
+ So that I can log in to the site
8
+
9
+ Scenario: Not-yet-activated user can activate her account
10
+ Given a registered user named 'Reggie' # need to rewrite
11
+ # And the user has activation_code: 'activate_me', activated_at: nil!
12
+ # And we try hard to remember the user's updated_at, and created_at
13
+ # When she goes to /activate/activate_me
14
+ # Then she should be redirected to 'login'
15
+ # When she follows that redirect!
16
+ # Then she should see a notice message 'Signup complete!'
17
+ # And a user with login: 'reggie' should exist
18
+ # And the user should have login: 'reggie', and email: 'registered@example.com'
19
+ # And the user's activation_code should be nil
20
+ # And the user's activated_at should not be nil
21
21
  # And she should not be logged in
@@ -0,0 +1,59 @@
1
+ Feature: JUnit output formatter
2
+ In order for developers to create test reports with ant
3
+ Cucumber should be able to output JUnit xml files
4
+
5
+ Background:
6
+ Given I am in junit
7
+ And the tmp directory is empty
8
+
9
+ Scenario: one feature, one passing scenario, one failing scenario
10
+ When I run cucumber --format junit --out tmp/ features/one_passing_one_failing.feature
11
+ Then it should fail with
12
+ """
13
+
14
+ """
15
+ And "examples/junit/tmp/TEST-One_passing_scenario__one_failing_scenario.xml" should contain XML
16
+ """
17
+ <?xml version="1.0" encoding="UTF-8"?>
18
+ <testsuite errors="0" tests="2" name="One passing scenario, one failing scenario" failures="1">
19
+ <testcase name="Given a passing scenario" classname="One passing scenario, one failing scenario.Passing">
20
+ </testcase>
21
+ <testcase name="Given a failing scenario" classname="One passing scenario, one failing scenario.Failing">
22
+ <failure message="Given a failing scenario">
23
+ (RuntimeError)
24
+ ./features/step_definitions/steps.rb:6:in `/a failing scenario/'
25
+ features/one_passing_one_failing.feature:7:in `Given a failing scenario' </failure>
26
+ </testcase>
27
+ </testsuite>
28
+
29
+ """
30
+ Scenario: pending step
31
+ When I run cucumber --format junit --out tmp/ features/pending.feature
32
+ Then it should pass with
33
+ """
34
+
35
+ """
36
+ And "examples/junit/tmp/TEST-Pending_step.xml" should contain XML
37
+ """
38
+ <?xml version="1.0" encoding="UTF-8"?>
39
+ <testsuite errors="0" tests="1" name="Pending step" failures="1">
40
+ <testcase name="Given a pending step" classname="Pending step.Pending">
41
+ <failure message="Given a pending step">
42
+ TODO (Cucumber::Pending)
43
+ ./features/step_definitions/steps.rb:10:in `/a pending step/'
44
+ features/pending.feature:4:in `Given a pending step' </failure>
45
+ </testcase>
46
+ </testsuite>
47
+
48
+ """
49
+
50
+ Scenario: run all features
51
+ When I run cucumber --format junit --out tmp/ features
52
+ Then it should fail with
53
+ """
54
+
55
+ """
56
+ And "examples/junit/tmp/TEST-One_passing_scenario__one_failing_scenario.xml" should exist
57
+ And "examples/junit/tmp/TEST-Pending_step.xml" should exist
58
+
59
+
@@ -1,3 +1,5 @@
1
+ require 'tempfile'
2
+
1
3
  Given /^I am in (.*)$/ do |example_dir_relative_path|
2
4
  @current_dir = examples_dir(example_dir_relative_path)
3
5
  end
@@ -10,6 +12,13 @@ Given /^a standard Cucumber project directory structure$/ do
10
12
  end
11
13
  end
12
14
 
15
+ Given /^the (.*) directory is empty$/ do |directory|
16
+ in_current_dir do
17
+ FileUtils.remove_dir(directory) rescue nil
18
+ FileUtils.mkdir 'tmp'
19
+ end
20
+ end
21
+
13
22
  Given /^a file named "([^\"]*)"$/ do |file_name|
14
23
  create_file(file_name, '')
15
24
  end
@@ -53,6 +62,18 @@ Then /^the output should not contain$/ do |text|
53
62
  last_stdout.should_not include(text)
54
63
  end
55
64
 
65
+ # http://diffxml.sourceforge.net/
66
+ Then /^"(.*)" should contain XML$/ do |file, xml|
67
+ t = Tempfile.new('cucumber-junit')
68
+ t.write(xml)
69
+ t.flush
70
+ t.close
71
+ diff = `diffxml #{t.path} #{file}`
72
+ if diff =~ /<delta>/m
73
+ raise diff + "\nXML WAS:\n" + IO.read(file)
74
+ end
75
+ end
76
+
56
77
  Then /^"(.*)" should contain$/ do |file, text|
57
78
  IO.read(file).should == text
58
79
  end
@@ -3,7 +3,7 @@ module Cucumber
3
3
  class YmlLoadError < StandardError; end
4
4
 
5
5
  class Configuration
6
- FORMATS = %w{pretty profile progress rerun}
6
+ FORMATS = %w{pretty profile progress rerun junit}
7
7
  DEFAULT_FORMAT = 'pretty'
8
8
 
9
9
  attr_reader :paths
@@ -66,10 +66,11 @@ module Cucumber
66
66
  @options[:formats][v] = @out_stream
67
67
  @active_format = v
68
68
  end
69
- opts.on("-o", "--out FILE",
70
- "Write output to a file instead of STDOUT. This option",
69
+ opts.on("-o", "--out [FILE|DIR]",
70
+ "Write output to a file/directory instead of STDOUT. This option",
71
71
  "applies to the previously specified --format, or the",
72
- "default format if no format is specified.") do |v|
72
+ "default format if no format is specified. Check the specific",
73
+ "formatter's docs to see whether to pass a file or a dir.") do |v|
73
74
  @options[:formats][@active_format] = v
74
75
  end
75
76
  opts.on("-t TAGS", "--tags TAGS",
@@ -198,10 +199,12 @@ module Cucumber
198
199
  return Formatter::Pretty.new(step_mother, nil, @options) if @options[:autoformat]
199
200
  formatters = @options[:formats].map do |format, out|
200
201
  if String === out # file name
201
- out = File.open(out, Cucumber.file_mode('w'))
202
- at_exit do
203
- out.flush
204
- out.close
202
+ unless File.directory?(out)
203
+ out = File.open(out, Cucumber.file_mode('w'))
204
+ at_exit do
205
+ out.flush
206
+ out.close
207
+ end
205
208
  end
206
209
  end
207
210
 
@@ -209,7 +212,7 @@ module Cucumber
209
212
  formatter_class = formatter_class(format)
210
213
  formatter_class.new(step_mother, out, @options)
211
214
  rescue Exception => e
212
- e.message += "\nError creating formatter: #{format}"
215
+ e.message << "\nError creating formatter: #{format}"
213
216
  raise e
214
217
  end
215
218
  end
@@ -227,6 +230,7 @@ module Cucumber
227
230
  when 'progress' then Formatter::Progress
228
231
  when 'rerun' then Formatter::Rerun
229
232
  when 'usage' then Formatter::Usage
233
+ when 'junit' then Formatter::JUnit
230
234
  else
231
235
  constantize(format)
232
236
  end
@@ -1 +1 @@
1
- %w{color_io pretty progress profile rerun html usage}.each{|n| require "cucumber/formatter/#{n}"}
1
+ %w{color_io pretty progress profile rerun html usage junit}.each{|n| require "cucumber/formatter/#{n}"}
@@ -0,0 +1,78 @@
1
+ begin
2
+ require 'builder'
3
+ rescue LoadError
4
+ gem 'builder'
5
+ require 'builder'
6
+ end
7
+
8
+ module Cucumber
9
+ module Formatter
10
+ class JUnit < Cucumber::Ast::Visitor
11
+
12
+ def initialize(step_mother, io, options)
13
+ super(step_mother)
14
+ @reportdir = io
15
+ raise "You *must* specify --out DIR for the junit formatter" unless @reportdir
16
+ raise "Use --out DIR (not --out FILE) for the junit formatter" if File === @reportdir
17
+ end
18
+
19
+ def visit_feature(feature)
20
+ @failures = @errors = @tests = 0
21
+ @builder = Builder::XmlMarkup.new( :indent => 2 )
22
+ super
23
+
24
+ @testsuite = Builder::XmlMarkup.new( :indent => 2 )
25
+ @testsuite.instruct!
26
+ @testsuite.testsuite(
27
+ :failures => @failures,
28
+ :errors => @errors,
29
+ :tests => @tests,
30
+ :name => @feature_name ) do
31
+ @testsuite << @builder.target!
32
+ end
33
+
34
+ File.open(@feature_filename, 'w') { |file| file.write(@testsuite.target!) }
35
+ end
36
+
37
+ def visit_feature_name(name)
38
+ lines = name.split(/\r?\n/)
39
+ @feature_name = lines[0].sub(/Feature\:/, '').strip
40
+ @feature_filename = convert_to_file_name(@feature_name)
41
+ end
42
+
43
+ def visit_scenario_name(keyword, name, file_colon_line, source_indent)
44
+ @scenario = name
45
+ end
46
+
47
+ def visit_steps(steps)
48
+ @steps_failed = false
49
+ super
50
+ @failures += 1 if @steps_failed
51
+ @tests += 1
52
+ end
53
+
54
+ def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
55
+ step_name = keyword + " " + step_match.format_args(lambda{|param| "*#{param}*"})
56
+ @builder.testcase(:classname => "#{@feature_name}.#{@scenario}", :name => step_name) do
57
+ if status != :passed
58
+ @builder.failure(:message => step_name) do
59
+ @builder.text!(format_exception(exception)) if exception
60
+ end
61
+ @steps_failed = true
62
+ end
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def convert_to_file_name(feature_name)
69
+ @reportdir + "TEST-" + feature_name.gsub(/[^\w_\.]/, '_') + ".xml"
70
+ end
71
+
72
+ def format_exception(exception)
73
+ (["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -481,15 +481,19 @@ module Cucumber
481
481
  end
482
482
 
483
483
  module Background1
484
-
485
484
  def matches_name?(regexp_to_match)
486
485
  name.build =~ regexp_to_match
487
486
  end
488
487
 
489
- def has_tags?(tag_names)
490
- feature_tags = self.parent.tags
491
- feature_tags.has_tags?(tag_names)
492
- end
488
+ def at_line?(line)
489
+ background_keyword.line == line ||
490
+ steps.at_line?(line)
491
+ end
492
+
493
+ def has_tags?(tag_names)
494
+ feature_tags = self.parent.tags
495
+ feature_tags.has_tags?(tag_names)
496
+ end
493
497
 
494
498
  def build
495
499
  Ast::Background.new(
@@ -499,7 +503,7 @@ module Cucumber
499
503
  name.build,
500
504
  steps.build
501
505
  )
502
- end
506
+ end
503
507
  end
504
508
 
505
509
  def _nt_background
@@ -76,27 +76,31 @@ module Cucumber
76
76
  end
77
77
 
78
78
  rule background
79
- comment white background_keyword space* name:lines_to_keyword? (eol+ / eof) steps {
79
+ comment white background_keyword space* name:lines_to_keyword? (eol+ / eof) steps {
80
+ def matches_name?(regexp_to_match)
81
+ name.build =~ regexp_to_match
82
+ end
80
83
 
81
- def matches_name?(regexp_to_match)
82
- name.build =~ regexp_to_match
83
- end
84
+ def at_line?(line)
85
+ background_keyword.line == line ||
86
+ steps.at_line?(line)
87
+ end
84
88
 
85
89
  def has_tags?(tag_names)
86
90
  feature_tags = self.parent.tags
87
91
  feature_tags.has_tags?(tag_names)
88
92
  end
89
93
 
90
- def build
91
- Ast::Background.new(
92
- comment.build,
93
- background_keyword.line,
94
- background_keyword.text_value,
95
- name.build,
96
- steps.build
97
- )
98
- end
99
- }
94
+ def build
95
+ Ast::Background.new(
96
+ comment.build,
97
+ background_keyword.line,
98
+ background_keyword.text_value,
99
+ name.build,
100
+ steps.build
101
+ )
102
+ end
103
+ }
100
104
  end
101
105
 
102
106
  rule feature_elements
@@ -3,7 +3,7 @@ module Cucumber #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 3
5
5
  TINY = 3
6
- PATCH = 4 # Set to nil for official release
6
+ PATCH = 5 # Set to nil for official release
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aslakhellesoy-cucumber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3.4
4
+ version: 0.3.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Aslak Helles\xC3\xB8y"
@@ -234,6 +234,9 @@ files:
234
234
  - examples/java/features/step_definitons/tree_steps.rb
235
235
  - examples/java/features/tree.feature
236
236
  - examples/java/src/cucumber/demo/Hello.java
237
+ - examples/junit/features/one_passing_one_failing.feature
238
+ - examples/junit/features/pending.feature
239
+ - examples/junit/features/step_definitions/steps.rb
237
240
  - examples/pure_java/README.textile
238
241
  - examples/selenium/Rakefile
239
242
  - examples/selenium/features/search.feature
@@ -318,6 +321,7 @@ files:
318
321
  - features/cucumber_cli_outlines.feature
319
322
  - features/custom_formatter.feature
320
323
  - features/exclude_files.feature
324
+ - features/junit_formatter.feature
321
325
  - features/multiline_names.feature
322
326
  - features/rake_task.feature
323
327
  - features/report_called_undefined_steps.feature
@@ -373,6 +377,7 @@ files:
373
377
  - lib/cucumber/formatter/cucumber.css
374
378
  - lib/cucumber/formatter/cucumber.sass
375
379
  - lib/cucumber/formatter/html.rb
380
+ - lib/cucumber/formatter/junit.rb
376
381
  - lib/cucumber/formatter/pretty.rb
377
382
  - lib/cucumber/formatter/profile.rb
378
383
  - lib/cucumber/formatter/progress.rb