grape 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
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
@@ -27,7 +27,7 @@ describe Grape::Middleware::Versioner::Path do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
[
|
30
|
+
[%w(v1 v2), [:v1, :v2], [:v1, 'v2'], ['v1', :v2]].each do |versions|
|
31
31
|
context 'with specified versions as #{versions}' do
|
32
32
|
before { @options = { versions: versions } }
|
33
33
|
|
@@ -40,5 +40,4 @@ describe Grape::Middleware::Versioner::Path do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
43
|
-
|
44
43
|
end
|
data/spec/grape/path_spec.rb
CHANGED
@@ -2,65 +2,64 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Grape
|
4
4
|
describe Path do
|
5
|
-
|
6
|
-
|
7
|
-
it "remembers the path" do
|
5
|
+
describe '#initialize' do
|
6
|
+
it 'remembers the path' do
|
8
7
|
path = Path.new('/:id', anything, anything)
|
9
8
|
expect(path.raw_path).to eql('/:id')
|
10
9
|
end
|
11
10
|
|
12
|
-
it
|
11
|
+
it 'remembers the namespace' do
|
13
12
|
path = Path.new(anything, '/users', anything)
|
14
13
|
expect(path.namespace).to eql('/users')
|
15
14
|
end
|
16
15
|
|
17
|
-
it
|
16
|
+
it 'remebers the settings' do
|
18
17
|
path = Path.new(anything, anything, foo: 'bar')
|
19
18
|
expect(path.settings).to eql(foo: 'bar')
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
23
|
-
describe
|
24
|
-
it
|
22
|
+
describe '#mount_path' do
|
23
|
+
it 'is nil when no mount path setting exists' do
|
25
24
|
path = Path.new(anything, anything, {})
|
26
25
|
expect(path.mount_path).to be_nil
|
27
26
|
end
|
28
27
|
|
29
|
-
it
|
28
|
+
it 'is nil when the mount path is nil' do
|
30
29
|
path = Path.new(anything, anything, mount_path: nil)
|
31
30
|
expect(path.mount_path).to be_nil
|
32
31
|
end
|
33
32
|
|
34
|
-
it
|
35
|
-
path = Path.new(anything, anything, mount_path:
|
36
|
-
expect(path.mount_path).to eql(
|
33
|
+
it 'splits the mount path' do
|
34
|
+
path = Path.new(anything, anything, mount_path: %w(foo bar))
|
35
|
+
expect(path.mount_path).to eql(%w(foo bar))
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
40
|
-
describe
|
41
|
-
it
|
39
|
+
describe '#root_prefix' do
|
40
|
+
it 'is nil when no root prefix setting exists' do
|
42
41
|
path = Path.new(anything, anything, {})
|
43
42
|
expect(path.root_prefix).to be_nil
|
44
43
|
end
|
45
44
|
|
46
|
-
it
|
45
|
+
it 'is nil when the mount path is nil' do
|
47
46
|
path = Path.new(anything, anything, root_prefix: nil)
|
48
47
|
expect(path.root_prefix).to be_nil
|
49
48
|
end
|
50
49
|
|
51
|
-
it
|
50
|
+
it 'splits the mount path' do
|
52
51
|
path = Path.new(anything, anything, root_prefix: 'hello/world')
|
53
|
-
expect(path.root_prefix).to eql(
|
52
|
+
expect(path.root_prefix).to eql(%w(hello world))
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
57
|
-
describe
|
58
|
-
it
|
56
|
+
describe '#uses_path_versioning?' do
|
57
|
+
it 'is false when the version setting is nil' do
|
59
58
|
path = Path.new(anything, anything, version: nil)
|
60
59
|
expect(path.uses_path_versioning?).to be false
|
61
60
|
end
|
62
61
|
|
63
|
-
it
|
62
|
+
it 'is false when the version option is header' do
|
64
63
|
path = Path.new(
|
65
64
|
anything,
|
66
65
|
anything,
|
@@ -71,7 +70,7 @@ module Grape
|
|
71
70
|
expect(path.uses_path_versioning?).to be false
|
72
71
|
end
|
73
72
|
|
74
|
-
it
|
73
|
+
it 'is true when the version option is path' do
|
75
74
|
path = Path.new(
|
76
75
|
anything,
|
77
76
|
anything,
|
@@ -83,70 +82,70 @@ module Grape
|
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
86
|
-
describe
|
87
|
-
it
|
85
|
+
describe '#has_namespace?' do
|
86
|
+
it 'is false when the namespace is nil' do
|
88
87
|
path = Path.new(anything, nil, anything)
|
89
88
|
expect(path).not_to have_namespace
|
90
89
|
end
|
91
90
|
|
92
|
-
it
|
91
|
+
it 'is false when the namespace starts with whitespace' do
|
93
92
|
path = Path.new(anything, ' /foo', anything)
|
94
93
|
expect(path).not_to have_namespace
|
95
94
|
end
|
96
95
|
|
97
|
-
it
|
96
|
+
it 'is false when the namespace is the root path' do
|
98
97
|
path = Path.new(anything, '/', anything)
|
99
98
|
expect(path).not_to have_namespace
|
100
99
|
end
|
101
100
|
|
102
|
-
it
|
101
|
+
it 'is true otherwise' do
|
103
102
|
path = Path.new(anything, '/world', anything)
|
104
103
|
expect(path).to have_namespace
|
105
104
|
end
|
106
105
|
end
|
107
106
|
|
108
|
-
describe
|
109
|
-
it
|
107
|
+
describe '#has_path?' do
|
108
|
+
it 'is false when the path is nil' do
|
110
109
|
path = Path.new(nil, anything, anything)
|
111
110
|
expect(path).not_to have_path
|
112
111
|
end
|
113
112
|
|
114
|
-
it
|
113
|
+
it 'is false when the path starts with whitespace' do
|
115
114
|
path = Path.new(' /foo', anything, anything)
|
116
115
|
expect(path).not_to have_path
|
117
116
|
end
|
118
117
|
|
119
|
-
it
|
118
|
+
it 'is false when the path is the root path' do
|
120
119
|
path = Path.new('/', anything, anything)
|
121
120
|
expect(path).not_to have_path
|
122
121
|
end
|
123
122
|
|
124
|
-
it
|
123
|
+
it 'is true otherwise' do
|
125
124
|
path = Path.new('/hello', anything, anything)
|
126
125
|
expect(path).to have_path
|
127
126
|
end
|
128
127
|
end
|
129
128
|
|
130
|
-
describe
|
131
|
-
context
|
132
|
-
it
|
129
|
+
describe '#path' do
|
130
|
+
context 'mount_path' do
|
131
|
+
it 'is not included when it is nil' do
|
133
132
|
path = Path.new(nil, nil, mount_path: '/foo/bar')
|
134
133
|
expect(path.path).to eql '/foo/bar'
|
135
134
|
end
|
136
135
|
|
137
|
-
it
|
136
|
+
it 'is included when it is not nil' do
|
138
137
|
path = Path.new(nil, nil, {})
|
139
138
|
expect(path.path).to eql('/')
|
140
139
|
end
|
141
140
|
end
|
142
141
|
|
143
|
-
context
|
144
|
-
it
|
142
|
+
context 'root_prefix' do
|
143
|
+
it 'is not included when it is nil' do
|
145
144
|
path = Path.new(nil, nil, {})
|
146
145
|
expect(path.path).to eql('/')
|
147
146
|
end
|
148
147
|
|
149
|
-
it
|
148
|
+
it 'is included after the mount path' do
|
150
149
|
path = Path.new(
|
151
150
|
nil,
|
152
151
|
nil,
|
@@ -158,7 +157,7 @@ module Grape
|
|
158
157
|
end
|
159
158
|
end
|
160
159
|
|
161
|
-
it
|
160
|
+
it 'uses the namespace after the mount path and root prefix' do
|
162
161
|
path = Path.new(
|
163
162
|
nil,
|
164
163
|
'namespace',
|
@@ -169,7 +168,7 @@ module Grape
|
|
169
168
|
expect(path.path).to eql('/foo/hello/namespace')
|
170
169
|
end
|
171
170
|
|
172
|
-
it
|
171
|
+
it 'uses the raw path after the namespace' do
|
173
172
|
path = Path.new(
|
174
173
|
'raw_path',
|
175
174
|
'namespace',
|
@@ -181,19 +180,30 @@ module Grape
|
|
181
180
|
end
|
182
181
|
end
|
183
182
|
|
184
|
-
describe
|
185
|
-
context
|
183
|
+
describe '#suffix' do
|
184
|
+
context 'when using a specific format' do
|
185
|
+
it 'is empty' do
|
186
|
+
path = Path.new(nil, nil, {})
|
187
|
+
allow(path).to receive(:uses_specific_format?) { true }
|
188
|
+
|
189
|
+
expect(path.suffix).to eql('')
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'when path versioning is used' do
|
186
194
|
it "includes a '/'" do
|
187
195
|
path = Path.new(nil, nil, {})
|
196
|
+
allow(path).to receive(:uses_specific_format?) { false }
|
188
197
|
allow(path).to receive(:uses_path_versioning?) { true }
|
189
198
|
|
190
199
|
expect(path.suffix).to eql('(/.:format)')
|
191
200
|
end
|
192
201
|
end
|
193
202
|
|
194
|
-
context
|
203
|
+
context 'when path versioning is not used' do
|
195
204
|
it "does not include a '/' when the path has a namespace" do
|
196
205
|
path = Path.new(nil, 'namespace', {})
|
206
|
+
allow(path).to receive(:uses_specific_format?) { false }
|
197
207
|
allow(path).to receive(:uses_path_versioning?) { true }
|
198
208
|
|
199
209
|
expect(path.suffix).to eql('(.:format)')
|
@@ -201,6 +211,7 @@ module Grape
|
|
201
211
|
|
202
212
|
it "does not include a '/' when the path has a path" do
|
203
213
|
path = Path.new('/path', nil, {})
|
214
|
+
allow(path).to receive(:uses_specific_format?) { false }
|
204
215
|
allow(path).to receive(:uses_path_versioning?) { true }
|
205
216
|
|
206
217
|
expect(path.suffix).to eql('(.:format)')
|
@@ -208,6 +219,7 @@ module Grape
|
|
208
219
|
|
209
220
|
it "includes a '/' otherwise" do
|
210
221
|
path = Path.new(nil, nil, {})
|
222
|
+
allow(path).to receive(:uses_specific_format?) { false }
|
211
223
|
allow(path).to receive(:uses_path_versioning?) { true }
|
212
224
|
|
213
225
|
expect(path.suffix).to eql('(/.:format)')
|
@@ -215,15 +227,24 @@ module Grape
|
|
215
227
|
end
|
216
228
|
end
|
217
229
|
|
218
|
-
describe
|
219
|
-
it
|
230
|
+
describe '#path_with_suffix' do
|
231
|
+
it 'combines the path and suffix' do
|
220
232
|
path = Path.new(nil, nil, {})
|
221
233
|
allow(path).to receive(:path) { '/the/path' }
|
222
234
|
allow(path).to receive(:suffix) { 'suffix' }
|
223
235
|
|
224
236
|
expect(path.path_with_suffix).to eql('/the/pathsuffix')
|
225
237
|
end
|
226
|
-
end
|
227
238
|
|
239
|
+
context 'when using a specific format' do
|
240
|
+
it 'does not have a suffix' do
|
241
|
+
path = Path.new(nil, nil, {})
|
242
|
+
allow(path).to receive(:path) { '/the/path' }
|
243
|
+
allow(path).to receive(:uses_specific_format?) { true }
|
244
|
+
|
245
|
+
expect(path.path_with_suffix).to eql('/the/path')
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
228
249
|
end
|
229
250
|
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Grape
|
3
|
+
module Util
|
4
|
+
describe InheritableSetting do
|
5
|
+
before :each do
|
6
|
+
InheritableSetting.reset_global!
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:parent) do
|
10
|
+
Grape::Util::InheritableSetting.new.tap do |settings|
|
11
|
+
settings.global[:global_thing] = :global_foo_bar
|
12
|
+
settings.namespace[:namespace_thing] = :namespace_foo_bar
|
13
|
+
settings.namespace_inheritable[:namespace_inheritable_thing] = :namespace_inheritable_foo_bar
|
14
|
+
settings.namespace_stackable[:namespace_stackable_thing] = :namespace_stackable_foo_bar
|
15
|
+
settings.route[:route_thing] = :route_foo_bar
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:other_parent) do
|
20
|
+
Grape::Util::InheritableSetting.new.tap do |settings|
|
21
|
+
settings.namespace[:namespace_thing] = :namespace_foo_bar_other
|
22
|
+
settings.namespace_inheritable[:namespace_inheritable_thing] = :namespace_inheritable_foo_bar_other
|
23
|
+
settings.namespace_stackable[:namespace_stackable_thing] = :namespace_stackable_foo_bar_other
|
24
|
+
settings.route[:route_thing] = :route_foo_bar_other
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
before :each do
|
29
|
+
subject.inherit_from parent
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#global' do
|
33
|
+
it 'sets a global value' do
|
34
|
+
subject.global[:some_thing] = :foo_bar
|
35
|
+
expect(subject.global[:some_thing]).to eq :foo_bar
|
36
|
+
subject.global[:some_thing] = :foo_bar_next
|
37
|
+
expect(subject.global[:some_thing]).to eq :foo_bar_next
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'sets the global inherited values' do
|
41
|
+
expect(subject.global[:global_thing]).to eq :global_foo_bar
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'overrides global values' do
|
45
|
+
subject.global[:global_thing] = :global_new_foo_bar
|
46
|
+
expect(parent.global[:global_thing]).to eq :global_new_foo_bar
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should handle different parents' do
|
50
|
+
subject.global[:global_thing] = :global_new_foo_bar
|
51
|
+
|
52
|
+
subject.inherit_from other_parent
|
53
|
+
|
54
|
+
expect(parent.global[:global_thing]).to eq :global_new_foo_bar
|
55
|
+
expect(other_parent.global[:global_thing]).to eq :global_new_foo_bar
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#api_class' do
|
60
|
+
it 'is specific to the class' do
|
61
|
+
subject.api_class[:some_thing] = :foo_bar
|
62
|
+
parent.api_class[:some_thing] = :some_thing
|
63
|
+
|
64
|
+
expect(subject.api_class[:some_thing]).to eq :foo_bar
|
65
|
+
expect(parent.api_class[:some_thing]).to eq :some_thing
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#namespace' do
|
70
|
+
it 'sets a value until the end of a namespace' do
|
71
|
+
subject.namespace[:some_thing] = :foo_bar
|
72
|
+
expect(subject.namespace[:some_thing]).to eq :foo_bar
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'uses new values when a new namespace starts' do
|
76
|
+
subject.namespace[:namespace_thing] = :new_namespace_foo_bar
|
77
|
+
expect(subject.namespace[:namespace_thing]).to eq :new_namespace_foo_bar
|
78
|
+
|
79
|
+
expect(parent.namespace[:namespace_thing]).to eq :namespace_foo_bar
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#namespace_inheritable' do
|
84
|
+
it 'works with inheritable values' do
|
85
|
+
expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should handle different parents' do
|
89
|
+
expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar
|
90
|
+
|
91
|
+
subject.inherit_from other_parent
|
92
|
+
|
93
|
+
expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar_other
|
94
|
+
|
95
|
+
subject.inherit_from parent
|
96
|
+
|
97
|
+
expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar
|
98
|
+
|
99
|
+
subject.inherit_from other_parent
|
100
|
+
|
101
|
+
subject.namespace_inheritable[:namespace_inheritable_thing] = :my_thing
|
102
|
+
|
103
|
+
expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_thing
|
104
|
+
|
105
|
+
subject.inherit_from parent
|
106
|
+
|
107
|
+
expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_thing
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#namespace_stackable' do
|
112
|
+
it 'works with stackable values' do
|
113
|
+
expect(subject.namespace_stackable[:namespace_stackable_thing]).to eq [:namespace_stackable_foo_bar]
|
114
|
+
|
115
|
+
subject.inherit_from other_parent
|
116
|
+
|
117
|
+
expect(subject.namespace_stackable[:namespace_stackable_thing]).to eq [:namespace_stackable_foo_bar_other]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe '#route' do
|
122
|
+
it 'sets a value until the next route' do
|
123
|
+
subject.route[:some_thing] = :foo_bar
|
124
|
+
expect(subject.route[:some_thing]).to eq :foo_bar
|
125
|
+
|
126
|
+
subject.route_end
|
127
|
+
|
128
|
+
expect(subject.route[:some_thing]).to be_nil
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'works with route values' do
|
132
|
+
expect(subject.route[:route_thing]).to eq :route_foo_bar
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe '#api_class' do
|
137
|
+
it 'is specific to the class' do
|
138
|
+
subject.api_class[:some_thing] = :foo_bar
|
139
|
+
expect(subject.api_class[:some_thing]).to eq :foo_bar
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#inherit_from' do
|
144
|
+
it 'notifies clones' do
|
145
|
+
new_settings = subject.point_in_time_copy
|
146
|
+
expect(new_settings).to receive(:inherit_from).with(other_parent)
|
147
|
+
|
148
|
+
subject.inherit_from other_parent
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe '#point_in_time_copy' do
|
153
|
+
let!(:cloned_obj) { subject.point_in_time_copy }
|
154
|
+
|
155
|
+
it 'resets point_in_time_copies' do
|
156
|
+
expect(cloned_obj.point_in_time_copies).to be_empty
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'decouples namespace values' do
|
160
|
+
subject.namespace[:namespace_thing] = :namespace_foo_bar
|
161
|
+
|
162
|
+
cloned_obj.namespace[:namespace_thing] = :new_namespace_foo_bar
|
163
|
+
expect(subject.namespace[:namespace_thing]).to eq :namespace_foo_bar
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'decouples namespace inheritable values' do
|
167
|
+
expect(cloned_obj.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar
|
168
|
+
|
169
|
+
subject.namespace_inheritable[:namespace_inheritable_thing] = :my_thing
|
170
|
+
expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_thing
|
171
|
+
|
172
|
+
expect(cloned_obj.namespace_inheritable[:namespace_inheritable_thing]).to eq :namespace_inheritable_foo_bar
|
173
|
+
|
174
|
+
cloned_obj.namespace_inheritable[:namespace_inheritable_thing] = :my_cloned_thing
|
175
|
+
expect(cloned_obj.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_cloned_thing
|
176
|
+
expect(subject.namespace_inheritable[:namespace_inheritable_thing]).to eq :my_thing
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'decouples namespace stackable values' do
|
180
|
+
expect(cloned_obj.namespace_stackable[:namespace_stackable_thing]).to eq [:namespace_stackable_foo_bar]
|
181
|
+
|
182
|
+
subject.namespace_stackable[:namespace_stackable_thing] = :other_thing
|
183
|
+
expect(subject.namespace_stackable[:namespace_stackable_thing]).to eq [:namespace_stackable_foo_bar, :other_thing]
|
184
|
+
expect(cloned_obj.namespace_stackable[:namespace_stackable_thing]).to eq [:namespace_stackable_foo_bar]
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'decouples route values' do
|
188
|
+
expect(cloned_obj.route[:route_thing]).to eq :route_foo_bar
|
189
|
+
|
190
|
+
subject.route[:route_thing] = :new_route_foo_bar
|
191
|
+
expect(cloned_obj.route[:route_thing]).to eq :route_foo_bar
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'adds itself to original as clone' do
|
195
|
+
expect(subject.point_in_time_copies).to include(cloned_obj)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe '#to_hash' do
|
200
|
+
it 'return all settings as a hash' do
|
201
|
+
subject.global[:global_thing] = :global_foo_bar
|
202
|
+
subject.namespace[:namespace_thing] = :namespace_foo_bar
|
203
|
+
subject.namespace_inheritable[:namespace_inheritable_thing] = :namespace_inheritable_foo_bar
|
204
|
+
subject.namespace_stackable[:namespace_stackable_thing] = [:namespace_stackable_foo_bar]
|
205
|
+
subject.route[:route_thing] = :route_foo_bar
|
206
|
+
|
207
|
+
expect(subject.to_hash).to include(global: { global_thing: :global_foo_bar })
|
208
|
+
expect(subject.to_hash).to include(namespace: { namespace_thing: :namespace_foo_bar })
|
209
|
+
expect(subject.to_hash).to include(namespace_inheritable: {
|
210
|
+
namespace_inheritable_thing: :namespace_inheritable_foo_bar })
|
211
|
+
expect(subject.to_hash).to include(namespace_stackable: { namespace_stackable_thing: [:namespace_stackable_foo_bar, [:namespace_stackable_foo_bar]] })
|
212
|
+
expect(subject.to_hash).to include(route: { route_thing: :route_foo_bar })
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|