simple-navigation 3.11.0 → 3.12.0

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