cucumber 3.1.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fef34be35b9337e5d78fe68a0b9e642e96a5bc8e
4
- data.tar.gz: 5331fac4008b678c3bdc18ec18f4df77e3e67bfb
2
+ SHA256:
3
+ metadata.gz: 6a9339e408c80955872fc7386ee99fc26b6519458369e06f0a65be76b27b6129
4
+ data.tar.gz: 10667fb8062a67fbf034a80a35a0d6ad53ca087bbe9cef9a9019d3343fddae94
5
5
  SHA512:
6
- metadata.gz: 560857486693d265017f21421942be4bc737f852d2972cd5a76c93f678ffe4ac06a0fd58e91f52b7ccb2d5c63156c2af13cb2e11e2bdaf9e194e516ddd663387
7
- data.tar.gz: e3ecdbb8d5a93e5e20d0e72a46be9ccb10021b12caa7d023cd3f16e845882331231764fb772cf7d1935c4db724166dbbe3eb40bbda33a4a84760ff7bd296e54a
6
+ metadata.gz: 4e9417b90d33b309f6a90845de1e66aeea91767146ca534b80f09989600ff50c1cc868f1c46696dccd48767d0cc78794df29cbe97cc227178db27c05bf510687
7
+ data.tar.gz: 2b2cdf34b49f79ec6bbb4d8b484d211c4afb82f0572baa75463b0bc8f9c614e02d1acb303fc623730b42a61e37343c1d882ffb817a1fd9eebdf7c59da7bf8813
@@ -10,6 +10,18 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
10
10
 
11
11
  ----
12
12
 
