aslakhellesoy-cucumber 0.3.11.6 → 0.3.11.200907091518

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.
Files changed (37) hide show
  1. data/History.txt +49 -1
  2. data/Manifest.txt +3 -0
  3. data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +1 -1
  4. data/examples/self_test/features/support/env.rb +2 -1
  5. data/examples/steps_library/features/step_definitions/steps_lib1.rb +8 -0
  6. data/examples/steps_library/features/step_definitions/steps_lib2.rb +8 -0
  7. data/examples/tickets/features/step_definitons/tickets_steps.rb +15 -0
  8. data/features/html_formatter/a.html +4 -4
  9. data/features/rake_task.feature +28 -0
  10. data/features/steps_formatter.feature +25 -0
  11. data/features/support/env.rb +5 -0
  12. data/lib/cucumber/ast/outline_table.rb +2 -1
  13. data/lib/cucumber/ast/py_string.rb +0 -1
  14. data/lib/cucumber/ast/step.rb +4 -1
  15. data/lib/cucumber/ast/table.rb +286 -48
  16. data/lib/cucumber/ast/visitor.rb +2 -1
  17. data/lib/cucumber/cli/configuration.rb +8 -2
  18. data/lib/cucumber/cli/language_help_formatter.rb +9 -7
  19. data/lib/cucumber/feature_file.rb +7 -1
  20. data/lib/cucumber/filter.rb +2 -2
  21. data/lib/cucumber/formatter/html.rb +1 -1
  22. data/lib/cucumber/formatter/pretty.rb +20 -5
  23. data/lib/cucumber/formatter/progress.rb +1 -1
  24. data/lib/cucumber/formatter/steps.rb +49 -0
  25. data/lib/cucumber/parser/feature.rb +27 -0
  26. data/lib/cucumber/parser/i18n/language.rb +8 -5
  27. data/lib/cucumber/rake/task.rb +6 -0
  28. data/lib/cucumber/step_match.rb +1 -1
  29. data/lib/cucumber/version.rb +1 -1
  30. data/rails_generators/cucumber/templates/env.rb +1 -0
  31. data/rails_generators/feature/templates/feature.erb +1 -1
  32. data/rails_generators/feature/templates/steps.erb +2 -8
  33. data/spec/cucumber/ast/table_spec.rb +144 -0
  34. data/spec/cucumber/cli/configuration_spec.rb +13 -0
  35. data/spec/cucumber/cli/main_spec.rb +0 -1
  36. data/spec/cucumber/formatter/progress_spec.rb +2 -2
  37. metadata +8 -4
@@ -64,6 +64,7 @@ module Cucumber
64
64
  end
65
65
 
66
66
  def visit_outline_table(outline_table)
67
+ @table = outline_table
67
68
  outline_table.accept(self)
68
69
  end
69
70
 
@@ -105,7 +106,7 @@ module Cucumber
105
106
  table_cell.accept(self)
106
107
  end
107
108
 
108
- def visit_table_cell_value(value, width, status)
109
+ def visit_table_cell_value(value, status)
109
110
  end
110
111
 
111
112
  def announce(announcement)
@@ -102,7 +102,9 @@ module Cucumber
102
102
  "TAGS must be comma-separated without spaces. Prefix tags with ~ to",
103
103
  "exclude features or scenarios having that tag. Tags can be specified",
104
104
  "with or without the @ prefix.") do |v|
105
- @options[:include_tags], @options[:exclude_tags] = *parse_tags(v)
105
+ include_tags, exclude_tags = *parse_tags(v)
106
+ @options[:include_tags] += include_tags
107
+ @options[:exclude_tags] += exclude_tags
106
108
  end
107
109
  opts.on("-n NAME", "--name NAME",
108
110
  "Only execute the feature elements which match part of the given name.",
@@ -268,7 +270,7 @@ module Cucumber
268
270
  end
269
271
 
270
272
  def files_to_require
271
- requires = @options[:require] || feature_dirs
273
+ requires = @options[:require] || require_dirs
272
274
  files = requires.map do |path|
273
275
  path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
274
276
  path = path.gsub(/\/$/, '') # Strip trailing slash.
@@ -310,6 +312,10 @@ module Cucumber
310
312
  @paths.map { |f| File.directory?(f) ? f : File.dirname(f) }.uniq
311
313
  end
312
314
 
315
+ def require_dirs
316
+ feature_dirs+Dir['vendor/{gems,plugins}/*/cucumber']
317
+ end
318
+
313
319
  def constantize(camel_cased_word)
314
320
  begin
315
321
  names = camel_cased_word.split('::')
@@ -1,4 +1,5 @@
1
1
  require 'cucumber/formatter/pretty'
2
+ require 'cucumber/parser/i18n/language'
2
3
 
3
4
  module Cucumber
4
5
  module Cli
@@ -18,15 +19,16 @@ http://wiki.github.com/aslakhellesoy/cucumber/spoken-languages
18
19
  [lang, Cucumber::LANGUAGES[lang]['name'], Cucumber::LANGUAGES[lang]['native']]
19
20
  end
20
21
  table = Ast::Table.new(raw)
21
- new(nil, io, {:check_lang=>true}, '').visit_multiline_arg(table)
22
+ new(nil, io, {:check_lang=>true}).visit_multiline_arg(table)
22
23
  end
23
24
 
24
25
  def self.list_keywords(io, lang)
25
- raw = Cucumber::KEYWORD_KEYS.map do |key|
26
- [key, Cucumber::LANGUAGES[lang][key]]
26
+ language = Parser::I18n::Language[lang]
27
+ raw = Parser::I18n::Language::KEYWORD_KEYS.map do |key|
28
+ [key, language.keywords(key)]
27
29
  end
28
30
  table = Ast::Table.new(raw)
29
- new(nil, io, {:incomplete => Cucumber.language_incomplete?(lang)}, '').visit_multiline_arg(table)
31
+ new(nil, io, {:incomplete => language.incomplete?}).visit_multiline_arg(table)
30
32
  end
31
33
 
32
34
  def visit_multiline_arg(table)
@@ -41,10 +43,10 @@ http://wiki.github.com/aslakhellesoy/cucumber/spoken-languages
41
43
  super
42
44
  end
43
45
 
44
- def visit_table_cell_value(value, width, status)
46
+ def visit_table_cell_value(value, status)
45
47
  if @col == 1
46
48
  if(@options[:check_lang])
47
- @incomplete = Cucumber.language_incomplete?(value)
49
+ @incomplete = Parser::I18n::Language[value].incomplete?
48
50
  end
49
51
  status = :comment
50
52
  elsif @incomplete
@@ -52,7 +54,7 @@ http://wiki.github.com/aslakhellesoy/cucumber/spoken-languages
52
54
  end
53
55
 
54
56
  @col += 1
55
- super(value, width, status)
57
+ super(value, status)
56
58
  end
57
59
  end
58
60
  end
@@ -31,7 +31,13 @@ module Cucumber
31
31
  require 'open-uri'
32
32
  open(@path).read
33
33
  else
34
- File.open(@path, Cucumber.file_mode('r')).read
34
+ begin
35
+ File.open(@path, Cucumber.file_mode('r')).read
36
+ rescue Errno::EACCES => e
37
+ p = File.expand_path(@path)
38
+ e.message << "\nCouldn't open #{p}"
39
+ raise e
40
+ end
35
41
  end
36
42
  end
37
43
 
@@ -32,7 +32,7 @@ module Cucumber
32
32
  end
33
33
 
34
34
  def included_by_tags?(syntax_node)
35
- @include_tags.empty? || syntax_node.has_tags?(@include_tags)
35
+ @include_tags.empty? || syntax_node.has_all_tags?(@include_tags)
36
36
  end
37
37
 
38
38
  def excluded_by_tags?(syntax_node)
@@ -47,4 +47,4 @@ module Cucumber
47
47
  @name_regexps.nil? || @name_regexps.empty? || @name_regexps.detect{|name_regexp| syntax_node.matches_name?(name_regexp)}
48
48
  end
49
49
  end
50
- end
50
+ end
@@ -214,7 +214,7 @@ module Cucumber
214
214
  @outline_row += 1 if @outline_row
215
215
  end
216
216
 
217
- def visit_table_cell_value(value, width, status)
217
+ def visit_table_cell_value(value, status)
218
218
  cell_type = @outline_row == 0 ? :th : :td
219
219
  attributes = {:id => "#{@row_id}_#{@col_index}", :class => 'val'}
220
220
  attributes[:class] += " #{status}" if status
@@ -13,13 +13,13 @@ module Cucumber
13
13
  include Console
14
14
  attr_writer :indent
15
15
 
16
- def initialize(step_mother, io, options, delim='|')
16
+ def initialize(step_mother, io, options)
17
17
  super(step_mother)
18
18
  @io = io
19
19
  @options = options
20
- @delim = delim
21
20
  @exceptions = []
22
21
  @indent = 0
22
+ @prefixes = options[:prefixes] || {}
23
23
  end
24
24
 
25
25
  def visit_features(features)
@@ -145,6 +145,7 @@ module Cucumber
145
145
 
146
146
  def visit_multiline_arg(multiline_arg)
147
147
  return if @options[:no_multiline]
148
+ @table = multiline_arg
148
149
  super
149
150
  end
150
151
 
@@ -154,7 +155,8 @@ module Cucumber
154
155
  end
155
156
 
156
157
  def visit_table_row(table_row)
157
- @io.print @delim.indent(@indent)
158
+ @col_index = 0
159
+ @io.print ' |'.indent(@indent-2)
158
160
  super
159
161
  @io.puts
160
162
  if table_row.exception && !@exceptions.index(table_row.exception)
@@ -169,13 +171,26 @@ module Cucumber
169
171
  @io.flush
170
172
  end
171
173
 
172
- def visit_table_cell_value(value, width, status)
174
+ def visit_table_cell(cell)
175
+ super
176
+ @col_index += 1
177
+ end
178
+
179
+ def visit_table_cell_value(value, status)
173
180
  status ||= @status || :passed
174
- @io.print(' ' + format_string((value.to_s || '').ljust(width), status) + ::Term::ANSIColor.reset(" #{@delim}"))
181
+ width = @table.col_width(@col_index)
182
+ cell_text = value.to_s || ''
183
+ padded = cell_text + (' ' * (width - cell_text.jlength))
184
+ prefix = cell_prefix(status)
185
+ @io.print(' ' + format_string("#{prefix}#{padded}", status) + ::Term::ANSIColor.reset(" |"))
175
186
  @io.flush
176
187
  end
177
188
 
178
189
  private
190
+
191
+ def cell_prefix(status)
192
+ @prefixes[status]
193
+ end
179
194
 
180
195
  def print_summary(features)
181
196
  print_stats(features)
@@ -23,7 +23,7 @@ module Cucumber
23
23
  @status = status
24
24
  end
25
25
 
26
- def visit_table_cell_value(value, width, status)
26
+ def visit_table_cell_value(value, status)
27
27
  status ||= @status
28
28
  progress(status) unless table_header_cell?(status)
29
29
  end
@@ -0,0 +1,49 @@
1
+ module Cucumber
2
+ module Formatter
3
+ class Steps < Ast::Visitor
4
+
5
+ def initialize(step_mother, io, options)
6
+ super(step_mother)
7
+ @io = io
8
+ @options = options
9
+ @step_definition_files = collect_steps(step_mother)
10
+ end
11
+
12
+ def visit_features(features)
13
+ print_summary
14
+ end
15
+
16
+ private
17
+
18
+ def print_summary
19
+ count = 0
20
+ @step_definition_files.keys.sort.each do |step_definition_file|
21
+ @io.puts step_definition_file
22
+
23
+ sources = @step_definition_files[step_definition_file]
24
+ source_indent = source_indent(sources)
25
+ sources.sort.each do |file_colon_line, regexp|
26
+ @io.print "#{regexp}".indent(2)
27
+ @io.print " # #{file_colon_line}".indent(source_indent - regexp.size)
28
+ @io.puts
29
+ end
30
+ @io.puts
31
+ count += sources.size
32
+ end
33
+ @io.puts "#{count} step definition(s) in #{@step_definition_files.size} source file(s)."
34
+ end
35
+
36
+ def collect_steps(step_mother)
37
+ step_mother.step_definitions.inject({}) do |step_definitions, step_definition|
38
+ step_definitions[step_definition.file] ||= []
39
+ step_definitions[step_definition.file] << [ step_definition.file_colon_line, step_definition.regexp.inspect ]
40
+ step_definitions
41
+ end
42
+ end
43
+
44
+ def source_indent(sources)
45
+ sources.map { |file_colon_line, regexp| regexp.size }.max + 1
46
+ end
47
+ end
48
+ end
49
+ end
@@ -55,6 +55,10 @@ module Cucumber
55
55
  def has_tags?(tag_names)
56
56
  tags.has_tags?(tag_names)
57
57
  end
58
+
59
+ def has_all_tags?(tag_names)
60
+ tags.has_all_tags?(tag_names)
61
+ end
58
62
 
59
63
  def build(filter)
60
64
  if(filter.nil? || feature_elements.accept?(filter) || (!bg.empty? && filter.accept?(bg)))
@@ -211,6 +215,10 @@ module Cucumber
211
215
  ts.elements.detect{|e| e.tag.line == line}
212
216
  end
213
217
 
218
+ def has_all_tags?(tags)
219
+ (tags & tag_names) == tags
220
+ end
221
+
214
222
  def has_tags?(tags)
215
223
  (tag_names & tags).any?
216
224
  end
@@ -491,6 +499,11 @@ module Cucumber
491
499
  feature_tags.has_tags?(tag_names)
492
500
  end
493
501
 
502
+ def has_all_tags?(tag_names)
503
+ feature_tags = self.parent.tags
504
+ feature_tags.has_all_tags?(tag_names)
505
+ end
506
+
494
507
  def build
495
508
  Ast::Background.new(
496
509
  comment.build,
@@ -688,6 +701,11 @@ module Cucumber
688
701
  tags.has_tags?(tag_names) || feature_tags.has_tags?(tag_names)
689
702
  end
690
703
 
704
+ def has_all_tags?(tag_names)
705
+ feature_tags = self.parent.parent.tags
706
+ tags.has_all_tags?(tag_names) || feature_tags.has_all_tags?(tag_names)
707
+ end
708
+
691
709
  def matches_name?(regexp_to_match)
692
710
  name.build =~ regexp_to_match
693
711
  end
@@ -826,6 +844,11 @@ module Cucumber
826
844
  tags.has_tags?(tag_names) || feature_tags.has_tags?(tag_names)
827
845
  end
828
846
 
847
+ def has_all_tags?(tag_names)
848
+ feature_tags = self.parent.parent.tags
849
+ tags.has_all_tags?(tag_names) || feature_tags.has_all_tags?(tag_names)
850
+ end
851
+
829
852
  def matches_name?(regexp_to_match)
830
853
  outline_matches_name?(regexp_to_match) || examples_sections.matches_name?(regexp_to_match)
831
854
  end
@@ -1162,6 +1185,10 @@ module Cucumber
1162
1185
  true
1163
1186
  end
1164
1187
 
1188
+ def has_all_tags?(tag_names)
1189
+ true
1190
+ end
1191
+
1165
1192
  def outline_at_line?(line)
1166
1193
  true
1167
1194
  end
@@ -32,34 +32,37 @@ module Cucumber
32
32
 
33
33
  alias_step_definitions(Cucumber::LANGUAGES['en'])
34
34
 
35
- attr_reader :parser
36
-
37
35
  def initialize(lang)
38
36
  @keywords = Cucumber::LANGUAGES[lang]
39
37
  raise "Language not supported: #{lang.inspect}" if @keywords.nil?
40
38
  @keywords['grammar_name'] = @keywords['name'].gsub(/\s/, '')
39
+ end
40
+
41
+ def parser
42
+ return @parser if @parser
41
43
  i18n_tt = File.expand_path(File.dirname(__FILE__) + '/../i18n.tt')
42
44
  template = File.open(i18n_tt, Cucumber.file_mode('r')).read
43
45
  erb = ERB.new(template)
44
46
  grammar = erb.result(binding)
45
47
  Treetop.load_from_string(grammar)
46
- @parser = Parser::I18n.const_get("#{@keywords['grammar_name']}Parser").new
47
48
  self.class.alias_step_definitions(@keywords)
49
+ @parser = Parser::I18n.const_get("#{@keywords['grammar_name']}Parser").new
48
50
  end
49
51
 
50
52
  def parse(source, path, filter)
51
- feature = @parser.parse_or_fail(source, path, filter)
53
+ feature = parser.parse_or_fail(source, path, filter)
52
54
  feature.language = self if feature
53
55
  feature
54
56
  end
55
57
 
56
58
  def keywords(key, raw=false)
57
59
  return @keywords[key] if raw
60
+ return nil unless @keywords[key]
58
61
  values = @keywords[key].split('|')
59
62
  values.map{|value| "'#{value}'"}.join(" / ")
60
63
  end
61
64
 
62
- def language_incomplete?
65
+ def incomplete?
63
66
  KEYWORD_KEYS.detect{|key| @keywords[key].nil?}
64
67
  end
65
68
 
@@ -194,6 +194,7 @@ module Cucumber
194
194
  result = []
195
195
  result += feature_list.to_a if feature_list
196
196
  result += FileList[feature_pattern].to_a if feature_pattern
197
+ result = make_command_line_safe(result)
197
198
  FileList[result]
198
199
  end
199
200
  end
@@ -208,6 +209,11 @@ module Cucumber
208
209
  FileList[result]
209
210
  end
210
211
  end
212
+
213
+ private
214
+ def make_command_line_safe(list)
215
+ list.map{|string| string.gsub(' ', '\ ')}
216
+ end
211
217
  end
212
218
 
213
219
  class FeatureTask < Task
@@ -34,7 +34,7 @@ module Cucumber
34
34
  end
35
35
 
36
36
  class NoStepMatch
37
- attr_reader :step_definition
37
+ attr_reader :step_definition, :name
38
38
 
39
39
  def initialize(step, name)
40
40
  @step = step
@@ -3,7 +3,7 @@ module Cucumber #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 3
5
5
  TINY = 11
6
- PATCH = 6 # Set to nil for official release
6
+ PATCH = 200907091518 # Set to nil for official release
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
9
9
  end
@@ -23,4 +23,5 @@ end
23
23
 
24
24
  require 'cucumber/rails/rspec'
25
25
  require 'webrat/core/matchers'
26
+ require 'cucumber/webrat/table_locator' # Lets you do table.diff!(table_at('#my_table').to_a)
26
27
  <% end -%>
@@ -25,7 +25,7 @@ Feature: Manage <%= plural_name %>
25
25
  <% end -%>
26
26
  When I delete the 3rd <%= singular_name %>
27
27
  Then I should see the following <%= plural_name %>:
28
- |<%= named_args.map(&:name).join('|') %>|
28
+ |<%= named_args.map{|arg| arg.name.humanize}.join('|') %>|
29
29
  <% [1,2,4].each do |n| -%>
30
30
  |<%= named_args.map{|arg| arg.value(n)}.join('|') %>|
31
31
  <% end -%>
@@ -9,12 +9,6 @@ When /^I delete the (\d+)(?:st|nd|rd|th) <%= singular_name %>$/ do |pos|
9
9
  end
10
10
  end
11
11
 
12
- Then /^I should see the following <%= plural_name %>:$/ do |<%= plural_name %>|
13
- <%= plural_name %>.rows.each_with_index do |row, i|
14
- row.each_with_index do |cell, j|
15
- response.should have_selector("table > tr:nth-child(#{i+2}) > td:nth-child(#{j+1})") { |td|
16
- td.inner_text.should == cell
17
- }
18
- end
19
- end
12
+ Then /^I should see the following <%= plural_name %>:$/ do |expected_<%= plural_name %>_table|
13
+ expected_<%= plural_name %>_table.diff!(table_at('table').to_a)
20
14
  end
@@ -168,6 +168,150 @@ module Cucumber
168
168
 
169
169
  end
170
170
 
171
+ describe "diff!" do
172
+ it "should detect a complex diff" do
173
+ t1 = table(%{
174
+ | 1 | 22 | 333 | 4444 |
175
+ | 55555 | 666666 | 7777777 | 88888888 |
176
+ | 999999999 | 0000000000 | 01010101010 | 121212121212 |
177
+ | 4000 | ABC | DEF | 50000 |
178
+ })
179
+
180
+ t2 = table(%{
181
+ | a | 4444 | 1 |
182
+ | bb | 88888888 | 55555 |
183
+ | ccc | xxxxxxxx | 999999999 |
184
+ | dddd | 4000 | 300 |
185
+ | e | 50000 | 4000 |
186
+ })
187
+ lambda{t1.diff!(t2)}.should raise_error
188
+ t1.to_s(:indent => 12, :color => false).should == %{
189
+ | 1 | (-) 22 | (-) 333 | 4444 | (+) a |
190
+ | 55555 | (-) 666666 | (-) 7777777 | 88888888 | (+) bb |
191
+ | (-) 999999999 | (-) 0000000000 | (-) 01010101010 | (-) 121212121212 | (+) |
192
+ | (+) 999999999 | (+) | (+) | (+) xxxxxxxx | (+) ccc |
193
+ | (+) 300 | (+) | (+) | (+) 4000 | (+) dddd |
194
+ | 4000 | (-) ABC | (-) DEF | 50000 | (+) e |
195
+ }
196
+ end
197
+
198
+ it "should not change table when diffed with identical" do
199
+ t = table(%{
200
+ |a|b|c|
201
+ |d|e|f|
202
+ |g|h|i|
203
+ })
204
+ t.diff!(t.dup)
205
+ t.to_s(:indent => 12, :color => false).should == %{
206
+ | a | b | c |
207
+ | d | e | f |
208
+ | g | h | i |
209
+ }
210
+ end
211
+
212
+ it "should inspect missing and surplus cells" do
213
+ t1 = Table.new([
214
+ ['name', 'male', 'lastname', 'swedish'],
215
+ ['aslak', 'true', 'hellesøy', 'false']
216
+ ])
217
+ t2 = Table.new([
218
+ ['name', 'male', 'lastname', 'swedish'],
219
+ ['aslak', true, 'hellesøy', false]
220
+ ])
221
+ lambda{t1.diff!(t2)}.should raise_error
222
+ t1.to_s(:indent => 12, :color => false).should == %{
223
+ | name | male | lastname | swedish |
224
+ | (-) aslak | (-) (i) "true" | (-) hellesøy | (-) (i) "false" |
225
+ | (+) aslak | (+) (i) true | (+) hellesøy | (+) (i) false |
226
+ }
227
+ end
228
+
229
+ it "should allow column mapping before diffing" do
230
+ t1 = Table.new([
231
+ ['name', 'male'],
232
+ ['aslak', 'true']
233
+ ])
234
+ t1.map_column!('male') { |m| m == 'true' }
235
+ t2 = Table.new([
236
+ ['name', 'male'],
237
+ ['aslak', true]
238
+ ])
239
+ t1.diff!(t2)
240
+ t1.to_s(:indent => 12, :color => false).should == %{
241
+ | name | male |
242
+ | aslak | true |
243
+ }
244
+ end
245
+
246
+ it "should allow header mapping before diffing" do
247
+ t1 = Table.new([
248
+ ['Name', 'Male'],
249
+ ['aslak', 'true']
250
+ ])
251
+ t1.map_headers!('Name' => 'name', 'Male' => 'male')
252
+ t1.map_column!('male') { |m| m == 'true' }
253
+ t2 = Table.new([
254
+ ['name', 'male'],
255
+ ['aslak', true]
256
+ ])
257
+ t1.diff!(t2)
258
+ t1.to_s(:indent => 12, :color => false).should == %{
259
+ | name | male |
260
+ | aslak | true |
261
+ }
262
+ end
263
+
264
+ describe "raising" do
265
+ before do
266
+ @t = table(%{
267
+ | a | b |
268
+ | c | d |
269
+ })
270
+ end
271
+
272
+ it "should raise on missing rows" do
273
+ t = table(%{
274
+ | a | b |
275
+ })
276
+ lambda { @t.dup.diff!(t) }.should raise_error
277
+ lambda { @t.dup.diff!(t, :missing_row => false) }.should_not raise_error
278
+ end
279
+
280
+ it "should raise on surplus rows" do
281
+ t = table(%{
282
+ | a | b |
283
+ | c | d |
284
+ | e | f |
285
+ })
286
+ lambda { @t.dup.diff!(t) }.should raise_error
287
+ lambda { @t.dup.diff!(t, :surplus_row => false) }.should_not raise_error
288
+ end
289
+
290
+ it "should raise on missing columns" do
291
+ t = table(%{
292
+ | a |
293
+ | c |
294
+ })
295
+ lambda { @t.dup.diff!(t) }.should raise_error
296
+ lambda { @t.dup.diff!(t, :missing_col => false) }.should_not raise_error
297
+ end
298
+
299
+ it "should not raise on surplus columns" do
300
+ t = table(%{
301
+ | a | b | x |
302
+ | c | d | y |
303
+ })
304
+ lambda { @t.dup.diff!(t) }.should_not raise_error
305
+ lambda { @t.dup.diff!(t, :surplus_col => true) }.should raise_error
306
+ end
307
+ end
308
+
309
+ def table(text, file=nil, line_offset=0)
310
+ @table_parser ||= Parser::TableParser.new
311
+ @table_parser.parse_or_fail(text.strip, file, line_offset)
312
+ end
313
+ end
314
+
171
315
  it "should convert to sexp" do
172
316
  @table.to_sexp.should ==
173
317
  [:table,