grape 0.9.0 → 0.10.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.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -66
- data/.rubocop_todo.yml +78 -17
- data/.travis.yml +7 -3
- data/Appraisals +7 -0
- data/CHANGELOG.md +24 -0
- data/CONTRIBUTING.md +7 -0
- data/Gemfile +1 -7
- data/Guardfile +1 -1
- data/README.md +560 -94
- data/RELEASING.md +1 -1
- data/Rakefile +10 -11
- data/UPGRADING.md +211 -3
- data/gemfiles/rails_3.gemfile +14 -0
- data/gemfiles/rails_4.gemfile +14 -0
- data/grape.gemspec +10 -9
- data/lib/backports/active_support/deep_dup.rb +49 -0
- data/lib/backports/active_support/duplicable.rb +88 -0
- data/lib/grape.rb +29 -2
- data/lib/grape/api.rb +59 -65
- data/lib/grape/dsl/api.rb +19 -0
- data/lib/grape/dsl/callbacks.rb +6 -4
- data/lib/grape/dsl/configuration.rb +49 -5
- data/lib/grape/dsl/helpers.rb +7 -8
- data/lib/grape/dsl/inside_route.rb +22 -10
- data/lib/grape/dsl/middleware.rb +5 -5
- data/lib/grape/dsl/parameters.rb +6 -2
- data/lib/grape/dsl/request_response.rb +23 -20
- data/lib/grape/dsl/routing.rb +52 -49
- data/lib/grape/dsl/settings.rb +110 -0
- data/lib/grape/dsl/validations.rb +14 -6
- data/lib/grape/endpoint.rb +104 -88
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/incompatible_option_values.rb +1 -1
- data/lib/grape/exceptions/invalid_formatter.rb +1 -1
- data/lib/grape/exceptions/invalid_versioner_option.rb +1 -1
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +1 -1
- data/lib/grape/exceptions/missing_mime_type.rb +1 -1
- data/lib/grape/exceptions/missing_option.rb +1 -1
- data/lib/grape/exceptions/missing_vendor_option.rb +1 -1
- data/lib/grape/exceptions/unknown_options.rb +1 -1
- data/lib/grape/exceptions/unknown_validator.rb +1 -1
- data/lib/grape/exceptions/validation.rb +1 -1
- data/lib/grape/exceptions/validation_errors.rb +2 -2
- data/lib/grape/formatter/serializable_hash.rb +1 -1
- data/lib/grape/formatter/xml.rb +1 -1
- data/lib/grape/locale/en.yml +2 -0
- data/lib/grape/middleware/auth/dsl.rb +26 -21
- data/lib/grape/middleware/auth/strategies.rb +1 -1
- data/lib/grape/middleware/auth/strategy_info.rb +0 -2
- data/lib/grape/middleware/base.rb +2 -2
- data/lib/grape/middleware/error.rb +1 -1
- data/lib/grape/middleware/formatter.rb +5 -5
- data/lib/grape/middleware/versioner.rb +1 -1
- data/lib/grape/middleware/versioner/header.rb +3 -3
- data/lib/grape/middleware/versioner/param.rb +2 -2
- data/lib/grape/middleware/versioner/path.rb +1 -1
- data/lib/grape/namespace.rb +1 -1
- data/lib/grape/path.rb +9 -3
- data/lib/grape/util/content_types.rb +16 -8
- data/lib/grape/util/inheritable_setting.rb +74 -0
- data/lib/grape/util/inheritable_values.rb +51 -0
- data/lib/grape/util/stackable_values.rb +52 -0
- data/lib/grape/util/strict_hash_configuration.rb +106 -0
- data/lib/grape/validations.rb +0 -220
- data/lib/grape/validations/attributes_iterator.rb +21 -0
- data/lib/grape/validations/params_scope.rb +176 -0
- data/lib/grape/validations/validators/all_or_none.rb +20 -0
- data/lib/grape/validations/validators/allow_blank.rb +30 -0
- data/lib/grape/validations/validators/at_least_one_of.rb +20 -0
- data/lib/grape/validations/validators/base.rb +37 -0
- data/lib/grape/validations/{coerce.rb → validators/coerce.rb} +3 -3
- data/lib/grape/validations/{default.rb → validators/default.rb} +1 -1
- data/lib/grape/validations/validators/exactly_one_of.rb +20 -0
- data/lib/grape/validations/validators/multiple_params_base.rb +26 -0
- data/lib/grape/validations/validators/mutual_exclusion.rb +25 -0
- data/lib/grape/validations/{presence.rb → validators/presence.rb} +2 -2
- data/lib/grape/validations/validators/regexp.rb +12 -0
- data/lib/grape/validations/validators/values.rb +26 -0
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +522 -343
- data/spec/grape/dsl/callbacks_spec.rb +4 -4
- data/spec/grape/dsl/configuration_spec.rb +48 -9
- data/spec/grape/dsl/helpers_spec.rb +6 -13
- data/spec/grape/dsl/inside_route_spec.rb +43 -4
- data/spec/grape/dsl/middleware_spec.rb +1 -10
- data/spec/grape/dsl/parameters_spec.rb +8 -1
- data/spec/grape/dsl/request_response_spec.rb +16 -22
- data/spec/grape/dsl/routing_spec.rb +21 -5
- data/spec/grape/dsl/settings_spec.rb +219 -0
- data/spec/grape/dsl/validations_spec.rb +8 -11
- data/spec/grape/endpoint_spec.rb +115 -86
- data/spec/grape/entity_spec.rb +33 -33
- data/spec/grape/exceptions/invalid_formatter_spec.rb +3 -5
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +4 -6
- data/spec/grape/exceptions/missing_mime_type_spec.rb +5 -6
- data/spec/grape/exceptions/missing_option_spec.rb +3 -5
- data/spec/grape/exceptions/unknown_options_spec.rb +3 -5
- data/spec/grape/exceptions/unknown_validator_spec.rb +3 -5
- data/spec/grape/exceptions/validation_errors_spec.rb +5 -5
- data/spec/grape/loading_spec.rb +44 -0
- data/spec/grape/middleware/auth/base_spec.rb +0 -4
- data/spec/grape/middleware/auth/dsl_spec.rb +2 -4
- data/spec/grape/middleware/auth/strategies_spec.rb +5 -6
- data/spec/grape/middleware/exception_spec.rb +8 -10
- data/spec/grape/middleware/formatter_spec.rb +13 -15
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +10 -10
- data/spec/grape/middleware/versioner/header_spec.rb +25 -25
- data/spec/grape/middleware/versioner/param_spec.rb +15 -17
- data/spec/grape/middleware/versioner/path_spec.rb +1 -2
- data/spec/grape/middleware/versioner_spec.rb +0 -1
- data/spec/grape/path_spec.rb +66 -45
- data/spec/grape/util/inheritable_setting_spec.rb +217 -0
- data/spec/grape/util/inheritable_values_spec.rb +63 -0
- data/spec/grape/util/stackable_values_spec.rb +115 -0
- data/spec/grape/util/strict_hash_configuration_spec.rb +38 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +4 -0
- data/spec/grape/validations/params_scope_spec.rb +57 -0
- data/spec/grape/validations/validators/all_or_none_spec.rb +60 -0
- data/spec/grape/validations/validators/allow_blank_spec.rb +170 -0
- data/spec/grape/validations/{at_least_one_of_spec.rb → validators/at_least_one_of_spec.rb} +7 -3
- data/spec/grape/validations/{coerce_spec.rb → validators/coerce_spec.rb} +8 -11
- data/spec/grape/validations/{default_spec.rb → validators/default_spec.rb} +7 -9
- data/spec/grape/validations/{exactly_one_of_spec.rb → validators/exactly_one_of_spec.rb} +15 -11
- data/spec/grape/validations/{mutual_exclusion_spec.rb → validators/mutual_exclusion_spec.rb} +11 -9
- data/spec/grape/validations/{presence_spec.rb → validators/presence_spec.rb} +30 -30
- data/spec/grape/validations/{regexp_spec.rb → validators/regexp_spec.rb} +2 -4
- data/spec/grape/validations/{values_spec.rb → validators/values_spec.rb} +95 -23
- data/spec/grape/validations/{zh-CN.yml → validators/zh-CN.yml} +0 -0
- data/spec/grape/validations_spec.rb +335 -70
- data/spec/shared/versioning_examples.rb +7 -8
- data/spec/spec_helper.rb +2 -0
- data/spec/support/basic_auth_encode_helpers.rb +1 -1
- data/spec/support/content_type_helpers.rb +1 -1
- data/spec/support/versioned_helpers.rb +3 -3
- metadata +80 -33
- data/lib/grape/util/deep_merge.rb +0 -23
- data/lib/grape/util/hash_stack.rb +0 -120
- data/lib/grape/validations/at_least_one_of.rb +0 -25
- data/lib/grape/validations/exactly_one_of.rb +0 -26
- data/lib/grape/validations/mutual_exclusion.rb +0 -25
- data/lib/grape/validations/regexp.rb +0 -12
- data/lib/grape/validations/values.rb +0 -23
- data/spec/grape/util/hash_stack_spec.rb +0 -132
| @@ -0,0 +1,219 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Grape
         | 
