cucumber 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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