diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c0e06ff..08b1de0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,9 +47,8 @@ have before they can be landed: place, but if you diverge from how things are done at the moment the patch won't get accepted as-is. -* Support Ruby 2.2 and higher. We maintain the same Ruby version - compatibility as Rack itself. We use [Travis CI test - runs](https://travis-ci.org/rack/rack-contrib) to validate this. +* Support Ruby 2.7 and higher. We maintain the same Ruby version + compatibility as Rack itself. * Require no external dependencies. Some existing middleware depends on additional gems in order to function; we feel that this is an diff --git a/Gemfile b/Gemfile index 4d37ed3..318b49e 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ source 'https://rubygems.org' gemspec gem 'i18n', '~> 0.6', '>= 0.6.8' -gem 'json', '~> 2.0' +gem 'json', '> 3.0' gem 'mime-types', '~> 3.0' gem 'minitest', '~> 5.6' gem 'minitest-hooks', '~> 1.0' diff --git a/lib/rack/contrib/json_body_parser.rb b/lib/rack/contrib/json_body_parser.rb index e98d9ad..db1a50b 100644 --- a/lib/rack/contrib/json_body_parser.rb +++ b/lib/rack/contrib/json_body_parser.rb @@ -40,7 +40,7 @@ class JSONBodyParser }.call(), }.freeze - DEFAULT_PARSER = ->(body) { JSON.parse(body, create_additions: false) } + DEFAULT_PARSER = ->(body) { JSON.parse(body) } def initialize( app, diff --git a/lib/rack/contrib/post_body_content_type_parser.rb b/lib/rack/contrib/post_body_content_type_parser.rb index 0ce71a9..a325b63 100644 --- a/lib/rack/contrib/post_body_content_type_parser.rb +++ b/lib/rack/contrib/post_body_content_type_parser.rb @@ -70,7 +70,7 @@ class PostBodyContentTypeParser def initialize(app, &block) warn "[DEPRECATION] `PostBodyContentTypeParser` is deprecated. Use `JSONBodyParser` as a drop-in replacement." @app = app - @block = block || Proc.new { |body| JSON.parse(body, :create_additions => false) } + @block = block || Proc.new { |body| JSON.parse(body) } end def call(env) diff --git a/rack-contrib.gemspec b/rack-contrib.gemspec index 94dc625..0bb7ffa 100644 --- a/rack-contrib.gemspec +++ b/rack-contrib.gemspec @@ -28,8 +28,9 @@ Gem::Specification.new do |s| s.extra_rdoc_files = %w[README.md COPYING] - s.required_ruby_version = '>= 2.2.2' + s.required_ruby_version = '>= 2.7.3' + s.add_runtime_dependency 'json', '> 3.0' s.add_runtime_dependency 'rack', '< 4' s.homepage = "https://github.com/rack/rack-contrib/" diff --git a/test/spec_rack_garbagecollector.rb b/test/spec_rack_garbagecollector.rb index 183f0f1..e239fe9 100644 --- a/test/spec_rack_garbagecollector.rb +++ b/test/spec_rack_garbagecollector.rb @@ -4,12 +4,19 @@ require 'rack/mock' require 'rack/contrib/garbagecollector' -describe 'Rack::GarbageCollector' do +describe Rack::GarbageCollector do + + def app + -> (env) { [200, {}, ['Hello World']] } + end + + def mock_env + headers = { 'REQUEST_METHOD' => 'POST' } + Rack::MockRequest.env_for '/', headers + end specify 'starts the garbage collector after each request' do - app = lambda { |env| - [200, {'Content-Type'=>'text/plain'}, ['Hello World']] } - Rack::Lint.new(Rack::GarbageCollector.new(app).call({})) + Rack::Lint.new(Rack::GarbageCollector.new(app)).call(mock_env) end end diff --git a/test/spec_rack_json_body_parser_spec.rb b/test/spec_rack_json_body_parser_spec.rb index d2930cc..e6a77fc 100644 --- a/test/spec_rack_json_body_parser_spec.rb +++ b/test/spec_rack_json_body_parser_spec.rb @@ -26,36 +26,36 @@ def create_parser(app, **args, &block) specify "should parse 'application/json' requests" do res = create_parser(app).call(mock_env) - _(res[2].to_enum.to_a.join).must_equal '{"key"=>"value"}' + _(res[2].to_enum.to_a.join).must_equal({"key"=>"value"}.inspect) end specify "should parse 'application/json; charset=utf-8' requests" do env = mock_env(type: 'application/json; charset=utf-8') res = create_parser(app).call(env) - _(res[2].to_enum.to_a.join).must_equal '{"key"=>"value"}' + _(res[2].to_enum.to_a.join).must_equal({"key"=>"value"}.inspect) end specify "should parse 'application/json' requests with an empty body" do res = create_parser(app).call(mock_env(input: '')) - _(res[2].to_enum.to_a.join).must_equal '{}' + _(res[2].to_enum.to_a.join).must_equal({}.inspect) end specify "shouldn't affect form-urlencoded requests" do env = mock_env(input: 'key=value', type: 'application/x-www-form-urlencoded') res = create_parser(app).call(env) - _(res[2].to_enum.to_a.join).must_equal '{"key"=>"value"}' + _(res[2].to_enum.to_a.join).must_equal({"key"=>"value"}.inspect) end specify "should not parse non-json media types" do env = mock_env(type: 'text/plain') res = create_parser(app).call(env) - _(res[2].to_enum.to_a.join).must_equal '{}' + _(res[2].to_enum.to_a.join).must_equal({}.inspect) end specify "shouldn't parse or error when CONTENT_TYPE is nil" do env = mock_env(type: nil) res = create_parser(app).call(env) - _(res[2].to_enum.to_a.join).must_equal %Q({"{\\"key\\": \\"value\\"}"=>nil}) + _(res[2].to_enum.to_a.join).must_equal({'{"key": "value"}' => nil}.inspect) end specify "should not rescue JSON:ParserError raised by the app" do @@ -91,7 +91,7 @@ class CustomParserError < StandardError; end { 'payload' => JSON.parse(body) } end res = parser.call(mock_env) - _(res[2].to_enum.to_a.join).must_equal '{"payload"=>{"key"=>"value"}}' + _(res[2].to_enum.to_a.join).must_equal({"payload"=>{"key"=>"value"}}.inspect) end specify "should accept an array of HTTP verbs to parse" do @@ -99,35 +99,35 @@ class CustomParserError < StandardError; end parser = create_parser(app, verbs: %w[GET]) res = parser.call(env) - _(res[2].to_enum.to_a.join).must_equal '{"key"=>"value"}' + _(res[2].to_enum.to_a.join).must_equal({"key"=>"value"}.inspect) res = parser.call(mock_env) - _(res[2].to_enum.to_a.join).must_equal '{}' + _(res[2].to_enum.to_a.join).must_equal({}.inspect) end specify "should accept an Array of media-types to parse" do parser = create_parser(app, media: ['application/json', 'text/plain']) env = mock_env(type: 'text/plain') res = parser.call(env) - _(res[2].to_enum.to_a.join).must_equal '{"key"=>"value"}' + _(res[2].to_enum.to_a.join).must_equal({"key"=>"value"}.inspect) html_env = mock_env(type: 'text/html') res = parser.call(html_env) - _(res[2].to_enum.to_a.join).must_equal '{}' + _(res[2].to_enum.to_a.join).must_equal({}.inspect) end specify "should accept a Regexp as a media-type matcher" do parser = create_parser(app, media: /json/) env = mock_env(type: 'weird/json.odd') res = parser.call(env) - _(res[2].to_enum.to_a.join).must_equal '{"key"=>"value"}' + _(res[2].to_enum.to_a.join).must_equal({"key"=>"value"}.inspect) end specify "should accept a String as a media-type matcher" do parser = create_parser(app, media: 'application/vnd.api+json') env = mock_env(type: 'application/vnd.api+json') res = parser.call(env) - _(res[2].to_enum.to_a.join).must_equal '{"key"=>"value"}' + _(res[2].to_enum.to_a.join).must_equal({"key"=>"value"}.inspect) end end end