simple-navigation 2.1.0 → 2.2.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/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ *2.2.0
2
+
3
+ * Allow Ranges for :level option. Credits to Ying Tsen Hong.
4
+ * Changing the API of Helpers#render_navigation. Now supports Ranges for :level option and :expand_all to render all levels as expanded. Old Api is still supported, but deprecated.
5
+ * Deprecated render_all_levels in config-file.
6
+
1
7
  *2.1.0
2
8
 
3
9
  * included Ben Marini's commit which allows individual id-generators. Thanks Ben!
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :patch: 0
3
3
  :major: 2
4
- :minor: 1
4
+ :minor: 2
@@ -6,12 +6,7 @@ SimpleNavigation::Configuration.run do |navigation|
6
6
 
7
7
  # Specify the class that will be applied to active navigation items. Defaults to 'selected'
8
8
  # navigation.selected_class = 'your_selected_class'
9
-
10
- # Normally only the current sub menu is renderedwhen render_navigation is called
11
- # setting this to true render all submenus which is useful for javascript
12
- # driven hovering menus like the jquery superfish plugin
13
- # navigation.render_all_levels = true
14
-
9
+
15
10
  # Item keys are normally added to list items as id.
16
11
  # This setting turns that off
17
12
  # navigation.autogenerate_item_ids = false
@@ -55,8 +55,23 @@ module SimpleNavigation
55
55
  self.controller.instance_variable_get(:"@sn_current_navigation_#{level}")
56
56
  end
57
57
 
58
+ # Returns the active item container for the specified level. Valid levels are
59
+ # * :all - in this case the primary_navigation is returned.
60
+ # * a specific level - the active item_container for the specified level will be returned
61
+ # * a range of levels - the active item_container for the range's minimum will be returned
62
+ #
63
+ # Returns nil if there is no active item_container for the specified level.
58
64
  def active_item_container_for(level)
59
- self.primary_navigation.active_item_container_for(level)
65
+ case level
66
+ when :all
67
+ self.primary_navigation
68
+ when Integer
69
+ self.primary_navigation.active_item_container_for(level)
70
+ when Range
71
+ self.primary_navigation.active_item_container_for(level.min)
72
+ else
73
+ raise ArgumentError, "Invalid navigation level: #{level}"
74
+ end
60
75
  end
61
76
 
62
77
  # If any navigation has been explicitely set in the controller this method evaluates the specified args set in the controller and sets
@@ -6,7 +6,8 @@ module SimpleNavigation
6
6
  class Configuration
7
7
  include Singleton
8
8
 
9
- attr_accessor :renderer, :selected_class, :render_all_levels, :autogenerate_item_ids, :id_generator, :auto_highlight
9
+ attr_accessor :renderer, :selected_class, :autogenerate_item_ids, :id_generator, :auto_highlight
10
+ attr_reader :render_all_levels
10
11
  attr_reader :primary_navigation
11
12
 
12
13
  class << self
@@ -45,12 +46,17 @@ module SimpleNavigation
45
46
  def initialize
46
47
  @renderer = SimpleNavigation::Renderer::List
47
48
  @selected_class = 'selected'
48
- @render_all_levels = false
49
49
  @autogenerate_item_ids = true
50
50
  @id_generator = Proc.new {|id| id.to_s }
51
51
  @auto_highlight = true
52
52
  end
53
53
 
54
+ # Adds a deprecation warning when this options is set in the config file
55
+ def render_all_levels=(do_it)
56
+ ActiveSupport::Deprecation.warn("Setting render_all_levels in the config-file has been deprected. Please use render_navigation(:expand_all => true) instead")
57
+ @render_all_levels = do_it
58
+ end
59
+
54
60
  # This is the main method for specifying the navigation items. It can be used in two ways:
55
61
  #
56
62
  # 1. Declaratively specify your items in the config/navigation.rb file using a block. It then yields an SimpleNavigation::ItemContainer for adding navigation items.
@@ -3,8 +3,10 @@ module SimpleNavigation
3
3
  # View helpers to render the navigation.
4
4
  #
5
5
  # Use render_navigation as following to render your navigation:
6
- # * call <tt>render_navigation</tt> without :level option to render your navigation as nested tree.
6
+ # * call <tt>render_navigation</tt> without :level option to render your complete navigation as nested tree.
7
7
  # * call <tt>render_navigation(:level => x)</tt> to render a specific navigation level (e.g. :level => 1 to render your primary navigation, :level => 2 to render the sub navigation and so forth)
8
+ # * call <tt>render_navigation(:level => 2..3)</tt> to render navigation levels 2 and 3).
9
+ # For example, you could use render_navigation(:level => 1) to render your primary navigation as tabs and render_navigation(:level => 2..3) to render the rest of the navigation as a tree in a sidebar.
8
10
  #
9
11
  # ==== Examples (using Haml)
10
12
  # #primary_navigation= render_navigation(:level => 1)
@@ -13,49 +15,44 @@ module SimpleNavigation
13
15
  #
14
16
  # #nested_navigation= render_navigation
15
17
  #
16
- # Please note that <tt>render_primary_navigation</tt> and <tt>render_sub_navigation</tt> still work, but have been deprecated and may be removed in a future release.
18
+ # #top_navigation= render_navigation(:level => 1..2)
19
+ # #sidebar_navigation= render_navigation(:level => 3)
17
20
  module Helpers
18
21
 
19
22
  # Renders the navigation according to the specified options-hash.
20
23
  #
21
24
  # The following options are supported:
22
- # * <tt>:level</tt> - defaults to :nested which renders the the sub_navigation for an active primary_navigation inside that active primary_navigation item.
25
+ # * <tt>:level</tt> - defaults to :all which renders the the sub_navigation for an active primary_navigation inside that active primary_navigation item.
23
26
  # Specify a specific level to only render that level of navigation (e.g. :level => 1 for primary_navigation etc...).
27
+ # Specifiy a Range of levels to render only those specific levels (e.g. :level => 1..2 to render both your first and second levels, maybe you want to render your third level somewhere else on the page)
28
+ # * <tt>:expand_all</tt> - defaults to false. If set to true the all specified levels will be rendered as a fully expanded tree (always open). This is useful for javascript menus like Superfish.
24
29
  # * <tt>:context</tt> - specifies the context for which you would render the navigation. Defaults to :default which loads the default navigation.rb (i.e. config/navigation.rb).
25
30
  # If you specify a context then the plugin tries to load the configuration file for that context, e.g. if you call <tt>render_navigation(:context => :admin)</tt> the file config/admin_navigation.rb
26
31
  # will be loaded and used for rendering the navigation.
27
- # * <tt>:all_open</tt> - setting this options to true means that all items are always open (ie. fully expanded tree). Same as setting render_all_levels option in the config-file.
28
32
  # * <tt>:items</tt> - you can specify the items directly (e.g. if items are dynamically generated from database). See SimpleNavigation::ItemsProvider for documentation on what to provide as items.
29
33
  def render_navigation(*args)
30
34
  args = [Hash.new] if args.empty?
31
35
  options = extract_backwards_compatible_options(*args)
32
- options = {:context => :default, :level => :nested}.merge(options)
33
- SimpleNavigation.load_config(options[:context]) rescue nil
34
- SimpleNavigation::Configuration.eval_config(self, options[:context]) rescue nil
35
- SimpleNavigation.config.render_all_levels = options[:all_open] unless options[:all_open].nil?
36
+ options = {:context => :default, :level => :all}.merge(options)
37
+ ctx = options.delete(:context)
38
+ SimpleNavigation.load_config(ctx) rescue nil
39
+ SimpleNavigation::Configuration.eval_config(self, ctx) rescue nil
36
40
  SimpleNavigation.config.items(options[:items]) if options[:items]
37
41
  SimpleNavigation.handle_explicit_navigation
38
42
  raise "no primary navigation defined, either use a navigation config file or pass items directly to render_navigation" unless SimpleNavigation.primary_navigation
39
- case options[:level]
40
- when Integer
41
- active_item_container = SimpleNavigation.active_item_container_for(options[:level])
42
- active_item_container.render if active_item_container
43
- when :nested
44
- SimpleNavigation.primary_navigation.render(true)
45
- else
46
- raise ArgumentError, "Invalid navigation level: #{options[:level]}"
47
- end
43
+ active_item_container = SimpleNavigation.active_item_container_for(options[:level])
44
+ active_item_container.render(options) unless active_item_container.nil?
48
45
  end
49
46
 
50
47
  # Deprecated. Renders the primary_navigation with the configured renderer. Calling render_navigation(:level => 0) has the same effect.
51
48
  def render_primary_navigation(options = {})
52
- ActiveSupport::Deprecation.warn("SimpleNavigation::Helpers.render_primary_navigation has been deprected. Please use render_navigation(:level => 1) instead")
49
+ ActiveSupport::Deprecation.warn("SimpleNavigation::Helpers.render_primary_navigation has been deprecated. Please use render_navigation(:level => 1) instead")
53
50
  render_navigation(options.merge(:level => 1))
54
51
  end
55
52
 
56
53
  # Deprecated. Renders the sub_navigation with the configured renderer. Calling render_navigation(:level => 1) has the same effect.
57
54
  def render_sub_navigation(options = {})
58
- ActiveSupport::Deprecation.warn("SimpleNavigation::Helpers.render_primary_navigation has been deprected. Please use render_navigation(:level => 2) instead")
55
+ ActiveSupport::Deprecation.warn("SimpleNavigation::Helpers.render_primary_navigation has been deprecated. Please use render_navigation(:level => 2) instead")
59
56
  render_navigation(options.merge(:level => 2))
