rspec-rails-routing 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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rspec-rails-routing.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jason Harrelson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # RspecRailsRouting
2
+
3
+ RSpec matchers for Rails routing.
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'rspec-rails-routing'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install rspec-rails-routing
19
+
20
+
21
+ ## Usage
22
+
23
+ Create a routing spec helper. In this file you will define at least a host. You can
24
+ add an addition level of indirection in order to have multiple hosts. This is useful
25
+ when subdomains are used in your application and must be speced for different routing.
26
+
27
+ # spec/support/routing_spec_helper.rb
28
+ module RoutingSpecHelper
29
+
30
+ module Hosts
31
+
32
+ def host
33
+ some_application_host
34
+ end
35
+
36
+ def some_application_host
37
+ 'http://www.some-application.test'
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ RSpec.configure do |config|
45
+ config.include RoutingSpecHelper::Hosts, :type => :routing
46
+ end
47
+
48
+ Write a routing spec.
49
+
50
+ # spec/routing/projects_routing_spec.rb
51
+ require 'spec_helper'
52
+
53
+ describe 'projects routing' do
54
+
55
+ let :args do
56
+ ['projects', { :host => host }]
57
+ end
58
+
59
+ describe 'path recognition' do
60
+
61
+ it { should recognize_restful_index_path( *args ) }
62
+ it { should recognize_restful_show_path( *args ) }
63
+ it { should recognize_restful_new_path( *args ) }
64
+ it { should recognize_restful_edit_path( *args ) }
65
+ it { should recognize_restful_create_path( *args ) }
66
+ it { should recognize_restful_update_path( *args ) }
67
+
68
+ it { should_not recognize_restful_destory_path( *args ) }
69
+
70
+ end
71
+
72
+ describe 'path helpers' do
73
+
74
+ # using an open struct here as ActiveRecord models do not have an ID until saved to DB
75
+ let :project do
76
+ OpenStruct.new( id: 1 )
77
+ end
78
+
79
+ it { should have_named_route( :projects, "/projects" ) }
80
+ it { should have_named_route( :project, project, "/projects/#{project.id}" ) }
81
+ it { should have_named_route( :new_project, "/projects/new" ) }
82
+ it { should have_named_route( :edit_project, project, "/projects/#{project.id}/edit" ) }
83
+
84
+ # The create and update actions do not have path helpers as the paths are just the
85
+ # index and show paths with different HTTP Verbs.
86
+
87
+ end
88
+
89
+ end
90
+
91
+ Given the routes file.
92
+
93
+ # config/routes.rb
94
+ SomeApplication::Application.routes.draw do
95
+ resources :projects, :except => [:destroy]
96
+ end
97
+
98
+ The preceding spec will pass.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ require "rspec_rails_routing"
@@ -0,0 +1,9 @@
1
+ require "rspec_rails_routing/version"
2
+
3
+ module RspecRailsRouting
4
+
5
+ autoload :Matchers, 'rspec_rails_routing/matchers'
6
+
7
+ end
8
+
9
+ require 'rspec_rails_routing/rspec' if defined?( RSpec )
@@ -0,0 +1,53 @@
1
+ require 'rspec/expectations'
2
+
3
+ module RspecRailsRouting
4
+ module Matchers
5
+
6
+ autoload :HaveNamedRoute, 'rspec_rails_routing/matchers/have_named_route'
7
+ autoload :Helpers, 'rspec_rails_routing/matchers/helpers'
8
+ autoload :Routing, 'rspec_rails_routing/matchers/routing'
9
+
10
+ end
11
+ end
12
+
13
+ %w(
14
+ index
15
+ show
16
+ new
17
+ edit
18
+ create
19
+ update
20
+ destroy
21
+ ).each do |action|
22
+
23
+ RSpec::Matchers.define :"recognize_restful_#{action}_path" do |*args|
24
+
25
+ include RspecRailsRouting::Matchers::Helpers
26
+
27
+ url, path, path_template, controller, nesting_params = extract_info( action, args )
28
+
29
+ match do |actual|
30
+ begin
31
+ router.recognize_path( url, :method => http_verb_for( action ) ) == {
32
+ :controller => controller,
33
+ :action => action
34
+ }.merge( nesting_params )
35
+ rescue ActionController::RoutingError => ex
36
+ false
37
+ end
38
+ end
39
+
40
+ description do
41
+ description_for action, path_template, controller
42
+ end
43
+
44
+ failure_message_for_should do |actual|
45
+ failure_message_for_should_for action, url
46
+ end
47
+
48
+ failure_message_for_should_not do |actual|
49
+ failure_message_for_should_not_for action, url
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,60 @@
1
+
2
+ require 'rspec/expectations'
3
+
4
+ module RspecRailsRouting
5
+ module Matchers
6
+ module Routing
7
+
8
+ class HaveNamedRoute
9
+ def initialize(context, name, *args)
10
+ @context = context
11
+ @name = name
12
+ @path = "#{name}_path"
13
+ @args = args
14
+ if ! args.last
15
+ raise ArgumentError, 'The last argument must be the expected uri'
16
+ end
17
+ @expected_uri = args.pop
18
+ end
19
+
20
+ def description
21
+ "have a route named #{@name}, where e.g. #{example_call} == #{@expected_uri}"
22
+ end
23
+
24
+ def matches?(subject)
25
+ begin
26
+ @actual_uri = @context.send( "#{@name}_path", *@args )
27
+ @actual_uri == @expected_uri
28
+ rescue NoMethodError
29
+ false
30
+ end
31
+ end
32
+
33
+ def failure_message_for_should
34
+ "expected #{example_call} to equal #{@expected_uri}, but got #{@actual_uri}"
35
+ end
36
+
37
+ def failure_message_for_should_not
38
+ "expected #{example_call} to not equal #{@expected_uri}, but it did"
39
+ end
40
+
41
+ def example_call
42
+ call = "#{@name}_path"
43
+ if ! @args.empty?
44
+ call << "(#{format_args( @args )})"
45
+ end
46
+
47
+ call
48
+ end
49
+
50
+ def format_args( args )
51
+ @args.map do |a|
52
+ a.is_a?( Hash ) ? a.inspect : a.to_s
53
+ end.join( ', ' )
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,103 @@
1
+ module RspecRailsRouting
2
+ module Matchers
3
+ module Helpers
4
+
5
+ def router
6
+ Rails.application.routes
7
+ end
8
+
9
+ def extract_info( action, args )
10
+ options = args.extract_options!
11
+ domain = args.pop
12
+
13
+ url_part = args.map do |p|
14
+ if p.is_a?( Symbol )
15
+ p.to_s
16
+ elsif p.is_a?( String )
17
+ "#{p}/1"
18
+ end
19
+ end.join( '/' )
20
+
21
+ url_template_part = args.map do |p|
22
+ if p.is_a?( Symbol )
23
+ p.to_s
24
+ elsif p.is_a?( String )
25
+ "#{p}/:#{p.singularize.foreign_key}"
26
+ end
27
+ end.join( '/' )
28
+
29
+ namespaces = args.select { |p| p.is_a?( Symbol ) }
30
+ args.shift( namespaces.size )
31
+
32
+ nesting_params = Hash[*args.map { |p| [p.singularize.foreign_key.to_sym, '1'] }.flatten]
33
+
34
+ if %w(show edit update destroy).include?( action.to_s )
35
+ nesting_params.merge! :id => '1'
36
+ end
37
+
38
+ url_end = case action.to_sym
39
+ when :index, :create
40
+ ''
41
+ when :show, :update, :destroy
42
+ '1'
43
+ when :new
44
+ 'new'
45
+ when :edit
46
+ '1/edit'
47
+ end
48
+
49
+ url_template_end = case action.to_sym
50
+ when :index, :create
51
+ ''
52
+ when :show, :update, :destroy
53
+ ':id'
54
+ when :new
55
+ 'new'
56
+ when :edit
57
+ ':id/edit'
58
+ end
59
+
60
+ path = [url_part, domain, url_end].reject( &:blank? ).join( '/' )
61
+ path_template = [url_template_part, domain, url_template_end].reject( &:blank? ).join( '/' )
62
+ url = "#{options[:host]}/" + path
63
+ controller = [namespaces, domain].reject( &:blank? ).join( '/' )
64
+
65
+ return url, path, path_template, controller, nesting_params
66
+ end
67
+
68
+ def format_url_or_path( url_or_path )
69
+ is_url = !url_or_path.match( /^http/ ).nil?
70
+ has_slash = !url_or_path.match( /^\\/ ).nil?
71
+ needs_slash = !is_url && !has_slash
72
+
73
+ "#{needs_slash ? '/' : ''}#{url_or_path}".gsub( /\/1/, '/:id' )
74
+ end
75
+
76
+ def description_for( action, path_template, controller )
77
+ "route the RESTful #{action} path #{http_verb_for( action ).to_s.upcase} #{format_url_or_path( path_template )} to #{controller}##{action}"
78
+ end
79
+
80
+ def failure_message_for_should_for( action, url )
81
+ "failed to recognize the RESTful #{action} path #{http_verb_for( action ).to_s.upcase} #{url}"
82
+ end
83
+
84
+ def failure_message_for_should_not_for( action, url )
85
+ "recognized the RESTful #{action} path #{http_verb_for( action ).to_s.upcase} #{url}, but should not"
86
+ end
87
+
88
+ def http_verb_for( action )
89
+ case action.to_sym
90
+ when :index, :show, :new, :edit
91
+ :get
92
+ when :create
93
+ :post
94
+ when :update
95
+ :put
96
+ when :destroy
97
+ :delete
98
+ end
99
+ end
100
+
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,63 @@
1
+ require 'rspec/expectations'
2
+
3
+ module RspecRailsRouting
4
+ module Matchers
5
+ module Routing
6
+
7
+ def have_named_route(name, *args)
8
+ HaveNamedRoute.new(self, name, *args)
9
+ end
10
+
11
+ #class HaveNamedRoute
12
+ #def initialize(context, name, *args)
13
+ #@context = context
14
+ #@name = name
15
+ #@path = "#{name}_path"
16
+ #@args = args
17
+ #if ! args.last
18
+ #raise ArgumentError, 'The last argument must be the expected uri'
19
+ #end
20
+ #@expected_uri = args.pop
21
+ #end
22
+
23
+ #def description
24
+ #"have a route named #{@name}, where e.g. #{example_call} == #{@expected_uri}"
25
+ #end
26
+
27
+ #def matches?(subject)
28
+ #begin
29
+ #@actual_uri = @context.send( "#{@name}_path", *@args )
30
+ #@actual_uri == @expected_uri
31
+ #rescue NoMethodError => ex
32
+ #false
33
+ #end
34
+ #end
35
+
36
+ #def failure_message_for_should
37
+ #"expected #{example_call} to equal #{@expected_uri}, but got #{@actual_uri}"
38
+ #end
39
+
40
+ #def failure_message_for_should_not
41
+ #"expected #{example_call} to not equal #{@expected_uri}, but it did"
42
+ #end
43
+
44
+ #def example_call
45
+ #call = "#{@name}_path"
46
+ #if ! @args.empty?
47
+ #call << "(#{format_args( @args )})"
48
+ #end
49
+
50
+ #call
51
+ #end
52
+
53
+ #def format_args( args )
54
+ #@args.map do |a|
55
+ #a.is_a?( Hash ) ? a.inspect : a.to_s
56
+ #end.join( ', ' )
57
+ #end
58
+
59
+ #end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,7 @@
1
+ require 'rspec/core'
2
+
3
+ RSpec.configure do |config|
4
+
5
+ config.include RspecRailsRouting::Matchers::Routing, :type => :routing
6
+
7
+ end
@@ -0,0 +1,7 @@
1
+ module Rspec
2
+ module Rails
3
+ module Routing
4
+ VERSION = "1.0.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rspec_rails_routing/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rspec-rails-routing"
8
+ spec.version = Rspec::Rails::Routing::VERSION
9
+ spec.authors = ["C. Jason Harrelson"]
10
+ spec.email = ["jason@lookforwardenterprises.com"]
11
+ spec.description = %q{Rspec matchers for Rails routing.}
12
+ spec.summary = %q{Rspec matchers for Rails routing.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-rails-routing
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - C. Jason Harrelson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Rspec matchers for Rails routing.
47
+ email:
48
+ - jason@lookforwardenterprises.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - lib/rspec-rails-routing.rb
59
+ - lib/rspec_rails_routing.rb
60
+ - lib/rspec_rails_routing/matchers.rb
61
+ - lib/rspec_rails_routing/matchers/have_named_route.rb
62
+ - lib/rspec_rails_routing/matchers/helpers.rb
63
+ - lib/rspec_rails_routing/matchers/routing.rb
64
+ - lib/rspec_rails_routing/rspec.rb
65
+ - lib/rspec_rails_routing/version.rb
66
+ - rspec-rails-routing.gemspec
67
+ homepage: ''
68
+ licenses:
69
+ - MIT
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ segments:
81
+ - 0
82
+ hash: -2030036764577703089
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ segments:
90
+ - 0
91
+ hash: -2030036764577703089
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 1.8.25
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Rspec matchers for Rails routing.
98
+ test_files: []