Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
bwillis committed Oct 30, 2013
1 parent 5a652eb commit acb6f76
Show file tree
Hide file tree
Showing 19 changed files with 112 additions and 29 deletions.
37 changes: 32 additions & 5 deletions lib/versioncake/configuration.rb
Expand Up @@ -5,6 +5,7 @@ module VersionCake
module Configuration

SUPPORTED_VERSIONS_DEFAULT = (1..10)
VERSION_FORMATS = [:numeric, :date]

mattr_reader :supported_version_numbers

Expand All @@ -14,6 +15,9 @@ module Configuration
mattr_accessor :default_version
self.default_version = nil

mattr_accessor :version_format
self.version_format = :numeric

def self.extraction_strategy=(val)
@@extraction_strategies.clear
Array.wrap(val).each do |configured_strategy|
Expand All @@ -26,16 +30,39 @@ def self.supported_version_numbers=(val)
@@supported_version_numbers.sort!.reverse!
end

def self.version_format=(val)
raise Exception, "Invalid version format, acceptable values are #{VERSION_FORMATS.join(", ")}" unless VERSION_FORMATS.include?(val)
@@version_format = val
end

def self.format_version(val)
puts "formatting version number #{val} to format #{@@version_format}"
case @@version_format
when :numeric
val.to_i if val && /[0-9]+/.match(val)
when :date
Date.strptime(val, "%Y-%m-%d") rescue nil
end
end

def self.supported_versions(requested_version_number=nil)
supported_version_numbers.collect do |supported_version_number|
if requested_version_number.nil? || supported_version_number <= requested_version_number
:"v#{supported_version_number}"
end
if requested_version_number
versions = supported_version_numbers.dup
versions.push(requested_version_number)
versions.uniq!.sort!.reverse!
version_list = versions[versions.index(requested_version_number)..versions.length]
else
version_list = supported_version_numbers
end

version_list.collect { |v| :"v#{v}" }
end

def self.supports_version?(version)
supported_version_numbers.include? version
puts "supports_version?(#{version}) in #{supported_version_numbers.join(",")}"
a = supported_version_numbers.include? version
puts "supported? #{a}"
a
end

def self.latest_version
Expand Down
4 changes: 4 additions & 0 deletions lib/versioncake/railtie.rb
Expand Up @@ -18,6 +18,10 @@ class ActionViewVersions < Rails::Railtie
if app.config.respond_to?(:default_version)
VersionCake::Configuration.default_version = app.config.default_version
end

if app.config.respond_to?(:view_version_format)
VersionCake::Configuration.version_version_format = app.config.version_version_format
end
end
end
end
3 changes: 1 addition & 2 deletions lib/versioncake/strategies/extraction_strategy.rb
Expand Up @@ -8,8 +8,7 @@ class ExtractionStrategy
@@version_string = 'api_version'

def extract(request)
version = execute(request)
return version.to_i if version && /[0-9]+/.match(version)
execute(request)
end

def execute(request)
Expand Down
Expand Up @@ -3,7 +3,7 @@ class HttpAcceptParameterStrategy < ExtractionStrategy

def execute(request)
if request.headers.key?("HTTP_ACCEPT") &&
match = request.headers["HTTP_ACCEPT"].match(/#{@@version_string}=([0-9]+)/)
match = request.headers["HTTP_ACCEPT"].match(/#{@@version_string}=([0-9\-]+)/)
match[1]
end
end
Expand Down
26 changes: 19 additions & 7 deletions lib/versioncake/versioned_request.rb
Expand Up @@ -4,35 +4,47 @@ class VersionedRequest

def initialize(request, version_override=nil)
@version = version_override || extract_version(request)
@is_latest_version = @version == VersionCake::Configuration.latest_version
@is_latest_version = @version == config.latest_version
end

def supported_versions
VersionCake::Configuration.supported_versions(@version)
config.supported_versions(@version)
end

private

def apply_strategies(request)
version = nil
VersionCake::Configuration.extraction_strategies.each do |strategy|
puts config.extraction_strategies
config.extraction_strategies.each do |strategy|
version = strategy.extract(request)
puts "strategy #{strategy} version: #{version.class}"
break unless version.nil?
end
version
version ? config.format_version(version) : nil
end

def extract_version(request)
@extracted_version = apply_strategies(request)
puts "extracted version #{@extracted_version}, class #{@extracted_version.class}"
puts "latest version: #{config.latest_version.class}"
if @extracted_version.nil?
@version = VersionCake::Configuration.default_version || VersionCake::Configuration.latest_version
elsif VersionCake::Configuration.supports_version? @extracted_version
puts "using default version"
@version = config.default_version || config.latest_version
elsif config.supports_version? @extracted_version
puts "version is supported"
@version = @extracted_version
elsif @extracted_version > VersionCake::Configuration.latest_version
elsif @extracted_version > config.latest_version
puts "version is too large"
raise ActionController::RoutingError.new("No route match for version")
else
puts "version is deprecated"
raise ActionController::RoutingError.new("Version is deprecated")
end
end

def config
VersionCake::Configuration
end
end
end
2 changes: 1 addition & 1 deletion lib/versioncake/view_additions.rb
Expand Up @@ -22,7 +22,7 @@
# the identifier method name filters out numbers,
# but we want to preserve them for v1 etc.
def identifier_method_name #:nodoc:
inspect.gsub(/[^a-z0-9_]/, '_')
inspect.gsub(/[^a-z0-9_\-]/, '_')
end

end
10 changes: 10 additions & 0 deletions test/app/controllers/renders_date_controller.rb
@@ -0,0 +1,10 @@
require "action_controller"
require "action_controller/base"

class RendersDateController < ActionController::Base
def index
if params[:override_version]
set_version(params[:override_version].to_i)
end
end
end
1 change: 1 addition & 0 deletions test/app/views/renders_date/index.html.v2013-01-01.erb
@@ -0,0 +1 @@
template v2013-01-01
1 change: 1 addition & 0 deletions test/app/views/renders_date/index.html.v2013-05-01.erb
@@ -0,0 +1 @@
template v2013-05-01
1 change: 1 addition & 0 deletions test/app/views/renders_date/index.html.v2013-09-01.erb
@@ -0,0 +1 @@
template v2013-09-01
1 change: 1 addition & 0 deletions test/config/routes.rb
@@ -1,3 +1,4 @@
RendersTest::Application.routes.draw do
resources :renders
resources :renders_date
end
34 changes: 34 additions & 0 deletions test/functional/renders_date_controller_test.rb
@@ -0,0 +1,34 @@
require './test/test_helper'
require 'action_controller'
require 'action_controller/test_case'

class RendersDateControllerTest < ActionController::TestCase

setup do
@previous_supported_version_numbers = VersionCake::Configuration.supported_version_numbers
@previous_version_format = VersionCake::Configuration.version_format
VersionCake::Configuration.supported_version_numbers = [Date.parse("2013-01-01"), Date.parse("2013-05-01"), Date.parse("2013-09-01")]
VersionCake::Configuration.version_format = :date
VersionCake::Configuration.extraction_strategy = :query_parameter
end

teardown do
VersionCake::Configuration.supported_version_numbers = @previous_supported_version_numbers
VersionCake::Configuration.version_format = @previous_version_format
end

test "render latest version of partial" do
get :index
assert_equal "template v2013-09-01", @response.body
end

test "requesting version retrieves the matching version" do
get :index, "api_version" => "2013-01-01"
assert_equal "template v2013-01-01", @response.body
end

test "requesting version retrieves the closest previous version" do
get :index, "api_version" => "2013-06-01"
assert_equal "template v2013-05-01", @response.body
end
end
2 changes: 1 addition & 1 deletion test/functional/strategy_controller_test.rb
Expand Up @@ -31,7 +31,7 @@ def custom_message(headers, params, method, response)
data = []
data << "headers:#{headers}" if headers
data << "params:#{params}" if params
"Expected #{data.join(",")} with method #{method} to yield #{response}"
"Expected #{method} request with #{data.join(",")} to yield #{response}"
end

end
7 changes: 0 additions & 7 deletions test/unit/strategies/extraction_strategy_test.rb
Expand Up @@ -7,13 +7,6 @@ class ExtractionStrategyTest < ActiveSupport::TestCase
end
end

test "extract will convert the the result to integer" do
class TestStrategy < VersionCake::ExtractionStrategy
def execute(request); "123"; end
end
assert_equal 123, TestStrategy.new.extract("request")
end

test "it can lookup a strategy" do
strategy = VersionCake::ExtractionStrategy.lookup(:query_parameter)
assert_equal VersionCake::QueryParameterStrategy, strategy.class
Expand Down
Expand Up @@ -7,7 +7,7 @@ class HttpAcceptParameterStrategyTest < ActiveSupport::TestCase

test "a request with an HTTP_ACCEPT version retrieves the version" do
request = stub(:headers => {'HTTP_ACCEPT' => 'application/xml; api_version=11'})
assert_equal 11, @strategy.extract(request)
assert_equal "11", @strategy.extract(request)
end

test "a request without an HTTP_ACCEPT version returns nil" do
Expand Down
2 changes: 1 addition & 1 deletion test/unit/strategies/http_header_strategy_test.rb
Expand Up @@ -7,7 +7,7 @@ class HttpHeaderStrategyTest < ActiveSupport::TestCase

test "a request with an HTTP_X_API_VERSION retrieves the version" do
request = stub(:headers => {'HTTP_X_API_VERSION' => '11'})
assert_equal 11, @strategy.extract(request)
assert_equal '11', @strategy.extract(request)
end

test "a request without an HTTP_X_API_VERSION returns nil" do
Expand Down
2 changes: 1 addition & 1 deletion test/unit/strategies/path_parameter_strategy_test.rb
Expand Up @@ -7,7 +7,7 @@ class PathParameterStrategyTest < ActiveSupport::TestCase

test "a request with an api_version path parameter retrieves the version" do
request = stub(:path_parameters => {:api_version => '11', :other => 'parameter'})
assert_equal 11, @strategy.extract(request)
assert_equal "11", @strategy.extract(request)
end

test "a request without an api_version path parameter returns nil" do
Expand Down
2 changes: 1 addition & 1 deletion test/unit/strategies/query_parameter_strategy_test.rb
Expand Up @@ -7,7 +7,7 @@ class QueryParameterStrategyTest < ActiveSupport::TestCase

test "a request with an api_version parameter retrieves the version" do
request = stub(:query_parameters => {:api_version => '11', :other => 'parameter'})
assert_equal 11, @strategy.extract(request)
assert_equal '11', @strategy.extract(request)
end

test "a request without an api_version parameter returns nil" do
Expand Down
2 changes: 1 addition & 1 deletion test/unit/strategies/request_parameter_strategy_test.rb
Expand Up @@ -7,7 +7,7 @@ class RequestParameterStrategyTest < ActiveSupport::TestCase

test "a request with an api_version request parameter retrieves the version" do
request = stub(:request_parameters => {:api_version => '11', :other => 'parameter'})
assert_equal 11, @strategy.extract(request)
assert_equal '11', @strategy.extract(request)
end

test "a request without an api_version request parameter returns nil" do
Expand Down

0 comments on commit acb6f76

Please sign in to comment.