60
57
  end
61
58
 
@@ -65,20 +62,33 @@ module SimpleNavigation
65
62
  case args.first
66
63
  when Hash
67
64
  options = args.first
65
+ options[:level] = options.delete(:levels) if options[:levels]
66
+ deprecated_api! if options[:level] == :primary || options[:level] == :secondary || options[:level] == :nested
68
67
  options[:level] = 1 if options[:level] == :primary
69
68
  options[:level] = 2 if options[:level] == :secondary
69
+ options[:level] = :all if options[:level] == :nested
70
70
  when Symbol
71
+ deprecated_api!
71
72
  raise ArgumentError, "Invalid arguments" unless [:primary, :secondary, :nested].include? args.first
72
73
  options = Hash.new
73
74
  options[:level] = args.first
75
+ options[:level] = :all if options[:level] == :nested
74
76
  options[:level] = 1 if options[:level] == :primary
75
77
  options[:level] = 2 if options[:level] == :secondary
76
78
  options.merge!(args[1] || {})
77
79
  else
78
80
  raise ArgumentError, "Invalid arguments"
79
81
  end
82
+ if options[:all_open]
83
+ options[:expand_all] = options.delete(:all_open)
84
+ ActiveSupport::Deprecation.warn("render_navigation(:all_open => true) has been deprecated, please use render_navigation(:expand_all => true) instead")
85
+ end
80
86
  options
81
87
  end
82
88
 
89
+ def deprecated_api!
90
+ ActiveSupport::Deprecation.warn("You are using a deprecated API of SimpleNavigation::Helpers.render_navigation, please check the documentation on http://wiki.github.com/andi/simple-navigation")
91
+ end
92
+
83
93
  end
84
94
  end
@@ -66,9 +66,9 @@ module SimpleNavigation
66
66
 
67
67
  # Renders the items in this ItemContainer using the configured renderer.
68
68
  #
69
- # Set <tt>include_sub_navigation</tt> to true if you want to nest the sub_navigation into the active parent_navigation
70
- def render(include_sub_navigation=false)
71
- self.renderer.new.render(self, include_sub_navigation)
69
+ # The options are the same as in the view's render_navigation call (they get passed on)
70
+ def render(options={})
71
+ self.renderer.new(options).render(self)
72
72
  end
73
73
 
74
74
  # Returns true if any of this container's items is selected.
@@ -8,7 +8,7 @@ module SimpleNavigation
8
8
  include ActionView::Helpers::UrlHelper
9
9
  include ActionView::Helpers::TagHelper
10
10
 
11
- attr_reader :controller
11
+ attr_reader :controller, :options
12
12
 
13
13
  class << self
14
14
 
@@ -23,21 +23,55 @@ module SimpleNavigation
23
23
 
24
24
  controller_method :form_authenticity_token, :protect_against_forgery?, :request_forgery_protection_token
25
25
 
26
- def initialize #:nodoc:
26
+ def initialize(options) #:nodoc:
27
+ @options = options
27
28
  @controller = SimpleNavigation.controller
28
29
  end
29
30
 
31
+ def expand_all?
32
+ !!options[:expand_all]
33
+ end
34
+
35
+ def level
36
+ options[:level] || :all
37
+ end
38
+
39
+ def include_sub_navigation?(item)
40
+ consider_sub_navigation?(item) && expand_sub_navigation?(item)
41
+ end
42
+
43
+ def render_sub_navigation_for(item)
44
+ item.sub_navigation.render(self.options)
45
+ end
46
+
30
47
  # Renders the specified ItemContainer to HTML.
31
48
  #
32
- # If <tt>include_sub_navigation</tt> is set to true, the renderer should nest the sub_navigation for the active navigation
33
- # inside that navigation item.
34
- #
35
- # A renderer should also take the option SimpleNavigation.config.render_all_levels into account. If it is set to true then it should render all navigation levels
36
- # independent of the <tt>include_sub_navigation</tt> option.
49
+ # When implementing a renderer, please consider to call include_sub_navigation? to determin
50
+ # whether an item's sub_navigation should be rendered or not.
37
51
  #
38
- def render(item_container, include_sub_navigation=false)
52
+ def render(item_container)
39
53
  raise 'subclass responsibility'
40
54
  end
55
+
56
+ protected
57
+
58
+ def consider_sub_navigation?(item)
59
+ return false if item.sub_navigation.nil?
60
+ case level
61
+ when :all
62
+ return true
63
+ when Integer
64
+ return false
65
+ when Range
66
+ return item.sub_navigation.level <= level.max
67
+ end
68
+ false
69
+ end
70
+
71
+ def expand_sub_navigation?(item)
72
+ expand_all? || item.selected?
73
+ end
74
+
41
75
 
