loaf 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -3
- data/.rspec +1 -0
- data/.travis.yml +30 -12
- data/Appraisals +27 -9
- data/CHANGELOG.md +59 -11
- data/Gemfile +11 -11
- data/Gemfile.lock +182 -0
- data/README.md +120 -56
- data/assets/loaf_logo.png +0 -0
- data/bin/appraisal +16 -0
- data/bin/rake +16 -0
- data/gemfiles/rails3.2.gemfile +15 -13
- data/gemfiles/rails4.0.gemfile +13 -12
- data/gemfiles/rails4.1.gemfile +14 -13
- data/gemfiles/rails4.2.gemfile +14 -13
- data/gemfiles/rails5.0.gemfile +22 -0
- data/gemfiles/rails5.1.gemfile +22 -0
- data/lib/loaf.rb +2 -22
- data/lib/loaf/breadcrumb.rb +30 -0
- data/lib/loaf/configuration.rb +7 -8
- data/lib/loaf/controller_extensions.rb +13 -28
- data/lib/loaf/crumb.rb +5 -4
- data/lib/loaf/crumb_formatter.rb +3 -1
- data/lib/loaf/errors.rb +1 -3
- data/lib/loaf/options_validator.rb +2 -2
- data/lib/loaf/railtie.rb +19 -13
- data/lib/loaf/translation.rb +1 -1
- data/lib/loaf/version.rb +1 -3
- data/lib/loaf/view_extensions.rb +69 -18
- data/loaf.gemspec +20 -13
- data/spec/integration/{crumbs_routing_spec.rb → breadcrumb_trail_spec.rb} +19 -12
- data/spec/rails_app/app/controllers/application_controller.rb +2 -0
- data/spec/rails_app/app/controllers/posts_controller.rb +1 -4
- data/spec/rails_app/app/views/layouts/_breadcrumbs.html.erb +7 -5
- data/spec/rails_app/app/views/layouts/application.html.erb +0 -2
- data/spec/rails_app/config/environments/test.rb +1 -1
- data/spec/rails_app/config/secrets.yml +22 -0
- data/spec/spec_helper.rb +3 -3
- data/spec/support/dummy_controller.rb +9 -0
- data/spec/support/dummy_view.rb +42 -2
- data/spec/unit/configuration_spec.rb +35 -0
- data/spec/unit/controller_extensions_spec.rb +5 -14
- data/spec/unit/generators/install_generator_spec.rb +2 -1
- data/spec/unit/view_extensions/breadcrumb_trail_spec.rb +232 -0
- metadata +65 -31
- data/.ruby-version +0 -1
- data/init.rb +0 -3
- data/lib/loaf/builder.rb +0 -38
- data/spec/rails_app/.gitignore +0 -5
- data/spec/rails_app/lib/assets/.gitkeep +0 -0
- data/spec/rails_app/lib/tasks/.gitkeep +0 -0
- data/spec/rails_app/script/rails +0 -6
- data/spec/unit/view_extensions/breadcrumbs_spec.rb +0 -128
data/loaf.gemspec
CHANGED
@@ -3,19 +3,26 @@ lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'loaf/version'
|
5
5
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'loaf'
|
8
|
+
spec.version = Loaf::VERSION.dup
|
9
|
+
spec.authors = ['Piotr Murach']
|
10
|
+
spec.email = [""]
|
11
|
+
spec.homepage = 'https://github.com/piotrmurach/loaf'
|
12
|
+
spec.summary = %q{Loaf manages and displays breadcrumb trails in your Rails application.}
|
13
|
+
spec.description = %q{Loaf manages and displays breadcrumb trails in your Rails app. It aims to handle breadcrumb data through easy dsl and expose it through view helpers without any assumptions about markup.}
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
spec.files = `git ls-files`.split("\n")
|
16
|
+
spec.test_files = `git ls-files -- {spec,features}/*`.split("\n")
|
17
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
|
20
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
|
+
spec.metadata['source_code_uri'] = 'https://github.com/piotrmurach/loaf'
|
22
|
+
spec.metadata['changelog_uri'] = 'https://github.com/piotrmurach/loaf/blob/master/CHANGELOG.md'
|
23
|
+
|
24
|
+
spec.add_dependency 'rails', '>= 3.2'
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
27
|
+
spec.add_development_dependency 'rake'
|
21
28
|
end
|
@@ -1,25 +1,30 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
RSpec.describe "crumbs routing" do
|
3
|
+
RSpec.describe "breadcrumbs trail" do
|
6
4
|
include ActionView::TestCase::Behavior
|
7
5
|
|
8
|
-
it "
|
6
|
+
it "shows root breadcrumb" do
|
9
7
|
visit root_path
|
10
|
-
|
8
|
+
|
9
|
+
within '#breadcrumbs .selected' do
|
10
|
+
expect(page.html).to include('<a href="/">Home</a>')
|
11
|
+
end
|
11
12
|
end
|
12
13
|
|
13
14
|
it "inherits controller breadcrumb and adds index action breadcrumb" do
|
14
15
|
visit posts_path
|
16
|
+
|
15
17
|
within '#breadcrumbs' do
|
16
18
|
expect(page.html).to include('<a href="/">Home</a>')
|
17
|
-
|
19
|
+
within '.selected' do
|
20
|
+
expect(page.html).to include('<a href="/posts">All Posts</a>')
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
21
25
|
it 'filters out controller breadcrumb and adds new action breadcrumb' do
|
22
26
|
visit new_post_path
|
27
|
+
|
23
28
|
within '#breadcrumbs' do
|
24
29
|
expect(page).to_not have_content('Home')
|
25
30
|
expect(page).to have_content('New Post')
|
@@ -28,25 +33,27 @@ RSpec.describe "crumbs routing" do
|
|
28
33
|
|
29
34
|
it "adds breadcrumb in view with path variable" do
|
30
35
|
visit post_path(1)
|
31
|
-
|
36
|
+
|
37
|
+
within '#breadcrumbs .selected' do
|
32
38
|
expect(page.html).to include('<a href="/posts/1">Show Post in view</a>')
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
36
42
|
it 'is current when forced' do
|
37
43
|
visit new_post_path
|
38
|
-
click_button "Create"
|
39
44
|
|
40
|
-
expect(page.current_path).to eq(
|
45
|
+
expect(page.current_path).to eq(new_post_path)
|
41
46
|
within '#breadcrumbs' do
|
42
|
-
expect(page).to
|
43
|
-
expect(page).to
|
47
|
+
expect(page).to have_selector('li.selected', count: 2)
|
48
|
+
expect(page.html).to include('<a href="/posts">All</a>')
|
49
|
+
expect(page.html).to include('<a href="/posts/new">New Post</a>')
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
47
53
|
it "allows for procs in name and url" do
|
48
54
|
visit post_comments_path(1)
|
49
|
-
|
55
|
+
|
56
|
+
within '#breadcrumbs .selected' do
|
50
57
|
expect(page.html).to include('<a href="/posts/1/comments">Post comments</a>')
|
51
58
|
end
|
52
59
|
end
|
@@ -1,9 +1,6 @@
|
|
1
1
|
class Post < Struct.new(:id); end
|
2
2
|
|
3
3
|
class PostsController < ApplicationController
|
4
|
-
|
5
|
-
breadcrumb 'Home', :root_path, only: :index
|
6
|
-
|
7
4
|
def index
|
8
5
|
breadcrumb 'all_posts', posts_path
|
9
6
|
end
|
@@ -13,11 +10,11 @@ class PostsController < ApplicationController
|
|
13
10
|
end
|
14
11
|
|
15
12
|
def new
|
13
|
+
breadcrumb 'All', :posts_path, match: :force
|
16
14
|
breadcrumb 'New Post', new_post_path
|
17
15
|
end
|
18
16
|
|
19
17
|
def create
|
20
|
-
breadcrumb 'New Post', new_post_path, force: true
|
21
18
|
render action: :new
|
22
19
|
end
|
23
20
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
-
<% if
|
1
|
+
<% if breadcrumb_trail.any? %>
|
2
2
|
<ul id='breadcrumbs'>
|
3
|
-
<%
|
4
|
-
<li class="<%=
|
5
|
-
<%= link_to name, url %>
|
6
|
-
|
3
|
+
<% breadcrumb_trail do |crumb| %>
|
4
|
+
<li class="<%= crumb.current? ? 'selected' : '' %>">
|
5
|
+
<%= link_to crumb.name, crumb.url %>
|
6
|
+
<% unless crumb.current? %>
|
7
|
+
<span>::</span>
|
8
|
+
<% end %>
|
7
9
|
</li>
|
8
10
|
<% end %>
|
9
11
|
</ul>
|
@@ -8,7 +8,7 @@ RailsApp::Application.configure do
|
|
8
8
|
config.cache_classes = true
|
9
9
|
|
10
10
|
# Configure static asset server for tests with Cache-Control for performance
|
11
|
-
config.
|
11
|
+
config.serve_static_files = true
|
12
12
|
config.static_cache_control = "public, max-age=3600"
|
13
13
|
|
14
14
|
# Show full error reports and disable caching
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Your secret key is used for verifying the integrity of signed cookies.
|
4
|
+
# If you change this key, all old signed cookies will become invalid!
|
5
|
+
|
6
|
+
# Make sure the secret is at least 30 characters and all random,
|
7
|
+
# no regular words or you'll be exposed to dictionary attacks.
|
8
|
+
# You can use `rake secret` to generate a secure secret key.
|
9
|
+
|
10
|
+
# Make sure the secrets in this file are kept private
|
11
|
+
# if you're sharing your code publicly.
|
12
|
+
|
13
|
+
development:
|
14
|
+
secret_key_base: c392df63ec28b42b36b92a5b9e8603fa62d7807024d07801ab162ec7a2a165a87d27a4a8535ce09cd2bf4a82afe45e3080fb8cc56613d608e5b18335594782b3
|
15
|
+
|
16
|
+
test:
|
17
|
+
secret_key_base: 4b1fba0d12c53b8b21880fda47b603b3dcca117ccf41fcc70091351b88ede5d4c5c91371f407cd056efd66fa5f306c23add65a89d4304e06a4243289ee97be1d
|
18
|
+
|
19
|
+
# Do not keep production secrets in the repository,
|
20
|
+
# instead read values from the environment.
|
21
|
+
production:
|
22
|
+
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
if
|
3
|
+
if (ENV['COVERAGE'] || ENV['TRAVIS']) && RUBY_VERSION < '2.4.0'
|
4
4
|
require 'simplecov'
|
5
5
|
require 'coveralls'
|
6
6
|
|
7
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
7
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
8
8
|
SimpleCov::Formatter::HTMLFormatter,
|
9
9
|
Coveralls::SimpleCov::Formatter
|
10
|
-
]
|
10
|
+
])
|
11
11
|
|
12
12
|
SimpleCov.start do
|
13
13
|
command_name 'spec'
|
data/spec/support/dummy_view.rb
CHANGED
@@ -1,7 +1,47 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
|
1
3
|
class DummyView < ActionView::Base
|
4
|
+
module FakeRequest
|
5
|
+
class Request
|
6
|
+
attr_accessor :path, :fullpath, :protocol, :host_with_port
|
7
|
+
def get?
|
8
|
+
true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
def request
|
12
|
+
@request ||= Request.new
|
13
|
+
end
|
14
|
+
def params
|
15
|
+
@params ||= {}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
include FakeRequest
|
20
|
+
include ActionView::Helpers::UrlHelper
|
2
21
|
include Loaf::ViewExtensions
|
22
|
+
|
3
23
|
attr_reader :_breadcrumbs
|
4
24
|
|
5
|
-
|
6
|
-
|
25
|
+
routes = ActionDispatch::Routing::RouteSet.new
|
26
|
+
routes.draw do
|
27
|
+
get "/" => "foo#bar", :as => :home
|
28
|
+
get "/posts" => "foo#posts"
|
29
|
+
get "/posts/:title" => "foo#posts"
|
30
|
+
get "/post/:id" => "foo#post", :as => :post
|
31
|
+
get "/post/:title" => "foo#title"
|
32
|
+
get "/post/:id/comments" => "foo#comments"
|
33
|
+
|
34
|
+
namespace :blog do
|
35
|
+
get "/" => "foo#bar"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
include routes.url_helpers
|
40
|
+
|
41
|
+
def set_path(path)
|
42
|
+
request.path = path
|
43
|
+
request.fullpath = path
|
44
|
+
request.protocol = 'http://'
|
45
|
+
request.host_with_port = 'www.example.com'
|
46
|
+
end
|
7
47
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe Loaf::Configuration do
|
4
|
+
it "allows to set and read attributes" do
|
5
|
+
config = Loaf::Configuration.new
|
6
|
+
|
7
|
+
config.crumb_length = 4
|
8
|
+
|
9
|
+
expect(config.crumb_length).to eq(4)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "accepts attributes at initialization" do
|
13
|
+
options = { crumb_length: 12 }
|
14
|
+
config = Loaf::Configuration.new(options)
|
15
|
+
|
16
|
+
expect(config.crumb_length).to eq(12)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "exports configuration as hash" do
|
20
|
+
config = Loaf::Configuration.new
|
21
|
+
expect(config.to_hash).to eq({
|
22
|
+
capitalize: false,
|
23
|
+
crumb_length: 30,
|
24
|
+
locales_path: '/'
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
it "yields configuration" do
|
29
|
+
conf = double(:conf)
|
30
|
+
allow(Loaf).to receive(:configuration).and_return(conf)
|
31
|
+
expect { |b|
|
32
|
+
Loaf.configure(&b)
|
33
|
+
}.to yield_with_args(conf)
|
34
|
+
end
|
35
|
+
end
|
@@ -1,14 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
class DummyController < ActionController::Base
|
6
|
-
def self.before_filter(options, &block)
|
7
|
-
yield self.new
|
8
|
-
end
|
9
|
-
include Loaf::ControllerExtensions
|
10
|
-
end
|
11
|
-
|
12
3
|
RSpec.describe Loaf::ControllerExtensions do
|
13
4
|
|
14
5
|
context 'when classes extend controller_extensions' do
|
@@ -16,18 +7,18 @@ RSpec.describe Loaf::ControllerExtensions do
|
|
16
7
|
it { expect(DummyController).to respond_to(:breadcrumb) }
|
17
8
|
it { expect(DummyController.new).to respond_to(:add_breadcrumb) }
|
18
9
|
it { expect(DummyController.new).to respond_to(:breadcrumb) }
|
19
|
-
it { expect(DummyController.new).to respond_to(:add_breadcrumbs) }
|
20
10
|
it { expect(DummyController.new).to respond_to(:clear_breadcrumbs) }
|
21
11
|
end
|
22
12
|
|
23
13
|
context 'class methods' do
|
24
|
-
it 'invokes
|
25
|
-
allow(DummyController).to receive(:
|
14
|
+
it 'invokes before_action' do
|
15
|
+
allow(DummyController).to receive(:before_action)
|
16
|
+
allow(DummyController).to receive(:respond_to?).and_return(true)
|
26
17
|
DummyController.breadcrumb('name', 'url_path')
|
27
|
-
expect(DummyController).to have_received(:
|
18
|
+
expect(DummyController).to have_received(:before_action)
|
28
19
|
end
|
29
20
|
|
30
|
-
it 'delegates to instance' do
|
21
|
+
it 'delegates breadcrumb registration to controller instance' do
|
31
22
|
name = 'List objects'
|
32
23
|
url = :object_path
|
33
24
|
options = {force: true}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'fileutils'
|
4
4
|
require 'generators/loaf/install_generator'
|
5
5
|
|
6
6
|
RSpec.describe Loaf::Generators::InstallGenerator, type: :generator do
|
@@ -12,5 +12,6 @@ RSpec.describe Loaf::Generators::InstallGenerator, type: :generator do
|
|
12
12
|
run_generator
|
13
13
|
locale = file("config/locales/loaf.en.yml")
|
14
14
|
expect(locale).to exist
|
15
|
+
FileUtils.rm_rf(File.expand_path("../../../tmp", __FILE__))
|
15
16
|
end
|
16
17
|
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe Loaf::ViewExtensions, '#breadcrumb_trail' do
|
4
|
+
it "resolves breadcrumb paths" do
|
5
|
+
view = DummyView.new
|
6
|
+
view.breadcrumb('home', :home_path)
|
7
|
+
view.breadcrumb('posts', :posts_path)
|
8
|
+
view.set_path('/posts')
|
9
|
+
|
10
|
+
yielded = []
|
11
|
+
block = -> (crumb) { yielded << crumb.to_a }
|
12
|
+
view.breadcrumb_trail(&block)
|
13
|
+
|
14
|
+
expect(yielded).to eq([
|
15
|
+
['home', '/', false],
|
16
|
+
['posts', '/posts', true]
|
17
|
+
])
|
18
|
+
end
|
19
|
+
|
20
|
+
it "matches current path with :inclusive option as default" do
|
21
|
+
view = DummyView.new
|
22
|
+
view.breadcrumb('home', :home_path)
|
23
|
+
view.breadcrumb('posts', :posts_path)
|
24
|
+
view.set_path('/posts?id=73-title')
|
25
|
+
|
26
|
+
yielded = []
|
27
|
+
block = -> (crumb) { yielded << crumb.to_a }
|
28
|
+
view.breadcrumb_trail(&block)
|
29
|
+
|
30
|
+
expect(yielded).to eq([
|
31
|
+
['home', '/', false],
|
32
|
+
['posts', '/posts', true]
|
33
|
+
])
|
34
|
+
end
|
35
|
+
|
36
|
+
it "matches current path with :inclusive when query params" do
|
37
|
+
view = DummyView.new
|
38
|
+
view.breadcrumb('posts', '/posts', match: :inclusive)
|
39
|
+
view.set_path('/posts?foo=bar')
|
40
|
+
|
41
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]])
|
42
|
+
end
|
43
|
+
|
44
|
+
it "matches current path with :inclusive when nested" do
|
45
|
+
view = DummyView.new
|
46
|
+
view.breadcrumb('posts', '/posts', match: :inclusive)
|
47
|
+
view.set_path('/posts/1/comment')
|
48
|
+
|
49
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]])
|
50
|
+
end
|
51
|
+
|
52
|
+
it "matches current path with :inclusive when nested" do
|
53
|
+
view = DummyView.new
|
54
|
+
view.breadcrumb('posts', '/posts', match: :inclusive)
|
55
|
+
view.set_path('/posts/1/comment')
|
56
|
+
|
57
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]])
|
58
|
+
end
|
59
|
+
|
60
|
+
it "doesn't match with :inclusive when unrelated path" do
|
61
|
+
view = DummyView.new
|
62
|
+
view.breadcrumb('posts', '/posts', match: :inclusive)
|
63
|
+
view.set_path('/post/1')
|
64
|
+
|
65
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]])
|
66
|
+
end
|
67
|
+
|
68
|
+
it "matches current path with :inclusive when extra trailing slash" do
|
69
|
+
view = DummyView.new
|
70
|
+
view.breadcrumb('posts', '/posts/', match: :inclusive)
|
71
|
+
view.set_path('/posts')
|
72
|
+
|
73
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts/', true]])
|
74
|
+
end
|
75
|
+
|
76
|
+
it "matches current path with :inclusive when absolute path" do
|
77
|
+
view = DummyView.new
|
78
|
+
view.breadcrumb('posts', 'http://www.example.com/posts/', match: :inclusive)
|
79
|
+
view.set_path('/posts')
|
80
|
+
|
81
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([
|
82
|
+
['posts', 'http://www.example.com/posts/', true]
|
83
|
+
])
|
84
|
+
end
|
85
|
+
|
86
|
+
it "matches current path with :exact when trailing slash" do
|
87
|
+
view = DummyView.new
|
88
|
+
view.breadcrumb('posts', '/posts/', match: :exact)
|
89
|
+
view.set_path('/posts')
|
90
|
+
|
91
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts/', true]])
|
92
|
+
end
|
93
|
+
|
94
|
+
it "fails to match current path with :exact when nested" do
|
95
|
+
view = DummyView.new
|
96
|
+
view.breadcrumb('posts', '/posts', match: :exact)
|
97
|
+
view.set_path('/posts/1/comment')
|
98
|
+
|
99
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]])
|
100
|
+
end
|
101
|
+
|
102
|
+
it "fails to match current path with :exact when query params" do
|
103
|
+
view = DummyView.new
|
104
|
+
view.breadcrumb('posts', '/posts', match: :exact)
|
105
|
+
view.set_path('/posts?foo=bar')
|
106
|
+
|
107
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]])
|
108
|
+
end
|
109
|
+
|
110
|
+
it "matches current path with :exclusive option when query params" do
|
111
|
+
view = DummyView.new
|
112
|
+
view.breadcrumb('posts', '/posts', match: :exclusive)
|
113
|
+
view.set_path('/posts?foo=bar')
|
114
|
+
|
115
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]])
|
116
|
+
end
|
117
|
+
|
118
|
+
it "fails to match current path with :exclusive option when nested" do
|
119
|
+
view = DummyView.new
|
120
|
+
view.breadcrumb('posts', '/posts', match: :exclusive)
|
121
|
+
view.set_path('/posts/1/comment')
|
122
|
+
|
123
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]])
|
124
|
+
end
|
125
|
+
|
126
|
+
it "matches current path with regex option when query params" do
|
127
|
+
view = DummyView.new
|
128
|
+
view.breadcrumb('posts', '/posts', match: %r{/po})
|
129
|
+
view.set_path('/posts?foo=bar')
|
130
|
+
|
131
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]])
|
132
|
+
end
|
133
|
+
|
134
|
+
it "matches current path with query params option" do
|
135
|
+
view = DummyView.new
|
136
|
+
view.breadcrumb('posts', '/posts', match: {foo: :bar})
|
137
|
+
view.set_path('/posts?foo=bar&baz=boo')
|
138
|
+
|
139
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]])
|
140
|
+
end
|
141
|
+
|
142
|
+
it "fails to match current path with query params option" do
|
143
|
+
view = DummyView.new
|
144
|
+
view.breadcrumb('posts', '/posts', match: {foo: :bar})
|
145
|
+
view.set_path('/posts?foo=2&baz=boo')
|
146
|
+
|
147
|
+
expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]])
|
148
|
+
end
|
149
|
+
|
150
|
+
it "failse to recognize the match option" do
|
151
|
+
view = DummyView.new
|
152
|
+
view.breadcrumb('posts', 'http://www.example.com/posts/', match: :boom)
|
153
|
+
view.set_path('/posts')
|
154
|
+
block = -> (*args) { }
|
155
|
+
expect {
|
156
|
+
view.breadcrumb_trail(&block)
|
157
|
+
}.to raise_error(ArgumentError, "Unknown `:boom` match option!")
|
158
|
+
end
|
159
|
+
|
160
|
+
it "forces current path" do
|
161
|
+
view = DummyView.new
|
162
|
+
view.breadcrumb('home', :home_path)
|
163
|
+
view.breadcrumb('posts', :posts_path, match: :force)
|
164
|
+
view.set_path('/')
|
165
|
+
|
166
|
+
yielded = []
|
167
|
+
block = -> (crumb) { yielded << crumb.to_a }
|
168
|
+
view.breadcrumb_trail(&block)
|
169
|
+
|
170
|
+
expect(yielded).to eq([
|
171
|
+
['home', '/', true],
|
172
|
+
['posts', '/posts', true]
|
173
|
+
])
|
174
|
+
end
|
175
|
+
|
176
|
+
it "returns enumerator without block" do
|
177
|
+
view = DummyView.new
|
178
|
+
view.breadcrumb('home', :home_path)
|
179
|
+
view.breadcrumb('posts', :posts_path)
|
180
|
+
view.set_path('/posts')
|
181
|
+
|
182
|
+
result = view.breadcrumb_trail
|
183
|
+
|
184
|
+
expect(result).to be_a(Enumerable)
|
185
|
+
expect(result.take(2).map(&:to_a)).to eq([
|
186
|
+
['home', '/', false],
|
187
|
+
['posts', '/posts', true]
|
188
|
+
])
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'validates passed options' do
|
192
|
+
view = DummyView.new
|
193
|
+
block = -> (name, url, styles) { }
|
194
|
+
expect {
|
195
|
+
view.breadcrumb_trail(unknown: true, &block)
|
196
|
+
}.to raise_error(Loaf::InvalidOptions)
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'uses global configuration for crumb formatting' do
|
200
|
+
allow(Loaf.configuration).to receive(:crumb_length).and_return(10)
|
201
|
+
view = DummyView.new
|
202
|
+
view.breadcrumb('home-sweet-home', :home_path)
|
203
|
+
view.breadcrumb('posts-for-everybody', :posts_path)
|
204
|
+
view.set_path('/posts')
|
205
|
+
|
206
|
+
yielded = []
|
207
|
+
block = -> (crumb) { yielded << crumb.to_a }
|
208
|
+
view.breadcrumb_trail(&block)
|
209
|
+
|
210
|
+
expect(yielded).to eq([
|
211
|
+
['home-sw...', '/', false],
|
212
|
+
['posts-f...', '/posts', true]
|
213
|
+
])
|
214
|
+
end
|
215
|
+
|
216
|
+
it "allows to overwrite global configuration" do
|
217
|
+
allow(Loaf.configuration).to receive(:crumb_length).and_return(10)
|
218
|
+
view = DummyView.new
|
219
|
+
view.breadcrumb('home-sweet-home', :home_path)
|
220
|
+
view.breadcrumb('posts-for-everybody', :posts_path)
|
221
|
+
view.set_path('/posts')
|
222
|
+
|
223
|
+
yielded = []
|
224
|
+
block = -> (crumb) { yielded << crumb.to_a }
|
225
|
+
view.breadcrumb_trail(crumb_length: 15, &block)
|
226
|
+
|
227
|
+
expect(yielded).to eq([
|
228
|
+
['home-sweet-home', '/', false],
|
229
|
+
['posts-for-ev...', '/posts', true]
|
230
|
+
])
|
231
|
+
end
|
232
|
+
end
|