simple-navigation 3.11.0 → 3.12.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.
Files changed (46) hide show
  1. data/.gitignore +6 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG +11 -0
  5. data/Gemfile +2 -16
  6. data/Guardfile +5 -0
  7. data/LICENSE +22 -0
  8. data/README.md +40 -0
  9. data/Rakefile +6 -39
  10. data/generators/navigation_config/templates/config/navigation.rb +7 -5
  11. data/init.rb +1 -0
  12. data/install.rb +5 -0
  13. data/lib/simple_navigation/adapters/rails.rb +5 -1
  14. data/lib/simple_navigation/core/configuration.rb +5 -1
  15. data/lib/simple_navigation/core/item.rb +2 -1
  16. data/lib/simple_navigation/core/item_adapter.rb +4 -4
  17. data/lib/simple_navigation/core/item_container.rb +6 -1
  18. data/lib/simple_navigation/rendering/renderer/breadcrumbs.rb +2 -2
  19. data/lib/simple_navigation/rendering/renderer/links.rb +2 -2
  20. data/lib/simple_navigation/rendering/renderer/list.rb +1 -1
  21. data/lib/simple_navigation/version.rb +3 -0
  22. data/lib/simple_navigation.rb +1 -0
  23. data/simple-navigation.gemspec +40 -0
  24. data/spec/initializers/have_css_matcher.rb +13 -0
  25. data/spec/lib/simple_navigation/adapters/padrino_spec.rb +23 -25
  26. data/spec/lib/simple_navigation/adapters/rails_spec.rb +276 -250
  27. data/spec/lib/simple_navigation/adapters/sinatra_spec.rb +64 -53
  28. data/spec/lib/simple_navigation/core/configuration_spec.rb +128 -106
  29. data/spec/lib/simple_navigation/core/item_adapter_spec.rb +144 -168
  30. data/spec/lib/simple_navigation/core/item_container_spec.rb +361 -339
  31. data/spec/lib/simple_navigation/core/item_spec.rb +571 -434
  32. data/spec/lib/simple_navigation/core/items_provider_spec.rb +35 -49
  33. data/spec/lib/simple_navigation/rails_controller_methods_spec.rb +194 -173
  34. data/spec/lib/simple_navigation/rendering/helpers_spec.rb +381 -225
  35. data/spec/lib/simple_navigation/rendering/renderer/base_spec.rb +205 -164
  36. data/spec/lib/simple_navigation/rendering/renderer/breadcrumbs_spec.rb +87 -67
  37. data/spec/lib/simple_navigation/rendering/renderer/json_spec.rb +52 -31
  38. data/spec/lib/simple_navigation/rendering/renderer/links_spec.rb +75 -48
  39. data/spec/lib/simple_navigation/rendering/renderer/list_spec.rb +62 -174
  40. data/spec/lib/simple_navigation/rendering/renderer/text_spec.rb +41 -28
  41. data/spec/lib/simple_navigation_spec.rb +207 -225
  42. data/spec/spec_helper.rb +53 -82
  43. data/uninstall.rb +1 -0
  44. metadata +100 -22
  45. data/README +0 -22
  46. data/VERSION +0 -1
@@ -1,566 +1,703 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe SimpleNavigation::Item do
3
+ module SimpleNavigation
4
+ describe Item do
5
+ let!(:item_container) { ItemContainer.new }
4
6
 
5
- before(:each) do
6
- @item_container = stub(:item_container, :level => 1, :selected_class => nil).as_null_object
7
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
8
- @adapter = stub(:adapter)
9
- SimpleNavigation.stub!(:adapter => @adapter)
10
- end
7
+ let(:adapter) { double(:adapter) }
8
+ let(:item_args) { [item_container, :my_key, 'name', url, options, items] }
9
+ let(:item) { Item.new(*item_args) }
10
+ let(:items) { nil }
11
+ let(:options) { Hash.new }
12
+ let(:url) { 'url' }
11
13
 
12
- describe 'initialize' do
13
- context 'subnavigation' do
14
- before(:each) do
15
- @subnav_container = stub(:subnav_container).as_null_object
16
- SimpleNavigation::ItemContainer.stub!(:new => @subnav_container)
17
- end
18
- context 'block given' do
19
- it "should create a new ItemContainer with a level+1" do
20
- SimpleNavigation::ItemContainer.should_receive(:new).with(2)
21
- SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) {}
22
- end
23
- it "should call the block" do
24
- @subnav_container.should_receive(:test)
25
- SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) {|subnav| subnav.test}
26
- end
27
- end
28
- context 'no block given' do
29
- context 'items given' do
30
- before(:each) do
31
- @items = stub(:items)
32
- end
33
- it "should create a new ItemContainer with a level+1" do
34
- SimpleNavigation::ItemContainer.should_receive(:new).with(2)
35
- SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}, @items)
14
+ before { SimpleNavigation.stub(adapter: adapter) }
15
+
16
+ describe '#initialize' do
17
+ context 'when there is a sub_navigation' do
18
+ let(:subnav_container) { double(:subnav_container).as_null_object }
19
+
20
+ before { ItemContainer.stub(new: subnav_container) }
21
+
22
+ context 'when a block is given' do
23
+ it 'creates a new ItemContainer with a level+1' do
24
+ expect(ItemContainer).to receive(:new).with(2)
25
+ Item.new(*item_args) {}
36
26
  end
37
- it "should set the items on the subnav_container" do
38
- @subnav_container.should_receive(:items=).with(@items)
39
- SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}, @items)
27
+
28
+ it 'calls the block' do
29
+ expect{ |blk|
30
+ Item.new(*item_args, &blk)
31
+ }.to yield_with_args(subnav_container)
40
32
  end
41
33
  end
42
- context 'no items given' do
43
- it "should not create a new ItemContainer" do
44
- SimpleNavigation::ItemContainer.should_not_receive(:new)
45
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
34
+
35
+ context 'when no block is given' do
36
+ context 'and items are given' do
37
+ let(:items) { double(:items) }
38
+
39
+ it 'creates a new ItemContainer with a level+1' do
40
+ expect(ItemContainer).to receive(:new).with(2)
41
+ Item.new(*item_args)
42
+ end
43
+
44
+ it "sets the items on the subnav_container" do
45
+ expect(subnav_container).to receive(:items=).with(items)
46
+ Item.new(*item_args)
47
+ end
48
+ end
49
+
50
+ context 'and no items are given' do
51
+ it "doesn't create a new ItemContainer" do
52
+ expect(ItemContainer).not_to receive(:new)
53
+ Item.new(*item_args)
54
+ end
46
55
  end
47
56
  end
48
57
  end
49
- end
50
- context ':method option' do
51
- context 'defined' do
52
- before(:each) do
53
- @options = {:method => :delete}
54
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
55
- end
56
- it 'should set the method as instance_var' do
57
- @item.method.should == :delete
58
+
59
+ context 'when a :method option is given' do
60
+ let(:options) {{ method: :delete }}
61
+
62
+ it "sets the item's method" do
63
+ expect(item.method).to eq :delete
58
64
  end
59
- it 'should set the html-options without the method' do
60
- @item.instance_variable_get(:@html_options).key?(:method).should be_false
65
+
66
+ it 'sets the html options without the method' do
67
+ meth = item.instance_variable_get(:@html_options).key?(:method)
68
+ expect(meth).to be_false
61
69
  end
62
70
  end
63
71
 
64
- context 'undefined' do
65
- it 'should set the instance-var to nil' do
66
- @item.method.should be_nil
72
+ context 'when no :method option is given' do
73
+ it "sets the item's method to nil" do
74
+ expect(item.method).to be_nil
67
75
  end
68
76
  end
69
- end
70
77
 
71
- context 'setting class and id on the container' do
72
- before(:each) do
73
- @options = {:container_class => 'container_class', :container_id => 'container_id'}
74
- end
75
- it {@item_container.should_receive(:dom_class=).with('container_class')}
76
- it {@item_container.should_receive(:dom_id=).with('container_id')}
77
- after(:each) do
78
- SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
78
+ context 'setting class and id on the container' do
79
+ let!(:create) { item }
80
+
81
+ let(:options) {{
82
+ container_class: 'container_class',
83
+ container_id: 'container_id',
84
+ container_attributes: { 'ng-show' => 'false' }
85
+ }}
86
+
87
+ it "fills in the container's dom_attributes" do
88
+ expect(item_container.dom_attributes).to eq({
89
+ id: 'container_id',
90
+ class: 'container_class',
91
+ 'ng-show' => 'false'
92
+ })
93
+ end
79
94
  end
80
- end
81
95
 
82
- context ':highlights_on option' do
83
- context 'defined' do
84
- before(:each) do
85
- @highlights_on = stub(:option)
86
- @options = {:highlights_on => @highlights_on}
87
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
96
+ context 'when a :highlights_on option is given' do
97
+ it "sets the item's highlights_on to nil" do
98
+ expect(item.highlights_on).to be_nil
88
99
  end
89
- it 'should set the method as instance_var' do
90
- @item.highlights_on.should == @highlights_on
100
+ end
101
+
102
+ context 'when no :highlights_on option is given' do
103
+ let(:highlights_on) { double(:highlights_on) }
104
+ let(:options) {{ highlights_on: highlights_on }}
105
+
106
+ it "sets the item's highlights_on" do
107
+ expect(item.highlights_on).to eq highlights_on
91
108
  end
92
- it 'should set the html-options without the method' do
93
- @item.instance_variable_get(:@html_options).key?(:highlights_on).should be_false
109
+
110
+ it 'sets the html options without the method' do
111
+ html_options = item.instance_variable_get(:@html_options)
112
+ expect(html_options).not_to have_key(:highlights_on)
94
113
  end
95
114
  end
96
115
 
97
- context 'undefined' do
98
- it 'should set the instance-var to nil' do
99
- @item.highlights_on.should be_nil
116
+ context 'when a url is given' do
117
+ context 'and it is a string' do
118
+ it "sets the item's url accordingly" do
119
+ expect(item.url).to eq 'url'
120
+ end
100
121
  end
101
- end
102
- end
103
122
 
104
- context 'url' do
105
- context 'url is a string' do
106
- before(:each) do
107
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
123
+ context 'and it is a proc' do
124
+ let(:url) { proc{ "my_" + "url" } }
125
+
126
+ it "sets the item's url accordingly" do
127
+ expect(item.url).to eq 'my_url'
128
+ end
108
129
  end
109
- it {@item.url.should == 'url'}
110
- end
111
- context 'url is a proc' do
112
- before(:each) do
113
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', Proc.new {"my_" + "url"}, {})
130
+
131
+ context 'and it is nil' do
132
+ let(:url) { nil }
133
+
134
+ it "sets the item's url accordingly" do
135
+ expect(item.url).to be_nil
136
+ end
114
137
  end
115
- it {@item.url.should == 'my_url'}
116
138
  end
117
- context 'url is nil' do
118
- before(:each) do
119
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', nil, {})
139
+
140
+ describe 'Optional url and optional options' do
141
+ context 'when no parameter is specified' do
142
+ let(:item_args) { [item_container, :my_key, 'name'] }
143
+
144
+ it "sets the item's url to nil" do
145
+ expect(item.url).to be_nil
146
+ end
147
+
148
+ it "sets the item's html_options to an empty hash" do
149
+ expect(item.instance_variable_get(:@html_options)).to eq({})
150
+ end
120
151
  end
121
- it {@item.url.should == nil}
122
- end
123
- context 'url is unspecified' do
124
- before(:each) do
125
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name')
152
+
153
+ context 'when only a url is given' do
154
+ let(:item_args) { [item_container, :my_key, 'name', 'url'] }
155
+
156
+ it "set the item's url accordingly" do
157
+ expect(item.url).to eq 'url'
158
+ end
159
+
160
+ it "sets the item's html_options to an empty hash" do
161
+ expect(item.instance_variable_get(:@html_options)).to eq({})
162
+ end
163
+ end
164
+
165
+ context 'when only options are given' do
166
+ let(:item_args) { [item_container, :my_key, 'name', { option: true }] }
167
+
168
+ it "sets the item's url to nil" do
169
+ expect(item.url).to be_nil
170
+ end
171
+
172
+ it "sets the item's html_options accordingly" do
173
+ html_options = item.instance_variable_get(:@html_options)
174
+ expect(html_options).to eq({ option: true })
175
+ end
176
+ end
177
+
178
+ context 'when url and options are given' do
179
+ let(:options) {{ option: true }}
180
+
181
+ it "set the item's url accordingly" do
182
+ expect(item.url).to eq 'url'
183
+ end
184
+
185
+ it "sets the item's html_options accordingly" do
186
+ html_options = item.instance_variable_get(:@html_options)
187
+ expect(html_options).to eq({ option: true })
188
+ end
126
189
  end
127
- it {@item.url.should == nil}
128
190
  end
129
191
  end
130
192
 
131
- context 'optional url and optional options' do
132
- context 'when constructed without any optional parameters' do
133
- before(:each) do
134
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name')
135
- end
136
- it {@item.url.should == nil}
137
- it {@item.instance_variable_get(:@html_options).should == {}}
193
+ describe '#name' do
194
+ before do
195
+ SimpleNavigation.config.stub(
196
+ name_generator: proc{ |name| "<span>#{name}</span>" })
138
197
  end
139
- context 'when constructed with only a url' do
140
- before(:each) do
141
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url')
198
+
199
+ context 'when no option is given' do
200
+ context 'and the name_generator uses only the name' do
201
+ it 'uses the default name_generator' do
202
+ expect(item.name).to eq '<span>name</span>'
203
+ end
142
204
  end
143
- it {@item.url.should == 'url'}
144
- it {@item.instance_variable_get(:@html_options).should == {}}
145
- end
146
- context 'when constructed with only options' do
147
- before(:each) do
148
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', {:option => true})
205
+
206
+ context 'and the name_generator uses only the item itself' do
207
+ before do
208
+ SimpleNavigation.config.stub(
209
+ name_generator: proc{ |name, item| "<span>#{item.key}</span>" })
210
+ end
211
+
212
+ it 'uses the default name_generator' do
213
+ expect(item.name).to eq '<span>my_key</span>'
214
+ end
149
215
  end
150
- it {@item.url.should == nil}
151
- it {@item.instance_variable_get(:@html_options).should == {:option => true}}
152
216
  end
153
- context 'when constructed with a url and options' do
154
- before(:each) do
155
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {:option => true})
217
+
218
+ context 'when the :apply_generator is false' do
219
+ it "returns the item's name" do
220
+ expect(item.name(apply_generator: false)).to eq 'name'
156
221
  end
157
- it {@item.url.should == 'url'}
158
- it {@item.instance_variable_get(:@html_options).should == {:option => true}}
159
222
  end
160
223
  end
161
- end
162
224
 
163
- describe 'name' do
164
- before(:each) do
165
- SimpleNavigation.config.stub!(:name_generator => Proc.new {|name| "<span>#{name}</span>"})
166
- end
167
- context 'default (generator is applied)' do
168
- it {@item.name.should == "<span>name</span>"}
169
- end
170
- context 'generator is skipped' do
171
- it {@item.name(:apply_generator => false).should == 'name'}
172
- end
173
- end
225
+ describe '#selected?' do
226
+ context 'when the item is explicitly selected' do
227
+ before { item.stub(selected_by_config?: true) }
174
228
 
175
- describe 'selected?' do
176
- context 'explicitly selected' do
177
- before(:each) do
178
- @item.stub!(:selected_by_config? => true)
179
- end
180
- it {@item.should be_selected}
181
- it "should not evaluate the subnav or urls" do
182
- @item.should_not_receive(:selected_by_subnav?)
183
- @item.should_not_receive(:selected_by_condition?)
184
- @item.selected?
185
- end
186
- end
187
- context 'not explicitly selected' do
188
- before(:each) do
189
- @item.stub!(:selected_by_config? => false)
190
- end
191
- context 'subnav is selected' do
192
- before(:each) do
193
- @item.stub!(:selected_by_subnav? => true)
229
+ it 'is selected' do
230
+ expect(item).to be_selected
194
231
  end
