diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 83021bf3dd..e0d6a1673b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,19 +1,19 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2017-06-12 13:25:24 -0600 using RuboCop version 0.47.0. +# on 2017-06-13 12:09:49 -0400 using RuboCop version 0.47.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 44 +# Offense count: 45 Metrics/AbcSize: Max: 44 -# Offense count: 277 +# Offense count: 278 # Configuration parameters: CountComments, ExcludedMethods. Metrics/BlockLength: - Max: 3104 + Max: 3117 # Offense count: 8 # Configuration parameters: CountComments. @@ -24,7 +24,7 @@ Metrics/ClassLength: Metrics/CyclomaticComplexity: Max: 14 -# Offense count: 1098 +# Offense count: 1108 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. # URISchemes: http, https Metrics/LineLength: diff --git a/.travis.yml b/.travis.yml index ca11c73be0..342dc0e3b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,16 @@ matrix: gemfile: gemfiles/rails_edge.gemfile - rvm: 2.4.1 gemfile: gemfiles/rails_5.gemfile + - rvm: 2.4.1 + gemfile: gemfiles/multi_json.gemfile + script: + - bundle exec rake + - bundle exec rspec spec/integration/multi_json + - rvm: 2.4.1 + gemfile: gemfiles/multi_xml.gemfile + script: + - bundle exec rake + - bundle exec rspec spec/integration/multi_xml - rvm: 2.3.4 gemfile: Gemfile - rvm: 2.3.4 diff --git a/Appraisals b/Appraisals index eb5efc247f..5ceb072bc0 100644 --- a/Appraisals +++ b/Appraisals @@ -22,3 +22,11 @@ end appraise 'rack-edge' do gem 'rack', github: 'rack/rack' end + +appraise 'multi_json' do + gem 'multi_json', require: 'multi_json' +end + +appraise 'multi_xml' do + gem 'multi_xml', require: 'multi_xml' +end diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c32b748c0..236b2fa5ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * [#1622](https://github.com/ruby-grape/grape/pull/1622): Add `except_values` validator to replace `except` option of `values` validator - [@jlfaber](https://github.com/jlfaber). * [#1635](https://github.com/ruby-grape/grape/pull/1635): Instrument validators with ActiveSupport::Notifications - [@ktimothy](https://github.com/ktimothy). * [#1646](https://github.com/ruby-grape/grape/pull/1646): Add ability to include an array of modules as helpers - [@pablonahuelgomez](https://github.com/pablonahuelgomez). +* [#1623](https://github.com/ruby-grape/grape/pull/1623): Removed `multi_json` and `multi_xml` dependencies - [@dblock](https://github.com/dblock). * Your contribution here. #### Fixes diff --git a/README.md b/README.md index a3cc7bfc41..3ecf5a7c17 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ - [CORS](#cors) - [Content-type](#content-type) - [API Data Formats](#api-data-formats) +- [JSON and XML Processors](#json-and-xml-processors) - [RESTful Model Representations](#restful-model-representations) - [Grape Entities](#grape-entities) - [Hypermedia and Roar](#hypermedia-and-roar) @@ -1146,7 +1147,7 @@ end ``` The `:values` option can also be supplied with a `Proc`, evaluated lazily with each request. -If the Proc has arity zero (i.e. it takes no arguments) it is expected to return either a list +If the Proc has arity zero (i.e. it takes no arguments) it is expected to return either a list or a range which will then be used to validate the parameter. For example, given a status model you may want to restrict by hashtags that you have @@ -2564,6 +2565,10 @@ curl -X PUT -d 'data' 'http://localhost:9292/value' -H Content-Type:text/custom You can disable parsing for a content-type with `nil`. For example, `parser :json, nil` will disable JSON parsing altogether. The request data is then available as-is in `env['api.request.body']`. +## JSON and XML Processors + +Grape uses `JSON` and `ActiveSupport::XmlMini` for JSON and XML parsing by default. It also detects and supports [multi_json](https://github.com/intridea/multi_json) and [multi_xml](https://github.com/sferik/multi_xml). Adding those gems to your Gemfile and requiring them will enable them and allow you to swap the JSON and XML back-ends. + ## RESTful Model Representations Grape supports a range of ways to present your data with some help from a generic `present` method, diff --git a/Rakefile b/Rakefile index f4e330c030..1df4278400 100644 --- a/Rakefile +++ b/Rakefile @@ -7,6 +7,7 @@ Bundler::GemHelper.install_tasks require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) do |spec| spec.pattern = 'spec/**/*_spec.rb' + spec.exclude_pattern = 'spec/integration/**/*_spec.rb' end RSpec::Core::RakeTask.new(:rcov) do |spec| diff --git a/UPGRADING.md b/UPGRADING.md index c26b9588d3..41cd80eb40 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -3,6 +3,16 @@ Upgrading Grape ### Upgrading to >= 1.0.0 +#### Changes in XML and JSON Parsers + +Grape no longer uses `multi_json` or `multi_xml` by default and uses `JSON` and `ActiveSupport::XmlMini` instead. This has no visible impact on JSON processing, but the default behavior of the XML parser has changed. For example, an XML POST containing `Bobby T.` was parsed as `Bobby T.` with `multi_xml`, and as now parsed as `{"__content__"=>"Bobby T."}` with `XmlMini`. + +If you were using `MultiJson.load`, `MultiJson.dump` or `MultiXml.parse`, you can substitute those with `Grape::Json.load`, `Grape::Json.dump`, `::Grape::Xml.parse`, or directly with `JSON.load`, `JSON.dump`, `XmlMini.parse`, etc. + +To restore previous behavior, add `multi_json` or `multi_xml` to your `Gemfile` and `require` it. + +See [#1623](https://github.com/ruby-grape/grape/pull/1623) for more information. + #### Changes in Parameter Class The default class for `params` has changed from `Hashie::Mash` to `ActiveSupport::HashWithIndifferentAccess` and the `hashie` dependency has been removed. This means that by default you can no longer access parameters by method name. diff --git a/gemfiles/multi_json.gemfile b/gemfiles/multi_json.gemfile new file mode 100644 index 0000000000..dc2a874e10 --- /dev/null +++ b/gemfiles/multi_json.gemfile @@ -0,0 +1,36 @@ +# This file was generated by Appraisal + +source 'https://rubygems.org' + +gem 'multi_json', require: 'multi_json' + +group :development, :test do + gem 'bundler' + gem 'rake' + gem 'rubocop', '0.47.0' + gem 'hashie' +end + +group :development do + gem 'guard' + gem 'guard-rspec' + gem 'guard-rubocop' + gem 'yard' + gem 'appraisal' + gem 'benchmark-ips' + gem 'redcarpet' +end + +group :test do + gem 'grape-entity', '~> 0.6' + gem 'maruku' + gem 'rack-test' + gem 'rspec', '~> 3.0' + gem 'cookiejar' + gem 'rack-jsonp', require: 'rack/jsonp' + gem 'mime-types' + gem 'ruby-grape-danger', '~> 0.1.0', require: false + gem 'coveralls', '~> 0.8.17', require: false +end + +gemspec path: '../' diff --git a/gemfiles/multi_xml.gemfile b/gemfiles/multi_xml.gemfile new file mode 100644 index 0000000000..af3b7eedfe --- /dev/null +++ b/gemfiles/multi_xml.gemfile @@ -0,0 +1,36 @@ +# This file was generated by Appraisal + +source 'https://rubygems.org' + +gem 'multi_xml', require: 'multi_xml' + +group :development, :test do + gem 'bundler' + gem 'rake' + gem 'rubocop', '0.47.0' + gem 'hashie' +end + +group :development do + gem 'guard' + gem 'guard-rspec' + gem 'guard-rubocop' + gem 'yard' + gem 'appraisal' + gem 'benchmark-ips' + gem 'redcarpet' +end + +group :test do + gem 'grape-entity', '~> 0.6' + gem 'maruku' + gem 'rack-test' + gem 'rspec', '~> 3.0' + gem 'cookiejar' + gem 'rack-jsonp', require: 'rack/jsonp' + gem 'mime-types' + gem 'ruby-grape-danger', '~> 0.1.0', require: false + gem 'coveralls', '~> 0.8.17', require: false +end + +gemspec path: '../' diff --git a/grape.gemspec b/grape.gemspec index 93e7777690..e2f43592a9 100644 --- a/grape.gemspec +++ b/grape.gemspec @@ -16,8 +16,6 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'mustermann-grape', '~> 1.0.0' s.add_runtime_dependency 'rack-accept' s.add_runtime_dependency 'activesupport' - s.add_runtime_dependency 'multi_json', '>= 1.3.2' - s.add_runtime_dependency 'multi_xml', '>= 0.5.2' s.add_runtime_dependency 'virtus', '>= 1.0.0' s.add_runtime_dependency 'builder' diff --git a/lib/grape.rb b/lib/grape.rb index 27a2e15280..d30ad3b530 100644 --- a/lib/grape.rb +++ b/lib/grape.rb @@ -16,8 +16,6 @@ require 'active_support/core_ext/hash/conversions' require 'active_support/dependencies/autoload' require 'active_support/notifications' -require 'multi_json' -require 'multi_xml' require 'i18n' require 'thread' @@ -44,6 +42,8 @@ module Grape autoload :Parser autoload :Request autoload :Env, 'grape/util/env' + autoload :Json, 'grape/util/json' + autoload :Xml, 'grape/util/xml' end module Http diff --git a/lib/grape/error_formatter/json.rb b/lib/grape/error_formatter/json.rb index 2885efd53d..e11210495c 100644 --- a/lib/grape/error_formatter/json.rb +++ b/lib/grape/error_formatter/json.rb @@ -10,7 +10,7 @@ def call(message, backtrace, options = {}, env = nil) if (options[:rescue_options] || {})[:backtrace] && backtrace && !backtrace.empty? result = result.merge(backtrace: backtrace) end - MultiJson.dump(result) + ::Grape::Json.dump(result) end private diff --git a/lib/grape/error_formatter/txt.rb b/lib/grape/error_formatter/txt.rb index 6813a5a98d..db8762f954 100644 --- a/lib/grape/error_formatter/txt.rb +++ b/lib/grape/error_formatter/txt.rb @@ -7,7 +7,7 @@ class << self def call(message, backtrace, options = {}, env = nil) message = present(message, env) - result = message.is_a?(Hash) ? MultiJson.dump(message) : message + result = message.is_a?(Hash) ? ::Grape::Json.dump(message) : message if (options[:rescue_options] || {})[:backtrace] && backtrace && !backtrace.empty? result += "\r\n " result += backtrace.join("\r\n ") diff --git a/lib/grape/formatter/json.rb b/lib/grape/formatter/json.rb index 353ee32e0c..5f96918b28 100644 --- a/lib/grape/formatter/json.rb +++ b/lib/grape/formatter/json.rb @@ -4,7 +4,7 @@ module Json class << self def call(object, _env) return object.to_json if object.respond_to?(:to_json) - MultiJson.dump(object) + ::Grape::Json.dump(object) end end end diff --git a/lib/grape/formatter/serializable_hash.rb b/lib/grape/formatter/serializable_hash.rb index 99cfb7b30e..c31fcebb0e 100644 --- a/lib/grape/formatter/serializable_hash.rb +++ b/lib/grape/formatter/serializable_hash.rb @@ -4,9 +4,9 @@ module SerializableHash class << self def call(object, _env) return object if object.is_a?(String) - return MultiJson.dump(serialize(object)) if serializable?(object) + return ::Grape::Json.dump(serialize(object)) if serializable?(object) return object.to_json if object.respond_to?(:to_json) - MultiJson.dump(object) + ::Grape::Json.dump(object) end private diff --git a/lib/grape/parser/json.rb b/lib/grape/parser/json.rb index 99c5ba0e94..89b50d3f2b 100644 --- a/lib/grape/parser/json.rb +++ b/lib/grape/parser/json.rb @@ -3,8 +3,8 @@ module Parser module Json class << self def call(object, _env) - MultiJson.load(object) - rescue MultiJson::ParseError + ::Grape::Json.load(object) + rescue ::Grape::Json::ParseError # handle JSON parsing errors via the rescue handlers or provide error message raise Grape::Exceptions::InvalidMessageBody, 'application/json' end diff --git a/lib/grape/parser/xml.rb b/lib/grape/parser/xml.rb index 5fa06f57e3..9fadf1c64f 100644 --- a/lib/grape/parser/xml.rb +++ b/lib/grape/parser/xml.rb @@ -3,8 +3,8 @@ module Parser module Xml class << self def call(object, _env) - MultiXml.parse(object) - rescue MultiXml::ParseError + ::Grape::Xml.parse(object) + rescue ::Grape::Xml::ParseError # handle XML parsing errors via the rescue handlers or provide error message raise Grape::Exceptions::InvalidMessageBody, 'application/xml' end diff --git a/lib/grape/util/json.rb b/lib/grape/util/json.rb new file mode 100644 index 0000000000..b0f5addb07 --- /dev/null +++ b/lib/grape/util/json.rb @@ -0,0 +1,8 @@ +module Grape + if Object.const_defined? :MultiJson + Json = ::MultiJson + else + Json = ::JSON + Json::ParseError = Json::ParserError + end +end diff --git a/lib/grape/util/xml.rb b/lib/grape/util/xml.rb new file mode 100644 index 0000000000..dd5d296e6b --- /dev/null +++ b/lib/grape/util/xml.rb @@ -0,0 +1,8 @@ +module Grape + if Object.const_defined? :MultiXml + Xml = ::MultiXml + else + Xml = ::ActiveSupport::XmlMini + Xml::ParseError = StandardError + end +end diff --git a/spec/grape/api/invalid_format_spec.rb b/spec/grape/api/invalid_format_spec.rb index 1d7ad8336b..5747694484 100644 --- a/spec/grape/api/invalid_format_spec.rb +++ b/spec/grape/api/invalid_format_spec.rb @@ -27,17 +27,17 @@ def app it 'no format' do get '/foo' expect(last_response.status).to eq 200 - expect(last_response.body).to eq(MultiJson.dump(id: 'foo', format: nil)) + expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: nil)) end it 'json format' do get '/foo.json' expect(last_response.status).to eq 200 - expect(last_response.body).to eq(MultiJson.dump(id: 'foo', format: 'json')) + expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: 'json')) end it 'invalid format' do get '/foo.invalid' expect(last_response.status).to eq 200 - expect(last_response.body).to eq(MultiJson.dump(id: 'foo', format: 'invalid')) + expect(last_response.body).to eq(::Grape::Json.dump(id: 'foo', format: 'invalid')) end end end diff --git a/spec/grape/api_spec.rb b/spec/grape/api_spec.rb index 8ed2ade68f..779893f8e2 100644 --- a/spec/grape/api_spec.rb +++ b/spec/grape/api_spec.rb @@ -1,6 +1,5 @@ require 'spec_helper' require 'shared/versioning_examples' -require 'grape-entity' describe Grape::API do subject { Class.new(Grape::API) } @@ -444,9 +443,9 @@ class DummyFormatClass subject.send(verb) do env['api.request.body'] end - send verb, '/', MultiJson.dump(object), 'CONTENT_TYPE' => 'application/json' + send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(verb == :post ? 201 : 200) - expect(last_response.body).to eql MultiJson.dump(object) + expect(last_response.body).to eql ::Grape::Json.dump(object) expect(last_request.params).to eql({}) end it 'stores input in api.request.input' do @@ -454,9 +453,9 @@ class DummyFormatClass subject.send(verb) do env['api.request.input'] end - send verb, '/', MultiJson.dump(object), 'CONTENT_TYPE' => 'application/json' + send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(verb == :post ? 201 : 200) - expect(last_response.body).to eql MultiJson.dump(object).to_json + expect(last_response.body).to eql ::Grape::Json.dump(object).to_json end context 'chunked transfer encoding' do it 'stores input in api.request.input' do @@ -464,9 +463,9 @@ class DummyFormatClass subject.send(verb) do env['api.request.input'] end - send verb, '/', MultiJson.dump(object), 'CONTENT_TYPE' => 'application/json', 'HTTP_TRANSFER_ENCODING' => 'chunked', 'CONTENT_LENGTH' => nil + send verb, '/', ::Grape::Json.dump(object), 'CONTENT_TYPE' => 'application/json', 'HTTP_TRANSFER_ENCODING' => 'chunked', 'CONTENT_LENGTH' => nil expect(last_response.status).to eq(verb == :post ? 201 : 200) - expect(last_response.body).to eql MultiJson.dump(object).to_json + expect(last_response.body).to eql ::Grape::Json.dump(object).to_json end end end @@ -2053,7 +2052,7 @@ def self.call(message, _backtrace, _option, _env) raise 'rain!' end get '/exception' - json = MultiJson.load(last_response.body) + json = ::Grape::Json.load(last_response.body) expect(json['error']).to eql 'rain!' expect(json['backtrace'].length).to be > 0 end @@ -2225,14 +2224,27 @@ def self.call(object, _env) expect(last_response.body).to eql 'elpmis' end end - context 'multi_xml' do - it "doesn't parse yaml" do - subject.put :yaml do - params[:tag] + if Object.const_defined? :MultiXml + context 'multi_xml' do + it "doesn't parse yaml" do + subject.put :yaml do + params[:tag] + end + put '/yaml', 'a123', 'CONTENT_TYPE' => 'application/xml' + expect(last_response.status).to eq(400) + expect(last_response.body).to eql 'Disallowed type attribute: "symbol"' + end + end + else + context 'default xml parser' do + it 'parses symbols' do + subject.put :yaml do + params[:tag] + end + put '/yaml', 'a123', 'CONTENT_TYPE' => 'application/xml' + expect(last_response.status).to eq(200) + expect(last_response.body).to eql '{"type"=>"symbol", "__content__"=>"a123"}' end - put '/yaml', 'a123', 'CONTENT_TYPE' => 'application/xml' - expect(last_response.status).to eq(400) - expect(last_response.body).to eql 'Disallowed type attribute: "symbol"' end end context 'none parser class' do @@ -3156,7 +3168,7 @@ def static end it 'path' do get '/endpoint/options' - options = MultiJson.load(last_response.body) + options = ::Grape::Json.load(last_response.body) expect(options['path']).to eq(['/endpoint/options']) expect(options['source_location'][0]).to include 'api_spec.rb' expect(options['source_location'][1].to_i).to be > 0 diff --git a/spec/grape/endpoint_spec.rb b/spec/grape/endpoint_spec.rb index 8d678b6a9f..ff06105388 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -470,7 +470,7 @@ def app '' end - post '/declared', MultiJson.dump(first: 'one', boolean: false), 'CONTENT_TYPE' => 'application/json' + post '/declared', ::Grape::Json.dump(first: 'one', boolean: false), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(201) end @@ -485,7 +485,7 @@ def app '' end - post '/declared', MultiJson.dump(first: 'one', second: nil), 'CONTENT_TYPE' => 'application/json' + post '/declared', ::Grape::Json.dump(first: 'one', second: nil), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(201) end @@ -873,7 +873,7 @@ def app end it 'converts JSON bodies to params' do - post '/request_body', MultiJson.dump(user: 'Bobby T.'), 'CONTENT_TYPE' => 'application/json' + post '/request_body', ::Grape::Json.dump(user: 'Bobby T.'), 'CONTENT_TYPE' => 'application/json' expect(last_response.body).to eq('Bobby T.') end @@ -882,14 +882,26 @@ def app expect(last_response.body).to eq('') end - it 'converts XML bodies to params' do - post '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' - expect(last_response.body).to eq('Bobby T.') - end + if Object.const_defined? :MultiXml + it 'converts XML bodies to params' do + post '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' + expect(last_response.body).to eq('Bobby T.') + end - it 'converts XML bodies to params' do - put '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' - expect(last_response.body).to eq('Bobby T.') + it 'converts XML bodies to params' do + put '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' + expect(last_response.body).to eq('Bobby T.') + end + else + it 'converts XML bodies to params' do + post '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' + expect(last_response.body).to eq('{"__content__"=>"Bobby T."}') + end + + it 'converts XML bodies to params' do + put '/request_body', 'Bobby T.', 'CONTENT_TYPE' => 'application/xml' + expect(last_response.body).to eq('{"__content__"=>"Bobby T."}') + end end it 'does not include parameters not defined by the body' do @@ -897,7 +909,7 @@ def app error! 400, 'expected nil' if params[:version] params[:user] end - post '/omitted_params', MultiJson.dump(user: 'Bob'), 'CONTENT_TYPE' => 'application/json' + post '/omitted_params', ::Grape::Json.dump(user: 'Bob'), 'CONTENT_TYPE' => 'application/json' expect(last_response.status).to eq(201) expect(last_response.body).to eq('Bob') end @@ -920,7 +932,7 @@ def app subject.put '/request_body' do params[:user] end - put '/request_body', MultiJson.dump(user: 'Bob'), 'CONTENT_TYPE' => 'text/plain' + put '/request_body', ::Grape::Json.dump(user: 'Bob'), 'CONTENT_TYPE' => 'text/plain' expect(last_response.status).to eq(406) expect(last_response.body).to eq('{"error":"The requested content-type \'text/plain\' is not supported."}') @@ -934,7 +946,7 @@ def app subject.post do params[:data] end - post '/', MultiJson.dump(data: { some: 'payload' }), 'CONTENT_TYPE' => 'application/json' + post '/', ::Grape::Json.dump(data: { some: 'payload' }), 'CONTENT_TYPE' => 'application/json' end it 'should not response with 406 for same type without params' do diff --git a/spec/grape/middleware/formatter_spec.rb b/spec/grape/middleware/formatter_spec.rb index a094f5bf6a..c90f6c1f9b 100644 --- a/spec/grape/middleware/formatter_spec.rb +++ b/spec/grape/middleware/formatter_spec.rb @@ -11,7 +11,7 @@ let(:body) { { 'abc' => 'def' } } it 'looks at the bodies for possibly serializable data' do _, _, bodies = *subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json') - bodies.each { |b| expect(b).to eq(MultiJson.dump(body)) } + bodies.each { |b| expect(b).to eq(::Grape::Json.dump(body)) } end context 'default format' do @@ -274,7 +274,11 @@ def to_xml 'rack.input' => io, 'CONTENT_LENGTH' => io.length ) - expect(subject.env['rack.request.form_hash']['thing']['name']).to eq('Test') + if Object.const_defined? :MultiXml + expect(subject.env['rack.request.form_hash']['thing']['name']).to eq('Test') + else + expect(subject.env['rack.request.form_hash']['thing']['name']['__content__']).to eq('Test') + end end [Rack::Request::FORM_DATA_MEDIA_TYPES, Rack::Request::PARSEABLE_DATA_MEDIA_TYPES].flatten.each do |content_type| it "ignores #{content_type}" do diff --git a/spec/integration/multi_json/json_spec.rb b/spec/integration/multi_json/json_spec.rb new file mode 100644 index 0000000000..11ae851322 --- /dev/null +++ b/spec/integration/multi_json/json_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe Grape::Json do + it 'uses multi_json' do + expect(Grape::Json).to eq(::MultiJson) + end +end diff --git a/spec/integration/multi_xml/xml_spec.rb b/spec/integration/multi_xml/xml_spec.rb new file mode 100644 index 0000000000..fce3c51ed8 --- /dev/null +++ b/spec/integration/multi_xml/xml_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe Grape::Xml do + it 'uses multi_xml' do + expect(Grape::Xml).to eq(::MultiXml) + end +end