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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +7 -0
- data/README.md +21 -11
- data/cucumberator.gemspec +7 -3
- data/features/cucumberize.feature +39 -0
- data/features/exit_all.feature +28 -0
- data/features/force_save.feature +31 -0
- data/features/help.feature +33 -0
- data/features/last_step.feature +23 -0
- data/features/next.feature +38 -0
- data/features/save.feature +88 -0
- data/features/simple_hook.feature +29 -0
- data/features/steps.feature +31 -0
- data/features/support/env.rb +5 -0
- data/features/undo.feature +89 -0
- data/features/where.feature +55 -0
- data/lib/cucumberator.rb +5 -4
- data/lib/cucumberator/commands.rb +14 -0
- data/lib/cucumberator/commands/exit.rb +10 -0
- data/lib/cucumberator/commands/exit_all.rb +11 -0
- data/lib/cucumberator/commands/help.rb +23 -0
- data/lib/cucumberator/commands/last_step.rb +9 -0
- data/lib/cucumberator/commands/next.rb +39 -0
- data/lib/cucumberator/commands/save.rb +80 -0
- data/lib/cucumberator/commands/steps.rb +19 -0
- data/lib/cucumberator/commands/undo.rb +27 -0
- data/lib/cucumberator/commands/where.rb +33 -0
- data/lib/cucumberator/current_step.rb +10 -6
- data/lib/cucumberator/feature_file.rb +27 -0
- data/lib/cucumberator/input.rb +42 -0
- data/lib/cucumberator/parser.rb +61 -0
- data/lib/cucumberator/step_line.rb +29 -0
- data/lib/cucumberator/steps.rb +20 -0
- data/lib/cucumberator/version.rb +1 -1
- metadata +53 -11
- data/lib/cucumberator/writer.rb +0 -260
@@ -0,0 +1,89 @@
|
|
1
|
+
Feature: undo
|
2
|
+
Background:
|
3
|
+
Given a file named "examples/support/env.rb" with:
|
4
|
+
"""
|
5
|
+
require 'cucumberator'
|
6
|
+
"""
|
7
|
+
Given a file named "examples/step_definitions/extra.rb" with:
|
8
|
+
"""
|
9
|
+
When(/I do some magical stuff with '(\w+)'/) do |*args|
|
10
|
+
# just example
|
11
|
+
end
|
12
|
+
|
13
|
+
"""
|
14
|
+
Given a file named "examples/undo.feature" with:
|
15
|
+
"""
|
16
|
+
Feature: example
|
17
|
+
Scenario: stop where exit
|
18
|
+
When I do some magical stuff with 'apples'
|
19
|
+
Then I will write new steps
|
20
|
+
|
21
|
+
"""
|
22
|
+
|
23
|
+
Scenario: no undo available
|
24
|
+
When I run `cucumber examples/undo.feature` interactively
|
25
|
+
And I type "undo"
|
26
|
+
And I type "exit"
|
27
|
+
Then it should pass with:
|
28
|
+
"""
|
29
|
+
There's nothing to revert yet
|
30
|
+
"""
|
31
|
+
|
32
|
+
Scenario: simple undo
|
33
|
+
When I run `cucumber examples/undo.feature` interactively
|
34
|
+
And I type "When I do some magical stuff with 'water'"
|
35
|
+
And I type "undo"
|
36
|
+
And I type "exit"
|
37
|
+
Then it should pass with:
|
38
|
+
"""
|
39
|
+
Saved `When I do some magical stuff with 'water'` to undo.feature
|
40
|
+
"""
|
41
|
+
And it should pass with:
|
42
|
+
"""
|
43
|
+
Removed `When I do some magical stuff with 'water'` from undo.feature
|
44
|
+
"""
|
45
|
+
And the file "examples/undo.feature" should contain exactly:
|
46
|
+
"""
|
47
|
+
Feature: example
|
48
|
+
Scenario: stop where exit
|
49
|
+
When I do some magical stuff with 'apples'
|
50
|
+
Then I will write new steps
|
51
|
+
|
52
|
+
"""
|
53
|
+
|
54
|
+
Scenario: multiple undo
|
55
|
+
When I run `cucumber examples/undo.feature` interactively
|
56
|
+
And I type "When I do some magical stuff with 'water'"
|
57
|
+
And I type "When I do some magical stuff with 'fire'"
|
58
|
+
And I type "undo"
|
59
|
+
And I type "undo"
|
60
|
+
And I type "undo"
|
61
|
+
And I type "exit"
|
62
|
+
Then it should pass with:
|
63
|
+
"""
|
64
|
+
Saved `When I do some magical stuff with 'water'` to undo.feature
|
65
|
+
"""
|
66
|
+
And it should pass with:
|
67
|
+
"""
|
68
|
+
Saved `When I do some magical stuff with 'fire'` to undo.feature
|
69
|
+
"""
|
70
|
+
And it should pass with:
|
71
|
+
"""
|
72
|
+
Removed `When I do some magical stuff with 'water'` from undo.feature
|
73
|
+
"""
|
74
|
+
And it should pass with:
|
75
|
+
"""
|
76
|
+
Removed `When I do some magical stuff with 'fire'` from undo.feature
|
77
|
+
"""
|
78
|
+
And it should pass with:
|
79
|
+
"""
|
80
|
+
There's nothing to revert yet
|
81
|
+
"""
|
82
|
+
And the file "examples/undo.feature" should contain exactly:
|
83
|
+
"""
|
84
|
+
Feature: example
|
85
|
+
Scenario: stop where exit
|
86
|
+
When I do some magical stuff with 'apples'
|
87
|
+
Then I will write new steps
|
88
|
+
|
89
|
+
"""
|
@@ -0,0 +1,55 @@
|
|
1
|
+
Feature: it should display the code around
|
2
|
+
Background:
|
3
|
+
Given a file named "examples/support/env.rb" with:
|
4
|
+
"""
|
5
|
+
require 'cucumberator'
|
6
|
+
"""
|
7
|
+
Given a file named "examples/step_definitions/extra.rb" with:
|
8
|
+
"""
|
9
|
+
When(/I do some magical stuff with "(\w+)"/) do |*args|
|
10
|
+
# just example
|
11
|
+
end
|
12
|
+
"""
|
13
|
+
|
14
|
+
Scenario: display code for simple scenario
|
15
|
+
Given a file named "examples/where.feature" with:
|
16
|
+
"""
|
17
|
+
Feature: example
|
18
|
+
Scenario: stop where exit
|
19
|
+
Then I will write new steps
|
20
|
+
|
21
|
+
"""
|
22
|
+
When I run `cucumber examples/where.feature` interactively
|
23
|
+
And I type "where"
|
24
|
+
And I type "exit"
|
25
|
+
Then it should pass with:
|
26
|
+
"""
|
27
|
+
2: Scenario: stop where exit
|
28
|
+
"""
|
29
|
+
And the output should contain "3: -> Then I will write new steps"
|
30
|
+
And the output should contain "4:"
|
31
|
+
|
32
|
+
Scenario: display code for larger scenario
|
33
|
+
Given a file named "examples/where_bigger.feature" with:
|
34
|
+
"""
|
35
|
+
Feature: example
|
36
|
+
Scenario: stop where exit
|
37
|
+
When I do some magical stuff with "apples"
|
38
|
+
And I do some magical stuff with "oranges"
|
39
|
+
And I do some magical stuff with "raspberries"
|
40
|
+
Then I will write new steps
|
41
|
+
And I do some magical stuff with "bananas"
|
42
|
+
And I do some magical stuff with "salad"
|
43
|
+
"""
|
44
|
+
When I run `cucumber examples/where_bigger.feature` interactively
|
45
|
+
And I type "where"
|
46
|
+
And I type "exit"
|
47
|
+
Then it should pass with:
|
48
|
+
"""
|
49
|
+
5: And I do some magical stuff with "raspberries"
|
50
|
+
"""
|
51
|
+
And the output should contain "6: -> Then I will write new steps"
|
52
|
+
Then it should pass with:
|
53
|
+
"""
|
54
|
+
7: And I do some magical stuff with "bananas"
|
55
|
+
"""
|
data/lib/cucumberator.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require "readline"
|
2
|
-
require
|
3
|
-
require
|
2
|
+
require 'cucumberator/current_step'
|
3
|
+
require 'cucumberator/input'
|
4
|
+
#require 'pry'
|
4
5
|
|
5
6
|
After('@cucumberize') do |scenario|
|
6
|
-
Cucumberator::
|
7
|
+
Cucumberator::Input.new(self, scenario)
|
7
8
|
end
|
8
9
|
|
9
10
|
Before do |scenario|
|
@@ -16,5 +17,5 @@ AfterStep do
|
|
16
17
|
end
|
17
18
|
|
18
19
|
Then /^I will write new steps$/ do
|
19
|
-
Cucumberator::
|
20
|
+
Cucumberator::Input.new(self, @current_cucumberator_scenario, @current_step.line)
|
20
21
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'cucumberator/commands/exit'
|
2
|
+
require 'cucumberator/commands/exit_all'
|
3
|
+
require 'cucumberator/commands/help'
|
4
|
+
require 'cucumberator/commands/where'
|
5
|
+
require 'cucumberator/commands/steps'
|
6
|
+
require 'cucumberator/commands/last_step'
|
7
|
+
require 'cucumberator/commands/save'
|
8
|
+
require 'cucumberator/commands/undo'
|
9
|
+
require 'cucumberator/commands/next'
|
10
|
+
|
11
|
+
# todo: magic!
|
12
|
+
module Cucumberator::Commands
|
13
|
+
AVAILABLE = %w(exit exit-all help last-step save undo next where steps)
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Cucumberator::Commands
|
2
|
+
class Help
|
3
|
+
class << self
|
4
|
+
# return value - wants to quit?
|
5
|
+
def perform(*args, &block)
|
6
|
+
puts ":: Write a step here and watch it happen on the browser."
|
7
|
+
puts ":: Steps are automatically saved unless it raises exception. Use 'save' to force-save it anyway."
|
8
|
+
puts ":: Available commands:"
|
9
|
+
puts ":: save - force-saves last step into current feature file"
|
10
|
+
puts ":: last-step - display last executed step (to be saved on 'save' command)"
|
11
|
+
puts ":: undo - remove last saved line from feature file"
|
12
|
+
puts ":: next - execute next step and stop"
|
13
|
+
puts ":: steps - display available steps"
|
14
|
+
puts ":: where - display current location in file"
|
15
|
+
puts ":: exit - exits current scenario"
|
16
|
+
puts ":: exit-all - exists whole Cucumber feature"
|
17
|
+
puts ":: help - display this notification"
|
18
|
+
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Cucumberator::Commands
|
2
|
+
class Next
|
3
|
+
class << self
|
4
|
+
def perform(scenario, step_line, *args, &block)
|
5
|
+
new(scenario, step_line).next_step
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(scenario, step_line)
|
10
|
+
@scenario, @step_line = scenario, step_line
|
11
|
+
@steps = Cucumberator::Steps.new(@scenario)
|
12
|
+
end
|
13
|
+
|
14
|
+
def next_step
|
15
|
+
if next_step = detect_next_step
|
16
|
+
puts next_step.backtrace_line
|
17
|
+
@steps.current_visitor.visit_step(next_step)
|
18
|
+
@step_line.set(next_step.file_colon_line.split(':').last.to_i)
|
19
|
+
false
|
20
|
+
else
|
21
|
+
puts ":: Looks like it's the end of feature file. Happy coding! <3"
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def detect_next_step
|
27
|
+
next_step = nil
|
28
|
+
|
29
|
+
@scenario.steps.each do |step|
|
30
|
+
if step.status == :skipped and not step.backtrace_line["Then I will write new steps"]
|
31
|
+
next_step = step
|
32
|
+
break
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
next_step
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Cucumberator::Commands
|
2
|
+
class Save
|
3
|
+
class << self
|
4
|
+
def perform(scenario, step_line, last_input, saved_stack, *args, &block)
|
5
|
+
new(scenario, step_line, last_input, saved_stack).save
|
6
|
+
false
|
7
|
+
end
|
8
|
+
|
9
|
+
def save_empty_line(scenario, step_line, saved_stack)
|
10
|
+
new(scenario, step_line, "", saved_stack).force_save_empty_line
|
11
|
+
false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :step_line, :saved_stack
|
16
|
+
|
17
|
+
def initialize(scenario, step_line, last_input, saved_stack)
|
18
|
+
@step_line, @last_input, @saved_stack = step_line, last_input, saved_stack
|
19
|
+
@feature_file = Cucumberator::FeatureFile.new(scenario)
|
20
|
+
end
|
21
|
+
|
22
|
+
def save
|
23
|
+
if @last_input.to_s.empty?
|
24
|
+
puts "Hm... nothing to save yet?"
|
25
|
+
else
|
26
|
+
string_to_save = (" " * spaces_in_last_input) + @last_input
|
27
|
+
save_to_feature_file(string_to_save)
|
28
|
+
|
29
|
+
puts "Saved `#{@last_input}` to #{@feature_file}"
|
30
|
+
@last_input = nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def force_save_empty_line
|
35
|
+
save_to_feature_file("")
|
36
|
+
@last_input = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def save_to_feature_file(line)
|
40
|
+
if step_line
|
41
|
+
insert_line_to_feature_file(line)
|
42
|
+
else
|
43
|
+
append_line_to_feature_file(line)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def insert_line_to_feature_file(line)
|
48
|
+
lines = @feature_file.lines
|
49
|
+
lines.insert(step_line - 1, line.to_s+$/) # $/ - default newline separator
|
50
|
+
@feature_file.overwrite(lines.join)
|
51
|
+
|
52
|
+
self.saved_stack << [step_line.number, line]
|
53
|
+
self.step_line.increment!
|
54
|
+
end
|
55
|
+
|
56
|
+
def append_line_to_feature_file(line)
|
57
|
+
@feature_file.append(line)
|
58
|
+
self.saved_stack << [@feature_file.lines.size, line]
|
59
|
+
end
|
60
|
+
|
61
|
+
def spaces_in_last_input
|
62
|
+
line = detect_last_line(@feature_file.lines)
|
63
|
+
spaces = line.to_s =~ /\S/
|
64
|
+
spaces.to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
def detect_last_line(lines)
|
68
|
+
if step_line
|
69
|
+
line = lines[step_line-1]
|
70
|
+
lines = lines.slice(0, step_line-1) if line.to_s.empty?
|
71
|
+
end
|
72
|
+
|
73
|
+
if line.to_s.empty?
|
74
|
+
line = lines.reverse.detect { |l| !l.to_s.empty? }
|
75
|
+
end
|
76
|
+
|
77
|
+
line
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Cucumberator::Commands
|
2
|
+
class Steps
|
3
|
+
class << self
|
4
|
+
def perform(scenario, *args, &block)
|
5
|
+
steps = all_steps(scenario)
|
6
|
+
if steps and steps.size > 0
|
7
|
+
puts ":: Yay, you have #{@steps.size} steps in your pocket:"
|
8
|
+
steps.each { |s| puts s }
|
9
|
+
else
|
10
|
+
puts ":: Sorry, no steps detected"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def all_steps(scenario)
|
15
|
+
@steps ||= Cucumberator::Steps.new(scenario).all
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Cucumberator::Commands
|
2
|
+
class Undo
|
3
|
+
class << self
|
4
|
+
def perform(scenario, step_line, last_input, saved_stack, *args, &block)
|
5
|
+
if saved_stack.empty?
|
6
|
+
puts "There's nothing to revert yet"
|
7
|
+
return false
|
8
|
+
end
|
9
|
+
|
10
|
+
new(scenario, step_line, saved_stack)
|
11
|
+
false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(scenario, step_line, saved_stack)
|
16
|
+
@feature_file = Cucumberator::FeatureFile.new(scenario)
|
17
|
+
lines = @feature_file.lines
|
18
|
+
|
19
|
+
remove_line, remove_string = saved_stack.pop
|
20
|
+
lines.delete_at(remove_line - 1)
|
21
|
+
@feature_file.overwrite(lines.join)
|
22
|
+
step_line.decrement!
|
23
|
+
|
24
|
+
puts "Removed `#{remove_string.to_s.strip}` from #{@feature_file}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Cucumberator::Commands
|
2
|
+
class Where
|
3
|
+
class << self
|
4
|
+
# return value - wants to quit?
|
5
|
+
def perform(scenario, step_line, *args, &block)
|
6
|
+
new(scenario, step_line)
|
7
|
+
false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(scenario, step_line)
|
12
|
+
@feature_file = Cucumberator::FeatureFile.new(scenario)
|
13
|
+
|
14
|
+
display_line(step_line - 1)
|
15
|
+
display_line(step_line.number, current: true)
|
16
|
+
display_line(step_line + 1)
|
17
|
+
end
|
18
|
+
|
19
|
+
def display_line(line_number, opts = {})
|
20
|
+
lines = @feature_file.lines
|
21
|
+
line_string = sprintf("%3d", line_number)
|
22
|
+
|
23
|
+
if opts[:current]
|
24
|
+
line_string << ": -> "
|
25
|
+
else
|
26
|
+
line_string << ": "
|
27
|
+
end
|
28
|
+
|
29
|
+
line_string << lines[line_number-1].to_s
|
30
|
+
puts line_string
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|