spreewald 1.5.5 → 1.6.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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +113 -97
  3. data/Rakefile +3 -3
  4. data/bin/spreewald +64 -23
  5. data/features/binary.feature +246 -0
  6. data/features/support/aruba.rb +1 -0
  7. data/lib/spreewald/web_steps.rb +1 -3
  8. data/lib/spreewald_support/version.rb +1 -1
  9. data/spreewald.gemspec +10 -0
  10. data/support/parser.rb +25 -0
  11. data/support/paths_manager.rb +35 -0
  12. data/support/step_definition.rb +46 -0
  13. data/support/step_definition_file.rb +50 -0
  14. data/support/step_manager.rb +32 -0
  15. data/tests/rails-2.3/app +1 -0
  16. data/tests/rails-2.3/config/cucumber.yml +1 -0
  17. data/tests/rails-2.3/config/database.yml +1 -0
  18. data/tests/rails-2.3/db +1 -0
  19. data/tests/rails-2.3/features/shared +1 -0
  20. data/tests/rails-2.3/features/support/paths.rb +1 -0
  21. data/tests/rails-2.3/features/support/selectors.rb +1 -0
  22. data/tests/rails-2.3/public +1 -0
  23. data/tests/rails-3.2/capybara-1/app +1 -0
  24. data/tests/rails-3.2/capybara-1/config/cucumber.yml +1 -0
  25. data/tests/rails-3.2/capybara-1/config/database.yml +1 -0
  26. data/tests/rails-3.2/capybara-1/db +1 -0
  27. data/tests/rails-3.2/capybara-1/features/shared +1 -0
  28. data/tests/rails-3.2/capybara-1/features/support/paths.rb +1 -0
  29. data/tests/rails-3.2/capybara-1/features/support/selectors.rb +1 -0
  30. data/tests/rails-3.2/capybara-1/public +1 -0
  31. data/tests/rails-3.2/capybara-2/Rakefile +1 -0
  32. data/tests/rails-3.2/capybara-2/app +1 -0
  33. data/tests/rails-3.2/capybara-2/config +1 -0
  34. data/tests/rails-3.2/capybara-2/db +1 -0
  35. data/tests/rails-3.2/capybara-2/features +1 -0
  36. data/tests/rails-3.2/capybara-2/public +1 -0
  37. metadata +165 -67
  38. data/support/documentation_generator.rb +0 -119
  39. data/tests/rails-2.3/config/cucumber.yml +0 -2
  40. data/tests/rails-2.3/config/database.yml +0 -3
  41. data/tests/rails-2.3/features/support/paths.rb +0 -16
  42. data/tests/rails-2.3/features/support/selectors.rb +0 -43
  43. data/tests/rails-3.2/capybara-1/config/cucumber.yml +0 -2
  44. data/tests/rails-3.2/capybara-1/config/database.yml +0 -3
  45. data/tests/rails-3.2/capybara-1/features/support/paths.rb +0 -16
  46. data/tests/rails-3.2/capybara-1/features/support/selectors.rb +0 -43
  47. data/tests/rails-3.2/capybara-2/Rakefile +0 -18
data/Rakefile CHANGED
@@ -7,15 +7,15 @@ task :default => 'all:rubies'
7
7
  desc 'Update the "Steps" section of the README'
8
8
  task :update_readme do
9
9
  if Kernel.respond_to? :require_relative
10
- require_relative './support/documentation_generator'
10
+ require_relative './support/step_manager'
11
11
  else
12
- require 'support/documentation_generator'
12
+ require 'support/step_manager'
13
13
  end
14
14
 
15
15
  readme = File.read('README.md')
16
16
  start_of_steps_section = readme =~ /^## Steps/
