# encoding: utf-8 RSpec.describe Loaf::ViewExtensions, '#breadcrumb_trail' do it "resolves breadcrumb paths" do view = DummyView.new view.breadcrumb('home', :home_path) view.breadcrumb('posts', :posts_path) view.set_path('/posts') yielded = [] block = -> (crumb) { yielded << crumb.to_a } view.breadcrumb_trail(&block) expect(yielded).to eq([ ['home', '/', false], ['posts', '/posts', true] ]) end it "matches current path with :inclusive option as default" do view = DummyView.new view.breadcrumb('home', :home_path) view.breadcrumb('posts', :posts_path) view.set_path('/posts?id=73-title') yielded = [] block = -> (crumb) { yielded << crumb.to_a } view.breadcrumb_trail(&block) expect(yielded).to eq([ ['home', '/', false], ['posts', '/posts', true] ]) end it "matches current path with :inclusive when query params" do view = DummyView.new view.breadcrumb('posts', '/posts', match: :inclusive) view.set_path('/posts?foo=bar') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]]) end it "matches current path with :inclusive when nested" do view = DummyView.new view.breadcrumb('posts', '/posts', match: :inclusive) view.set_path('/posts/1/comment') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]]) end it "matches current path with :inclusive when nested" do view = DummyView.new view.breadcrumb('posts', '/posts', match: :inclusive) view.set_path('/posts/1/comment') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]]) end it "doesn't match with :inclusive when unrelated path" do view = DummyView.new view.breadcrumb('posts', '/posts', match: :inclusive) view.set_path('/post/1') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]]) end it "matches current path with :inclusive when extra trailing slash" do view = DummyView.new view.breadcrumb('posts', '/posts/', match: :inclusive) view.set_path('/posts') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts/', true]]) end it "matches current path with :inclusive when absolute path" do view = DummyView.new view.breadcrumb('posts', 'http://www.example.com/posts/', match: :inclusive) view.set_path('/posts') expect(view.breadcrumb_trail.map(&:to_a)).to eq([ ['posts', 'http://www.example.com/posts/', true] ]) end it "matches current path with :exact when trailing slash" do view = DummyView.new view.breadcrumb('posts', '/posts/', match: :exact) view.set_path('/posts') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts/', true]]) end it "fails to match current path with :exact when nested" do view = DummyView.new view.breadcrumb('posts', '/posts', match: :exact) view.set_path('/posts/1/comment') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]]) end it "fails to match current path with :exact when query params" do view = DummyView.new view.breadcrumb('posts', '/posts', match: :exact) view.set_path('/posts?foo=bar') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]]) end it "matches current path with :exclusive option when query params" do view = DummyView.new view.breadcrumb('posts', '/posts', match: :exclusive) view.set_path('/posts?foo=bar') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]]) end it "fails to match current path with :exclusive option when nested" do view = DummyView.new view.breadcrumb('posts', '/posts', match: :exclusive) view.set_path('/posts/1/comment') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]]) end it "matches current path with regex option when query params" do view = DummyView.new view.breadcrumb('posts', '/posts', match: %r{/po}) view.set_path('/posts?foo=bar') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]]) end it "matches current path with query params option" do view = DummyView.new view.breadcrumb('posts', '/posts', match: {foo: :bar}) view.set_path('/posts?foo=bar&baz=boo') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', true]]) end it "fails to match current path with query params option" do view = DummyView.new view.breadcrumb('posts', '/posts', match: {foo: :bar}) view.set_path('/posts?foo=2&baz=boo') expect(view.breadcrumb_trail.map(&:to_a)).to eq([['posts', '/posts', false]]) end it "failse to recognize the match option" do view = DummyView.new view.breadcrumb('posts', 'http://www.example.com/posts/', match: :boom) view.set_path('/posts') block = -> (*args) { } expect { view.breadcrumb_trail(&block) }.to raise_error(ArgumentError, "Unknown `:boom` match option!") end it "forces current path" do view = DummyView.new view.breadcrumb('home', :home_path) view.breadcrumb('posts', :posts_path, match: :force) view.set_path('/') yielded = [] block = -> (crumb) { yielded << crumb.to_a } view.breadcrumb_trail(&block) expect(yielded).to eq([ ['home', '/', true], ['posts', '/posts', true] ]) end it "returns enumerator without block" do view = DummyView.new view.breadcrumb('home', :home_path) view.breadcrumb('posts', :posts_path) view.set_path('/posts') result = view.breadcrumb_trail expect(result).to be_a(Enumerable) expect(result.take(2).map(&:to_a)).to eq([ ['home', '/', false], ['posts', '/posts', true] ]) end it 'validates passed options' do view = DummyView.new block = -> (name, url, styles) { } expect { view.breadcrumb_trail(unknown: true, &block) }.to raise_error(Loaf::InvalidOptions) end it 'uses global configuration for crumb formatting' do allow(Loaf.configuration).to receive(:crumb_length).and_return(10) view = DummyView.new view.breadcrumb('home-sweet-home', :home_path) view.breadcrumb('posts-for-everybody', :posts_path) view.set_path('/posts') yielded = [] block = -> (crumb) { yielded << crumb.to_a } view.breadcrumb_trail(&block) expect(yielded).to eq([ ['home-sw...', '/', false], ['posts-f...', '/posts', true] ]) end it "allows to overwrite global configuration" do allow(Loaf.configuration).to receive(:crumb_length).and_return(10) view = DummyView.new view.breadcrumb('home-sweet-home', :home_path) view.breadcrumb('posts-for-everybody', :posts_path) view.set_path('/posts') yielded = [] block = -> (crumb) { yielded << crumb.to_a } view.breadcrumb_trail(crumb_length: 15, &block) expect(yielded).to eq([ ['home-sweet-home', '/', false], ['posts-for-ev...', '/posts', true] ]) end end