simple-navigation 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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