17
17
  length_of_steps_section = (readme[(start_of_steps_section+1)..-1] =~ /^##[^#]/) || readme.size - start_of_steps_section
18
- readme[start_of_steps_section, length_of_steps_section] = "## Steps\n\n" + DocumentationGenerator::StepDefinitionsDirectory.new('lib/spreewald').format
18
+ readme[start_of_steps_section, length_of_steps_section] = "## Steps\n\n" + StepManager.new('lib/spreewald').to_markdown
19
19
  File.open('README.md', 'w') { |f| f.write(readme) }
20
20
  end
21
21
 
data/bin/spreewald CHANGED
@@ -1,31 +1,72 @@
1
1
  #!/usr/bin/env ruby
2
- require File.expand_path('../../support/documentation_generator', __FILE__)
2
+ require File.expand_path('../../support/step_manager', __FILE__)
3
+ require File.expand_path('../../support/paths_manager', __FILE__)
3
4
 
4
- ORDERED_KINDS = %w[Given When Then]
5
- heading = 'All Spreewald steps'
6
- search_string = ARGV.shift
5
+ def announce(text)
6
+ puts "\e[4;34m\n# #{text}\e[0m" # blue underline
7
+ end
7
8
 
8
- # collect
9
- steps_glob = File.expand_path('../../lib/spreewald/*_steps.rb', __FILE__)
10
- step_names = `cat #{steps_glob}`.split($/).select { |line| line =~ /^\s*(Given|When|Then)/ }
9
+ case (option = ARGV.shift)
10
+ when '--selectors', '-s'
11
+ search = ARGV.join(' ')
12
+ manager = PathsManager.new('features/support/selectors.rb')
11
13
 
12
- # format
13
- step_names.map! do |step|
14
- DocumentationGenerator::StepDefinition.try_and_parse(step).format_definition
15
- end
14
+ heading = 'All selectors from features/support/selectors.rb'
15
+ heading << " containing '#{search}'" if search
16
16
 
17
- # sort
18
- step_names = step_names.sort_by do |step|
19
- step =~ /^(\w+)(.*)/
20
- [ORDERED_KINDS.index($1), $2]
21
- end
17
+ announce heading
18
+ puts manager.paths(search)
19
+
20
+ when '--paths', '-p'
21
+ search = ARGV.join(' ')
22
+ manager = PathsManager.new('features/support/paths.rb')
23
+
24
+ heading = 'All paths from features/support/paths.rb'
25
+ heading << " containing '#{search}'" if search
26
+
27
+ announce heading
28
+ puts manager.paths(search)
29
+
30
+ when '--help', '-h'
31
+
32
+ puts <<-HELP
33
+ USAGE:
34
+ spreewald [SEARCH]
35
+ List all Spreewald steps + all steps from the current project (run from
36
+ project root). Optionally filtered by SEARCH.
37
+
38
+ spreewald --paths [SEARCH]
39
+ List all paths from features/support/paths.rb, optionally filtered by SEARCH
40
+ Alias -p
41
+
42
+ spreewald --selectors [SEARCH]
43
+ List all paths from features/support/paths.rb, optionally filtered by SEARCH
44
+ Alias -s
45
+
46
+ spreewald --version
47
+ Print Spreewald's version and exit
48
+ Alias -v
49
+
50
+ spreewald --help
51
+ Print this help and exit
52
+ Alias -h
53
+
54
+ HELP
55
+
56
+ when '--version', '-v'
57
+ require File.expand_path('../../lib/spreewald_support/version', __FILE__)
58
+ puts "Spreewald #{ Spreewald::VERSION }"
59
+
60
+ else
61
+ search = [option].concat(ARGV).join(' ')
62
+ spreewald_steps = File.expand_path('../../lib/spreewald', __FILE__)
63
+ project_steps = 'features/step_definitions'
64
+ manager = StepManager.new(spreewald_steps, project_steps)
65
+
66
+ heading = 'All Spreewald steps'
67
+ heading << " containing '#{search}'" if search
22
68
 
23
- # filter
24
- if search_string
25
- heading << " containing '#{search_string}'"
26
- step_names = step_names.grep Regexp.new(search_string)
69
+ announce heading
70
+ puts manager.steps(search).map(&:to_s)
27
71
  end
28
72
 
29
- # Output
30
- puts "\e[4;34m\n# #{heading}\e[0m" # blue underline
31
- puts step_names
@@ -0,0 +1,246 @@
1
+ Feature: The `spreewald` binary
2
+
3
+ Scenario: Without arguments, it prints a list of all its steps
4
+ When I run `spreewald`
5
+ Then the output should contain "# All Spreewald steps"
6
+ And the output should contain "Then it should work"
7
+
8
+
9
+ Scenario: Filters the steps (by a multi-word string)
10
+ When I run `spreewald should not see`
11
+ Then the output should contain:
12
+ """
13
+ # All Spreewald steps containing 'should not see'
14
+ Then I should not see "..."
15
+ Then I should not see "..." in the HTML
16
+ Then I should not see /.../
17
+ """
18
+ But the output should not contain "Then I should see"
19
+ And the output should not contain "mail"
20
+
21
+
22
+ Scenario: Steps from the local project directory are included
23
+ Given a file named "features/step_definitions/test_steps.rb" with:
24
+ """
25
+ Then /^there is a test step$/ do
26
+ # Just testing
27
+ end
28
+ """
29
+ And a file named "features/step_definitions/nested/nested_steps.rb" with:
30
+ """
31
+ Then /^there is a nested test step$/ do
32
+ # Nested step testing
33
+ end
34
+ """
35
+
36
+ When I run `spreewald`
37
+ Then the output should contain "Then there is a test step"
38
+ And the output should contain "Then there is a nested test step"
39
+
40
+
41
+ Scenario: It humanizes the step expressions
42
+ Given a file named "features/step_definitions/test_steps.rb" with:
43
+ """
44
+ Then(/it strips parentheses/) do
45
+ Then /^(?:|I )should see \/([^\/]*)\/$/ do
46
+ Then(/^the "(.*?)" field should (not )?contain:$/) do
47
+ """
48
+
49
+ When I run `spreewald`
50
+ Then the output should contain "Then it strips parentheses"
51
+ And the output should contain "Then I should see /.../"
52
+ And the output should contain:
53
+ """
54
+ Then the "..." field should (not )?contain:
55
+ """
56
+
57
+
58
+ Scenario: Listing paths from paths.rb (full example)
59
+ Given a file named "features/support/paths.rb" with:
60
+ """
61
+ module PathHelpers
62
+
63
+ def path_to(page_name)
64
+ case page_name
65
+
66
+ when /^regex (with|optional parts)$/
67
+ root_path
68
+ when /^simple regex$/
69
+ albums_path
70
+
71
+ when 'single quoted path'
72
+ admin_path anchor: '/videos_overview'
73
+
74
+ when "double quoted path"
75
+ admin_path anchor: '/photos_overview'
76
+
77
+ when /^the admin( .+)? (page|form) for the (.+) above$/
78
+ # Some path
79
+
80
+ when /^the path "(.+)"$/
81
+ $1
82
+
83
+ # Examples:
84
+ # the album collection above
85
+ when /^the (.+) above$/
86
+
87
+ else
88
+ raise "Unknown page: #{page_name.inspect}"
89
+ end
90
+ end
91
+
92
+ end
93
+ World(PathHelpers)
94
+ """
95
+
96
+ When I run `spreewald --paths`
97
+ Then the output should contain "All paths from features/support/paths.rb"
98
+ And the output should contain:
99
+ """
100
+ regex (with|optional parts)
101
+ simple regex
102
+ single quoted path
103
+ double quoted path
104
+ the admin( ...)? (page|form) for the ... above
105
+ the path "..."
106
+ the ... above
107
+ """
108
+
109
+
110
+ Scenario: Filtering paths
111
+ Given a file named "features/support/paths.rb" with:
112
+ """
113
+ when 'only quoted'
114
+ when 'single quoted path'
115
+ when "double quoted path"
116
+ """
117
+
118
+ When I run `spreewald --paths only`
119
+ Then the output should contain "All paths from features/support/paths.rb containing 'only'"
120
+ And the output should contain "only quoted"
121
+ But the output should not contain "single quoted path"
122
+ And the output should not contain "double quoted path"
123
+
124
+ # Support for multi-word filtering
125
+ When I run `spreewald --paths quoted path`
126
+ Then the output should contain "All paths from features/support/paths.rb containing 'quoted path'"
127
+ And the output should contain "single quoted path"
128
+ And the output should contain "double quoted path"
129
+ But the output from "spreewald --paths quoted path" should not contain "only quoted"
130
+
131
+
132
+ Scenario: List paths with short option "-p"
133
+ Given a file named "features/support/paths.rb" with:
134
+ """
135
+ when 'single quoted path'
136
+ """
137
+
138
+ When I run `spreewald -p`
139
+ Then the output should contain "All paths from features/support/paths.rb"
140
+ And the output should contain "single quoted path"
141
+
142
+
143
+ Scenario: List selectors from selectors.rb
144
+ Given a file named "features/support/selectors.rb" with:
145
+ """
146
+ module HtmlSelectorsHelpers
147
+ def selector_for(locator)
148
+ case locator
149
+
150
+ when /^simple regex$/
151
+ '.simple-regex'
152
+
153
+ when 'single quoted selector'
154
+ '.single-quoted-selector'
155
+
156
+ when "double quoted selector"
157
+ '.double-quoted-selector'
158
+
159
+ when /^the(?: (\d+)(?:st|nd|rd|th))? (.+) page item$/
160
+ # e.g. the frontend page items
161
+
162
+ when /^the (\d+)(st|nd|rd|th) gallery row$/
163
+ ".gallery .row:nth-of-type(#{$1})"
164
+
165
+ # Auto-mapper for BEM classes
166
+ # E.g. the slider's item that is current
167
+ when /^the (.+?)(?:'s? (.+?))?(?: that (.+))?$/
168
+ # Something
169
+
170
+ when /^"(.+)"$/
171
+ $1
172
+
173
+ else
174
+ raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
175
+ "Now, go and add a mapping in #{__FILE__}"
176
+ end
177
+ end
178
+ end
179
+ """
180
+
181
+ When I run `spreewald --selectors`
182
+ Then the output should contain "All selectors from features/support/selectors.rb"
183
+ And the output should contain:
184
+ """
185
+ simple regex
186
+ single quoted selector
187
+ double quoted selector
188
+ the( <nth>)? ... page item
189
+ the <nth> gallery row
190
+ the ...('s? ...)?( that ...)?
191
+ "..."
192
+ """
193
+
194
+
195
+ Scenario: Filtering selectors
196
+ Given a file named "features/support/paths.rb" with:
197
+ """
198
+ when 'only quoted'
199
+ when 'single quoted selector'
200
+ when "double quoted selector"
201
+ """
202
+
203
+ When I run `spreewald --paths only`
204
+ Then the output should contain "All paths from features/support/paths.rb containing 'only'"
205
+ And the output should contain "only quoted"
206
+ But the output should not contain "single quoted selector"
207
+ And the output should not contain "double quoted selector"
208
+
209
+ # Support for multi-word filtering
210
+ When I run `spreewald --paths quoted selector`
211
+ Then the output should contain "All paths from features/support/paths.rb containing 'quoted selector'"
212
+ And the output should contain "single quoted selector"
213
+ And the output should contain "double quoted selector"
214
+ But the output from "spreewald --paths quoted selector" should not contain "only quoted"
215
+
216
+
217
+ Scenario: List selectors with short option "-s"
218
+ Given a file named "features/support/selectors.rb" with:
219
+ """
220
+ when 'single quoted selector'
221
+ """
222
+
223
+ When I run `spreewald -s`
224
+ Then the output should contain "All selectors from features/support/selectors.rb"
225
+ And the output should contain "single quoted selector"
226
+
227
+
228
+ Scenario: Print help
229
+ When I run `spreewald --help`
230
+ Then the output should contain:
231
+ """
232
+ USAGE:
233
+ spreewald [SEARCH]
234
+ """
235
+ And the output should contain "spreewald --paths"
236
+ And the output should contain "spreewald --selectors"
237
+ And the output should contain "spreewald --version"
238
+ And the output should contain "spreewald --help"
239
+
240
+
241
+ Scenario: Print version
242
+ When I run `spreewald --version`
243
+ Then the output should contain "Spreewald 1."
244
+
245
+ When I run `spreewald -v`
246
+ Then the output should contain "Spreewald 1."
@@ -0,0 +1 @@
1
+ require 'aruba/cucumber'
@@ -268,7 +268,6 @@ Then /^the "([^"]*)" field should have no error$/ do |field|
268
268
  end