13
+ ## [3.2.0](https://github.com/cucumber/cucumber-ruby/compare/v3.1.2...v3.2.0) (2020-07-02)
14
+
15
+ ### Added
16
+
17
+ * `--out` option now supports URL:
18
+ * default method is `PUT`
19
+ * you can ussed cURL like options, for example: `--out "http://example.com -X POST -H Content-Type:text/json"` (Backport of [#1395](https://github.com/cucumber/cucumber-ruby/pull/1395) and [#1406](https://github.com/cucumber/cucumber-ruby/pull/1406))
20
+
21
+ ### Fixed
22
+
23
+ * JSON report: Do not fail when trying to embed bytes [#1388](https://github.com/cucumber/cucumber-ruby/issues/1388)
24
+
13
25
  ## [3.1.2](https://github.com/cucumber/cucumber-ruby/compare/v3.1.1...v3.1.2) (2018-07-13)
14
26
 
15
27
  ### Changed
@@ -109,7 +109,7 @@ module Cucumber
109
109
  add_option :formats, [*parse_formats(v), @out_stream]
110
110
  end
111
111
  opts.on('--init', *init_msg) { |v| initialize_project }
112
- opts.on('-o', '--out [FILE|DIR]', *out_msg) { |v| out_stream v }
112
+ opts.on('-o', '--out [FILE|DIR|URL]', *out_msg) { |v| out_stream v }
113
113
  opts.on('-t TAG_EXPRESSION', '--tags TAG_EXPRESSION', *tags_msg) { |v| add_tag v }
114
114
  opts.on('-n NAME', '--name NAME', *name_msg) { |v| add_option :name_regexps, /#{v}/ }
115
115
  opts.on('-e', '--exclude PATTERN', *exclude_msg) { |v| add_option :excludes, Regexp.new(v) }
@@ -305,10 +305,14 @@ TEXT
305
305
 
306
306
  def out_msg
307
307
  [
308
- 'Write output to a file/directory instead of STDOUT. This option',
308
+ 'Write output to a file/directory/URL instead of STDOUT. This option',
309
309
  'applies to the previously specified --format, or the',
310
310
  'default format if no format is specified. Check the specific',
311
- "formatter's docs to see whether to pass a file or a dir."
311
+ "formatter's docs to see whether to pass a file, dir or URL.",
312
+ "\n",
313
+ 'When using a URL, the output of the formatter will be sent as the HTTP request body.',
314
+ 'HTTP headers and request method can be set with cURL like options.',
315
+ 'Example: --out "http://example.com -X POST -H Content-Type:text/json"'
312
316
  ]
313
317
  end
314
318
 
@@ -0,0 +1,146 @@
1
+ require 'net/http'
2
+ require 'tempfile'
3
+
4
+ module Cucumber
5
+ module Formatter
6
+ class HTTPIO
7
+ class << self
8
+ # Returns an IO that will write to a HTTP request's body
9
+ def open(url, https_verify_mode = nil)
10
+ @https_verify_mode = https_verify_mode
11
+ uri, method, headers = CurlOptionParser.parse(url)
12
+ IOHTTPBuffer.new(uri, method, headers, https_verify_mode)
13
+ end
14
+ end
15
+ end
16
+
17
+ class CurlOptionParser
18
+ def self.parse(options)
19
+ chunks = options.split(/\s/).compact
20
+ http_method = 'PUT'
21
+ url = chunks[0]
22
+ headers = ''
23
+
24
+ last_flag = nil
25
+ chunks.each do |chunk|
26
+ if ['-X', '--request'].include?(chunk)
27
+ last_flag = '-X'
28
+ next
29
+ end
30
+
31
+ if chunk == '-H'
32
+ last_flag = '-H'
33
+ next
34
+ end
35
+
36
+ if last_flag == '-X'
37
+ http_method = chunk
38
+ last_flag = nil
39
+ end
40
+
41
+ headers += chunk if last_flag == '-H'
42
+ end
43
+
44
+ [
45
+ url,
46
+ http_method,
47
+ make_headers(headers)
48
+ ]
49
+ end
50
+
51
+ def self.make_headers(headers)
52
+ hash_headers = {}
53
+ str_scanner = /("(?<key>[^":]+)\s*:\s*(?<value>[^":]+)")|('(?<key1>[^':]+)\s*:\s*(?<value1>[^':]+)')/
54
+
55
+ headers.scan(str_scanner) do |header|
56
+ header = header.compact!
57
+ hash_headers[header[0]] = header[1] ? header[1].strip : header[1]
58
+ end
59
+
60
+ hash_headers
61
+ end
62
+ end
63
+
64
+ class IOHTTPBuffer
65
+ attr_reader :uri, :method, :headers
66
+
67
+ def initialize(uri, method, headers = {}, https_verify_mode = nil)
68
+ @uri = URI(uri)
69
+ @method = method
70
+ @headers = headers
71
+ @write_io = Tempfile.new('cucumber', encoding: 'UTF-8')
72
+ @https_verify_mode = https_verify_mode
73
+ end
74
+
75
+ def close
76
+ post_content(@uri, @method, @headers)
77
+ @write_io.close
78
+ end
79
+
80
+ def write(data)
81
+ @write_io.write(data)
82
+ end
83
+
84
+ def flush
85
+ @write_io.flush
86
+ end
87
+
88
+ def closed?
89
+ @write_io.closed?
90
+ end
91
+
92
+ private
93
+
94
+ def post_content(uri, method, headers, attempt = 10)
95
+ content = @write_io
96
+ http = build_client(uri, @https_verify_mode)
97
+
98
+ raise StandardError, "request to #{uri} failed (too many redirections)" if attempt <= 0
99
+ req = build_request(
100
+ uri,
101
+ method,
102
+ headers.merge(
103
+ 'Content-Length' => content.size.to_s
104
+ )
105
+ )
106
+
107
+ content.rewind
108
+ req.body_stream = content
109
+
110
+ begin
111
+ response = http.request(req)
112
+ rescue SystemCallError
113
+ # We may get the redirect response before pushing the file.
114
+ response = http.request(build_request(uri, method, headers))
115
+ end
116
+
117
+ case response
118
+ when Net::HTTPSuccess
119
+ response
120
+ when Net::HTTPRedirection
121
+ post_content(URI(response['Location']), method, headers, attempt - 1)
122
+ else
123
+ raise StandardError, "request to #{uri} failed with status #{response.code}"
124
+ end
125
+ end
126
+
127
+ def build_request(uri, method, headers)
128
+ method_class_name = "#{method[0].upcase}#{method[1..-1].downcase}"
129
+ req = Net::HTTP.const_get(method_class_name).new(uri)
130
+ headers.each do |header, value|
131
+ req[header] = value
132
+ end
133
+ req
134
+ end
135
+
136
+ def build_client(uri, https_verify_mode)
137
+ http = Net::HTTP.new(uri.hostname, uri.port)
138
+ if uri.scheme == 'https'
139
+ http.use_ssl = true
140
+ http.verify_mode = https_verify_mode if https_verify_mode
141
+ end
142
+ http
143
+ end
144
+ end
145
+ end
146
+ end
@@ -1,32 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'cucumber/formatter/http_io'
4
+
3
5
  module Cucumber
4
6
  module Formatter
5
7
  module Io
6
8
  module_function
7
9
 
8
- def ensure_io(path_or_io)
9
- return nil if path_or_io.nil?
10
- return path_or_io if path_or_io.respond_to?(:write)
11
- file = File.open(path_or_io, Cucumber.file_mode('w'))
10
+ def ensure_io(path_or_url_or_io)
11
+ return nil if path_or_url_or_io.nil?
12
+ return path_or_url_or_io if path_or_url_or_io.respond_to?(:write)
13
+ io = if path_or_url_or_io =~ %r{^https?://}
14
+ HTTPIO.open(path_or_url_or_io)
15
+ else
16
+ File.open(path_or_url_or_io, Cucumber.file_mode('w'))
17
+ end
12
18
  at_exit do
13
- unless file.closed?
14
- file.flush
15
- file.close
19
+ unless io.closed?
20
+ io.flush
21
+ io.close
16
22
  end
17
23
  end
18
- file
24
+ io
19
25
  end
20
26
 
21
27
  def ensure_file(path, name)
22
- raise "You *must* specify --out FILE for the #{name} formatter" unless String === path
28
+ raise "You *must* specify --out FILE for the #{name} formatter" unless String == path.class
23
29
  raise "I can't write #{name} to a directory - it has to be a file" if File.directory?(path)
24
- raise "I can't write #{name} to a file in the non-existing directory #{File.dirname(path)}" if !File.directory?(File.dirname(path))
30
+ raise "I can't write #{name} to a file in the non-existing directory #{File.dirname(path)}" unless File.directory?(File.dirname(path))
25
31
  ensure_io(path)
26
32
  end
27
33
 
28
34
  def ensure_dir(path, name)
29
- raise "You *must* specify --out DIR for the #{name} formatter" unless String === path
35
+ raise "You *must* specify --out DIR for the #{name} formatter" unless String == path.class
30
36
  raise "I can't write #{name} reports to a file - it has to be a directory" if File.file?(path)
31
37
  FileUtils.mkdir_p(path) unless File.directory?(path)
32
38
  File.absolute_path path
@@ -82,7 +82,13 @@ module Cucumber
82
82
  end
83
83
 
84
84
  def embed(src, mime_type, _label)
85
- if File.file?(src)
85
+ begin
86
+ is_file = File.file?(src)
87
+ rescue ArgumentError
88
+ is_file = false
89
+ end
90
+
91
+ if is_file
86
92
  content = File.open(src, 'rb', &:read)
87
93
  data = encode64(content)
88
94
  else
@@ -1 +1 @@
1
- 3.1.2
1
+ 3.2.0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.2
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aslak Hellesøy
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-07-13 00:00:00.000000000 Z
13
+ date: 2020-06-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: builder
@@ -345,7 +345,6 @@ files:
345
345
  - lib/cucumber/encoding.rb
346
346
  - lib/cucumber/errors.rb
347
347
  - lib/cucumber/events.rb
348
- - lib/cucumber/events/gherkin_source_parsed.rb~
349
348
  - lib/cucumber/events/gherkin_source_read.rb
350
349
  - lib/cucumber/events/step_activated.rb
351
350
  - lib/cucumber/events/step_definition_registered.rb
@@ -372,7 +371,6 @@ files:
372
371
  - lib/cucumber/filters/tag_limits/test_case_index.rb
373
372
  - lib/cucumber/filters/tag_limits/verifier.rb
374
373
  - lib/cucumber/formatter/ansicolor.rb
375
- - lib/cucumber/formatter/ast_lookup.rb~
376
374
  - lib/cucumber/formatter/backtrace_filter.rb
377
375
  - lib/cucumber/formatter/console.rb
378
376
  - lib/cucumber/formatter/console_counts.rb
@@ -386,6 +384,7 @@ files:
386
384
  - lib/cucumber/formatter/hook_query_visitor.rb
387
385
  - lib/cucumber/formatter/html.rb
388
386
  - lib/cucumber/formatter/html_builder.rb
387
+ - lib/cucumber/formatter/http_io.rb
389
388
  - lib/cucumber/formatter/ignore_missing_messages.rb
390
389
  - lib/cucumber/formatter/inline-js.js
391
390
  - lib/cucumber/formatter/interceptor.rb
@@ -467,9 +466,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
467
466
  - !ruby/object:Gem::Version
468
467
  version: '0'
469
468
  requirements: []
470
- rubyforge_project:
471
- rubygems_version: 2.5.2
469
+ rubygems_version: 3.0.6
472
470
  signing_key:
473
471
  specification_version: 4
474
- summary: cucumber-3.1.2
472
+ summary: cucumber-3.2.0
475
473
  test_files: []
@@ -1,14 +0,0 @@
1
- require 'cucumber/core/events'
2
-
3
- module Cucumber
4
- module Events
5
- # Fired after we've read in the contents of a feature file
6
- class GherkinSourceRead < Core::Event.new(:path, :body)
7
- # The path to the file
8
- attr_reader :path
9
-
10
- # The raw Gherkin source
11
- attr_reader :body
12
- end
13
- end
14
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Cucumber
4
- module Formatter
5
- module AstLookup
6
-
7
- end
8
- end
9
- end