gurke 2.0.0.dev.1.b25 → 2.0.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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ODU3MmU4NTFmMzQ3ZWY1NDkwZDQyYTI5MWMyMzJjM2JkNWZmYzIyYg==
5
- data.tar.gz: !binary |-
6
- ODFhNjU4YzYwNTk5ZDlhYWEwYjdjNmMwOTJhYjM0ZmQ5NTFmMGE1NA==
2
+ SHA1:
3
+ metadata.gz: 8ebd0a6959baccc23f93332d2d2437b59dfb0742
4
+ data.tar.gz: 66ec55c6ffd3a9487115eee3c0dae66b326a6701
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YzNkODczMzkyM2NhZWExMzI2MWM0ODdjZDUzM2FlODJkZDdhZWU1NGQzNDli
10
- ODUwYzUwNTU2MzQxNDU1M2Y4MGQ2NDZjZjQyYzU3M2U3NTgyZjAyMjRmMTM2
11
- YTMyMTIzODE5Mzc2Yjk0YmFjODlkNzQ1ZTY3NDJkZTMwMzEzNDg=
12
- data.tar.gz: !binary |-
13
- NzcwNjdmZTNmMjkxOWY3MmRjODkxNTVjMGE3ZTE0M2MxMzhhNmNiYWQwOTQ4
14
- M2JhODhkZDMwMGRkYTMyZjhiYTQ1YjQwZmE2N2IwNzM2OWU1ZDkxNjk0OGU4
15
- OGUxNzE4ZjdjOTEzNjI0NGY3MWY1NmYzZThhY2ZjNjBlNTgxYzk=
6
+ metadata.gz: 90252df07209004f455cb6044ddc252a81a0e9d8f51c5eb54c05db80b9541c205908f6e6b4d7ecb50f270f503ca259df03403b622d019b9059594afdeeb49f26
7
+ data.tar.gz: a45350648d213fe996202271d31a601562b6f8eb0fb095ae4443610ae87e10ec207c7c3ec95f7051bd8ce0081f6061d9257ca27cc55083226465c784e873eba3
@@ -0,0 +1,93 @@
1
+ Feature: Run specific features or scenarios
2
+ In order to get faster test results
3
+ As a user
4
+ I want run only a specific set of files or lines
5
+
6
+ Background:
7
+ Given I am in a project using gurke
8
+ Given a file "features/a.feature" with the following content exists
9
+ """
10
+ Feature: F
11
+ Bla blub, a longer description.
12
+ Dadada.
13
+
14
+ Scenario: Scenario A1
15
+ Given I am "John"
16
+ When I am "John"
17
+ Then I am "John"
18
+
19
+ Scenario: Scenario A2
20
+ Given I am "John"
21
+ When I am "John"
22
+ Then I am "John"
23
+ """
24
+ Given a file "features/b.feature" with the following content exists
25
+ """
26
+ # Comment.
27
+ Feature: F
28
+ Bla blub, a longer description.
29
+
30
+ Dadada.
31
+
32
+ Scenario: Scenario B1
33
+ Given I am "John"
34
+ When I am "John"
35
+ Then I am "John"
36
+
37
+ Scenario: Scenario B2
38
+ Given I am "John"
39
+ When I am "John"
40
+ Then I am "John"
41
+
42
+ Scenario: Scenario B3
43
+ Given I am "John"
44
+ When I am "John"
45
+ Then I am "John"
46
+ """
47
+ And a file "features/support/steps/test_steps.rb" with the following content exists
48
+ """
49
+ require 'test/unit/assertions'
50
+
51
+ module Steps
52
+ include MiniTest::Assertions
53
+
54
+ Given(/^I am "(.+)"$/) do |name|
55
+ @me = name
56
+ end
57
+
58
+ When(/^I am "(.+)"$/) do |name|
59
+ @copy = @me
60
+ end
61
+
62
+ Then(/^I am "(.+)"$/) do |name|
63
+ assert name == @copy, "Expected #{name.inspect} but #{@me.inspect} given."
64
+ end
65
+ end
66
+ Gurke.world.send :include, Steps
67
+ """
68
+
69
+ Scenario: Run specific file (I)
70
+ When I execute "bundle exec gurke features/a.feature"
71
+ And the program output should include "2 scenarios: 0 failing, 0 pending"
72
+
73
+ Scenario: Run specific file (II)
74
+ When I execute "bundle exec gurke features/b.feature"
75
+ And the program output should include "3 scenarios: 0 failing, 0 pending"
76
+
77
+ Scenario: Run specific line of a scenario (I)
78
+ When I execute "bundle exec gurke features/b.feature:7"
79
+ And the program output should include "Scenario: Scenario B1"
80
+ And the program output should include "1 scenarios: 0 failing, 0 pending"
81
+
82
+ Scenario: Run specific line of a scenario (II)
83
+ When I execute "bundle exec gurke features/b.feature:7:19"
84
+ And the program output should include "Scenario: Scenario B1"
85
+ And the program output should include "Scenario: Scenario B3"
86
+ And the program output should include "2 scenarios: 0 failing, 0 pending"
87
+
88
+ Scenario: Run specific line of a scenario (III)
89
+ When I execute "bundle exec gurke features/a.feature:11 features/b.feature:7:19"
90
+ And the program output should include "Scenario: Scenario A2"
91
+ And the program output should include "Scenario: Scenario B1"
92
+ And the program output should include "Scenario: Scenario B3"
93
+ And the program output should include "3 scenarios: 0 failing, 0 pending"
@@ -5,12 +5,9 @@ module CLISteps
5
5
  def _execute(exec)