42
76
  end
43
77
  end
@@ -4,28 +4,24 @@ module SimpleNavigation
4
4
  # Renders an ItemContainer as a <ul> element and its containing items as <li> elements.
5
5
  # It adds the 'selected' class to li element AND the link inside the li element that is currently active.
6
6
  #
7
- # If the sub navigation should be included, it renders another <ul> containing the sub navigation inside the active <li> element.
8
- #
9
- # If the SimpleNavigation.config.render_all_levels option is set to true, it always renders all levels of navigation (fully expanded tree).
7
+ # If the sub navigation should be included (based on the level and expand_all options), it renders another <ul> containing the sub navigation inside the active <li> element.
10
8
  #
11
9
  # By default, the renderer sets the item's key as dom_id for the rendered <li> element unless the config option <tt>autogenerate_item_ids</tt> is set to false.
12
10
  # The id can also be explicitely specified by setting the id in the html-options of the 'item' method in the config/navigation.rb file.
13
11
  class List < SimpleNavigation::Renderer::Base
14
12
 
15
- def render(item_container, include_sub_navigation=false)
13
+ def render(item_container)
16
14
  list_content = item_container.items.inject([]) do |list, item|
17
15
  html_options = item.html_options
18
16
  li_content = link_to(item.name, item.url, :class => item.selected_class, :method => item.method)
19
- if item.sub_navigation
20
- if SimpleNavigation.config.render_all_levels || (include_sub_navigation && item.selected?)
21
- li_content << (item.sub_navigation.render(include_sub_navigation))
22
- end
17
+ if include_sub_navigation?(item)
18
+ li_content << render_sub_navigation_for(item)
23
19
  end
24
20
  list << content_tag(:li, li_content, html_options)
25
21
  end
26
22
  content_tag(:ul, list_content.join, {:id => item_container.dom_id, :class => item_container.dom_class})
27
23
  end
28
-
29
24
  end
25
+
30
26
  end
31
- end
27
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{simple-navigation}
8
- s.version = "2.1.0"
8
+ s.version = "2.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andi Schacke"]
12
- s.date = %q{2009-12-18}
12
+ s.date = %q{2010-01-17}
13
13
  s.description = %q{With the simple-navigation gem installed you can easily create multilevel navigations for your Ruby on Rails applications. The navigation is defined in a single configuration file. It supports automatic as well as explicit highlighting of the currently active navigation.}