| 4 | 
            +
              module DSL
         | 
| 5 | 
            +
                module SettingsSpec
         | 
| 6 | 
            +
                  class Dummy
         | 
| 7 | 
            +
                    include Grape::DSL::Settings
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def reset_validations!; end
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                describe Settings do
         | 
| 14 | 
            +
                  subject { SettingsSpec::Dummy.new }
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  describe '#unset' do
         | 
| 17 | 
            +
                    it 'deletes a key from settings' do
         | 
| 18 | 
            +
                      subject.namespace_setting :dummy, 1
         | 
| 19 | 
            +
                      expect(subject.inheritable_setting.namespace.keys).to include(:dummy)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                      subject.unset :namespace, :dummy
         | 
| 22 | 
            +
                      expect(subject.inheritable_setting.namespace.keys).not_to include(:dummy)
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  describe '#get_or_set' do
         | 
| 27 | 
            +
                    it 'sets a values' do
         | 
| 28 | 
            +
                      subject.get_or_set :namespace, :dummy, 1
         | 
| 29 | 
            +
                      expect(subject.namespace_setting(:dummy)).to eq 1
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    it 'returns a value when nil is new value is provided' do
         | 
| 33 | 
            +
                      subject.get_or_set :namespace, :dummy, 1
         | 
| 34 | 
            +
                      expect(subject.get_or_set(:namespace, :dummy, nil)).to eq 1
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  describe '#global_setting' do
         | 
| 39 | 
            +
                    it 'delegates to get_or_set' do
         | 
| 40 | 
            +
                      expect(subject).to receive(:get_or_set).with(:global, :dummy, 1)
         | 
| 41 | 
            +
                      subject.global_setting(:dummy, 1)
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  describe '#route_setting' do
         | 
| 46 | 
            +
                    it 'delegates to get_or_set' do
         | 
| 47 | 
            +
                      expect(subject).to receive(:get_or_set).with(:route, :dummy, 1)
         | 
| 48 | 
            +
                      subject.route_setting(:dummy, 1)
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    it 'sets a value until the next route' do
         | 
| 52 | 
            +
                      subject.route_setting :some_thing, :foo_bar
         | 
| 53 | 
            +
                      expect(subject.route_setting(:some_thing)).to eq :foo_bar
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                      subject.route_end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                      expect(subject.route_setting(:some_thing)).to be_nil
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  describe '#namespace_setting' do
         | 
| 62 | 
            +
                    it 'delegates to get_or_set' do
         | 
| 63 | 
            +
                      expect(subject).to receive(:get_or_set).with(:namespace, :dummy, 1)
         | 
| 64 | 
            +
                      subject.namespace_setting(:dummy, 1)
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    it 'sets a value until the end of a namespace' do
         | 
| 68 | 
            +
                      subject.namespace_start
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                      subject.namespace_setting :some_thing, :foo_bar
         | 
| 71 | 
            +
                      expect(subject.namespace_setting(:some_thing)).to eq :foo_bar
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                      subject.namespace_end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                      expect(subject.namespace_setting(:some_thing)).to be_nil
         | 
| 76 | 
            +
                    end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                    it 'resets values after leaving nested namespaces' do
         | 
| 79 | 
            +
                      subject.namespace_start
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                      subject.namespace_setting :some_thing, :foo_bar
         | 
| 82 | 
            +
                      expect(subject.namespace_setting(:some_thing)).to eq :foo_bar
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                      subject.namespace_start
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                      expect(subject.namespace_setting(:some_thing)).to be_nil
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                      subject.namespace_end
         | 
| 89 | 
            +
                      expect(subject.namespace_setting(:some_thing)).to eq :foo_bar
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                      subject.namespace_end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                      expect(subject.namespace_setting(:some_thing)).to be_nil
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  describe '#namespace_inheritable' do
         | 
| 98 | 
            +
                    it 'delegates to get_or_set' do
         | 
| 99 | 
            +
                      expect(subject).to receive(:get_or_set).with(:namespace_inheritable, :dummy, 1)
         | 
| 100 | 
            +
                      subject.namespace_inheritable(:dummy, 1)
         | 
| 101 | 
            +
                    end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                    it 'inherits values from surrounding namespace' do
         | 
| 104 | 
            +
                      subject.namespace_start
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                      subject.namespace_inheritable(:some_thing, :foo_bar)
         | 
| 107 | 
            +
                      expect(subject.namespace_inheritable(:some_thing)).to eq :foo_bar
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                      subject.namespace_start
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                      expect(subject.namespace_inheritable(:some_thing)).to eq :foo_bar
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                      subject.namespace_inheritable(:some_thing, :foo_bar_2)
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                      expect(subject.namespace_inheritable(:some_thing)).to eq :foo_bar_2
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                      subject.namespace_end
         | 
| 118 | 
            +
                      expect(subject.namespace_inheritable(:some_thing)).to eq :foo_bar
         | 
| 119 | 
            +
                      subject.namespace_end
         | 
| 120 | 
            +
                    end
         | 
| 121 | 
            +
                  end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                  describe '#namespace_stackable' do
         | 
| 124 | 
            +
                    it 'delegates to get_or_set' do
         | 
| 125 | 
            +
                      expect(subject).to receive(:get_or_set).with(:namespace_stackable, :dummy, 1)
         | 
| 126 | 
            +
                      subject.namespace_stackable(:dummy, 1)
         | 
| 127 | 
            +
                    end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                    it 'stacks values from surrounding namespace' do
         | 
| 130 | 
            +
                      subject.namespace_start
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                      subject.namespace_stackable(:some_thing, :foo_bar)
         | 
| 133 | 
            +
                      expect(subject.namespace_stackable(:some_thing)).to eq [:foo_bar]
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                      subject.namespace_start
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                      expect(subject.namespace_stackable(:some_thing)).to eq [:foo_bar]
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                      subject.namespace_stackable(:some_thing, :foo_bar_2)
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                      expect(subject.namespace_stackable(:some_thing)).to eq [:foo_bar, :foo_bar_2]
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                      subject.namespace_end
         | 
| 144 | 
            +
                      expect(subject.namespace_stackable(:some_thing)).to eq [:foo_bar]
         | 
| 145 | 
            +
                      subject.namespace_end
         | 
| 146 | 
            +
                    end
         | 
| 147 | 
            +
                  end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                  describe '#api_class_setting' do
         | 
| 150 | 
            +
                    it 'delegates to get_or_set' do
         | 
| 151 | 
            +
                      expect(subject).to receive(:get_or_set).with(:api_class, :dummy, 1)
         | 
| 152 | 
            +
                      subject.api_class_setting(:dummy, 1)
         | 
| 153 | 
            +
                    end
         | 
| 154 | 
            +
                  end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                  describe '#within_namespace' do
         | 
| 157 | 
            +
                    it 'calls start and end for a namespace' do
         | 
| 158 | 
            +
                      expect(subject).to receive :namespace_start
         | 
| 159 | 
            +
                      expect(subject).to receive :namespace_end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                      subject.within_namespace do
         | 
| 162 | 
            +
                      end
         | 
| 163 | 
            +
                    end
         | 
| 164 | 
            +
             | 
| 165 | 
            +
                    it 'returns the last result' do
         | 
| 166 | 
            +
                      result = subject.within_namespace do
         | 
| 167 | 
            +
                        1
         | 
| 168 | 
            +
                      end
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                      expect(result).to eq 1
         | 
| 171 | 
            +
                    end
         | 
| 172 | 
            +
                  end
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                  describe 'complex scenario' do
         | 
| 175 | 
            +
                    it 'plays well' do
         | 
| 176 | 
            +
                      obj1 = SettingsSpec::Dummy.new
         | 
| 177 | 
            +
                      obj2 = SettingsSpec::Dummy.new
         | 
| 178 | 
            +
                      obj3 = SettingsSpec::Dummy.new
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                      obj1_copy = nil
         | 
| 181 | 
            +
                      obj2_copy = nil
         | 
| 182 | 
            +
                      obj3_copy = nil
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                      obj1.within_namespace do
         | 
| 185 | 
            +
                        obj1.namespace_stackable(:some_thing, :obj1)
         | 
| 186 | 
            +
                        expect(obj1.namespace_stackable(:some_thing)).to eq [:obj1]
         | 
| 187 | 
            +
                        obj1_copy = obj1.inheritable_setting.point_in_time_copy
         | 
| 188 | 
            +
                      end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                      expect(obj1.namespace_stackable(:some_thing)).to eq []
         | 
| 191 | 
            +
                      expect(obj1_copy.namespace_stackable[:some_thing]).to eq [:obj1]
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                      obj2.within_namespace do
         | 
| 194 | 
            +
                        obj2.namespace_stackable(:some_thing, :obj2)
         | 
| 195 | 
            +
                        expect(obj2.namespace_stackable(:some_thing)).to eq [:obj2]
         | 
| 196 | 
            +
                        obj2_copy = obj2.inheritable_setting.point_in_time_copy
         | 
| 197 | 
            +
                      end
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                      expect(obj2.namespace_stackable(:some_thing)).to eq []
         | 
| 200 | 
            +
                      expect(obj2_copy.namespace_stackable[:some_thing]).to eq [:obj2]
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                      obj3.within_namespace do
         | 
| 203 | 
            +
                        obj3.namespace_stackable(:some_thing, :obj3)
         | 
| 204 | 
            +
                        expect(obj3.namespace_stackable(:some_thing)).to eq [:obj3]
         | 
| 205 | 
            +
                        obj3_copy = obj3.inheritable_setting.point_in_time_copy
         | 
| 206 | 
            +
                      end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                      expect(obj3.namespace_stackable(:some_thing)).to eq []
         | 
| 209 | 
            +
                      expect(obj3_copy.namespace_stackable[:some_thing]).to eq [:obj3]
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                      obj1.top_level_setting.inherit_from obj2_copy.point_in_time_copy
         | 
| 212 | 
            +
                      obj2.top_level_setting.inherit_from obj3_copy.point_in_time_copy
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                      expect(obj1_copy.namespace_stackable[:some_thing]).to eq [:obj3, :obj2, :obj1]
         | 
| 215 | 
            +
                    end
         | 
| 216 | 
            +
                  end
         | 
| 217 | 
            +
                end
         | 
| 218 | 
            +
              end
         | 
| 219 | 
            +
            end
         | 
| @@ -5,10 +5,6 @@ module Grape | |
| 5 5 | 
             
                module ValidationsSpec
         | 
| 6 6 | 
             
                  class Dummy
         | 
| 7 7 | 
             
                    include Grape::DSL::Validations
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                    def self.settings
         | 
| 10 | 
            -
                      @settings ||= Grape::Util::HashStack.new
         | 
| 11 | 
            -
                    end
         | 
| 12 8 | 
             
                  end
         | 
| 13 9 | 
             
                end
         | 
| 14 10 |  | 
| @@ -17,17 +13,17 @@ module Grape | |
| 17 13 |  | 
| 18 14 | 
             
                  describe '.reset_validations!' do
         | 
| 19 15 | 
             
                    before do
         | 
| 20 | 
            -
                      subject. | 
| 21 | 
            -
                      subject. | 
| 16 | 
            +
                      subject.namespace_stackable :declared_params, ['dummy']
         | 
| 17 | 
            +
                      subject.namespace_stackable :validations, ['dummy']
         | 
| 22 18 | 
             
                      subject.reset_validations!
         | 
| 23 19 | 
             
                    end
         | 
| 24 20 |  | 
| 25 21 | 
             
                    it 'resets declared params' do
         | 