6
6
  Dir.chdir(@__root) do
7
7
  Bundler.with_clean_env do
8
- Open3.popen2e(exec) do |_, stdout_err, wait_thr|
9
- exit_status = wait_thr.value
10
- stdout_err = stdout_err.read
8
+ out, err, status = Open3.capture3('bash', '-lc', exec)
11
9
 
12
- @last_process = [exit_status.to_i, stdout_err]
13
- end
10
+ @last_process = [Integer(status), out, err]
14
11
  end
15
12
  end
16
13
  end
@@ -2,25 +2,42 @@ require 'gherkin'
2
2
 
3
3
  module Gurke
4
4
  class Builder
5
- attr_reader :features, :options
6
-
7
- def initialize(options)
8
- @options = options
9
- @features = FeatureList.new
5
+ attr_reader :features, :keywords
6
+
7
+ def initialize
8
+ # @options = options
9
+ # @files = files.map do |file|
10
+ # split = file.split(':')
11
+ # [split[0], split[1..-1].map{|l| Integer(l) }]
12
+ # end
10
13
  @language = 'en'
11
14
  @parser = Gherkin::Parser::Parser.new(
12
15
  self, true, 'root', false, @language)
16
+ end
13
17
 
14
- @keywords = {}
15
- Gherkin::I18n::LANGUAGES[@language].each do |k, v|
16
- v.split('|').map(&:strip).each do |str|
17
- @keywords[str] = k.to_sym if str != '*'
18
+ def keywords
19
+ @keywords ||= begin
20
+ keywords = {}
21
+ Gherkin::I18n::LANGUAGES[@language].each do |k, v|
22
+ v.split('|').map(&:strip).each do |str|
23
+ keywords[str] = k.to_sym if str != '*'
24
+ end
18
25
  end
26
+
27
+ keywords
19
28
  end
20
29
  end
21
30
 
22
- def parse(feature_file)
23
- @parser.parse(File.read(feature_file), feature_file, 0)
31
+ def load(files)
32
+ FeatureList.new.tap do |fl|
33
+ @features = fl
34
+
35
+ files.each do |file|
36
+ @parser.parse File.read(file), file, 0
37
+ end
38
+
39
+ @features = nil
40
+ end
24
41
  end
25
42
 
26
43
  def uri(raw)
@@ -52,7 +69,7 @@ module Gurke
52
69
  @context = @scenario
53
70
  @type = nil
54
71
 
55
- @feature.scenarios << @scenario unless filtered?(@scenario)
72
+ @feature.scenarios << @scenario #unless filtered?(@scenario)
56
73
  end
57
74
 
58
75
  def step(raw)
@@ -73,38 +90,12 @@ module Gurke
73
90
  private
74
91
 
75
92
  def lookup_type(keyword)
76
- case (kw = @keywords.fetch(keyword))
93
+ case (kw = keywords.fetch(keyword))
77
94
  when :and, :but
78
95
  @type
79
96
  else
80
97
  kw
81
98
  end
82
99
  end
83
-
84
- def filter_sets
85
- @filter_sets ||= options[:tags].map do |list|
86
- list.strip.split(/[,+\s]\s*/).map{|t| Filter.new(t) }
87
- end
88
- end
89
-
90
- def filtered?(scenario)
91
- !filter_sets.reduce(false) do |memo, set|
92
- memo || set.all?{|rule| rule.match? scenario }
93
- end
94
- end
95
-
96
- Filter = Struct.new(:tag) do
97
- def name
98
- @name ||= negated? ? tag[1..-1] : tag
99
- end
100
-
101
- def negated?
102
- tag[0] == '~'
103
- end
104
-
105
- def match?(taggable)
106
- negated? != taggable.tags.any?{|t| t.name == name }
107
- end
108
- end
109
100
  end
110
101
  end
