versioncake 0.5.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
![Version Cake](https://raw.github.com/alicial/versioncake/master/images/versioncake-logo450x100.png)
|
2
2
|
|
3
3
|
[![Build Status](https://secure.travis-ci.org/bwillis/versioncake.png?branch=master)](http://travis-ci.org/bwillis/versioncake)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/bwillis/versioncake.png)](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.
|