httparty 0.20.0 → 0.22.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.
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ gemspec
3
3
 
4
4
  gem 'rake'
5
5
  gem 'mongrel', '1.2.0.pre2'
6
+ gem 'json'
6
7
 
7
8
  group :development do
8
9
  gem 'guard'
@@ -11,6 +12,7 @@ group :development do
11
12
  end
12
13
 
13
14
  group :test do
15
+ gem 'rexml'
14
16
  gem 'rspec', '~> 3.4'
15
17
  gem 'simplecov', require: false
16
18
  gem 'aruba'
data/Guardfile CHANGED
@@ -1,7 +1,8 @@
1
1
  rspec_options = {
2
- version: 1,
3
2
  all_after_pass: false,
4
- all_on_start: false
3
+ all_on_start: false,
4
+ failed_mode: :keep,
5
+ cmd: 'bundle exec rspec',
5
6
  }
6
7
 
7
8
  guard 'rspec', rspec_options do
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # httparty
2
2
 
3
- [![Build Status](https://travis-ci.org/jnunemaker/httparty.svg?branch=master)](https://travis-ci.org/jnunemaker/httparty)
3
+ [![CI](https://github.com/jnunemaker/httparty/actions/workflows/ci.yml/badge.svg)](https://github.com/jnunemaker/httparty/actions/workflows/ci.yml)
4
4
 
5
5
  Makes http fun again! Ain't no party like a httparty, because a httparty don't stop.
6
6
 
data/docs/README.md CHANGED
@@ -14,6 +14,20 @@ response = HTTParty.get('http://example.com', format: :plain)
14
14
  JSON.parse response, symbolize_names: true
15
15
  ```
16
16
 
17
+ ## Posting JSON
18
+ When using Content Type `application/json` with `POST`, `PUT` or `PATCH` requests, the body should be a string of valid JSON:
19
+
20
+ ```ruby
21
+ # With written JSON
22
+ HTTParty.post('http://example.com', body: "{\"foo\":\"bar\"}", headers: { 'Content-Type' => 'application/json' })
23
+
24
+ # Using JSON.generate
25
+ HTTParty.post('http://example.com', body: JSON.generate({ foo: 'bar' }), headers: { 'Content-Type' => 'application/json' })
26
+
27
+ # Using object.to_json
28
+ HTTParty.post('http://example.com', body: { foo: 'bar' }.to_json, headers: { 'Content-Type' => 'application/json' })
29
+ ```
30
+
17
31
  ## Working with SSL
18
32
 
19
33
  You can use this guide to work with SSL certificates.
@@ -123,11 +137,16 @@ If you explicitly set `Accept-Encoding`, there be dragons:
123
137
  `Net::HTTP` will automatically decompress it, and will omit `Content-Encoding`
124
138
  from your `HTTParty::Response` headers.
125
139
 
126
- * For encodings `br` (Brotli) or `compress` (LZW), HTTParty will automatically
127
- decompress if you include the `brotli` or `ruby-lzws` gems respectively into your project.
140
+ * For the following encodings, HTTParty will automatically decompress them if you include
141
+ the required gem into your project. Similar to above, if decompression succeeds,
142
+ `Content-Encoding` will be omitted from your `HTTParty::Response` headers.
128
143
  **Warning:** Support for these encodings is experimental and not fully battle-tested.
129
- Similar to above, if decompression succeeds, `Content-Encoding` will be omitted
130
- from your `HTTParty::Response` headers.
144
+
145
+ | Content-Encoding | Required Gem |
146
+ | --- | --- |
147
+ | `br` (Brotli) | [brotli](https://rubygems.org/gems/brotli) |
148
+ | `compress` (LZW) | [ruby-lzws](https://rubygems.org/gems/ruby-lzws) |
149
+ | `zstd` (Zstandard) | [zstd-ruby](https://rubygems.org/gems/zstd-ruby) |
131
150
 
132
151
  * For other encodings, `HTTParty::Response#body` will return the raw uncompressed byte string,
133
152
  and you'll need to inspect the `Content-Encoding` response header and decompress it yourself.
@@ -147,7 +166,8 @@ JSON.parse(res.body) # safe
147
166
 
148
167
  require 'brotli'
149
168
  require 'lzws'
150
- res = HTTParty.get('https://example.com/test.json', headers: { 'Accept-Encoding' => 'br,compress' })
169
+ require 'zstd-ruby'
170
+ res = HTTParty.get('https://example.com/test.json', headers: { 'Accept-Encoding' => 'br,compress,zstd' })
151
171
  JSON.parse(res.body)
152
172
 
153
173
 
data/httparty.gemspec CHANGED
@@ -13,10 +13,11 @@ Gem::Specification.new do |s|
13
13
  s.summary = 'Makes http fun! Also, makes consuming restful web services dead easy.'
14
14
  s.description = 'Makes http fun! Also, makes consuming restful web services dead easy.'
15
15
 
16
- s.required_ruby_version = '>= 2.3.0'
16
+ s.required_ruby_version = '>= 2.7.0'
17
17
 
18
+ s.add_dependency 'csv'
18
19
  s.add_dependency 'multi_xml', ">= 0.5.2"
19
- s.add_dependency('mime-types', "~> 3.0")
20
+ s.add_dependency 'mini_mime', ">= 1.0.0"
20
21
 
21
22
  # If this line is removed, all hard partying will cease.
22
23
  s.post_install_message = "When you HTTParty, you must party hard!"
@@ -119,10 +119,7 @@ module HTTParty
119
119
  if add_timeout?(options[:timeout])
120
120
  http.open_timeout = options[:timeout]
121
121
  http.read_timeout = options[:timeout]
122
-
123
- from_ruby_version('2.6.0', option: :write_timeout, warn: false) do
124
- http.write_timeout = options[:timeout]
125
- end
122
+ http.write_timeout = options[:timeout]
126
123
  end
127
124
 
128
125
  if add_timeout?(options[:read_timeout])
@@ -134,15 +131,11 @@ module HTTParty
134
131
  end
135
132
 
136
133
  if add_timeout?(options[:write_timeout])
137
- from_ruby_version('2.6.0', option: :write_timeout) do
138
- http.write_timeout = options[:write_timeout]
139
- end
134
+ http.write_timeout = options[:write_timeout]
140
135
  end
141
136
 
142
137
  if add_max_retries?(options[:max_retries])
143
- from_ruby_version('2.5.0', option: :max_retries) do
144
- http.max_retries = options[:max_retries]
145
- end
138
+ http.max_retries = options[:max_retries]
146
139
  end
147
140
 
148
141
  if options[:debug_output]
@@ -157,15 +150,11 @@ module HTTParty
157
150
  #
158
151
  # @see https://bugs.ruby-lang.org/issues/6617
159
152
  if options[:local_host]
160
- from_ruby_version('2.0.0', option: :local_host) do
161
- http.local_host = options[:local_host]
162
- end
153
+ http.local_host = options[:local_host]
163
154
  end
164
155
 
165
156
  if options[:local_port]
166
- from_ruby_version('2.0.0', option: :local_port) do
167
- http.local_port = options[:local_port]
168
- end
157
+ http.local_port = options[:local_port]
169
158
  end
170
159
 
171
160
  http
@@ -173,14 +162,6 @@ module HTTParty
173
162
 
174
163
  private
175
164
 
176
- def from_ruby_version(ruby_version, option: nil, warn: true)
177
- if RUBY_VERSION >= ruby_version
178
- yield
179
- elsif warn
180
- Kernel.warn("Warning: option #{ option } requires Ruby version #{ ruby_version } or later")
181
- end
182
- end
183
-
184
165
  def add_timeout?(timeout)
185
166
  timeout && (timeout.is_a?(Integer) || timeout.is_a?(Float))
186
167
  end
@@ -17,7 +17,8 @@ module HTTParty
17
17
  'none' => :none,
18
18
  'identity' => :none,
19
19
  'br' => :brotli,
20
- 'compress' => :lzw
20
+ 'compress' => :lzw,
21
+ 'zstd' => :zstd
21
22
  }.freeze
22
23
 
23
24
  # The response body of the request
@@ -88,5 +89,14 @@ module HTTParty
88
89
  nil
89
90
  end
90
91
  end
92
+
93
+ def zstd
94
+ return nil unless defined?(::Zstd)
95
+ begin
96
+ ::Zstd.decompress(body)
97
+ rescue StandardError
98
+ nil
99
+ end
100
+ end
91
101
  end
92
102
  end
@@ -22,7 +22,7 @@ module HTTParty
22
22
  log_request
23
23
  log_response
24
24
 
25
- logger.public_send level, messages.join('\n')
25
+ logger.public_send level, messages.join("\n")
26
26
  end
27
27
 
28
28
  private
@@ -24,6 +24,7 @@ module HTTParty
24
24
  attr_reader :request, :response
25
25
 
26
26
  def logstash_message
27
+ require 'json'
27
28
  {
28
29
  '@timestamp' => current_time,
29
30
  '@version' => 1,
@@ -29,7 +29,7 @@ module HTTParty
29
29
  @mattr_inheritable_attrs += args
30
30
 
31
31
  args.each do |arg|
32
- module_eval %(class << self; attr_accessor :#{arg} end)
32
+ singleton_class.attr_accessor(arg)
33
33
  end
34
34
 
35
35
  @mattr_inheritable_attrs
@@ -42,14 +42,12 @@ module HTTParty
42
42
  subclass.instance_variable_set(ivar, instance_variable_get(ivar).clone)
43
43
 
44
44
  if instance_variable_get(ivar).respond_to?(:merge)
45
- method = <<-EOM
45
+ subclass.class_eval <<~RUBY, __FILE__, __LINE__ + 1
46
46
  def self.#{inheritable_attribute}
47
47
  duplicate = ModuleInheritableAttributes.hash_deep_dup(#{ivar})
48
48
  #{ivar} = superclass.#{inheritable_attribute}.merge(duplicate)
49
49
  end
50
- EOM
51
-
52
- subclass.class_eval method
50
+ RUBY
53
51
  end
54
52
  end
55
53
  end
@@ -118,16 +118,19 @@ module HTTParty
118
118
  protected
119
119
 
120
120
  def xml
121
+ require 'multi_xml'
121
122
  MultiXml.parse(body)
122
123
  end
123
124
 
124
125
  UTF8_BOM = "\xEF\xBB\xBF"
125
126
 
126
127
  def json
128
+ require 'json'
127
129
  JSON.parse(body, :quirks_mode => true, :allow_nan => true)
128
130
  end
129
131
 
130
132
  def csv
133
+ require 'csv'
131
134
  CSV.parse(body)
132
135
  end
133
136
 
@@ -32,6 +32,13 @@ module HTTParty
32
32
 
33
33
  private
34
34
 
35
+ # https://html.spec.whatwg.org/#multipart-form-data
36
+ MULTIPART_FORM_DATA_REPLACEMENT_TABLE = {
37
+ '"' => '%22',
38
+ "\r" => '%0D',
39
+ "\n" => '%0A'
40
+ }.freeze
41
+
35
42
  def generate_multipart
36
43
  normalized_params = params.flat_map { |key, value| HashConversions.normalize_keys(key, value) }
37
44
 
@@ -40,7 +47,7 @@ module HTTParty
40
47
  memo << %(Content-Disposition: form-data; name="#{key}")
41
48
  # value.path is used to support ActionDispatch::Http::UploadedFile
42
49
  # https://github.com/jnunemaker/httparty/pull/585
43
- memo << %(; filename="#{file_name(value)}") if file?(value)
50
+ memo << %(; filename="#{file_name(value).gsub(/["\r\n]/, MULTIPART_FORM_DATA_REPLACEMENT_TABLE)}") if file?(value)
44
51
  memo << NEWLINE
45
52
  memo << "Content-Type: #{content_type(value)}#{NEWLINE}" if file?(value)
46
53
  memo << NEWLINE
@@ -84,8 +91,9 @@ module HTTParty
84
91
 
85
92
  def content_type(object)
86
93
  return object.content_type if object.respond_to?(:content_type)
87
- mime = MIME::Types.type_for(object.path)
88
- mime.empty? ? 'application/octet-stream' : mime[0].content_type
94
+ require 'mini_mime'
95
+ mime = MiniMime.lookup_by_filename(object.path)
96
+ mime ? mime.content_type : 'application/octet-stream'
89
97
  end
90
98
 
91
99
  def file_name(object)
@@ -47,8 +47,12 @@ module HTTParty
47
47
  end
48
48
 
49
49
  def self._load(data)
50
- http_method, path, options = Marshal.load(data)
51
- new(http_method, path, options)
50
+ http_method, path, options, last_response, last_uri, raw_request = Marshal.load(data)
51
+ instance = new(http_method, path, options)
52
+ instance.last_response = last_response
53
+ instance.last_uri = last_uri
54
+ instance.instance_variable_set("@raw_request", raw_request)
55
+ instance
52
56
  end
53
57
 
54
58
  attr_accessor :http_method, :options, :last_response, :redirect, :last_uri
@@ -184,7 +188,7 @@ module HTTParty
184
188
  opts = options.dup
185
189
  opts.delete(:logger)
186
190
  opts.delete(:parser) if opts[:parser] && opts[:parser].is_a?(Proc)
187
- Marshal.dump([http_method, path, opts])
191
+ Marshal.dump([http_method, path, opts, last_response, @last_uri, @raw_request])
188
192
  end
189
193
 
190
194
  private
@@ -291,24 +295,7 @@ module HTTParty
291
295
 
292
296
  def handle_response(raw_body, &block)
293
297
  if response_redirects?
294
- options[:limit] -= 1
295
- if options[:logger]
296
- logger = HTTParty::Logger.build(options[:logger], options[:log_level], options[:log_format])
297
- logger.format(self, last_response)
298
- end
299
- self.path = last_response['location']
300
- self.redirect = true
301
- if last_response.class == Net::HTTPSeeOther
302
- unless options[:maintain_method_across_redirects] && options[:resend_on_redirect]
303
- self.http_method = Net::HTTP::Get
304
- end
305
- elsif last_response.code != '307' && last_response.code != '308'
306
- unless options[:maintain_method_across_redirects]
307
- self.http_method = Net::HTTP::Get
308
- end
309
- end
310
- capture_cookies(last_response)
311
- perform(&block)
298
+ handle_redirection(&block)
312
299
  else
313
300
  raw_body ||= last_response.body
314
301
 
@@ -327,10 +314,34 @@ module HTTParty
327
314
  end
328
315
  end
329
316
 
317
+ def handle_redirection(&block)
318
+ options[:limit] -= 1
319
+ if options[:logger]
320
+ logger = HTTParty::Logger.build(options[:logger], options[:log_level], options[:log_format])
321
+ logger.format(self, last_response)
322
+ end
323
+ self.path = last_response['location']
324
+ self.redirect = true
325
+ if last_response.class == Net::HTTPSeeOther
326
+ unless options[:maintain_method_across_redirects] && options[:resend_on_redirect]
327
+ self.http_method = Net::HTTP::Get
328
+ end
329
+ elsif last_response.code != '307' && last_response.code != '308'
330
+ unless options[:maintain_method_across_redirects]
331
+ self.http_method = Net::HTTP::Get
332
+ end
333
+ end
334
+ if http_method == Net::HTTP::Get
335
+ clear_body
336
+ end
337
+ capture_cookies(last_response)
338
+ perform(&block)
339
+ end
340
+
330
341
  def handle_host_redirection
331
342
  check_duplicate_location_header
332
343
  redirect_path = options[:uri_adapter].parse(last_response['location']).normalize
333
- return if redirect_path.relative? || path.host == redirect_path.host
344
+ return if redirect_path.relative? || path.host == redirect_path.host || uri.host == redirect_path.host
334
345
  @changed_hosts = true
335
346
  end
336
347
 
@@ -358,6 +369,14 @@ module HTTParty
358
369
  parser.call(body, format)
359
370
  end
360
371
 
372
+ # Some Web Application Firewalls reject incoming GET requests that have a body
373
+ # if we redirect, and the resulting verb is GET then we will clear the body that
374
+ # may be left behind from the initiating request
375
+ def clear_body
376
+ options[:body] = nil
377
+ @raw_request.body = nil
378
+ end
379
+
361
380
  def capture_cookies(response)
362
381
  return unless response['Set-Cookie']
363
382
  cookies_hash = HTTParty::CookieHash.new
@@ -67,12 +67,12 @@ module HTTParty
67
67
  end
68
68
 
69
69
  # Support old multiple_choice? method from pre 2.0.0 era.
70
- if ::RUBY_VERSION >= '2.0.0' && ::RUBY_PLATFORM != 'java'
70
+ if ::RUBY_PLATFORM != 'java'
71
71
  alias_method :multiple_choice?, :multiple_choices?
72
72
  end
73
73
 
74
74
  # Support old status codes method from pre 2.6.0 era.
75
- if ::RUBY_VERSION >= '2.6.0' && ::RUBY_PLATFORM != 'java'
75
+ if ::RUBY_PLATFORM != 'java'
76
76
  alias_method :gateway_time_out?, :gateway_timeout?
77
77
  alias_method :request_entity_too_large?, :payload_too_large?
78
78
  alias_method :request_time_out?, :request_timeout?
@@ -133,7 +133,7 @@ module HTTParty
133
133
  end
134
134
 
135
135
  def throw_exception
136
- if @request.options[:raise_on] && @request.options[:raise_on].include?(code)
136
+ if @request.options[:raise_on].to_a.detect { |c| code.to_s.match(/#{c.to_s}/) }
137
137
  ::Kernel.raise ::HTTParty::ResponseError.new(@response), "Code #{code} - #{body}"
138
138
  end
139
139
  end
@@ -5,7 +5,7 @@ module HTTParty
5
5
  attr_reader :text, :content_type, :assume_utf16_is_big_endian
6
6
 
7
7
  def initialize(text, assume_utf16_is_big_endian: true, content_type: nil)
8
- @text = text.dup
8
+ @text = +text
9
9
  @content_type = content_type
10
10
  @assume_utf16_is_big_endian = assume_utf16_is_big_endian
11
11
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTParty
4
- VERSION = '0.20.0'
4
+ VERSION = '0.22.0'
5
5
  end
data/lib/httparty.rb CHANGED
@@ -2,13 +2,7 @@
2
2
 
3
3
  require 'pathname'
4
4
  require 'net/http'
5
- require 'net/https'
6
5
  require 'uri'
7
- require 'zlib'
8
- require 'multi_xml'
9
- require 'mime/types'
10
- require 'json'
11
- require 'csv'
12
6
 
13
7
  require 'httparty/module_inheritable_attributes'
14
8
  require 'httparty/cookie_hash'
@@ -84,7 +78,7 @@ module HTTParty
84
78
  #
85
79
  # class Foo
86
80
  # include HTTParty
87
- # raise_on [404, 500]
81
+ # raise_on [404, 500, '5[0-9]*']
88
82
  # end
89
83
  def raise_on(codes = [])
90
84
  default_options[:raise_on] = *codes
@@ -592,6 +586,13 @@ module HTTParty
592
586
  perform_request Net::HTTP::Unlock, path, options, &block
593
587
  end
594
588
 
589
+ def build_request(http_method, path, options = {})
590
+ options = ModuleInheritableAttributes.hash_deep_dup(default_options).merge(options)
591
+ HeadersProcessor.new(headers, options).call
592
+ process_cookies(options)
593
+ Request.new(http_method, path, options)
594
+ end
595
+
595
596
  attr_reader :default_options
596
597
 
597
598
  private
@@ -607,10 +608,7 @@ module HTTParty
607
608
  end
608
609
 
609
610
  def perform_request(http_method, path, options, &block) #:nodoc:
610
- options = ModuleInheritableAttributes.hash_deep_dup(default_options).merge(options)
611
- HeadersProcessor.new(headers, options).call
612
- process_cookies(options)
613
- Request.new(http_method, path, options).perform(&block)
611
+ build_request(http_method, path, options).perform(&block)
614
612
  end
615
613
 
616
614
  def process_cookies(options) #:nodoc:
@@ -677,6 +675,10 @@ module HTTParty
677
675
  def self.options(*args, &block)
678
676
  Basement.options(*args, &block)
679
677
  end
678
+
679
+ def self.build_request(*args, &block)
680
+ Basement.build_request(*args, &block)
681
+ end
680
682
  end
681
683
 
682
684
  require 'httparty/hash_conversions'
data/script/release CHANGED
@@ -18,9 +18,9 @@ gem_name=httparty
18
18
  rm -rf $gem_name-*.gem
19
19
  gem build -q $gem_name.gemspec
20
20
 
21
- # Make sure we're on the master branch.
22
- (git branch | grep -q '* master') || {
23
- echo "Only release from the master branch."
21
+ # Make sure we're on the main branch.
22
+ (git branch | grep -q '* main') || {
23
+ echo "Only release from the main branch."
24
24
  exit 1
25
25
  }
26
26
 
@@ -39,4 +39,4 @@ git fetch -t origin
39
39
 
40
40
  # Tag it and bag it.
41
41
  gem push $gem_name-*.gem && git tag "$tag" &&
42
- git push origin master && git push origin "$tag"
42
+ git push origin main && git push origin "$tag"
metadata CHANGED
@@ -1,16 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 0.22.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  - Sandro Turriate
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-09-29 00:00:00.000000000 Z
12
+ date: 2024-04-29 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: csv
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: multi_xml
16
30
  requirement: !ruby/object:Gem::Requirement
@@ -26,19 +40,19 @@ dependencies:
26
40
  - !ruby/object:Gem::Version
27
41
  version: 0.5.2
28
42
  - !ruby/object:Gem::Dependency
29
- name: mime-types
43
+ name: mini_mime
30
44
  requirement: !ruby/object:Gem::Requirement
31
45
  requirements:
32
- - - "~>"
46
+ - - ">="
33
47
  - !ruby/object:Gem::Version
34
- version: '3.0'
48
+ version: 1.0.0
35
49
  type: :runtime
36
50
  prerelease: false
37
51
  version_requirements: !ruby/object:Gem::Requirement
38
52
  requirements:
39
- - - "~>"
53
+ - - ">="
40
54
  - !ruby/object:Gem::Version
41
- version: '3.0'
55
+ version: 1.0.0
42
56
  description: Makes http fun! Also, makes consuming restful web services dead easy.
43
57
  email:
44
58
  - nunemaker@gmail.com
@@ -48,11 +62,11 @@ extensions: []
48
62
  extra_rdoc_files: []
49
63
  files:
50
64
  - ".editorconfig"
65
+ - ".github/dependabot.yml"
51
66
  - ".github/workflows/ci.yml"
52
67
  - ".gitignore"
53
68
  - ".rubocop.yml"
54
69
  - ".rubocop_todo.yml"
55
- - ".simplecov"
56
70
  - CONTRIBUTING.md
57
71
  - Changelog.md
58
72
  - Gemfile
@@ -124,15 +138,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
124
138
  requirements:
125
139
  - - ">="
126
140
  - !ruby/object:Gem::Version
127
- version: 2.3.0
141
+ version: 2.7.0
128
142
  required_rubygems_version: !ruby/object:Gem::Requirement
129
143
  requirements:
130
144
  - - ">="
131
145
  - !ruby/object:Gem::Version
132
146
  version: '0'
133
147
  requirements: []
134
- rubygems_version: 3.0.3
135
- signing_key:
148
+ rubygems_version: 3.3.7
149
+ signing_key:
136
150
  specification_version: 4
137
151
  summary: Makes http fun! Also, makes consuming restful web services dead easy.
138
152
  test_files: []
data/.simplecov DELETED
@@ -1 +0,0 @@
1
- SimpleCov.start "test_frameworks"