versioncake 0.5.0 → 1.0.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.
- data/Gemfile.lock +1 -1
- data/README.md +50 -1
- data/lib/versioncake/action_view/versions.rb +31 -30
- data/lib/versioncake/version.rb +1 -1
- data/test/functional/renders_controller_test.rb +17 -5
- data/test/template/render_test.rb +1 -1
- metadata +3 -3
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|

|
2
2
|
|
3
3
|
[](http://travis-ci.org/bwillis/versioncake)
|
4
|
+
[](https://codeclimate.com/github/bwillis/versioncake)
|
4
5
|
|
5
6
|
Co-authored by Ben Willis ([@bwillis](https://github.com/bwillis/)) and Jim Jones ([@aantix](https://github.com/aantix)).
|
6
7
|
|
@@ -170,6 +171,7 @@ config.view_version_extraction_strategy = :query_parameter # [:http_header, :htt
|
|
170
171
|
```
|
171
172
|
These are the available strategies:
|
172
173
|
- **query_parameter**: version in the url query parameter, for testing or to override for special case i.e. ```http://localhost:3000/posts.json?api_version=1``` (This is the default.)
|
174
|
+
- **request_parameter**: version that is sent in the body of the request. Good for testing.
|
173
175
|
- **http_header**: Api version HTTP header ie. ```X-API-Version: 1```
|
174
176
|
- **http_accept_parameter**: HTTP Accept header ie. ```Accept: application/xml; version=1``` [why do this?](http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http#i_want_my_api_to_be_versioned)
|
175
177
|
- **custom**: `lambda {|request| request.headers["HTTP_X_MY_VERSION"].to_i }` takes the request object and must return an integer
|
@@ -215,6 +217,53 @@ end
|
|
215
217
|
|
216
218
|
When a client makes a request it will automatically receive the latest supported version of the view. The client can also request for a specific version by one of the strategies configured by ``view_version_extraction_strategy``.
|
217
219
|
|
220
|
+
## How to test
|
221
|
+
|
222
|
+
Testing can be painful but here are some easy ways to test different versions of your api using version cake.
|
223
|
+
|
224
|
+
### Test configuration
|
225
|
+
|
226
|
+
Allowing more extraction strategies during testing can be helpful when needing to override the version.
|
227
|
+
```ruby
|
228
|
+
# config/environments/test.rb
|
229
|
+
config.view_version_extraction_strategy = [:query_parameter, :request_parameter, :http_header, :http_accept_parameter]
|
230
|
+
```
|
231
|
+
|
232
|
+
### Testing a specific version
|
233
|
+
|
234
|
+
One way to test a specific version for would be to stub the requested version in the before block:
|
235
|
+
```ruby
|
236
|
+
before do
|
237
|
+
@controller.stubs(:requested_version).returns(3)
|
238
|
+
end
|
239
|
+
```
|
240
|
+
|
241
|
+
You can also test a specific version through a specific strategy such query_parameter or request_parameter strategies (configured in test environment) like so:
|
242
|
+
```ruby
|
243
|
+
# test/functional/renders_controller_test.rb#L47
|
244
|
+
test "render version 1 of the partial based on the parameter _api_version" do
|
245
|
+
get :index, "api_version" => "1"
|
246
|
+
assert_equal @response.body, "index.v1.html.erb"
|
247
|
+
end
|
248
|
+
```
|
249
|
+
|
250
|
+
### Testing all supported versions
|
251
|
+
|
252
|
+
You can iterate over all of the supported version numbers by accessing the ```AppName::Application.config.view_versions```.
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
AppName::Application.config.view_versions.each do |supported_version|
|
256
|
+
before do
|
257
|
+
@controller.stubs(:requested_version).returns(supported_version)
|
258
|
+
end
|
259
|
+
|
260
|
+
test "all versions render the correct template" do
|
261
|
+
get :index
|
262
|
+
assert_equal @response.body, "index.v1.html.erb"
|
263
|
+
end
|
264
|
+
end
|
265
|
+
```
|
266
|
+
|
218
267
|
# Related Material
|
219
268
|
|
220
269
|
## Usages
|
@@ -231,7 +280,7 @@ When a client makes a request it will automatically receive the latest supported
|
|
231
280
|
## Discussions
|
232
281
|
|
233
282
|
- [Steve Klabnik on how to version in a resful way](http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http#i_want_my_api_to_be_versioned)
|
234
|
-
- [Rails API project disucssion on versioning](https://github.com/
|
283
|
+
- [Rails API project disucssion on versioning](https://github.com/rails-api/rails-api/issues/8)
|
235
284
|
- [Railscast on versioning](http://railscasts.com/episodes/350-rest-api-versioning)
|
236
285
|
- [Ruby5 on versioncake](http://ruby5.envylabs.com/episodes/310-episode-306-september-18th-2012/stories/2704-version-cake)
|
237
286
|
- [Rails core discussion](https://groups.google.com/forum/#!msg/rubyonrails-core/odwmEYYIum0/9POep66BvoMJ)
|
@@ -13,38 +13,39 @@ module ActionView
|
|
13
13
|
mattr_accessor :extraction_strategy
|
14
14
|
self.extraction_strategy = [:query_parameter]
|
15
15
|
|
16
|
-
EXTRACTION_STRATEGIES = {
|
17
|
-
:query_parameter => lambda { |request|
|
18
|
-
if request.query_parameters.has_key? @@version_string.to_sym
|
19
|
-
request.query_parameters[@@version_string.to_sym].to_i
|
20
|
-
end
|
21
|
-
},
|
22
|
-
:http_header => lambda { |request|
|
23
|
-
if request.headers.has_key? "HTTP_X_#{@@version_string.upcase}"
|
24
|
-
request.headers["HTTP_X_#{@@version_string.upcase}"].to_i
|
25
|
-
end
|
26
|
-
},
|
27
|
-
:http_accept_parameter => lambda { |request|
|
28
|
-
if request.headers.has_key?("HTTP_ACCEPT") &&
|
29
|
-
match = request.headers["HTTP_ACCEPT"].match(%{#{@@version_string}=([0-9])})
|
30
|
-
match[1].to_i
|
31
|
-
end
|
32
|
-
}
|
33
|
-
}
|
34
|
-
|
35
16
|
def self.extract_version(request)
|
36
17
|
version = nil
|
37
18
|
extraction_strategy.each do |strategy|
|
38
|
-
version =
|
19
|
+
version = apply_strategy(request, strategy)
|
20
|
+
break unless version.nil?
|
21
|
+
end
|
22
|
+
version
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.apply_strategy(request, strategy)
|
26
|
+
case strategy
|
27
|
+
when Proc
|
39
28
|
strategy.call(request)
|
40
|
-
|
41
|
-
|
29
|
+
when :http_accept_parameter
|
30
|
+
if request.headers.has_key?("HTTP_ACCEPT") &&
|
31
|
+
match = request.headers["HTTP_ACCEPT"].match(%{#{@@version_string}=([0-9])})
|
32
|
+
match[1].to_i
|
33
|
+
end
|
34
|
+
when :http_header
|
35
|
+
if request.headers.has_key? "HTTP_X_#{@@version_string.upcase}"
|
36
|
+
request.headers["HTTP_X_#{@@version_string.upcase}"].to_i
|
37
|
+
end
|
38
|
+
when :query_parameter
|
39
|
+
if request.query_parameters.has_key? @@version_string.to_sym
|
40
|
+
request.query_parameters[@@version_string.to_sym].to_i
|
41
|
+
end
|
42
|
+
when :request_parameter
|
43
|
+
if request.request_parameters.has_key? @@version_string.to_sym
|
44
|
+
request.request_parameters[@@version_string.to_sym].to_i
|
45
|
+
end
|
42
46
|
else
|
43
47
|
raise "Unknown extraction strategy #{strategy}"
|
44
|
-
end
|
45
|
-
break unless version.nil?
|
46
48
|
end
|
47
|
-
version
|
48
49
|
end
|
49
50
|
|
50
51
|
def self.extraction_strategy=(val)
|
@@ -59,11 +60,11 @@ module ActionView
|
|
59
60
|
def self.supported_version_numbers=(val)
|
60
61
|
case val
|
61
62
|
when Range
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
@@supported_version_numbers = val.to_a
|
64
|
+
when Array
|
65
|
+
@@supported_version_numbers = val
|
66
|
+
else
|
67
|
+
@@supported_version_numbers = Array.wrap(val)
|
67
68
|
end
|
68
69
|
@@supported_version_numbers.sort!.reverse!
|
69
70
|
end
|
data/lib/versioncake/version.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
require
|
4
|
-
require "action_controller/test_case"
|
1
|
+
require './test/test_helper'
|
2
|
+
require 'action_controller'
|
3
|
+
require 'action_controller/test_case'
|
5
4
|
|
6
5
|
class RendersControllerTest < ActionController::TestCase
|
7
6
|
|
@@ -94,6 +93,19 @@ tests RendersController
|
|
94
93
|
end
|
95
94
|
end
|
96
95
|
|
96
|
+
class RequestBodyStrategyTest < ActionController::TestCase
|
97
|
+
tests RendersController
|
98
|
+
|
99
|
+
setup do
|
100
|
+
ActionView::Template::Versions.extraction_strategy = :request_parameter
|
101
|
+
end
|
102
|
+
|
103
|
+
test "requested version is in the body" do
|
104
|
+
post :index, "api_version" => "2"
|
105
|
+
assert_equal 2, @controller.requested_version
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
97
109
|
class AcceptHeaderStrategyTest < ActionController::TestCase
|
98
110
|
tests RendersController
|
99
111
|
|
@@ -183,4 +195,4 @@ class UnsupportedVersionTest < ActionController::TestCase
|
|
183
195
|
get :index, "api_version" => "1"
|
184
196
|
end
|
185
197
|
end
|
186
|
-
end
|
198
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: versioncake
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-03-14 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: actionpack
|
@@ -160,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
160
|
version: '0'
|
161
161
|
requirements: []
|
162
162
|
rubyforge_project:
|
163
|
-
rubygems_version: 1.8.
|
163
|
+
rubygems_version: 1.8.19
|
164
164
|
signing_key:
|
165
165
|
specification_version: 3
|
166
166
|
summary: Easily render versions of your rails views.
|