14
14
  s.email = %q{andreas.schacke@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -120,9 +120,6 @@ describe SimpleNavigation::Configuration do
120
120
  it "should set the selected_class to 'selected' as default" do
121
121
  @config.selected_class.should == 'selected'
122
122
  end
123
- it "should set render_all_levels to false as default" do
124
- @config.render_all_levels.should be_false
125
- end
126
123
  it "should set autogenerate_item_ids to true as default" do
127
124
  @config.autogenerate_item_ids.should be_true
128
125
  end
@@ -186,6 +183,15 @@ describe SimpleNavigation::Configuration do
186
183
  end
187
184
  end
188
185
 
186
+ describe 'render_all_levels=' do
187
+ it "should set the instance var" do
188
+ ActiveSupport::Deprecation.silence do
189
+ @config.render_all_levels = true
190
+ @config.render_all_levels.should be_true
191
+ end
192
+ end
193
+ end
194
+
189
195
  describe 'loaded?' do
190
196
  it "should return true if primary_nav is set" do
191
197
  @config.instance_variable_set(:@primary_navigation, :bla)
@@ -34,28 +34,7 @@ describe SimpleNavigation::Helpers do
34
34
  SimpleNavigation::Configuration.should_receive(:eval_config).with(@controller, :default)
35
35
  @controller.render_navigation
36
36
  end
37
-
38
- describe "regarding setting the 'render_all_levels' option" do
39
- context 'all_open is not specified' do
40
- it "should not set the option" do
41
- SimpleNavigation.config.should_not_receive(:render_all_levels=)
42
- @controller.render_navigation
43
- end
44
- end
45
- context 'all_open is true' do
46
- it "should set the option to true" do
47
- SimpleNavigation.config.should_receive(:render_all_levels=).with(true)
48
- @controller.render_navigation(:all_open => true)
49
- end
50
- end
51
- context 'all_open is false' do
52
- it "should set the option to false" do
53
- SimpleNavigation.config.should_receive(:render_all_levels=).with(false)
54
- @controller.render_navigation(:all_open => false)
55
- end
56
- end
57
- end
58
-
37
+
59
38
  describe 'regarding setting of items' do
60
39
  context 'not items specified in options' do
61
40
  it "should not set the items directly" do
@@ -81,17 +60,43 @@ describe SimpleNavigation::Helpers do
81
60
  it {lambda {@controller.render_navigation}.should raise_error}
82
61
  end
83
62
 
63
+ context 'rendering of the item_container' do
64
+ before(:each) do
65
+ @active_item_container = stub(:item_container, :null_object => true)
66
+ SimpleNavigation.stub!(:active_item_container_for => @active_item_container)
67
+ end
68
+ it "should lookup the active_item_container based on the level" do
69
+ SimpleNavigation.should_receive(:active_item_container_for).with(:all)
70
+ @controller.render_navigation
71
+ end
72
+ context 'active_item_container is nil' do
73
+ before(:each) do
74
+ SimpleNavigation.stub!(:active_item_container_for => nil)
75
+ end
76
+ it "should not call render" do
77
+ @active_item_container.should_not_receive(:render)
78
+ @controller.render_navigation
79
+ end
80
+ end
81
+ context 'active_item_container is not nil' do
82
+ it "should call render on the container" do
83
+ @active_item_container.should_receive(:render)
84
+ @controller.render_navigation
85
+ end
86
+ end
87
+ end
88
+
84
89
  context 'primary' do
85
90
  it "should call render on the primary_navigation" do
86
91
  @primary_navigation.should_receive(:render)
87
- @controller.render_navigation(:primary)
92
+ ActiveSupport::Deprecation.silence {@controller.render_navigation(:primary)}
88
93
  end
89
94
  it "should call render on the primary_navigation (specifying level through options)" do
90
95
  @primary_navigation.should_receive(:render)
91
- @controller.render_navigation(:level => :primary)
96
+ ActiveSupport::Deprecation.silence {@controller.render_navigation(:level => :primary)}
92
97
  end
93
98
  it "should call render on the primary_navigation (specifying level through options)" do
94
- @primary_navigation.should_receive(:render)
99
+ @primary_navigation.should_receive(:render).with(:level => 1)
95
100
  @controller.render_navigation(:level => 1)
96
101
  end
97
102
  end
@@ -104,19 +109,19 @@ describe SimpleNavigation::Helpers do
104
109
  end
105
110
  it "should find the selected sub_navigation for the specified level" do
106
111
  SimpleNavigation.should_receive(:active_item_container_for).with(2)
107
- @controller.render_navigation(:secondary)
112
+ ActiveSupport::Deprecation.silence {@controller.render_navigation(:secondary)}
108
113
  end
109
114
  it "should find the selected sub_navigation for the specified level" do
110
115
  SimpleNavigation.should_receive(:active_item_container_for).with(2)
111
- @controller.render_navigation(:level => :secondary)
116
+ ActiveSupport::Deprecation.silence {@controller.render_navigation(:level => :secondary)}
112
117
  end
113
118
  it "should find the selected sub_navigation for the specified level" do
114
119
  SimpleNavigation.should_receive(:active_item_container_for).with(1)
115
120
  @controller.render_navigation(:level => 1)
116
121
  end
117
122
  it "should call render on the active item_container" do
118
- @selected_item_container.should_receive(:render)
119
- @controller.render_navigation(:secondary)
123
+ @selected_item_container.should_receive(:render).with(:level => 2)
124
+ ActiveSupport::Deprecation.silence {@controller.render_navigation(:secondary)}
120
125
  end
121
126
  end
122
127
  context 'without an active item_container set' do
@@ -124,22 +129,22 @@ describe SimpleNavigation::Helpers do
124
129
  SimpleNavigation.stub!(:active_item_container_for => nil)
125
130
  end
126
131
  it "should not raise an error" do
127
- lambda{@controller.render_navigation(:secondary)}.should_not raise_error
132
+ lambda{ActiveSupport::Deprecation.silence {@controller.render_navigation(:secondary)}}.should_not raise_error
128
133
  end
129
134
  end
130
135
 
131
136
  end
132
137
 
133
138
  context 'nested' do
134
- it "should call render on the primary navigation with the include_subnavigation option set" do
135
- @primary_navigation.should_receive(:render).with(true)
136
- @controller.render_navigation(:nested)
139
+ it "should call render on the primary navigation with the :level => :all option set" do
140
+ @primary_navigation.should_receive(:render).with(:level => :all)
141
+ ActiveSupport::Deprecation.silence {@controller.render_navigation(:nested)}
137
142
  end
138
143
  end
139
144
 
140
145
  context 'unknown level' do
141
146
  it "should raise an error" do
142
- lambda {@controller.render_navigation(:unknown)}.should raise_error(ArgumentError)
147
+ lambda {ActiveSupport::Deprecation.silence {@controller.render_navigation(:unknown)}}.should raise_error(ArgumentError)
143
148
  end
144
149
  it "should raise an error" do
145
150
  lambda {@controller.render_navigation(:level => :unknown)}.should raise_error(ArgumentError)
@@ -151,7 +156,7 @@ describe SimpleNavigation::Helpers do
151
156
  end
152
157
 
153
158
  describe 'render_primary_navigation' do
154
- it "should delegate to render_navigation(:primary)" do
159
+ it "should delegate to render_navigation(:level => 1)" do
155
160
  ActiveSupport::Deprecation.silence do
156
161
  @controller.should_receive(:render_navigation).with(:level => 1)
157
162
  @controller.render_primary_navigation
@@ -160,7 +165,7 @@ describe SimpleNavigation::Helpers do
160
165
  end
161
166
 
162
167
  describe 'render_sub_navigation' do
163
- it "should delegate to render_navigation(:secondary)" do
168
+ it "should delegate to render_navigation(:level => 2)" do
164
169
  ActiveSupport::Deprecation.silence do
165
170
  @controller.should_receive(:render_navigation).with(:level => 2)
166
171
  @controller.render_sub_navigation
@@ -168,4 +173,22 @@ describe SimpleNavigation::Helpers do
168
173
  end
169
174
  end
170
175
 
176
+ describe "should treat :level and :levels options the same" do
177
+ before(:each) do
178
+ @selected_item_container = stub(:selected_container, :null_object => true)
179
+ SimpleNavigation.stub!(:active_item_container_for => @selected_item_container)
180
+ end
181
+ it "should pass a valid levels options as level" do
182
+ @selected_item_container.should_receive(:render).with(:level => 2)
183
+ @controller.render_navigation(:levels => 2)
184
+ end
185
+ end
186
+
187
+ describe 'option all_open should work as expand_all' do
188
+ it "should call render on the primary navigation with the include_subnavigation option set" do
189
+ @primary_navigation.should_receive(:render).with(:level => :all, :expand_all => true)
190
+ ActiveSupport::Deprecation.silence {@controller.render_navigation(:level => :all, :all_open => true)}
191
+ end
192
+ end
193
+
171
194
  end
@@ -315,18 +315,15 @@ describe SimpleNavigation::ItemContainer do
315
315
  @item_container.stub!(:renderer).and_return(@renderer)
316
316
  @items = stub(:items)
317
317
  @item_container.stub!(:items).and_return(@items)
318
+ @options = stub(:options)
318
319
  end
319
320
  it "should instatiate a renderer" do
320
- @renderer.should_receive(:new)
321
- @item_container.render(:current_navigation)
321
+ @renderer.should_receive(:new).with(@options)
322
+ @item_container.render(@options)
322
323
  end
323
324
  it "should call render on the renderer and pass self" do
324
- @renderer_instance.should_receive(:render).with(@item_container, anything)
325
- @item_container.render(:current_navigation)
326
- end
327
- it "should call render on the renderer and pass the include_sub_navigation option" do
328
- @renderer_instance.should_receive(:render).with(anything, true)
329
- @item_container.render(true)
325
+ @renderer_instance.should_receive(:render).with(@item_container)
326
+ @item_container.render
330
327
  end
331
328
 
332
329
  end
@@ -2,9 +2,10 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
2
2
 
3
3
  describe SimpleNavigation::Renderer::Base do
4
4
  before(:each) do
5
+ @options = stub(:options, :null_object => true)
5
6
  @controller = stub(:controller)
6
7
  SimpleNavigation.stub!(:controller).and_return(@controller)
7
- @base_renderer = SimpleNavigation::Renderer::Base.new
8
+ @base_renderer = SimpleNavigation::Renderer::Base.new(@options)
8
9
  end
9
10
  it "should inclue ActionView::Helpers::UrlHelper" do
10
11
  @base_renderer.should respond_to(:link_to)
@@ -21,6 +22,7 @@ describe SimpleNavigation::Renderer::Base do
21
22
 
22
23
  describe 'initialize' do
23
24
  it {@base_renderer.controller.should == @controller}
25
+ it {@base_renderer.options.should == @options}
24
26
  end
25
27
 
26
28
  describe 'controller_method' do
@@ -56,5 +58,154 @@ describe SimpleNavigation::Renderer::Base do
56
58
  lambda {@base_renderer.render(:container)}.should raise_error('subclass responsibility')
57
59
  end
58
60
  end
61
+
62
+ describe 'expand_all?' do
63
+ context 'option is set' do
64
+ context 'expand_all is true' do
65
+ before(:each) do
66
+ @base_renderer.stub!(:options => {:expand_all => true})
67
+ end
68
+ it {@base_renderer.expand_all?.should be_true}
69
+ end
70
+ context 'expand_all is false' do
71
+ before(:each) do
72
+ @base_renderer.stub!(:options => {:expand_all => false})
73
+ end
74
+ it {@base_renderer.expand_all?.should be_false}
75
+ end
76
+ end
77
+ context 'option is not set' do
78
+ before(:each) do
79
+ @base_renderer.stub!(:options => {})
80
+ end
81
+ it {@base_renderer.expand_all?.should be_false}
82
+ end
83
+ end
84
+
85
+ describe 'level' do
86
+ context 'options[level] is set' do
87
+ before(:each) do
88
+ @base_renderer.stub!(:options => {:level => 1})
89
+ end
90
+ it {@base_renderer.level.should == 1}
91
+ end
92
+ context 'options[level] is not set' do
93
+ before(:each) do
94
+ @base_renderer.stub!(:options => {})
95
+ end
96
+ it {@base_renderer.level.should == :all}
97
+ end
98
+ end
99
+
100
+ describe 'consider_sub_navigation?' do
101
+ before(:each) do
102
+ @item = stub(:item)
103
+ end
104
+ context 'item has no subnavigation' do
105
+ before(:each) do
106
+ @item.stub!(:sub_navigation => nil)
107
+ end
108
+ it {@base_renderer.send(:consider_sub_navigation?, @item).should be_false}
109
+ end
110
+ context 'item has subnavigation' do
111
+ before(:each) do
112
+ @sub_navigation = stub(:sub_navigation)
113
+ @item.stub!(:sub_navigation => @sub_navigation)
114
+ end
115
+ context 'level is something unknown' do
116
+ before(:each) do
117
+ @base_renderer.stub!(:level => 'unknown')
118
+ end
119
+ it {@base_renderer.send(:consider_sub_navigation?, @item).should be_false}
120
+ end
121
+ context 'level is :all' do
122
+ before(:each) do
123
+ @base_renderer.stub!(:level => :all)
124
+ end
125
+ it {@base_renderer.send(:consider_sub_navigation?, @item).should be_true}
126
+ end
127
+ context 'level is an Integer' do
128
+ before(:each) do
129
+ @base_renderer.stub!(:level => 2)
130
+ end
131
+ it {@base_renderer.send(:consider_sub_navigation?, @item).should be_false}
132
+ end
133
+ context 'level is a Range' do
134
+ before(:each) do
135
+ @base_renderer.stub!(:level => 2..3)
136
+ end
137
+ context 'subnavs level > range.max' do
138
+ before(:each) do
139
+ @sub_navigation.stub!(:level => 4)
140
+ end
141
+ it {@base_renderer.send(:consider_sub_navigation?, @item).should be_false}
142
+ end
143
+ context 'subnavs level = range.max' do
144
+ before(:each) do
145
+ @sub_navigation.stub!(:level => 3)
146
+ end
147
+ it {@base_renderer.send(:consider_sub_navigation?, @item).should be_true}
148
+
149
+ end
150
+ context 'subnavs level < range.max' do
151
+ before(:each) do
152
+ @sub_navigation.stub!(:level => 2)
153
+ end
154
+ it {@base_renderer.send(:consider_sub_navigation?, @item).should be_true}
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ describe 'include_sub_navigation?' do
161
+ before(:each) do
162
+ @item = stub(:item)
163
+ end
164
+ context 'consider_sub_navigation? is true' do
165
+ before(:each) do
166
+ @base_renderer.stub!(:consider_sub_navigation? => true)
167
+ end
168
+ context 'expand_sub_navigation? is true' do
169
+ before(:each) do
170
+ @base_renderer.stub!(:expand_sub_navigation? => true)
171
+ end
172
+ it {@base_renderer.include_sub_navigation?(@item).should be_true}
173
+ end
174
+ context 'expand_sub_navigation? is false' do
175
+ before(:each) do
176
+ @base_renderer.stub!(:expand_sub_navigation? => false)
177
+ end
178
+ it {@base_renderer.include_sub_navigation?(@item).should be_false}
179
+ end
180
+ end
181
+ context 'consider_sub_navigation is false' do
182
+ before(:each) do
183
+ @base_renderer.stub!(:consider_sub_navigation? => false)
184
+ end
185
+ context 'expand_sub_navigation? is true' do
186
+ before(:each) do
187
+ @base_renderer.stub!(:expand_sub_navigation? => true)
188
+ end
189
+ it {@base_renderer.include_sub_navigation?(@item).should be_false}
190
+ end
191
+ context 'expand_sub_navigation? is false' do
192
+ before(:each) do
193
+ @base_renderer.stub!(:expand_sub_navigation? => false)
194
+ end
195
+ it {@base_renderer.include_sub_navigation?(@item).should be_false}
196
+ end
197
+ end
198
+ end
199
+
200
+ describe 'render_sub_navigation_for' do
201
+ before(:each) do
202
+ @sub_navigation = stub(:sub_navigation)
203
+ @item = stub(:item, :sub_navigation => @sub_navigation)
204
+ end
205
+ it "should call render on the sub_navigation (passing the options)" do
206
+ @sub_navigation.should_receive(:render).with(@options)
207
+ @base_renderer.render_sub_navigation_for(@item)
208
+ end
209
+ end
59
210
 
60
211
  end
@@ -47,11 +47,11 @@ describe SimpleNavigation::Renderer::List do
47
47
  container
48
48
  end
49
49
 
50
- def render(current_nav=nil, include_subnav=false)
50
+ def render(current_nav=nil, options={:level => :all})
51
51
  primary_navigation = primary_container
52
52
  select_item(current_nav) if current_nav
53
- @renderer = SimpleNavigation::Renderer::List.new
54
- HTML::Document.new(@renderer.render(primary_navigation, include_subnav)).root
53
+ @renderer = SimpleNavigation::Renderer::List.new(options)
54
+ HTML::Document.new(@renderer.render(primary_navigation)).root
55
55
  end
56
56
 
57
57
  it "should render a ul-tag around the items" do
@@ -103,31 +103,25 @@ describe SimpleNavigation::Renderer::List do
103
103
 
104
104
  context 'nested sub_navigation' do
105
105
  it "should nest the current_primary's subnavigation inside the selected li-element" do
106
- HTML::Selector.new('li.selected ul li').select(render(:invoices, true)).should have(2).entries
106
+ HTML::Selector.new('li.selected ul li').select(render(:invoices)).should have(2).entries
107
107
  end
108
108
  it "should be possible to identify sub items using an html selector (using ids)" do
109
- HTML::Selector.new('#invoices #subnav1').select(render(:invoices, true)).should have(1).entries
109
+ HTML::Selector.new('#invoices #subnav1').select(render(:invoices)).should have(1).entries
110
110
  end
111
- context 'render_all_levels = false' do
112
- before(:each) do
113
- SimpleNavigation.config.render_all_levels = false
114
- end
111
+ context 'expand_all => false' do
115
112
  it "should not render the invoices submenu if the user-primary is active" do
116
- HTML::Selector.new('#invoices #subnav1').select(render(:users, true)).should be_empty
117
- HTML::Selector.new('#invoices #subnav2').select(render(:users, true)).should be_empty
113
+ HTML::Selector.new('#invoices #subnav1').select(render(:users, :level => :all, :expand_all => false)).should be_empty
114
+ HTML::Selector.new('#invoices #subnav2').select(render(:users, :level => :all, :expand_all => false)).should be_empty
118
115
  end
119
116
  end
120
117
 
121
- context 'render_all_levels = true' do
122
- before(:each) do
123
- SimpleNavigation.config.render_all_levels = true
124
- end
118
+ context 'expand_all => true' do
125
119
  it "should render the invoices submenu even if the user-primary is active" do
126
- HTML::Selector.new('#invoices #subnav1').select(render(:users, true)).should have(1).entry
127
- HTML::Selector.new('#invoices #subnav2').select(render(:users, true)).should have(1).entry
120
+ HTML::Selector.new('#invoices #subnav1').select(render(:users, :level => :all, :expand_all => true)).should have(1).entry
121
+ HTML::Selector.new('#invoices #subnav2').select(render(:users, :level => :all, :expand_all => true)).should have(1).entry
128
122
  end
129
123
  end
130
-
124
+
131
125
  end
132
126
 
133
127
  end
@@ -153,9 +153,27 @@ describe SimpleNavigation do
153
153
  @primary = stub(:primary)
154
154
  SimpleNavigation.config.stub!(:primary_navigation => @primary)
155
155
  end
156
- it "should call active_item_container_for on the primary_navigation with the specified level" do
157
- @primary.should_receive(:active_item_container_for).with(1)
158
- SimpleNavigation.active_item_container_for 1
156
+ context 'level is :all' do
157
+ it "should return the primary_navigation" do
158
+ SimpleNavigation.active_item_container_for(:all).should == @primary
159
+ end
160
+ end
161
+ context 'level is a Range' do
162
+ it "should take the min of the range to lookup the active container" do
163
+ @primary.should_receive(:active_item_container_for).with(2)
164
+ SimpleNavigation.active_item_container_for(2..3)
165
+ end
166
+ end
167
+ context 'level is an Integer' do
168
+ it "should consider the Integer to lookup the active container" do
169
+ @primary.should_receive(:active_item_container_for).with(1)
170
+ SimpleNavigation.active_item_container_for(1)
171
+ end
172
+ end
173
+ context 'level is something else' do
174
+ it "should raise an ArgumentError" do
175
+ lambda {SimpleNavigation.active_item_container_for('something else')}.should raise_error(ArgumentError)
176
+ end
159
177
  end
160
178
  end
161
179
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple-navigation
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andi Schacke
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-18 00:00:00 +01:00
12
+ date: 2010-01-17 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15