Add a new Routing module
Why: * The `route` matcher can not only be used within controller example groups but also routing example groups. * Now that we are mixing matchers into specific example groups, `route` is no longer available in routing example groups. To satisfy the above: * Create a new module that contains a `route` method and returns a new instance of RouteMatcher. (RouteMatcher still lives in the ActionController namespace.) * Mix this module into routing example groups when the gem configuration block is run.
This commit is contained in:
parent
af98a23091
commit
8cf449b4ca
|
@ -12,6 +12,7 @@ require 'shoulda/matchers/warn'
|
|||
require 'shoulda/matchers/action_controller'
|
||||
require 'shoulda/matchers/active_model'
|
||||
require 'shoulda/matchers/active_record'
|
||||
require 'shoulda/matchers/routing'
|
||||
|
||||
module Shoulda
|
||||
module Matchers
|
||||
|
|
|
@ -3,6 +3,7 @@ require 'shoulda/matchers/integrations/libraries/active_model'
|
|||
require 'shoulda/matchers/integrations/libraries/active_record'
|
||||
require 'shoulda/matchers/integrations/libraries/missing_library'
|
||||
require 'shoulda/matchers/integrations/libraries/rails'
|
||||
require 'shoulda/matchers/integrations/libraries/routing'
|
||||
|
||||
module Shoulda
|
||||
module Matchers
|
||||
|
|
|
@ -11,7 +11,8 @@ module Shoulda
|
|||
SUB_LIBRARIES = [
|
||||
:active_model,
|
||||
:active_record,
|
||||
:action_controller
|
||||
:action_controller,
|
||||
:routing
|
||||
]
|
||||
|
||||
def integrate_with(test_framework)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
module Shoulda
|
||||
module Matchers
|
||||
module Integrations
|
||||
module Libraries
|
||||
# @private
|
||||
class Routing
|
||||
Integrations.register_library(self, :routing)
|
||||
|
||||
include Integrations::Inclusion
|
||||
include Integrations::Rails
|
||||
|
||||
def integrate_with(test_framework)
|
||||
test_framework.include(matchers_module, type: :routing)
|
||||
|
||||
include_into(::ActionController::TestCase, matchers_module)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def matchers_module
|
||||
Shoulda::Matchers::Routing
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
module Shoulda
|
||||
module Matchers
|
||||
module Routing
|
||||
# @private
|
||||
def route(method, path)
|
||||
ActionController::RouteMatcher.new(method, path, self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,242 @@
|
|||
require 'unit_spec_helper'
|
||||
|
||||
describe 'Shoulda::Matchers::Routing::RouteMatcher', type: :routing do
|
||||
before do
|
||||
define_controller('ThingsController')
|
||||
end
|
||||
|
||||
shared_examples_for 'core tests' do
|
||||
context 'when the given method, path, controller, and action match an existing route' do
|
||||
it 'accepts' do
|
||||
define_routes { get '/', to: 'things#index' }
|
||||
|
||||
assert_accepts add_target_to(
|
||||
route(:get, '/'),
|
||||
controller: 'things',
|
||||
action: 'index'
|
||||
)
|
||||
end
|
||||
|
||||
context 'and the expected controller is specified as a symbol' do
|
||||
it 'accepts' do
|
||||
define_routes { get '/', to: 'things#index' }
|
||||
|
||||
assert_accepts add_target_to(
|
||||
route(:get, '/'),
|
||||
controller: :things,
|
||||
action: 'index'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and the expected action is specified as a symbol' do
|
||||
it 'accepts' do
|
||||
define_routes { get '/', to: 'things#index' }
|
||||
|
||||
assert_accepts add_target_to(
|
||||
route(:get, '/'),
|
||||
controller: 'things',
|
||||
action: :index
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given method, path, controller, and action do not match an existing route' do
|
||||
it 'rejects' do
|
||||
assert_rejects add_target_to(
|
||||
route(:get, '/non_existent_route'),
|
||||
controller: 'no_controller',
|
||||
action: 'no_action'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given path, controller, and action match an existing route but the method does not' do
|
||||
it 'rejects' do
|
||||
define_routes { post '/', to: 'things#index' }
|
||||
|
||||
assert_rejects add_target_to(
|
||||
route(:get, '/'),
|
||||
controller: 'things',
|
||||
action: 'index'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given method, controller, and action match an existing route but the path does not' do
|
||||
it 'rejects' do
|
||||
define_routes { get '/', to: 'things#index' }
|
||||
|
||||
assert_rejects add_target_to(
|
||||
route(:get, '/different_path'),
|
||||
controller: 'things',
|
||||
action: 'index'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given method and path match an existing route but the controller does not' do
|
||||
it 'rejects' do
|
||||
define_routes { get '/', to: 'another_controller#index' }
|
||||
|
||||
assert_rejects add_target_to(
|
||||
route(:get, '/'),
|
||||
controller: 'things',
|
||||
action: 'index'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the given method, path, and controller match an existing route but the action does not' do
|
||||
it 'rejects' do
|
||||
define_routes { get '/', to: 'things#index' }
|
||||
|
||||
assert_rejects add_target_to(
|
||||
route(:get, '/'),
|
||||
controller: 'things',
|
||||
action: 'another_action'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the actual route has a param' do
|
||||
context 'and the expected params include that param' do
|
||||
it 'accepts' do
|
||||
define_routes { get '/things/:id', to: 'things#show' }
|
||||
|
||||
assert_accepts add_target_to(
|
||||
route(:get, '/things/1'),
|
||||
controller: 'things',
|
||||
action: 'show',
|
||||
id: '1'
|
||||
)
|
||||
end
|
||||
|
||||
context 'but its value was not specified as a string' do
|
||||
it 'accepts, treating it as a string' do
|
||||
define_routes { get '/things/:id', to: 'things#show' }
|
||||
|
||||
assert_accepts add_target_to(
|
||||
route(:get, '/things/1'),
|
||||
controller: 'things',
|
||||
action: 'show',
|
||||
id: 1
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'and the expected params do not match the actual params' do
|
||||
it 'rejects' do
|
||||
define_routes { get '/things/:id', to: 'things#show' }
|
||||
|
||||
params = {
|
||||
controller: 'things',
|
||||
action: 'show',
|
||||
some: 'other',
|
||||
params: 'here'
|
||||
}
|
||||
assert_rejects add_target_to(
|
||||
route(:get, '/things/:id'),
|
||||
params
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the actual route has a default param whose value is a symbol' do
|
||||
context 'and the expected params include a value for it' do
|
||||
context 'as a symbol' do
|
||||
it 'accepts' do
|
||||
define_routes do
|
||||
post '/things(.:format)',
|
||||
to: 'things#create',
|
||||
defaults: { format: :json }
|
||||
end
|
||||
|
||||
assert_accepts add_target_to(
|
||||
route(:post, '/things'),
|
||||
controller: 'things',
|
||||
action: 'create',
|
||||
format: :json
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'as a string' do
|
||||
it 'accepts' do
|
||||
define_routes do
|
||||
post '/things(.:format)',
|
||||
to: 'things#create',
|
||||
defaults: { format: :json }
|
||||
end
|
||||
|
||||
assert_accepts add_target_to(
|
||||
route(:post, '/things'),
|
||||
controller: 'things',
|
||||
action: 'create',
|
||||
format: 'json'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the existing route has a glob segment' do
|
||||
context 'and a param is given which represents the segment' do
|
||||
it 'accepts' do
|
||||
define_routes { get '/things/*id', to: 'things#whatever' }
|
||||
|
||||
assert_accepts add_target_to(
|
||||
route(:get, '/things/foo/bar'),
|
||||
controller: 'things',
|
||||
action: 'whatever',
|
||||
id: 'foo/bar'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'and no param is given which represents the segment' do
|
||||
it 'rejects' do
|
||||
define_routes { get '/things/*id', to: 'things#whatever' }
|
||||
|
||||
assert_rejects add_target_to(
|
||||
route(:get, '/things'),
|
||||
controller: 'things',
|
||||
action: 'whatever'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a controller and action specified as individual options' do
|
||||
include_examples 'core tests'
|
||||
|
||||
def add_target_to(route_matcher, params)
|
||||
route_matcher.to(params)
|
||||
end
|
||||
end
|
||||
|
||||
context 'given a controller and action joined together in a string' do
|
||||
include_examples 'core tests'
|
||||
|
||||
def add_target_to(route_matcher, args)
|
||||
controller = args.fetch(:controller)
|
||||
action = args.fetch(:action)
|
||||
route_matcher.to(
|
||||
"#{controller}##{action}",
|
||||
args.except(:controller, :action)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_accepts(matcher)
|
||||
should(matcher)
|
||||
end
|
||||
|
||||
def assert_rejects(matcher)
|
||||
should_not(matcher)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue