cucumber 0.8.0 → 0.8.1

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.
@@ -39,6 +39,9 @@ module Cucumber
39
39
  @rows = []
40
40
  end
41
41
 
42
+ def location(uri, offset)
43
+ end
44
+
42
45
  def row(row, line_number)
43
46
  @rows << row
44
47
  end
@@ -58,10 +61,10 @@ module Cucumber
58
61
  "table"
59
62
  end
60
63
 
61
- def self.parse(text)
64
+ def self.parse(text, uri, offset)
62
65
  builder = Builder.new
63
66
  lexer = Gherkin::I18nLexer.new(builder)
64
- lexer.scan(text)
67
+ lexer.scan(text, uri, offset)
65
68
  new(builder.rows)
66
69
  end
67
70
 
@@ -1,5 +1,6 @@
1
1
  require 'cucumber/parser/gherkin_builder'
2
2
  require 'gherkin/parser/filter_listener'
3
+ require 'gherkin/parser/formatter_listener'
3
4
  require 'gherkin/parser/parser'
4
5
  require 'gherkin/i18n_lexer'
5
6
 
@@ -26,14 +27,15 @@ module Cucumber
26
27
  def parse(step_mother, options)
27
28
  filters = @lines || options.filters
28
29
 
29
- builder = Cucumber::Parser::GherkinBuilder.new
30
- filter_listener = Gherkin::Parser::FilterListener.new(builder, filters)
31
- parser = Gherkin::Parser::Parser.new(filter_listener, true, "root")
32
- lexer = Gherkin::I18nLexer.new(parser, false)
30
+ builder = Cucumber::Parser::GherkinBuilder.new
31
+ formatter_listener = Gherkin::Parser::FormatterListener.new(builder)
32
+ filter_listener = Gherkin::Parser::FilterListener.new(formatter_listener, filters)
33
+ parser = Gherkin::Parser::Parser.new(filter_listener, true, "root")
34
+ lexer = Gherkin::I18nLexer.new(parser, false)
33
35
 
34
36
  begin
35
37
  s = ENV['FILTER_PML_CALLOUT'] ? source.gsub(C_CALLOUT, '') : source
36
- lexer.scan(s)
38
+ lexer.scan(s, @path, 0)
37
39
  ast = builder.ast
38
40
  return nil if ast.nil? # Filter caused nothing to match
39
41
  ast.language = lexer.i18n_language
@@ -69,7 +69,8 @@ module Cucumber
69
69
 
70
70
  def step_name(keyword, step_match, status, source_indent, background)
71
71
  @current_step[:status] = status
72
- @current_step[:name] = "#{keyword}#{step_match.name || step_match.format_args}" # ?
72
+ @current_step[:keyword] = "#{keyword}"
73
+ @current_step[:name] = "#{step_match.name || step_match.format_args}"
73
74
  @current_step[:file_colon_line] = step_match.file_colon_line
74
75
  end
75
76
 
@@ -126,6 +127,17 @@ module Cucumber
126
127
  @io.flush
127
128
  end
128
129
 
130
+ def embed(file, mime_type)
131
+ obj = @current_step || @current_object
132
+ obj[:embedded] ||= []
133
+
134
+ obj[:embedded] << {
135
+ :file => file,
136
+ :mime_type => mime_type,
137
+ :data => [File.read(file)].pack("m*") # base64
138
+ }
139
+ end
140
+
129
141
  private
130
142
 
131
143
  def json_string
@@ -3,21 +3,11 @@ require 'cucumber/formatter/io'
3
3
  require 'fileutils'
4
4
 
5
5
  begin
6
- require 'htmlentities'
7
- rescue LoadError => e
8
- e.message << "\nPlease gem install htmlentities"
9
- raise e
10
- end
11
-
12
- begin
13
- gem 'prawn', '=0.6.3'
14
- require 'prawn'
6
+ require 'rubygems'
7
+ require 'prawn/core'
15
8
  require "prawn/layout"
16
-
17
- gem 'prawn-format', '=0.2.3'
18
- require "prawn/format"
19
9
  rescue LoadError => e
20
- e.message << "\nPlease gem install prawn --version 0.6.3 && gem install prawn-format --version 0.2.3. Newer versions are not known to work."
10
+ e.message << "\nYou need the prawn gem. Please do 'gem install prawn'"
21
11
  raise e
22
12
  end
23
13
 
@@ -36,7 +26,6 @@ module Cucumber
36
26
  def initialize(step_mother, path_or_io, options)
37
27
  @step_mother = step_mother
38
28
  @file = ensure_file(path_or_io, "pdf")
39
- @coder = HTMLEntities.new
40
29
 
41
30
  if(options[:dry_run])
42
31
  @status_colors = { :passed => BLACK, :skipped => BLACK, :undefined => BLACK, :failed => BLACK, :announced => GREY}
@@ -53,8 +42,8 @@ module Cucumber
53
42
  @buffer = []
54
43
  load_cover_page_image
55
44
  @pdf.text "\n\n\nCucumber features", :align => :center, :size => 32
56
- @pdf.text "Generated: #{Time.now.strftime("%Y-%m-%d %H:%M")}", :size => 10, :at => [0, 24]
57
- @pdf.text "Command: <code>cucumber #{ARGV.join(" ")}</code>", :size => 10, :at => [0,10]
45
+ @pdf.draw_text "Generated: #{Time.now.strftime("%Y-%m-%d %H:%M")}", :size => 10, :at => [0, 24]
46
+ @pdf.draw_text "$ cucumber #{ARGV.join(" ")}", :size => 10, :at => [0,10]
58
47
  unless options[:dry_run]
59
48
  @pdf.bounding_box [450,100] , :width => 100 do
60
49
  @pdf.text 'Legend', :size => 10
@@ -153,7 +142,7 @@ module Cucumber
153
142
 
154
143
  def step_name(keyword, step_match, status, source_indent, background)
155
144
  return if @hide_this_step
156
- line = "<b>#{keyword}</b> #{encode(step_match.format_args("%s"))}"
145
+ line = "#{keyword} #{step_match.format_args("%s")}"
157
146
  colorize(line, status)
158
147
  end
159
148
 
@@ -188,7 +177,7 @@ module Cucumber
188
177
  s = %{"""\n#{string}\n"""}.indent(10)
189
178
  s = s.split("\n").map{|l| l =~ /^\s+$/ ? '' : l}
190
179
  s.each do |line|
191
- keep_with { @doc.text(encode(line), :size => 8) }
180
+ keep_with { @doc.text(line, :size => 8) }
192
181
  end
193
182
  end
194
183
 
@@ -211,11 +200,7 @@ module Cucumber
211
200
  end
212
201
 
213
202
  private
214
-
215
- def encode(text)
216
- @coder.encode(text, :decimal)
217
- end
218
-
203
+
219
204
  def colorize(text, status)
220
205
  keep_with do
221
206
  @doc.fill_color(@status_colors[status] || BLACK)
@@ -252,9 +237,7 @@ module Cucumber
252
237
  end
253
238
 
254
239
  def print_table(table, row_colors)
255
- rows = table.rows.map { |row| row.map{ |cell| encode(cell) }}
256
- headers = table.headers.map { |text| encode(text) }
257
- @doc.table(rows, :headers => headers, :position => :center, :row_colors => row_colors)
240
+ @doc.table(table.rows, :headers => table.headers, :position => :center, :row_colors => row_colors)
258
241
  end
259
242
  end
260
243
  end
@@ -1,4 +1,5 @@
1
1
  require 'cucumber/ast'
2
+ require 'gherkin/rubify'
2
3
 
3
4
  module Cucumber
4
5
  module Parser
@@ -6,38 +7,29 @@ module Cucumber
6
7
  # "legacy" AST. It will be replaced later when we have a new "clean"
7
8
  # AST.
8
9
  class GherkinBuilder
10
+ include Gherkin::Rubify
9
11
 
10
12
  def ast
11
13
  @feature || @multiline_arg
12
14
  end
13
15
 
14
- def tag(name, line)
15
- @tags ||= []
16
- @tags << name
17
- end
18
-
19
- def comment(content, line)
20
- @comments ||= []
21
- @comments << content
22
- end
23
-
24
- def feature(keyword, name, line)
16
+ def feature(comments, tags, keyword, name, description, uri)
25
17
  @feature = Ast::Feature.new(
26
18
  nil,
27
- Ast::Comment.new(grab_comments!('')),
28
- Ast::Tags.new(nil, grab_tags!('')),
19
+ Ast::Comment.new(comments.join("\n")),
20
+ Ast::Tags.new(nil, tags),
29
21
  keyword,
30
- name,
22
+ legacy_name_for(name, description),
31
23
  []
32
24
  )
33
25
  end
34
26
 
35
- def background(keyword, name, line)
27
+ def background(comments, keyword, name, description, line)
36
28
  @background = Ast::Background.new(
37
- Ast::Comment.new(grab_comments!('')),
29
+ Ast::Comment.new(comments.join("\n")),
38
30
  line,
39
31
  keyword,
40
- name,
32
+ legacy_name_for(name, description),
41
33
  steps=[]
42
34
  )
43
35
  @feature.background = @background
@@ -45,15 +37,14 @@ module Cucumber
45
37
  @step_container = @background
46
38
  end
47
39
 
48
- def scenario(keyword, name, line)
49
- grab_table!
40
+ def scenario(comments, tags, keyword, name, description, line)
50
41
  scenario = Ast::Scenario.new(
51
42
  @background,
52
- Ast::Comment.new(grab_comments!('')),
53
- Ast::Tags.new(nil, grab_tags!('')),
43
+ Ast::Comment.new(comments.join("\n")),
44
+ Ast::Tags.new(nil, tags),
54
45
  line,
55
46
  keyword,
56
- name,
47
+ legacy_name_for(name, description),
57
48
  steps=[]
58
49
  )
59
50
  @feature.add_feature_element(scenario)
@@ -61,15 +52,14 @@ module Cucumber
61
52
  @step_container = scenario
62
53
  end
63
54
 
64
- def scenario_outline(keyword, name, line)
65
- grab_table!
55
+ def scenario_outline(comments, tags, keyword, name, description, line)
66
56
  scenario_outline = Ast::ScenarioOutline.new(
67
57
  @background,
68
- Ast::Comment.new(grab_comments!('')),
69
- Ast::Tags.new(nil, grab_tags!('')),
58
+ Ast::Comment.new(comments.join("\n")),
59
+ Ast::Tags.new(nil, tags),
70
60
  line,
71
61
  keyword,
72
- name,
62
+ legacy_name_for(name, description),
73
63
  steps=[],
74
64
  example_sections=[]
75
65
  )
@@ -81,64 +71,47 @@ module Cucumber
81
71
  @step_container = scenario_outline
82
72
  end
83
73
 
84
- def examples(keyword, name, line)
85
- grab_table!
86
- @examples_fields = [Ast::Comment.new(grab_comments!('')), line, keyword, name]
74
+ def examples(comments, tags, keyword, name, description, line, examples_table)
75
+ examples_fields = [Ast::Comment.new(comments.join("\n")), line, keyword, legacy_name_for(name, description), matrix(examples_table)]
76
+ @step_container.add_examples(examples_fields)
87
77
  end
88
78
 
89
- def step(keyword, name, line)
90
- grab_table!
79
+ def step(comments, keyword, name, line, multiline_arg, status, exception, arguments, stepdef_location)
91
80
  @table_owner = Ast::Step.new(line, keyword, name)
92
- @step_container.add_step(@table_owner)
93
- end
94
-
95
- def row(row, line)
96
- @rows ||= []
97
- @rows << row
98
- class << row
99
- attr_accessor :line
81
+ multiline_arg = rubify(multiline_arg)
82
+ case(multiline_arg)
83
+ when String
84
+ @table_owner.multiline_arg = Ast::PyString.new(multiline_arg)
85
+ when Array
86
+ @table_owner.multiline_arg = Ast::Table.new(matrix(multiline_arg))
100
87
  end
101
- row.line = line
102
- end
103
-
104
- def py_string(string, line)
105
- @multiline_arg = Ast::PyString.new(string)
106
- @table_owner.multiline_arg = @multiline_arg if @table_owner
88
+ @step_container.add_step(@table_owner)
107
89
  end
108
90
 
109
91
  def eof
110
- grab_table!
111
92
  end
112
93
 
113
94
  def syntax_error(state, event, legal_events, line)
114
95
  # raise "SYNTAX ERROR"
115
96
  end
116
-
97
+
117
98
  private
118
-
119
- def grab_table!
120
- return if @rows.nil?
121
- if @examples_fields
122
- @examples_fields << @rows
123
- @step_container.add_examples(@examples_fields)
124
- @examples_fields = nil
125
- else
126
- @multiline_arg = Ast::Table.new(@rows)
127
- @table_owner.multiline_arg = @multiline_arg if @table_owner
99
+
100
+ def legacy_name_for(name, description)
101
+ s = name
102
+ s += "\n#{description}" if description != ""
103
+ s
104
+ end
105
+
106
+ def matrix(gherkin_table)
107
+ gherkin_table.map do |gherkin_row|
108
+ row = gherkin_row.cells
109
+ class << row
110
+ attr_accessor :line
111
+ end
112
+ row.line = gherkin_row.line
113
+ row
128
114
  end
129
- @rows = nil
130
- end
131
-
132
- def grab_tags!(indent)
133
- tags = @tags ? @tags : []
134
- @tags = nil
135
- tags
136
- end
137
-
138
- def grab_comments!(indent)
139
- comments = @comments ? indent + @comments.join("\n#{indent}") : ''
140
- @comments = nil
141
- comments
142
115
  end
143
116
  end
144
117
  end
@@ -87,15 +87,17 @@ module Cucumber
87
87
  end.compact
88
88
  end
89
89
 
90
- def snippet_text(step_keyword, step_name, multiline_arg_class)
91
- escaped = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/')
92
- escaped = escaped.gsub(PARAM_PATTERN, ESCAPED_PARAM_PATTERN)
90
+ ARGUMENT_PATTERNS = ['"([^"]*)"', '(\d+)']
93
91
 
94
- n = 0
95
- block_args = escaped.scan(ESCAPED_PARAM_PATTERN).map do |a|
96
- n += 1
97
- "arg#{n}"
92
+ def snippet_text(step_keyword, step_name, multiline_arg_class)
93
+ snippet_pattern = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/')
94
+ arg_count = 0
95
+ ARGUMENT_PATTERNS.each do |pattern|
96
+ snippet_pattern = snippet_pattern.gsub(Regexp.new(pattern), pattern)
97
+ arg_count += snippet_pattern.scan(pattern).length
98
98
  end
99
+
100
+ block_args = (0...arg_count).map {|n| "arg#{n+1}"}
99
101
  block_args << multiline_arg_class.default_arg_name unless multiline_arg_class.nil?
100
102
  block_arg_string = block_args.empty? ? "" : " |#{block_args.join(", ")}|"
101
103
  multiline_class_comment = ""
@@ -103,7 +105,7 @@ module Cucumber
103
105
  multiline_class_comment = "# #{multiline_arg_class.default_arg_name} is a #{multiline_arg_class.to_s}\n "
104
106
  end
105
107
 
106
- "#{Gherkin::I18n.code_keyword_for(step_keyword)} /^#{escaped}$/ do#{block_arg_string}\n #{multiline_class_comment}pending # express the regexp above with the code you wish you had\nend"
108
+ "#{Gherkin::I18n.code_keyword_for(step_keyword)} /^#{snippet_pattern}$/ do#{block_arg_string}\n #{multiline_class_comment}pending # express the regexp above with the code you wish you had\nend"
107
109
  end
108
110
 
109
111
  def begin_rb_scenario(scenario)
@@ -151,9 +153,6 @@ module Cucumber
151
153
 
152
154
  private
153
155
 
154
- PARAM_PATTERN = /"([^"]*)"/
155
- ESCAPED_PARAM_PATTERN = '"([^"]*)"'
156
-
157
156
  def create_world
158
157
  if(@world_proc)
159
158
  @current_world = @world_proc.call
@@ -24,7 +24,7 @@ module Cucumber
24
24
 
25
25
  # See StepMother#invoke_steps
26
26
  def steps(steps_text)
27
- @__cucumber_step_mother.invoke_steps(steps_text, @__natural_language)
27
+ @__cucumber_step_mother.invoke_steps(steps_text, @__natural_language, caller[0])
28
28
  end
29
29
 
30
30
  # See StepMother#table
@@ -189,9 +189,10 @@ module Cucumber
189
189
  # Given I have 8 cukes in my belly
190
190
  # Then I should not be thirsty
191
191
  # })
192
- def invoke_steps(steps_text, i18n)
192
+ def invoke_steps(steps_text, i18n, file_colon_line)
193
+ file, line = file_colon_line.split(':')
193
194
  lexer = i18n.lexer(Gherkin::Parser::Parser.new(StepInvoker.new(self), true, 'steps'))
194
- lexer.scan(steps_text)
195
+ lexer.scan(steps_text, file, line)
195
196
  end
196
197
 
197
198
  class StepInvoker
@@ -199,6 +200,9 @@ module Cucumber
199
200
  @step_mother = step_mother
200
201
  end
201
202
 
203
+ def location(uri, offset)
204
+ end
205
+
202
206
  def step(keyword, name, line)