| 26 | 
            -
                      expect(subject. | 
| 22 | 
            +
                      expect(subject.namespace_stackable(:declared_params)).to eq []
         | 
| 27 23 | 
             
                    end
         | 
| 28 24 |  | 
| 29 25 | 
             
                    it 'resets validations' do
         | 
| 30 | 
            -
                      expect(subject. | 
| 26 | 
            +
                      expect(subject.namespace_stackable(:validations)).to eq []
         | 
| 31 27 | 
             
                    end
         | 
| 32 28 | 
             
                  end
         | 
| 33 29 |  | 
| @@ -37,7 +33,7 @@ module Grape | |
| 37 33 | 
             
                    end
         | 
| 38 34 |  | 
| 39 35 | 
             
                    it 'evaluates block' do
         | 
| 40 | 
            -
                      expect { subject.params {  | 
| 36 | 
            +
                      expect { subject.params { fail 'foo' } }.to raise_error RuntimeError, 'foo'
         | 
| 41 37 | 
             
                    end
         | 
| 42 38 | 
             
                  end
         | 
| 43 39 |  | 
| @@ -46,8 +42,9 @@ module Grape | |
| 46 42 | 
             
                      subject.document_attribute([full_name: 'xxx'], foo: 'bar')
         | 
| 47 43 | 
             
                    end
         | 
| 48 44 |  | 
| 49 | 
            -
                    it 'creates  | 
| 50 | 
            -
                      expect(subject. | 
| 45 | 
            +
                    it 'creates a param documentation' do
         | 
| 46 | 
            +
                      expect(subject.namespace_stackable(:params)).to eq(['xxx' => { foo: 'bar' }])
         | 
| 47 | 
            +
                      expect(subject.route_setting(:description)).to eq(params: { 'xxx' => { foo: 'bar' } })
         | 
| 51 48 | 
             
                    end
         | 
| 52 49 | 
             
                  end
         | 
| 53 50 | 
             
                end
         | 
    
        data/spec/grape/endpoint_spec.rb
    CHANGED
    
    | @@ -11,27 +11,27 @@ describe Grape::Endpoint do | |
| 11 11 | 
             
                after { Grape::Endpoint.before_each(nil) }
         | 
| 12 12 |  | 
| 13 13 | 
             
                it 'should be settable via block' do
         | 
| 14 | 
            -
                  block = lambda { |endpoint|  | 
| 14 | 
            +
                  block = lambda { |endpoint| 'noop' }
         | 
| 15 15 | 
             
                  Grape::Endpoint.before_each(&block)
         | 
| 16 16 | 
             
                  expect(Grape::Endpoint.before_each).to eq(block)
         | 
| 17 17 | 
             
                end
         | 
| 18 18 |  | 
| 19 19 | 
             
                it 'should be settable via reference' do
         | 
| 20 | 
            -
                  block = lambda { |endpoint|  | 
| 20 | 
            +
                  block = lambda { |endpoint| 'noop' }
         | 
| 21 21 | 
             
                  Grape::Endpoint.before_each block
         | 
| 22 22 | 
             
                  expect(Grape::Endpoint.before_each).to eq(block)
         | 
| 23 23 | 
             
                end
         | 
| 24 24 |  | 
| 25 25 | 
             
                it 'should be able to override a helper' do
         | 
| 26 | 
            -
                  subject.get( | 
| 26 | 
            +
                  subject.get('/') { current_user }
         | 
| 27 27 | 
             
                  expect { get '/' }.to raise_error(NameError)
         | 
| 28 28 |  | 
| 29 29 | 
             
                  Grape::Endpoint.before_each do |endpoint|
         | 
| 30 | 
            -
                    allow(endpoint).to receive(:current_user).and_return( | 
| 30 | 
            +
                    allow(endpoint).to receive(:current_user).and_return('Bob')
         | 
| 31 31 | 
             
                  end
         | 
| 32 32 |  | 
| 33 33 | 
             
                  get '/'
         | 
| 34 | 
            -
                  expect(last_response.body).to eq( | 
| 34 | 
            +
                  expect(last_response.body).to eq('Bob')
         | 
| 35 35 |  | 
| 36 36 | 
             
                  Grape::Endpoint.before_each(nil)
         | 
| 37 37 | 
             
                  expect { get '/' }.to raise_error(NameError)
         | 
| @@ -41,17 +41,17 @@ describe Grape::Endpoint do | |
| 41 41 | 
             
              describe '#initialize' do
         | 
| 42 42 | 
             
                it 'takes a settings stack, options, and a block' do
         | 
| 43 43 | 
             
                  p = proc {}
         | 
| 44 | 
            -
                  expect  | 
| 45 | 
            -
                    Grape::Endpoint.new(Grape::Util:: | 
| 44 | 
            +
                  expect do
         | 
| 45 | 
            +
                    Grape::Endpoint.new(Grape::Util::InheritableSetting.new, {
         | 
| 46 46 | 
             
                                          path: '/',
         | 
| 47 47 | 
             
                                          method: :get
         | 
| 48 48 | 
             
                                        }, &p)
         | 
| 49 | 
            -
                   | 
| 49 | 
            +
                  end.not_to raise_error
         | 
| 50 50 | 
             
                end
         | 
| 51 51 | 
             
              end
         | 
| 52 52 |  | 
| 53 53 | 
             
              it 'sets itself in the env upon call' do
         | 
| 54 | 
            -
                subject.get('/') {  | 
| 54 | 
            +
                subject.get('/') { 'Hello world.' }
         | 
| 55 55 | 
             
                get '/'
         | 
| 56 56 | 
             
                expect(last_request.env['api.endpoint']).to be_kind_of(Grape::Endpoint)
         | 
| 57 57 | 
             
              end
         | 
| @@ -60,47 +60,46 @@ describe Grape::Endpoint do | |
| 60 60 | 
             
                it 'is callable from within a block' do
         | 
| 61 61 | 
             
                  subject.get('/home') do
         | 
| 62 62 | 
             
                    status 206
         | 
| 63 | 
            -
                     | 
| 63 | 
            +
                    'Hello'
         | 
| 64 64 | 
             
                  end
         | 
| 65 65 |  | 
| 66 66 | 
             
                  get '/home'
         | 
| 67 67 | 
             
                  expect(last_response.status).to eq(206)
         | 
| 68 | 
            -
                  expect(last_response.body).to eq( | 
| 68 | 
            +
                  expect(last_response.body).to eq('Hello')
         | 
| 69 69 | 
             
                end
         | 
| 70 70 |  | 
| 71 71 | 
             
                it 'is set as default to 200 for get' do
         | 
| 72 72 | 
             
                  memoized_status = nil
         | 
| 73 73 | 
             
                  subject.get('/home') do
         | 
| 74 74 | 
             
                    memoized_status = status
         | 
| 75 | 
            -
                     | 
| 75 | 
            +
                    'Hello'
         | 
| 76 76 | 
             
                  end
         | 
| 77 77 |  | 
| 78 78 | 
             
                  get '/home'
         | 
| 79 79 | 
             
                  expect(last_response.status).to eq(200)
         | 
| 80 80 | 
             
                  expect(memoized_status).to eq(200)
         | 
| 81 | 
            -
                  expect(last_response.body).to eq( | 
| 81 | 
            +
                  expect(last_response.body).to eq('Hello')
         | 
| 82 82 | 
             
                end
         | 
| 83 83 |  | 
| 84 84 | 
             
                it 'is set as default to 201 for post' do
         | 
| 85 85 | 
             
                  memoized_status = nil
         | 
| 86 86 | 
             
                  subject.post('/home') do
         | 
| 87 87 | 
             
                    memoized_status = status
         | 
| 88 | 
            -
                     | 
| 88 | 
            +
                    'Hello'
         | 
| 89 89 | 
             
                  end
         | 
| 90 90 |  | 
| 91 91 | 
             
                  post '/home'
         | 
| 92 92 | 
             
                  expect(last_response.status).to eq(201)
         | 
| 93 93 | 
             
                  expect(memoized_status).to eq(201)
         | 
| 94 | 
            -
                  expect(last_response.body).to eq( | 
| 94 | 
            +
                  expect(last_response.body).to eq('Hello')
         | 
| 95 95 | 
             
                end
         | 
| 96 | 
            -
             | 
| 97 96 | 
             
              end
         | 
| 98 97 |  | 
| 99 98 | 
             
              describe '#header' do
         | 
| 100 99 | 
             
                it 'is callable from within a block' do
         | 
| 101 100 | 
             
                  subject.get('/hey') do
         | 
| 102 101 | 
             
                    header 'X-Awesome', 'true'
         | 
| 103 | 
            -
                     | 
| 102 | 
            +
                    'Awesome'
         | 
| 104 103 | 
             
                  end
         | 
| 105 104 |  | 
| 106 105 | 
             
                  get '/hey'
         | 
| @@ -117,19 +116,19 @@ describe Grape::Endpoint do | |
| 117 116 | 
             
                it 'includes request headers' do
         | 
| 118 117 | 
             
                  get '/headers'
         | 
| 119 118 | 
             
                  expect(JSON.parse(last_response.body)).to eq(
         | 
| 120 | 
            -
                       | 
| 121 | 
            -
                       | 
| 119 | 
            +
                      'Host' => 'example.org',
         | 
| 120 | 
            +
                      'Cookie' => ''
         | 
| 122 121 | 
             
                  )
         | 
| 123 122 | 
             
                end
         | 
| 124 123 | 
             
                it 'includes additional request headers' do
         | 
| 125 | 
            -
                  get '/headers', nil,  | 
| 126 | 
            -
                  expect(JSON.parse(last_response.body)[ | 
| 124 | 
            +
                  get '/headers', nil, 'HTTP_X_GRAPE_CLIENT' => '1'
         | 
| 125 | 
            +
                  expect(JSON.parse(last_response.body)['X-Grape-Client']).to eq('1')
         | 
| 127 126 | 
             
                end
         | 
| 128 127 | 
             
                it 'includes headers passed as symbols' do
         | 
| 129 | 
            -
                  env = Rack::MockRequest.env_for( | 
| 130 | 
            -
                  env[ | 
| 128 | 
            +
                  env = Rack::MockRequest.env_for('/headers')
         | 
| 129 | 
            +
                  env['HTTP_SYMBOL_HEADER'.to_sym] = 'Goliath passes symbols'
         | 
| 131 130 | 
             
                  body = subject.call(env)[2].body.first
         | 
| 132 | 
            -
                  expect(JSON.parse(body)[ | 
| 131 | 
            +
                  expect(JSON.parse(body)['Symbol-Header']).to eq('Goliath passes symbols')
         | 
| 133 132 | 
             
                end
         | 
| 134 133 | 
             
              end
         | 
| 135 134 |  | 
| @@ -150,10 +149,10 @@ describe Grape::Endpoint do | |
| 150 149 | 
             
                  get('/get/cookies')
         | 
| 151 150 |  | 
| 152 151 | 
             
                  expect(last_response.headers['Set-Cookie'].split("\n").sort).to eql [
         | 
| 153 | 
            -
                     | 
| 154 | 
            -
                     | 
| 155 | 
            -
                     | 
| 156 | 
            -
                     | 
| 152 | 
            +
                    'cookie3=symbol',
         | 
| 153 | 
            +
                    'cookie4=secret+code+here',
         | 
| 154 | 
            +
                    'my-awesome-cookie1=is+cool',
         | 
| 155 | 
            +
                    'my-awesome-cookie2=is+cool+too; domain=my.example.com; path=/; secure'
         | 
| 157 156 | 
             
                 ]
         | 
| 158 157 | 
             
                end
         | 
| 159 158 |  | 
| @@ -170,7 +169,7 @@ describe Grape::Endpoint do | |
| 170 169 | 
             
                it 'sets and update browser cookies' do
         | 
| 171 170 | 
             
                  subject.get('/username') do
         | 
| 172 171 | 
             
                    cookies[:sandbox] = true if cookies[:sandbox] == 'false'
         | 
| 173 | 
            -
                    cookies[:username] +=  | 
| 172 | 
            +
                    cookies[:username] += '_test'
         | 
| 174 173 | 
             
                  end
         | 
| 175 174 | 
             
                  get('/username', {}, 'HTTP_COOKIE' => 'username=user; sandbox=false')
         | 
| 176 175 | 
             
                  expect(last_response.body).to eq('user_test')
         | 
| @@ -194,10 +193,10 @@ describe Grape::Endpoint do | |
| 194 193 | 
             
                    [cookie.name, cookie]
         | 
| 195 194 | 
             
                  end]
         | 
| 196 195 | 
             
                  expect(cookies.size).to eq(2)
         | 
| 197 | 
            -
                   | 
| 196 | 
            +
                  %w(and_this delete_this_cookie).each do |cookie_name|
         | 
| 198 197 | 
             
                    cookie = cookies[cookie_name]
         | 
| 199 198 | 
             
                    expect(cookie).not_to be_nil
         | 
| 200 | 
            -
                    expect(cookie.value).to eq( | 
| 199 | 
            +
                    expect(cookie.value).to eq('deleted')
         | 
| 201 200 | 
             
                    expect(cookie.expired?).to be true
         | 
| 202 201 | 
             
                  end
         | 
| 203 202 | 
             
                end
         | 
| @@ -218,11 +217,11 @@ describe Grape::Endpoint do | |
| 218 217 | 
             
                    [cookie.name, cookie]
         | 
| 219 218 | 
             
                  end]
         | 
| 220 219 | 
             
                  expect(cookies.size).to eq(2)
         | 
| 221 | 
            -
                   | 
| 220 | 
            +
                  %w(and_this delete_this_cookie).each do |cookie_name|
         | 
| 222 221 | 
             
                    cookie = cookies[cookie_name]
         | 
| 223 222 | 
             
                    expect(cookie).not_to be_nil
         | 
| 224 | 
            -
                    expect(cookie.value).to eq( | 
| 225 | 
            -
                    expect(cookie.path).to eq( | 
| 223 | 
            +
                    expect(cookie.value).to eq('deleted')
         | 
| 224 | 
            +
                    expect(cookie.path).to eq('/test')
         | 
| 226 225 | 
             
                    expect(cookie.expired?).to be true
         | 
| 227 226 | 
             
                  end
         | 
| 228 227 | 
             
                end
         | 
| @@ -244,7 +243,7 @@ describe Grape::Endpoint do | |
| 244 243 | 
             
                  inner_params = nil
         | 
| 245 244 | 
             
                  subject.get '/declared' do
         | 
| 246 245 | 
             
                    inner_params = declared(params).keys
         | 
| 247 | 
            -
                     | 
| 246 | 
            +
                    ''
         | 
| 248 247 | 
             
                  end
         | 
| 249 248 | 
             
                  get '/declared?first=present'
         | 
| 250 249 | 
             
                  expect(last_response.status).to eq(200)
         | 
| @@ -255,7 +254,7 @@ describe Grape::Endpoint do | |
| 255 254 | 
             
                  inner_params = nil
         | 
| 256 255 | 
             
                  subject.get '/declared' do
         | 
| 257 256 | 
             
                    inner_params = declared(params)
         | 
| 258 | 
            -
                     | 
| 257 | 
            +
                    ''
         | 
| 259 258 | 
             
                  end
         | 
| 260 259 | 
             
                  get '/declared?first=one'
         | 
| 261 260 | 
             
                  expect(last_response.status).to eq(200)
         | 
| @@ -266,7 +265,7 @@ describe Grape::Endpoint do | |
| 266 265 | 
             
                  inner_params = nil
         | 
| 267 266 | 
             
                  subject.get '/declared' do
         | 
| 268 267 | 
             
                    inner_params = declared(params)
         | 
| 269 | 
            -
                     | 
| 268 | 
            +
                    ''
         | 
| 270 269 | 
             
                  end
         | 
| 271 270 |  | 
| 272 271 | 
             
                  get '/declared?first=present&nested[fourth]=1'
         | 
| @@ -288,7 +287,7 @@ describe Grape::Endpoint do | |
| 288 287 | 
             
                  inner_params = nil
         | 
| 289 288 | 
             
                  subject.get '/declared' do
         | 
| 290 289 | 
             
                    inner_params = declared(params)
         | 
| 291 | 
            -
                     | 
| 290 | 
            +
                    ''
         | 
| 292 291 | 
             
                  end
         | 
| 293 292 |  | 
| 294 293 | 
             
                  get '/declared?first=present&nested[][fourth]=1&nested[][fourth]=2'
         | 
| @@ -300,7 +299,7 @@ describe Grape::Endpoint do | |
| 300 299 | 
             
                  inner_params = nil
         | 
| 301 300 | 
             
                  subject.get '/declared' do
         | 
| 302 301 | 
             
                    inner_params = declared(params)
         | 
| 303 | 
            -
                     | 
| 302 | 
            +
                    ''
         | 
| 304 303 | 
             
                  end
         | 
| 305 304 | 
             
                  get '/declared?first=one&other=two'
         | 
| 306 305 | 
             
                  expect(last_response.status).to eq(200)
         | 
| @@ -311,23 +310,57 @@ describe Grape::Endpoint do | |
| 311 310 | 
             
                  inner_params = nil
         | 
| 312 311 | 
             
                  subject.get '/declared' do
         | 
| 313 312 | 
             
                    inner_params = declared(params, stringify: true)
         | 
| 314 | 
            -
                     | 
| 313 | 
            +
                    ''
         | 
| 315 314 | 
             
                  end
         | 
| 316 315 |  | 
| 317 316 | 
             
                  get '/declared?first=one&other=two'
         | 
| 318 317 | 
             
                  expect(last_response.status).to eq(200)
         | 
| 319 | 
            -
                  expect(inner_params[ | 
| 318 | 
            +
                  expect(inner_params['first']).to eq 'one'
         | 
| 320 319 | 
             
                end
         | 
| 321 320 |  | 
| 322 321 | 
             
                it 'does not include missing attributes if that option is passed' do
         | 
| 323 322 | 
             
                  subject.get '/declared' do
         | 
| 324 | 
            -
                    error! 400,  | 
| 325 | 
            -
                     | 
| 323 | 
            +
                    error! 400, 'expected nil' if declared(params, include_missing: false)[:second]
         | 
| 324 | 
            +
                    ''
         | 
| 326 325 | 
             
                  end
         | 
| 327 326 |  | 
| 328 327 | 
             
                  get '/declared?first=one&other=two'
         | 
| 329 328 | 
             
                  expect(last_response.status).to eq(200)
         | 
| 330 329 | 
             
                end
         | 
| 330 | 
            +
             | 
| 331 | 
            +
                it 'does not include missing attributes when there are nested hashes' do
         | 
| 332 | 
            +
                  subject.get '/dummy' do
         | 
| 333 | 
            +
                  end
         | 
| 334 | 
            +
             | 
| 335 | 
            +
                  subject.params do
         | 
| 336 | 
            +
                    requires :first
         | 
| 337 | 
            +
                    optional :second
         | 
| 338 | 
            +
                    optional :third, default: nil
         | 
| 339 | 
            +
                    optional :nested, type: Hash do
         | 
| 340 | 
            +
                      optional :fourth, default: nil
         | 
| 341 | 
            +
                      optional :fifth, default: nil
         | 
| 342 | 
            +
                      requires :nested_nested, type: Hash do
         | 
| 343 | 
            +
                        optional :sixth, default: 'sixth-default'
         | 
| 344 | 
            +
                        optional :seven, default: nil
         | 
| 345 | 
            +
                      end
         | 
| 346 | 
            +
                    end
         | 
| 347 | 
            +
                  end
         | 
| 348 | 
            +
             | 
| 349 | 
            +
                  inner_params = nil
         | 
| 350 | 
            +
                  subject.get '/declared' do
         | 
| 351 | 
            +
                    inner_params = declared(params, include_missing: false)
         | 
| 352 | 
            +
                    ''
         | 
| 353 | 
            +
                  end
         | 
| 354 | 
            +
             | 
| 355 | 
            +
                  get '/declared?first=present&nested[fourth]=&nested[nested_nested][sixth]=sixth'
         | 
| 356 | 
            +
             | 
| 357 | 
            +
                  expect(last_response.status).to eq(200)
         | 
| 358 | 
            +
                  expect(inner_params[:first]).to eq 'present'
         | 
| 359 | 
            +
                  expect(inner_params[:nested].keys).to eq [:fourth, :nested_nested]
         | 
| 360 | 
            +
                  expect(inner_params[:nested][:fourth]).to eq ''
         | 
| 361 | 
            +
                  expect(inner_params[:nested][:nested_nested].keys).to eq [:sixth]
         | 
| 362 | 
            +
                  expect(inner_params[:nested][:nested_nested][:sixth]).to eq 'sixth'
         | 
| 363 | 
            +
                end
         | 
| 331 364 | 
             
              end
         | 
| 332 365 |  | 
| 333 366 | 
             
              describe '#declared; call from child namespace' do
         | 
| @@ -451,7 +484,7 @@ describe Grape::Endpoint do | |
| 451 484 | 
             
                        end
         | 
| 452 485 | 
             
                      end
         | 
| 453 486 | 
             
                    end
         | 
| 454 | 
            -
                    it  | 
| 487 | 
            +
                    it 'parse email param with provided requirements for params' do
         | 
| 455 488 | 
             
                      get '/outer/abc@example.com'
         | 
| 456 489 | 
             
                      expect(last_response.body).to eq('abc@example.com')
         | 
| 457 490 | 
             
                    end
         | 
| @@ -464,7 +497,6 @@ describe Grape::Endpoint do | |
| 464 497 | 
             
                      expect(last_response.status).to eq(200)
         | 
| 465 498 | 
             
                      expect(last_response.body).to eq('someone@testing.com1')
         | 
| 466 499 | 
             
                    end
         | 
| 467 | 
            -
             | 
| 468 500 | 
             
                  end
         | 
| 469 501 | 
             
                end
         | 
| 470 502 |  | 
| @@ -500,16 +532,16 @@ describe Grape::Endpoint do | |
| 500 532 |  | 
| 501 533 | 
             
                  it 'does not include parameters not defined by the body' do
         | 
| 502 534 | 
             
                    subject.post '/omitted_params' do
         | 
| 503 | 
            -
                      error! 400,  | 
| 535 | 
            +
                      error! 400, 'expected nil' if params[:version]
         | 
| 504 536 | 
             
                      params[:user]
         | 
| 505 537 | 
             
                    end
         | 
| 506 538 | 
             
                    post '/omitted_params', MultiJson.dump(user: 'Bob'), 'CONTENT_TYPE' => 'application/json'
         | 
| 507 539 | 
             
                    expect(last_response.status).to eq(201)
         | 
| 508 | 
            -
                    expect(last_response.body).to eq( | 
| 540 | 
            +
                    expect(last_response.body).to eq('Bob')
         | 
| 509 541 | 
             
                  end
         | 
| 510 542 | 
             
                end
         | 
| 511 543 |  | 
| 512 | 
            -
                it  | 
| 544 | 
            +
                it 'responds with a 406 for an unsupported content-type' do
         | 
| 513 545 | 
             
                  subject.format :json
         | 
| 514 546 | 
             
                  # subject.content_type :json, "application/json"
         | 
| 515 547 | 
             
                  subject.put '/request_body' do
         | 
| @@ -531,18 +563,16 @@ describe Grape::Endpoint do | |
| 531 563 | 
             
                    post '/', MultiJson.dump(data: { some: 'payload' }), 'CONTENT_TYPE' => 'application/json'
         | 
| 532 564 | 
             
                  end
         | 
| 533 565 |  | 
| 534 | 
            -
                  it  | 
| 566 | 
            +
                  it 'should not response with 406 for same type without params' do
         | 
| 535 567 | 
             
                    expect(last_response.status).not_to be 406
         | 
| 536 568 | 
             
                  end
         | 
| 537 569 |  | 
| 538 | 
            -
                  it  | 
| 570 | 
            +
                  it 'should response with given content type in headers' do
         | 
| 539 571 | 
             
                    expect(last_response.headers['Content-Type']).to eq 'application/json; charset=utf-8'
         | 
| 540 572 | 
             
                  end
         | 
| 541 | 
            -
             | 
| 542 573 | 
             
                end
         | 
| 543 574 |  | 
| 544 575 | 
             
                context 'precedence' do
         | 
| 545 | 
            -
             | 
| 546 576 | 
             
                  before do
         | 
| 547 577 | 
             
                    subject.format :json
         | 
| 548 578 | 
             
                    subject.namespace '/:id' do
         | 
| @@ -578,29 +608,28 @@ describe Grape::Endpoint do | |
| 578 608 | 
             
                    expect(JSON.parse(last_response.body)['params']).to eq '123'
         | 
| 579 609 | 
             
                  end
         | 
| 580 610 | 
             
                end
         | 
| 581 | 
            -
             | 
| 582 611 | 
             
              end
         | 
| 583 612 |  | 
| 584 613 | 
             
              describe '#error!' do
         | 
| 585 614 | 
             
                it 'accepts a message' do
         | 
| 586 615 | 
             
                  subject.get('/hey') do
         | 
| 587 | 
            -
                    error!  | 
| 588 | 
            -
                     | 
| 616 | 
            +
                    error! 'This is not valid.'
         | 
| 617 | 
            +
                    'This is valid.'
         | 
| 589 618 | 
             
                  end
         | 
| 590 619 |  | 
| 591 620 | 
             
                  get '/hey'
         | 
| 592 621 | 
             
                  expect(last_response.status).to eq(500)
         | 
| 593 | 
            -
                  expect(last_response.body).to eq( | 
| 622 | 
            +
                  expect(last_response.body).to eq('This is not valid.')
         | 
| 594 623 | 
             
                end
         | 
| 595 624 |  | 
| 596 625 | 
             
                it 'accepts a code' do
         | 
| 597 626 | 
             
                  subject.get('/hey') do
         | 
| 598 | 
            -
                    error!  | 
| 627 | 
            +
                    error! 'Unauthorized.', 401
         | 
| 599 628 | 
             
                  end
         | 
| 600 629 |  | 
| 601 630 | 
             
                  get '/hey'
         | 
| 602 631 | 
             
                  expect(last_response.status).to eq(401)
         | 
| 603 | 
            -
                  expect(last_response.body).to eq( | 
| 632 | 
            +
                  expect(last_response.body).to eq('Unauthorized.')
         | 
| 604 633 | 
             
                end
         | 
| 605 634 |  | 
| 606 635 | 
             
                it 'accepts an object and render it in format' do
         | 
| @@ -640,31 +669,31 @@ describe Grape::Endpoint do | |
| 640 669 | 
             
              describe '#redirect' do
         | 
| 641 670 | 
             
                it 'redirects to a url with status 302' do
         | 
| 642 671 | 
             
                  subject.get('/hey') do
         | 
| 643 | 
            -
                    redirect  | 
| 672 | 
            +
                    redirect '/ha'
         | 
| 644 673 | 
             
                  end
         | 
| 645 674 | 
             
                  get '/hey'
         | 
| 646 675 | 
             
                  expect(last_response.status).to eq 302
         | 
| 647 | 
            -
                  expect(last_response.headers['Location']).to eq  | 
| 648 | 
            -
                  expect(last_response.body).to eq  | 
| 676 | 
            +
                  expect(last_response.headers['Location']).to eq '/ha'
         | 
| 677 | 
            +
                  expect(last_response.body).to eq ''
         | 
| 649 678 | 
             
                end
         | 
| 650 679 |  | 
| 651 680 | 
             
                it 'has status code 303 if it is not get request and it is http 1.1' do
         | 
| 652 681 | 
             
                  subject.post('/hey') do
         | 
| 653 | 
            -
                    redirect  | 
| 682 | 
            +
                    redirect '/ha'
         | 
| 654 683 | 
             
                  end
         | 
| 655 684 | 
             
                  post '/hey', {}, 'HTTP_VERSION' => 'HTTP/1.1'
         | 
| 656 685 | 
             
                  expect(last_response.status).to eq 303
         | 
| 657 | 
            -
                  expect(last_response.headers['Location']).to eq  | 
| 686 | 
            +
                  expect(last_response.headers['Location']).to eq '/ha'
         | 
| 658 687 | 
             
                end
         | 
| 659 688 |  | 
| 660 689 | 
             
                it 'support permanent redirect' do
         | 
| 661 690 | 
             
                  subject.get('/hey') do
         | 
| 662 | 
            -
                    redirect  | 
| 691 | 
            +
                    redirect '/ha', permanent: true
         | 
| 663 692 | 
             
                  end
         | 
| 664 693 | 
             
                  get '/hey'
         | 
| 665 694 | 
             
                  expect(last_response.status).to eq 301
         | 
| 666 | 
            -
                  expect(last_response.headers['Location']).to eq  | 
| 667 | 
            -
                  expect(last_response.body).to eq  | 
| 695 | 
            +
                  expect(last_response.headers['Location']).to eq '/ha'
         | 
| 696 | 
            +
                  expect(last_response.body).to eq ''
         | 
| 668 697 | 
             
                end
         | 
| 669 698 | 
             
              end
         | 
| 670 699 |  | 
| @@ -699,54 +728,54 @@ describe Grape::Endpoint do | |
| 699 728 |  | 
| 700 729 | 
             
              it 'allows explicit return calls' do
         | 
| 701 730 | 
             
                subject.get('/home') do
         | 
| 702 | 
            -
                  return  | 
| 731 | 
            +
                  return 'Hello'
         | 
| 703 732 | 
             
                end
         | 
| 704 733 |  | 
| 705 734 | 
             
                get '/home'
         | 
| 706 735 | 
             
                expect(last_response.status).to eq(200)
         | 
| 707 | 
            -
                expect(last_response.body).to eq( | 
| 736 | 
            +
                expect(last_response.body).to eq('Hello')
         | 
| 708 737 | 
             
              end
         | 
| 709 738 |  | 
| 710 739 | 
             
              describe '.generate_api_method' do
         | 
| 711 740 | 
             
                it 'raises NameError if the method name is already in use' do
         | 
| 712 | 
            -
                  expect  | 
| 713 | 
            -
                    Grape::Endpoint.generate_api_method( | 
| 714 | 
            -
                   | 
| 741 | 
            +
                  expect do
         | 
| 742 | 
            +
                    Grape::Endpoint.generate_api_method('version', &proc {})
         | 
| 743 | 
            +
                  end.to raise_error(NameError)
         | 
| 715 744 | 
             
                end
         | 
| 716 745 | 
             
                it 'raises ArgumentError if a block is not given' do
         | 
| 717 | 
            -
                  expect  | 
| 718 | 
            -
                    Grape::Endpoint.generate_api_method( | 
| 719 | 
            -
                   | 
| 746 | 
            +
                  expect do
         | 
| 747 | 
            +
                    Grape::Endpoint.generate_api_method('GET without a block method')
         | 
| 748 | 
            +
                  end.to raise_error(ArgumentError)
         | 
| 720 749 | 
             
                end
         | 
| 721 750 | 
             
                it 'returns a Proc' do
         | 
| 722 | 
            -
                  expect(Grape::Endpoint.generate_api_method( | 
| 751 | 
            +
                  expect(Grape::Endpoint.generate_api_method('GET test for a proc', &proc {})).to be_a Proc
         | 
| 723 752 | 
             
                end
         | 
| 724 753 | 
             
              end
         | 
| 725 754 |  | 
| 726 755 | 
             
              context 'filters' do
         | 
| 727 756 | 
             
                describe 'before filters' do
         | 
| 728 757 | 
             
                  it 'runs the before filter if set' do
         | 
| 729 | 
            -
                    subject.before { env['before_test'] =  | 
| 758 | 
            +
                    subject.before { env['before_test'] = 'OK' }
         | 
| 730 759 | 
             
                    subject.get('/before_test') { env['before_test'] }
         | 
| 731 760 |  | 
| 732 761 | 
             
                    get '/before_test'
         | 
| 733 | 
            -
                    expect(last_response.body).to eq( | 
| 762 | 
            +
                    expect(last_response.body).to eq('OK')
         | 
| 734 763 | 
             
                  end
         | 
| 735 764 | 
             
                end
         | 
| 736 765 |  | 
| 737 766 | 
             
                describe 'after filters' do
         | 
| 738 767 | 
             
                  it 'overrides the response body if it sets it' do
         | 
| 739 | 
            -
                    subject.after { body  | 
| 740 | 
            -
                    subject.get('/after_test') {  | 
| 768 | 
            +
                    subject.after { body 'after' }
         | 
| 769 | 
            +
                    subject.get('/after_test') { 'during' }
         | 
| 741 770 | 
             
                    get '/after_test'
         | 
| 742 771 | 
             
                    expect(last_response.body).to eq('after')
         | 
| 743 772 | 
             
                  end
         | 
| 744 773 |  | 
| 745 774 | 
             
                  it 'does not override the response body with its return' do
         | 
| 746 | 
            -
                    subject.after {  | 
| 747 | 
            -
                    subject.get('/after_test') {  | 
| 775 | 
            +
                    subject.after { 'after' }
         | 
| 776 | 
            +
                    subject.get('/after_test') { 'body' }
         | 
| 748 777 | 
             
                    get '/after_test'
         | 
| 749 | 
            -
                    expect(last_response.body).to eq( | 
| 778 | 
            +
                    expect(last_response.body).to eq('body')
         | 
| 750 779 | 
             
                  end
         | 
| 751 780 | 
             
                end
         | 
| 752 781 | 
             
              end
         | 
| @@ -776,7 +805,7 @@ describe Grape::Endpoint do | |
| 776 805 | 
             
                      verb
         | 
| 777 806 | 
             
                    end
         | 
| 778 807 | 
             
                    send(verb, '/example/and/some/more')
         | 
| 779 | 
            -
                    expect(last_response.status).to eql verb ==  | 
| 808 | 
            +
                    expect(last_response.status).to eql verb == 'post' ? 201 : 200
         | 
| 780 809 | 
             
                    expect(last_response.body).to eql verb == 'head' ? '' : verb
         | 
| 781 810 | 
             
                  end
         | 
| 782 811 | 
             
                end
         | 
| @@ -788,7 +817,7 @@ describe Grape::Endpoint do | |
| 788 817 | 
             
                    request.url
         | 
| 789 818 | 
             
                  end
         | 
| 790 819 | 
             
                  get '/url'
         | 
| 791 | 
            -
                  expect(last_response.body).to eq( | 
| 820 | 
            +
                  expect(last_response.body).to eq('http://example.org/url')
         | 
| 792 821 | 
             
                end
         | 
| 793 822 | 
             
                ['v1', :v1].each do |version|
         | 
| 794 823 | 
             
                  it 'should include version #{version}' do
         | 
| @@ -807,7 +836,7 @@ describe Grape::Endpoint do | |
| 807 836 | 
             
                    request.url
         | 
| 808 837 | 
             
                  end
         | 
| 809 838 | 
             
                  get '/api/v1/url'
         | 
| 810 | 
            -
                  expect(last_response.body).to eq( | 
| 839 | 
            +
                  expect(last_response.body).to eq('http://example.org/api/v1/url')
         | 
| 811 840 | 
             
                end
         | 
| 812 841 | 
             
              end
         | 
| 813 842 |  | 
| @@ -816,7 +845,7 @@ describe Grape::Endpoint do | |
| 816 845 | 
             
                  # NOTE: a 404 is returned instead of the 406 if cascade: false is not set.
         | 
| 817 846 | 
             
                  subject.version 'v1', using: :header, vendor: 'ohanapi', cascade: false
         | 
| 818 847 | 
             
                  subject.get '/test' do
         | 
| 819 | 
            -
                     | 
| 848 | 
            +
                    'Hello!'
         | 
| 820 849 | 
             
                  end
         | 
| 821 850 | 
             
                end
         | 
| 822 851 |  |