cucumberator 0.0.8 → 1.0.0

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