cucumberator 0.0.8 → 1.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.
@@ -1,19 +1,23 @@
1
+ require 'cucumberator/step_line'
2
+
1
3
  module Cucumberator
2
4
  class CurrentStep
3
5
  attr_accessor :line
4
6
 
5
7
  def initialize(scenario)
6
8
  @scenario_sexp = scenario.steps.to_sexp
9
+ @offset = 0
10
+ set_line
7
11
  end
8
12
 
9
13
  def increase
10
- if self.line
11
- @offset += 1
12
- else
13
- @offset = 0
14
- end
14
+ @offset += 1
15
+ set_line
16
+ end
15
17
 
16
- self.line = @scenario_sexp[@offset][1]
18
+ def set_line
19
+ current_sexp = @scenario_sexp[@offset]
20
+ self.line = Cucumberator::StepLine.new(current_sexp[1]) if current_sexp
17
21
  end
18
22
  end
19
23
  end
@@ -0,0 +1,27 @@
1
+ module Cucumberator
2
+ class FeatureFile
3
+ def initialize(scenario)
4
+ @scenario = scenario
5
+ end
6
+
7
+ def lines
8
+ File.readlines(file)
9
+ end
10
+
11
+ def file
12
+ @feature_file ||= File.join(Dir.pwd, @scenario.file_colon_line.split(":").first)
13
+ end
14
+
15
+ def to_s
16
+ File.basename(file)
17
+ end
18
+
19
+ def overwrite(contents)
20
+ File.open(file, 'w') { |f| f.puts(contents) }
21
+ end
22
+
23
+ def append(contents)
24
+ File.open(file, 'a') { |f| f.puts(contents) }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,42 @@
1
+ require 'cucumberator/parser'
2
+ require 'cucumberator/steps'
3
+
4
+ module Cucumberator
5
+ class Input
6
+ attr_accessor :world, :scenario, :step_line, :last_input, :exit_flag, :saved_stack
7
+
8
+ def initialize(world, scenario, step_line = nil)
9
+ @world, @scenario = world, scenario
10
+ @step_line = step_line if step_line
11
+ @saved_stack = []
12
+
13
+ check_scenario
14
+ set_autocomplete
15
+ read_input
16
+ end
17
+
18
+ def check_scenario
19
+ raise "Sorry, cucumberator is not available when scenario is already failing!" if scenario.failed?
20
+ end
21
+
22
+ def read_input
23
+ input = Readline.readline("> ", true)
24
+ exit_flag = Cucumberator::Parser.parse_input(input, scenario, step_line, world, saved_stack)
25
+ read_input unless exit_flag
26
+ end
27
+
28
+ def set_autocomplete
29
+ commands = Cucumberator::Commands::AVAILABLE
30
+
31
+ Cucumberator::Steps.new(scenario).all.each do |s|
32
+ # remove typical start/end regexp parts
33
+ step = s.gsub(/^\/\^|\$\/$/,'')
34
+ # every step is equal, no matter if When/Then/And, so combining everything for autocomplete
35
+ commands << "When #{step}" << "Then #{step}" << "And #{step}"
36
+ end
37
+
38
+ Readline.basic_word_break_characters = ""; # no break chars = no autobreaking for completion input
39
+ Readline.completion_proc = proc { |s| commands.grep( /^#{Regexp.escape(s)}/ ) }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,61 @@
1
+ require 'cucumberator/commands'
2
+ require 'cucumberator/feature_file'
3
+
4
+ module Cucumberator
5
+ class Parser
6
+ FULL_BACKTRACE = false # for debugging
7
+
8
+ class << self
9
+ attr_accessor :last_input
10
+
11
+ def parse_input(input, scenario, step_line, world, saved_stack)
12
+ if Cucumberator::Commands::AVAILABLE.include?(input)
13
+ runner = command_runner_for(input)
14
+ runner.perform(scenario, step_line, last_input, saved_stack)
15
+ elsif input == ""
16
+ Cucumberator::Commands::Save.save_empty_line(scenario, step_line, saved_stack)
17
+ else
18
+ try_to_execute(input, scenario, step_line, world, saved_stack)
19
+ false
20
+ end
21
+ end
22
+
23
+ def try_to_execute(input, scenario, step_line, world, saved_stack)
24
+ execute_cucumber_step(input, world)
25
+ Cucumberator::Commands::Save.perform(scenario, step_line, last_input, saved_stack)
26
+ rescue => e
27
+ puts e.inspect
28
+ puts e.backtrace.join("\n") if FULL_BACKTRACE
29
+ end
30
+
31
+ def command_runner_for(command)
32
+ full_klass_name = "Cucumberator::Commands::#{klass_name_for(command)}"
33
+ constantize(full_klass_name)
34
+ end
35
+
36
+ def klass_name_for(command)
37
+ command.scan(/\w+/).map(&:capitalize).join
38
+ end
39
+
40
+ def execute_cucumber_step(input, world)
41
+ return if input.to_s.empty?
42
+
43
+ self.last_input = input
44
+ world.steps(input)
45
+ end
46
+
47
+ # copied from ActiveSupport
48
+ # activesupport/lib/active_support/inflector/methods.rb
49
+ def constantize(camel_cased_word)
50
+ names = camel_cased_word.split('::')
51
+ names.shift if names.empty? || names.first.empty?
52
+
53
+ constant = Object
54
+ names.each do |name|
55
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
56
+ end
57
+ constant
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,29 @@
1
+ module Cucumberator
2
+ class StepLine
3
+ attr_accessor :number
4
+
5
+ def initialize(line)
6
+ @number = line.to_i
7
+ end
8
+
9
+ def -(other)
10
+ number - other.to_i
11
+ end
12
+
13
+ def +(other)
14
+ number + other.to_i
15
+ end
16
+
17
+ def set(other)
18
+ self.number = other.to_i
19
+ end
20
+
21
+ def increment!
22
+ self.number += 1
23
+ end
24
+
25
+ def decrement!
26
+ self.number -= 1
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,20 @@
1
+ module Cucumberator
2
+ class Steps
3
+ def initialize(scenario)
4
+ @scenario = scenario
5
+ end
6
+
7
+ def all
8
+ @steps ||= all_defined_steps
9
+ end
10
+
11
+ def all_defined_steps
12
+ support_code = current_visitor.runtime.instance_variable_get("@support_code")
13
+ support_code.step_definitions.map { |sd| sd.regexp_source }
14
+ end
15
+
16
+ def current_visitor
17
+ @current_visitor ||= @scenario.instance_variable_get("@current_visitor")
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module Cucumberator
2
- VERSION = "0.0.8"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumberator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vidmantas Kabošis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-14 00:00:00.000000000 Z
11
+ date: 2013-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -25,19 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
- name: cucumber-rails
28
+ name: aruba
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>'
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
34
- type: :runtime
33
+ version: 0.5.3
34
+ type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>'
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: '1.3'
40
+ version: 0.5.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  description: Prompt for writing Cucumber tests
42
56
  email:
43
57
  - vidmantas@kabosis.lt
@@ -46,15 +60,42 @@ extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
62
  - .gitignore
63
+ - .travis.yml
49
64
  - Gemfile
50
65
  - LICENSE
51
66
  - README.md
52
67
  - Rakefile
53
68
  - cucumberator.gemspec
69
+ - features/cucumberize.feature
70
+ - features/exit_all.feature
71
+ - features/force_save.feature
72
+ - features/help.feature
73
+ - features/last_step.feature
74
+ - features/next.feature
75
+ - features/save.feature
76
+ - features/simple_hook.feature
77
+ - features/steps.feature
78
+ - features/support/env.rb
79
+ - features/undo.feature
80
+ - features/where.feature
54
81
  - lib/cucumberator.rb
82
+ - lib/cucumberator/commands.rb
83
+ - lib/cucumberator/commands/exit.rb
84
+ - lib/cucumberator/commands/exit_all.rb
85
+ - lib/cucumberator/commands/help.rb
86
+ - lib/cucumberator/commands/last_step.rb
87
+ - lib/cucumberator/commands/next.rb
88
+ - lib/cucumberator/commands/save.rb
89
+ - lib/cucumberator/commands/steps.rb
90
+ - lib/cucumberator/commands/undo.rb
91
+ - lib/cucumberator/commands/where.rb
55
92
  - lib/cucumberator/current_step.rb
93
+ - lib/cucumberator/feature_file.rb
94
+ - lib/cucumberator/input.rb
95
+ - lib/cucumberator/parser.rb
96
+ - lib/cucumberator/step_line.rb
97
+ - lib/cucumberator/steps.rb
56
98
  - lib/cucumberator/version.rb
57
- - lib/cucumberator/writer.rb
58
99
  homepage: https://github.com/vidmantas/cucumberator
59
100
  licenses:
60
101
  - MIT
@@ -71,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
112
  requirements:
72
113
  - - '>='
73
114
  - !ruby/object:Gem::Version
74
- version: '0'
115
+ version: 1.9.3
75
116
  required_rubygems_version: !ruby/object:Gem::Requirement
76
117
  requirements:
77
118
  - - '>='
@@ -82,5 +123,6 @@ rubyforge_project:
82
123
  rubygems_version: 2.0.3
83
124
  signing_key:
84
125
  specification_version: 4
85
- summary: cucumberator-0.0.8
126
+ summary: cucumberator-1.0.0
86
127
  test_files: []
128
+ has_rdoc:
@@ -1,260 +0,0 @@
1
- module Cucumberator
2
- class Writer
3
- attr_accessor :world, :scenario, :step_line, :original_step_line, :last_input, :exit_flag, :saved_stack
4
-
5
- FULL_BACKTRACE = false
6
-
7
- def initialize(world, scenario, step_line = nil)
8
- @world, @scenario = world, scenario
9
- @step_line = @original_step_line = step_line if step_line
10
- @saved_stack = []
11
-
12
- check_scenario
13
- set_autocomplete
14
- read_input
15
- end
16
-
17
- def check_scenario
18
- raise "Sorry, cucumberator is not available when scenario is already failing!" if scenario.failed?
19
- end
20
-
21
- def set_autocomplete
22
- commands = %w(exit exit-all help last-step save undo next where whereami steps)
23
-
24
- @steps = all_defined_steps
25
- @steps.each do |s|
26
- # remove typical start/end regexp parts
27
- step = s.gsub(/^\/\^|\$\/$/,'')
28
- # every step is equal, no matter if When/Then/And, so combining everything for autocomplete
29
- commands << "When #{step}" << "Then #{step}" << "And #{step}"
30
- end
31
-
32
- Readline.basic_word_break_characters = ""; # no break chars = no autobreaking for completion input
33
- Readline.completion_proc = proc { |s| commands.grep( /^#{Regexp.escape(s)}/ ) }
34
- end
35
-
36
- def current_visitor
37
- @current_visitor ||= scenario.instance_variable_get("@current_visitor")
38
- end
39
-
40
- def all_defined_steps
41
- support_code = current_visitor.runtime.instance_variable_get("@support_code")
42
- support_code.step_definitions.map { |sd| sd.regexp_source }
43
- end
44
-
45
- def read_input
46
- input = Readline.readline("> ", true)
47
- parse_input(input)
48
- read_input unless exit_flag
49
- end
50
-
51
- def mark_exit(totally = false)
52
- Cucumber.wants_to_quit = true if totally
53
- self.exit_flag = true
54
- end
55
-
56
- def parse_input(input)
57
- case input
58
- when "exit"
59
- mark_exit and return
60
-
61
- when "exit-all"
62
- mark_exit(true)
63
-
64
- when "help"
65
- display_help
66
-
67
- when "last-step"
68
- puts last_input
69
-
70
- when "save"
71
- save_last_input
72
-
73
- when "undo"
74
- undo
75
-
76
- when "next"
77
- execute_next_step
78
-
79
- when "steps"
80
- display_steps
81
-
82
- when "where", "whereami"
83
- display_current_location
84
-
85
- when ""
86
- save_empty_line
87
-
88
- else
89
- begin
90
- execute_cucumber_step(input)
91
- save_last_input
92
- rescue Exception => e
93
- raise e
94
- end
95
-
96
- end
97
- rescue Exception => e
98
- puts e.inspect
99
- puts e.backtrace.join("\n") if FULL_BACKTRACE
100
- end
101
-
102
-
103
- ## COMMANDS
104
-
105
- def display_help
106
- puts ":: Write a step here and watch it happen on the browser."
107
- puts ":: Steps are automatically saved unless it raises exception. Use 'save' to force-save it anyway."
108
- puts ":: Available commands:"
109
- puts ":: save - force-saves last step into current feature file"
110
- puts ":: last-step - display last executed step (to be saved on 'save' command)"
111
- puts ":: undo - remove last saved line from feature file"
112
- puts ":: next - execute next step and stop"
113
- puts ":: steps - display available steps"
114
- puts ":: where - display current location in file"
115
- puts ":: exit - exits current scenario"
116
- puts ":: exit-all - exists whole Cucumber feature"
117
- puts ":: help - display this notification"
118
- end
119
-
120
- def save_last_input
121
- if last_input.blank?
122
- puts "Hm... nothing to save yet?"
123
- else
124
- string_to_save = (" " * spaces_in_last_input) + last_input
125
- save_to_feature_file(string_to_save)
126
-
127
- puts "Saved `#{last_input}` to #{File.basename(feature_file)}"
128
- self.last_input = nil
129
- end
130
- end
131
-
132
- def save_to_feature_file(string)
133
- if step_line
134
- lines = feature_file_lines
135
- lines.insert(step_line, string.to_s+$/) # $/ - default newline separator
136
- File.open(feature_file, 'w'){|f| f.puts(lines.join) }
137
- self.saved_stack << [step_line, string]
138
- self.step_line += 1
139
- else
140
- File.open(feature_file, 'a'){|f| f.puts(string) }
141
- self.saved_stack << [feature_file_lines.size, string]
142
- end
143
- end
144
-
145
- def save_empty_line
146
- save_to_feature_file("")
147
- self.last_input = nil
148
- end
149
-
150
- def execute_cucumber_step(input)
151
- return if input.blank?
152
-
153
- self.last_input = input
154
- world.steps(input)
155
- end
156
-
157
- def undo
158
- if saved_stack.empty?
159
- puts "There's nothing to revert yet"
160
- return
161
- end
162
-
163
- lines = feature_file_lines
164
-
165
- remove_line, remove_string = self.saved_stack.pop
166
- lines.delete_at(remove_line)
167
- File.open(feature_file, 'w') { |f| f.puts(lines.join) }
168
- self.step_line -= 1
169
-
170
- puts "Removed `#{remove_string.to_s.strip}` from #{File.basename(feature_file)}"
171
- end
172
-
173
- def display_current_location
174
- display_line(step_line - 1)
175
- display_line(step_line, current: true)
176
- display_line(step_line + 1)
177
- end
178
-
179
- def display_line(line_number, opts = {})
180
- lines = feature_file_lines
181
- line_string = sprintf("%3d", line_number)
182
-
183
- if opts[:current]
184
- line_string << ": -> "
185
- else
186
- line_string << ": "
187
- end
188
-
189
- line_string << lines[line_number]
190
- puts line_string
191
- end
192
-
193
- def execute_next_step
194
- next_step = detect_next_step
195
-
196
- if next_step
197
- puts next_step.backtrace_line
198
- current_visitor.visit_step(next_step)
199
- self.step_line = next_step.file_colon_line.split(':').last.to_i + 1
200
- else
201
- puts ":: Looks like it's the end of feature file. Happy coding! <3"
202
- mark_exit(true)
203
- end
204
- end
205
-
206
- def detect_next_step
207
- next_step = nil
208
-
209
- scenario.steps.each do |step|
210
- if step.status == :skipped and not step.backtrace_line["Then I will write new steps"]
211
- next_step = step
212
- break
213
- end
214
- end
215
-
216
- next_step
217
- end
218
-
219
- def feature_file_lines
220
- File.readlines(feature_file)
221
- end
222
-
223
- def display_steps
224
- if @steps and @steps.size > 0
225
- puts ":: Yay, you have #{@steps.size} steps in your pocket:"
226
- @steps.each { |s| puts s }
227
- else
228
- puts ":: Sorry, no steps detected?"
229
- end
230
- end
231
-
232
- ## HELPERS
233
-
234
- def feature_file
235
- @feature_file ||= File.join(Rails.root, scenario.file_colon_line.split(":").first)
236
- end
237
-
238
- def spaces_in_last_input
239
- lines = File.readlines(feature_file)
240
-
241
- if step_line
242
- line = lines[step_line-1]
243
- lines = lines.slice(0, step_line-1) if line.blank?
244
- end
245
-
246
- if line.blank?
247
- for l in lines.reverse
248
- unless l.blank?
249
- line = l
250
- break
251
- end
252
- end
253
- end
254
-
255
- spaces = line =~ /\S/
256
- spaces.to_i
257
- end
258
- end
259
-
260
- end