@@ -69,8 +69,8 @@ module Gurke
69
69
  'filtering expression. TODO: Description.',
70
70
  default: ['~wip'],
71
71
  multi: true
72
- opt :drb_server, 'Run gurke DRb server.', short: :none
73
- opt :drb, 'Run features on already started DRb server.', short: :none
72
+ opt :drb_server, 'Run gurke DRb server. (experimental)', short: :none
73
+ opt :drb, 'Run features on already started DRb server. (experimental)', short: :none
74
74
  end
75
75
  end
76
76
  end
@@ -65,6 +65,16 @@ module Gurke
65
65
  scenarios.any?(&:pending?)
66
66
  end
67
67
 
68
+ def self.new(*args)
69
+ if args.size == 1 && (f = args.first).is_a?(self)
70
+ super f.file, f.line, f.tags, f.raw
71
+ else
72
+ super
73
+ end
74
+ end
75
+
76
+ # -----------------------------------------------------
77
+
68
78
  # @api private
69
79
  def run(runner, reporter)
70
80
  reporter.invoke :before_feature, self
@@ -22,6 +22,27 @@ module Gurke
22
22
  !any?{|s| s.failed? }
23
23
  end
24
24
 
25
+ # @api private
26
+ def filter(options, files)
27
+ list = FeatureList.new
28
+ filter = Filter.new options, files
29
+
30
+ each do |feature|
31
+ file, lines = files.select{|f, _| f == feature.file }.first
32
+ next unless file
33
+
34
+ f = Feature.new(feature)
35
+
36
+ feature.scenarios.each do |scenario|
37
+ f.scenarios << scenario unless filter.filtered?(scenario)
38
+ end
39
+
40
+ list << f if f.scenarios.any?
41
+ end
42
+
43
+ list
44
+ end
45
+
25
46
  private
26
47
 
27
48
  def run_features(runner, reporter)
@@ -33,5 +54,52 @@ module Gurke
33
54
  ensure
34
55
  reporter.invoke :end_features, self
35
56
  end
57
+
58
+ class Filter
59
+ attr_reader :options, :files
60
+
61
+ def initialize(options, files)
62
+ @options = options
63
+ @files = files
64
+ end
65
+
66
+ def tag_filters
67
+ @tag_filters ||= options[:tags].map do |list|
68
+ list.strip.split(/[,+\s]\s*/).map{|t| TagFilter.new(t) }
69
+ end
70
+ end
71
+
72
+ def filtered?(scenario)
73
+ filtered_by_tags?(scenario) || filtered_by_line?(scenario)
74
+ end
75
+
76
+ def filtered_by_tags?(scenario)
77
+ !tag_filters.reduce(false) do |memo, set|
78
+ memo || set.all?{|rule| rule.match? scenario }
79
+ end
80
+ end
81
+
82
+ def filtered_by_line?(scenario)
83
+ _, lines = files.select{|f, _| f == scenario.file }.first
84
+
85
+ return false if lines.empty?
86
+
87
+ !lines.any?{|l| scenario.line <= l && scenario.steps.last.line >= l }
88
+ end
89
+
90
+ TagFilter = Struct.new(:tag) do
91
+ def name
92
+ @name ||= negated? ? tag[1..-1] : tag
93
+ end
94
+
95
+ def negated?
96
+ tag[0] == '~'
97
+ end
98
+
99
+ def match?(taggable)
100
+ negated? != taggable.tags.any?{|t| t.name == name }
101
+ end
102
+ end
103
+ end
36
104
  end
37
105
  end
@@ -11,17 +11,18 @@ module Gurke
11
11
  @reporter ||= Reporters::DefaultReporter.new
12
12
  end
13
13
 
14
- def load_feature_set(files)
15
- builder = Builder.new options
16
- files.each{|f| builder.parse(f) }
17
-
18
- features = builder.features
19
- features.freeze
14
+ def builder
15
+ @builder ||= Builder.new
20
16
  end
21
17
 
22
18
  def run(files, reporter = self.reporter)
23
- features = load_feature_set files
24
- features.run self, reporter
19
+ files.map! do |file|
20
+ split = file.split(':')
21
+ [split[0], split[1..-1].map{|i| Integer(i) }]
22
+ end
23
+
24
+ features = builder.load files.map{|file, _| file }
25
+ features.filter(options, files).run self, reporter
25
26
  end
26
27
 
27
28
  def hook(scope, world, &block)
@@ -39,11 +40,9 @@ module Gurke
39
40
  end
40
41
 
41
42
  class LocalRunner < Runner
42
- def run(files, reporter = self.reporter)
43
- features = load_feature_set files
44
-
43
+ def run(*)
45
44
  hook :system, nil do
46
- features.run self, reporter
45
+ super
47
46
  end
