Class: Cucumber2RSpec::Step

Inherits:
Object
  • Object
show all
Defined in:
lib/cucumber2rspec/step.rb

Overview

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(scenario, cucumber_ast_step_invocation) ⇒ Step

Returns a new instance of Step.



32
33
34
35
# File 'lib/cucumber2rspec/step.rb', line 32

def initialize scenario, cucumber_ast_step_invocation
  @scenario = scenario
  @_step    = cucumber_ast_step_invocation # Cucumber::Ast::StepInvocation
end

Instance Attribute Details

#_stepObject (readonly)

Returns the value of attribute _step.



5
6
7
# File 'lib/cucumber2rspec/step.rb', line 5

def _step
  @_step
end

#scenarioObject (readonly)

Returns the value of attribute scenario.



5
6
7
# File 'lib/cucumber2rspec/step.rb', line 5

def scenario
  @scenario
end

Class Method Details

.code_for_steps(steps) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/cucumber2rspec/step.rb', line 7

def self.code_for_steps steps
  the_code = ''
  groups   = {
    'Given' => [],
    'When'  => [],
    'Then'  => []
  }

  last_keyword = 'Given'
  steps.each do |step|
    keyword = (step.keyword == 'And') ? last_keyword : step.keyword
    groups[keyword] << step.code
    last_keyword = step.keyword unless step.keyword == 'And'
  end

  groups['Given'].each {|code| the_code << (code.indent(4) + "\n") }
  the_code << "\n" if groups['Given'].length > 0
  
  groups['When' ].each {|code| the_code << (code.indent(4) + "\n") }
  the_code << "\n" if groups['When'].length > 0

  groups['Then' ].each {|code| the_code << (code.indent(4) + "\n") }
  the_code
end

Instance Method Details

#_step_definitionObject



61
62
63
# File 'lib/cucumber2rspec/step.rb', line 61

def _step_definition
  Cucumber2RSpec.step_match(text).instance_variable_get('@step_definition')
end

#codeObject



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/cucumber2rspec/step.rb', line 106

def code
  Cucumber2RSpec.log { '    ' + text }

  if has_table?
    # require cucumber and create a local variable defining the cucumber table
    header = "require 'cucumber'\n"
    header << "#{table_variable_name} = Cucumber::Ast::Table.new(#{ table.raw.inspect })\n"
  end

  if variable_names.empty?
    ruby = the_proc.to_ruby

    if has_table?
      # get rid of proc { |table| }
      ruby = ruby.sub(/^proc \{ \|#{table_variable_name}\|\s+/, '').sub(/\s\}$/, '')
    else
      # get rid of proc { }
      ruby = ruby.sub(/^proc \{\s+/, '').sub(/\s\}$/, '')
    end

  else
    # TODO replace with the_proc.to_sexp
    sexp_for_proc = ParseTree.new.process(the_proc.to_ruby) # turn the proc into an Sexp
    matches.each do |name, value|
      str = Sexp.new(:str, value)

      # s(:lvar, :var) => s(:str, "dogs")
      Cucumber2RSpec.replace_in_sexp sexp_for_proc, Sexp.new(:lvar, name), str

      # s(:evstr, s(:str, "dogs")) => s(:str, "dogs")
      Cucumber2RSpec.replace_in_sexp sexp_for_proc, Sexp.new(:evstr, str), str
    end
    ruby = Ruby2Ruby.new.process(sexp_for_proc) # turn it back into ruby
    if ruby =~ /^proc do/
      # get rid of the proc do |x| end
      ruby = ruby.sub(/^proc do \|([\w+, ]+)\|\n  /, '').sub(/\send$/, '')
    elsif ruby =~ /^proc \{ |/
      # get rid of proc { |whatever, ...| }
      ruby = ruby.sub(/^proc \{ \|([^\|]+)\|\s+/, '').sub(/\s\}$/, '')
    elsif ruby =~ /^proc \{/
      # get rid of proc { }
      ruby = ruby.sub(/^proc \{\s+/, '').sub(/\s\}$/, '')
    else
      raise "Not sure how to clean up the code for: #{ ruby }"
    end
  end

  ruby = header + ruby if has_table?

  # get rid of any spaces after any newlines
  ruby.gsub(/\n[ ]+/, "\n")
end

#full_textObject



57
58
59
# File 'lib/cucumber2rspec/step.rb', line 57

def full_text
  "#{keyword} #{text}"
end

#has_table?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/cucumber2rspec/step.rb', line 45

def has_table?
  !! table
end

#keywordObject



37
38
39
# File 'lib/cucumber2rspec/step.rb', line 37

def keyword
  _step.respond_to?(:actual_keyword) ? _step.actual_keyword : _step.keyword
end

#matchesObject



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/cucumber2rspec/step.rb', line 88

def matches
  return [] if variable_names.empty?

  match = text.match(regexp)
  if match
    matches = {}
    if match.captures.length != variable_names.length
      raise "Problem getting #{ variable_names.inspect } from #{ text.inspect }."
    end
    variable_names.each_with_index do |name, i|
      matches[name] = match.captures[i]
    end
    matches
  else
    []
  end
end

#raw_variable_namesObject



69
70
71
# File 'lib/cucumber2rspec/step.rb', line 69

def raw_variable_names
  Cucumber2RSpec.block_variable_names(the_proc)
end

#regexpObject



65
66
67
# File 'lib/cucumber2rspec/step.rb', line 65

def regexp
  Regexp.new _step_definition.instance_variable_get('@regexp')
end

#tableObject



41
42
43
# File 'lib/cucumber2rspec/step.rb', line 41

def table
  _step.multiline_arg if _step.respond_to?(:multiline_arg)
end

#table_variable_nameObject



80
81
82
# File 'lib/cucumber2rspec/step.rb', line 80

def table_variable_name
  raw_variable_names.last if has_table?
end

#textObject



49
50
51
52
53
54
55
# File 'lib/cucumber2rspec/step.rb', line 49

def text
  if has_table?
    _step.to_sexp[ _step.to_sexp.length - 2 ] # the last argument will be the table!
  else
    _step.to_sexp.last
  end
end

#the_procObject



84
85
86
# File 'lib/cucumber2rspec/step.rb', line 84

def the_proc
  _step_definition.instance_variable_get('@proc')
end

#variable_namesObject



73
74
75
76
77
78
# File 'lib/cucumber2rspec/step.rb', line 73

def variable_names
  # if has_table? then we ignore the last block variable (which is the table)
  variables = raw_variable_names
  variables.pop if has_table?
  variables
end