cucumber 2.1.0 → 2.2.0

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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -0
  3. data/Gemfile +3 -1
  4. data/History.md +18 -2
  5. data/README.md +5 -1
  6. data/cucumber.gemspec +3 -4
  7. data/cucumber.yml +2 -2
  8. data/features/docs/api/run_cli_main_with_existing_runtime.feature +4 -7
  9. data/features/docs/defining_steps/skip_scenario.feature +6 -2
  10. data/features/docs/formatters/api_methods.feature +36 -0
  11. data/features/docs/profiles.feature +2 -2
  12. data/features/lib/step_definitions/profile_steps.rb +1 -1
  13. data/lib/cucumber.rb +11 -4
  14. data/lib/cucumber/cli/configuration.rb +2 -2
  15. data/lib/cucumber/cli/options.rb +2 -2
  16. data/lib/cucumber/configuration.rb +25 -3
  17. data/lib/cucumber/deprecate.rb +29 -0
  18. data/lib/cucumber/filters/activate_steps.rb +39 -5
  19. data/lib/cucumber/formatter/console.rb +4 -4
  20. data/lib/cucumber/formatter/io.rb +1 -1
  21. data/lib/cucumber/formatter/legacy_api/adapter.rb +30 -30
  22. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +4 -9
  23. data/lib/cucumber/platform.rb +2 -7
  24. data/lib/cucumber/rb_support/rb_language.rb +72 -26
  25. data/lib/cucumber/rb_support/rb_step_definition.rb +2 -2
  26. data/lib/cucumber/rb_support/rb_world.rb +6 -1
  27. data/lib/cucumber/rb_support/snippet.rb +21 -0
  28. data/lib/cucumber/running_test_case.rb +5 -1
  29. data/lib/cucumber/runtime.rb +11 -15
  30. data/lib/cucumber/runtime/support_code.rb +20 -128
  31. data/lib/cucumber/step_argument.rb +25 -0
  32. data/lib/cucumber/step_match.rb +6 -12
  33. data/lib/cucumber/step_match_search.rb +67 -0
  34. data/lib/cucumber/version +1 -0
  35. data/spec/cucumber/configuration_spec.rb +3 -2
  36. data/spec/cucumber/filters/activate_steps_spec.rb +95 -3
  37. data/spec/cucumber/formatter/html_spec.rb +1 -1
  38. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +55 -28
  39. data/spec/cucumber/formatter/pretty_spec.rb +2 -2
  40. data/spec/cucumber/formatter/spec_helper.rb +22 -12
  41. data/spec/cucumber/rb_support/rb_language_spec.rb +9 -45
  42. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +2 -2
  43. data/spec/cucumber/rb_support/rb_world_spec.rb +47 -0
  44. data/spec/cucumber/runtime/for_programming_languages_spec.rb +1 -1
  45. data/spec/cucumber/runtime/support_code_spec.rb +4 -111
  46. data/spec/cucumber/step_argument_spec.rb +18 -0
  47. data/spec/cucumber/step_match_search_spec.rb +122 -0
  48. data/spec/cucumber/step_match_spec.rb +8 -2
  49. data/spec/cucumber/world/pending_spec.rb +2 -1
  50. data/spec/cucumber_spec.rb +39 -0
  51. metadata +45 -50
  52. data/features/docs/wire_protocol/erb_configuration.feature +0 -56
  53. data/features/docs/wire_protocol/handle_unexpected_response.feature +0 -30
  54. data/features/docs/wire_protocol/invoke_message.feature +0 -216
  55. data/features/docs/wire_protocol/readme.md +0 -26
  56. data/features/docs/wire_protocol/snippets_message.feature +0 -51
  57. data/features/docs/wire_protocol/step_matches_message.feature +0 -81
  58. data/features/docs/wire_protocol/table_diffing.feature +0 -126
  59. data/features/docs/wire_protocol/tags.feature +0 -87
  60. data/features/docs/wire_protocol/timeouts.feature +0 -64
  61. data/lib/cucumber/events/bus.rb +0 -86
  62. data/lib/cucumber/gherkin/formatter/argument.rb +0 -17
  63. data/lib/cucumber/gherkin/formatter/hashable.rb +0 -27
  64. data/lib/cucumber/language_support.rb +0 -30
  65. data/lib/cucumber/language_support/language_methods.rb +0 -72
  66. data/lib/cucumber/rb_support/regexp_argument_matcher.rb +0 -21
  67. data/lib/cucumber/wire_support/configuration.rb +0 -38
  68. data/lib/cucumber/wire_support/connection.rb +0 -61
  69. data/lib/cucumber/wire_support/request_handler.rb +0 -32
  70. data/lib/cucumber/wire_support/wire_exception.rb +0 -32
  71. data/lib/cucumber/wire_support/wire_language.rb +0 -68
  72. data/lib/cucumber/wire_support/wire_packet.rb +0 -34
  73. data/lib/cucumber/wire_support/wire_protocol.rb +0 -43
  74. data/lib/cucumber/wire_support/wire_protocol/requests.rb +0 -133
  75. data/lib/cucumber/wire_support/wire_step_definition.rb +0 -21
  76. data/spec/cucumber/events/bus_spec.rb +0 -94
  77. data/spec/cucumber/rb_support/regexp_argument_matcher_spec.rb +0 -22
  78. data/spec/cucumber/wire_support/configuration_spec.rb +0 -64
  79. data/spec/cucumber/wire_support/connection_spec.rb +0 -64
  80. data/spec/cucumber/wire_support/wire_exception_spec.rb +0 -50
  81. data/spec/cucumber/wire_support/wire_language_spec.rb +0 -46
  82. data/spec/cucumber/wire_support/wire_packet_spec.rb +0 -44