195
- it {@item.should be_selected}
196
- end
197
- context 'subnav is not selected' do
198
- before(:each) do
199
- @item.stub!(:selected_by_subnav? => false)
232
+
233
+ # FIXME: testing the implementation not the behavior here
234
+ it "doesn't check for selection by sub navigation" do
235
+ expect(item).not_to receive(:selected_by_subnav?)
236
+ item.selected?
237
+ end
238
+
239
+ # FIXME: testing the implementation not the behavior here
240
+ it "doesn't check for selection by highlighting condition" do
241
+ expect(item).not_to receive(:selected_by_condition?)
242
+ item.selected?
200
243
  end
201
- context 'selected by condition' do
202
- before(:each) do
203
- @item.stub!(:selected_by_condition? => true)
244
+ end
245
+
246
+ context "when the item isn't explicitly selected" do
247
+ before { item.stub(selected_by_config?: false) }
248
+
249
+ context 'and it is selected by sub navigation' do
250
+ before { item.stub(selected_by_subnav?: true) }
251
+
252
+ it 'is selected' do
253
+ expect(item).to be_selected
204
254
  end
205
- it {@item.should be_selected}
206
255
  end
207
- context 'not selected by condition' do
208
- before(:each) do
209
- @item.stub!(:selected_by_condition? => false)
256
+
257
+ context "and it isn't selected by sub navigation" do
258
+ before { item.stub(selected_by_subnav?: false) }
259
+
260
+ context 'and it is selected by a highlighting condition' do
261
+ before { item.stub(selected_by_condition?: true) }
262
+
263
+ it 'is selected' do
264
+ expect(item).to be_selected
265
+ end
266
+ end
267
+
268
+ context "and it isn't selected by any highlighting condition" do
269
+ before { item.stub(selected_by_condition?: false) }
270
+
271
+ it "isn't selected" do
272
+ expect(item).not_to be_selected
273
+ end
210
274
  end
211
- it {@item.should_not be_selected}
212
275
  end
213
276
  end
214
277
  end
215
- end
216
278
 
217
- describe 'selected_class' do
218
- context 'selected_class is defined in context' do
219
- before(:each) do
220
- @item_container = stub(:item_container, :level => 1, :selected_class => 'context_defined').as_null_object
221
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
222
- @item.stub!(:selected? => true)
223
- end
224
- it {@item.instance_eval {selected_class.should == 'context_defined'}}
225
- end
226
- context 'item is selected' do
227
- before(:each) do
228
- @item.stub!(:selected? => true)
279
+ describe '#selected_class' do
280
+ context 'when the item is selected' do
281
+ before { item.stub(selected?: true) }
282
+
283
+ it 'returns the default selected_class' do
284
+ expect(item.selected_class).to eq 'selected'
285
+ end
286
+
287
+ context 'and selected_class is defined in the context' do
288
+ before { item_container.stub(selected_class: 'defined') }
289
+
290
+ it "returns the context's selected_class" do
291
+ expect(item.selected_class).to eq 'defined'
292
+ end
293
+ end
229
294
  end
230
- it {@item.instance_eval {selected_class.should == 'selected'}}
231
- end
295
+
296
+ context 'when the item is not selected' do
297
+ before { item.stub(selected?: false) }
232
298
 
233
- context 'item is not selected' do
234
- before(:each) do
235
- @item.stub!(:selected? => false)
299
+ it 'returns nil' do
300
+ expect(item.selected_class).to be_nil
301
+ end
236
302
  end
237
- it {@item.instance_eval {selected_class.should == nil}}
238
303
  end
239
- end
240
304
 
241
- describe 'html_options' do
242
- describe 'class' do
243
- context 'with classes defined in options' do
244
- before(:each) do
245
- @options = {:class => 'my_class'}
246
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
247
- end
248
- context 'with item selected' do
249
- before(:each) do
250
- @item.stub!(:selected? => true, :selected_by_condition? => true)
305
+ describe ':html_options argument' do
306
+ let(:selected_classes) { 'selected simple-navigation-active-leaf' }
307
+
308
+ context 'when the :class option is given' do
309
+ let(:options) {{ class: 'my_class' }}
310
+
311
+ context 'and the item is selected' do
312
+ before { item.stub(selected?: true, selected_by_condition?: true) }
313
+
314
+ it "adds the specified class to the item's html classes" do
315
+ expect(item.html_options[:class]).to include('my_class')
316
+ end
317
+
318
+ it "doesn't replace the default html classes of a selected item" do
319
+ expect(item.html_options[:class]).to include(selected_classes)
251
320
  end
252
- it {@item.html_options[:class].should == 'my_class selected simple-navigation-active-leaf'}
253
321
  end
254
322
 
255
- context 'with item not selected' do
256
- before(:each) do
257
- @item.stub!(:selected? => false, :selected_by_condition? => false)
323
+ context "and the item isn't selected" do
324
+ before { item.stub(selected?: false, selected_by_condition?: false) }
325
+
326
+ it "sets the specified class as the item's html classes" do
327
+ expect(item.html_options[:class]).to include('my_class')
258
328
  end
259
- it {@item.html_options[:class].should == 'my_class'}
260
329
  end
261
330
  end
262
331
 
263
- context 'without classes in options' do
264
- before(:each) do
265
- @options = {}
266
- @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
267
- end
268
- context 'with item selected' do
269
- before(:each) do
270
- @item.stub!(:selected? => true, :selected_by_condition? => true)
332
+ context "when the :class option isn't given" do
333
+ context 'and the item is selected' do
334
+ before { item.stub(selected?: true, selected_by_condition?: true) }
335
+
336
+ it "sets the default html classes of a selected item" do
337
+ expect(item.html_options[:class]).to include(selected_classes)
271
338
  end
272
- it {@item.html_options[:class].should == 'selected simple-navigation-active-leaf'}
273
339
  end
274
340
 
275
- context 'with item not selected' do
276
- before(:each) do
277
- @item.stub!(:selected? => false, :selected_by_condition? => false)
278
- end
279
- it {@item.html_options[:class].should be_blank}
341
+ context "and the item isn't selected" do
342
+ before { item.stub(selected?: false, selected_by_condition?: false) }
343
+
344
+ it "doesn't set any html class on the item" do
345
+ expect(item.html_options[:class]).to be_blank
346
+ end
280
347
  end
281
348
  end
282
349
 
283
- end
350
+ shared_examples 'generating id' do |id|
351
+ it "sets the item's html id to the specified id" do
352
+ expect(item.html_options[:id]).to eq id
353
+ end
354
+ end
355
+
356
+ describe 'when the :id option is given' do
357
+ let(:options) {{ id: 'my_id' }}
284
358
 
285
- describe 'id' do
286
- context 'with autogenerate_item_ids == true' do
287
- before(:each) do
288
- @item.stub!(:autogenerate_item_ids? => true)
289
- @item.stub!(:selected? => false, :selected_by_condition? => false)
359
+ before do
360
+ item.stub(selected?: false,
361
+ selected_by_condition?: false,
362
+ autogenerate_item_ids?: generate_ids)
290
363
  end
291
- context 'with id defined in options' do
292
- before(:each) do
293
- @item.html_options = {:id => 'my_id'}
294
- end
295
- it {@item.html_options[:id].should == 'my_id'}
364
+
365
+ context 'and :autogenerate_item_ids is true' do
366
+ let(:generate_ids) { true }
367
+
368
+ it_behaves_like 'generating id', 'my_id'
296
369
  end
297
370
 
298
- context 'with no id defined in options (using default id)' do
299
- before(:each) do
300
- @item.html_options = {}
301
- end
302
- it {@item.html_options[:id].should == 'my_key'}
371
+ context 'and :autogenerate_item_ids is false' do
372
+ let(:generate_ids) { false }
373
+
374
+ it_behaves_like 'generating id', 'my_id'
303
375
  end
304
376
  end
305
377
 
306
- context 'with autogenerate_item_ids == false' do
307
- before(:each) do
308
- @item.stub!(:autogenerate_item_ids? => false)
309
- @item.stub!(:selected? => false, :selected_by_condition? => false)
378
+ context "when the :id option isn't given" do
379
+ before do
380
+ item.stub(selected?: false,
381
+ selected_by_condition?: false,
382
+ autogenerate_item_ids?: generate_ids)
310
383
  end
311
- context 'with id defined in options' do
312
- before(:each) do
313
- @item.html_options = {:id => 'my_id'}
314
- end
315
- it {@item.html_options[:id].should == 'my_id'}
384
+
385
+ context 'and :autogenerate_item_ids is true' do
386
+ let(:generate_ids) { true }
387
+
388
+ it_behaves_like 'generating id', 'my_key'
316
389
  end
317
390
 
318
- context 'with no id definied in options (using default id)' do
319
- before(:each) do
320
- @item.html_options = {}
391
+ context 'and :autogenerate_item_ids is false' do
392
+ let(:generate_ids) { false }
393
+
394
+ it "doesn't set any html id on the item" do
395
+ expect(item.html_options[:id]).to be_blank
321
396
  end
322
- it {@item.html_options[:id].should be_nil}
323
397
  end
324
-
325
398
  end
326
-
327
399
  end
328
400
 
329
- end
401
+ describe '#selected_by_subnav?' do
402
+ before { item.stub(sub_navigation: sub_navigation) }
330
403
 
331
- describe 'selected_by_subnav?' do
332
- context 'item has subnav' do
333
- before(:each) do
334
- @sub_navigation = stub(:sub_navigation)
335
- @item.stub!(:sub_navigation => @sub_navigation)
336
- end
337
- it "should return true if subnav is selected" do
338
- @sub_navigation.stub!(:selected? => true, :selected_by_condition? => true)
339
- @item.should be_selected_by_subnav
340
- end
341
- it "should return false if subnav is not selected" do
342
- @sub_navigation.stub!(:selected? => false, :selected_by_condition? => true)
343
- @item.should_not be_selected_by_subnav
404
+ context 'the item has a sub_navigation' do
405
+ let(:sub_navigation) { double(:sub_navigation) }
406
+
407
+ context 'and an item of the sub_navigation is selected' do
408
+ before do
409
+ sub_navigation.stub(selected?: true, selected_by_condition?: true)
410
+ end
411
+
412
+ it 'returns true' do
413
+ expect(item).to be_selected_by_subnav
414
+ end
415
+ end
416
+
417
+ context 'and no item of the sub_navigation is selected' do
418
+ before do
419
+ sub_navigation.stub(selected?: false, selected_by_condition?: true)
420
+ end
421
+
422
+ it 'returns false' do
423
+ expect(item).not_to be_selected_by_subnav
424
+ end
425
+ end
344
426
  end
