gurke 2.1.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c12df541b21f5f76f5956d731764ec23b85e4ac
4
- data.tar.gz: 8397ac6205619fc8667afc0f0694beb0ce395a99
3
+ metadata.gz: d8c96ab204add1ca62ac31c38b6c375324ee89e3
4
+ data.tar.gz: 42ba448e6eaf2bdf6352df493d31036c0ab789cc
5
5
  SHA512:
6
- metadata.gz: e54e0281307bf79d2bea76bf7c0a9b3d84f677669810be1fc0e65a6a6c537700a2869a4969d0ab19fc6e34c5d3c3d3368a97f25136948884bc26a5f5a2aab8d7
7
- data.tar.gz: 490ad37a6ad2a9f3d15db99ec35eabf2694fd82ab5256578d4d1351d63ff9d6241e626dafead371309512b8633f080fdae5edf66604a108399488b846b1c84e6
6
+ metadata.gz: 350ced1ca8fac0b2279ceab141bccd3c16eb358a129de1aa7ed06c960c94a11e61706e4730cc53af2846e2c9e73493e1e29544a8c659b610d2ce7448c183cf36
7
+ data.tar.gz: 2b2831a82dea72c9c8c552e88187ac17574d9bcbce2e69deae41a94efe4e144ea3c5c13ae07052826244ca1a7f962d3e56ec27585e38689be58d1e84370fc713
@@ -0,0 +1,23 @@
1
+ # Changelog
2
+
3
+ ## 2.2.1
4
+
5
+ * BugFix (missing argument in cli.rb)
6
+ * BugFix in after_feature hook call (missing feature argument)
7
+
8
+ ## 2.2.0
9
+
10
+ + Support executing all features inside one directory
11
+ + Support reporter selection via cli
12
+ + Add TeamCityReporter (`gurke --formatter team_city`)
13
+ * Support string as step definitions correctly
14
+ * Smaller bugfix in improved exception formatting
15
+
16
+
17
+ ## 2.1.0
18
+
19
+ * Improve exception formating
20
+
21
+ ## 2.0.0
22
+
23
+ * Project start
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Gurke
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/gurke.svg)](http://badge.fury.io/rb/gurke) [![Build Status](http://img.shields.io/travis/jgraichen/gurke/master.svg)](https://travis-ci.org/jgraichen/gurke) [![Code Climate](http://img.shields.io/codeclimate/github/jgraichen/gurke.svg)](https://codeclimate.com/github/jgraichen/gurke) [![Dependency Status](http://img.shields.io/gemnasium/jgraichen/gurke.svg)](https://gemnasium.com/jgraichen/gurke) [![RubyDoc Documentation](http://img.shields.io/badge/rubydoc-here-blue.svg)](http://rubydoc.info/github/jgraichen/gurke/master/frames)
4
+
3
5
  **Gurke** is an experimental, alternative cucumber runner. It ~~steals~~ borrows ideas and concepts from [turnip](https://github.com/jnicklas/turnip), [rspec](http://rspec.info) and tries to avoid [cucumber](https://github.com/cucumber/cucumber/).
4
6
 
5
7
  That includes * Step definitions in modules * Before, After and Around hooks * Formatters * Partial step inclusion (via modules) * etc. Also new ideas like keyword depended step definitions are planned.
@@ -0,0 +1,35 @@
1
+ Feature: Other Reporter
2
+ As a developer
3
+ In order to adjust the output to my requirements (e.g. inside a CI)
4
+ I want to pass a command line argument to change the reporter
5
+
6
+ Background:
7
+ Given I am in a project using gurke
8
+ And a file "features/test.feature" with the following content exists
9
+ """
10
+ Feature: F
11
+ Scenario: Scenario A
12
+ Given this is a success
13
+
14
+ """
15
+ And a file "features/support/steps/test_steps.rb" with the following content exists
16
+ """
17
+ module TestSteps
18
+ step("This is a success") { }
19
+ end
20
+ Gurke.configure{|c| c.include TestSteps }
21
+ """
22
+
23
+ Scenario: Use the default reporter without addition arguments
24
+ When I execute "bundle exec gurke"
25
+ Then the program output should not include "##teamcity"
26
+
27
+ Scenario: Use specified reporter when run with --formatter
28
+ When I execute "bundle exec gurke --formatter team_city"
29
+ Then the program output should include "##teamcity[testStarted name='Scenario A']"
30
+ Then the program output should include "##teamcity[testFinished name='Scenario A']"
31
+
32
+ Scenario: Use specified reporter when run with -f
33
+ When I execute "bundle exec gurke -f team_city"
34
+ Then the program output should include "##teamcity[testStarted name='Scenario A']"
35
+ Then the program output should include "##teamcity[testFinished name='Scenario A']"
@@ -0,0 +1,62 @@
1
+ Feature: Run specific features or scenarios
2
+ In order to get faster test results
3
+ As a user
4
+ I want run only feature files from one directory
5
+
6
+ Background:
7
+ Given I am in a project using gurke
8
+ Given a file "features/odd/a.feature" with the following content exists
9
+ """
10
+ Feature: F
11
+ Bla blub, a longer description.
12
+
13
+ Scenario: Scenario A
14
+ Given I am successful
15
+ """
16
+ Given a file "features/odd/c.feature" with the following content exists
17
+ """
18
+ Feature: F
19
+ Bla blub, a longer description.
20
+
21
+ Scenario: Scenario C
22
+ Given I am successful
23
+ """
24
+ Given a file "features/even/b.feature" with the following content exists
25
+ """
26
+ Feature: F
27
+ Bla blub, a longer description.
28
+
29
+ Scenario: Scenario B
30
+ Given I am successful
31
+ """
32
+ Given a file "trash/b.f" with the following content exists
33
+ """
34
+ Feature: F
35
+ Bla blub, a longer description.
36
+
37
+ Scenario: Scenario B
38
+ Given I am successful
39
+ """
40
+ And a file "features/support/steps/test_steps.rb" with the following content exists
41
+ """
42
+ module TestSteps
43
+ Given("I am successful") { true }
44
+ end
45
+ Gurke.configure{|c| c.include TestSteps }
46
+ """
47
+
48
+ Scenario: Run all features from on directory
49
+ When I execute "bundle exec gurke features/odd"
50
+ And the program output should include "2 scenarios: 0 failing, 0 pending"
51
+
52
+ Scenario: Run all features from on directory (II)
53
+ When I execute "bundle exec gurke features/even"
54
+ And the program output should include "1 scenarios: 0 failing, 0 pending"
55
+
56
+ Scenario: Run all features from on directory (with subdirectories)
57
+ When I execute "bundle exec gurke features"
58
+ And the program output should include "3 scenarios: 0 failing, 0 pending"
59
+
60
+ Scenario: Run all features from on directory (based on feature pattern)
61
+ When I execute "bundle exec gurke trash"
62
+ And the program output should include "0 scenarios: 0 failing, 0 pending"
@@ -21,6 +21,7 @@ module Gurke
21
21
  module Reporters
22
22
  require 'gurke/reporters/null_reporter'
23
23
  require 'gurke/reporters/default_reporter'
24
+ require 'gurke/reporters/team_city_reporter'
24
25
  end
25
26
 
26
27
  class Error < StandardError; end
@@ -28,8 +28,7 @@ module Gurke
28
28
  Dir[r].each{|f| require File.expand_path(f) }
29
29
  end if options[:require].any?
30
30
 
31
- files = Dir[options[:pattern].to_s] if files.empty? && options[:pattern]
32
- files.map!{|f| File.expand_path(f) }
31
+ files = expand_files files, options
33
32
 
34
33
  runner = if options[:drb_server]
35
34
  Runner::DRbServer
@@ -58,6 +57,8 @@ module Gurke
58
57
  opt :help, 'Print this help.'
59
58
  opt :version, 'Show program version information.'
60
59
  opt :backtrace, 'Show full error backtraces.'
60
+ opt :formatter, 'Select a special formatter as reporter', \
61
+ default: 'default'
61
62
  opt :pattern, 'File pattern matching feature files to be run.',
62
63
  default: 'features/**/*.feature'
63
64
  opt :require, 'Files matching this pattern will be required after'\
@@ -73,5 +74,21 @@ module Gurke
73
74
  opt :drb, 'Run features on already started DRb server. (experimental)', short: :none
74
75
  end
75
76
  end
77
+
78
+ private
79
+ def expand_files(files, options)
80
+ files = Dir[options[:pattern].to_s] if files.empty? && options[:pattern]
81
+ files.inject([]) do |memo, input|
82
+ if File.directory? input
83
+ Dir[input + '/**/*'].each do |file_in_dir|
84
+ next if options[:pattern] && !File.fnmatch?(options[:pattern], file_in_dir)
85
+ memo << File.expand_path(file_in_dir)
86
+ end
87
+ else
88
+ memo << File.expand_path(input)
89
+ end
90
+ memo
91
+ end
92
+ end
76
93
  end
77
94
  end
@@ -83,7 +83,7 @@ module Gurke
83
83
  run_feature runner, reporter
84
84
  end
85
85
  ensure
86
- reporter.invoke :after_feature
86
+ reporter.invoke :after_feature, self
87
87
  end
88
88
 
89
89
  private
@@ -255,5 +255,32 @@ module Gurke
255
255
  rescue => e
256
256
  warn "Rescued in reporter: #{e}\n" + e.backtrace.join("\n")
257
257
  end
258
+
259
+
260
+ # @api private
261
+ #
262
+ protected
263
+ def format_exception(ex)
264
+ s = [ex.class.to_s + ': ' + ex.message.strip]
265
+ if ex.backtrace.nil?
266
+ s << ' <no backtrace available>'
267
+ elsif ex.backtrace.empty?
268
+ s << ' <backtrace empty>'
269
+ else
270
+ ex.backtrace.each do |bt|
271
+ s << ' ' + bt.strip
272
+ end
273
+ end
274
+
275
+ if ex.respond_to?(:cause) && ex.cause &&
276
+ ex.cause.respond_to?(:message) && ex.cause.respond_to?(:backtrace)
277
+
278
+ cause = format_exception(ex.cause)
279
+ s << 'caused by: ' + cause.shift
280
+ s += cause
281
+ end
282
+
283
+ s
284
+ end
258
285
  end
259
286
  end
@@ -90,29 +90,6 @@ module Gurke::Reporters
90
90
  io.puts exout.map{|s| red(" #{s}\n") }.join
91
91
  end
92
92
 
93
- def format_exception(ex)
94
- s = [ex.message.strip]
95
- if ex.backtrace.nil?
96
- s << ' <no backtrace available>'
97
- elsif ex.backtrace.empty?
98
- s << ' <backtrace empty>'
99
- else
100
- ex.backtrace.each do |bt|
101
- s << ' ' + bt.strip
102
- end
103
- end
104
-
105
- if ex.respond_to?(:cause) && ex.cause &&
106
- ex.cause.respond_to?(:message) && ex.cause.respond_to?(:backtrace)
107
-
108
- cause = format_exception(ex.cause)
109
- s << 'caused by: ' + cause.shift
110
- s += cause
111
- end
112
-
113
- s
114
- end
115
-
116
93
  [:black, :red, :green, :yellow, :blue,
117
94
  :magenta, :cyan, :white, :default, :light_black,
118
95
  :light_red, :light_green, :light_yellow, :light_blue,
@@ -0,0 +1,128 @@
1
+ module Gurke::Reporters
2
+ #
3
+ # The {TeamCityReporter} prints features, scenarios and
4
+ # steps in a format parseable by TeamCity CI.
5
+ #
6
+ class TeamCityReporter < NullReporter
7
+ attr_reader :io
8
+ def initialize(io = $stdout)
9
+ @io = io
10
+ end
11
+
12
+ def before_feature(feature)
13
+ publish :testSuiteStarted, name: feature.name
14
+ io.puts " #{feature.description.split("\n").join("\n ")}"
15
+ io.puts
16
+ end
17
+
18
+ def before_scenario(scenario)
19
+ @scenario = scenario
20
+ publish :testStarted, name: scenario.name
21
+ end
22
+
23
+ def start_background(*)
24
+ unless @background
25
+ io.puts ' Background:'
26
+ end
27
+
28
+ @background = true
29
+ end
30
+
31
+ def end_background(*)
32
+ @background = false
33
+ end
34
+
35
+ def before_step(step, *)
36
+ io.print ' ' if @background
37
+ io.print ' '
38
+ io.print step.keyword
39
+ io.print step.name
40
+ end
41
+
42
+ def after_step(step, *)
43
+ case step.state
44
+ when :pending then print_pending step
45
+ when :failed then print_failed step
46
+ when :success then print_braces 'success'
47
+ else print_braces 'skipped'
48
+ end
49
+ io.puts
50
+ io.flush
51
+ end
52
+
53
+ def after_scenario(scenario)
54
+ publish :testFinished, name: scenario.name
55
+ end
56
+
57
+ def after_feature(feature)
58
+ publish :testSuiteFinished, name: feature.name
59
+ end
60
+
61
+ def after_features(features)
62
+ scenarios = features.map(&:scenarios).flatten
63
+
64
+ example_count = scenarios.size
65
+ failure_count = scenarios.select(&:failed?).size
66
+ pending_count = scenarios.select(&:pending?).size
67
+
68
+ io.puts " #{example_count} scenarios: " \
69
+ "#{failure_count} failing, " \
70
+ "#{pending_count} pending"
71
+ io.puts
72
+ end
73
+
74
+ private
75
+
76
+ def print_braces(str)
77
+ io.print " (#{str})"
78
+ end
79
+
80
+ def print_pending(step)
81
+ return if @pending == @scenario # only once per scenario
82
+ publish :testPending,
83
+ name: @scenario.name,
84
+ message: 'Step definition missing'
85
+ @pending = @scenario
86
+ end
87
+
88
+ def print_failed(step)
89
+ publish :testFailed,
90
+ name: @scenario.name,
91
+ message: step.exception.inspect,
92
+ backtrace: step.exception.backtrace.join('\n')
93
+
94
+ print_braces 'failure'
95
+ io.puts
96
+
97
+ exout = format_exception(step.exception)
98
+ io.puts exout.map{|s| " #{s}\n" }.join
99
+ end
100
+
101
+
102
+ private
103
+ def publish(message_name, args)
104
+ args = [] << message_name.to_s << escaped_array_of(args)
105
+ args = args.flatten.reject(&:nil?)
106
+
107
+ io.puts "##teamcity[#{args.join(' ')}]"
108
+ end
109
+
110
+ def escape(string)
111
+ string.gsub(/(\||'|\r|\n|\u0085|\u2028|\u2029|\[|\])/, '|$1')
112
+ end
113
+
114
+ def escaped_array_of(args)
115
+ return [] if args.nil?
116
+
117
+ if args.is_a? Hash
118
+ args.map { |key, value| "#{key.to_s}='#{escape value.to_s}'" }
119
+ else
120
+ "'#{escape args}'"
121
+ end
122
+ end
123
+
124
+ def step_name(step)
125
+ step.keyword + step.name.gsub(/"(.*?)"/, '\0')
126
+ end
127
+ end
128
+ end
@@ -8,7 +8,10 @@ module Gurke
8
8
  end
9
9
 
10
10
  def reporter
11
- @reporter ||= Reporters::DefaultReporter.new
11
+ @reporter ||= begin
12
+ r = (options[:formatter] + '_reporter').split('_').map(&:capitalize).join
13
+ Reporters.const_get(r).new
14
+ end
12
15
  end
13
16
 
14
17
  def builder
@@ -16,10 +16,11 @@ module Gurke
16
16
  end
17
17
 
18
18
  def match(name, type = :any)
19
+ return if self.type != :any && self.type != type
20
+ return if pattern.is_a?(String) && name != pattern
19
21
  match = pattern.match(name)
20
22
 
21
23
  return unless match
22
- return if self.type != :any && self.type != type
23
24
 
24
25
  Match.new(method_name, match.to_a[1..-1])
25
26
  end
@@ -1,8 +1,8 @@
1
1
  module Gurke
2
2
  module VERSION
3
3
  MAJOR = 2
4
- MINOR = 1
5
- PATCH = 0
4
+ MINOR = 2
5
+ PATCH = 1
6
6
  STAGE = nil
7
7
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.').freeze
8
8
 
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Gurke::StepDefinition do
6
+ let(:pattern) { nil }
7
+ let(:step_definition) { described_class.new pattern }
8
+ subject { step_definition }
9
+
10
+ context '#match' do
11
+ context 'with regex' do
12
+ let(:pattern) { /dies ist (ein|zwei) regex/ }
13
+
14
+ it { expect(subject.match('dies ist ein regex')).to be_a(Gurke::StepDefinition::Match) }
15
+ it { expect(subject.match('dies ist zwei regex')).to be_a(Gurke::StepDefinition::Match) }
16
+ end
17
+
18
+ context 'with string' do
19
+ let(:pattern) { 'a string' }
20
+
21
+ it { expect(subject.match('a string')).to be_a(Gurke::StepDefinition::Match) }
22
+ it { expect(subject.match(' a string')).to be_nil }
23
+ it { expect(subject.match('a string ')).to be_nil }
24
+ it { expect(subject.match(' a string ')).to be_nil }
25
+ end
26
+ end
27
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gurke
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen
@@ -74,6 +74,7 @@ executables:
74
74
  extensions: []
75
75
  extra_rdoc_files: []
76
76
  files:
77
+ - CHANGELOG.md
77
78
  - LICENSE.txt
78
79
  - README.md
79
80
  - bin/gurke
@@ -81,7 +82,9 @@ files:
81
82
  - features/gurke.rb
82
83
  - features/gurke/backtrace_filtering.feature
83
84
  - features/gurke/filter_by_tags.feature
85
+ - features/gurke/other_reporter.feature
84
86
  - features/gurke/pending_steps.feature
87
+ - features/gurke/run_specific_directories.feature
85
88
  - features/gurke/run_specific_scenarios.feature
86
89
  - features/gurke/step_specific_definitions.feature
87
90
  - features/support/steps/cli_steps.rb
@@ -99,6 +102,7 @@ files:
99
102
  - lib/gurke/reporter.rb
100
103
  - lib/gurke/reporters/default_reporter.rb
101
104
  - lib/gurke/reporters/null_reporter.rb
105
+ - lib/gurke/reporters/team_city_reporter.rb
102
106
  - lib/gurke/rspec.rb
103
107
  - lib/gurke/run_list.rb
104
108
  - lib/gurke/runner.rb
@@ -111,6 +115,7 @@ files:
111
115
  - spec/gurke/feature_list_spec.rb
112
116
  - spec/gurke/run_list_spec.rb
113
117
  - spec/gurke/scenario_spec.rb
118
+ - spec/gurke/step_definition_spec.rb
114
119
  - spec/spec_helper.rb
115
120
  homepage: https://github.com/jgraichen/gurke
116
121
  licenses:
@@ -141,7 +146,9 @@ test_files:
141
146
  - features/gurke.rb
142
147
  - features/gurke/backtrace_filtering.feature
143
148
  - features/gurke/filter_by_tags.feature
149
+ - features/gurke/other_reporter.feature
144
150
  - features/gurke/pending_steps.feature
151
+ - features/gurke/run_specific_directories.feature
145
152
  - features/gurke/run_specific_scenarios.feature
146
153
  - features/gurke/step_specific_definitions.feature
147
154
  - features/support/steps/cli_steps.rb
@@ -149,5 +156,6 @@ test_files:
149
156
  - spec/gurke/feature_list_spec.rb
150
157
  - spec/gurke/run_list_spec.rb
151
158
  - spec/gurke/scenario_spec.rb
159
+ - spec/gurke/step_definition_spec.rb
152
160
  - spec/spec_helper.rb
153
161
  has_rdoc: