cucumber 0.8.0 → 0.8.1

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