345
- end
346
- context 'item does not have subnav' do
347
- before(:each) do
348
- @item.stub!(:sub_navigation => @sub_navigation)
427
+
428
+ context "when the item doesn't have any sub_navigation" do
429
+ let(:sub_navigation) { nil }
430
+
431
+ it 'returns false' do
432
+ expect(item).not_to be_selected_by_subnav
433
+ end
349
434
  end
350
- it {@item.should_not be_selected_by_subnav}
351
435
  end
352
- end
353
436
 
354
- describe 'selected_by_condition?' do
355
- context ':highlights_on option is set' do
356
- before(:each) do
357
- @item.stub!(:highlights_on => /^\/current/)
358
- SimpleNavigation.stub!(:request_uri => '/current_url')
359
- end
360
- it "should not check for autohighlighting" do
361
- @item.should_not_receive(:auto_highlight?)
362
- @item.send(:selected_by_condition?)
363
- end
364
- context ':highlights_on is a regexp' do
365
- context 'regexp matches current_url' do
366
- it {@item.send(:selected_by_condition?).should be_true}
437
+ describe '#selected_by_condition?' do
438
+ let(:current_url) { '' }
439
+
440
+ before { adapter.stub(request_uri: current_url) }
441
+
442
+ context 'when the :highlights_on option is set' do
443
+ before { item.stub(highlights_on: /^\/matching/) }
444
+
445
+ context 'and :highlights_on is a regexp' do
446
+ context 'and it matches the current url' do
447
+ let(:current_url) { '/matching_url' }
448
+
449
+ it 'returns true' do
450
+ expect(item).to be_selected_by_condition
451
+ end
452
+ end
453
+
454
+ context "and it doesn't match current url" do
455
+ let(:current_url) { '/other_url' }
456
+
457
+ it 'returns false' do
458
+ expect(item).not_to be_selected_by_condition
459
+ end
460
+ end
367
461
  end
368
- context 'regexp does not match current_url' do
369
- before(:each) do
370
- @item.stub!(:highlights_on => /^\/no_match/)
462
+
463
+ context 'and :highlights_on is a lambda' do
464
+ context 'and it is truthy' do
465
+ before { item.stub(highlights_on: ->{ true }) }
466
+
467
+ it 'returns true' do
468
+ expect(item).to be_selected_by_condition
469
+ end
470
+ end
471
+
472
+ context 'falsey lambda results in no selection' do
473
+ before { item.stub(highlights_on: ->{ false }) }
474
+
475
+ it 'returns false' do
476
+ expect(item).not_to be_selected_by_condition
477
+ end
371
478
  end
372
- it {@item.send(:selected_by_condition?).should be_false}
373
479
  end
374
- end
375
- context ':highlights_on is a lambda' do
376
- context 'truthy lambda results in selection' do
377
- before(:each) do
378
- @item.stub!(:highlights_on => lambda{true})
480
+
481
+ context 'and :highlights_on is :subpath' do
482
+ before { item.stub(url: '/path', highlights_on: :subpath) }
483
+
484
+ context "and the current url is a sub path of the item's url" do
485
+ let(:current_url) { '/path/sub-path' }
486
+
487
+ it 'returns true' do
488
+ expect(item).to be_selected_by_condition
489
+ end
490
+ end
491
+
492
+ context "and the current url starts with item's url" do
493
+ let(:current_url) { '/path_group/id' }
494
+
495
+ it 'returns false' do
496
+ expect(item).not_to be_selected_by_condition
497
+ end
498
+ end
499
+
500
+ context "and the current url is totally different from the item's url" do
501
+ let(:current_url) { '/other_path/id' }
502
+
503
+ it 'returns false' do
504
+ expect(item).not_to be_selected_by_condition
505
+ end
379
506
  end
380
- it {@item.send(:selected_by_condition?).should be_true}
381
507
  end
382
- context 'falsey lambda results in no selection' do
383
- before(:each) do
384
- @item.stub!(:highlights_on => lambda{false})
508
+
509
+ context 'when :highlights_on something else' do
510
+ before { item.stub(highlights_on: 'nothing') }
511
+
512
+ it 'raises an exception' do
513
+ expect{ item.send(:selected_by_condition?) }.to raise_error
385
514
  end
386
- it {@item.send(:selected_by_condition?).should be_false}
387
515
  end
388
516
  end
389
- context ':highlights_on is :subpath' do
390
- before(:each) do
391
- @item.stub!(:url => '/resources')
392
- @item.stub!(:highlights_on => :subpath)
393
- end
394
- context 'we are in a route beginning with this item path' do
395
- before(:each) do
396
- SimpleNavigation.stub!(:request_uri => '/resources/id')
517
+
518
+ context 'when :auto_highlight is true' do
519
+ before { item.stub(auto_highlight?: true) }
520
+
521
+ context 'and root path matches' do
522
+ before { item.stub(root_path_match?: true) }
523
+
524
+ it 'returns true' do
525
+ expect(item).to be_selected_by_condition
397
526
  end
398
- it {@item.send(:selected_by_condition?).should be_true}
399
527
  end
400
- context 'we are in a route that has a similar name' do
401
- before(:each) do
402
- SimpleNavigation.stub!(:request_uri => '/resources_group/id')
528
+
529
+ context "and root path doesn't match" do
530
+ before { item.stub(root_path_match?: false) }
531
+
532
+ context "and the current url matches the item's url" do
533
+ let(:url) { 'url#anchor' }
534
+
535
+ before { adapter.stub(current_page?: true) }
536
+
537
+ it 'returns true' do
538
+ expect(item).to be_selected_by_condition
539
+ end
540
+
541
+ # FIXME: testing the implementation not the behavior here
542
+ it "removes anchors before testing the item's url" do
543
+ expect(adapter).to receive(:current_page?).with('url')
544
+ item.send(:selected_by_condition?)
545
+ end
546
+
547
+ context 'when url is nil' do
548
+ let(:url) { nil }
549
+
550
+ it "doesn't check the url" do
551
+ expect(adapter).not_to receive(:current_page?)
552
+ item.send(:selected_by_condition?)
553
+ end
554
+ end
403
555
  end
404
- it {@item.send(:selected_by_condition?).should be_false}
405
- end
406
- context 'we are in a route not beginning with this item path' do
407
- before(:each) do
408
- SimpleNavigation.stub!(:request_uri => '/another_resource/id')
556
+
557
+ context "and the current url doesn't match the item's url" do
558
+ before { adapter.stub(current_page?: false) }
559
+
560
+ it 'returns false' do
561
+ expect(item).not_to be_selected_by_condition
562
+ end
409
563
  end
410
- it {@item.send(:selected_by_condition?).should be_false}
411
564
  end
412
565
  end
413
- context ':highlights_on is not a regexp or a proc' do
414
- before(:each) do
415
- @item.stub!(:highlights_on => "not a regexp")
416
- end
417
- it "should raise an error" do
418
- lambda {@item.send(:selected_by_condition?).should raise_error(ArgumentError)}
566
+
567
+ context 'when :auto_highlight is false' do
568
+ before { item.stub(auto_highlight?: false) }
569
+
570
+ it 'returns false' do
571
+ expect(item).not_to be_selected_by_condition
419
572
  end
420
573
  end
421
574
  end
422
- context ':highlights_on option is not set' do
423
- before(:each) do
424
- @item.stub!(:highlights_on => nil)
425
- end
426
- it "should check for autohighlighting" do
427
- @item.should_receive(:auto_highlight?)
428
- @item.send(:selected_by_condition?)
429
- end
430
- end
431
- context 'auto_highlight is turned on' do
432
- before(:each) do
433
- @item.stub!(:auto_highlight? => true)
434
- end
435
- context 'root path matches' do
436
- before(:each) do
437
- @item.stub!(:root_path_match? => true)
438
- end
439
- it {@item.send(:selected_by_condition?).should be_true}
440
- end
441
- context 'root path does not match' do
442
- before(:each) do
443
- @item.stub!(:root_path_match? => false)
444
- end
445
- context 'current request url matches url' do
446
- before(:each) do
447
- @adapter.stub!(:current_page? => true)
448
- end
449
- it "should test with the item's url" do
450
- @adapter.should_receive(:current_page?).with('url')
451
- @item.send(:selected_by_condition?)
575
+
576
+ describe '#root_path_match?' do
577
+ context "when current url is /" do
578
+ before { adapter.stub(request_path: '/') }
579
+
580
+ context "and the item's url is /" do
581
+ let(:url) { '/' }
582
+
583
+ it 'returns true' do
584
+ expect(item.send(:root_path_match?)).to be_true
452
585
  end
453
- it "should remove anchors before testing the item's url" do
454
- @item.stub!(:url => 'url#anchor')
455
- @adapter.should_receive(:current_page?).with('url')
456
- @item.send(:selected_by_condition?)
586
+ end
587
+
588
+ context "and the item's url isn't /" do
589
+ let(:url) { '/other' }
590
+
591
+ it 'returns false' do
592
+ expect(item.send(:root_path_match?)).to be_false
457
593
  end
458
- it "should not be queried when url is nil" do
459
- @item.stub!(:url => nil)
460
- @adapter.should_not_receive(:current_page?)
461
- @item.send(:selected_by_condition?)
594
+ end
595
+ end
596
+
597
+ context "when current url isn't /" do
598
+ before { adapter.stub(request_path: '/other') }
599
+
600
+ context "and the item's url is /" do
601
+ let(:url) { '/' }
602
+
603
+ it 'returns false' do
604
+ expect(item.send(:root_path_match?)).to be_false
462
605
  end
463
- it {@item.send(:selected_by_condition?).should be_true}
464
606
  end
465
- context 'no match' do
466
- before(:each) do
467
- @adapter.stub!(:current_page? => false)
607
+
608
+ context "and the item's url is nil" do
609
+ let(:url) { nil }
610
+
611
+ it 'returns false' do
612
+ expect(item.send(:root_path_match?)).to be_false
468
613
  end
469
- it {@item.send(:selected_by_condition?).should be_false}
470
614
  end
471
615
  end
472
- end
473
- context 'auto_highlight is turned off' do
474
- before(:each) do
475
- @item.stub!(:auto_highlight? => false)
476
- end
477
- it {@item.send(:selected_by_condition?).should be_false}
478
- end
479
- end
480
616
 
481
- describe 'root_path_match?' do
482
- it "should match if both url == /" do
483
- @adapter.stub!(:request_path => '/')
484
- @item.stub!(:url => '/')
485
- @item.send(:root_path_match?).should be_true
486
- end
487
- it "should not match if item url is not /" do
488
- @adapter.stub(:request_path => '/')
489
- @item.stub!(:url => '/bla')
490
- @item.send(:root_path_match?).should be_false
491
- end
492
- it "should not match if request url is not /" do
493
- @adapter.stub(:request_path => '/bla')
494
- @item.stub!(:url => '/')
495
- @item.send(:root_path_match?).should be_false
496
- end
497
- it "should not match if urls do not match" do
498
- @adapter.stub(:request_path => 'bla')
499
- @item.stub!(:url => '/bli')
500
- @item.send(:root_path_match?).should be_false
501
- end
502
- it "should not match if url is nil" do
503
- @adapter.stub(:request_path => 'bla')
504
- @item.stub!(:url => nil)
505
- @item.send(:root_path_match?).should be_false
506
- end
507
- end
617
+ context "when current url doesn't match the item's url" do
618
+ let(:url) { '/path' }
508
619
 
509
- describe 'auto_highlight?' do
510
- before(:each) do
511
- @global = stub(:config)
512
- SimpleNavigation.stub!(:config => @global)
513
- end
514
- context 'global auto_highlight on' do
515
- before(:each) do
516
- @global.stub!(:auto_highlight => true)
517
- end
518
- context 'container auto_highlight on' do
519
- before(:each) do
520
- @item_container.stub!(:auto_highlight => true)
620
+ before { adapter.stub(request_path: '/other') }
621
+
622
+ it 'returns false' do
623
+ expect(item.send(:root_path_match?)).to be_false
521
624
  end
522
- it {@item.send(:auto_highlight?).should be_true}
523
625
  end
524
- context 'container auto_highlight off' do
525
- before(:each) do
526
- @item_container.stub!(:auto_highlight => false)
626
+
627
+ context "when current url doesn't match the item's url" do
628
+ let(:url) { nil }
629
+
630
+ before { adapter.stub(request_path: '/other') }
631
+
632
+ it 'returns false' do
633
+ expect(item.send(:root_path_match?)).to be_false
527
634
  end
528
- it {@item.send(:auto_highlight?).should be_false}
529
635
  end
530
636
  end
531
- context 'global auto_highlight off' do
532
- before(:each) do
533
- @global.stub!(:auto_highlight => false)
534
- end
535
- context 'container auto_highlight on' do
536
- before(:each) do
537
- @item_container.stub!(:auto_highlight => true)
637
+
638
+ describe '#auto_highlight?' do
639
+ let(:global) { double(:config) }
640
+
641
+ before { SimpleNavigation.stub(config: global) }
642
+
643
+ context 'when :auto_highlight is globally true' do
644
+ before { global.stub(auto_highlight: true) }
645
+
646
+ context "and container's :auto_highlight is true" do
647
+ before { item_container.stub(auto_highlight: true) }
648
+
649
+ it 'returns true' do
650
+ expect(item.send(:auto_highlight?)).to be_true
651
+ end
652
+ end
653
+
654
+ context "and container's :auto_highlight is false" do
655
+ before { item_container.stub(auto_highlight: false) }
656
+
657
+ it 'returns false' do
658
+ expect(item.send(:auto_highlight?)).to be_false
659
+ end
538
660
  end
539
- it {@item.send(:auto_highlight?).should be_false}
540
661
  end
541
- context 'container auto_highlight off' do
542
- before(:each) do
543
- @item_container.stub!(:auto_highlight => false)
662
+
663
+ context 'when :auto_highlight is globally false' do
664
+ before { global.stub(auto_highlight: false) }
665
+
666
+ context 'when :auto_highlight is globally true' do
667
+ before { item_container.stub(auto_highlight: true) }
668
+
669
+ it 'returns false' do
670
+ expect(item.send(:auto_highlight?)).to be_false
671
+ end
672
+ end
673
+
674
+ context "and container's :auto_highlight is false" do
675
+ before { item_container.stub(auto_highlight: false) }
676
+
677
+ it 'returns false' do
678
+ expect(item.send(:auto_highlight?)).to be_false
679
+ end
544
680
  end
545
- it {@item.send(:auto_highlight?).should be_false}
546
681
  end
547
682
  end
548
- end
549
683
 
550
- describe 'autogenerated_item_id' do
551
- context 'calls' do
552
- before(:each) do
553
- @id_generator = stub(:id_generator)
554
- SimpleNavigation.config.stub!(:id_generator => @id_generator)
684
+ describe '#autogenerated_item_id' do
685
+ context 'when no generator is configured' do
686
+ let(:id_generator) { double(:id_generator) }
687
+
688
+ before { SimpleNavigation.config.stub(id_generator: id_generator) }
689
+
690
+ it 'calls the globally configured id generator' do
691
+ expect(id_generator).to receive(:call).with(:my_key)
692
+ item.send(:autogenerated_item_id)
693
+ end
555
694
  end
556
- it "should call the configured generator with the key as param" do
557
- @id_generator.should_receive(:call).with(:my_key)
558
- @item.send(:autogenerated_item_id)
695
+
696
+ context 'when no generator is configured' do
697
+ it 'uses the default generator' do
698
+ expect(item.send(:autogenerated_item_id)).to eq 'my_key'
699
+ end
559
700
  end
560
701
  end
561
- context 'default generator' do
562
- it {@item.send(:autogenerated_item_id).should == 'my_key'}
563
- end
564
702
  end
565
-
566
703
  end