269
269
  end.overridable
270
270
 
271
- # nodoc
272
271
  Then /^the "([^"]*)" checkbox should( not)? be checked$/ do |label, negate|
273
272
  expectation = negate ? :should_not : :should
274
273
 
@@ -353,7 +352,7 @@ Then /^"([^"]*)" should be selected for "([^"]*)"$/ do |value, field|
353
352
  step %(the "#{field}" field should contain "#{value}")
354
353
  end.overridable
355
354
 
356
- Then /^nothing should be selected for "([^"]*)"?$/ do |field|
355
+ Then /^nothing should be selected for "([^"]*)"$/ do |field|
357
356
  patiently do
358
357
  select = find_field(field)
359
358
  begin
@@ -404,7 +403,6 @@ Then /^I should see an error$/ do
404
403
  (400 .. 599).should include(page.status_code)
405
404
  end.overridable
406
405
 
407
- #nodoc
408
406
  Then /^the window should be titled "([^"]*)"$/ do |title|
409
407
  patiently do
410
408
  page.should have_css('title', :text => title)
@@ -1,3 +1,3 @@
1
1
  module Spreewald
2
- VERSION = '1.5.5'
2
+ VERSION = '1.6.0'
3
3
  end
data/spreewald.gemspec CHANGED
@@ -19,4 +19,14 @@ Gem::Specification.new do |gem|
19
19
 
