diff --git a/CHANGELOG.md b/CHANGELOG.md index fa624dff2c..b48d657876 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Next Release * [#1517](https://github.com/ruby-grape/grape/pull/1517), [#1089](https://github.com/ruby-grape/grape/pull/1089): Fix: priority of ANY routes - [@namusyaka](https://github.com/namusyaka), [@wagenet](https://github.com/wagenet). * [#1512](https://github.com/ruby-grape/grape/pull/1512): Fix: deeply nested parameters are included within `#declared(params)` - [@krbs](https://github.com/krbs). * [#1510](https://github.com/ruby-grape/grape/pull/1510): Fix: inconsistent validation for multiple parameters - [@dgasper](https://github.com/dgasper). +* [#1526](https://github.com/ruby-grape/grape/pull/1526): Remove warnings caused by instance variables not initialized - [@cpetschnig](https://github.com/cpetschnig). 0.18.0 (10/7/2016) ================== diff --git a/lib/grape/dsl/helpers.rb b/lib/grape/dsl/helpers.rb index 2c8f4ea5be..8a961f7302 100644 --- a/lib/grape/dsl/helpers.rb +++ b/lib/grape/dsl/helpers.rb @@ -77,6 +77,7 @@ def api_changed(new_api) protected def process_named_params + @named_params ||= nil return unless @named_params && @named_params.any? api.namespace_stackable(:named_params, @named_params) end diff --git a/lib/grape/dsl/inside_route.rb b/lib/grape/dsl/inside_route.rb index 22f13e017a..14e877e382 100644 --- a/lib/grape/dsl/inside_route.rb +++ b/lib/grape/dsl/inside_route.rb @@ -118,6 +118,7 @@ def redirect(url, permanent: false, body: nil, **_options) # # @param status [Integer] The HTTP Status Code to return for this request. def status(status = nil) + @status ||= nil case status when Symbol raise ArgumentError, "Status code :#{status} is invalid." unless Rack::Utils::SYMBOL_TO_STATUS_CODE.keys.include?(status) @@ -175,7 +176,7 @@ def body(value = nil) @body = '' status 204 else - @body + @body ||= nil end end @@ -195,7 +196,7 @@ def file(value = nil) warn '[DEPRECATION] Argument as FileStreamer-like object is deprecated. Use path to file instead.' @file = Grape::ServeFile::FileResponse.new(value) else - @file + @file ||= nil end end @@ -253,6 +254,7 @@ def present(*args) object end + @body ||= nil representation = { root => representation } if root if key representation = (@body || {}).merge(key => representation) diff --git a/lib/grape/dsl/parameters.rb b/lib/grape/dsl/parameters.rb index 3ef506c71f..7c66edd2a8 100644 --- a/lib/grape/dsl/parameters.rb +++ b/lib/grape/dsl/parameters.rb @@ -30,6 +30,7 @@ module Parameters # end # end def use(*names) + @api ||= nil named_params = @api.namespace_stackable_with_hash(:named_params) || {} options = names.extract_options! names.each do |name| @@ -97,6 +98,7 @@ def use(*names) def requires(*attrs, &block) orig_attrs = attrs.clone + @group ||= nil opts = attrs.extract_options!.clone opts[:presence] = { value: true, message: opts[:message] } opts = @group.merge(opts) if @group @@ -117,6 +119,7 @@ def requires(*attrs, &block) def optional(*attrs, &block) orig_attrs = attrs.clone + @group ||= nil opts = attrs.extract_options!.clone type = opts[:type] opts = @group.merge(opts) if @group @@ -209,6 +212,8 @@ def map_params(params, element) # @return hash of parameters relevant for the current scope # @api private def params(params) + @parent ||= nil + @element ||= nil params = @parent.params(params) if @parent params = map_params(params, @element) if @element params diff --git a/lib/grape/dsl/routing.rb b/lib/grape/dsl/routing.rb index 401da0800b..143afca656 100644 --- a/lib/grape/dsl/routing.rb +++ b/lib/grape/dsl/routing.rb @@ -49,6 +49,7 @@ def version(*args, &block) end end + @versions ||= nil @versions.last unless @versions.nil? end @@ -157,6 +158,7 @@ def route(methods, paths = ['/'], route_options = {}, &block) # end # end def namespace(space = nil, options = {}, &block) + @namespace_description ||= nil if space || block_given? within_namespace do previous_namespace_description = @namespace_description diff --git a/lib/grape/endpoint.rb b/lib/grape/endpoint.rb index 4c2b4234ec..1c349f4453 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -95,6 +95,8 @@ def initialize(new_settings, options = {}, &block) @options[:route_options] ||= {} @lazy_initialize_lock = Mutex.new + @lazy_initialized = nil + @block = nil return unless block_given? diff --git a/lib/grape/middleware/formatter.rb b/lib/grape/middleware/formatter.rb index ea5705e1f8..80a7b44f91 100644 --- a/lib/grape/middleware/formatter.rb +++ b/lib/grape/middleware/formatter.rb @@ -5,6 +5,11 @@ module Middleware class Formatter < Base CHUNKED = 'chunked'.freeze + def initialize(*_) + super + @app_response = nil + end + def default_options { default_format: :txt, diff --git a/lib/grape/validations/params_scope.rb b/lib/grape/validations/params_scope.rb index 779eea4dc1..558e72bc08 100644 --- a/lib/grape/validations/params_scope.rb +++ b/lib/grape/validations/params_scope.rb @@ -29,6 +29,7 @@ def initialize(opts, &block) @group = opts[:group] || {} @dependent_on = opts[:dependent_on] @declared_params = [] + @index = nil instance_eval(&block) if block_given? diff --git a/spec/grape/api_spec.rb b/spec/grape/api_spec.rb index 565dd16dd5..72b4beef22 100644 --- a/spec/grape/api_spec.rb +++ b/spec/grape/api_spec.rb @@ -1202,7 +1202,7 @@ class PhonyMiddleware def initialize(app, *args) @args = args @app = app - @block = true if block_given? + @block = block_given? ? true : nil end def call(env) diff --git a/spec/grape/middleware/formatter_spec.rb b/spec/grape/middleware/formatter_spec.rb index 5a1fd1120b..a094f5bf6a 100644 --- a/spec/grape/middleware/formatter_spec.rb +++ b/spec/grape/middleware/formatter_spec.rb @@ -4,46 +4,53 @@ subject { Grape::Middleware::Formatter.new(app) } before { allow(subject).to receive(:dup).and_return(subject) } - let(:app) { ->(_env) { [200, {}, [@body || { 'foo' => 'bar' }]] } } + let(:body) { { 'foo' => 'bar' } } + let(:app) { ->(_env) { [200, {}, [body]] } } context 'serialization' do + let(:body) { { 'abc' => 'def' } } it 'looks at the bodies for possibly serializable data' do - @body = { 'abc' => 'def' } _, _, 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(MultiJson.dump(body)) } end - it 'calls #to_json since default format is json' do - @body = ['foo'] - @body.instance_eval do - def to_json - '"bar"' + context 'default format' do + let(:body) { ['foo'] } + it 'calls #to_json since default format is json' do + body.instance_eval do + def to_json + '"bar"' + end end - end - subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('"bar"') } + subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('"bar"') } + end end - it 'calls #to_json if the content type is jsonapi' do - @body = { 'foos' => [{ 'bar' => 'baz' }] } - @body.instance_eval do - def to_json - '{"foos":[{"bar":"baz"}] }' + context 'jsonapi' do + let(:body) { { 'foos' => [{ 'bar' => 'baz' }] } } + it 'calls #to_json if the content type is jsonapi' do + body.instance_eval do + def to_json + '{"foos":[{"bar":"baz"}] }' + end end - end - subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/vnd.api+json').to_a.last.each { |b| expect(b).to eq('{"foos":[{"bar":"baz"}] }') } + subject.call('PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/vnd.api+json').to_a.last.each { |b| expect(b).to eq('{"foos":[{"bar":"baz"}] }') } + end end - it 'calls #to_xml if the content type is xml' do - @body = 'string' - @body.instance_eval do - def to_xml - '' + context 'xml' do + let(:body) { 'string' } + it 'calls #to_xml if the content type is xml' do + body.instance_eval do + def to_xml + '' + end end - end - subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('') } + subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json').to_a.last.each { |b| expect(b).to eq('') } + end end end @@ -189,10 +196,12 @@ def to_xml _, _, body = subject.call('PATH_INFO' => '/info.custom') expect(body.body).to eq(['CUSTOM FORMAT']) end - it 'uses default json formatter' do - @body = ['blah'] - _, _, body = subject.call('PATH_INFO' => '/info.json') - expect(body.body).to eq(['["blah"]']) + context 'default' do + let(:body) { ['blah'] } + it 'uses default json formatter' do + _, _, body = subject.call('PATH_INFO' => '/info.json') + expect(body.body).to eq(['["blah"]']) + end end it 'uses custom json formatter' do subject.options[:formatters][:json] = ->(_obj, _env) { 'CUSTOM JSON FORMAT' } @@ -284,10 +293,10 @@ def to_xml end context 'send file' do - let(:app) { ->(_env) { [200, {}, @body] } } + let(:body) { Grape::ServeFile::FileResponse.new('file') } + let(:app) { ->(_env) { [200, {}, body] } } it 'returns Grape::Uril::SendFileReponse' do - @body = Grape::ServeFile::FileResponse.new('file') env = { 'PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json' } expect(subject.call(env)).to be_a(Grape::ServeFile::SendfileResponse) end diff --git a/spec/grape/middleware/versioner/param_spec.rb b/spec/grape/middleware/versioner/param_spec.rb index 3d9934a7da..98bb0710a0 100644 --- a/spec/grape/middleware/versioner/param_spec.rb +++ b/spec/grape/middleware/versioner/param_spec.rb @@ -2,7 +2,8 @@ describe Grape::Middleware::Versioner::Param do let(:app) { ->(env) { [200, env, env['api.version']] } } - subject { Grape::Middleware::Versioner::Param.new(app, @options || {}) } + let(:options) { {} } + subject { Grape::Middleware::Versioner::Param.new(app, options) } it 'sets the API version based on the default param (apiver)' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v1' }) @@ -22,7 +23,7 @@ end context 'with specified parameter name' do - before { @options = { version_options: { parameter: 'v' } } } + let(:options) { { version_options: { parameter: 'v' } } } it 'sets the API version based on the custom parameter name' do env = Rack::MockRequest.env_for('/awesome', params: { 'v' => 'v1' }) expect(subject.call(env)[1]['api.version']).to eq('v1') @@ -34,7 +35,7 @@ end context 'with specified versions' do - before { @options = { versions: %w(v1 v2) } } + let(:options) { { versions: %w(v1 v2) } } it 'throws an error if a non-allowed version is specified' do env = Rack::MockRequest.env_for('/awesome', params: { 'apiver' => 'v3' }) expect(catch(:error) { subject.call(env) }[:status]).to eq(404) @@ -45,13 +46,17 @@ end end - it 'returns a 200 when no version is set (matches the first version found)' do - @options = { - versions: ['v1'], - version_options: { using: :header } - } - env = Rack::MockRequest.env_for('/awesome', params: {}) - expect(subject.call(env).first).to eq(200) + context 'when no version is set' do + let(:options) do + { + versions: ['v1'], + version_options: { using: :header } + } + end + it 'returns a 200 (matches the first version found)' do + env = Rack::MockRequest.env_for('/awesome', params: {}) + expect(subject.call(env).first).to eq(200) + end end context 'when there are multiple versions without a custom param' do diff --git a/spec/grape/middleware/versioner/path_spec.rb b/spec/grape/middleware/versioner/path_spec.rb index e92d92503f..cb3842427f 100644 --- a/spec/grape/middleware/versioner/path_spec.rb +++ b/spec/grape/middleware/versioner/path_spec.rb @@ -2,7 +2,8 @@ describe Grape::Middleware::Versioner::Path do let(:app) { ->(env) { [200, env, env['api.version']] } } - subject { Grape::Middleware::Versioner::Path.new(app, @options || {}) } + let(:options) { {} } + subject { Grape::Middleware::Versioner::Path.new(app, options) } it 'sets the API version based on the first path' do expect(subject.call('PATH_INFO' => '/v1/awesome').last).to eq('v1') @@ -17,7 +18,7 @@ end context 'with a pattern' do - before { @options = { pattern: /v./i } } + let(:options) { { pattern: /v./i } } it 'sets the version if it matches' do expect(subject.call('PATH_INFO' => '/v1/awesome').last).to eq('v1') end @@ -29,7 +30,7 @@ [%w(v1 v2), [:v1, :v2], [:v1, 'v2'], ['v1', :v2]].each do |versions| context "with specified versions as #{versions}" do - before { @options = { versions: versions } } + let(:options) { { versions: versions } } it 'throws an error if a non-allowed version is specified' do expect(catch(:error) { subject.call('PATH_INFO' => '/v3/awesome') }[:status]).to eq(404) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9f346cf08c..65a6534d74 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -18,5 +18,7 @@ config.include Rack::Test::Methods config.raise_errors_for_deprecations! + config.warnings = true + config.before(:each) { Grape::Util::InheritableSetting.reset_global! } end