require 'spec_helper'
describe SimpleNavigation::Item do
before(:each) do
@item_container = stub(:item_container, :level => 1, :selected_class => nil).as_null_object
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
@adapter = stub(:adapter)
SimpleNavigation.stub!(:adapter => @adapter)
end
describe 'initialize' do
context 'subnavigation' do
before(:each) do
@subnav_container = stub(:subnav_container).as_null_object
SimpleNavigation::ItemContainer.stub!(:new => @subnav_container)
end
context 'block given' do
it "should create a new ItemContainer with a level+1" do
SimpleNavigation::ItemContainer.should_receive(:new).with(2)
SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) {}
end
it "should call the block" do
@subnav_container.should_receive(:test)
SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) {|subnav| subnav.test}
end
end
context 'no block given' do
context 'items given' do
before(:each) do
@items = stub(:items)
end
it "should create a new ItemContainer with a level+1" do
SimpleNavigation::ItemContainer.should_receive(:new).with(2)
SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}, @items)
end
it "should set the items on the subnav_container" do
@subnav_container.should_receive(:items=).with(@items)
SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}, @items)
end
end
context 'no items given' do
it "should not create a new ItemContainer" do
SimpleNavigation::ItemContainer.should_not_receive(:new)
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
end
end
end
end
context ':method option' do
context 'defined' do
before(:each) do
@options = {:method => :delete}
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
end
it 'should set the method as instance_var' do
@item.method.should == :delete
end
it 'should set the html-options without the method' do
@item.instance_variable_get(:@html_options).key?(:method).should be_false
end
end
context 'undefined' do
it 'should set the instance-var to nil' do
@item.method.should be_nil
end
end
end
context 'setting class and id on the container' do
before(:each) do
@options = {:container_class => 'container_class', :container_id => 'container_id'}
end
it {@item_container.should_receive(:dom_class=).with('container_class')}
it {@item_container.should_receive(:dom_id=).with('container_id')}
after(:each) do
SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
end
end
context ':highlights_on option' do
context 'defined' do
before(:each) do
@highlights_on = stub(:option)
@options = {:highlights_on => @highlights_on}
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
end
it 'should set the method as instance_var' do
@item.highlights_on.should == @highlights_on
end
it 'should set the html-options without the method' do
@item.instance_variable_get(:@html_options).key?(:highlights_on).should be_false
end
end
context 'undefined' do
it 'should set the instance-var to nil' do
@item.highlights_on.should be_nil
end
end
end
context 'url' do
context 'url is a string' do
before(:each) do
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
end
it {@item.url.should == 'url'}
end
context 'url is a proc' do
before(:each) do
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', Proc.new {"my_" + "url"}, {})
end
it {@item.url.should == 'my_url'}
end
context 'url is nil' do
before(:each) do
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', nil, {})
end
it {@item.url.should == nil}
end
context 'url is unspecified' do
before(:each) do
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name')
end
it {@item.url.should == nil}
end
end
context 'optional url and optional options' do
context 'when constructed without any optional parameters' do
before(:each) do
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name')
end
it {@item.url.should == nil}
it {@item.instance_variable_get(:@html_options).should == {}}
end
context 'when constructed with only a url' do
before(:each) do
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url')
end
it {@item.url.should == 'url'}
it {@item.instance_variable_get(:@html_options).should == {}}
end
context 'when constructed with only options' do
before(:each) do
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', {:option => true})
end
it {@item.url.should == nil}
it {@item.instance_variable_get(:@html_options).should == {:option => true}}
end
context 'when constructed with a url and options' do
before(:each) do
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {:option => true})
end
it {@item.url.should == 'url'}
it {@item.instance_variable_get(:@html_options).should == {:option => true}}
end
end
end
describe 'name' do
before(:each) do
SimpleNavigation.config.stub!(:name_generator => Proc.new {|name| "#{name}"})
end
context 'default (generator is applied)' do
it {@item.name.should == "name"}
end
context 'generator is skipped' do
it {@item.name(:apply_generator => false).should == 'name'}
end
end
describe 'selected?' do
context 'explicitly selected' do
before(:each) do
@item.stub!(:selected_by_config? => true)
end
it {@item.should be_selected}
it "should not evaluate the subnav or urls" do
@item.should_not_receive(:selected_by_subnav?)
@item.should_not_receive(:selected_by_condition?)
@item.selected?
end
end
context 'not explicitly selected' do
before(:each) do
@item.stub!(:selected_by_config? => false)
end
context 'subnav is selected' do
before(:each) do
@item.stub!(:selected_by_subnav? => true)
end
it {@item.should be_selected}
end
context 'subnav is not selected' do
before(:each) do
@item.stub!(:selected_by_subnav? => false)
end
context 'selected by condition' do
before(:each) do
@item.stub!(:selected_by_condition? => true)
end
it {@item.should be_selected}
end
context 'not selected by condition' do
before(:each) do
@item.stub!(:selected_by_condition? => false)
end
it {@item.should_not be_selected}
end
end
end
end
describe 'selected_class' do
context 'selected_class is defined in context' do
before(:each) do
@item_container = stub(:item_container, :level => 1, :selected_class => 'context_defined').as_null_object
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
@item.stub!(:selected? => true)
end
it {@item.instance_eval {selected_class.should == 'context_defined'}}
end
context 'item is selected' do
before(:each) do
@item.stub!(:selected? => true)
end
it {@item.instance_eval {selected_class.should == 'selected'}}
end
context 'item is not selected' do
before(:each) do
@item.stub!(:selected? => false)
end
it {@item.instance_eval {selected_class.should == nil}}
end
end
describe 'html_options' do
describe 'class' do
context 'with classes defined in options' do
before(:each) do
@options = {:class => 'my_class'}
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
end
context 'with item selected' do
before(:each) do
@item.stub!(:selected? => true, :selected_by_condition? => true)
end
it {@item.html_options[:class].should == 'my_class selected simple-navigation-active-leaf'}
end
context 'with item not selected' do
before(:each) do
@item.stub!(:selected? => false, :selected_by_condition? => false)
end
it {@item.html_options[:class].should == 'my_class'}
end
end
context 'without classes in options' do
before(:each) do
@options = {}
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
end
context 'with item selected' do
before(:each) do
@item.stub!(:selected? => true, :selected_by_condition? => true)
end
it {@item.html_options[:class].should == 'selected simple-navigation-active-leaf'}
end
context 'with item not selected' do
before(:each) do
@item.stub!(:selected? => false, :selected_by_condition? => false)
end
it {@item.html_options[:class].should be_blank}
end
end
end
describe 'id' do
context 'with autogenerate_item_ids == true' do
before(:each) do
@item.stub!(:autogenerate_item_ids? => true)
@item.stub!(:selected? => false, :selected_by_condition? => false)
end
context 'with id defined in options' do
before(:each) do
@item.html_options = {:id => 'my_id'}
end
it {@item.html_options[:id].should == 'my_id'}
end
context 'with no id defined in options (using default id)' do
before(:each) do
@item.html_options = {}
end
it {@item.html_options[:id].should == 'my_key'}
end
end
context 'with autogenerate_item_ids == false' do
before(:each) do
@item.stub!(:autogenerate_item_ids? => false)
@item.stub!(:selected? => false, :selected_by_condition? => false)
end
context 'with id defined in options' do
before(:each) do
@item.html_options = {:id => 'my_id'}
end
it {@item.html_options[:id].should == 'my_id'}
end
context 'with no id definied in options (using default id)' do
before(:each) do
@item.html_options = {}
end
it {@item.html_options[:id].should be_nil}
end
end
end
end
describe 'selected_by_subnav?' do
context 'item has subnav' do
before(:each) do
@sub_navigation = stub(:sub_navigation)
@item.stub!(:sub_navigation => @sub_navigation)
end
it "should return true if subnav is selected" do
@sub_navigation.stub!(:selected? => true, :selected_by_condition? => true)
@item.should be_selected_by_subnav
end
it "should return false if subnav is not selected" do
@sub_navigation.stub!(:selected? => false, :selected_by_condition? => true)
@item.should_not be_selected_by_subnav
end
end
context 'item does not have subnav' do
before(:each) do
@item.stub!(:sub_navigation => @sub_navigation)
end
it {@item.should_not be_selected_by_subnav}
end
end
describe 'selected_by_condition?' do
context ':highlights_on option is set' do
before(:each) do
@item.stub!(:highlights_on => /^\/current/)
SimpleNavigation.stub!(:request_uri => '/current_url')
end
it "should not check for autohighlighting" do
@item.should_not_receive(:auto_highlight?)
@item.send(:selected_by_condition?)
end
context ':highlights_on is a regexp' do
context 'regexp matches current_url' do
it {@item.send(:selected_by_condition?).should be_true}
end
context 'regexp does not match current_url' do
before(:each) do
@item.stub!(:highlights_on => /^\/no_match/)
end
it {@item.send(:selected_by_condition?).should be_false}
end
end
context ':highlights_on is a lambda' do
context 'truthy lambda results in selection' do
before(:each) do
@item.stub!(:highlights_on => lambda{true})
end
it {@item.send(:selected_by_condition?).should be_true}
end
context 'falsey lambda results in no selection' do
before(:each) do
@item.stub!(:highlights_on => lambda{false})
end
it {@item.send(:selected_by_condition?).should be_false}
end
end
context ':highlights_on is :subpath' do
before(:each) do
@item.stub!(:url => '/resources')
@item.stub!(:highlights_on => :subpath)
end
context 'we are in a route beginning with this item path' do
before(:each) do
SimpleNavigation.stub!(:request_uri => '/resources/id')
end
it {@item.send(:selected_by_condition?).should be_true}
end
context 'we are in a route that has a similar name' do
before(:each) do
SimpleNavigation.stub!(:request_uri => '/resources_group/id')
end
it {@item.send(:selected_by_condition?).should be_false}
end
context 'we are in a route not beginning with this item path' do
before(:each) do
SimpleNavigation.stub!(:request_uri => '/another_resource/id')
end
it {@item.send(:selected_by_condition?).should be_false}
end
end
context ':highlights_on is not a regexp or a proc' do
before(:each) do
@item.stub!(:highlights_on => "not a regexp")
end
it "should raise an error" do
lambda {@item.send(:selected_by_condition?).should raise_error(ArgumentError)}
end
end
end
context ':highlights_on option is not set' do
before(:each) do
@item.stub!(:highlights_on => nil)
end
it "should check for autohighlighting" do
@item.should_receive(:auto_highlight?)
@item.send(:selected_by_condition?)
end
end
context 'auto_highlight is turned on' do
before(:each) do
@item.stub!(:auto_highlight? => true)
end
context 'root path matches' do
before(:each) do
@item.stub!(:root_path_match? => true)
end
it {@item.send(:selected_by_condition?).should be_true}
end
context 'root path does not match' do
before(:each) do
@item.stub!(:root_path_match? => false)
end
context 'current request url matches url' do
before(:each) do
@adapter.stub!(:current_page? => true)
end
it "should test with the item's url" do
@adapter.should_receive(:current_page?).with('url')
@item.send(:selected_by_condition?)
end
it "should remove anchors before testing the item's url" do
@item.stub!(:url => 'url#anchor')
@adapter.should_receive(:current_page?).with('url')
@item.send(:selected_by_condition?)
end
it "should not be queried when url is nil" do
@item.stub!(:url => nil)
@adapter.should_not_receive(:current_page?)
@item.send(:selected_by_condition?)
end
it {@item.send(:selected_by_condition?).should be_true}
end
context 'no match' do
before(:each) do
@adapter.stub!(:current_page? => false)
end
it {@item.send(:selected_by_condition?).should be_false}
end
end
end
context 'auto_highlight is turned off' do
before(:each) do
@item.stub!(:auto_highlight? => false)
end
it {@item.send(:selected_by_condition?).should be_false}
end
end
describe 'root_path_match?' do
it "should match if both url == /" do
@adapter.stub!(:request_path => '/')
@item.stub!(:url => '/')
@item.send(:root_path_match?).should be_true
end
it "should not match if item url is not /" do
@adapter.stub(:request_path => '/')
@item.stub!(:url => '/bla')
@item.send(:root_path_match?).should be_false
end
it "should not match if request url is not /" do
@adapter.stub(:request_path => '/bla')
@item.stub!(:url => '/')
@item.send(:root_path_match?).should be_false
end
it "should not match if urls do not match" do
@adapter.stub(:request_path => 'bla')
@item.stub!(:url => '/bli')
@item.send(:root_path_match?).should be_false
end
it "should not match if url is nil" do
@adapter.stub(:request_path => 'bla')
@item.stub!(:url => nil)
@item.send(:root_path_match?).should be_false
end
end
describe 'auto_highlight?' do
before(:each) do
@global = stub(:config)
SimpleNavigation.stub!(:config => @global)
end
context 'global auto_highlight on' do
before(:each) do
@global.stub!(:auto_highlight => true)
end
context 'container auto_highlight on' do
before(:each) do
@item_container.stub!(:auto_highlight => true)
end
it {@item.send(:auto_highlight?).should be_true}
end
context 'container auto_highlight off' do
before(:each) do
@item_container.stub!(:auto_highlight => false)
end
it {@item.send(:auto_highlight?).should be_false}
end
end
context 'global auto_highlight off' do
before(:each) do
@global.stub!(:auto_highlight => false)
end
context 'container auto_highlight on' do
before(:each) do
@item_container.stub!(:auto_highlight => true)
end
it {@item.send(:auto_highlight?).should be_false}
end
context 'container auto_highlight off' do
before(:each) do
@item_container.stub!(:auto_highlight => false)
end
it {@item.send(:auto_highlight?).should be_false}
end
end
end
describe 'autogenerated_item_id' do
context 'calls' do
before(:each) do
@id_generator = stub(:id_generator)
SimpleNavigation.config.stub!(:id_generator => @id_generator)
end
it "should call the configured generator with the key as param" do
@id_generator.should_receive(:call).with(:my_key)
@item.send(:autogenerated_item_id)
end
end
context 'default generator' do
it {@item.send(:autogenerated_item_id).should == 'my_key'}
end
end
end