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.
- data/History.txt +49 -1
- data/Manifest.txt +3 -0
- data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +1 -1
- data/examples/self_test/features/support/env.rb +2 -1
- data/examples/steps_library/features/step_definitions/steps_lib1.rb +8 -0
- data/examples/steps_library/features/step_definitions/steps_lib2.rb +8 -0
- data/examples/tickets/features/step_definitons/tickets_steps.rb +15 -0
- data/features/html_formatter/a.html +4 -4
- data/features/rake_task.feature +28 -0
- data/features/steps_formatter.feature +25 -0
- data/features/support/env.rb +5 -0
- data/lib/cucumber/ast/outline_table.rb +2 -1
- data/lib/cucumber/ast/py_string.rb +0 -1
- data/lib/cucumber/ast/step.rb +4 -1
- data/lib/cucumber/ast/table.rb +286 -48
- data/lib/cucumber/ast/visitor.rb +2 -1
- data/lib/cucumber/cli/configuration.rb +8 -2
- data/lib/cucumber/cli/language_help_formatter.rb +9 -7
- data/lib/cucumber/feature_file.rb +7 -1
- data/lib/cucumber/filter.rb +2 -2
- data/lib/cucumber/formatter/html.rb +1 -1
- data/lib/cucumber/formatter/pretty.rb +20 -5
- data/lib/cucumber/formatter/progress.rb +1 -1
- data/lib/cucumber/formatter/steps.rb +49 -0
- data/lib/cucumber/parser/feature.rb +27 -0
- data/lib/cucumber/parser/i18n/language.rb +8 -5
- data/lib/cucumber/rake/task.rb +6 -0
- data/lib/cucumber/step_match.rb +1 -1
- data/lib/cucumber/version.rb +1 -1
- data/rails_generators/cucumber/templates/env.rb +1 -0
- data/rails_generators/feature/templates/feature.erb +1 -1
- data/rails_generators/feature/templates/steps.erb +2 -8
- data/spec/cucumber/ast/table_spec.rb +144 -0
- data/spec/cucumber/cli/configuration_spec.rb +13 -0
- data/spec/cucumber/cli/main_spec.rb +0 -1
- data/spec/cucumber/formatter/progress_spec.rb +2 -2
- metadata +8 -4
data/lib/cucumber/ast/visitor.rb
CHANGED
@@ -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,
|
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
|
-
|
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] ||
|
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}
|
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
|
-
|
26
|
-
|
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 =>
|
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,
|
46
|
+
def visit_table_cell_value(value, status)
|
45
47
|
if @col == 1
|
46
48
|
if(@options[:check_lang])
|
47
|
-
@incomplete =
|
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,
|
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
|
-
|
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
|
|
data/lib/cucumber/filter.rb
CHANGED
@@ -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.
|
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,
|
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
|
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
|
-
@
|
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
|
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
|
-
|
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)
|
@@ -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 =
|
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
|
65
|
+
def incomplete?
|
63
66
|
KEYWORD_KEYS.detect{|key| @keywords[key].nil?}
|
64
67
|
end
|
65
68
|
|
data/lib/cucumber/rake/task.rb
CHANGED
@@ -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
|
data/lib/cucumber/step_match.rb
CHANGED
data/lib/cucumber/version.rb
CHANGED
@@ -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
|
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
|
13
|
-
<%= plural_name
|
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,
|