203
207
  invoke
204
208
  @name = name
@@ -251,7 +255,7 @@ module Cucumber
251
255
  if Array === text_or_table
252
256
  Ast::Table.new(text_or_table)
253
257
  else
254
- Ast::Table.parse(text_or_table)
258
+ Ast::Table.parse(text_or_table, file, line_offset)
255
259
  end
256
260
  end
257
261
 
@@ -229,7 +229,7 @@ module Cucumber
229
229
  | 55555 | 666666 | 7777777 | 88888888 |
230
230
  | 999999999 | 0000000000 | 01010101010 | 121212121212 |
231
231
  | 4000 | ABC | DEF | 50000 |
232
- })
232
+ }, __FILE__, __LINE__)
233
233
 
234
234
  t2 = table(%{
235
235
  | a | 4444 | 1 |
@@ -237,7 +237,7 @@ module Cucumber
237
237
  | ccc | xxxxxxxx | 999999999 |
238
238
  | dddd | 4000 | 300 |
239
239
  | e | 50000 | 4000 |
240
- })
240
+ }, __FILE__, __LINE__)
241
241
  lambda{t1.diff!(t2)}.should raise_error
242
242
  t1.to_s(:indent => 12, :color => false).should == %{
243
243
  | 1 | (-) 22 | (-) 333 | 4444 | (+) a |
@@ -254,7 +254,7 @@ module Cucumber
254
254
  |a|b|c|
255
255
  |d|e|f|
256
256
  |g|h|i|
257
- })
257
+ }, __FILE__, __LINE__)
258
258
  t.diff!(t.dup)
259
259
  t.to_s(:indent => 12, :color => false).should == %{
260
260
  | a | b | c |
@@ -350,14 +350,14 @@ module Cucumber
350
350
  @t = table(%{
351
351
  | a | b |
352
352
  | c | d |
353
- })
353
+ }, __FILE__, __LINE__)
354
354
  @t.should_not == nil
355
355
  end
356
356
 
357
357
  it "should raise on missing rows" do
358
358
  t = table(%{
359
359
  | a | b |
360
- })
360
+ }, __FILE__, __LINE__)
361
361
  lambda { @t.dup.diff!(t) }.should raise_error
362
362
  lambda { @t.dup.diff!(t, :missing_row => false) }.should_not raise_error
363
363
  end
@@ -367,7 +367,7 @@ module Cucumber
367
367
  | a | b |
368
368
  | c | d |
369
369
  | e | f |
370
- })
370
+ }, __FILE__, __LINE__)
371
371
  lambda { @t.dup.diff!(t) }.should raise_error
372
372
  lambda { @t.dup.diff!(t, :surplus_row => false) }.should_not raise_error
373
373
  end
@@ -376,7 +376,7 @@ module Cucumber
376
376
  t1 = table(%{
377
377
  | row_1 | row_2 |
378
378
  | four | 4 |
379
- })
379
+ }, __FILE__, __LINE__)
380
380
  t2 = table(%{
381
381
  | row_1 | row_2 |
382
382
  | one | 1 |
@@ -384,7 +384,7 @@ module Cucumber
384
384
  | three | 3 |
385
385
  | four | 4 |
386
386
  | five | 5 |
387
- })
387
+ }, __FILE__, __LINE__)
388
388
  lambda { t1.dup.diff!(t2) }.should raise_error
389
389
 
390
390
  begin
@@ -400,7 +400,7 @@ module Cucumber
400
400
  t = table(%{
401
401
  | a |
402
402
  | c |
403
- })
403
+ }, __FILE__, __LINE__)
404
404
  lambda { @t.dup.diff!(t) }.should raise_error
405
405
  lambda { @t.dup.diff!(t, :missing_col => false) }.should_not raise_error
406
406
  end
@@ -409,14 +409,14 @@ module Cucumber
409
409
  t = table(%{
410
410
  | a | b | x |
411
411
  | c | d | y |
412
- })
412
+ }, __FILE__, __LINE__)
413
413
  lambda { @t.dup.diff!(t) }.should_not raise_error
414
414
  lambda { @t.dup.diff!(t, :surplus_col => true) }.should raise_error
415
415
  end
416
416
  end
417
417
 
418
- def table(text, file=nil, line_offset=0)
419
- Table.parse(text)
418
+ def table(text, file, offset)
419
+ Table.parse(text, file, offset)
420
420
  end
421
421
  end
422
422