Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Adding documentation to new api generator

Adding rack middleware
More tests
  • Loading branch information...
commit cb187bc5842b8aa5b4a9a5d6ff0701e561206ea8 1 parent 1baeab7
Brian Ploetz authored
Showing with 464 additions and 203 deletions.
  1. +2 −0  Gemfile.lock
  2. +2 −2 lib/versionist.rb
  3. +3 −24 lib/versionist/configuration.rb
  4. +3 −0  lib/versionist/generators/new_api_version/new_api_version_generator.rb
  5. +10 −0 lib/versionist/generators/new_api_version/templates/docs_index.rb
  6. +1 −0  lib/versionist/generators/new_api_version/templates/docs_style.rb
  7. +35 −0 lib/versionist/middleware.rb
  8. +5 −15 lib/versionist/railtie.rb
  9. +32 −5 lib/versionist/routing.rb
  10. +10 −3 lib/versionist/versioning_strategy.rb
  11. +6 −5 lib/versionist/versioning_strategy/base.rb
  12. +11 −20 lib/versionist/versioning_strategy/header.rb
  13. +23 −0 lib/versionist/versioning_strategy/parameter.rb
  14. +22 −0 lib/versionist/versioning_strategy/path.rb
  15. +0 −17 lib/versionist/versioning_strategy/url.rb
  16. +140 −46 spec/api_routing_spec.rb
  17. +11 −39 spec/configuration_spec.rb
  18. +29 −0 spec/generators/new_api_version_generator_spec.rb
  19. +0 −15 spec/header_versioning_strategy_spec.rb
  20. +39 −0 spec/middleware_spec.rb
  21. +1 −0  spec/spec_helper.rb
  22. +6 −0 spec/test-api/app/controllers/application_controller.rb
  23. +1 −1  spec/test-api/app/controllers/v1/foos_controller.rb
  24. +3 −5 spec/test-api/app/controllers/v2.1/foos_controller.rb
  25. +3 −5 spec/test-api/app/controllers/v2/foos_controller.rb
  26. +4 −1 spec/test-api/config/application.rb
  27. +22 −0 spec/versioning_strategy/base_spec.rb
  28. +15 −0 spec/versioning_strategy/header_spec.rb
  29. +15 −0 spec/versioning_strategy/parameter_spec.rb
  30. +9 −0 spec/versioning_strategy/path_spec.rb
  31. +1 −0  versionist.gemspec
2  Gemfile.lock
View
@@ -36,6 +36,7 @@ GEM
activesupport (3.1.3)
multi_json (~> 1.0)
arel (2.2.1)
+ awesome_print (1.0.2)
builder (3.0.0)
diff-lcs (1.1.3)
erubis (2.7.0)
@@ -111,6 +112,7 @@ PLATFORMS
ruby
DEPENDENCIES
+ awesome_print (= 1.0.2)
generator_spec (= 0.8.4)
rails (~> 3.0)
rake (>= 0.9.2)
4 lib/versionist.rb
View
@@ -1,6 +1,5 @@
require 'versionist/railtie' if defined?(Rails) && Rails::VERSION::MAJOR == 3
-
-require 'active_support'
+require 'active_support/dependencies/autoload'
module Versionist
extend ActiveSupport::Autoload
@@ -10,6 +9,7 @@ module Versionist
autoload :NewControllerGenerator, "versionist/generators/new_controller/new_controller_generator"
autoload :NewPresenterGenerator, "versionist/generators/new_presenter/new_presenter_generator"
autoload :VersioningStrategy, "versionist/versioning_strategy"
+ autoload :Middleware
autoload :Routing
def self.configuration
27 lib/versionist/configuration.rb
View
@@ -1,30 +1,9 @@
-require 'active_model/validations'
-
module Versionist
class Configuration
- include ActiveModel::Validations
- include ActiveModel::Validations::HelperMethods
-
- attr_accessor :versioning_strategy_name
- validates_inclusion_of :versioning_strategy_name, :in => %W( header url )
- attr_accessor :versioning_config
- attr_accessor :default_version
+ attr_accessor :versioning_strategies
- def versioning_strategy=(args)
- if args.is_a?(Array)
- name = args[0]
- raise ArgumentError, "First argument to versioning_strategy= must be a string specifying the versioning_strategy name" if !name.is_a?(String)
- @versioning_strategy_name = name
- if args.length > 1
- config = args[1]
- raise ArgumentError, "Second argument to versioning_strategy= must be a hash specifying the versioning_strategy config" if !config.is_a?(Hash)
- @versioning_config = config
- end
- else
- name = args
- raise ArgumentError, "First argument to versioning_strategy= must be a string specifying the versioning_strategy name" if !name.is_a?(String)
- @versioning_strategy_name = name
- end
+ def initialize
+ @versioning_strategies ||= Array.new
end
end
end
3  lib/versionist/generators/new_api_version/new_api_version_generator.rb
View
@@ -6,6 +6,9 @@ def new_api_version
empty_directory "app/controllers/#{file_name}"
template 'base_controller.rb', File.join("app", "controllers", "#{file_name}", "base_controller.rb")
empty_directory "app/presenters/#{file_name}"
+ empty_directory "public/docs/#{file_name}"
+ template 'docs_index.rb', File.join("public", "docs", "#{file_name}", "index.html")
+ template 'docs_style.rb', File.join("public", "docs", "#{file_name}", "style.css")
end
end
end
10 lib/versionist/generators/new_api_version/templates/docs_index.rb
View
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en-US">
+ <head>
+ <title>Documentation for <%= file_name%></title>
+ <link href="default.css" media="screen" rel="stylesheet" type="text/css">
+ </head>
+ <body>
+ <h1>Documentation for <%= file_name%></h1>
+ </body>
+</html>
1  lib/versionist/generators/new_api_version/templates/docs_style.rb
View
@@ -0,0 +1 @@
+body {background-color: #fff; color: #000;}
35 lib/versionist/middleware.rb
View
@@ -0,0 +1,35 @@
+module Versionist
+ # When your routes don't include an explicit format in the URL (i.e. `match 'foos.(:format)' => foos#index`),
+ # Rails inspects the `Accept` header to determine the requested format. Since an `Accept` header can have multiple values,
+ # Rails uses the first one present to determine the format. If your custom version header happens to be the first value
+ # in the `Accept` header, it would incorrectly be interpretted as the format. This middleware moves your custom version header
+ # to the end of the `Accept` header so as to not interfere with the format.
+ class Middleware
+
+ ACCEPT = "Accept"
+ HTTP_ACCEPT = "HTTP_ACCEPT"
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ request = ::Rack::Request.new(env)
+ strategy = Versionist.configuration.versioning_strategies.detect {|vs| vs.is_a?(Versionist::VersioningStrategy::Header) && vs.config[:header] == ACCEPT && env[HTTP_ACCEPT].include?(vs.config[:value])}
+ if !strategy.nil?
+ entries = env[HTTP_ACCEPT].split(',')
+ index = -1
+ entries.each_with_index do |e, i|
+ e.strip!
+ index = i if e == strategy.config[:value]
+ end
+ if (index != -1)
+ version = entries.delete_at(index)
+ entries << version
+ end
+ env[HTTP_ACCEPT] = entries.join(", ")
+ end
+ @app.call(env)
+ end
+ end
+end
20 lib/versionist/railtie.rb
View
@@ -5,21 +5,11 @@ class Railtie < Rails::Railtie
config.versionist = ActiveSupport::OrderedOptions.new
initializer 'versionist.configure' do |app|
- Versionist.configure do |config|
- config.versioning_strategy = 'header'
- if app.config.versionist.versioning_strategy
- config.versioning_strategy = app.config.versionist.versioning_strategy
- raise "Invalid value for config.versionist.versioning_strategy" if !config.valid?
-
- if config.versioning_strategy == 'header'
- if app.config.versionist.vendor_name
- config.vendor_name = app.config.versionist.vendor_name
- else
- raise "Must specify config.versionist.vendor_name if config.versionist.versioning_strategy is set to 'header'."
- end
- end
- end
- end
+ # Versionist.configure do |config|
+ # config.versioning_strategies = Array.new
+ # end
end
+
+ config.app_middleware.use Versionist::Middleware
end
end
37 lib/versionist/routing.rb
View
@@ -1,12 +1,39 @@
module Versionist
module Routing
- def api_version(version)
- if Versionist.configuration.versioning_strategy_name == Versionist::VersioningStrategy::Base::HEADER_STRATEGY
- return Versionist::VersioningStrategy::Header.new(version, Versionist.configuration.versioning_config)
- elsif Versionist.configuration.versioning_strategy_name == Versionist::VersioningStrategy::Base::URL_STRATEGY
- return Versionist::VersioningStrategy::Url.new(version, Versionist.configuration.versioning_config)
+ # Allows you to constrain routes to specific versions of your api using versioning strategies.
+ # Supported formats:
+ # api_version(:header => "Accept", :value => "application/vnd.mycompany.com-v1")
+ # api_version(:path => "/v2.3.4/")
+ # api_version(:parameter => "version", :value => "v20120317")
+ #
+ # Specifying default version:
+ # api_version(:header => "X-MY-HEADER", :value => "v3.0.0", :default => true)
+ def api_version(config)
+ raise ArgumentError, "you must pass a configuration Hash to api_version" if config.nil? || !config.is_a?(Hash)
+ raise ArgumentError, "you must specify :header, :path, or :parameter in configuration Hash passed to api_version" if !config.has_key?(:header) && !config.has_key?(:path) && !config.has_key?(:parameter)
+ if config.has_key?(:header)
+ return configure_header(config)
+ elsif config.has_key?(:path)
+ configure_path(config)
+ elsif config.has_key?(:parameter)
+ configure_parameter(config)
end
end
+
+
+ private
+
+ def configure_header(config)
+ return Versionist::VersioningStrategy::Header.new(config)
+ end
+
+ def configure_path(config)
+
+ end
+
+ def configure_parameter(config)
+ raise ArgumentError, "you must specify :value in the configuration Hash to api_version" if !config.has_key?(:value)
+ end
end
end
13 lib/versionist/versioning_strategy.rb
View
@@ -1,3 +1,10 @@
-require 'versionist/versioning_strategy/base'
-require 'versionist/versioning_strategy/header'
-require 'versionist/versioning_strategy/url'
+module Versionist
+ module VersioningStrategy
+ extend ActiveSupport::Autoload
+
+ autoload :Base, 'versionist/versioning_strategy/base'
+ autoload :Header, 'versionist/versioning_strategy/header'
+ autoload :Path, 'versionist/versioning_strategy/path'
+ autoload :Parameter, 'versionist/versioning_strategy/parameter'
+ end
+end
11 lib/versionist/versioning_strategy/base.rb
View
@@ -1,14 +1,15 @@
+require 'active_support/core_ext/hash/keys'
+
module Versionist
module VersioningStrategy
class Base
+ attr_reader :config
- HEADER_STRATEGY = "header"
- URL_STRATEGY = "url"
-
- def initialize(version, config={})
- @version = version
+ def initialize(config={})
+ raise ArgumentError, "you must pass a configuration Hash" if config.nil? || !config.is_a?(Hash)
@config = config
@config.symbolize_keys!
+ Versionist.configuration.versioning_strategies << self
end
end
end
31 lib/versionist/versioning_strategy/header.rb
View
@@ -1,31 +1,22 @@
-require 'erb'
-
module Versionist
module VersioningStrategy
- # Implements the header versioning strategy. Inspects the Accept header
- # to determine the requested version. Assumes the following format:
- # Accept: application/vnd.<vendor_name>-<version>+<format>
+ # Implements the header versioning strategy.
class Header < Base
- # Creates a new Header VersioningStrategy object.
- # The config hash must contain the following properties:
- # - header the header to inspect
- # - template the template of the header
- def initialize(version, config={})
+ # Creates a new Header VersioningStrategy object. config must contain the following keys:
+ # - :header the header to inspect
+ # - :value the value of the header specifying the version
+ def initialize(config)
+ raise ArgumentError, "you must specify :header in the configuration Hash" if !config.has_key?(:header)
+ raise ArgumentError, "you must specify :value in the configuration Hash" if !config.has_key?(:value)
super
- raise ArgumentError, "header must be specified for the header versioning_strategy" if !config.has_key?(:header)
- raise ArgumentError, "template must be specified for the header versioning_strategy" if !config.has_key?(:template)
- @erb_template = ERB.new(@config[:template], 0, "%<>")
end
def matches?(request)
- b = binding
- version = @version
- # TODO:
- format = "foobar"
- versioned_header_string = @erb_template.result(b)
- passed_header_string = request.headers[@config[:header]]
- return passed_header_string == versioned_header_string
+ #ap request.env
+ #ap request.accepts
+ #ap request.formats
+ return false
end
end
end
23 lib/versionist/versioning_strategy/parameter.rb
View
@@ -0,0 +1,23 @@
+module Versionist
+ module VersioningStrategy
+ # Implements the parameter versioning strategy.
+ class Parameter < Base
+
+ # Creates a new Parameter VersioningStrategy object. config must contain the following keys:
+ # - :parameter the parameter to inspect
+ # - :value the value of the parameter specifying the version
+ def initialize(config)
+ raise ArgumentError, "you must specify :parameter in the configuration Hash" if !config.has_key?(:parameter)
+ raise ArgumentError, "you must specify :value in the configuration Hash" if !config.has_key?(:value)
+ super
+ end
+
+ def matches?(request)
+ #ap request.env
+ #ap request.accepts
+ #ap request.formats
+ return false
+ end
+ end
+ end
+end
22 lib/versionist/versioning_strategy/path.rb
View
@@ -0,0 +1,22 @@
+module Versionist
+ module VersioningStrategy
+ # Implements the path versioning strategy. It expects the following path format:
+ # GET /<version>/...
+ class Path < Base
+
+ # Creates a new Path VersioningStrategy object. config must contain the following keys:
+ # - :path the path prefix containing the version
+ def initialize(config)
+ raise ArgumentError, "you must specify :path in the configuration Hash" if !config.has_key?(:path)
+ super
+ end
+
+ def matches?(request)
+ #ap request.env
+ #ap request.accepts
+ #ap request.formats
+ return false
+ end
+ end
+ end
+end
17 lib/versionist/versioning_strategy/url.rb
View
@@ -1,17 +0,0 @@
-module Versionist
- module VersioningStrategy
- # Implements the URL versioning strategy. It expects the following path format:
- # GET /<version>/...
- class Url < Base
-
- # Creates a new Url VersioningStrategy object.
- def initialize(version, config={})
- super
- end
-
- def matches?(request)
-
- end
- end
- end
-end
186 spec/api_routing_spec.rb
View
@@ -2,70 +2,164 @@
ENV["RAILS_ENV"] = 'test'
require File.expand_path("../test-api/config/application", __FILE__)
-TestApi::Application.initialize!
require 'rspec/rails'
describe Versionist::Routing do
include RSpec::Rails::RequestExampleGroup
- context "header strategy" do
- context "version" do
- before :each do
- Versionist.configure do |config|
- config.versioning_strategy = "header", {:header => "Accept", :template => "application/vnd.mycompany.com-<%=version%>"}
- config.default_version = "v1"
+ context "#api_version" do
+ it "should raise an error when config nil" do
+ lambda {
+ TestApi::Application.routes.draw do
+ scope :module => "v1", :constraints => api_version(nil)
end
+ }.should raise_error(ArgumentError, /you must pass a configuration Hash to api_version/)
+ end
+ it "should raise an error when config is not a Hash" do
+ lambda {
TestApi::Application.routes.draw do
- scope :module => "v1", :constraints => api_version("v1") do
- match '/foos.(:format)' => 'foos#index', :via => :get
- end
+ scope :module => "v1", :constraints => api_version(1)
end
- end
+ }.should raise_error(ArgumentError, /you must pass a configuration Hash to api_version/)
+ end
- it "should not route to the correct controller when header isn't present" do
- @headers ||= {}
- begin
- get "/foos.json", nil, @headers
- rescue => err
- print err.message
- print err.backtrace.join("\n")
+ it "should raise an error when config doesn't contain any supported strategies" do
+ lambda {
+ TestApi::Application.routes.draw do
+ scope :module => "v1", :constraints => api_version({})
end
- assert_response 404
- end
+ }.should raise_error(ArgumentError, /you must specify :header, :path, or :parameter in configuration Hash passed to api_version/)
+ end
- it "should route to the correct controller when the header doesn't match" do
- @headers ||= {}
- @headers["HTTP_ACCEPT"] = "application/vnd.mycompany.com-v3"
- begin
- get "/foos.json", nil, @headers
- rescue => err
- print err.message
- print err.backtrace.join("\n")
+ context ":header" do
+ it "should add the accept header middleware if the header is Accept" do
+ TestApi::Application.routes.draw do
+ scope :module => "v1", :constraints => api_version({:header => "Accept", :value => "application/vnd.mycompany.com-v1"}) do
+ match '/foos.(:format)' => 'foos#index', :via => :get
+ match '/foos_no_format' => 'foos#index', :via => :get
+ resources :bars
+ end
+ match '/foos(:format)' => 'foos#index', :via => :get
end
- assert_response 404
+ TestApi::Application.initialize!
+ TestApi::Application.config.middleware.should include(Versionist::Middleware)
end
+ end
- it "should route to the correct controller when header matches" do
- @headers ||= {}
- @headers["HTTP_ACCEPT"] = "application/vnd.mycompany.com-v1"
- begin
- get "/foos.json", nil, @headers
- rescue => err
- print err.message
- print err.backtrace.join("\n")
- end
- assert_response 200
- assert_equal 'application/json', response.content_type
- assert_equal "v1", response.body
- end
+ context ":path" do
end
- end
- context "url strategy" do
- it "should route to the correct controller" do
-
+ context ":parameter" do
end
+
+ # before :each do
+ # TestApi::Application.routes.draw do
+ # scope :module => "v1", :constraints => api_version(:version => "v1", :header => "Accept", :template => "application/vnd.mycompany.com-<%=version%>") do
+ # match '/foos.(:format)' => 'foos#index', :via => :get
+ # match '/foos_no_format' => 'foos#index', :via => :get
+ # resources :bars
+ # end
+ # match '*a', :to => 'application#not_found'
+ # end
+ # end
+ end
+
+ # context "header strategy" do
+ # context "Accept header" do
+ # before :each do
+ # Versionist.configure do |config|
+ # config.versioning_strategy = "header", {:header => "Accept", :template => "application/vnd.mycompany.com-<%=version%>"}
+ # config.default_version = "v1"
+ # end
+#
+ # TestApi::Application.routes.draw do
+ # scope :module => "v1", :constraints => api_version("v1") do
+ # match '/foos.(:format)' => 'foos#index', :via => :get
+ # match '/foos_no_format' => 'foos#index', :via => :get
+ # end
+ # match '*a', :to => 'application#not_found'
+ # end
+ # end
+#
+ # it "should not route when the configured header isn't present" do
+ # @headers ||= {}
+ # get "/foos.json", nil, @headers
+ # assert_response 404
+ # end
+#
+ # it "should not route when the header doesn't match" do
+ # @headers ||= {}
+ # @headers["HTTP_ACCEPT"] = "application/vnd.mycompany.com-v3"
+ # get "/foos.json", nil, @headers
+ # assert_response 404
+ # end
+#
+ # it "should route to the correct controller when header matches" do
+ # @headers ||= {}
+ # @headers["HTTP_ACCEPT"] = "application/vnd.mycompany.com-v1"
+ # get "/foos.json", nil, @headers
+ # assert_response 200
+ # assert_equal 'application/json', response.content_type
+ # assert_equal "v1", response.body
+ # end
+#
+ # it "should route to the correct controller when format specified via accept header" do
+ # @headers ||= {}
+ # @headers["HTTP_ACCEPT"] = "application/vnd.mycompany.com-v1,application/json"
+ # get "/foos_no_format", nil, @headers
+ # assert_response 200
+ # assert_equal 'application/json', response.content_type
+ # assert_equal "v1", response.body
+ # end
+ # end
+#
+ # context "custom header" do
+ # before :each do
+ # Versionist.configure do |config|
+ # config.versioning_strategy = "header", {:header => "X-MY-CUSTOM-HEADER", :template => "<%=version%>"}
+ # config.default_version = "v1"
+ # end
+#
+ # TestApi::Application.routes.draw do
+ # scope :module => "v1", :constraints => api_version("v1") do
+ # match '/foos.(:format)' => 'foos#index', :via => :get
+ # match '/foos_no_format' => 'foos#index', :via => :get
+ # end
+ # match '*a', :to => 'application#not_found'
+ # end
+ # end
+#
+ # it "should not route when the configured header isn't present" do
+ # @headers ||= {}
+ # get "/foos.json", nil, @headers
+ # assert_response 404
+ # end
+#
+ # it "should not route when the header doesn't match" do
+ # @headers ||= {}
+ # @headers["HTTP_X_MY_CUSTOM_HEADER"] = "v3"
+ # get "/foos.json", nil, @headers
+ # assert_response 404
+ # end
+#
+ # it "should route to the correct controller when header matches" do
+ # @headers ||= {}
+ # @headers["HTTP_X_MY_CUSTOM_HEADER"] = "v3"
+ # get "/foos.json", nil, @headers
+ # assert_response 200
+ # assert_equal 'application/json', response.content_type
+ # assert_equal "v3", response.body
+ # end
+ # end
+ # end
+
+ context "path strategy" do
+ it "should route to the correct controller"
+ end
+
+ context "query string strategy" do
+ it "should route to the correct controller"
end
end
50 spec/configuration_spec.rb
View
@@ -1,46 +1,18 @@
require 'spec_helper'
describe Versionist do
- context ".configure" do
- before :each do
- Versionist.configure do |config|
- config.versioning_strategy = "header", {:vendor_name => "mydomain.com"}
- config.default_version = "v1"
- end
- end
-
- it "should configure the versioning_strategy" do
- Versionist.configuration.versioning_strategy_name.should == "header"
- end
-
- it "should configure the vendor_name" do
- Versionist.configuration.versioning_config[:vendor_name].should == "mydomain.com"
- end
-
- it "should configure the default_version" do
- Versionist.configuration.default_version.should == "v1"
- end
-
- it "should validate versioning_strategy" do
- Versionist.configure do |config|
- config.versioning_strategy = "bogus"
- end
- Versionist.configuration.valid?.should == false
-
- Versionist.configure do |config|
- config.versioning_strategy = "bogus", {:vendor_name => "foo"}
- end
- Versionist.configuration.valid?.should == false
+ before :each do
+ Versionist.configuration.versioning_strategies.clear
+ end
- Versionist.configure do |config|
- config.versioning_strategy = "header"
- end
- Versionist.configuration.valid?.should == true
+ after :each do
+ Versionist.configuration.versioning_strategies.clear
+ end
- Versionist.configure do |config|
- config.versioning_strategy = "url"
- end
- Versionist.configuration.valid?.should == true
- end
+ it "should add versioning strategies" do
+ Versionist.configuration.versioning_strategies.should be_empty
+ Versionist::VersioningStrategy::Base.new({})
+ Versionist.configuration.versioning_strategies.should_not be_nil
+ Versionist.configuration.versioning_strategies.size.should == 1
end
end
29 spec/generators/new_api_version_generator_spec.rb
View
@@ -30,6 +30,31 @@ class V1::BaseController < ApplicationController
it "should create a namespaced presenters directory" do
assert_directory "app/presenters/v1"
end
+
+ it "should create a documentation directory" do
+ assert_directory "public/docs/v1"
+ end
+
+ it "should create a documentation index.html" do
+ assert_file "public/docs/v1/index.html", <<-CONTENTS
+<!DOCTYPE html>
+<html lang="en-US">
+ <head>
+ <title>Documentation for v1</title>
+ <link href="default.css" media="screen" rel="stylesheet" type="text/css">
+ </head>
+ <body>
+ <h1>Documentation for v1</h1>
+ </body>
+</html>
+ CONTENTS
+ end
+
+ it "should create a documentation style.css" do
+ assert_file "public/docs/v1/style.css", <<-CONTENTS
+body {background-color: #fff; color: #000;}
+ CONTENTS
+ end
end
context "special characters in version name" do
@@ -51,5 +76,9 @@ class V3_4_2::BaseController < ApplicationController
it "should create a namespaced presenters directory" do
assert_directory "app/presenters/v3.4.2"
end
+
+ it "should create a documentation directory" do
+ assert_directory "public/docs/v3.4.2"
+ end
end
end
15 spec/header_versioning_strategy_spec.rb
View
@@ -1,15 +0,0 @@
-require 'spec_helper'
-
-describe Versionist::VersioningStrategy::Header do
- it "should raise an ArgumentError if header is not specified" do
- lambda {
- Versionist::VersioningStrategy::Header.new("v1")
- }.should raise_error(ArgumentError, /header must be specified for the header versioning_strategy/)
- end
-
- it "should raise an ArgumentError if template is not specified" do
- lambda {
- Versionist::VersioningStrategy::Header.new("v1", {:header => "Accept"})
- }.should raise_error(ArgumentError, /template must be specified for the header versioning_strategy/)
- end
-end
39 spec/middleware_spec.rb
View
@@ -0,0 +1,39 @@
+require 'spec_helper'
+require 'rack/test'
+
+describe Versionist::Middleware do
+ before :all do
+ Versionist::VersioningStrategy::Header.new({:header => "Accept", :value => "application/vnd.mycompany.com-v2.3.0"})
+ @app = lambda {|env| [200, {"Content-Type" => "text/plain"}, [env["HTTP_ACCEPT"]]]}
+ end
+
+ after :all do
+ Versionist.configuration.versioning_strategies.clear
+ end
+
+ context "Accept header" do
+ it "should not alter the header if the version is not present" do
+ request = Rack::MockRequest.env_for("/foos", "HTTP_ACCEPT" => "application/json", :lint => true, :fatal => true)
+ status, headers, response = described_class.new(@app).call(request)
+ response[0].should == "application/json"
+ end
+
+ it "should not alter the header if an unconfigured version is present" do
+ request = Rack::MockRequest.env_for("/foos", "HTTP_ACCEPT" => "application/vnd.mycompany.com-v1,application/json", :lint => true, :fatal => true)
+ status, headers, response = described_class.new(@app).call(request)
+ response[0].should == "application/vnd.mycompany.com-v1,application/json"
+ end
+
+ it "should move the version to the end" do
+ request = Rack::MockRequest.env_for("/foos", "HTTP_ACCEPT" => "application/vnd.mycompany.com-v2.3.0,application/json", :lint => true, :fatal => true)
+ status, headers, response = described_class.new(@app).call(request)
+ response[0].should == "application/json, application/vnd.mycompany.com-v2.3.0"
+ end
+
+ it "should move the version to the end and retain accept params" do
+ request = Rack::MockRequest.env_for("/foos", "HTTP_ACCEPT" => "audio/*; q=0.2, audio/basic, application/vnd.mycompany.com-v2.3.0, application/json", :lint => true, :fatal => true)
+ status, headers, response = described_class.new(@app).call(request)
+ response[0].should == "audio/*; q=0.2, audio/basic, application/json, application/vnd.mycompany.com-v2.3.0"
+ end
+ end
+end
1  spec/spec_helper.rb
View
@@ -21,6 +21,7 @@
require 'versionist'
require 'fileutils'
+require 'ap'
RSpec.configure do |config|
config.mock_with :rspec
6 spec/test-api/app/controllers/application_controller.rb
View
@@ -0,0 +1,6 @@
+class ApplicationController < ActionController::Base
+ def not_found
+ # just silence it
+ head :not_found
+ end
+end
2  spec/test-api/app/controllers/v1/foos_controller.rb
View
@@ -1,4 +1,4 @@
-class V1::FoosController < ActionController::Base
+class V1::FoosController < ApplicationController
def index
render :text => "v1"
end
8 spec/test-api/app/controllers/v2.1/foos_controller.rb
View
@@ -1,7 +1,5 @@
-module V2_1
- class FoosController < ActionController::Base
- def index
- render :text => "v2.1"
- end
+class V2_1::FoosController < ApplicationController
+ def index
+ render :text => "v2.1"
end
end
8 spec/test-api/app/controllers/v2/foos_controller.rb
View
@@ -1,7 +1,5 @@
-module V2
- class FoosController < ActionController::Base
- def index
- render :text => "v2"
- end
+class V2::FoosController < ApplicationController
+ def index
+ render :text => "v2"
end
end
5 spec/test-api/config/application.rb
View
@@ -1,5 +1,6 @@
require "action_controller/railtie"
require "sprockets/railtie"
+require 'versionist/railtie'
module TestApi
class Application < Rails::Application
@@ -8,6 +9,8 @@ class Application < Rails::Application
config.active_support.deprecation = :log
config.action_controller.logger = nil
config.logger = Logger.new(STDOUT)
- config.log_level = Logger::Severity::FATAL
+ config.log_level = Logger::Severity::UNKNOWN
+ config.action_controller.logger = nil
+ config.middleware.delete Rails::Rack::Logger
end
end
22 spec/versioning_strategy/base_spec.rb
View
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe Versionist::VersioningStrategy::Base do
+ it "should raise an error when config nil" do
+ lambda {
+ Versionist::VersioningStrategy::Base.new(nil)
+ }.should raise_error(ArgumentError, /you must pass a configuration Hash/)
+ end
+
+ it "should raise an error when config is not a Hash" do
+ lambda {
+ Versionist::VersioningStrategy::Base.new(1)
+ }.should raise_error(ArgumentError, /you must pass a configuration Hash/)
+ end
+
+ it "should add self to Versionist::Configuration.versioning_strategies" do
+ Versionist.configuration.versioning_strategies.should be_empty
+ Versionist::VersioningStrategy::Base.new({})
+ Versionist.configuration.versioning_strategies.should_not be_empty
+ Versionist.configuration.versioning_strategies.size.should == 1
+ end
+end
15 spec/versioning_strategy/header_spec.rb
View
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe Versionist::VersioningStrategy::Header do
+ it "should raise an ArgumentError if :header is not specified" do
+ lambda {
+ Versionist::VersioningStrategy::Header.new({:foo => :bar})
+ }.should raise_error(ArgumentError, /you must specify :header in the configuration Hash/)
+ end
+
+ it "should raise an ArgumentError if :value is not specified" do
+ lambda {
+ Versionist::VersioningStrategy::Header.new({:header => "foo"})
+ }.should raise_error(ArgumentError, /you must specify :value in the configuration Hash/)
+ end
+end
15 spec/versioning_strategy/parameter_spec.rb
View
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe Versionist::VersioningStrategy::Parameter do
+ it "should raise an ArgumentError if :parameter is not specified" do
+ lambda {
+ Versionist::VersioningStrategy::Parameter.new({})
+ }.should raise_error(ArgumentError, /you must specify :parameter in the configuration Hash/)
+ end
+
+ it "should raise an ArgumentError if :value is not specified" do
+ lambda {
+ Versionist::VersioningStrategy::Parameter.new({:parameter => "version"})
+ }.should raise_error(ArgumentError, /you must specify :value in the configuration Hash/)
+ end
+end
9 spec/versioning_strategy/path_spec.rb
View
@@ -0,0 +1,9 @@
+require 'spec_helper'
+
+describe Versionist::VersioningStrategy::Path do
+ it "should raise an ArgumentError if :path is not specified" do
+ lambda {
+ Versionist::VersioningStrategy::Path.new({})
+ }.should raise_error(ArgumentError, /you must specify :path in the configuration Hash/)
+ end
+end
1  versionist.gemspec
View
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
s.add_dependency('rails', '~> 3.0')
+ s.add_development_dependency('awesome_print', '= 1.0.2')
s.add_development_dependency('rake', '>= 0.9.2')
s.add_development_dependency('rspec', '2.7.0')
s.add_development_dependency('rspec-rails', '2.7.0')
Please sign in to comment.
Something went wrong with that request. Please try again.