kosmas58-cucumber 0.1.16.6 → 0.1.99.21
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 +126 -2
- data/License.txt +1 -1
- data/Manifest.txt +0 -270
- data/Rakefile +1 -1
- data/bin/cucumber +2 -2
- data/config/hoe.rb +7 -2
- data/examples/cs/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/README.textile +1 -1
- data/examples/i18n/Rakefile +3 -3
- data/examples/i18n/ar/features/step_definitons/calculator_steps.rb +1 -6
- data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +1 -1
- data/examples/i18n/de/features/addition.feature +6 -6
- data/examples/i18n/de/features/step_definitons/calculator_steps.rb +2 -2
- data/examples/i18n/en/features/addition.feature +6 -6
- data/examples/i18n/en/features/step_definitons/calculator_steps.rb +2 -2
- data/examples/i18n/es/features/adicion.feature +11 -12
- data/examples/i18n/es/features/step_definitons/calculador_steps.rb +7 -10
- data/examples/i18n/es/lib/calculador.rb +4 -1
- data/examples/i18n/et/features/liitmine.feature +7 -6
- data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +1 -1
- data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +1 -1
- data/examples/i18n/fi/features/yhteenlasku.feature +2 -2
- data/examples/i18n/fr/features/addition.feature +2 -2
- data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +1 -1
- data/examples/i18n/id/features/addition.feature +6 -6
- data/examples/i18n/id/features/step_definitons/calculator_steps.rb +2 -2
- data/examples/i18n/it/features/step_definitons/calcolatrice_steps.rb +1 -1
- data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +2 -3
- data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/lt/features/addition.feature +7 -6
- data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +2 -2
- data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +7 -7
- data/examples/i18n/no/features/summering.feature +1 -0
- data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +1 -1
- data/examples/i18n/ro/features/step_definitons/calculator_steps.rb +1 -1
- data/examples/i18n/se/features/step_definitons/kalkulator_steps.rb +1 -1
- data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +2 -2
- data/examples/java/src/cucumber/demo/Hello.java +16 -0
- data/examples/jbehave/README.textile +17 -0
- data/examples/jbehave/features/support/env.rb +7 -0
- data/examples/jbehave/features/trading.feature +24 -0
- data/examples/jbehave/pom.xml +48 -0
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/converters/TraderConverter.java +32 -0
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Stock.java +42 -0
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Trader.java +29 -0
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/persistence/TraderPersister.java +22 -0
- data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java +65 -0
- data/examples/self_test/README.textile +4 -1
- data/examples/{calculator_ruby_features → self_test}/Rakefile +3 -3
- data/examples/self_test/features/background/failing_background.feature +10 -0
- data/examples/self_test/features/background/failing_background_after_success.feature +11 -0
- data/examples/self_test/features/background/multiline_args_background.feature +32 -0
- data/examples/self_test/features/background/passing_background.feature +10 -0
- data/examples/self_test/features/background/pending_background.feature +10 -0
- data/examples/self_test/features/background/scenario_outline_failing_background.feature +16 -0
- data/examples/self_test/features/background/scenario_outline_passing_background.feature +16 -0
- data/examples/self_test/features/call_undefined_step_from_step_def.feature +7 -0
- data/examples/self_test/features/lots_of_undefined.feature +8 -0
- data/examples/self_test/features/outline_sample.feature +11 -5
- data/examples/self_test/features/sample.feature +8 -3
- data/examples/self_test/features/step_definitions/sample_steps.rb +53 -4
- data/examples/self_test/features/support/env.rb +1 -0
- data/examples/self_test/features/support/tag_count_formatter.rb +25 -0
- data/examples/tickets/features/172.feature +28 -0
- data/examples/tickets/features/177/1.feature +29 -0
- data/examples/tickets/features/177/2.feature +21 -0
- data/examples/tickets/features/177/3.feature +18 -0
- data/examples/tickets/features/180.feature +7 -0
- data/examples/tickets/features/scenario_outline.feature +6 -1
- data/examples/tickets/features/step_definitons/tickets_steps.rb +27 -3
- data/examples/tickets/features/tickets.feature +4 -0
- data/features/background.feature +223 -0
- data/features/cucumber_cli.feature +218 -98
- data/features/cucumber_cli_outlines.feature +54 -37
- data/features/custom_formatter.feature +11 -0
- data/features/report_called_undefined_steps.feature +32 -0
- data/features/step_definitions/cucumber_steps.rb +7 -3
- data/features/step_definitions/extra_steps.rb +1 -1
- data/features/support/env.rb +2 -1
- data/gem_tasks/flog.rake +1 -1
- data/gem_tasks/gemspec.rake +2 -2
- data/gem_tasks/jar.rake +67 -0
- data/lib/autotest/cucumber_mixin.rb +17 -23
- data/lib/cucumber.rb +63 -11
- data/lib/cucumber/ast.rb +29 -0
- data/lib/cucumber/ast/background.rb +88 -0
- data/lib/cucumber/ast/comment.rb +26 -0
- data/lib/cucumber/ast/examples.rb +26 -0
- data/lib/cucumber/ast/feature.rb +66 -0
- data/lib/cucumber/ast/features.rb +39 -0
- data/lib/cucumber/ast/filter.rb +22 -0
- data/lib/cucumber/ast/outline_table.rb +49 -0
- data/lib/cucumber/ast/py_string.rb +52 -0
- data/lib/cucumber/ast/scenario.rb +103 -0
- data/lib/cucumber/ast/scenario_outline.rb +92 -0
- data/lib/cucumber/ast/step.rb +161 -0
- data/lib/cucumber/ast/steps.rb +13 -0
- data/lib/cucumber/ast/table.rb +218 -0
- data/lib/cucumber/ast/tags.rb +40 -0
- data/lib/cucumber/ast/visitor.rb +109 -0
- data/lib/cucumber/broadcaster.rb +1 -6
- data/lib/cucumber/cli/configuration.rb +339 -0
- data/lib/cucumber/cli/language_help_formatter.rb +59 -0
- data/lib/cucumber/cli/main.rb +100 -0
- data/lib/cucumber/core_ext/exception.rb +41 -8
- data/lib/cucumber/core_ext/instance_exec.rb +54 -0
- data/lib/cucumber/core_ext/proc.rb +29 -65
- data/lib/cucumber/core_ext/string.rb +19 -0
- data/lib/cucumber/formatter.rb +1 -0
- data/lib/cucumber/{formatters → formatter}/ansicolor.rb +14 -16
- data/lib/cucumber/formatter/color_io.rb +17 -0
- data/lib/cucumber/formatter/console.rb +119 -0
- data/lib/cucumber/formatter/cucumber.css +55 -0
- data/lib/cucumber/formatter/cucumber.sass +49 -0
- data/lib/cucumber/formatter/html.rb +121 -0
- data/lib/cucumber/formatter/pretty.rb +167 -0
- data/lib/cucumber/formatter/profile.rb +77 -0
- data/lib/cucumber/formatter/progress.rb +68 -0
- data/lib/cucumber/formatter/rerun.rb +35 -0
- data/lib/cucumber/formatter/unicode.rb +35 -0
- data/lib/cucumber/formatters/unicode.rb +2 -35
- data/lib/cucumber/jbehave.rb +102 -0
- data/lib/cucumber/languages.yml +128 -75
- data/lib/cucumber/parser.rb +43 -0
- data/lib/cucumber/parser/basic.rb +0 -0
- data/lib/cucumber/parser/feature.rb +1490 -0
- data/lib/cucumber/parser/feature.tt +188 -0
- data/lib/cucumber/parser/i18n.tt +31 -0
- data/lib/cucumber/parser/table.rb +402 -0
- data/lib/cucumber/parser/table.tt +59 -0
- data/lib/cucumber/parser/treetop_ext.rb +75 -0
- data/lib/cucumber/platform.rb +3 -17
- data/lib/cucumber/rails/rspec.rb +5 -2
- data/lib/cucumber/step_definition.rb +87 -0
- data/lib/cucumber/step_mother.rb +151 -66
- data/lib/cucumber/version.rb +2 -2
- data/rails_generators/cucumber/USAGE +3 -2
- data/rails_generators/cucumber/cucumber_generator.rb +33 -23
- data/rails_generators/cucumber/templates/cucumber +2 -1
- data/rails_generators/cucumber/templates/cucumber.rake +6 -1
- data/rails_generators/cucumber/templates/env.rb +1 -1
- data/rails_generators/feature/USAGE +3 -0
- data/rails_generators/feature/feature_generator.rb +30 -6
- data/spec/cucumber/ast/background_spec.rb +58 -0
- data/spec/cucumber/ast/feature_factory.rb +54 -0
- data/spec/cucumber/ast/feature_spec.rb +60 -0
- data/spec/cucumber/ast/py_string_spec.rb +40 -0
- data/spec/cucumber/ast/scenario_outline_spec.rb +64 -0
- data/spec/cucumber/ast/scenario_spec.rb +82 -0
- data/spec/cucumber/ast/step_spec.rb +45 -0
- data/spec/cucumber/ast/table_spec.rb +81 -0
- data/spec/cucumber/ast/tags_spec.rb +23 -0
- data/spec/cucumber/broadcaster_spec.rb +4 -17
- data/spec/cucumber/cli/configuration_spec.rb +239 -0
- data/spec/cucumber/cli/main_spec.rb +164 -0
- data/spec/cucumber/core_ext/proc_spec.rb +27 -35
- data/spec/cucumber/core_ext/string_spec.rb +8 -0
- data/spec/cucumber/{formatters → formatter}/ansicolor_spec.rb +2 -2
- data/spec/cucumber/formatter/html/cucumber.css +37 -0
- data/spec/cucumber/formatter/html/cucumber.js +13 -0
- data/spec/cucumber/formatter/html/index.html +45 -0
- data/spec/cucumber/formatter/html/jquery-1.3.min.js +19 -0
- data/spec/cucumber/formatter/html/jquery.uitableedit.js +100 -0
- data/spec/cucumber/formatters/profile_formatter_spec.rb +17 -16
- data/spec/cucumber/parser/feature_parser_spec.rb +281 -0
- data/spec/cucumber/parser/table_parser_spec.rb +48 -0
- data/spec/cucumber/step_definition_spec.rb +62 -0
- data/spec/cucumber/step_mother_spec.rb +50 -51
- data/spec/cucumber/treetop_parser/empty_feature.feature +1 -1
- data/spec/cucumber/treetop_parser/scenario_outline.feature +1 -1
- data/spec/cucumber/treetop_parser/spaces.feature +3 -1
- data/spec/cucumber/treetop_parser/with_comments.feature +1 -1
- data/spec/cucumber/treetop_parser/with_tags.feature +18 -0
- data/spec/cucumber/world/pending_spec.rb +13 -12
- data/spec/spec_helper.rb +1 -1
- metadata +107 -79
- data/examples/calculator_ruby_features/features/addition.rb +0 -39
- data/examples/calculator_ruby_features/features/step_definitons/calculator_steps.rb +0 -43
- data/gem_tasks/treetop.rake +0 -41
- data/lib/cucumber/cli.rb +0 -355
- data/lib/cucumber/executor.rb +0 -205
- data/lib/cucumber/formatters.rb +0 -1
- data/lib/cucumber/formatters/autotest_formatter.rb +0 -23
- data/lib/cucumber/formatters/cucumber.css +0 -132
- data/lib/cucumber/formatters/cucumber.js +0 -11
- data/lib/cucumber/formatters/html_formatter.rb +0 -152
- data/lib/cucumber/formatters/jquery.js +0 -32
- data/lib/cucumber/formatters/pretty_formatter.rb +0 -285
- data/lib/cucumber/formatters/profile_formatter.rb +0 -92
- data/lib/cucumber/formatters/progress_formatter.rb +0 -61
- data/lib/cucumber/model.rb +0 -1
- data/lib/cucumber/model/table.rb +0 -32
- data/lib/cucumber/step_methods.rb +0 -49
- data/lib/cucumber/tree.rb +0 -16
- data/lib/cucumber/tree/feature.rb +0 -105
- data/lib/cucumber/tree/features.rb +0 -21
- data/lib/cucumber/tree/given_scenario.rb +0 -13
- data/lib/cucumber/tree/scenario.rb +0 -240
- data/lib/cucumber/tree/step.rb +0 -173
- data/lib/cucumber/tree/table.rb +0 -26
- data/lib/cucumber/tree/top_down_visitor.rb +0 -23
- data/lib/cucumber/treetop_parser/feature.treetop.erb +0 -254
- data/lib/cucumber/treetop_parser/feature_ar.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_cy.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_da.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_de.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_en-lol.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_en-tx.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_en.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_es.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_et.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_fi.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_fr.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_id.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_it.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_ja.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_ko.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_lt.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_nl.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_no.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_parser.rb +0 -36
- data/lib/cucumber/treetop_parser/feature_pl.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_pt.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_ro.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_ro2.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_ru.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_se.rb +0 -1951
- data/lib/cucumber/treetop_parser/feature_zh-CN.rb +0 -1951
- data/lib/cucumber/world.rb +0 -1
- data/lib/cucumber/world/pending.rb +0 -22
- data/setup.rb +0 -1585
- data/spec/cucumber/cli_spec.rb +0 -521
- data/spec/cucumber/executor_spec.rb +0 -382
- data/spec/cucumber/formatters/autotest_formatter_spec.rb +0 -26
- data/spec/cucumber/formatters/features.html +0 -269
- data/spec/cucumber/formatters/html_formatter_spec.rb +0 -110
- data/spec/cucumber/formatters/pretty_formatter_spec.rb +0 -410
- data/spec/cucumber/formatters/progress_formatter_spec.rb +0 -81
- data/spec/cucumber/model/table_spec.rb +0 -32
- data/spec/cucumber/tree/feature_spec.rb +0 -122
- data/spec/cucumber/tree/row_scenario_outline_spec.rb +0 -73
- data/spec/cucumber/tree/row_scenario_spec.rb +0 -55
- data/spec/cucumber/tree/row_step_outline_spec.rb +0 -38
- data/spec/cucumber/tree/scenario_outline_spec.rb +0 -50
- data/spec/cucumber/tree/scenario_spec.rb +0 -134
- data/spec/cucumber/tree/step_outline_spec.rb +0 -17
- data/spec/cucumber/tree/step_spec.rb +0 -59
- data/spec/cucumber/treetop_parser/feature_parser_spec.rb +0 -120
data/lib/cucumber/broadcaster.rb
CHANGED
@@ -5,14 +5,9 @@ module Cucumber
|
|
5
5
|
@receivers = receivers
|
6
6
|
end
|
7
7
|
|
8
|
-
def register(receiver)
|
9
|
-
@receivers << receiver
|
10
|
-
end
|
11
|
-
|
12
8
|
def method_missing(method_name, *args)
|
13
9
|
@receivers.each do |receiver|
|
14
|
-
|
15
|
-
r.__send__(method_name, *args) if receiver.respond_to?(method_name)
|
10
|
+
receiver.__send__(method_name, *args)
|
16
11
|
end
|
17
12
|
end
|
18
13
|
|
@@ -0,0 +1,339 @@
|
|
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. Prefix tags with ! to",
|
77
|
+
"exclude features or scenarios having that tag. tags can be specified",
|
78
|
+
"with or without the @ prefix.") do |v|
|
79
|
+
@options[:tags] = v.split(",")
|
80
|
+
end
|
81
|
+
opts.on("-s SCENARIO", "--scenario SCENARIO",
|
82
|
+
"Only execute the scenario with the given name. If this option",
|
83
|
+
"is given more than once, run all the specified scenarios.") do |v|
|
84
|
+
@options[:scenario_names] << v
|
85
|
+
end
|
86
|
+
opts.on("-e", "--exclude PATTERN", "Don't run feature files matching PATTERN") do |v|
|
87
|
+
@options[:excludes] << v
|
88
|
+
end
|
89
|
+
opts.on("-p", "--profile PROFILE", "Pull commandline arguments from cucumber.yml.") do |v|
|
90
|
+
parse_args_from_profile(v)
|
91
|
+
end
|
92
|
+
opts.on("-c", "--[no-]color",
|
93
|
+
"Whether or not to use ANSI color in the output. Cucumber decides",
|
94
|
+
"based on your platform and the output destination if not specified.") do |v|
|
95
|
+
Term::ANSIColor.coloring = v
|
96
|
+
end
|
97
|
+
opts.on("-d", "--dry-run", "Invokes formatters without executing the steps.",
|
98
|
+
"Implies --quiet.") do
|
99
|
+
@options[:dry_run] = true
|
100
|
+
@quiet = true
|
101
|
+
end
|
102
|
+
opts.on("-a", "--autoformat DIRECTORY",
|
103
|
+
"Reformats (pretty prints) feature files and write them to DIRECTORY.",
|
104
|
+
"Be careful if you choose to overwrite the originals.",
|
105
|
+
"Implies --dry-run --formatter pretty.") do |directory|
|
106
|
+
@options[:autoformat] = directory
|
107
|
+
Term::ANSIColor.coloring = false
|
108
|
+
@options[:dry_run] = true
|
109
|
+
@quiet = true
|
110
|
+
end
|
111
|
+
opts.on("-m", "--no-multiline",
|
112
|
+
"Don't print multiline strings and tables under steps.") do
|
113
|
+
@options[:no_multiline] = true
|
114
|
+
end
|
115
|
+
opts.on("-n", "--no-source",
|
116
|
+
"Don't print the file and line of the step definition with the steps.") do
|
117
|
+
@options[:source] = false
|
118
|
+
end
|
119
|
+
opts.on("-i", "--no-snippets", "Don't print snippets for pending steps.") do
|
120
|
+
@options[:snippets] = false
|
121
|
+
end
|
122
|
+
opts.on("-q", "--quiet", "Alias for --no-snippets --no-source.") do
|
123
|
+
@quiet = true
|
124
|
+
end
|
125
|
+
opts.on("-b", "--backtrace", "Show full backtrace for all errors.") do
|
126
|
+
Exception.cucumber_full_backtrace = true
|
127
|
+
end
|
128
|
+
opts.on("--strict", "Fail if there are any undefined steps.") do
|
129
|
+
@options[:strict] = true
|
130
|
+
end
|
131
|
+
opts.on("-v", "--verbose", "Show the files and features loaded.") do
|
132
|
+
@options[:verbose] = true
|
133
|
+
end
|
134
|
+
opts.on("-g", "--guess", "Guess best match for Ambiguous steps.") do
|
135
|
+
@options[:guess] = true
|
136
|
+
end
|
137
|
+
opts.on_tail("--version", "Show version.") do
|
138
|
+
@out_stream.puts VERSION::STRING
|
139
|
+
Kernel.exit
|
140
|
+
end
|
141
|
+
opts.on_tail("--help", "You're looking at it.") do
|
142
|
+
@out_stream.puts opts.help
|
143
|
+
Kernel.exit
|
144
|
+
end
|
145
|
+
end.parse!
|
146
|
+
|
147
|
+
@options[:formats]['pretty'] = @out_stream if @options[:formats].empty?
|
148
|
+
|
149
|
+
@options[:snippets] = true if !@quiet && @options[:snippets].nil?
|
150
|
+
@options[:source] = true if !@quiet && @options[:source].nil?
|
151
|
+
|
152
|
+
# Whatever is left after option parsing is the FILE arguments
|
153
|
+
@paths += args
|
154
|
+
end
|
155
|
+
|
156
|
+
def ast_filter
|
157
|
+
Ast::Filter.new(@options)
|
158
|
+
end
|
159
|
+
|
160
|
+
def verbose?
|
161
|
+
@options[:verbose]
|
162
|
+
end
|
163
|
+
|
164
|
+
def strict?
|
165
|
+
@options[:strict]
|
166
|
+
end
|
167
|
+
|
168
|
+
def guess?
|
169
|
+
!!@options[:guess]
|
170
|
+
end
|
171
|
+
|
172
|
+
def load_language
|
173
|
+
Cucumber.load_language(@options[:lang])
|
174
|
+
|
175
|
+
if Cucumber.language_incomplete?
|
176
|
+
list_keywords(Cucumber.lang)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def build_formatter_broadcaster(step_mother)
|
181
|
+
return Formatter::Pretty.new(step_mother, nil, @options) if @options[:autoformat]
|
182
|
+
formatters = @options[:formats].map do |format, out|
|
183
|
+
if String === out # file name
|
184
|
+
out = File.open(out, Cucumber.file_mode('w'))
|
185
|
+
at_exit do
|
186
|
+
out.flush
|
187
|
+
out.close
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
begin
|
192
|
+
formatter_class = formatter_class(format)
|
193
|
+
formatter_class.new(step_mother, out, @options)
|
194
|
+
rescue Exception => e
|
195
|
+
exit_with_error("Error creating formatter: #{format}", e)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
broadcaster = Broadcaster.new(formatters)
|
200
|
+
broadcaster.options = @options
|
201
|
+
return broadcaster
|
202
|
+
end
|
203
|
+
|
204
|
+
def formatter_class(format)
|
205
|
+
case format
|
206
|
+
when 'pretty' then Formatter::Pretty
|
207
|
+
when 'progress' then Formatter::Progress
|
208
|
+
when 'profile' then Formatter::Profile
|
209
|
+
when 'rerun' then Formatter::Rerun
|
210
|
+
when 'html' then Formatter::Html
|
211
|
+
else
|
212
|
+
constantize(format)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def files_to_require
|
217
|
+
requires = @options[:require] || feature_dirs
|
218
|
+
files = requires.map do |path|
|
219
|
+
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
220
|
+
File.directory?(path) ? Dir["#{path}/**/*.rb"] : path
|
221
|
+
end.flatten.uniq
|
222
|
+
files.sort { |a,b| (b =~ %r{/support/} || -1) <=> (a =~ %r{/support/} || -1) }.reject{|f| f =~ /^http/}
|
223
|
+
end
|
224
|
+
|
225
|
+
def feature_files
|
226
|
+
potential_feature_files = @paths.map do |path|
|
227
|
+
path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
|
228
|
+
path = path.chomp('/')
|
229
|
+
File.directory?(path) ? Dir["#{path}/**/*.feature"] : path
|
230
|
+
end.flatten.uniq
|
231
|
+
|
232
|
+
@options[:excludes].each do |exclude|
|
233
|
+
potential_feature_files.reject! do |path|
|
234
|
+
path =~ /#{Regexp.escape(exclude)}/
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
potential_feature_files
|
239
|
+
end
|
240
|
+
|
241
|
+
protected
|
242
|
+
|
243
|
+
def feature_dirs
|
244
|
+
feature_files.map { |f| File.directory?(f) ? f : File.dirname(f) }.uniq
|
245
|
+
end
|
246
|
+
|
247
|
+
def constantize(camel_cased_word)
|
248
|
+
names = camel_cased_word.split('::')
|
249
|
+
names.shift if names.empty? || names.first.empty?
|
250
|
+
|
251
|
+
constant = Object
|
252
|
+
names.each do |name|
|
253
|
+
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
254
|
+
end
|
255
|
+
constant
|
256
|
+
end
|
257
|
+
|
258
|
+
def parse_args_from_profile(profile)
|
259
|
+
unless cucumber_yml.has_key?(profile)
|
260
|
+
return(exit_with_error <<-END_OF_ERROR)
|
261
|
+
Could not find profile: '#{profile}'
|
262
|
+
|
263
|
+
Defined profiles in cucumber.yml:
|
264
|
+
* #{cucumber_yml.keys.join("\n * ")}
|
265
|
+
END_OF_ERROR
|
266
|
+
end
|
267
|
+
|
268
|
+
args_from_yml = cucumber_yml[profile] || ''
|
269
|
+
|
270
|
+
if !args_from_yml.is_a?(String)
|
271
|
+
exit_with_error "Profiles must be defined as a String. The '#{profile}' profile was #{args_from_yml.inspect} (#{args_from_yml.class}).\n"
|
272
|
+
elsif args_from_yml =~ /^\s*$/
|
273
|
+
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"
|
274
|
+
else
|
275
|
+
parse!(args_from_yml.split(' '))
|
276
|
+
end
|
277
|
+
|
278
|
+
rescue YmlLoadError => e
|
279
|
+
exit_with_error(e.message)
|
280
|
+
end
|
281
|
+
|
282
|
+
def cucumber_yml
|
283
|
+
return @cucumber_yml if @cucumber_yml
|
284
|
+
unless File.exist?('cucumber.yml')
|
285
|
+
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")
|
286
|
+
end
|
287
|
+
|
288
|
+
require 'yaml'
|
289
|
+
begin
|
290
|
+
@cucumber_yml = YAML::load(IO.read('cucumber.yml'))
|
291
|
+
rescue Exception => e
|
292
|
+
raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentaion on correct profile usage.\n")
|
293
|
+
end
|
294
|
+
|
295
|
+
if @cucumber_yml.nil? || !@cucumber_yml.is_a?(Hash)
|
296
|
+
raise(YmlLoadError,"cucumber.yml was found, but was blank or malformed. Please refer to cucumber's documentaion on correct profile usage.\n")
|
297
|
+
end
|
298
|
+
|
299
|
+
return @cucumber_yml
|
300
|
+
end
|
301
|
+
|
302
|
+
def list_keywords(lang)
|
303
|
+
unless Cucumber::LANGUAGES[lang]
|
304
|
+
exit_with_error("No language with key #{lang}")
|
305
|
+
end
|
306
|
+
LanguageHelpFormatter.list_keywords(@out_stream, lang)
|
307
|
+
Kernel.exit
|
308
|
+
end
|
309
|
+
|
310
|
+
def list_languages
|
311
|
+
LanguageHelpFormatter.list_languages(@out_stream)
|
312
|
+
Kernel.exit
|
313
|
+
end
|
314
|
+
|
315
|
+
def default_options
|
316
|
+
{
|
317
|
+
:strict => false,
|
318
|
+
:require => nil,
|
319
|
+
:lang => 'en',
|
320
|
+
:dry_run => false,
|
321
|
+
:formats => {},
|
322
|
+
:excludes => [],
|
323
|
+
:tags => [],
|
324
|
+
:scenario_names => []
|
325
|
+
}
|
326
|
+
end
|
327
|
+
|
328
|
+
def exit_with_error(error_message, e=nil)
|
329
|
+
@error_stream.puts(error_message)
|
330
|
+
if e
|
331
|
+
@error_stream.puts("#{e.message} (#{e.class})")
|
332
|
+
@error_stream.puts(e.backtrace.join("\n"))
|
333
|
+
end
|
334
|
+
Kernel.exit 1
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
end
|
339
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'cucumber/formatter/pretty'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Cli
|
5
|
+
class LanguageHelpFormatter < Formatter::Pretty
|
6
|
+
INCOMPLETE = %{
|
7
|
+
The Cucumber grammar has evolved since this translation was written.
|
8
|
+
Please help us complete the translation by translating the missing words in
|
9
|
+
|
10
|
+
#{Cucumber::LANGUAGE_FILE}
|
11
|
+
|
12
|
+
Then contribute back to the Cucumber project. Details here:
|
13
|
+
http://wiki.github.com/aslakhellesoy/cucumber/spoken-languages
|
14
|
+
}
|
15
|
+
|
16
|
+
def self.list_languages(io)
|
17
|
+
raw = Cucumber::LANGUAGES.keys.sort.map do |lang|
|
18
|
+
[lang, Cucumber::LANGUAGES[lang]['name'], Cucumber::LANGUAGES[lang]['native']]
|
19
|
+
end
|
20
|
+
table = Ast::Table.new(raw)
|
21
|
+
new(nil, io, {:check_lang=>true}, '').visit_multiline_arg(table, :passed)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.list_keywords(io, lang)
|
25
|
+
raw = Cucumber::KEYWORD_KEYS.map do |key|
|
26
|
+
[key, Cucumber::LANGUAGES[lang][key]]
|
27
|
+
end
|
28
|
+
table = Ast::Table.new(raw)
|
29
|
+
new(nil, io, {:incomplete => Cucumber.language_incomplete?(lang)}, '').visit_multiline_arg(table, :passed)
|
30
|
+
end
|
31
|
+
|
32
|
+
def visit_multiline_arg(table, status)
|
33
|
+
if @options[:incomplete]
|
34
|
+
@io.puts(format_string(INCOMPLETE, :failed))
|
35
|
+
end
|
36
|
+
super
|
37
|
+
end
|
38
|
+
|
39
|
+
def visit_table_row(table_row, status)
|
40
|
+
@col = 1
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
def visit_table_cell_value(value, width, status)
|
45
|
+
if @col == 1
|
46
|
+
if(@options[:check_lang])
|
47
|
+
@incomplete = Cucumber.language_incomplete?(value)
|
48
|
+
end
|
49
|
+
status = :comment
|
50
|
+
elsif @incomplete
|
51
|
+
status = :failed
|
52
|
+
end
|
53
|
+
|
54
|
+
@col += 1
|
55
|
+
super(value, width, status)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'cucumber'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'cucumber/parser'
|
5
|
+
require 'cucumber/formatter'
|
6
|
+
require 'cucumber/cli/language_help_formatter'
|
7
|
+
require 'cucumber/cli/configuration'
|
8
|
+
|
9
|
+
module Cucumber
|
10
|
+
module Cli
|
11
|
+
class Main
|
12
|
+
class << self
|
13
|
+
def step_mother=(step_mother)
|
14
|
+
@step_mother = step_mother
|
15
|
+
@step_mother.extend(StepMother)
|
16
|
+
@step_mother.snippet_generator = StepDefinition
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute(args)
|
20
|
+
new(args).execute!(@step_mother)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(args, out_stream = STDOUT, error_stream = STDERR)
|
25
|
+
@args = args
|
26
|
+
@out_stream = out_stream == STDOUT ? Formatter::ColorIO.new : out_stream
|
27
|
+
@error_stream = error_stream
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute!(step_mother)
|
31
|
+
configuration.load_language
|
32
|
+
step_mother.options = configuration.options
|
33
|
+
|
34
|
+
require_files
|
35
|
+
enable_diffing
|
36
|
+
|
37
|
+
features = load_plain_text_features
|
38
|
+
|
39
|
+
visitor = configuration.build_formatter_broadcaster(step_mother)
|
40
|
+
visitor.visit_features(features)
|
41
|
+
|
42
|
+
failure = features.steps[:failed].any? || (configuration.strict? && features.steps[:undefined].length)
|
43
|
+
Kernel.exit(failure ? 1 : 0)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def configuration
|
49
|
+
return @configuration if @configuration
|
50
|
+
|
51
|
+
@configuration = Configuration.new(@out_stream, @error_stream)
|
52
|
+
@configuration.parse!(@args)
|
53
|
+
@configuration
|
54
|
+
end
|
55
|
+
|
56
|
+
def require_files
|
57
|
+
verbose_log("Ruby files required:")
|
58
|
+
configuration.files_to_require.each do |lib|
|
59
|
+
begin
|
60
|
+
require lib
|
61
|
+
verbose_log(" * #{lib}")
|
62
|
+
rescue LoadError => e
|
63
|
+
e.message << "\nFailed to load #{lib}"
|
64
|
+
raise e
|
65
|
+
end
|
66
|
+
end
|
67
|
+
verbose_log("\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
def load_plain_text_features
|
71
|
+
filter = configuration.ast_filter
|
72
|
+
features = Ast::Features.new(filter)
|
73
|
+
parser = Parser::FeatureParser.new
|
74
|
+
|
75
|
+
verbose_log("Features:")
|
76
|
+
configuration.feature_files.each do |f|
|
77
|
+
features.add_feature(parser.parse_file(f))
|
78
|
+
verbose_log(" * #{f}")
|
79
|
+
end
|
80
|
+
verbose_log("\n"*2)
|
81
|
+
features
|
82
|
+
end
|
83
|
+
|
84
|
+
def verbose_log(string)
|
85
|
+
@out_stream.puts(string) if configuration.verbose?
|
86
|
+
end
|
87
|
+
|
88
|
+
def enable_diffing
|
89
|
+
if defined?(::Spec)
|
90
|
+
require 'spec/expectations/differs/default'
|
91
|
+
options = OpenStruct.new(:diff_format => :unified, :context_lines => 3)
|
92
|
+
::Spec::Expectations.differ = ::Spec::Expectations::Differs::Default.new(options)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
Cucumber::Cli::Main.step_mother = self
|