48
47
  end
49
48
  end
@@ -3,7 +3,7 @@ module Gurke
3
3
  MAJOR = 2
4
4
  MINOR = 0
5
5
  PATCH = 0
6
- STAGE = :dev
6
+ STAGE = nil
7
7
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.').freeze
8
8
 
9
9
  def self.to_s
metadata CHANGED
@@ -1,71 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gurke
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.dev.1.b25
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Graichen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-05 00:00:00.000000000 Z
11
+ date: 2014-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trollop
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
15
20
  requirement: !ruby/object:Gem::Requirement
16
21
  requirements:
17
- - - ! '>='
22
+ - - '>='
18
23
  - !ruby/object:Gem::Version
19
24
  version: '0'
20
- type: :runtime
21
25
  prerelease: false
26
+ type: :runtime
27
+ - !ruby/object:Gem::Dependency
28
+ name: gherkin
22
29
  version_requirements: !ruby/object:Gem::Requirement
23
30
  requirements:
24
- - - ! '>='
31
+ - - '>='
25
32
  - !ruby/object:Gem::Version
26
33
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: gherkin
29
34
  requirement: !ruby/object:Gem::Requirement
30
35
  requirements:
31
- - - ! '>='
36
+ - - '>='
32
37
  - !ruby/object:Gem::Version
33
38
  version: '0'
34
- type: :runtime
35
39
  prerelease: false
40
+ type: :runtime
41
+ - !ruby/object:Gem::Dependency
42
+ name: colorize
36
43
  version_requirements: !ruby/object:Gem::Requirement
37
44
  requirements:
38
- - - ! '>='
45
+ - - '>='
39
46
  - !ruby/object:Gem::Version
40
47
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: colorize
43
48
  requirement: !ruby/object:Gem::Requirement
44
49
  requirements:
45
- - - ! '>='
50
+ - - '>='
46
51
  - !ruby/object:Gem::Version
47
52
  version: '0'
48
- type: :runtime
49
53
  prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
54
+ type: :runtime
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
- requirement: !ruby/object:Gem::Requirement
57
+ version_requirements: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.3'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
62
+ requirement: !ruby/object:Gem::Requirement
65
63
  requirements:
66
64
  - - ~>
67
65
  - !ruby/object:Gem::Version
68
66
  version: '1.3'
67
+ prerelease: false
68
+ type: :development
69
69
  description: An alternative gherkin feature runner inspired by rspec and turnip.
70
70
  email:
71
71
  - jg@altimos.de
@@ -82,6 +82,7 @@ files:
82
82
  - features/gurke/backtrace_filtering.feature
83
83
  - features/gurke/filter_by_tags.feature
84
84
  - features/gurke/pending_steps.feature
85
+ - features/gurke/run_specific_scenarios.feature
85
86
  - features/gurke/step_specific_definitions.feature
86
87
  - features/support/steps/cli_steps.rb
87
88
  - features/support/steps/file_steps.rb
@@ -115,24 +116,24 @@ homepage: https://github.com/jgraichen/gurke
115
116
  licenses:
116
117
  - MIT
117
118
  metadata: {}
118
- post_install_message:
119
+ post_install_message:
119
120
  rdoc_options: []
120
121
  require_paths:
121
122
  - lib
122
123
  required_ruby_version: !ruby/object:Gem::Requirement
123
124
  requirements:
124
- - - ! '>='
125
+ - - '>='
125
126
  - !ruby/object:Gem::Version
126
127
  version: '0'
127
128
  required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  requirements:
129
- - - ! '>'
130
+ - - '>='
130
131
  - !ruby/object:Gem::Version
131
- version: 1.3.1
132
+ version: '0'
132
133
  requirements: []
133
- rubyforge_project:
134
+ rubyforge_project:
134
135
  rubygems_version: 2.2.2
135
- signing_key:
136
+ signing_key:
136
137
  specification_version: 4
137
138
  summary: An alternative gherkin feature runner inspired by rspec and turnip.
138
139
  test_files:
@@ -141,6 +142,7 @@ test_files:
141
142
  - features/gurke/backtrace_filtering.feature
142
143
  - features/gurke/filter_by_tags.feature
143
144
  - features/gurke/pending_steps.feature
145
+ - features/gurke/run_specific_scenarios.feature
144
146
  - features/gurke/step_specific_definitions.feature
145
147
  - features/support/steps/cli_steps.rb
146
148
  - features/support/steps/file_steps.rb
@@ -148,3 +150,4 @@ test_files:
148
150
  - spec/gurke/run_list_spec.rb
149
151
  - spec/gurke/scenario_spec.rb
150
152
  - spec/spec_helper.rb
153
+ has_rdoc: