passages 0.1.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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +119 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +20 -0
  8. data/app/assets/javascripts/passages/application.js +74 -0
  9. data/app/assets/stylesheets/passages/application.css +20 -0
  10. data/app/controllers/passages/routes_controller.rb +49 -0
  11. data/app/views/passages/routes/_route.html.erb +7 -0
  12. data/app/views/passages/routes/_routes_header.html.erb +5 -0
  13. data/app/views/passages/routes/routes.html.erb +59 -0
  14. data/config/initializers/assets.rb +1 -0
  15. data/config/routes.rb +3 -0
  16. data/lib/passages/engine.rb +11 -0
  17. data/lib/passages/engine_route.rb +13 -0
  18. data/lib/passages/engine_route_collection.rb +10 -0
  19. data/lib/passages/mount_route.rb +12 -0
  20. data/lib/passages/route.rb +44 -0
  21. data/lib/passages/route_collection.rb +23 -0
  22. data/lib/passages.rb +5 -0
  23. data/passages.gemspec +24 -0
  24. data/spec/controllers/passages/routes_controller_spec.rb +46 -0
  25. data/spec/lib/passages/engine_route_collection_spec.rb +42 -0
  26. data/spec/lib/passages/mount_route_spec.rb +29 -0
  27. data/spec/lib/passages/route_collection_spec.rb +50 -0
  28. data/spec/lib/passages/route_spec.rb +64 -0
  29. data/spec/spec_helper.rb +4 -0
  30. data/vendor/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  31. data/vendor/assets/fonts/glyphicons-halflings-regular.svg +288 -0
  32. data/vendor/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  33. data/vendor/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  34. data/vendor/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
  35. data/vendor/assets/javascripts/bootstrap.min.js +7 -0
  36. data/vendor/assets/javascripts/jquery-2.1.4.min.js +4 -0
  37. data/vendor/assets/stylesheets/bootstrap-theme.min.css +5 -0
  38. data/vendor/assets/stylesheets/bootstrap.min.css +5 -0
  39. data/version.rb +7 -0
  40. metadata +118 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 47e75e77bbe676fe75044de45fd56441e7c11a2b
4
+ data.tar.gz: f6d446dab10cf91edbd16cacb326d75a70bfa5f3
5
+ SHA512:
6
+ metadata.gz: 7bc750e7f13b7ee420c77c129095c69193b6f35a1bc481925431244fbccaca33ae993ee5c3e416b880b0855156630e73240eb8fdc6b83bafb5b8b9824c9db32d
7
+ data.tar.gz: 01bd77ac13587d13301a5a31bbddc8b8cf0e9da4616233e1da1f779bf16854f2747c65f3c2bcf851a720eb97c6ddd56cf7d9cb0f513eca506f03be2cd8d8ddda
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .ruby-*
2
+ *.gem
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0
4
+ - 2.2.1
5
+ - 2.2.2
6
+
7
+ script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,119 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ passages (0.0.1)
5
+ rails (~> 4.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionmailer (4.2.4)
11
+ actionpack (= 4.2.4)
12
+ actionview (= 4.2.4)
13
+ activejob (= 4.2.4)
14
+ mail (~> 2.5, >= 2.5.4)
15
+ rails-dom-testing (~> 1.0, >= 1.0.5)
16
+ actionpack (4.2.4)
17
+ actionview (= 4.2.4)
18
+ activesupport (= 4.2.4)
19
+ rack (~> 1.6)
20
+ rack-test (~> 0.6.2)
21
+ rails-dom-testing (~> 1.0, >= 1.0.5)
22
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
23
+ actionview (4.2.4)
24
+ activesupport (= 4.2.4)
25
+ builder (~> 3.1)
26
+ erubis (~> 2.7.0)
27
+ rails-dom-testing (~> 1.0, >= 1.0.5)
28
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
29
+ activejob (4.2.4)
30
+ activesupport (= 4.2.4)
31
+ globalid (>= 0.3.0)
32
+ activemodel (4.2.4)
33
+ activesupport (= 4.2.4)
34
+ builder (~> 3.1)
35
+ activerecord (4.2.4)
36
+ activemodel (= 4.2.4)
37
+ activesupport (= 4.2.4)
38
+ arel (~> 6.0)
39
+ activesupport (4.2.4)
40
+ i18n (~> 0.7)
41
+ json (~> 1.7, >= 1.7.7)
42
+ minitest (~> 5.1)
43
+ thread_safe (~> 0.3, >= 0.3.4)
44
+ tzinfo (~> 1.1)
45
+ arel (6.0.3)
46
+ builder (3.2.2)
47
+ diff-lcs (1.2.5)
48
+ erubis (2.7.0)
49
+ globalid (0.3.6)
50
+ activesupport (>= 4.1.0)
51
+ i18n (0.7.0)
52
+ json (1.8.3)
53
+ loofah (2.0.3)
54
+ nokogiri (>= 1.5.9)
55
+ mail (2.6.3)
56
+ mime-types (>= 1.16, < 3)
57
+ mime-types (2.6.2)
58
+ mini_portile (0.6.2)
59
+ minitest (5.8.1)
60
+ nokogiri (1.6.6.2)
61
+ mini_portile (~> 0.6.0)
62
+ rack (1.6.4)
63
+ rack-test (0.6.3)
64
+ rack (>= 1.0)
65
+ rails (4.2.4)
66
+ actionmailer (= 4.2.4)
67
+ actionpack (= 4.2.4)
68
+ actionview (= 4.2.4)
69
+ activejob (= 4.2.4)
70
+ activemodel (= 4.2.4)
71
+ activerecord (= 4.2.4)
72
+ activesupport (= 4.2.4)
73
+ bundler (>= 1.3.0, < 2.0)
74
+ railties (= 4.2.4)
75
+ sprockets-rails
76
+ rails-deprecated_sanitizer (1.0.3)
77
+ activesupport (>= 4.2.0.alpha)
78
+ rails-dom-testing (1.0.7)
79
+ activesupport (>= 4.2.0.beta, < 5.0)
80
+ nokogiri (~> 1.6.0)
81
+ rails-deprecated_sanitizer (>= 1.0.1)
82
+ rails-html-sanitizer (1.0.2)
83
+ loofah (~> 2.0)
84
+ railties (4.2.4)
85
+ actionpack (= 4.2.4)
86
+ activesupport (= 4.2.4)
87
+ rake (>= 0.8.7)
88
+ thor (>= 0.18.1, < 2.0)
89
+ rake (10.4.2)
90
+ rspec (3.3.0)
91
+ rspec-core (~> 3.3.0)
92
+ rspec-expectations (~> 3.3.0)
93
+ rspec-mocks (~> 3.3.0)
94
+ rspec-core (3.3.2)
95
+ rspec-support (~> 3.3.0)
96
+ rspec-expectations (3.3.1)
97
+ diff-lcs (>= 1.2.0, < 2.0)
98
+ rspec-support (~> 3.3.0)
99
+ rspec-mocks (3.3.2)
100
+ diff-lcs (>= 1.2.0, < 2.0)
101
+ rspec-support (~> 3.3.0)
102
+ rspec-support (3.3.0)
103
+ sprockets (3.3.5)
104
+ rack (> 1, < 3)
105
+ sprockets-rails (2.3.3)
106
+ actionpack (>= 3.0)
107
+ activesupport (>= 3.0)
108
+ sprockets (>= 2.8, < 4.0)
109
+ thor (0.19.1)
110
+ thread_safe (0.3.5)
111
+ tzinfo (1.2.2)
112
+ thread_safe (~> 0.1)
113
+
114
+ PLATFORMS
115
+ ruby
116
+
117
+ DEPENDENCIES
118
+ passages!
119
+ rspec (~> 3.2)
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Jake Yesbeck
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,20 @@
1
+ ## Roots
2
+
3
+ ![Build Status](https://travis-ci.org/yez/roots.svg?branch=master)
4
+
5
+ Route display and search for Ruby on Rails applications.
6
+
7
+ ## Install
8
+
9
+ In your `Gemfile`
10
+
11
+ ```ruby
12
+ source 'https://rubygems.org'
13
+ gem 'roots'
14
+ ```
15
+
16
+ `bundle install`
17
+
18
+ The `Roots` engine will **prepend** a `/roots` route to the application
19
+
20
+ Visiting `/roots` will
@@ -0,0 +1,74 @@
1
+ //= require jquery-2.1.4.min
2
+
3
+ DomElements = {
4
+ matchingTerm: 'table.matching-term'
5
+ };
6
+
7
+ function clearAndHideResultTable() {
8
+ var header = $('table.matching-term .header');
9
+ $(DomElements.matchingTerm).html(header);
10
+ $(DomElements.matchingTerm).hide();
11
+ }
12
+
13
+ function hideNoResults() {
14
+ $('.no-results').hide();
15
+ }
16
+
17
+ function showNoResults(searchTerm) {
18
+ $('.no-results').html('No results match "' + searchTerm + '"').show();
19
+ }
20
+
21
+ function showResultTable() {
22
+ hideNoResults();
23
+ $(DomElements.matchingTerm).show();
24
+ }
25
+
26
+ function searchResults(query) {
27
+ clearAndHideResultTable();
28
+ return $('[data-search*=' + query).parent('tr');
29
+ }
30
+
31
+ function highlight(element, term) {
32
+ var existing = $(element).html();
33
+ var bolded = existing.replace(new RegExp("(" + term + ")", "i"), "<span class='highlighted'>$1</span>");
34
+ $(element).html(bolded)
35
+ }
36
+
37
+ function addToResultTable(result, searchTerm){
38
+ showResultTable();
39
+ var table = $('.matching-term');
40
+ var lastChild = table.find('tr:last');
41
+
42
+ $.each(result.children(), function(index, element) {
43
+ highlight(element, searchTerm);
44
+ });
45
+
46
+ if(lastChild.length == 0) {
47
+ table.html(result);
48
+ }
49
+ else {
50
+ lastChild.after(result);
51
+ }
52
+ }
53
+
54
+ $(document).on('ready', function(){
55
+ $('input[name=search]').keyup(function(event){
56
+ var searchTerm = event.target.value;
57
+ if(searchTerm.length > 0) {
58
+ hideNoResults();
59
+ var results = searchResults(searchTerm.toLowerCase());
60
+ if (results.length > 0) {
61
+ $.each(results, function(index, value){
62
+ addToResultTable($(value).clone(), searchTerm);
63
+ });
64
+ }
65
+ else {
66
+ showNoResults(searchTerm);
67
+ }
68
+ }
69
+ else {
70
+ hideNoResults();
71
+ clearAndHideResultTable();
72
+ }
73
+ });
74
+ });
@@ -0,0 +1,20 @@
1
+ /*
2
+ *= require bootstrap.min
3
+ */
4
+
5
+ .vertical-spacer {
6
+ height: 20px;
7
+ }
8
+
9
+ .no-results {
10
+ display: none;
11
+ color: red;
12
+ }
13
+
14
+ .matching-term {
15
+ display: none;
16
+ }
17
+
18
+ .highlighted {
19
+ font-weight: bold;
20
+ }
@@ -0,0 +1,49 @@
1
+ require 'passages/route'
2
+ require 'passages/engine_route'
3
+ require 'passages/mount_route'
4
+ require 'passages/route_collection'
5
+ require 'passages/engine_route_collection'
6
+
7
+ module Passages
8
+ class RoutesController < ActionController::Base
9
+ layout false
10
+
11
+ def routes
12
+ @routes = application_routes
13
+ @engine_routes = engine_routes
14
+ @mount_routes = mount_routes
15
+ end
16
+
17
+ private
18
+
19
+ def engine_routes
20
+ EngineRouteCollection.new(mounted_engine_routes)
21
+ end
22
+
23
+ def application_routes
24
+ routes = passages_rails_routes.reject { |route| route.is_a?(MountRoute) }
25
+
26
+ RouteCollection.new(routes)
27
+ end
28
+
29
+ def mounted_engine_routes
30
+ @mounted_engine_routes ||= ::Rails::Engine.subclasses.map do |engine|
31
+ routes = engine.routes.routes.routes.map { |route| EngineRoute.new(route, engine.name) }
32
+
33
+ { engine: engine.name, routes: routes }
34
+ end.compact
35
+ end
36
+
37
+ def passages_rails_routes
38
+ @passages_rails_routes ||= Rails.application.routes.routes.map { |route| Route.from_raw_route(route) }
39
+ end
40
+
41
+ def mount_routes
42
+ {}.tap do |_mount_routes|
43
+ passages_rails_routes.each do |route|
44
+ _mount_routes[route.engine_name] = route if route.is_a?(MountRoute)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,7 @@
1
+ <tr>
2
+ <% Passages::Route.attributes_for_display.each do |attribute| %>
3
+ <td data-search='<%= route.send(attribute).downcase %>' data-matching-attribute='<%=attribute%>'>
4
+ <%= route.send(attribute) %>
5
+ </td>
6
+ <% end %>
7
+ </tr>
@@ -0,0 +1,5 @@
1
+ <tr class='header'>
2
+ <% Passages::Route.attributes_for_display.each do |header| %>
3
+ <th><%= header.titleize %></th>
4
+ <% end %>
5
+ </tr>
@@ -0,0 +1,59 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <%= stylesheet_link_tag 'passages/application', media: 'all' %>
5
+ <%= javascript_include_tag 'passages/application' %>
6
+ <title>Passages</title>
7
+ </head>
8
+ <body class='container'>
9
+ <div class = 'row'>
10
+ <div class='col-xs-12 vertical-spacer'></div>
11
+ </div>
12
+
13
+ <div class ='row'>
14
+ <div class='col-xs-6 '>
15
+ <input class='form-control' name='search' type='text' placeholder='Route Matching...'/>
16
+ </div>
17
+ </div>
18
+
19
+ <div class = 'row'>
20
+ <div class='col-xs-12 vertical-spacer'></div>
21
+ </div>
22
+
23
+ <div class = 'row'>
24
+ <div class='col-xs-12'>
25
+ <h3 class='no-results'></h3>
26
+ <table class='matching-term table table-striped table-bordered'>
27
+ <%= render partial: 'routes_header', locals: { collection: @route_collection } %>
28
+ </table>
29
+ </div>
30
+ </div>
31
+
32
+ <div class = 'row'>
33
+ <div class ='col-xs-12 '>
34
+ <% if @engine_routes.present? %>
35
+ <h3>Engine Routes</h3>
36
+ <% @engine_routes.each do |engine_hash| %>
37
+ <table class='table table-striped table-bordered'>
38
+ <tr>
39
+ <td colspan='2'><b>Routes for Engine:</b> <%= engine_hash[:engine] %></td>
40
+ <td colspan='3'><b>Mounted at:</b> <%= @mount_routes[engine_hash[:engine]].path %></td>
41
+ </tr>
42
+ <%= render partial: 'routes_header', locals: { collection: engine_hash[:routes] } %>
43
+ <% engine_hash[:routes].each do |route| %>
44
+ <%= render partial: 'route', locals: { route: route } %>
45
+ <% end %>
46
+ </table>
47
+ <% end %>
48
+ <% end %>
49
+ <h3>App Routes</h3>
50
+ <table class='table table-striped table-bordered'>
51
+ <%= render partial: 'routes_header', locals: { collection: @route_collection } %>
52
+ <% @routes.each do |route| %>
53
+ <%= render partial: 'route', locals: { route: route } %>
54
+ <% end %>
55
+ </table>
56
+ </div>
57
+ </div>
58
+ </body>
59
+ </html>
@@ -0,0 +1 @@
1
+ Rails.application.config.assets.version = '1.0'
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Passages::Engine.routes.draw do
2
+ root to: 'routes#routes'
3
+ end
@@ -0,0 +1,11 @@
1
+ module Passages
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Passages
4
+
5
+ initializer 'passages', before: :load_config_initializers do |app|
6
+ Rails.application.routes.prepend do
7
+ mount Passages::Engine, at: '/passages'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_support/core_ext'
2
+
3
+ module Passages
4
+ class EngineRoute < DelegateClass(ActionDispatch::Routing::RouteWrapper)
5
+ attr_reader :engine_name
6
+
7
+ def initialize(raw_route, engine_name)
8
+ @engine_name = engine_name
9
+
10
+ super(ActionDispatch::Routing::RouteWrapper.new(raw_route))
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ require_relative 'route'
2
+ require_relative 'route_collection'
3
+
4
+ module Passages
5
+ class EngineRouteCollection < RouteCollection
6
+ def initialize(_routes)
7
+ @routes = _routes.reject { |h| h[:routes].all?(&:internal?) }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ module Passages
2
+ class MountRoute < DelegateClass(ActionDispatch::Routing::RouteWrapper)
3
+ def initialize(route, app)
4
+ @app = app
5
+ super(ActionDispatch::Routing::RouteWrapper.new(route))
6
+ end
7
+
8
+ def engine_name
9
+ @app.name
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,44 @@
1
+ require 'active_support/core_ext'
2
+ require 'action_dispatch/routing/inspector'
3
+ require_relative 'mount_route'
4
+
5
+ module Passages
6
+ class Route < DelegateClass(ActionDispatch::Routing::RouteWrapper)
7
+
8
+ def initialize(route)
9
+ super(ActionDispatch::Routing::RouteWrapper.new(route))
10
+ end
11
+
12
+ class << self
13
+ def attributes_for_display
14
+ %w[name verb controller action path]
15
+ end
16
+
17
+ def from_raw_route(raw_route)
18
+ mount_class = mount_route_class(raw_route)
19
+
20
+ if mount_class.nil?
21
+ new(raw_route)
22
+ else
23
+ MountRoute.new(raw_route, mount_class)
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def mount_route_class(route)
30
+ route_app = route.app
31
+
32
+ app = if route_app.class == Class
33
+ route_app
34
+ else
35
+ route_app.try(:app)
36
+ end
37
+
38
+ app if app.ancestors.include?(Rails::Engine)
39
+ rescue
40
+ nil
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'route'
2
+
3
+ module Passages
4
+ class RouteCollection
5
+ include Enumerable
6
+
7
+ attr_reader :routes
8
+
9
+ def initialize(_routes)
10
+ @routes = _routes.reject { |r| r.internal? }
11
+ end
12
+
13
+ def each(&block)
14
+ Array(routes).each(&block)
15
+ end
16
+
17
+ private
18
+
19
+ def main_app_name
20
+ Rails.application.class.name
21
+ end
22
+ end
23
+ end
data/lib/passages.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'passages/engine'
2
+ require 'controllers/passages/routes_controller'
3
+
4
+ module Passages
5
+ end
data/passages.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH << File.dirname(__FILE__) + '/lib'
2
+ $LOAD_PATH << File.dirname(__FILE__) + '/app'
3
+
4
+ require './version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'passages'
8
+ s.version = Passages::VERSION
9
+ s.summary = %q{Display and search capabilities for Ruby on Rails routes}
10
+ s.description = %q{Rails Engine to make internal routes searchable and discoverable for more than just the name of the route. All aspects of a route are searchable from the HTTP verb to the paramters a route supports.}
11
+ s.authors = ['Jake Yesbeck']
12
+ s.email = 'yesbeckjs@gmail.com'
13
+ s.homepage = 'https://github.com/yez/roots'
14
+ s.license = 'MIT'
15
+
16
+ s.require_paths = %w(lib app)
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = s.files.grep(/^spec\//)
19
+
20
+ s.required_ruby_version = '>= 2.0.0'
21
+ s.add_dependency 'rails', '~> 4.0'
22
+
23
+ s.add_development_dependency 'rspec', '~> 3.2'
24
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+ require 'action_dispatch/routing'
3
+ require 'rails'
4
+
5
+ require_relative '../../../lib/passages/engine'
6
+ require_relative '../../../app/controllers/passages/routes_controller'
7
+
8
+ module Passages
9
+ describe RoutesController do
10
+
11
+ describe '#routes' do
12
+ before do
13
+ allow(subject).to receive(:application_routes) { anything }
14
+ allow(subject).to receive(:engine_routes) { anything }
15
+ allow(subject).to receive(:mount_routes) { anything }
16
+ subject.routes
17
+ end
18
+
19
+ it 'sets @routes' do
20
+ expect(subject.instance_variable_get(:@routes)).to_not be_nil
21
+ end
22
+
23
+ it 'sets @engine_routes' do
24
+ expect(subject.instance_variable_get(:@engine_routes)).to_not be_nil
25
+ end
26
+
27
+ it 'sets @mount_routes' do
28
+ expect(subject.instance_variable_get(:@mount_routes)).to_not be_nil
29
+ end
30
+ end
31
+
32
+ describe '!#engine_routes' do
33
+ it 'calls mounted_engine_routes' do
34
+ expect(subject).to receive(:mounted_engine_routes) { [] }
35
+ subject.send(:engine_routes)
36
+ end
37
+ end
38
+
39
+ describe '!#passages_rails_routes' do
40
+ it 'calls deep into the Rails routes' do
41
+ expect(Rails).to receive_message_chain(:application, :routes, :routes) { [] }
42
+ subject.send(:passages_rails_routes)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,42 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/passages/engine_route'
3
+ require_relative '../../../lib/passages/engine_route_collection'
4
+
5
+ module Passages
6
+ describe EngineRouteCollection do
7
+ describe '#initialize' do
8
+ let(:fake_route) { instance_double(EngineRoute) }
9
+ let(:engine_name) { 'Whatever' }
10
+
11
+ before do
12
+ allow(fake_route).to receive(:engine_name) { engine_name }
13
+ allow(fake_route).to receive(:internal?) { false }
14
+ end
15
+
16
+ subject { described_class.new([{engine: engine_name, routes: [fake_route]}]) }
17
+
18
+ it 'adds the engine name to each route' do
19
+ expect(subject.routes.all? { |route| route[:engine] == engine_name }).to eq(true)
20
+ end
21
+
22
+ context 'all an engine\'s routes are internal' do
23
+ it 'does not add it to the ivar' do
24
+ allow(fake_route).to receive(:internal?) { true }
25
+ expect(subject.routes).to be_empty
26
+ end
27
+ end
28
+
29
+ context 'only some of an engine\'s routes are internal' do
30
+ let(:another_fake_route) { instance_double(EngineRoute, internal?: false) }
31
+ let(:routes) { [fake_route, another_fake_route]}
32
+ subject { described_class.new([{engine: engine_name, routes: routes }]) }
33
+
34
+ it 'adds the engine to the ivar' do
35
+ expect(subject.routes).to_not be_empty
36
+ expect(subject.routes.all? { |r| r[:engine] == engine_name }).to eq(true)
37
+ expect(subject.routes.first[:routes]).to eq(routes)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end