20
20
  gem.add_dependency('cucumber')
21
21
  gem.add_dependency('cucumber_priority')
22
+
23
+ # Development
24
+ gem.add_development_dependency 'bundler', '~> 1.11'
25
+ gem.add_development_dependency 'rake'
26
+ gem.add_development_dependency 'pry'
27
+
28
+ # Testing
29
+ gem.add_development_dependency 'aruba', '~> 0.10.2'
30
+ gem.add_development_dependency 'guard-cucumber'
31
+ gem.add_development_dependency 'rspec', '~> 3.4.0'
22
32
  end
data/support/parser.rb ADDED
@@ -0,0 +1,25 @@
1
+ class Parser
2
+
3
+ ANYTHINGS = %w[([^\"]*) ([^"]+) ([^"]*) (.*) (.*?) [^"]+ ([^\"]+) ([^']*)
4
+ ([^\/]*) (.+) (.*[^:]) (.+?) .+].map &Regexp.method(:escape)
5
+
6
+ def self.human_regex(regex)
7
+ regex.
8
+ sub(/^\(?\/\^?/, ''). # Strip Regex beginning
9
+ sub(/\$?\/\)?$/, ''). # Strip Regex end
10
+ gsub(' ?', ' ').
11
+ gsub('(?:|I )', 'I ').
12
+ gsub('(?:', '(').
13
+ gsub(Regexp.new(Regexp.escape '(\d+)(st|nd|rd|th)'), '<nth>').
14
+ gsub(Regexp.new(ANYTHINGS.join '|'), '...').
15
+ gsub(/\\\//, '/')
16
+ end
17
+
18
+ def self.format_comment(comment)
19
+ comment.gsub! /.*coding:.*UTF-8.*/, ''
20
+ comment.strip!
21
+ comment_lines = comment.split("\n").take_while { |line| line =~ /^\s*#/ }
22
+ comment_lines && comment_lines.join("\n").gsub(/^\s*# ?/, '')
23
+ end
24
+
25
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path('../parser', __FILE__)
2
+
3
+ class PathsManager
4
+
5
+ def initialize(file_path)
6
+ @file_path = file_path
7
+ read_paths
8
+ end
9
+
10
+ def paths(search = nil)
11
+ paths = @raw_paths.map do |raw_path|
12
+ path = raw_path.sub(/^\s+when/, '').strip
13
+
14
+ if path.start_with? '/'
15
+ Parser.human_regex(path)
16
+ else
17
+ path.gsub /\A["']|["']\z/, ''
18
+ end
19
+ end
20
+
21
+ paths.reject do |path|
22
+ if search
23
+ path !~ Regexp.new(search)
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def read_paths
31
+ lines = File.readlines @file_path
32
+ @raw_paths = lines.grep /^\s*when /
33
+ end
34
+
35
+ end