cucumber 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +86 -3
- data/Manifest.txt +93 -44
- data/Rakefile +5 -1
- data/bin/cucumber +1 -0
- data/cucumber.yml +1 -1
- data/examples/calculator_ruby_features/features/{steps → step_definitons}/calculator_steps.rb +0 -0
- data/examples/cs/features/{steps → step_definitons}/hello_steps.rb +0 -0
- data/examples/cs/features/{steps → step_definitons}/tree_steps.rb +0 -0
- data/examples/i18n/README.textile +18 -0
- data/examples/i18n/Rakefile +16 -0
- data/examples/i18n/ar/Rakefile +6 -0
- data/examples/i18n/ar/features/addition.feature +17 -0
- data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +31 -0
- data/examples/i18n/ar/lib/calculator.rb +10 -0
- data/examples/i18n/da/Rakefile +6 -0
- data/examples/{danish_calculator/features/steps → i18n/da/features/step_definitons}/kalkulator_steps.rb +0 -0
- data/examples/{danish_calculator → i18n/da}/features/summering.feature +1 -1
- data/examples/{danish_calculator → i18n/da}/lib/kalkulator.rb +0 -0
- data/examples/{swedish_calculator → i18n/en}/Rakefile +1 -1
- data/examples/{calculator → i18n/en}/features/addition.feature +0 -0
- data/examples/{calculator → i18n/en}/features/division.feature +0 -0
- data/examples/{calculator/features/steps → i18n/en/features/step_definitons}/calculator_steps.rb +0 -0
- data/examples/{calculator → i18n/en}/lib/calculator.rb +0 -2
- data/examples/i18n/es/Rakefile +6 -0
- data/examples/{spanish_calculator → i18n/es}/features/adicion.feature +1 -1
- data/examples/{spanish_calculator/features/steps → i18n/es/features/step_definitons}/calculador_steps.rb +0 -0
- data/examples/{spanish_calculator/lib/Calculador.rb → i18n/es/lib/calculador.rb} +0 -0
- data/examples/i18n/et/Rakefile +6 -0
- data/examples/i18n/et/features/liitmine.feature +17 -0
- data/examples/{estonian_calculator/features → i18n/et/features/step_definitions}/kalkulaator_steps.rb +2 -11
- data/examples/i18n/et/lib/kalkulaator.rb +10 -0
- data/examples/i18n/fr/Rakefile +6 -0
- data/examples/{calculatrice_francaise_avec_soit_scenario → i18n/fr}/features/addition.feature +0 -0
- data/examples/{calculatrice_francaise_avec_soit_scenario/features → i18n/fr/features/step_definitions}/calculatrice_steps.rb +2 -11
- data/examples/i18n/fr/lib/calculatrice.rb +10 -0
- data/examples/i18n/id/Rakefile +6 -0
- data/examples/i18n/id/features/addition.feature +17 -0
- data/examples/i18n/id/features/division.feature +10 -0
- data/examples/i18n/id/features/step_definitons/calculator_steps.rb +31 -0
- data/examples/i18n/id/lib/calculator.rb +14 -0
- data/examples/i18n/it/Rakefile +6 -0
- data/examples/i18n/it/features/somma.feature +10 -0
- data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +22 -0
- data/examples/i18n/it/lib/calcolatrice.rb +11 -0
- data/examples/{calculator → i18n/ja}/README.txt +0 -0
- data/examples/i18n/ja/Rakefile +6 -0
- data/examples/i18n/ja/features/addition.feature +17 -0
- data/examples/i18n/ja/features/division.feature +10 -0
- data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +30 -0
- data/examples/i18n/ja/lib/calculator.rb +14 -0
- data/examples/i18n/no/Rakefile +6 -0
- data/examples/{norwegian_calculator/features/steps → i18n/no/features/step_definitons}/kalkulator_steps.rb +0 -0
- data/examples/{norwegian_calculator → i18n/no}/features/summering.feature +0 -0
- data/examples/{norwegian_calculator → i18n/no}/lib/kalkulator.rb +0 -0
- data/examples/i18n/pt/Rakefile +6 -0
- data/examples/{portuguese_calculator → i18n/pt}/features/adicao.feature +0 -0
- data/examples/{portuguese_calculator/features → i18n/pt/features/step_definitions}/calculadora_steps.rb +2 -11
- data/examples/i18n/pt/lib/calculadora.rb +10 -0
- data/examples/i18n/ro/Rakefile +6 -0
- data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +22 -0
- data/examples/i18n/ro/features/suma.feature +10 -0
- data/examples/i18n/ro/lib/calculator.rb +11 -0
- data/examples/i18n/se/Rakefile +6 -0
- data/examples/{swedish_calculator/features/steps → i18n/se/features/step_definitons}/kalkulator_steps.rb +0 -0
- data/examples/{swedish_calculator → i18n/se}/features/summering.feature +0 -0
- data/examples/{swedish_calculator → i18n/se}/lib/kalkulator.rb +0 -0
- data/examples/i18n/zh-CN/Rakefile +6 -0
- data/examples/{chinese_simplified_calculator → i18n/zh-CN}/features/addition.feature +0 -0
- data/examples/{chinese_simplified_calculator/features/steps → i18n/zh-CN/features/step_definitons}/calculator_steps.rb +0 -0
- data/examples/{chinese_simplified_calculator → i18n/zh-CN}/lib/calculator.rb +0 -0
- data/examples/java/features/{steps → step_definitons}/hello_steps.rb +0 -0
- data/examples/java/features/{steps → step_definitons}/tree_steps.rb +0 -0
- data/examples/selenium/features/{steps → step_definitons}/stories_steps.rb +0 -0
- data/examples/tickets/features/{steps → step_definitons}/tickets_steps.rb +0 -0
- data/examples/watir/features/search.feature +2 -2
- data/examples/watir/features/{steps → step_definitons}/stories_steps.rb +0 -0
- data/gem_tasks/treetop.rake +1 -9
- data/lib/autotest/cucumber.rb +6 -0
- data/lib/autotest/cucumber_mixin.rb +109 -0
- data/lib/autotest/cucumber_rails.rb +6 -0
- data/lib/autotest/cucumber_rails_rspec.rb +6 -0
- data/lib/autotest/cucumber_rspec.rb +6 -0
- data/lib/autotest/discover.rb +9 -0
- data/lib/cucumber.rb +4 -0
- data/lib/cucumber/broadcaster.rb +20 -0
- data/lib/cucumber/cli.rb +139 -48
- data/lib/cucumber/core_ext/proc.rb +2 -3
- data/lib/cucumber/executor.rb +59 -32
- data/lib/cucumber/formatters.rb +1 -1
- data/lib/cucumber/formatters/ansicolor.rb +3 -4
- data/lib/cucumber/formatters/autotest_formatter.rb +23 -0
- data/lib/cucumber/formatters/pretty_formatter.rb +99 -42
- data/lib/cucumber/formatters/progress_formatter.rb +21 -5
- data/lib/cucumber/languages.yml +125 -10
- data/lib/cucumber/rails/world.rb +1 -1
- data/lib/cucumber/rake/task.rb +52 -26
- data/lib/cucumber/step_mother.rb +7 -1
- data/lib/cucumber/tree/feature.rb +8 -6
- data/lib/cucumber/tree/scenario.rb +34 -15
- data/lib/cucumber/tree/step.rb +3 -1
- data/lib/cucumber/treetop_parser/feature.treetop.erb +15 -10
- data/lib/cucumber/treetop_parser/feature_ar.rb +1591 -0
- data/lib/cucumber/treetop_parser/feature_cy.rb +1591 -0
- data/lib/cucumber/treetop_parser/feature_da.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_de.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_en-tx.rb +1591 -0
- data/lib/cucumber/treetop_parser/feature_en.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_es.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_et.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_fr.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_id.rb +1591 -0
- data/lib/cucumber/treetop_parser/feature_it.rb +1591 -0
- data/lib/cucumber/treetop_parser/feature_ja.rb +1591 -0
- data/lib/cucumber/treetop_parser/feature_nl.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_no.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_pl.rb +1591 -0
- data/lib/cucumber/treetop_parser/feature_pt.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_ro.rb +1591 -0
- data/lib/cucumber/treetop_parser/feature_ro2.rb +1591 -0
- data/lib/cucumber/treetop_parser/feature_ru.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_se.rb +238 -240
- data/lib/cucumber/treetop_parser/feature_zh-CN.rb +238 -240
- data/lib/cucumber/version.rb +1 -1
- data/rails_generators/cucumber/USAGE +11 -0
- data/rails_generators/cucumber/cucumber_generator.rb +9 -6
- data/rails_generators/cucumber/templates/cucumber +6 -1
- data/rails_generators/cucumber/templates/{common_webrat.rb → webrat_steps.rb} +4 -0
- data/rails_generators/feature/USAGE +12 -0
- data/rails_generators/feature/feature_generator.rb +3 -4
- data/spec/cucumber/broadcaster_spec.rb +27 -0
- data/spec/cucumber/cli_spec.rb +211 -23
- data/spec/cucumber/executor_spec.rb +104 -14
- data/spec/cucumber/formatters/ansicolor_spec.rb +9 -1
- data/spec/cucumber/formatters/autotest_formatter_spec.rb +26 -0
- data/spec/cucumber/formatters/pretty_formatter_spec.rb +119 -26
- data/spec/cucumber/formatters/profile_formatter_spec.rb +1 -2
- data/spec/cucumber/formatters/progress_formatter_spec.rb +22 -1
- data/spec/cucumber/sell_cucumbers.feature +10 -0
- data/spec/cucumber/step_mother_spec.rb +21 -0
- data/spec/cucumber/tree/row_scenario_spec.rb +25 -0
- data/spec/cucumber/tree/scenario_spec.rb +47 -8
- data/spec/cucumber/tree/step_spec.rb +19 -0
- data/spec/cucumber/treetop_parser/feature_parser_spec.rb +2 -0
- data/spec/cucumber/treetop_parser/multiline_steps.feature +7 -3
- data/spec/spec_helper.rb +2 -0
- metadata +97 -48
- data/examples/calculator/Rakefile +0 -5
- data/examples/calculatrice_francaise_avec_soit_scenario/Rakefile +0 -6
- data/examples/chinese_simplified_calculator/Rakefile +0 -6
- data/examples/danish_calculator/Rakefile +0 -6
- data/examples/estonian_calculator/Rakefile +0 -6
- data/examples/estonian_calculator/features/liitmine.feature +0 -16
- data/examples/norwegian_calculator/Rakefile +0 -6
- data/examples/portuguese_calculator/Rakefile +0 -6
- data/examples/spanish_calculator/Rakefile +0 -6
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec'
|
2
|
+
$:.unshift(File.dirname(__FILE__) + '/../../lib')
|
3
|
+
require 'calculator'
|
4
|
+
|
5
|
+
Before do
|
6
|
+
@calc = Calculator.new
|
7
|
+
end
|
8
|
+
|
9
|
+
After do
|
10
|
+
end
|
11
|
+
|
12
|
+
Given /introduc (\d+)/ do |n|
|
13
|
+
@calc.push n.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
When 'apas suma' do
|
17
|
+
@result = @calc.add
|
18
|
+
end
|
19
|
+
|
20
|
+
Then /rezultatul trebuie sa fie (\d*)/ do |result|
|
21
|
+
@result.should == result.to_i
|
22
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -5,5 +5,5 @@ Feature: Search
|
|
5
5
|
|
6
6
|
Scenario: Find what I'm looking for
|
7
7
|
Given I am on the Google search page
|
8
|
-
When I search for "
|
9
|
-
Then I should see a link to "
|
8
|
+
When I search for "cucumber github"
|
9
|
+
Then I should see a link to "Ruby on Rails — cucumber — GitHub":http://github.com/aslakhellesoy/cucumber/wikis/ruby-on-rails
|
File without changes
|
data/gem_tasks/treetop.rake
CHANGED
@@ -25,15 +25,6 @@ class FeatureCompiler
|
|
25
25
|
end
|
26
26
|
sh "#{@tt} #{grammar_file}"
|
27
27
|
FileUtils.rm(grammar_file)
|
28
|
-
|
29
|
-
# Change code so it isn't part of RDoc
|
30
|
-
lines = IO.read(ruby_file).split("\n")
|
31
|
-
lines.each do |line|
|
32
|
-
if line =~ /\s*(def|class|module)/
|
33
|
-
line << " #:nodoc:"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
File.open(ruby_file, 'wb'){|io| io.write(lines.join("\n"))}
|
37
28
|
end
|
38
29
|
end
|
39
30
|
|
@@ -43,6 +34,7 @@ namespace :treetop do
|
|
43
34
|
FeatureCompiler.new.compile_all
|
44
35
|
end
|
45
36
|
|
37
|
+
desc 'Compile the English grammar'
|
46
38
|
task :compile_en do
|
47
39
|
FeatureCompiler.new.compile('en')
|
48
40
|
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'autotest'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module Autotest::CucumberMixin
|
5
|
+
def self.included(receiver)
|
6
|
+
receiver::ALL_HOOKS << [:run_features, :ran_features]
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :scenarios_to_run
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super
|
13
|
+
reset_features
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
hook :initialize
|
18
|
+
reset
|
19
|
+
reset_features
|
20
|
+
add_sigint_handler
|
21
|
+
|
22
|
+
self.last_mtime = Time.now if $f
|
23
|
+
|
24
|
+
loop do # ^c handler
|
25
|
+
begin
|
26
|
+
get_to_green
|
27
|
+
if self.tainted then
|
28
|
+
rerun_all_tests
|
29
|
+
rerun_all_features if all_good
|
30
|
+
else
|
31
|
+
hook :all_good
|
32
|
+
end
|
33
|
+
wait_for_changes
|
34
|
+
# Once tests and features are green, reset features every
|
35
|
+
# time a file is changed to see if anything breaks.
|
36
|
+
reset_features
|
37
|
+
rescue Interrupt
|
38
|
+
break if self.wants_to_quit
|
39
|
+
reset
|
40
|
+
reset_features
|
41
|
+
end
|
42
|
+
end
|
43
|
+
hook :quit
|
44
|
+
end
|
45
|
+
|
46
|
+
def all_features_good
|
47
|
+
scenarios_to_run == []
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_to_green
|
51
|
+
begin
|
52
|
+
super
|
53
|
+
run_features
|
54
|
+
wait_for_changes unless all_features_good
|
55
|
+
end until all_features_good
|
56
|
+
end
|
57
|
+
|
58
|
+
def rerun_all_features
|
59
|
+
reset_features
|
60
|
+
run_features
|
61
|
+
end
|
62
|
+
|
63
|
+
def reset_features
|
64
|
+
self.scenarios_to_run = :all
|
65
|
+
end
|
66
|
+
|
67
|
+
def run_features
|
68
|
+
hook :run_features
|
69
|
+
Tempfile.open('autotest-cucumber') do |dirty_scenarios_file|
|
70
|
+
cmd = self.make_cucumber_cmd self.scenarios_to_run, dirty_scenarios_file.path
|
71
|
+
return if cmd.empty?
|
72
|
+
puts cmd unless $q
|
73
|
+
system cmd
|
74
|
+
self.scenarios_to_run = dirty_scenarios_file.readlines.map { |l| l.chomp }
|
75
|
+
self.tainted = true unless self.scenarios_to_run == []
|
76
|
+
end
|
77
|
+
hook :ran_features
|
78
|
+
end
|
79
|
+
|
80
|
+
def make_cucumber_cmd(scenarios_to_run, dirty_scenarios_filename)
|
81
|
+
return '' if scenarios_to_run == []
|
82
|
+
|
83
|
+
profiles = YAML.load_file("cucumber.yml").keys rescue []
|
84
|
+
|
85
|
+
profile ||= "autotest-all" if profiles.include?("autotest-all") and scenarios_to_run == :all
|
86
|
+
profile ||= "autotest" if profiles.include?("autotest")
|
87
|
+
profile ||= nil
|
88
|
+
|
89
|
+
if profile
|
90
|
+
args = ["--profile", profile]
|
91
|
+
else
|
92
|
+
args = %w{features --format} << (scenarios_to_run == :all ? "progress" : "pretty")
|
93
|
+
end
|
94
|
+
args += %w{--format autotest --out} << dirty_scenarios_filename
|
95
|
+
args = args.join(' ')
|
96
|
+
|
97
|
+
if scenarios_to_run == :all
|
98
|
+
scenario_args = nil
|
99
|
+
else
|
100
|
+
scenario_args = scenarios_to_run.map { |s| "-s '#{s}'" }.join(' ')
|
101
|
+
end
|
102
|
+
|
103
|
+
return "#{cucumber} #{args} #{scenario_args}"
|
104
|
+
end
|
105
|
+
|
106
|
+
def cucumber
|
107
|
+
File.exist?("script/cucumber") ? "script/cucumber" : "cucumber"
|
108
|
+
end
|
109
|
+
end
|
data/lib/cucumber.rb
CHANGED
@@ -12,6 +12,10 @@ require 'cucumber/step_mother'
|
|
12
12
|
require 'cucumber/formatters'
|
13
13
|
require 'cucumber/treetop_parser/feature_parser'
|
14
14
|
require 'cucumber/cli'
|
15
|
+
require 'cucumber/broadcaster'
|
16
|
+
|
17
|
+
$KCODE='u'
|
18
|
+
require 'jcode'
|
15
19
|
|
16
20
|
module Cucumber
|
17
21
|
LANGUAGE_FILE = File.expand_path(File.dirname(__FILE__) + '/cucumber/languages.yml')
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Cucumber
|
2
|
+
class Broadcaster
|
3
|
+
|
4
|
+
def initialize(receivers = [])
|
5
|
+
@receivers = receivers
|
6
|
+
end
|
7
|
+
|
8
|
+
def register(receiver)
|
9
|
+
@receivers << receiver
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing(method_name, *args)
|
13
|
+
@receivers.each do |receiver|
|
14
|
+
r = (receiver == STDOUT) ? Kernel: receiver # Needed to make colors work on Windows
|
15
|
+
r.__send__(method_name, *args) if receiver.respond_to?(method_name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
data/lib/cucumber/cli.rb
CHANGED
@@ -5,12 +5,12 @@ module Cucumber
|
|
5
5
|
class CLI
|
6
6
|
class << self
|
7
7
|
attr_writer :step_mother, :executor, :features
|
8
|
-
|
8
|
+
|
9
9
|
def execute
|
10
10
|
@execute_called = true
|
11
11
|
parse(ARGV).execute!(@step_mother, @executor, @features)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def execute_called?
|
15
15
|
@execute_called
|
16
16
|
end
|
@@ -21,52 +21,87 @@ module Cucumber
|
|
21
21
|
cli
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
attr_reader :options
|
26
|
-
FORMATS = %w{pretty profile progress html}
|
26
|
+
FORMATS = %w{pretty profile progress html autotest}
|
27
|
+
DEFAULT_FORMAT = 'pretty'
|
27
28
|
|
28
|
-
def initialize
|
29
|
+
def initialize(out_stream = STDOUT, error_stream = STDERR)
|
30
|
+
@out_stream = out_stream
|
31
|
+
@error_stream = error_stream
|
29
32
|
@paths = []
|
33
|
+
@options = {
|
34
|
+
:require => nil,
|
35
|
+
:lang => 'en',
|
36
|
+
:dry_run => false,
|
37
|
+
:source => true,
|
38
|
+
:snippets => true,
|
39
|
+
:formats => {},
|
40
|
+
:excludes => [],
|
41
|
+
:scenario_names => nil
|
42
|
+
}
|
43
|
+
@active_format = DEFAULT_FORMAT
|
30
44
|
end
|
31
45
|
|
32
46
|
def parse_options!(args)
|
33
47
|
return parse_args_from_profile('default') if args.empty?
|
34
48
|
args.extend(OptionParser::Arguable)
|
35
49
|
|
36
|
-
@options ||= {
|
37
|
-
:require => nil,
|
38
|
-
:lang => 'en',
|
39
|
-
:format => 'pretty',
|
40
|
-
:dry_run => false,
|
41
|
-
:source => true,
|
42
|
-
:out => STDOUT
|
43
|
-
}
|
44
50
|
args.options do |opts|
|
45
51
|
opts.banner = "Usage: cucumber [options] FILES|DIRS"
|
46
52
|
opts.on("-r LIBRARY|DIR", "--require LIBRARY|DIR", "Require files before executing the features.",
|
47
53
|
"If this option is not specified, all *.rb files that",
|
48
|
-
"are siblings or below the features will be autorequired"
|
54
|
+
"are siblings or below the features will be autorequired",
|
55
|
+
"This option can be specified multiple times.") do |v|
|
49
56
|
@options[:require] ||= []
|
50
57
|
@options[:require] << v
|
51
58
|
end
|
52
59
|
opts.on("-l LINE", "--line LINE", "Only execute the scenario at the given line") do |v|
|
53
60
|
@options[:line] = v
|
54
61
|
end
|
62
|
+
opts.on("-s SCENARIO", "--scenario SCENARIO", "Only execute the scenario with the given name.",
|
63
|
+
"If this option is given more than once, run all",
|
64
|
+
"the specified scenarios.") do |v|
|
65
|
+
@options[:scenario_names] ||= []
|
66
|
+
@options[:scenario_names] << v
|
67
|
+
end
|
55
68
|
opts.on("-a LANG", "--language LANG", "Specify language for features (Default: #{@options[:lang]})",
|
56
69
|
"Available languages: #{Cucumber.languages.join(", ")}",
|
57
70
|
"Look at #{Cucumber::LANGUAGE_FILE} for keywords") do |v|
|
58
71
|
@options[:lang] = v
|
59
72
|
end
|
60
|
-
opts.on("-f FORMAT", "--format FORMAT", "How to format features (Default: #{
|
61
|
-
"Available formats: #{FORMATS.join(", ")}"
|
62
|
-
|
63
|
-
|
64
|
-
|
73
|
+
opts.on("-f FORMAT", "--format FORMAT", "How to format features (Default: #{DEFAULT_FORMAT})",
|
74
|
+
"Available formats: #{FORMATS.join(", ")}",
|
75
|
+
"This option can be specified multiple times.") do |v|
|
76
|
+
unless FORMATS.index(v)
|
77
|
+
@error_stream.puts "Invalid format: #{v}\n"
|
78
|
+
@error_stream.puts opts.help
|
65
79
|
exit 1
|
66
80
|
end
|
67
|
-
@options[:
|
81
|
+
@options[:formats][v] ||= []
|
82
|
+
@options[:formats][v] << @out_stream
|
83
|
+
@active_format = v
|
84
|
+
end
|
85
|
+
opts.on("-o", "--out FILE", "Write output to a file instead of @out_stream.",
|
86
|
+
"This option can be specified multiple times, and applies to the previously",
|
87
|
+
"specified --format.") do |v|
|
88
|
+
@options[:formats][@active_format] ||= []
|
89
|
+
if @options[:formats][@active_format].last == @out_stream
|
90
|
+
@options[:formats][@active_format][-1] = File.open(v, 'w')
|
91
|
+
else
|
92
|
+
@options[:formats][@active_format] << File.open(v, 'w')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
opts.on("-c", "--[no-]color", "Use ANSI color in the output, if formatters use it. If",
|
96
|
+
"these options are given multiple times, the last one is",
|
97
|
+
"used. If neither --color or --no-color is given cucumber",
|
98
|
+
"decides based on your platform and the output destination") do |v|
|
99
|
+
@options[:color] = v
|
68
100
|
end
|
69
|
-
opts.on("-
|
101
|
+
opts.on("-e", "--exclude PATTERN", "Don't run features matching a pattern") do |v|
|
102
|
+
@options[:excludes] << v
|
103
|
+
end
|
104
|
+
opts.on("-p", "--profile PROFILE", "Pull commandline arguments from cucumber.yml.") do |v|
|
70
105
|
parse_args_from_profile(v)
|
71
106
|
end
|
72
107
|
opts.on("-d", "--dry-run", "Invokes formatters without executing the steps.") do
|
@@ -75,8 +110,12 @@ module Cucumber
|
|
75
110
|
opts.on("-n", "--no-source", "Don't show the file and line of the step definition with the steps.") do
|
76
111
|
@options[:source] = false
|
77
112
|
end
|
78
|
-
opts.on("-
|
79
|
-
@options[:
|
113
|
+
opts.on("-i", "--no-snippets", "Don't show the snippets for pending steps") do
|
114
|
+
@options[:snippets] = false
|
115
|
+
end
|
116
|
+
opts.on("-q", "--quiet", "Don't show any development aid information") do
|
117
|
+
@options[:snippets] = false
|
118
|
+
@options[:source] = false
|
80
119
|
end
|
81
120
|
opts.on_tail("--version", "Show version") do
|
82
121
|
puts VERSION::STRING
|
@@ -87,31 +126,52 @@ module Cucumber
|
|
87
126
|
exit
|
88
127
|
end
|
89
128
|
end.parse!
|
90
|
-
|
129
|
+
|
130
|
+
if @options[:formats].empty?
|
131
|
+
@options[:formats][DEFAULT_FORMAT] = [@out_stream]
|
132
|
+
end
|
133
|
+
|
91
134
|
# Whatever is left after option parsing is the FILE arguments
|
92
135
|
@paths += args
|
93
136
|
end
|
94
|
-
|
137
|
+
|
95
138
|
def parse_args_from_profile(profile)
|
139
|
+
unless File.exist?('cucumber.yml')
|
140
|
+
return exit_with_error("cucumber.yml was not found. Please define your '#{profile}' and other profiles in cucumber.yml.\n"+
|
141
|
+
"Type 'cucumber --help' for usage.\n")
|
142
|
+
end
|
143
|
+
|
96
144
|
require 'yaml'
|
97
145
|
cucumber_yml = YAML::load(IO.read('cucumber.yml'))
|
98
146
|
args_from_yml = cucumber_yml[profile]
|
99
|
-
|
100
|
-
|
147
|
+
if args_from_yml.nil?
|
148
|
+
exit_with_error <<-END_OF_ERROR
|
149
|
+
Could not find profile: '#{profile}'
|
150
|
+
|
151
|
+
Defined profiles in cucumber.yml:
|
152
|
+
* #{cucumber_yml.keys.join("\n * ")}
|
153
|
+
END_OF_ERROR
|
154
|
+
elsif !args_from_yml.is_a?(String)
|
155
|
+
exit_with_error "Profiles must be defined as a String. The '#{profile}' profile was #{args_from_yml.inspect} (#{args_from_yml.class}).\n"
|
156
|
+
else
|
157
|
+
parse_options!(args_from_yml.split(' '))
|
158
|
+
end
|
101
159
|
end
|
102
|
-
|
160
|
+
|
103
161
|
def execute!(step_mother, executor, features)
|
162
|
+
Term::ANSIColor.coloring = @options[:color] unless @options[:color].nil?
|
104
163
|
Cucumber.load_language(@options[:lang])
|
105
|
-
executor.
|
164
|
+
executor.formatters = build_formatter_broadcaster(step_mother)
|
106
165
|
require_files
|
107
166
|
load_plain_text_features(features)
|
108
167
|
executor.line = @options[:line].to_i if @options[:line]
|
168
|
+
executor.scenario_names = @options[:scenario_names] if @options[:scenario_names]
|
109
169
|
executor.visit_features(features)
|
110
170
|
exit 1 if executor.failed
|
111
171
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
172
|
+
|
173
|
+
private
|
174
|
+
|
115
175
|
# Requires files - typically step files and ruby feature files.
|
116
176
|
def require_files
|
117
177
|
ARGV.clear # Shut up RSpec
|
@@ -134,16 +194,25 @@ module Cucumber
|
|
134
194
|
end
|
135
195
|
|
136
196
|
def feature_files
|
137
|
-
@paths.map do |path|
|
197
|
+
potential_feature_files = @paths.map do |path|
|
138
198
|
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
199
|
+
path = path.chomp('/')
|
139
200
|
File.directory?(path) ? Dir["#{path}/**/*.feature"] : path
|
140
201
|
end.flatten.uniq
|
202
|
+
|
203
|
+
@options[:excludes].each do |exclude|
|
204
|
+
potential_feature_files.reject! do |path|
|
205
|
+
path =~ /#{Regexp.escape(exclude)}/
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
potential_feature_files
|
141
210
|
end
|
142
|
-
|
211
|
+
|
143
212
|
def feature_dirs
|
144
213
|
feature_files.map{|f| File.directory?(f) ? f : File.dirname(f)}.uniq
|
145
214
|
end
|
146
|
-
|
215
|
+
|
147
216
|
def load_plain_text_features(features)
|
148
217
|
parser = TreetopParser::FeatureParser.new
|
149
218
|
|
@@ -151,22 +220,44 @@ module Cucumber
|
|
151
220
|
features << parser.parse_feature(f)
|
152
221
|
end
|
153
222
|
end
|
154
|
-
|
155
|
-
def
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
223
|
+
|
224
|
+
def build_formatter_broadcaster(step_mother)
|
225
|
+
formatter_broadcaster = Broadcaster.new
|
226
|
+
@options[:formats].each do |format, output_list|
|
227
|
+
output_broadcaster = build_output_broadcaster(output_list)
|
228
|
+
case format
|
229
|
+
when 'pretty'
|
230
|
+
formatter_broadcaster.register(Formatters::PrettyFormatter.new(output_broadcaster, step_mother, @options))
|
231
|
+
when 'progress'
|
232
|
+
formatter_broadcaster.register(Formatters::ProgressFormatter.new(output_broadcaster))
|
233
|
+
when 'profile'
|
234
|
+
formatter_broadcaster.register(Formatters::ProfileFormatter.new(output_broadcaster, step_mother))
|
235
|
+
when 'html'
|
236
|
+
formatter_broadcaster.register(Formatters::HtmlFormatter.new(output_broadcaster, step_mother))
|
237
|
+
when 'autotest'
|
238
|
+
formatter_broadcaster.register(Formatters::AutotestFormatter.new(output_broadcaster))
|
239
|
+
else
|
240
|
+
raise "Unknown formatter: #{@options[:format]}"
|
241
|
+
end
|
167
242
|
end
|
243
|
+
formatter_broadcaster
|
244
|
+
end
|
245
|
+
|
246
|
+
def build_output_broadcaster(output_list)
|
247
|
+
output_broadcaster = Broadcaster.new
|
248
|
+
output_list.each do |output|
|
249
|
+
output_broadcaster.register(output)
|
250
|
+
end
|
251
|
+
output_broadcaster
|
168
252
|
end
|
169
253
|
|
254
|
+
private
|
255
|
+
|
256
|
+
def exit_with_error(error_message)
|
257
|
+
@error_stream << error_message
|
258
|
+
Kernel.exit 1
|
259
|
+
end
|
260
|
+
|
170
261
|
end
|
171
262
|
end
|
172
263
|
|