gurke 2.0.0.dev.1.b25 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: