aslakhellesoy-cucumber 0.1.99.15 → 0.1.99.17
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 +1 -0
- data/Manifest.txt +5 -0
- data/examples/tickets/features/177-1.feature +29 -0
- data/examples/tickets/features/177-2.feature +21 -0
- data/examples/tickets/features/180.feature +7 -0
- data/features/cucumber_cli.feature +1 -1
- data/features/report_called_undefined_steps.feature +2 -2
- data/features/support/env.rb +1 -0
- data/gem_tasks/jar.rake +67 -0
- data/lib/cucumber.rb +0 -1
- data/lib/cucumber/ast/step.rb +2 -2
- data/lib/cucumber/cli/configuration.rb +336 -0
- data/lib/cucumber/cli/language_help_formatter.rb +1 -1
- data/lib/cucumber/cli/main.rb +65 -355
- data/lib/cucumber/formatter/ansicolor.rb +2 -2
- data/lib/cucumber/formatter/console.rb +1 -1
- data/lib/cucumber/parser/feature.rb +34 -21
- data/lib/cucumber/parser/feature.tt +16 -5
- data/lib/cucumber/parser/table.rb +6 -0
- data/lib/cucumber/parser/table.tt +6 -0
- data/lib/cucumber/parser/treetop_ext.rb +12 -4
- data/lib/cucumber/step_mother.rb +52 -33
- data/lib/cucumber/version.rb +1 -1
- data/spec/cucumber/cli/configuration_spec.rb +239 -0
- data/spec/cucumber/cli/main_spec.rb +10 -264
- data/spec/cucumber/parser/feature_parser_spec.rb +1 -1
- data/spec/cucumber/step_definition_spec.rb +2 -2
- data/spec/cucumber/step_mother_spec.rb +27 -3
- metadata +9 -2
data/History.txt
CHANGED
@@ -94,6 +94,7 @@ pure Ruby users have been enjoying for a while.
|
|
94
94
|
* Run cucumber --language LANG help to see keywords for a given language. (Aslak Hellesøy)
|
95
95
|
* Multiline arguments (tables and """ strings) are printed in the output. (Aslak Hellesøy)
|
96
96
|
* It's no longer necessary to compile the Treetop grammar when adding a new language. Localised parser is generated at runtime. (Aslak Hellesøy)
|
97
|
+
* New --guess option tries to guess the best step definition match instead of raising Cucumber::Multiple. (Jake Howerton)
|
97
98
|
|
98
99
|
=== Removed features
|
99
100
|
* "GivenScenario" is gone. Instead you can call Steps from Steps, or wait for "Background (#153)"
|
data/Manifest.txt
CHANGED
@@ -138,6 +138,9 @@ examples/test_unit/features/test_unit.feature
|
|
138
138
|
examples/tickets/Rakefile
|
139
139
|
examples/tickets/cucumber.yml
|
140
140
|
examples/tickets/features/172.feature
|
141
|
+
examples/tickets/features/177-1.feature
|
142
|
+
examples/tickets/features/177-2.feature
|
143
|
+
examples/tickets/features/180.feature
|
141
144
|
examples/tickets/features/lib/eatting_machine.rb
|
142
145
|
examples/tickets/features/lib/pantry.rb
|
143
146
|
examples/tickets/features/scenario_outline.feature
|
@@ -188,6 +191,7 @@ lib/cucumber/ast/table.rb
|
|
188
191
|
lib/cucumber/ast/tags.rb
|
189
192
|
lib/cucumber/ast/visitor.rb
|
190
193
|
lib/cucumber/broadcaster.rb
|
194
|
+
lib/cucumber/cli/configuration.rb
|
191
195
|
lib/cucumber/cli/language_help_formatter.rb
|
192
196
|
lib/cucumber/cli/main.rb
|
193
197
|
lib/cucumber/core_ext/exception.rb
|
@@ -240,6 +244,7 @@ spec/cucumber/ast/scenario_spec.rb
|
|
240
244
|
spec/cucumber/ast/step_spec.rb
|
241
245
|
spec/cucumber/ast/table_spec.rb
|
242
246
|
spec/cucumber/broadcaster_spec.rb
|
247
|
+
spec/cucumber/cli/configuration_spec.rb
|
243
248
|
spec/cucumber/cli/main_spec.rb
|
244
249
|
spec/cucumber/core_ext/proc_spec.rb
|
245
250
|
spec/cucumber/core_ext/string_spec.rb
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Users want to know that nobody can masquerade as them. We want to extend trust
|
2
|
+
only to visitors who present the appropriate credentials. Everyone wants this
|
3
|
+
identity verification to be as secure and convenient as possible.
|
4
|
+
|
5
|
+
Feature: Logging in
|
6
|
+
As an anonymous user with an account
|
7
|
+
I want to log in to my account
|
8
|
+
So that I can be myself
|
9
|
+
|
10
|
+
#
|
11
|
+
# Log in: get form
|
12
|
+
#
|
13
|
+
Scenario: Anonymous user can get a login form.
|
14
|
+
Given I am logged out
|
15
|
+
When I go to "/login"
|
16
|
+
Then I should be at the "sessions/new" page
|
17
|
+
|
18
|
+
#
|
19
|
+
# Log in successfully, but don't remember me
|
20
|
+
#
|
21
|
+
Scenario: Anonymous user can log in
|
22
|
+
Given an "activated" user named "reggie" exists
|
23
|
+
And I am logged out
|
24
|
+
When I go to "/login"
|
25
|
+
And I fill in "Login" with "reggie"
|
26
|
+
And I fill in "Password" with "password"
|
27
|
+
And I press "Log in"
|
28
|
+
Then I should be at the "dashboard/index" page
|
29
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Visitors may create an account, but for those who are not already in the
|
2
|
+
system an someone must activate the account for them before it can be used.
|
3
|
+
|
4
|
+
Feature: Activating an account
|
5
|
+
As a registered, but not yet activated, user
|
6
|
+
I want to be able to activate my account
|
7
|
+
So that I can log in to the site
|
8
|
+
|
9
|
+
Scenario: Not-yet-activated user can activate her account
|
10
|
+
Given a registered user named 'Reggie' # need to rewrite
|
11
|
+
# And the user has activation_code: 'activate_me', activated_at: nil!
|
12
|
+
# And we try hard to remember the user's updated_at, and created_at
|
13
|
+
# When she goes to /activate/activate_me
|
14
|
+
# Then she should be redirected to 'login'
|
15
|
+
# When she follows that redirect!
|
16
|
+
# Then she should see a notice message 'Signup complete!'
|
17
|
+
# And a user with login: 'reggie' should exist
|
18
|
+
# And the user should have login: 'reggie', and email: 'registered@example.com'
|
19
|
+
# And the user's activation_code should be nil
|
20
|
+
# And the user's activated_at should not be nil
|
21
|
+
# And she should not be logged in
|
@@ -28,7 +28,7 @@ Feature: Cucumber command line
|
|
28
28
|
@two @three
|
29
29
|
Scenario: Missing
|
30
30
|
Given missing
|
31
|
-
Undefined step: "missing" (Cucumber::
|
31
|
+
Undefined step: "missing" (Cucumber::Undefined)
|
32
32
|
features/sample.feature:6:in `Given missing'
|
33
33
|
|
34
34
|
1 scenario
|
@@ -10,12 +10,12 @@ Feature: Cucumber command line
|
|
10
10
|
|
11
11
|
Scenario: Call directly # features/call_undefined_step_from_step_def.feature:3
|
12
12
|
Given a step definition that calls an undefined step # features/step_definitions/sample_steps.rb:19
|
13
|
-
Undefined step: "this does not exist" (Cucumber::
|
13
|
+
Undefined step: "this does not exist" (Cucumber::Undefined)
|
14
14
|
./features/step_definitions/sample_steps.rb:20:in `/^a step definition that calls an undefined step$/'
|
15
15
|
|
16
16
|
Scenario: Call via another # features/call_undefined_step_from_step_def.feature:6
|
17
17
|
Given call step "a step definition that calls an undefined step" # features/step_definitions/sample_steps.rb:23
|
18
|
-
Undefined step: "this does not exist" (Cucumber::
|
18
|
+
Undefined step: "this does not exist" (Cucumber::Undefined)
|
19
19
|
./features/step_definitions/sample_steps.rb:20:in `/^a step definition that calls an undefined step$/'
|
20
20
|
|
21
21
|
2 scenarios
|
data/features/support/env.rb
CHANGED
data/gem_tasks/jar.rake
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# http://blog.nicksieger.com/articles/2009/01/10/jruby-1-1-6-gems-in-a-jar
|
2
|
+
|
3
|
+
USE_JRUBY_VERSION = '1.1.6'
|
4
|
+
USE_JBEHAVE_VERSION = '2.1'
|
5
|
+
USE_JUNIT_VERSION = '4.5'
|
6
|
+
USE_HAMCREST_VERSION = '1.1'
|
7
|
+
CUCUMBER_VERSIONED = "cucumber-#{Cucumber::VERSION::STRING}"
|
8
|
+
|
9
|
+
task :jar => [
|
10
|
+
:clean,
|
11
|
+
'jar:download_jruby',
|
12
|
+
'jar:install_gems',
|
13
|
+
'jar:bundle_gems',
|
14
|
+
'jar:download_jars_deps',
|
15
|
+
'jar:unpack_jar_deps',
|
16
|
+
'jar:bundle_jars',
|
17
|
+
'jar:fix_gem_binaries',
|
18
|
+
'jar:test_jar'
|
19
|
+
]
|
20
|
+
|
21
|
+
namespace :jar do
|
22
|
+
task :download_jruby do
|
23
|
+
sh "wget http://dist.codehaus.org/jruby/#{USE_JRUBY_VERSION}/jruby-complete-#{USE_JRUBY_VERSION}.jar -O #{CUCUMBER_VERSIONED}.jar"
|
24
|
+
end
|
25
|
+
|
26
|
+
task :install_gems => :gem do
|
27
|
+
mkdir 'pkg/jar_gems'
|
28
|
+
sh "java -jar #{CUCUMBER_VERSIONED}.jar -S gem install -i ./pkg/jar_gems pkg/#{CUCUMBER_VERSIONED}.gem --no-ri --no-rdoc"
|
29
|
+
end
|
30
|
+
|
31
|
+
task :bundle_gems do
|
32
|
+
sh "jar uf #{CUCUMBER_VERSIONED}.jar -C pkg/jar_gems ."
|
33
|
+
end
|
34
|
+
|
35
|
+
task :download_jars_deps do
|
36
|
+
mkdir 'pkg/jar_deps'
|
37
|
+
sh "wget http://repository.codehaus.org/org/jbehave/jbehave-core/#{USE_JBEHAVE_VERSION}/jbehave-core-#{USE_JBEHAVE_VERSION}.jar -O pkg/jar_deps/jbehave-core-#{USE_JBEHAVE_VERSION}.jar"
|
38
|
+
sh "wget http://mirrors.ibiblio.org/pub/mirrors/maven2/junit/junit/#{USE_JUNIT_VERSION}/junit-#{USE_JUNIT_VERSION}.jar -O pkg/jar_deps/junit-#{USE_JUNIT_VERSION}.jar"
|
39
|
+
sh "wget http://hamcrest.googlecode.com/files/hamcrest-all-#{USE_HAMCREST_VERSION}.jar -O pkg/jar_deps/hamcrest-all-#{USE_HAMCREST_VERSION}.jar"
|
40
|
+
end
|
41
|
+
|
42
|
+
task :unpack_jar_deps do
|
43
|
+
Dir.chdir 'pkg/jar_deps' do
|
44
|
+
Dir['*.jar'].each do |jar|
|
45
|
+
sh "jar xvf #{jar}"
|
46
|
+
rm_rf jar
|
47
|
+
rm_rf 'META-INF'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
task :bundle_jars do
|
53
|
+
sh "jar uf #{CUCUMBER_VERSIONED}.jar -C pkg/jar_deps ."
|
54
|
+
end
|
55
|
+
|
56
|
+
task :fix_gem_binaries do
|
57
|
+
mkdir_p 'pkg/gem_binaries/META-INF/jruby.home'
|
58
|
+
Dir.chdir 'pkg/gem_binaries/META-INF/jruby.home' do
|
59
|
+
sh "jar xvf ../../../../#{CUCUMBER_VERSIONED}.jar bin"
|
60
|
+
end
|
61
|
+
sh "jar uf #{CUCUMBER_VERSIONED}.jar -C pkg/gem_binaries ."
|
62
|
+
end
|
63
|
+
|
64
|
+
task :test_jar do
|
65
|
+
sh "java -cp examples/jbehave/target/classes -jar #{CUCUMBER_VERSIONED}.jar -S cucumber examples/jbehave/features"
|
66
|
+
end
|
67
|
+
end
|
data/lib/cucumber.rb
CHANGED
data/lib/cucumber/ast/step.rb
CHANGED
@@ -104,14 +104,14 @@ module Cucumber
|
|
104
104
|
else
|
105
105
|
@status = :skipped
|
106
106
|
end
|
107
|
-
rescue
|
107
|
+
rescue Undefined => exception
|
108
108
|
if visitor.options[:strict]
|
109
109
|
exception.set_backtrace([])
|
110
110
|
failed(exception)
|
111
111
|
else
|
112
112
|
@status = :undefined
|
113
113
|
end
|
114
|
-
rescue
|
114
|
+
rescue Pending => exception
|
115
115
|
visitor.options[:strict] ? failed(exception) : @status = :pending
|
116
116
|
rescue Exception => exception
|
117
117
|
failed(exception)
|
@@ -0,0 +1,336 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Cli
|
3
|
+
class YmlLoadError < StandardError; end
|
4
|
+
|
5
|
+
class Configuration
|
6
|
+
FORMATS = %w{pretty profile progress rerun}
|
7
|
+
DEFAULT_FORMAT = 'pretty'
|
8
|
+
|
9
|
+
attr_reader :paths
|
10
|
+
attr_reader :options
|
11
|
+
|
12
|
+
def initialize(out_stream = STDOUT, error_stream = STDERR)
|
13
|
+
@out_stream = out_stream
|
14
|
+
@error_stream = error_stream
|
15
|
+
|
16
|
+
@paths = []
|
17
|
+
@options = default_options
|
18
|
+
@active_format = DEFAULT_FORMAT
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse!(args)
|
22
|
+
@args = args
|
23
|
+
return parse_args_from_profile('default') if @args.empty?
|
24
|
+
@args.extend(::OptionParser::Arguable)
|
25
|
+
|
26
|
+
@args.options do |opts|
|
27
|
+
opts.banner = ["Usage: cucumber [options] [ [FILE|DIR|URL][:LINE[:LINE]*] ]+", "",
|
28
|
+
"Examples:",
|
29
|
+
"cucumber examples/i18n/en/features",
|
30
|
+
"cucumber --language it examples/i18n/it/features/somma.feature:6:98:113",
|
31
|
+
"cucumber -n -i http://rubyurl.com/eeCl", "", "",
|
32
|
+
].join("\n")
|
33
|
+
opts.on("-r LIBRARY|DIR", "--require LIBRARY|DIR",
|
34
|
+
"Require files before executing the features. If this",
|
35
|
+
"option is not specified, all *.rb files that are",
|
36
|
+
"siblings or below the features will be loaded auto-",
|
37
|
+
"matically. Automatic loading is disabled when this",
|
38
|
+
"option is specified, and all loading becomes explicit.",
|
39
|
+
"Files under directories named \"support\" are always",
|
40
|
+
"loaded first.",
|
41
|
+
"This option can be specified multiple times.") do |v|
|
42
|
+
@options[:require] ||= []
|
43
|
+
@options[:require] << v
|
44
|
+
end
|
45
|
+
opts.on("-l LANG", "--language LANG",
|
46
|
+
"Specify language for features (Default: #{@options[:lang]})",
|
47
|
+
%{Run with "--language help" to see all languages},
|
48
|
+
%{Run with "--language LANG help" to list keywords for LANG}) do |v|
|
49
|
+
if v == 'help'
|
50
|
+
list_languages
|
51
|
+
elsif args==['help']
|
52
|
+
list_keywords(v)
|
53
|
+
else
|
54
|
+
@options[:lang] = v
|
55
|
+
end
|
56
|
+
end
|
57
|
+
opts.on("-f FORMAT", "--format FORMAT",
|
58
|
+
"How to format features (Default: #{DEFAULT_FORMAT})",
|
59
|
+
"Available formats: #{FORMATS.join(", ")}",
|
60
|
+
"You can also provide your own formatter classes as long",
|
61
|
+
"as they have been previously required using --require or",
|
62
|
+
"if they are in the folder structure such that cucumber",
|
63
|
+
"will require them automatically.",
|
64
|
+
"This option can be specified multiple times.") do |v|
|
65
|
+
@options[:formats][v] = @out_stream
|
66
|
+
@active_format = v
|
67
|
+
end
|
68
|
+
opts.on("-o", "--out FILE",
|
69
|
+
"Write output to a file instead of STDOUT. This option",
|
70
|
+
"applies to the previously specified --format, or the",
|
71
|
+
"default format if no format is specified.") do |v|
|
72
|
+
@options[:formats][@active_format] = v
|
73
|
+
end
|
74
|
+
opts.on("-t TAGS", "--tags TAGS",
|
75
|
+
"Only execute the features or scenarios with the specified tags.",
|
76
|
+
"TAGS must be comma-separated without spaces.") do |v|
|
77
|
+
@options[:tags] = v.split(",")
|
78
|
+
end
|
79
|
+
opts.on("-s SCENARIO", "--scenario SCENARIO",
|
80
|
+
"Only execute the scenario with the given name. If this option",
|
81
|
+
"is given more than once, run all the specified scenarios.") do |v|
|
82
|
+
@options[:scenario_names] << v
|
83
|
+
end
|
84
|
+
opts.on("-e", "--exclude PATTERN", "Don't run feature files matching PATTERN") do |v|
|
85
|
+
@options[:excludes] << v
|
86
|
+
end
|
87
|
+
opts.on("-p", "--profile PROFILE", "Pull commandline arguments from cucumber.yml.") do |v|
|
88
|
+
parse_args_from_profile(v)
|
89
|
+
end
|
90
|
+
opts.on("-c", "--[no-]color",
|
91
|
+
"Whether or not to use ANSI color in the output. Cucumber decides",
|
92
|
+
"based on your platform and the output destination if not specified.") do |v|
|
93
|
+
Term::ANSIColor.coloring = v
|
94
|
+
end
|
95
|
+
opts.on("-d", "--dry-run", "Invokes formatters without executing the steps.",
|
96
|
+
"Implies --quiet.") do
|
97
|
+
@options[:dry_run] = true
|
98
|
+
@quiet = true
|
99
|
+
end
|
100
|
+
opts.on("-a", "--autoformat DIRECTORY",
|
101
|
+
"Reformats (pretty prints) feature files and write them to DIRECTORY.",
|
102
|
+
"Be careful if you choose to overwrite the originals.",
|
103
|
+
"Implies --dry-run --formatter pretty.") do |directory|
|
104
|
+
@options[:autoformat] = directory
|
105
|
+
Term::ANSIColor.coloring = false
|
106
|
+
@options[:dry_run] = true
|
107
|
+
@quiet = true
|
108
|
+
end
|
109
|
+
opts.on("-m", "--no-multiline",
|
110
|
+
"Don't print multiline strings and tables under steps.") do
|
111
|
+
@options[:no_multiline] = true
|
112
|
+
end
|
113
|
+
opts.on("-n", "--no-source",
|
114
|
+
"Don't print the file and line of the step definition with the steps.") do
|
115
|
+
@options[:source] = false
|
116
|
+
end
|
117
|
+
opts.on("-i", "--no-snippets", "Don't print snippets for pending steps.") do
|
118
|
+
@options[:snippets] = false
|
119
|
+
end
|
120
|
+
opts.on("-q", "--quiet", "Alias for --no-snippets --no-source.") do
|
121
|
+
@quiet = true
|
122
|
+
end
|
123
|
+
opts.on("-b", "--backtrace", "Show full backtrace for all errors.") do
|
124
|
+
Exception.cucumber_full_backtrace = true
|
125
|
+
end
|
126
|
+
opts.on("--strict", "Fail if there are any undefined steps.") do
|
127
|
+
@options[:strict] = true
|
128
|
+
end
|
129
|
+
opts.on("-v", "--verbose", "Show the files and features loaded.") do
|
130
|
+
@options[:verbose] = true
|
131
|
+
end
|
132
|
+
opts.on("-g", "--guess", "Guess best match for Ambiguous steps.") do
|
133
|
+
@options[:guess] = true
|
134
|
+
end
|
135
|
+
opts.on_tail("--version", "Show version.") do
|
136
|
+
@out_stream.puts VERSION::STRING
|
137
|
+
Kernel.exit
|
138
|
+
end
|
139
|
+
opts.on_tail("--help", "You're looking at it.") do
|
140
|
+
@out_stream.puts opts.help
|
141
|
+
Kernel.exit
|
142
|
+
end
|
143
|
+
end.parse!
|
144
|
+
|
145
|
+
@options[:formats]['pretty'] = @out_stream if @options[:formats].empty?
|
146
|
+
|
147
|
+
@options[:snippets] = true if !@quiet && @options[:snippets].nil?
|
148
|
+
@options[:source] = true if !@quiet && @options[:source].nil?
|
149
|
+
|
150
|
+
# Whatever is left after option parsing is the FILE arguments
|
151
|
+
@paths += args
|
152
|
+
end
|
153
|
+
|
154
|
+
def ast_filter
|
155
|
+
Ast::Filter.new(@options)
|
156
|
+
end
|
157
|
+
|
158
|
+
def verbose?
|
159
|
+
@options[:verbose]
|
160
|
+
end
|
161
|
+
|
162
|
+
def strict?
|
163
|
+
@options[:strict]
|
164
|
+
end
|
165
|
+
|
166
|
+
def guess?
|
167
|
+
!!@options[:guess]
|
168
|
+
end
|
169
|
+
|
170
|
+
def load_language
|
171
|
+
Cucumber.load_language(@options[:lang])
|
172
|
+
|
173
|
+
if Cucumber.language_incomplete?
|
174
|
+
list_keywords(Cucumber.lang)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def build_formatter_broadcaster(step_mother)
|
179
|
+
return Formatter::Pretty.new(step_mother, nil, @options) if @options[:autoformat]
|
180
|
+
formatters = @options[:formats].map do |format, out|
|
181
|
+
if String === out # file name
|
182
|
+
out = File.open(out, Cucumber.file_mode('w'))
|
183
|
+
at_exit do
|
184
|
+
out.flush
|
185
|
+
out.close
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
begin
|
190
|
+
formatter_class = formatter_class(format)
|
191
|
+
formatter_class.new(step_mother, out, @options)
|
192
|
+
rescue Exception => e
|
193
|
+
exit_with_error("Error creating formatter: #{format}", e)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
broadcaster = Broadcaster.new(formatters)
|
198
|
+
broadcaster.options = @options
|
199
|
+
return broadcaster
|
200
|
+
end
|
201
|
+
|
202
|
+
def formatter_class(format)
|
203
|
+
case format
|
204
|
+
when 'pretty' then Formatter::Pretty
|
205
|
+
when 'progress' then Formatter::Progress
|
206
|
+
when 'profile' then Formatter::Profile
|
207
|
+
when 'rerun' then Formatter::Rerun
|
208
|
+
else
|
209
|
+
constantize(format)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def files_to_require
|
214
|
+
requires = @options[:require] || feature_dirs
|
215
|
+
files = requires.map do |path|
|
216
|
+
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
217
|
+
File.directory?(path) ? Dir["#{path}/**/*.rb"] : path
|
218
|
+
end.flatten.uniq
|
219
|
+
files.sort { |a,b| (b =~ %r{/support/} || -1) <=> (a =~ %r{/support/} || -1) }.reject{|f| f =~ /^http/}
|
220
|
+
end
|
221
|
+
|
222
|
+
def feature_files
|
223
|
+
potential_feature_files = @paths.map do |path|
|
224
|
+
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
225
|
+
path = path.chomp('/')
|
226
|
+
File.directory?(path) ? Dir["#{path}/**/*.feature"] : path
|
227
|
+
end.flatten.uniq
|
228
|
+
|
229
|
+
@options[:excludes].each do |exclude|
|
230
|
+
potential_feature_files.reject! do |path|
|
231
|
+
path =~ /#{Regexp.escape(exclude)}/
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
potential_feature_files
|
236
|
+
end
|
237
|
+
|
238
|
+
protected
|
239
|
+
|
240
|
+
def feature_dirs
|
241
|
+
feature_files.map { |f| File.directory?(f) ? f : File.dirname(f) }.uniq
|
242
|
+
end
|
243
|
+
|
244
|
+
def constantize(camel_cased_word)
|
245
|
+
names = camel_cased_word.split('::')
|
246
|
+
names.shift if names.empty? || names.first.empty?
|
247
|
+
|
248
|
+
constant = Object
|
249
|
+
names.each do |name|
|
250
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
251
|
+
end
|
252
|
+
constant
|
253
|
+
end
|
254
|
+
|
255
|
+
def parse_args_from_profile(profile)
|
256
|
+
unless cucumber_yml.has_key?(profile)
|
257
|
+
return(exit_with_error <<-END_OF_ERROR)
|
258
|
+
Could not find profile: '#{profile}'
|
259
|
+
|
260
|
+
Defined profiles in cucumber.yml:
|
261
|
+
* #{cucumber_yml.keys.join("\n * ")}
|
262
|
+
END_OF_ERROR
|
263
|
+
end
|
264
|
+
|
265
|
+
args_from_yml = cucumber_yml[profile] || ''
|
266
|
+
|
267
|
+
if !args_from_yml.is_a?(String)
|
268
|
+
exit_with_error "Profiles must be defined as a String. The '#{profile}' profile was #{args_from_yml.inspect} (#{args_from_yml.class}).\n"
|
269
|
+
elsif args_from_yml =~ /^\s*$/
|
270
|
+
exit_with_error "The 'foo' profile in cucumber.yml was blank. Please define the command line arguments for the 'foo' profile in cucumber.yml.\n"
|
271
|
+
else
|
272
|
+
parse!(args_from_yml.split(' '))
|
273
|
+
end
|
274
|
+
|
275
|
+
rescue YmlLoadError => e
|
276
|
+
exit_with_error(e.message)
|
277
|
+
end
|
278
|
+
|
279
|
+
def cucumber_yml
|
280
|
+
return @cucumber_yml if @cucumber_yml
|
281
|
+
unless File.exist?('cucumber.yml')
|
282
|
+
raise(YmlLoadError,"cucumber.yml was not found. Please refer to cucumber's documentaion on defining profiles in cucumber.yml. You must define a 'default' profile to use the cucumber command without any arguments.\nType 'cucumber --help' for usage.\n")
|
283
|
+
end
|
284
|
+
|
285
|
+
require 'yaml'
|
286
|
+
begin
|
287
|
+
@cucumber_yml = YAML::load(IO.read('cucumber.yml'))
|
288
|
+
rescue Exception => e
|
289
|
+
raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentaion on correct profile usage.\n")
|
290
|
+
end
|
291
|
+
|
292
|
+
if @cucumber_yml.nil? || !@cucumber_yml.is_a?(Hash)
|
293
|
+
raise(YmlLoadError,"cucumber.yml was found, but was blank or malformed. Please refer to cucumber's documentaion on correct profile usage.\n")
|
294
|
+
end
|
295
|
+
|
296
|
+
return @cucumber_yml
|
297
|
+
end
|
298
|
+
|
299
|
+
def list_keywords(lang)
|
300
|
+
unless Cucumber::LANGUAGES[lang]
|
301
|
+
exit_with_error("No language with key #{lang}")
|
302
|
+
end
|
303
|
+
LanguageHelpFormatter.list_keywords(@out_stream, lang)
|
304
|
+
Kernel.exit
|
305
|
+
end
|
306
|
+
|
307
|
+
def list_languages
|
308
|
+
LanguageHelpFormatter.list_languages(@out_stream)
|
309
|
+
Kernel.exit
|
310
|
+
end
|
311
|
+
|
312
|
+
def default_options
|
313
|
+
{
|
314
|
+
:strict => false,
|
315
|
+
:require => nil,
|
316
|
+
:lang => 'en',
|
317
|
+
:dry_run => false,
|
318
|
+
:formats => {},
|
319
|
+
:excludes => [],
|
320
|
+
:tags => [],
|
321
|
+
:scenario_names => []
|
322
|
+
}
|
323
|
+
end
|
324
|
+
|
325
|
+
def exit_with_error(error_message, e=nil)
|
326
|
+
@error_stream.puts(error_message)
|
327
|
+
if e
|
328
|
+
@error_stream.puts("#{e.message} (#{e.class})")
|
329
|
+
@error_stream.puts(e.backtrace.join("\n"))
|
330
|
+
end
|
331
|
+
Kernel.exit 1
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
end
|
336
|
+
end
|