casecumber 1.0.2.1 → 1.2.1.cb2
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -1
- data/.travis.yml +13 -6
- data/Gemfile +2 -0
- data/History.md +139 -0
- data/LICENSE +1 -1
- data/README.md +19 -4
- data/cucumber.gemspec +16 -29
- data/cucumber.yml +3 -3
- data/examples/i18n/README.textile +1 -16
- data/features/.cucumber/stepdefs.json +612 -0
- data/features/backtraces.feature +36 -0
- data/features/doc_strings.feature +73 -0
- data/features/drb_server_integration.feature +63 -0
- data/features/formatter_step_file_colon_line.feature +46 -0
- data/features/json_formatter.feature +137 -137
- data/features/nested_steps.feature +60 -0
- data/features/rerun_formatter.feature +35 -0
- data/features/run_specific_scenarios.feature +47 -0
- data/features/step_definitions/cucumber-features/cucumber_ruby_mappings.rb +32 -3
- data/features/step_definitions/cucumber_steps.rb +15 -0
- data/features/step_definitions/drb_steps.rb +3 -0
- data/features/support/env.rb +4 -0
- data/features/support/feature_factory.rb +50 -0
- data/gem_tasks/cucumber.rake +15 -8
- data/gem_tasks/yard.rake +18 -0
- data/legacy_features/call_steps_from_stepdefs.feature +1 -1
- data/legacy_features/cucumber_cli.feature +0 -7
- data/legacy_features/default_snippets.feature +3 -2
- data/legacy_features/junit_formatter.feature +60 -10
- data/legacy_features/language_help.feature +17 -15
- data/legacy_features/snippets_when_using_star_keyword.feature +3 -2
- data/legacy_features/step_definitions/cucumber_steps.rb +1 -1
- data/legacy_features/support/env.rb +1 -1
- data/legacy_features/wire_protocol.feature +1 -1
- data/lib/cucumber/ast/background.rb +11 -0
- data/lib/cucumber/ast/doc_string.rb +10 -29
- data/lib/cucumber/ast/feature.rb +6 -2
- data/lib/cucumber/ast/feature_element.rb +7 -3
- data/lib/cucumber/ast/multiline_argument.rb +30 -0
- data/lib/cucumber/ast/outline_table.rb +20 -12
- data/lib/cucumber/ast/step.rb +1 -1
- data/lib/cucumber/ast/step_invocation.rb +2 -15
- data/lib/cucumber/ast/table.rb +67 -38
- data/lib/cucumber/ast/tags.rb +7 -7
- data/lib/cucumber/ast/tree_walker.rb +5 -5
- data/lib/cucumber/cli/configuration.rb +4 -0
- data/lib/cucumber/cli/main.rb +1 -0
- data/lib/cucumber/cli/options.rb +29 -10
- data/lib/cucumber/constantize.rb +1 -1
- data/lib/cucumber/core_ext/disable_mini_and_test_unit_autorun.rb +24 -10
- data/lib/cucumber/formatter/ansicolor.rb +8 -13
- data/lib/cucumber/formatter/console.rb +3 -2
- data/lib/cucumber/formatter/cucumber.css +7 -1
- data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +6 -2
- data/lib/cucumber/formatter/html.rb +14 -8
- data/lib/cucumber/formatter/interceptor.rb +62 -0
- data/lib/cucumber/formatter/json.rb +0 -12
- data/lib/cucumber/formatter/junit.rb +31 -15
- data/lib/cucumber/formatter/pretty.rb +3 -3
- data/lib/cucumber/formatter/progress.rb +1 -1
- data/lib/cucumber/formatter/rerun.rb +31 -8
- data/lib/cucumber/formatter/usage.rb +1 -1
- data/lib/cucumber/js_support/js_language.rb +1 -1
- data/lib/cucumber/js_support/js_snippets.rb +1 -1
- data/lib/cucumber/language_support/language_methods.rb +0 -4
- data/lib/cucumber/parser/gherkin_builder.rb +13 -14
- data/lib/cucumber/platform.rb +1 -1
- data/lib/cucumber/py_support/py_language.rb +3 -7
- data/lib/cucumber/rb_support/rb_dsl.rb +15 -8
- data/lib/cucumber/rb_support/rb_language.rb +3 -17
- data/lib/cucumber/rb_support/rb_step_definition.rb +17 -5
- data/lib/cucumber/rb_support/rb_transform.rb +5 -2
- data/lib/cucumber/rb_support/rb_world.rb +9 -5
- data/lib/cucumber/rb_support/regexp_argument_matcher.rb +3 -3
- data/lib/cucumber/runtime/results.rb +2 -2
- data/lib/cucumber/runtime/support_code.rb +14 -19
- data/lib/cucumber/runtime.rb +40 -2
- data/lib/cucumber/step_match.rb +3 -4
- data/lib/cucumber/term/ansicolor.rb +118 -0
- data/lib/cucumber/wire_support/wire_protocol/requests.rb +7 -5
- data/lib/cucumber/wire_support/wire_protocol.rb +0 -1
- data/lib/cucumber.rb +2 -1
- data/spec/cucumber/ast/doc_string_spec.rb +2 -2
- data/spec/cucumber/ast/feature_factory.rb +4 -3
- data/spec/cucumber/ast/scenario_outline_spec.rb +1 -2
- data/spec/cucumber/ast/step_spec.rb +1 -1
- data/spec/cucumber/ast/table_spec.rb +61 -27
- data/spec/cucumber/cli/configuration_spec.rb +12 -6
- data/spec/cucumber/cli/main_spec.rb +2 -2
- data/spec/cucumber/cli/options_spec.rb +9 -3
- data/spec/cucumber/constantize_spec.rb +16 -0
- data/spec/cucumber/formatter/ansicolor_spec.rb +1 -1
- data/spec/cucumber/formatter/html_spec.rb +4 -3
- data/spec/cucumber/formatter/interceptor_spec.rb +111 -0
- data/spec/cucumber/formatter/junit_spec.rb +36 -20
- data/spec/cucumber/formatter/progress_spec.rb +2 -2
- data/spec/cucumber/rb_support/rb_language_spec.rb +5 -5
- data/spec/cucumber/rb_support/rb_step_definition_spec.rb +20 -4
- data/spec/cucumber/rb_support/rb_transform_spec.rb +6 -2
- data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +7 -3
- data/spec/cucumber/runtime/results_spec.rb +81 -0
- data/spec/cucumber/step_match_spec.rb +8 -4
- data/spec/spec_helper.rb +15 -1
- metadata +68 -128
- data/.gitignore +0 -26
- data/.gitmodules +0 -3
- data/.yardopts +0 -0
- data/Gemfile.lock +0 -115
- data/examples/i18n/de/.gitignore +0 -1
- data/examples/i18n/en/.gitignore +0 -1
- data/examples/i18n/eo/.gitignore +0 -1
- data/examples/i18n/fi/.gitignore +0 -1
- data/examples/i18n/hu/.gitignore +0 -1
- data/examples/i18n/id/.gitignore +0 -1
- data/examples/i18n/ja/.gitignore +0 -1
- data/examples/i18n/ko/.gitignore +0 -1
- data/examples/i18n/lt/.gitignore +0 -1
- data/examples/i18n/pl/.gitignore +0 -1
- data/examples/i18n/sk/.gitignore +0 -1
- data/examples/i18n/tr/.gitignore +0 -1
- data/examples/i18n/zh-TW/.gitignore +0 -1
- data/examples/python/lib/.gitignore +0 -1
- data/examples/ruby2python/lib/.gitignore +0 -1
- data/examples/watir/.gitignore +0 -2
- data/fixtures/self_test/.gitignore +0 -1
- data/lib/cucumber/formatter/pdf.rb +0 -244
- data/lib/cucumber/step_argument.rb +0 -9
@@ -19,18 +19,25 @@ module Cucumber
|
|
19
19
|
|
20
20
|
class MissingProc < StandardError
|
21
21
|
def message
|
22
|
-
"Step definitions must always have a proc"
|
22
|
+
"Step definitions must always have a proc or symbol"
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
def initialize(rb_language, regexp,
|
27
|
-
raise MissingProc if
|
26
|
+
def initialize(rb_language, regexp, proc_or_sym, options)
|
27
|
+
raise MissingProc if proc_or_sym.nil?
|
28
28
|
if String === regexp
|
29
29
|
p = Regexp.escape(regexp)
|
30
30
|
p = p.gsub(/\\\$\w+/, '(.*)') # Replace $var with (.*)
|
31
31
|
regexp = Regexp.new("^#{p}$")
|
32
32
|
end
|
33
|
-
@rb_language, @regexp, @proc = rb_language, regexp,
|
33
|
+
@rb_language, @regexp, @proc = rb_language, regexp, proc_or_sym
|
34
|
+
if @proc.kind_of? Symbol
|
35
|
+
@proc = lambda do |*args|
|
36
|
+
target = options[:on] ? instance_exec(&options[:on]) : self
|
37
|
+
target.send(proc_or_sym, *args)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
34
41
|
@rb_language.available_step_definition(regexp_source, file_colon_line)
|
35
42
|
end
|
36
43
|
|
@@ -71,7 +78,12 @@ module Cucumber
|
|
71
78
|
end
|
72
79
|
|
73
80
|
def file_colon_line
|
74
|
-
@proc
|
81
|
+
case @proc
|
82
|
+
when Proc
|
83
|
+
@proc.file_colon_line
|
84
|
+
when Symbol
|
85
|
+
":#{@proc}"
|
86
|
+
end
|
75
87
|
end
|
76
88
|
|
77
89
|
def file
|
@@ -34,11 +34,14 @@ module Cucumber
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def to_s
|
37
|
-
|
37
|
+
convert_captures(strip_anchors(@regexp.source))
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
41
|
-
|
41
|
+
def convert_captures(regexp_source)
|
42
|
+
regexp_source.gsub(/(\()(?!\?:)/,'(?:')
|
43
|
+
end
|
44
|
+
|
42
45
|
def strip_captures(regexp_source)
|
43
46
|
regexp_source.
|
44
47
|
gsub(/(\()/, '').
|
@@ -4,7 +4,7 @@ module Cucumber
|
|
4
4
|
module RbSupport
|
5
5
|
# All steps are run in the context of an object that extends this module.
|
6
6
|
module RbWorld
|
7
|
-
|
7
|
+
AnsiEscapes = Gherkin::Formatter::AnsiEscapes
|
8
8
|
|
9
9
|
class << self
|
10
10
|
def alias_adverb(adverb)
|
@@ -17,12 +17,16 @@ module Cucumber
|
|
17
17
|
rb = @__cucumber_step_mother.load_programming_language('rb')
|
18
18
|
rb.execute_transforms([arg]).first
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
attr_writer :__cucumber_step_mother, :__natural_language
|
22
22
|
|
23
|
-
# Call a step from within a step definition. This method is aliased to
|
24
|
-
# the same i18n as RbDsl.
|
25
23
|
def __cucumber_invoke(name, multiline_argument=nil) #:nodoc:
|
24
|
+
STDERR.puts AnsiEscapes.failed + "WARNING: Using 'Given/When/Then' in step definitions is deprecated, use 'step' to call other steps instead:" + caller[0] + AnsiEscapes.reset
|
25
|
+
@__cucumber_step_mother.invoke(name, multiline_argument)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Invoke a single step.
|
29
|
+
def step(name, multiline_argument=nil)
|
26
30
|
@__cucumber_step_mother.invoke(name, multiline_argument)
|
27
31
|
end
|
28
32
|
|
@@ -42,7 +46,7 @@ module Cucumber
|
|
42
46
|
end
|
43
47
|
|
44
48
|
def announce(*messages)
|
45
|
-
STDERR.puts failed + "WARNING: #announce is deprecated. Use #puts instead:" + caller[0] + reset
|
49
|
+
STDERR.puts AnsiEscapes.failed + "WARNING: #announce is deprecated. Use #puts instead:" + caller[0] + AnsiEscapes.reset
|
46
50
|
puts(*messages)
|
47
51
|
end
|
48
52
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'gherkin/formatter/argument'
|
2
2
|
|
3
3
|
module Cucumber
|
4
4
|
module RbSupport
|
@@ -9,8 +9,8 @@ module Cucumber
|
|
9
9
|
n = 0
|
10
10
|
match.captures.map do |val|
|
11
11
|
n += 1
|
12
|
-
|
13
|
-
|
12
|
+
offset = match.offset(n)[0]
|
13
|
+
Gherkin::Formatter::Argument.new(offset, val)
|
14
14
|
end
|
15
15
|
else
|
16
16
|
nil
|
@@ -54,11 +54,11 @@ module Cucumber
|
|
54
54
|
if @configuration.wip?
|
55
55
|
scenarios(:passed).any?
|
56
56
|
else
|
57
|
-
scenarios(:failed).any? ||
|
57
|
+
scenarios(:failed).any? || steps(:failed).any? ||
|
58
58
|
(@configuration.strict? && (steps(:undefined).any? || steps(:pending).any?))
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'cucumber/constantize'
|
2
|
+
require 'cucumber/ast/multiline_argument'
|
2
3
|
require 'cucumber/runtime/for_programming_languages'
|
3
4
|
|
4
5
|
module Cucumber
|
6
|
+
|
5
7
|
class Runtime
|
6
8
|
|
7
9
|
class SupportCode
|
@@ -18,15 +20,7 @@ module Cucumber
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def step(step)
|
21
|
-
|
22
|
-
when Gherkin::Formatter::Model::DocString
|
23
|
-
step.multiline_arg.value
|
24
|
-
when Array
|
25
|
-
Ast::Table.new(step.multiline_arg.map{|row| row.cells})
|
26
|
-
else
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
@support_code.invoke(step.name, cucumber_multiline_arg)
|
23
|
+
@support_code.invoke(step.name, Ast::MultilineArgument.from(step.doc_string || step.rows))
|
30
24
|
end
|
31
25
|
|
32
26
|
def eof
|
@@ -58,6 +52,17 @@ module Cucumber
|
|
58
52
|
parser = Gherkin::Parser::Parser.new(StepInvoker.new(self), true, 'steps')
|
59
53
|
parser.parse(steps_text, file, line.to_i)
|
60
54
|
end
|
55
|
+
|
56
|
+
def invoke(step_name, multiline_argument=nil)
|
57
|
+
multiline_argument = Cucumber::Ast::MultilineArgument.from(multiline_argument)
|
58
|
+
# It is very important to leave multiline_argument=nil as a vararg. Cuke4Duke needs it that way.
|
59
|
+
begin
|
60
|
+
step_match(step_name).invoke(multiline_argument)
|
61
|
+
rescue Exception => e
|
62
|
+
e.nested! if Undefined === e
|
63
|
+
raise e
|
64
|
+
end
|
65
|
+
end
|
61
66
|
|
62
67
|
# Loads and registers programming language implementation.
|
63
68
|
# Instances are cached, so calling with the same argument
|
@@ -132,16 +137,6 @@ module Cucumber
|
|
132
137
|
matches[0]
|
133
138
|
end
|
134
139
|
|
135
|
-
def invoke(step_name, multiline_argument=nil)
|
136
|
-
# It is very important to leave multiline_argument=nil as a vararg. Cuke4Duke needs it that way.
|
137
|
-
begin
|
138
|
-
step_match(step_name).invoke(multiline_argument)
|
139
|
-
rescue Exception => e
|
140
|
-
e.nested! if Undefined === e
|
141
|
-
raise e
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
140
|
private
|
146
141
|
|
147
142
|
def guess_step_matches?
|
data/lib/cucumber/runtime.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'fileutils'
|
1
2
|
require 'gherkin/rubify'
|
2
3
|
require 'gherkin/i18n'
|
3
4
|
require 'cucumber/configuration'
|
@@ -118,6 +119,43 @@ module Cucumber
|
|
118
119
|
@support_code.unknown_programming_language?
|
119
120
|
end
|
120
121
|
|
122
|
+
def write_stepdefs_json
|
123
|
+
if(@configuration.dotcucumber)
|
124
|
+
stepdefs = []
|
125
|
+
@support_code.step_definitions.sort{|a,b| a.to_hash['source'] <=> a.to_hash['source']}.each do |stepdef|
|
126
|
+
stepdef_hash = stepdef.to_hash
|
127
|
+
steps = []
|
128
|
+
features.each do |feature|
|
129
|
+
feature.feature_elements.each do |feature_element|
|
130
|
+
feature_element.raw_steps.each do |step|
|
131
|
+
args = stepdef.arguments_from(step.name)
|
132
|
+
if(args)
|
133
|
+
steps << {
|
134
|
+
'name' => step.name,
|
135
|
+
'args' => args.map do |arg|
|
136
|
+
{
|
137
|
+
'offset' => arg.offset,
|
138
|
+
'val' => arg.val
|
139
|
+
}
|
140
|
+
end
|
141
|
+
}
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
stepdef_hash['file_colon_line'] = stepdef.file_colon_line
|
147
|
+
stepdef_hash['steps'] = steps.uniq.sort {|a,b| a['name'] <=> b['name']}
|
148
|
+
stepdefs << stepdef_hash
|
149
|
+
end
|
150
|
+
if !File.directory?(@configuration.dotcucumber)
|
151
|
+
FileUtils.mkdir_p(@configuration.dotcucumber)
|
152
|
+
end
|
153
|
+
File.open(File.join(@configuration.dotcucumber, 'stepdefs.json'), 'w') do |io|
|
154
|
+
io.write(JSON.pretty_generate(stepdefs))
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
121
159
|
private
|
122
160
|
|
123
161
|
def fire_after_configuration_hook #:nodoc
|
@@ -125,11 +163,11 @@ module Cucumber
|
|
125
163
|
end
|
126
164
|
|
127
165
|
def features
|
128
|
-
loader
|
166
|
+
@loader ||= Runtime::FeaturesLoader.new(
|
129
167
|
@configuration.feature_files,
|
130
168
|
@configuration.filters,
|
131
169
|
@configuration.tag_expression)
|
132
|
-
loader.features
|
170
|
+
@loader.features
|
133
171
|
end
|
134
172
|
|
135
173
|
def load_step_definitions
|
data/lib/cucumber/step_match.rb
CHANGED
@@ -20,7 +20,6 @@ module Cucumber
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def invoke(multiline_arg)
|
23
|
-
multiline_arg = Ast::DocString.new(multiline_arg) if String === multiline_arg
|
24
23
|
all_args = args
|
25
24
|
all_args << multiline_arg.to_step_definition_arg if multiline_arg
|
26
25
|
@step_definition.invoke(all_args)
|
@@ -61,7 +60,7 @@ module Cucumber
|
|
61
60
|
s = string.dup
|
62
61
|
offset = past_offset = 0
|
63
62
|
step_arguments.each do |step_argument|
|
64
|
-
next if step_argument.
|
63
|
+
next if step_argument.offset.nil? || step_argument.offset < past_offset
|
65
64
|
|
66
65
|
replacement = if block_given?
|
67
66
|
proc.call(step_argument.val)
|
@@ -71,9 +70,9 @@ module Cucumber
|
|
71
70
|
format % step_argument.val
|
72
71
|
end
|
73
72
|
|
74
|
-
s[step_argument.
|
73
|
+
s[step_argument.offset + offset, step_argument.val.length] = replacement
|
75
74
|
offset += replacement.unpack('U*').length - step_argument.val.unpack('U*').length
|
76
|
-
past_offset = step_argument.
|
75
|
+
past_offset = step_argument.offset + step_argument.val.length
|
77
76
|
end
|
78
77
|
s
|
79
78
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Term
|
3
|
+
# The ANSIColor module can be used for namespacing and mixed into your own
|
4
|
+
# classes.
|
5
|
+
module ANSIColor
|
6
|
+
# :stopdoc:
|
7
|
+
ATTRIBUTES = [
|
8
|
+
[ :clear , 0 ],
|
9
|
+
[ :reset , 0 ], # synonym for :clear
|
10
|
+
[ :bold , 1 ],
|
11
|
+
[ :dark , 2 ],
|
12
|
+
[ :italic , 3 ], # not widely implemented
|
13
|
+
[ :underline , 4 ],
|
14
|
+
[ :underscore , 4 ], # synonym for :underline
|
15
|
+
[ :blink , 5 ],
|
16
|
+
[ :rapid_blink , 6 ], # not widely implemented
|
17
|
+
[ :negative , 7 ], # no reverse because of String#reverse
|
18
|
+
[ :concealed , 8 ],
|
19
|
+
[ :strikethrough, 9 ], # not widely implemented
|
20
|
+
[ :black , 30 ],
|
21
|
+
[ :red , 31 ],
|
22
|
+
[ :green , 32 ],
|
23
|
+
[ :yellow , 33 ],
|
24
|
+
[ :blue , 34 ],
|
25
|
+
[ :magenta , 35 ],
|
26
|
+
[ :cyan , 36 ],
|
27
|
+
[ :white , 37 ],
|
28
|
+
[ :on_black , 40 ],
|
29
|
+
[ :on_red , 41 ],
|
30
|
+
[ :on_green , 42 ],
|
31
|
+
[ :on_yellow , 43 ],
|
32
|
+
[ :on_blue , 44 ],
|
33
|
+
[ :on_magenta , 45 ],
|
34
|
+
[ :on_cyan , 46 ],
|
35
|
+
[ :on_white , 47 ],
|
36
|
+
]
|
37
|
+
|
38
|
+
ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
|
39
|
+
# :startdoc:
|
40
|
+
|
41
|
+
# Returns true, if the coloring function of this module
|
42
|
+
# is switched on, false otherwise.
|
43
|
+
def self.coloring?
|
44
|
+
@coloring
|
45
|
+
end
|
46
|
+
|
47
|
+
# Turns the coloring on or off globally, so you can easily do
|
48
|
+
# this for example:
|
49
|
+
# Cucumber::Term::ANSIColor::coloring = STDOUT.isatty
|
50
|
+
def self.coloring=(val)
|
51
|
+
@coloring = val
|
52
|
+
end
|
53
|
+
self.coloring = true
|
54
|
+
|
55
|
+
ATTRIBUTES.each do |c, v|
|
56
|
+
eval %Q{
|
57
|
+
def #{c}(string = nil)
|
58
|
+
result = ''
|
59
|
+
result << "\e[#{v}m" if Cucumber::Term::ANSIColor.coloring?
|
60
|
+
if block_given?
|
61
|
+
result << yield
|
62
|
+
elsif string
|
63
|
+
result << string
|
64
|
+
elsif respond_to?(:to_str)
|
65
|
+
result << to_str
|
66
|
+
else
|
67
|
+
return result #only switch on
|
68
|
+
end
|
69
|
+
result << "\e[0m" if Cucumber::Term::ANSIColor.coloring?
|
70
|
+
result
|
71
|
+
end
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
# Regular expression that is used to scan for ANSI-sequences while
|
76
|
+
# uncoloring strings.
|
77
|
+
COLORED_REGEXP = /\e\[(?:[34][0-7]|[0-9])?m/
|
78
|
+
|
79
|
+
|
80
|
+
def self.included(klass)
|
81
|
+
if version_is_greater_than_18? and klass == String
|
82
|
+
ATTRIBUTES.delete(:clear)
|
83
|
+
ATTRIBUTE_NAMES.delete(:clear)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns an uncolored version of the string, that is all
|
88
|
+
# ANSI-sequences are stripped from the string.
|
89
|
+
def uncolored(string = nil) # :yields:
|
90
|
+
if block_given?
|
91
|
+
yield.gsub(COLORED_REGEXP, '')
|
92
|
+
elsif string
|
93
|
+
string.gsub(COLORED_REGEXP, '')
|
94
|
+
elsif respond_to?(:to_str)
|
95
|
+
to_str.gsub(COLORED_REGEXP, '')
|
96
|
+
else
|
97
|
+
''
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
module_function
|
102
|
+
|
103
|
+
# Returns an array of all Cucumber::Term::ANSIColor attributes as symbols.
|
104
|
+
def attributes
|
105
|
+
ATTRIBUTE_NAMES
|
106
|
+
end
|
107
|
+
extend self
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def version_is_greater_than_18?
|
112
|
+
version = RUBY_VERSION.split('.')
|
113
|
+
version.map! &:to_i
|
114
|
+
version[0] >= 1 && version[1] > 8
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'cucumber/wire_support/request_handler'
|
2
|
+
require 'gherkin/formatter/argument'
|
3
|
+
|
2
4
|
module Cucumber
|
3
5
|
module WireSupport
|
4
6
|
module WireProtocol
|
@@ -25,7 +27,7 @@ module Cucumber
|
|
25
27
|
def create_step_match(raw_step_match)
|
26
28
|
step_definition = WireStepDefinition.new(@connection, raw_step_match)
|
27
29
|
step_args = raw_step_match['args'].map do |raw_arg|
|
28
|
-
|
30
|
+
Gherkin::Formatter::Argument.new(raw_arg['pos'], raw_arg['val'])
|
29
31
|
end
|
30
32
|
step_match(step_definition, step_args)
|
31
33
|
end
|
@@ -92,13 +94,13 @@ module Cucumber
|
|
92
94
|
end
|
93
95
|
|
94
96
|
module Tags
|
95
|
-
def
|
96
|
-
scenario.
|
97
|
+
def clean_tag_names(scenario)
|
98
|
+
scenario.source_tags.map { |tag| tag.name.gsub(/^@/, '') }.sort
|
97
99
|
end
|
98
100
|
|
99
101
|
def request_params(scenario)
|
100
|
-
return nil unless scenario.
|
101
|
-
{ "tags" =>
|
102
|
+
return nil unless scenario.source_tags.any?
|
103
|
+
{ "tags" => clean_tag_names(scenario) }
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
data/lib/cucumber.rb
CHANGED
@@ -8,6 +8,7 @@ require 'cucumber/step_mother'
|
|
8
8
|
require 'cucumber/cli/main'
|
9
9
|
require 'cucumber/broadcaster'
|
10
10
|
require 'cucumber/step_definitions'
|
11
|
+
require 'cucumber/term/ansicolor'
|
11
12
|
|
12
13
|
module Cucumber
|
13
14
|
class << self
|
@@ -24,4 +25,4 @@ module Cucumber
|
|
24
25
|
@log = logger
|
25
26
|
end
|
26
27
|
end
|
27
|
-
end
|
28
|
+
end
|
@@ -7,7 +7,7 @@ module Cucumber
|
|
7
7
|
describe "replacing arguments" do
|
8
8
|
|
9
9
|
before(:each) do
|
10
|
-
@ps = DocString.new("<book>\n<qty>\n")
|
10
|
+
@ps = DocString.new("<book>\n<qty>\n", '')
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should return a new doc_string with arguments replaced with values" do
|
@@ -23,7 +23,7 @@ module Cucumber
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it "should replaced nil with empty string" do
|
26
|
-
ps = DocString.new("'<book>'")
|
26
|
+
ps = DocString.new("'<book>'", '')
|
27
27
|
doc_string_with_replaced_arg = ps.arguments_replaced({'<book>' => nil})
|
28
28
|
|
29
29
|
doc_string_with_replaced_arg.to_step_definition_arg.should == "''"
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'cucumber/ast'
|
2
2
|
require 'cucumber/step_mother'
|
3
|
+
require 'gherkin/formatter/model'
|
3
4
|
|
4
5
|
module Cucumber
|
5
6
|
module Ast
|
@@ -24,7 +25,7 @@ module Cucumber
|
|
24
25
|
%w{1 22 333},
|
25
26
|
%w{4444 55555 666666}
|
26
27
|
])
|
27
|
-
doc_string = Ast::DocString.new(%{\n I like\nCucumber sandwich\n})
|
28
|
+
doc_string = Ast::DocString.new(%{\n I like\nCucumber sandwich\n}, '')
|
28
29
|
|
29
30
|
background = Ast::Background.new(Ast::Comment.new(""), 2, "Background:", "", "",
|
30
31
|
[
|
@@ -35,14 +36,14 @@ module Cucumber
|
|
35
36
|
f = Ast::Feature.new(
|
36
37
|
background,
|
37
38
|
Ast::Comment.new("# My feature comment\n"),
|
38
|
-
Ast::Tags.new(6, ['one', 'two']),
|
39
|
+
Ast::Tags.new(6, [Gherkin::Formatter::Model::Tag.new('one', 6), Gherkin::Formatter::Model::Tag.new('two', 6)]),
|
39
40
|
"Feature",
|
40
41
|
"Pretty printing",
|
41
42
|
"",
|
42
43
|
[Ast::Scenario.new(
|
43
44
|
background,
|
44
45
|
Ast::Comment.new(" # My scenario comment \n# On two lines \n"),
|
45
|
-
Ast::Tags.new(8, ['three', 'four']),
|
46
|
+
Ast::Tags.new(8, [Gherkin::Formatter::Model::Tag.new('three', 8), Gherkin::Formatter::Model::Tag.new('four', 8)]),
|
46
47
|
9,
|
47
48
|
"Scenario:", "A Scenario", "",
|
48
49
|
[
|
@@ -48,7 +48,7 @@ module Cucumber
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it "should replace arguments in py string arg" do
|
51
|
-
doc_string = DocString.new('taste_<taste> color_<color>')
|
51
|
+
doc_string = DocString.new('taste_<taste> color_<color>', '')
|
52
52
|
|
53
53
|
step = Step.new(1, 'Given', 'a <color> cucumber', doc_string)
|
54
54
|
|
@@ -45,40 +45,54 @@ module Cucumber
|
|
45
45
|
@table.hashes.first[:one].should == '4444'
|
46
46
|
end
|
47
47
|
|
48
|
-
it "should
|
49
|
-
@table.
|
50
|
-
@table.hashes.first['one'].should == 4444
|
48
|
+
it "should return the row values in order" do
|
49
|
+
@table.rows.first.should == %w{4444 55555 666666}
|
51
50
|
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
describe '#map_column!' do
|
53
|
+
it "should allow mapping columns" do
|
54
|
+
@table.map_column!('one') { |v| v.to_i }
|
55
|
+
@table.hashes.first['one'].should == 4444
|
56
|
+
end
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
it "applies the block once to each value" do
|
59
|
+
headers = ['header']
|
60
|
+
rows = ['value']
|
61
|
+
table = Table.new [headers, rows]
|
62
|
+
count = 0
|
63
|
+
table.map_column!('header') { |value| count +=1 }
|
64
|
+
table.rows
|
65
|
+
count.should eq rows.size
|
66
|
+
end
|
63
67
|
|
64
|
-
|
65
|
-
|
66
|
-
|
68
|
+
it "should allow mapping columns and take a symbol as the column name" do
|
69
|
+
@table.map_column!(:one) { |v| v.to_i }
|
70
|
+
@table.hashes.first['one'].should == 4444
|
71
|
+
end
|
67
72
|
|
68
|
-
|
69
|
-
|
70
|
-
@table.
|
71
|
-
|
72
|
-
|
73
|
+
it "should allow mapping columns and modify the rows as well" do
|
74
|
+
@table.map_column!(:one) { |v| v.to_i }
|
75
|
+
@table.rows.first.should include(4444)
|
76
|
+
@table.rows.first.should_not include('4444')
|
77
|
+
end
|
73
78
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
+
it "should pass silently if a mapped column does not exist in non-strict mode" do
|
80
|
+
lambda {
|
81
|
+
@table.map_column!('two', false) { |v| v.to_i }
|
82
|
+
@table.hashes
|
83
|
+
}.should_not raise_error
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should fail if a mapped column does not exist in strict mode" do
|
87
|
+
lambda {
|
88
|
+
@table.map_column!('two', true) { |v| v.to_i }
|
89
|
+
@table.hashes
|
90
|
+
}.should raise_error('The column named "two" does not exist')
|
91
|
+
end
|
79
92
|
|
80
|
-
|
81
|
-
|
93
|
+
it "should return the table" do
|
94
|
+
(@table.map_column!(:one) { |v| v.to_i }).should == @table
|
95
|
+
end
|
82
96
|
end
|
83
97
|
|
84
98
|
describe "#match" do
|
@@ -132,6 +146,16 @@ module Cucumber
|
|
132
146
|
faulty_table.rows_hash
|
133
147
|
}.should raise_error('The table must have exactly 2 columns')
|
134
148
|
end
|
149
|
+
|
150
|
+
it "should support header and column mapping" do
|
151
|
+
table = Table.new([
|
152
|
+
%w{one 1111},
|
153
|
+
%w{two 22222}
|
154
|
+
])
|
155
|
+
table.map_headers!({ 'two' => 'Two' }) { |header| header.upcase }
|
156
|
+
table.map_column!('two', false) { |val| val.to_i }
|
157
|
+
table.rows_hash.should == { 'ONE' => '1111', 'Two' => 22222 }
|
158
|
+
end
|
135
159
|
end
|
136
160
|
|
137
161
|
describe '#map_headers' do
|
@@ -378,6 +402,7 @@ module Cucumber
|
|
378
402
|
])
|
379
403
|
lambda do
|
380
404
|
t1.map_headers!(/uk/ => 'u')
|
405
|
+
t1.hashes
|
381
406
|
end.should raise_error(%{2 headers matched /uk/: ["Cuke", "Duke"]})
|
382
407
|
end
|
383
408
|
|
@@ -449,6 +474,15 @@ module Cucumber
|
|
449
474
|
lambda { @t.dup.diff!(t) }.should_not raise_error
|
450
475
|
lambda { @t.dup.diff!(t, :surplus_col => true) }.should raise_error
|
451
476
|
end
|
477
|
+
|
478
|
+
it "should not raise on misplaced columns" do
|
479
|
+
t = table(%{
|
480
|
+
| b | a |
|
481
|
+
| d | c |
|
482
|
+
}, __FILE__, __LINE__)
|
483
|
+
lambda { @t.dup.diff!(t) }.should_not raise_error
|
484
|
+
lambda { @t.dup.diff!(t, :misplaced_col => true) }.should raise_error
|
485
|
+
end
|
452
486
|
end
|
453
487
|
|
454
488
|
def table(text, file, offset)
|