aslakhellesoy-cucumber 0.1.99.4 → 0.1.99.5
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 +4 -1
- data/Manifest.txt +2 -10
- data/cucumber.yml +1 -0
- data/examples/cs/README.textile +1 -0
- data/examples/cs/Rakefile +12 -0
- data/examples/cs/compile.bat +1 -0
- data/examples/cs/features/addition.feature +16 -0
- data/examples/cs/features/step_definitons/calculator_steps.rb +19 -0
- data/examples/cs/src/demo/Calculator.cs +20 -0
- data/examples/dos_line_endings/Rakefile +6 -0
- data/examples/dos_line_endings/features/dos_line_endings.feature +9 -0
- data/examples/i18n/README.textile +18 -0
- data/examples/i18n/Rakefile +32 -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 +28 -0
- data/examples/i18n/ar/lib/calculator.rb +10 -0
- data/examples/i18n/da/Rakefile +6 -0
- data/examples/i18n/da/features/step_definitons/kalkulator_steps.rb +24 -0
- data/examples/i18n/da/features/summering.feature +17 -0
- data/examples/i18n/da/lib/kalkulator.rb +11 -0
- data/examples/i18n/de/Rakefile +6 -0
- data/examples/i18n/de/features/addition.feature +16 -0
- data/examples/i18n/de/features/division.feature +9 -0
- data/examples/i18n/de/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/de/lib/calculator.rb +14 -0
- data/examples/i18n/en/Rakefile +6 -0
- data/examples/i18n/en/features/addition.feature +16 -0
- data/examples/i18n/en/features/division.feature +9 -0
- data/examples/i18n/en/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/en/lib/calculator.rb +14 -0
- data/examples/i18n/es/Rakefile +6 -0
- data/examples/i18n/es/features/adicion.feature +17 -0
- data/examples/i18n/es/features/step_definitons/calculador_steps.rb +24 -0
- data/examples/i18n/es/lib/calculador.rb +11 -0
- data/examples/i18n/et/Rakefile +6 -0
- data/examples/i18n/et/features/liitmine.feature +17 -0
- data/examples/i18n/et/features/step_definitions/kalkulaator_steps.rb +24 -0
- data/examples/i18n/et/lib/kalkulaator.rb +10 -0
- data/examples/i18n/fi/Rakefile +6 -0
- data/examples/i18n/fi/features/jakolasku.feature +9 -0
- data/examples/i18n/fi/features/step_definitons/laskin_steps.rb +24 -0
- data/examples/i18n/fi/features/yhteenlasku.feature +16 -0
- data/examples/i18n/fi/lib/laskin.rb +14 -0
- data/examples/i18n/fr/Rakefile +6 -0
- data/examples/i18n/fr/features/addition.feature +15 -0
- data/examples/i18n/fr/features/step_definitions/calculatrice_steps.rb +27 -0
- data/examples/i18n/fr/lib/calculatrice.rb +10 -0
- data/examples/i18n/id/Rakefile +6 -0
- data/examples/i18n/id/features/addition.feature +16 -0
- data/examples/i18n/id/features/division.feature +9 -0
- data/examples/i18n/id/features/step_definitons/calculator_steps.rb +24 -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 +24 -0
- data/examples/i18n/it/lib/calcolatrice.rb +11 -0
- data/examples/i18n/ja/README.txt +5 -0
- data/examples/i18n/ja/Rakefile +6 -0
- data/examples/i18n/ja/features/addition.feature +16 -0
- data/examples/i18n/ja/features/division.feature +9 -0
- data/examples/i18n/ja/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/ja/lib/calculator.rb +14 -0
- data/examples/i18n/ko/Rakefile +6 -0
- data/examples/i18n/ko/features/addition.feature +16 -0
- data/examples/i18n/ko/features/division.feature +10 -0
- data/examples/i18n/ko/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/ko/lib/calculator.rb +14 -0
- data/examples/i18n/lt/Rakefile +6 -0
- data/examples/i18n/lt/features/addition.feature +17 -0
- data/examples/i18n/lt/features/division.feature +9 -0
- data/examples/i18n/lt/features/step_definitons/calculator_steps.rb +24 -0
- data/examples/i18n/lt/lib/calculator.rb +14 -0
- data/examples/i18n/no/Rakefile +6 -0
- data/examples/i18n/no/features/step_definitons/kalkulator_steps.rb +24 -0
- data/examples/i18n/no/features/summering.feature +18 -0
- data/examples/i18n/no/lib/kalkulator.rb +11 -0
- data/examples/i18n/pt/Rakefile +6 -0
- data/examples/i18n/pt/features/adicao.feature +10 -0
- data/examples/i18n/pt/features/step_definitions/calculadora_steps.rb +24 -0
- 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 +24 -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/i18n/se/features/step_definitons/kalkulator_steps.rb +24 -0
- data/examples/i18n/se/features/summering.feature +17 -0
- data/examples/i18n/se/lib/kalkulator.rb +11 -0
- data/examples/i18n/zh-CN/Rakefile +6 -0
- data/examples/i18n/zh-CN/features/addition.feature +17 -0
- data/examples/i18n/zh-CN/features/step_definitons/calculator_steps.rb +26 -0
- data/examples/i18n/zh-CN/lib/calculator.rb +10 -0
- data/examples/java/README.textile +22 -0
- data/examples/java/Rakefile +12 -0
- data/examples/java/features/hello.feature +11 -0
- data/examples/java/features/step_definitons/hello_steps.rb +25 -0
- data/examples/java/features/step_definitons/tree_steps.rb +14 -0
- data/examples/java/features/tree.feature +9 -0
- 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/selenium/Rakefile +6 -0
- data/examples/selenium/features/search.feature +9 -0
- data/examples/selenium/features/step_definitons/stories_steps.rb +40 -0
- data/examples/self_test/README.textile +6 -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 +15 -0
- data/examples/self_test/features/sample.feature +16 -0
- data/examples/self_test/features/step_definitions/sample_steps.rb +25 -0
- data/examples/test_unit/Rakefile +6 -0
- data/examples/test_unit/features/step_definitions/test_unit_steps.rb +26 -0
- data/examples/test_unit/features/test_unit.feature +9 -0
- data/examples/tickets/Rakefile +11 -0
- data/examples/tickets/cucumber.yml +2 -0
- data/examples/tickets/features/lib/eatting_machine.rb +18 -0
- data/examples/tickets/features/lib/pantry.rb +20 -0
- data/examples/tickets/features/scenario_outline.feature +95 -0
- data/examples/tickets/features/step_definitons/scenario_outline_steps.rb +42 -0
- data/examples/tickets/features/step_definitons/tickets_steps.rb +60 -0
- data/examples/tickets/features/tickets.feature +28 -0
- data/examples/watir/README.textile +16 -0
- data/examples/watir/Rakefile +6 -0
- data/examples/watir/features/search.feature +9 -0
- data/examples/watir/features/step_definitons/search_steps.rb +24 -0
- data/examples/watir/features/support/env.rb +32 -0
- data/features/cucumber_cli.feature +331 -0
- data/features/cucumber_cli_outlines.feature +90 -0
- data/features/report_called_undefined_steps.feature +32 -0
- data/features/step_definitions/cucumber_steps.rb +31 -0
- data/features/step_definitions/extra_steps.rb +2 -0
- data/features/support/env.rb +7 -0
- data/gem_tasks/deployment.rake +11 -0
- data/gem_tasks/environment.rake +7 -0
- data/gem_tasks/features.rake +6 -0
- data/gem_tasks/fix_cr_lf.rake +10 -0
- data/gem_tasks/flog.rake +4 -0
- data/gem_tasks/gemspec.rake +10 -0
- data/gem_tasks/rspec.rake +35 -0
- data/gem_tasks/yard.rake +8 -0
- data/lib/autotest/cucumber.rb +6 -0
- data/lib/autotest/cucumber_mixin.rb +124 -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 +72 -0
- data/lib/cucumber/ast.rb +27 -0
- data/lib/cucumber/ast/comment.rb +26 -0
- data/lib/cucumber/ast/examples.rb +22 -0
- data/lib/cucumber/ast/feature.rb +60 -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 +95 -0
- data/lib/cucumber/ast/scenario_outline.rb +83 -0
- data/lib/cucumber/ast/step.rb +139 -0
- data/lib/cucumber/ast/table.rb +214 -0
- data/lib/cucumber/ast/tags.rb +33 -0
- data/lib/cucumber/ast/visitor.rb +93 -0
- data/lib/cucumber/broadcaster.rb +15 -0
- data/lib/cucumber/cli.rb +414 -0
- data/lib/cucumber/core_ext/exception.rb +53 -0
- data/lib/cucumber/core_ext/instance_exec.rb +54 -0
- data/lib/cucumber/core_ext/proc.rb +33 -0
- data/lib/cucumber/core_ext/string.rb +48 -0
- data/lib/cucumber/formatter.rb +1 -0
- data/lib/cucumber/formatter/ansicolor.rb +106 -0
- data/lib/cucumber/formatter/console.rb +116 -0
- data/lib/cucumber/formatter/pretty.rb +158 -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/formatters/unicode.rb +2 -0
- data/lib/cucumber/jbehave.rb +104 -0
- data/lib/cucumber/languages.yml +314 -0
- data/lib/cucumber/parser.rb +24 -0
- data/lib/cucumber/parser/basic.rb +0 -0
- data/lib/cucumber/parser/feature.rb +1351 -0
- data/lib/cucumber/parser/feature.tt +160 -0
- data/lib/cucumber/parser/i18n.tt +27 -0
- data/lib/cucumber/parser/table.rb +396 -0
- data/lib/cucumber/parser/table.tt +53 -0
- data/lib/cucumber/parser/treetop_ext.rb +67 -0
- data/lib/cucumber/platform.rb +18 -0
- data/lib/cucumber/rails/rspec.rb +5 -0
- data/lib/cucumber/rails/world.rb +73 -0
- data/lib/cucumber/rake/task.rb +106 -0
- data/lib/cucumber/step_definition.rb +87 -0
- data/lib/cucumber/step_mother.rb +164 -0
- data/lib/cucumber/version.rb +10 -0
- data/pretty.txt +486 -0
- data/rails_generators/cucumber/USAGE +11 -0
- data/rails_generators/cucumber/cucumber_generator.rb +31 -0
- data/rails_generators/cucumber/templates/cucumber +8 -0
- data/rails_generators/cucumber/templates/cucumber.rake +7 -0
- data/rails_generators/cucumber/templates/env.rb +16 -0
- data/rails_generators/cucumber/templates/paths.rb +12 -0
- data/rails_generators/cucumber/templates/webrat_steps.rb +99 -0
- data/rails_generators/feature/USAGE +12 -0
- data/rails_generators/feature/feature_generator.rb +36 -0
- data/rails_generators/feature/templates/feature.erb +31 -0
- data/rails_generators/feature/templates/steps.erb +24 -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/broadcaster_spec.rb +14 -0
- data/spec/cucumber/cli_spec.rb +416 -0
- data/spec/cucumber/core_ext/proc_spec.rb +37 -0
- data/spec/cucumber/core_ext/string_spec.rb +42 -0
- data/spec/cucumber/formatter/ansicolor_spec.rb +35 -0
- 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 +198 -0
- data/spec/cucumber/parser/feature_parser_spec.rb +247 -0
- data/spec/cucumber/parser/table_parser_spec.rb +48 -0
- data/spec/cucumber/rails/stubs/mini_rails.rb +18 -0
- data/spec/cucumber/rails/stubs/test_help.rb +1 -0
- data/spec/cucumber/rails/world_spec.rb +11 -0
- data/spec/cucumber/sell_cucumbers.feature +19 -0
- data/spec/cucumber/step_definition_spec.rb +62 -0
- data/spec/cucumber/treetop_parser/empty_feature.feature +4 -0
- data/spec/cucumber/treetop_parser/empty_scenario.feature +9 -0
- data/spec/cucumber/treetop_parser/empty_scenario_outline.feature +3 -0
- data/spec/cucumber/treetop_parser/fit_scenario.feature +8 -0
- data/spec/cucumber/treetop_parser/given_scenario.feature +9 -0
- data/spec/cucumber/treetop_parser/invalid_scenario_outlines.feature +7 -0
- data/spec/cucumber/treetop_parser/multiline_steps.feature +17 -0
- data/spec/cucumber/treetop_parser/multiple_tables.feature +27 -0
- data/spec/cucumber/treetop_parser/scenario_outline.feature +16 -0
- data/spec/cucumber/treetop_parser/spaces.feature +12 -0
- data/spec/cucumber/treetop_parser/test_dos.feature +25 -0
- data/spec/cucumber/treetop_parser/with_comments.feature +10 -0
- data/spec/cucumber/treetop_parser/with_tags.feature +18 -0
- data/spec/cucumber/world/pending_spec.rb +47 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +21 -0
- metadata +7 -1
@@ -0,0 +1,53 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Parser
|
3
|
+
grammar Table
|
4
|
+
|
5
|
+
rule table
|
6
|
+
table_row+ {
|
7
|
+
def build
|
8
|
+
Ast::Table.new(raw)
|
9
|
+
end
|
10
|
+
|
11
|
+
def raw
|
12
|
+
elements.map{|e| e.build}
|
13
|
+
end
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
rule table_row
|
18
|
+
space* '|' cells:(cell '|')+ space* (eol+ / eof) {
|
19
|
+
def build
|
20
|
+
row = cells.elements.map do |elt|
|
21
|
+
value = elt.cell.text_value.strip
|
22
|
+
value.empty? ? nil : value
|
23
|
+
end
|
24
|
+
|
25
|
+
class << row
|
26
|
+
attr_accessor :line
|
27
|
+
end
|
28
|
+
row.line = cells.line
|
29
|
+
|
30
|
+
row
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
rule cell
|
36
|
+
(!('|' / eol) .)*
|
37
|
+
end
|
38
|
+
|
39
|
+
rule space
|
40
|
+
[ \t]
|
41
|
+
end
|
42
|
+
|
43
|
+
rule eol
|
44
|
+
"\n" / ("\r" "\n"?)
|
45
|
+
end
|
46
|
+
|
47
|
+
rule eof
|
48
|
+
!.
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'treetop'
|
2
|
+
require 'treetop/runtime'
|
3
|
+
require 'treetop/ruby_extensions'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Parser
|
7
|
+
module TreetopExt
|
8
|
+
FILE_LINE_PATTERN = /^([\w\W]*?):([\d:]+)$/
|
9
|
+
|
10
|
+
# Parses a file and returns a Cucumber::Ast
|
11
|
+
def parse_file(file)
|
12
|
+
_, path, lines = *FILE_LINE_PATTERN.match(file)
|
13
|
+
if path
|
14
|
+
lines = lines.split(':').map { |line| line.to_i }
|
15
|
+
else
|
16
|
+
path = file
|
17
|
+
lines = []
|
18
|
+
end
|
19
|
+
|
20
|
+
feature = File.open(path, Cucumber.file_mode('r')) do |io|
|
21
|
+
parse_or_fail(io.read, path)
|
22
|
+
end
|
23
|
+
feature.lines = lines
|
24
|
+
feature
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class SyntaxError < StandardError
|
29
|
+
def initialize(parser, file, line_offset)
|
30
|
+
tf = parser.terminal_failures
|
31
|
+
expected = tf.size == 1 ? tf[0].expected_string.inspect : "one of #{tf.map{|f| f.expected_string.inspect}.uniq*', '}"
|
32
|
+
after = parser.input[parser.index...parser.failure_index]
|
33
|
+
found = parser.input[parser.failure_index..parser.failure_index]
|
34
|
+
|
35
|
+
line = parser.failure_line + line_offset
|
36
|
+
message = "#{file}:#{line}:#{parser.failure_column}: " +
|
37
|
+
"Parse error, expected #{expected}. After #{after.inspect}. Found: #{found.inspect}"
|
38
|
+
super(message)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module Treetop
|
45
|
+
module Runtime
|
46
|
+
class SyntaxNode
|
47
|
+
def line
|
48
|
+
input.line_of(interval.first)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class CompiledParser
|
53
|
+
include Cucumber::Parser::TreetopExt
|
54
|
+
|
55
|
+
def parse_or_fail(s, file=nil, line=0)
|
56
|
+
parse_tree = parse(s)
|
57
|
+
if parse_tree.nil?
|
58
|
+
raise Cucumber::Parser::SyntaxError.new(self, file, line)
|
59
|
+
else
|
60
|
+
ast = parse_tree.build
|
61
|
+
ast.file = file
|
62
|
+
ast
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Detect the platform we're running on so we can tweak behaviour
|
2
|
+
# in various places.
|
3
|
+
require 'rbconfig'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
module Cucumber
|
7
|
+
LANGUAGE_FILE = File.expand_path(File.dirname(__FILE__) + '/languages.yml')
|
8
|
+
LANGUAGES = YAML.load_file(LANGUAGE_FILE)
|
9
|
+
BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/cucumber')
|
10
|
+
JRUBY = defined?(JRUBY_VERSION)
|
11
|
+
IRONRUBY = Config::CONFIG['sitedir'] =~ /IronRuby/
|
12
|
+
WINDOWS = Config::CONFIG['host_os'] =~ /mswin|mingw/
|
13
|
+
WINDOWS_MRI = WINDOWS && !JRUBY && !IRONRUBY
|
14
|
+
RAILS = defined?(Rails)
|
15
|
+
RUBY_BINARY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
|
16
|
+
RUBY_1_9 = RUBY_VERSION =~ /^1\.9/
|
17
|
+
EXCEPTION_STATUS = Hash.new(:failed)
|
18
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Based on code from Brian Takita, Yurii Rashkovskii and Ben Mabey
|
2
|
+
# Adapted by Aslak Hellesøy
|
3
|
+
|
4
|
+
if defined?(ActiveRecord::Base)
|
5
|
+
require 'test_help'
|
6
|
+
else
|
7
|
+
require 'action_controller/test_process'
|
8
|
+
require 'action_controller/integration'
|
9
|
+
end
|
10
|
+
require 'test/unit/testresult'
|
11
|
+
|
12
|
+
# These allow exceptions to come through as opposed to being caught and having non-helpful responses returned.
|
13
|
+
ActionController::Base.class_eval do
|
14
|
+
def perform_action_with_rescue
|
15
|
+
perform_action_without_rescue
|
16
|
+
end
|
17
|
+
end
|
18
|
+
ActionController::Dispatcher.class_eval do
|
19
|
+
def self.failsafe_response(output, status, exception = nil)
|
20
|
+
raise exception
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# So that Test::Unit doesn't launch at the end - makes it think it has already been run.
|
25
|
+
Test::Unit.run = true if Test::Unit.respond_to?(:run=)
|
26
|
+
|
27
|
+
$cucumber_toplevel = self
|
28
|
+
|
29
|
+
module Cucumber #:nodoc:
|
30
|
+
module Rails
|
31
|
+
# All scenarios will execute in the context of a new instance of World.
|
32
|
+
class World < ActionController::IntegrationTest
|
33
|
+
if defined?(ActiveRecord::Base)
|
34
|
+
self.use_transactional_fixtures = false
|
35
|
+
else
|
36
|
+
def self.fixture_table_names; []; end # Workaround for projects that don't use ActiveRecord
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize #:nodoc:
|
40
|
+
@_result = Test::Unit::TestResult.new
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.use_transactional_fixtures
|
45
|
+
World.use_transactional_fixtures = true
|
46
|
+
if defined?(ActiveRecord::Base)
|
47
|
+
$cucumber_toplevel.Before do
|
48
|
+
if ActiveRecord::Base.connection.respond_to?(:increment_open_transactions)
|
49
|
+
ActiveRecord::Base.connection.increment_open_transactions
|
50
|
+
else
|
51
|
+
ActiveRecord::Base.__send__(:increment_open_transactions)
|
52
|
+
end
|
53
|
+
ActiveRecord::Base.connection.begin_db_transaction
|
54
|
+
ActionMailer::Base.deliveries = [] if defined?(ActionMailer::Base)
|
55
|
+
end
|
56
|
+
|
57
|
+
$cucumber_toplevel.After do
|
58
|
+
ActiveRecord::Base.connection.rollback_db_transaction
|
59
|
+
if ActiveRecord::Base.connection.respond_to?(:decrement_open_transactions)
|
60
|
+
ActiveRecord::Base.connection.decrement_open_transactions
|
61
|
+
else
|
62
|
+
ActiveRecord::Base.__send__(:decrement_open_transactions)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
World do
|
72
|
+
Cucumber::Rails::World.new
|
73
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'cucumber/platform'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Rake
|
5
|
+
# Defines a task for running features.
|
6
|
+
class Task
|
7
|
+
LIB = File.expand_path(File.dirname(__FILE__) + '/../..')
|
8
|
+
|
9
|
+
attr_accessor :libs
|
10
|
+
attr_accessor :binary
|
11
|
+
attr_accessor :step_list
|
12
|
+
attr_accessor :step_pattern
|
13
|
+
attr_accessor :feature_list
|
14
|
+
attr_accessor :feature_pattern
|
15
|
+
attr_accessor :cucumber_opts
|
16
|
+
attr_accessor :rcov
|
17
|
+
attr_accessor :rcov_opts
|
18
|
+
|
19
|
+
# Define a task
|
20
|
+
def initialize(task_name = "features", desc = "Run Features with Cucumber")
|
21
|
+
@task_name, @desc = task_name, desc
|
22
|
+
@libs = []
|
23
|
+
@rcov_opts = %w{--rails --exclude osx\/objc,gems\/}
|
24
|
+
|
25
|
+
yield self if block_given?
|
26
|
+
|
27
|
+
@feature_pattern = "features/**/*.feature" if feature_pattern.nil? && feature_list.nil?
|
28
|
+
@step_pattern = "features/**/*.rb" if step_pattern.nil? && step_list.nil?
|
29
|
+
|
30
|
+
@binary = binary.nil? ? Cucumber::BINARY : File.expand_path(binary)
|
31
|
+
@libs.insert(0, LIB) if binary == Cucumber::BINARY
|
32
|
+
|
33
|
+
define_task
|
34
|
+
end
|
35
|
+
|
36
|
+
def define_task
|
37
|
+
desc @desc
|
38
|
+
task @task_name do
|
39
|
+
ruby(arguments_for_ruby_execution.join(" ")) # ruby(*args) is broken on Windows
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def arguments_for_ruby_execution(task_args = nil)
|
44
|
+
lib_args = ['"%s"' % libs.join(File::PATH_SEPARATOR)]
|
45
|
+
cucumber_bin = ['"%s"' % binary]
|
46
|
+
cuc_opts = [(ENV['CUCUMBER_OPTS'] || cucumber_opts)]
|
47
|
+
|
48
|
+
step_files(task_args).each do |step_file|
|
49
|
+
cuc_opts << '--require'
|
50
|
+
cuc_opts << step_file
|
51
|
+
end
|
52
|
+
|
53
|
+
if rcov
|
54
|
+
args = (['-I'] + lib_args + ['-S', 'rcov'] + rcov_opts +
|
55
|
+
cucumber_bin + ['--'] + cuc_opts + feature_files(task_args)).flatten
|
56
|
+
else
|
57
|
+
args = (['-I'] + lib_args + cucumber_bin + cuc_opts + feature_files(task_args)).flatten
|
58
|
+
end
|
59
|
+
|
60
|
+
args
|
61
|
+
end
|
62
|
+
|
63
|
+
def feature_files(task_args = nil) # :nodoc:
|
64
|
+
if ENV['FEATURE']
|
65
|
+
FileList[ ENV['FEATURE'] ]
|
66
|
+
else
|
67
|
+
result = []
|
68
|
+
result += feature_list.to_a if feature_list
|
69
|
+
result += FileList[feature_pattern].to_a if feature_pattern
|
70
|
+
FileList[result]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def step_files(task_args = nil) # :nodoc:
|
75
|
+
if ENV['STEPS']
|
76
|
+
FileList[ ENV['STEPS'] ]
|
77
|
+
else
|
78
|
+
result = []
|
79
|
+
result += Array(step_list) if step_list
|
80
|
+
result += Array(FileList[step_pattern]) if step_pattern
|
81
|
+
FileList[result]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class FeatureTask < Task
|
87
|
+
|
88
|
+
def initialize(task_name = "feature", desc = "Run a specified feature with Cucumber. #{task_name}[feature_name]")
|
89
|
+
super(task_name, desc)
|
90
|
+
end
|
91
|
+
|
92
|
+
def define_task
|
93
|
+
desc @desc
|
94
|
+
task @task_name, :feature_name do |t, args|
|
95
|
+
ruby(arguments_for_ruby_execution(args).join(" ")) # ruby(*args) is broken on Windows
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def feature_files(task_arguments) # :nodoc:
|
100
|
+
FileList[File.join("features", "**", "#{task_arguments[:feature_name]}.feature")]
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'cucumber/core_ext/string'
|
2
|
+
require 'cucumber/core_ext/proc'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
# A Step Definition holds a Regexp and a Proc, and is created
|
6
|
+
# by calling <tt>Given</tt>, <tt>When</tt> or <tt>Then</tt>
|
7
|
+
# in the <tt>step_definitions</tt> ruby files - for example:
|
8
|
+
#
|
9
|
+
# Given /I have (\d+) cucumbers in my belly/ do
|
10
|
+
# # some code here
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
class StepDefinition
|
14
|
+
def self.snippet_text(step_keyword, step_name)
|
15
|
+
escaped = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/')
|
16
|
+
"#{step_keyword} /^#{escaped}$/ do\n pending\nend"
|
17
|
+
end
|
18
|
+
|
19
|
+
class MissingProc < StandardError
|
20
|
+
def message
|
21
|
+
"Step definitions must always have a proc"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :regexp
|
26
|
+
|
27
|
+
def initialize(pattern, &proc)
|
28
|
+
raise MissingProc if proc.nil?
|
29
|
+
if String === pattern
|
30
|
+
p = pattern.gsub(/\$\w+/, '(.*)')
|
31
|
+
pattern = Regexp.new("^#{p}$")
|
32
|
+
end
|
33
|
+
@regexp, @proc = pattern, proc
|
34
|
+
end
|
35
|
+
|
36
|
+
#:stopdoc:
|
37
|
+
|
38
|
+
def match(step_name)
|
39
|
+
case step_name
|
40
|
+
when String then @regexp.match(step_name)
|
41
|
+
when Regexp then @regexp == step_name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Formats the matched arguments of the associated Step. This method
|
46
|
+
# is usually called from visitors, which render output.
|
47
|
+
#
|
48
|
+
# The +format+ either be a String or a Proc.
|
49
|
+
#
|
50
|
+
# If it is a String it should be a format string according to
|
51
|
+
# <tt>Kernel#sprinf</tt>, for example:
|
52
|
+
#
|
53
|
+
# '<span class="param">%s</span></tt>'
|
54
|
+
#
|
55
|
+
# If it is a Proc, it should take one argument and return the formatted
|
56
|
+
# argument, for example:
|
57
|
+
#
|
58
|
+
# lambda { |param| "[#{param}]" }
|
59
|
+
#
|
60
|
+
def format_args(step_name, format)
|
61
|
+
step_name.gzub(@regexp, format)
|
62
|
+
end
|
63
|
+
|
64
|
+
def matched_args(step_name)
|
65
|
+
step_name.match(@regexp).captures
|
66
|
+
end
|
67
|
+
|
68
|
+
def execute(step_name, world, *args)
|
69
|
+
args = args.map{|arg| Ast::PyString === arg ? arg.to_s : arg}
|
70
|
+
begin
|
71
|
+
world.cucumber_instance_exec(true, @regexp.inspect, *args, &@proc)
|
72
|
+
rescue Cucumber::ArityMismatchError => e
|
73
|
+
e.backtrace.unshift(self.to_backtrace_line)
|
74
|
+
raise e
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_backtrace_line
|
79
|
+
"#{file_colon_line}:in `#{@regexp.inspect}'"
|
80
|
+
end
|
81
|
+
|
82
|
+
def file_colon_line
|
83
|
+
@proc.file_colon_line
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'cucumber/step_definition'
|
2
|
+
require 'cucumber/core_ext/instance_exec'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
# This is the main interface for registering step definitions, which is done
|
6
|
+
# from <tt>*_steps.rb</tt> files. This module is included right at the top-level
|
7
|
+
# so #register_step_definition (and more interestingly - its aliases) are
|
8
|
+
# available from the top-level.
|
9
|
+
module StepMother
|
10
|
+
attr_writer :snippet_generator
|
11
|
+
|
12
|
+
class Undefined < StandardError
|
13
|
+
attr_reader :step_name
|
14
|
+
|
15
|
+
def initialize(step_name)
|
16
|
+
super %{Undefined step: "#{step_name}"}
|
17
|
+
@step_name = step_name
|
18
|
+
end
|
19
|
+
Cucumber::EXCEPTION_STATUS[self] = :undefined
|
20
|
+
end
|
21
|
+
|
22
|
+
class Pending < StandardError
|
23
|
+
Cucumber::EXCEPTION_STATUS[self] = :pending
|
24
|
+
end
|
25
|
+
|
26
|
+
# Raised when a step matches 2 or more StepDefinition
|
27
|
+
class Ambiguous < StandardError
|
28
|
+
def initialize(step_name, step_definitions)
|
29
|
+
message = "Ambiguous match of \"#{step_name}\":\n\n"
|
30
|
+
message << step_definitions.map{|sd| sd.to_backtrace_line}.join("\n")
|
31
|
+
message << "\n\n"
|
32
|
+
super(message)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Raised when 2 or more StepDefinition have the same Regexp
|
37
|
+
class Redundant < StandardError
|
38
|
+
def initialize(step_def_1, step_def_2)
|
39
|
+
message = "Multiple step definitions have the same Regexp:\n\n"
|
40
|
+
message << step_def_1.to_backtrace_line << "\n"
|
41
|
+
message << step_def_2.to_backtrace_line << "\n\n"
|
42
|
+
super(message)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Registers a new StepDefinition. This method is aliased
|
47
|
+
# to <tt>Given</tt>, <tt>When</tt> and <tt>Then</tt>.
|
48
|
+
#
|
49
|
+
# See Cucumber#alias_steps for details on how to
|
50
|
+
# create your own aliases.
|
51
|
+
#
|
52
|
+
# The +&proc+ gets executed in the context of a <tt>world</tt>
|
53
|
+
# object, which is defined by #World. A new <tt>world</tt>
|
54
|
+
# object is created for each scenario and is shared across
|
55
|
+
# step definitions within that scenario.
|
56
|
+
def register_step_definition(regexp, &proc)
|
57
|
+
step_definition = StepDefinition.new(regexp, &proc)
|
58
|
+
step_definitions.each do |already|
|
59
|
+
raise Redundant.new(already, step_definition) if already.match(regexp)
|
60
|
+
end
|
61
|
+
step_definitions << step_definition
|
62
|
+
step_definition
|
63
|
+
end
|
64
|
+
|
65
|
+
def world(scenario, &proc)
|
66
|
+
world = new_world
|
67
|
+
begin
|
68
|
+
(@before_procs ||= []).each do |proc|
|
69
|
+
world.cucumber_instance_exec(false, 'Before', scenario, &proc)
|
70
|
+
end
|
71
|
+
yield world
|
72
|
+
ensure
|
73
|
+
(@after_procs ||= []).each do |proc|
|
74
|
+
world.cucumber_instance_exec(false, 'After', scenario, &proc)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Registers a Before proc. You can call this method as many times as you
|
80
|
+
# want (typically from ruby scripts under <tt>support</tt>).
|
81
|
+
def Before(&proc)
|
82
|
+
(@before_procs ||= []) << proc
|
83
|
+
end
|
84
|
+
|
85
|
+
def After(&proc)
|
86
|
+
(@after_procs ||= []) << proc
|
87
|
+
end
|
88
|
+
|
89
|
+
# Registers a World proc. You can call this method as many times as you
|
90
|
+
# want (typically from ruby scripts under <tt>support</tt>).
|
91
|
+
def World(&proc)
|
92
|
+
(@world_procs ||= []) << proc
|
93
|
+
end
|
94
|
+
|
95
|
+
# Creates a new world instance
|
96
|
+
def new_world #:nodoc:
|
97
|
+
world = Object.new
|
98
|
+
(@world_procs ||= []).each do |proc|
|
99
|
+
world = proc.call(world)
|
100
|
+
end
|
101
|
+
|
102
|
+
world.extend(WorldMethods)
|
103
|
+
world.__cucumber_step_mother = self
|
104
|
+
|
105
|
+
world.extend(::Spec::Matchers) if defined?(::Spec::Matchers)
|
106
|
+
world
|
107
|
+
end
|
108
|
+
|
109
|
+
# Looks up the StepDefinition that matches +step_name+
|
110
|
+
def step_definition(step_name) #:nodoc:
|
111
|
+
found = step_definitions.select do |step_definition|
|
112
|
+
step_definition.match(step_name)
|
113
|
+
end
|
114
|
+
raise Undefined.new(step_name) if found.empty?
|
115
|
+
raise Ambiguous.new(step_name, found) if found.size > 1
|
116
|
+
found[0]
|
117
|
+
end
|
118
|
+
|
119
|
+
def step_definitions
|
120
|
+
@step_definitions ||= []
|
121
|
+
end
|
122
|
+
|
123
|
+
def snippet_text(step_keyword, step_name)
|
124
|
+
@snippet_generator.snippet_text(step_keyword, step_name)
|
125
|
+
end
|
126
|
+
|
127
|
+
module WorldMethods #:nodoc:
|
128
|
+
attr_writer :__cucumber_step_mother, :__cucumber_current_step
|
129
|
+
|
130
|
+
# Call a step from within a step definition
|
131
|
+
def __cucumber_invoke(name, *multiline_arguments)
|
132
|
+
begin
|
133
|
+
# TODO: Very similar to code in Step. Refactor. Get back StepInvocation?
|
134
|
+
# Make more similar to JBehave?
|
135
|
+
step_definition = @__cucumber_step_mother.step_definition(name)
|
136
|
+
matched_args = step_definition.matched_args(name)
|
137
|
+
args = (matched_args + multiline_arguments)
|
138
|
+
step_definition.execute(name, self, *args)
|
139
|
+
rescue Exception => e
|
140
|
+
@__cucumber_current_step.exception = e
|
141
|
+
raise e
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def table(text, file=nil, line=0)
|
146
|
+
@table_parser ||= Parser::TableParser.new
|
147
|
+
@table_parser.parse_or_fail(text.strip, file, line)
|
148
|
+
end
|
149
|
+
|
150
|
+
def pending(message = "TODO")
|
151
|
+
if block_given?
|
152
|
+
begin
|
153
|
+
yield
|
154
|
+
rescue Exception => e
|
155
|
+
raise Pending.new(message)
|
156
|
+
end
|
157
|
+
raise Pending.new("Expected pending '#{message}' to fail. No Error was raised. No longer pending?")
|
158
|
+
else
|
159
|
+
raise Pending.new(message)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|