@@ -1,21 +0,0 @@
1
- require 'cucumber/gherkin/formatter/argument'
2
-
3
- module Cucumber
4
- module RbSupport
5
- class RegexpArgumentMatcher
6
- def self.arguments_from(regexp, step_name)
7
- match = regexp.match(step_name)
8
- if match
9
- n = 0
10
- match.captures.map do |val|
11
- n += 1
12
- offset = match.offset(n)[0]
13
- Cucumber::Gherkin::Formatter::Argument.new(offset, val)
14
- end
15
- else
16
- nil
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,38 +0,0 @@
1
- require 'yaml'
2
- require 'erb'
3
-
4
- module Cucumber
5
- module WireSupport
6
- class Configuration
7
- attr_reader :host, :port, :unix
8
-
9
- def self.from_file(wire_file)
10
- settings = YAML.load(ERB.new(File.read(wire_file)).result)
11
- new(settings)
12
- end
13
-
14
- def initialize(args)
15
- @host = args['host']
16
- @port = args['port']
17
- @unix = args['unix'] if RUBY_PLATFORM !~ /mingw|mswin/
18
- @timeouts = DEFAULT_TIMEOUTS.merge(args['timeout'] || {})
19
- end
20
-
21
- def timeout(message = nil)
22
- return @timeouts[message.to_s] || 3
23
- end
24
-
25
- def to_s
26
- return @unix if @unix
27
- "#{@host}:#{@port}"
28
- end
29
-
30
- DEFAULT_TIMEOUTS = {
31
- 'connect' => 11,
32
- 'invoke' => 120,
33
- 'begin_scenario' => 120,
34
- 'end_scenario' => 120
35
- }
36
- end
37
- end
38
- end
@@ -1,61 +0,0 @@
1
- require 'timeout'
2
- require 'cucumber/wire_support/wire_protocol'
3
-
4
- module Cucumber
5
- module WireSupport
6
- class Connection
7
- class ConnectionError < StandardError; end
8
-
9
- include WireProtocol
10
-
11
- def initialize(config)
12
- @config = config
13
- end
14
-
15
- def call_remote(request_handler, message, params)
16
- packet = WirePacket.new(message, params)
17
-
18
- begin
19
- send_data_to_socket(packet.to_json)
20
- response = fetch_data_from_socket(@config.timeout(message))
21
- response.handle_with(request_handler)
22
- rescue Timeout::Error => e
23
- backtrace = e.backtrace ; backtrace.shift # because Timeout puts some wierd stuff in there
24
- raise Timeout::Error, "Timed out calling wire server with message '#{message}'", backtrace
25
- end
26
- end
27
-
28
- def exception(params)
29
- WireException.new(params, @config)
30
- end
31
-
32
- private
33
-
34
- def send_data_to_socket(data)
35
- Timeout.timeout(@config.timeout('connect')) { socket.puts(data) }
36
- end
37
-
38
- def fetch_data_from_socket(timeout)
39
- raw_response =
40
- if timeout == :never
41
- socket.gets
42
- else
43
- Timeout.timeout(timeout) { socket.gets }
44
- end
45
- raise exception({'message' => "Remote Socket with #{@config.host}:#{@config.port} closed."}) if raw_response.nil?
46
- WirePacket.parse(raw_response)
47
- end
48
-
49
- def socket
50
- return @socket if @socket
51
- if @config.unix
52
- @socket = UNIXSocket.new(@config.unix)
53
- else
54
- @socket = TCPSocket.new(@config.host, @config.port)
55
- end
56
- rescue Errno::ECONNREFUSED => exception
57
- raise(ConnectionError, "Unable to contact the wire server at #{@config}. Is it up?")
58
- end
59
- end
60
- end
61
- end
@@ -1,32 +0,0 @@
1
- module Cucumber
2
- module WireSupport
3
- class RequestHandler
4
- def initialize(connection)
5
- @connection = connection
6
- @message = underscore(self.class.name.split('::').last)
7
- end
8
-
9
- def execute(request_params = nil)
10
- @connection.call_remote(self, @message, request_params)
11
- end
12
-
13
- def handle_fail(params)
14
- raise @connection.exception(params)
15
- end
16
-
17
- def handle_success(params)
18
- end
19
-
20
- private
21
-
22
- # Props to Rails
23
- def underscore(camel_cased_word)
24
- camel_cased_word.to_s.gsub(/::/, '/').
25
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
26
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
27
- tr("-", "_").
28
- downcase
29
- end
30
- end
31
- end
32
- end
@@ -1,32 +0,0 @@
1
- module Cucumber
2
- module WireSupport
3
- # Proxy for an exception that occured at the remote end of the wire
4
- class WireException < StandardError
5
- module CanSetName
6
- attr_writer :exception_name
7
- def to_s
8
- @exception_name
9
- end
10
- end
11
-
12
- def initialize(args, config)
13
- super args['message']
14
- if args['exception']
15
- self.class.extend(CanSetName)
16
- self.class.exception_name = "#{args['exception']} from #{config}"
17
- end
18
- if args['backtrace']
19
- @backtrace = if args['backtrace'].is_a?(String)
20
- args['backtrace'].split("\n") # TODO: change cuke4nuke to pass an array instead of a big string
21
- else
22
- args['backtrace']
23
- end
24
- end
25
- end
26
-
27
- def backtrace
28
- @backtrace || super
29
- end
30
- end
31
- end
32
- end
@@ -1,68 +0,0 @@
1
- require 'multi_json'
2
- require 'socket'
3
- require 'cucumber/wire_support/connection'
4
- require 'cucumber/wire_support/configuration'
5
- require 'cucumber/wire_support/wire_packet'
6
- require 'cucumber/wire_support/wire_exception'
7
- require 'cucumber/wire_support/wire_step_definition'
8
-
9
- module Cucumber
10
- module WireSupport
11
-
12
- # The wire-protocol (language independent) implementation of the programming
13
- # language API.
14
- class WireLanguage
15
- include LanguageSupport::LanguageMethods
16
-
17
- def initialize(_=nil)
18
- @connections = []
19
- end
20
-
21
- def load_code_file(wire_file)
22
- config = Configuration.from_file(wire_file)
23
- @connections << Connection.new(config)
24
- end
25
-
26
- def snippet_text(code_keyword, step_name, multiline_arg, snippet_type)
27
- snippets = @connections.map do |remote|
28
- remote.snippet_text(code_keyword, step_name, MultilineArgClassName.new(multiline_arg).to_s)
29
- end
30
- snippets.flatten.join("\n")
31
- end
32
-
33
- def step_matches(step_name, formatted_step_name)
34
- @connections.map{ |c| c.step_matches(step_name, formatted_step_name)}.flatten
35
- end
36
-
37
- def begin_scenario(scenario)
38
- @connections.each { |c| c.begin_scenario(scenario) }
39
- @current_scenario = scenario
40
- end
41
-
42
- def end_scenario
43
- scenario = @current_scenario
44
- @connections.each { |c| c.end_scenario(scenario) }
45
- @current_scenario = nil
46
- end
47
-
48
- class MultilineArgClassName
49
- def initialize(arg)
50
- arg.describe_to(self)
51
- @result = ""
52
- end
53
-
54
- def data_table(*)
55
- @result = "Cucumber::MultilineArgument::DataTable"
56
- end
57
-
58
- def doc_string(*)
59
- @result = "Cucumber::MultilineArgument::DocString"
60
- end
61
-
62
- def to_s
63
- @result
64
- end
65
- end
66
- end
67
- end
68
- end
@@ -1,34 +0,0 @@
1
- require 'multi_json'
2
-
3
- module Cucumber
4
- module WireSupport
5
- # Represents the packet of data sent over the wire as JSON data, containing
6
- # a message and a hash of arguments
7
- class WirePacket
8
- class << self
9
- def parse(raw)
10
- attributes = MultiJson.load(raw.strip)
11
- message = attributes[0]
12
- params = attributes[1]
13
- new(message, params)
14
- end
15
- end
16
-
17
- attr_reader :message, :params
18
-
19
- def initialize(message, params = nil)
20
- @message, @params = message, params
21
- end
22
-
23
- def to_json
24
- packet = [@message]
25
- packet << @params if @params
26
- MultiJson.dump(packet)
27
- end
28
-
29
- def handle_with(handler)
30
- handler.send("handle_#{@message}", @params)
31
- end
32
- end
33
- end
34
- end
@@ -1,43 +0,0 @@
1
- require 'cucumber/wire_support/wire_protocol/requests'
2
-
3
- module Cucumber
4
- module WireSupport
5
- module WireProtocol
6
- def step_matches(name_to_match, name_to_report)
7
- handler = Requests::StepMatches.new(self)
8
- handler.execute(name_to_match, name_to_report)
9
- end
10
-
11
- def snippet_text(step_keyword, step_name, multiline_arg_class_name)
12
- handler = Requests::SnippetText.new(self)
13
- handler.execute(step_keyword, step_name, multiline_arg_class_name)
14
- end
15
-
16
- def invoke(step_definition_id, args)
17
- handler = Requests::Invoke.new(self)
18
- handler.execute(step_definition_id, args)
19
- end
20
-
21
- def diff_failed
22
- handler = Requests::DiffFailed.new(self)
23
- handler.execute
24
- end
25
-
26
- def diff_ok
27
- handler = Requests::DiffOk.new(self)
28
- handler.execute
29
- end
30
-
31
- def begin_scenario(scenario)
32
- handler = Requests::BeginScenario.new(self)
33
- handler.execute(scenario)
34
- end
35
-
36
- def end_scenario(scenario)
37
- handler = Requests::EndScenario.new(self)
38
- handler.execute(scenario)
39
- end
40
-
41
- end
42
- end
43
- end
@@ -1,133 +0,0 @@
1
- require 'cucumber/wire_support/request_handler'
2
- require 'cucumber/gherkin/formatter/argument'
3
-
4
- module Cucumber
5
- module WireSupport
6
- module WireProtocol
7
- module Requests
8
- class StepMatches < RequestHandler
9
- def execute(name_to_match, name_to_report)
10
- @name_to_match, @name_to_report = name_to_match, name_to_report
11
- request_params = {
12
- :name_to_match => name_to_match
13
- }
14
- super(request_params)
15
- end
16
-
17
- def handle_success(params)
18
- params.map do |raw_step_match|
19
- create_step_match(raw_step_match)
20
- end
21
- end
22
-
23
- alias :handle_step_matches :handle_success
24
-
25
- private
26
-
27
- def create_step_match(raw_step_match)
28
- step_definition = WireStepDefinition.new(@connection, raw_step_match)
29
- step_args = raw_step_match['args'].map do |raw_arg|
30
- Cucumber::Gherkin::Formatter::Argument.new(raw_arg['pos'], raw_arg['val'])
31
- end
32
- step_match(step_definition, step_args)
33
- end
34
-
35
- def step_match(step_definition, step_args)
36
- StepMatch.new(step_definition, @name_to_match, @name_to_report, step_args)
37
- end
38
- end
39
-
40
- class SnippetText < RequestHandler
41
- def execute(step_keyword, step_name, multiline_arg_class_name)
42
- request_params = {
43
- :step_keyword => step_keyword,
44
- :step_name => step_name,
45
- :multiline_arg_class => multiline_arg_class_name
46
- }
47
- super(request_params)
48
- end
49
-
50
- def handle_success(snippet_text)
51
- snippet_text
52
- end
53
-
54
- alias :handle_snippet_text :handle_success
55
- end
56
-
57
- class Invoke < RequestHandler
58
- def execute(step_definition_id, args)
59
- request_params = {
60
- :id => step_definition_id,
61
- :args => args
62
- }
63
- super(request_params)
64
- end
65
-
66
- def handle_pending(message)
67
- raise Pending, message || "TODO"
68
- end
69
-
70
- def handle_diff!(tables)
71
- # TODO: figure out if / how we could get a location for a table from the wire (or make a null location)
72
- location = Core::Ast::Location.new(__FILE__, __LINE__)
73
- table1 = table(tables[0], location)
74
- table2 = table(tables[1], location)
75
- table1.diff!(table2)
76
- end
77
-
78
- def handle_diff(tables)
79
- begin
80
- handle_diff!(tables)
81
- rescue Cucumber::MultilineArgument::DataTable::Different
82
- @connection.diff_failed
83
- end
84
- @connection.diff_ok
85
- end
86
-
87
- alias :handle_step_failed :handle_fail
88
-
89
- private
90
-
91
- def table(data, location)
92
- Cucumber::MultilineArgument.from_core(Core::Ast::DataTable.new(data, location))
93
- end
94
- end
95
-
96
- class DiffFailed < RequestHandler
97
- alias :handle_step_failed :handle_fail
98
- end
99
-
100
- class DiffOk < RequestHandler
101
- alias :handle_step_failed :handle_fail
102
- end
103
-
104
- module Tags
105
- def clean_tag_names(scenario)
106
- scenario.tags.map { |tag| tag.name.gsub(/^@/, '') }.sort
107
- end
108
-
109
- def request_params(scenario)
110
- return nil unless scenario.tags.any?
111
- { "tags" => clean_tag_names(scenario) }
112
- end
113
- end
114
-
115
- class BeginScenario < RequestHandler
116
- include Tags
117
-
118
- def execute(scenario)
119
- super(request_params(scenario))
120
- end
121
- end
122
-
123
- class EndScenario < RequestHandler
124
- include Tags
125
-
126
- def execute(scenario)
127
- super(request_params(scenario))
128
- end
129
- end
130
- end
131
- end
132
- end
133
- end