simple-navigation-ext 0.0.1

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/CHANGELOG +177 -0
  2. data/README +22 -0
  3. data/Rakefile +48 -0
  4. data/VERSION +1 -0
  5. data/generators/navigation_config/USAGE +1 -0
  6. data/generators/navigation_config/navigation_config_generator.rb +8 -0
  7. data/generators/navigation_config/templates/config/navigation.rb +67 -0
  8. data/lib/generators/navigation_config/navigation_config_generator.rb +12 -0
  9. data/lib/simple-navigation.rb +1 -0
  10. data/lib/simple_navigation/adapters/base.rb +37 -0
  11. data/lib/simple_navigation/adapters/padrino.rb +20 -0
  12. data/lib/simple_navigation/adapters/rails.rb +94 -0
  13. data/lib/simple_navigation/adapters/sinatra.rb +68 -0
  14. data/lib/simple_navigation/adapters.rb +9 -0
  15. data/lib/simple_navigation/core/configuration.rb +70 -0
  16. data/lib/simple_navigation/core/item.rb +117 -0
  17. data/lib/simple_navigation/core/item_adapter.rb +63 -0
  18. data/lib/simple_navigation/core/item_container.rb +146 -0
  19. data/lib/simple_navigation/core/items_provider.rb +35 -0
  20. data/lib/simple_navigation/core.rb +5 -0
  21. data/lib/simple_navigation/rails_controller_methods.rb +144 -0
  22. data/lib/simple_navigation/rendering/helpers.rb +82 -0
  23. data/lib/simple_navigation/rendering/renderer/base.rb +71 -0
  24. data/lib/simple_navigation/rendering/renderer/breadcrumbs.rb +37 -0
  25. data/lib/simple_navigation/rendering/renderer/links.rb +25 -0
  26. data/lib/simple_navigation/rendering/renderer/list.rb +47 -0
  27. data/lib/simple_navigation/rendering.rb +10 -0
  28. data/lib/simple_navigation.rb +162 -0
  29. data/rails/init.rb +1 -0
  30. data/spec/lib/simple_navigation/adapters/padrino_spec.rb +29 -0
  31. data/spec/lib/simple_navigation/adapters/rails_spec.rb +284 -0
  32. data/spec/lib/simple_navigation/adapters/sinatra_spec.rb +60 -0
  33. data/spec/lib/simple_navigation/core/configuration_spec.rb +122 -0
  34. data/spec/lib/simple_navigation/core/item_adapter_spec.rb +209 -0
  35. data/spec/lib/simple_navigation/core/item_container_spec.rb +396 -0
  36. data/spec/lib/simple_navigation/core/item_spec.rb +513 -0
  37. data/spec/lib/simple_navigation/core/items_provider_spec.rb +60 -0
  38. data/spec/lib/simple_navigation/rails_controller_methods_spec.rb +249 -0
  39. data/spec/lib/simple_navigation/rendering/helpers_spec.rb +183 -0
  40. data/spec/lib/simple_navigation/rendering/renderer/base_spec.rb +199 -0
  41. data/spec/lib/simple_navigation/rendering/renderer/breadcrumbs_spec.rb +58 -0
  42. data/spec/lib/simple_navigation/rendering/renderer/links_spec.rb +58 -0
  43. data/spec/lib/simple_navigation/rendering/renderer/list_spec.rb +189 -0
  44. data/spec/lib/simple_navigation_spec.rb +307 -0
  45. data/spec/spec_helper.rb +96 -0
  46. metadata +158 -0
@@ -0,0 +1,513 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleNavigation::Item do
4
+
5
+ before(:each) do
6
+ @item_container = stub(:item_container, :level => 1).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
11
+
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)
36
+ 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)
40
+ end
41
+ 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', {})
46
+ end
47
+ end
48
+ 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
+ end
59
+ it 'should set the html-options without the method' do
60
+ @item.instance_variable_get(:@html_options).key?(:method).should be_false
61
+ end
62
+ end
63
+
64
+ context 'undefined' do
65
+ it 'should set the instance-var to nil' do
66
+ @item.method.should be_nil
67
+ end
68
+ end
69
+ end
70
+
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)
79
+ end
80
+ end
81
+
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)
88
+ end
89
+ it 'should set the method as instance_var' do
90
+ @item.highlights_on.should == @highlights_on
91
+ 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
94
+ end
95
+ end
96
+
97
+ context 'undefined' do
98
+ it 'should set the instance-var to nil' do
99
+ @item.highlights_on.should be_nil
100
+ end
101
+ end
102
+ end
103
+
104
+ context ':exclude_highlight_if option' do
105
+ context 'defined' do
106
+ before(:each) do
107
+ @exclude_highlighting = stub(:option)
108
+ @options = {:exclude_highlight_if => @exclude_highlighting}
109
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
110
+ @item.stub!(:selected? => true)
111
+ end
112
+ it 'should set the method as instance_var' do
113
+ @item.exclude_highlighting.should == @exclude_highlighting
114
+ end
115
+ it 'should set the html-options without the method' do
116
+ @item.instance_variable_get(:@html_options).key?(:exclude_highlighting).should be_false
117
+ end
118
+ end
119
+
120
+ context 'undefined' do
121
+ it 'should set the instance-var to nil' do
122
+ @item.exclude_highlighting.should be_nil
123
+ end
124
+ end
125
+ end
126
+
127
+ context 'url' do
128
+ context 'url is a string' do
129
+ before(:each) do
130
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
131
+ end
132
+ it {@item.url.should == 'url'}
133
+ end
134
+ context 'url is a proc' do
135
+ before(:each) do
136
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', Proc.new {"my_" + "url"}, {})
137
+ end
138
+ it {@item.url.should == 'my_url'}
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ describe 'selected?' do
145
+ context 'explicitly selected' do
146
+ before(:each) do
147
+ @item.stub!(:selected_by_config? => true)
148
+ end
149
+ it {@item.should be_selected}
150
+ it "should not evaluate the subnav or urls" do
151
+ @item.should_not_receive(:selected_by_subnav?)
152
+ @item.should_not_receive(:selected_by_url?)
153
+ @item.selected?
154
+ end
155
+ end
156
+ context 'not explicitly selected' do
157
+ before(:each) do
158
+ @item.stub!(:selected_by_config? => false)
159
+ end
160
+ context 'subnav is selected' do
161
+ before(:each) do
162
+ @item.stub!(:selected_by_subnav? => true)
163
+ end
164
+ it {@item.should be_selected}
165
+ end
166
+ context 'subnav is not selected' do
167
+ before(:each) do
168
+ @item.stub!(:selected_by_subnav? => false)
169
+ end
170
+ context 'selected by url' do
171
+ before(:each) do
172
+ @item.stub!(:selected_by_url? => true)
173
+ end
174
+ it {@item.should be_selected}
175
+ end
176
+ context 'not selected by url' do
177
+ before(:each) do
178
+ @item.stub!(:selected_by_url? => false)
179
+ end
180
+ it {@item.should_not be_selected}
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ describe 'selected_class' do
187
+ context 'item is selected' do
188
+ before(:each) do
189
+ @item.stub!(:selected? => true)
190
+ end
191
+ it {@item.instance_eval {selected_class.should == 'selected'}}
192
+ end
193
+
194
+ context 'item is not selected' do
195
+ before(:each) do
196
+ @item.stub!(:selected? => false)
197
+ end
198
+ it {@item.instance_eval {selected_class.should == nil}}
199
+ end
200
+ end
201
+
202
+ describe 'html_options' do
203
+ describe 'class' do
204
+ context 'with classes defined in options' do
205
+ before(:each) do
206
+ @options = {:class => 'my_class'}
207
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
208
+ end
209
+ context 'with item selected' do
210
+ before(:each) do
211
+ @item.stub!(:selected? => true)
212
+ end
213
+ it {@item.html_options[:class].should == 'my_class selected'}
214
+ end
215
+
216
+ context 'with item not selected' do
217
+ before(:each) do
218
+ @item.stub!(:selected? => false)
219
+ end
220
+ it {@item.html_options[:class].should == 'my_class'}
221
+ end
222
+ end
223
+
224
+ context 'without classes in options' do
225
+ before(:each) do
226
+ @options = {}
227
+ @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options)
228
+ end
229
+ context 'with item selected' do
230
+ before(:each) do
231
+ @item.stub!(:selected? => true)
232
+ end
233
+ it {@item.html_options[:class].should == 'selected'}
234
+ end
235
+
236
+ context 'with item not selected' do
237
+ before(:each) do
238
+ @item.stub!(:selected? => false)
239
+ end
240
+ it {@item.html_options[:class].should be_blank}
241
+ end
242
+ end
243
+ end
244
+
245
+ describe 'id' do
246
+ context 'with autogenerate_item_ids == true' do
247
+ before(:each) do
248
+ @item.stub!(:autogenerate_item_ids? => true)
249
+ @item.stub!(:selected? => false)
250
+ end
251
+ context 'with id defined in options' do
252
+ before(:each) do
253
+ @item.html_options = {:id => 'my_id'}
254
+ end
255
+ it {@item.html_options[:id].should == 'my_id'}
256
+ end
257
+
258
+ context 'with no id defined in options (using default id)' do
259
+ before(:each) do
260
+ @item.html_options = {}
261
+ end
262
+ it {@item.html_options[:id].should == 'my_key'}
263
+ end
264
+ end
265
+
266
+ context 'with autogenerate_item_ids == false' do
267
+ before(:each) do
268
+ @item.stub!(:autogenerate_item_ids? => false)
269
+ @item.stub!(:selected? => false)
270
+ end
271
+ context 'with id defined in options' do
272
+ before(:each) do
273
+ @item.html_options = {:id => 'my_id'}
274
+ end
275
+ it {@item.html_options[:id].should == 'my_id'}
276
+ end
277
+
278
+ context 'with no id definied in options (using default id)' do
279
+ before(:each) do
280
+ @item.html_options = {}
281
+ end
282
+ it {@item.html_options[:id].should be_nil}
283
+ end
284
+
285
+ end
286
+
287
+ end
288
+
289
+ end
290
+
291
+ describe 'selected_by_subnav?' do
292
+ context 'item has subnav' do
293
+ before(:each) do
294
+ @sub_navigation = stub(:sub_navigation)
295
+ @item.stub!(:sub_navigation => @sub_navigation)
296
+ end
297
+ it "should return true if subnav is selected" do
298
+ @sub_navigation.stub!(:selected? => true)
299
+ @item.should be_selected_by_subnav
300
+ end
301
+ it "should return false if subnav is not selected" do
302
+ @sub_navigation.stub!(:selected? => false)
303
+ @item.should_not be_selected_by_subnav
304
+ end
305
+ end
306
+ context 'item does not have subnav' do
307
+ before(:each) do
308
+ @item.stub!(:sub_navigation => @sub_navigation)
309
+ end
310
+ it {@item.should_not be_selected_by_subnav}
311
+ end
312
+ end
313
+
314
+ describe 'selected_by_url?' do
315
+ context ':highlights_on option is set' do
316
+ before(:each) do
317
+ @item.stub!(:highlights_on => /^\/current/)
318
+ SimpleNavigation.stub!(:request_uri => '/current_url')
319
+ @item.stub!(:selected? => true)
320
+ end
321
+ it "should not check for autohighlighting" do
322
+ @item.should_not_receive(:auto_highlight?)
323
+ @item.send(:selected_by_url?)
324
+ end
325
+ it 'should have a selected class' do
326
+ @item.selected_class.should be_true
327
+ end
328
+
329
+ context ':highlights_on is a regexp without exclusion' do
330
+ context 'regexp matches current_url' do
331
+ it {@item.send(:selected_by_url?).should be_true}
332
+ end
333
+ context 'regexp does not match current_url' do
334
+ before(:each) do
335
+ @item.stub!(:highlights_on => /^\/no_match/)
336
+ end
337
+ it {@item.send(:selected_by_url?).should be_false}
338
+ end
339
+ end
340
+
341
+ context ':highlights_on is a regexp' do
342
+ before(:each) do
343
+ @item.stub!(:highlights_on => /^\/current/)
344
+ @item.stub!(:selected? => true)
345
+ end
346
+
347
+ it 'should have a selected class' do
348
+ @item.selected_class.should be_true
349
+ end
350
+
351
+
352
+ context 'with exclusion on a highlighted url' do
353
+ before(:each) { @item.stub!(:exclude_highlighting).and_return(/\/current/) }
354
+
355
+ it 'should not have a selected class' do
356
+ @item.selected_class.should be_false
357
+ end
358
+ end
359
+
360
+ context 'with exclusion on a not highlighted url' do
361
+ before(:each) { @item.stub!(:exclude_highlighting).and_return(/\/test/) }
362
+
363
+ it 'should have a selected class' do
364
+ @item.selected_class.should be_true
365
+ end
366
+ end
367
+ end
368
+
369
+ context ':highlights_on is not a regexp' do
370
+ before(:each) do
371
+ @item.stub!(:highlights_on => "not a regexp")
372
+ end
373
+ it "should raise an error" do
374
+ lambda {@item.send(:selected_by_url?).should raise_error(ArgumentError)}
375
+ end
376
+ end
377
+ end
378
+
379
+ context ':highlights_on option is not set' do
380
+ before(:each) do
381
+ @item.stub!(:highlights_on => nil)
382
+ end
383
+ it "should check for autohighlighting" do
384
+ @item.should_receive(:auto_highlight?)
385
+ @item.send(:selected_by_url?)
386
+ end
387
+ end
388
+ context 'auto_highlight is turned on' do
389
+ before(:each) do
390
+ @item.stub!(:auto_highlight? => true)
391
+ end
392
+ context 'root path matches' do
393
+ before(:each) do
394
+ @item.stub!(:root_path_match? => true)
395
+ end
396
+ it {@item.send(:selected_by_url?).should be_true}
397
+ end
398
+ context 'root path does not match' do
399
+ before(:each) do
400
+ @item.stub!(:root_path_match? => false)
401
+ end
402
+ context 'current request url matches url' do
403
+ before(:each) do
404
+ @adapter.stub!(:current_page? => true)
405
+ end
406
+ it "should test with the item's url" do
407
+ @adapter.should_receive(:current_page?).with('url')
408
+ @item.send(:selected_by_url?)
409
+ end
410
+ it "should remove anchors before testing the item's url" do
411
+ @item.stub!(:url => 'url#anchor')
412
+ @adapter.should_receive(:current_page?).with('url')
413
+ @item.send(:selected_by_url?)
414
+ end
415
+ it {@item.send(:selected_by_url?).should be_true}
416
+ end
417
+ context 'no match' do
418
+ before(:each) do
419
+ @adapter.stub!(:current_page? => false)
420
+ end
421
+ it {@item.send(:selected_by_url?).should be_false}
422
+ end
423
+ end
424
+ end
425
+ context 'auto_highlight is turned off' do
426
+ before(:each) do
427
+ @item.stub!(:auto_highlight? => false)
428
+ end
429
+ it {@item.send(:selected_by_url?).should be_false}
430
+ end
431
+ end
432
+
433
+ describe 'root_path_match?' do
434
+ it "should match if both url == /" do
435
+ @adapter.stub!(:request_path => '/')
436
+ @item.stub!(:url => '/')
437
+ @item.send(:root_path_match?).should be_true
438
+ end
439
+ it "should not match if item url is not /" do
440
+ @adapter.stub(:request_path => '/')
441
+ @item.stub!(:url => '/bla')
442
+ @item.send(:root_path_match?).should be_false
443
+ end
444
+ it "should not match if request url is not /" do
445
+ @adapter.stub(:request_path => '/bla')
446
+ @item.stub!(:url => '/')
447
+ @item.send(:root_path_match?).should be_false
448
+ end
449
+ it "should not match if urls do not match" do
450
+ @adapter.stub(:request_path => 'bla')
451
+ @item.stub!(:url => '/bli')
452
+ @item.send(:root_path_match?).should be_false
453
+ end
454
+ end
455
+
456
+ describe 'auto_highlight?' do
457
+ before(:each) do
458
+ @global = stub(:config)
459
+ SimpleNavigation.stub!(:config => @global)
460
+ end
461
+ context 'global auto_highlight on' do
462
+ before(:each) do
463
+ @global.stub!(:auto_highlight => true)
464
+ end
465
+ context 'container auto_highlight on' do
466
+ before(:each) do
467
+ @item_container.stub!(:auto_highlight => true)
468
+ end
469
+ it {@item.send(:auto_highlight?).should be_true}
470
+ end
471
+ context 'container auto_highlight off' do
472
+ before(:each) do
473
+ @item_container.stub!(:auto_highlight => false)
474
+ end
475
+ it {@item.send(:auto_highlight?).should be_false}
476
+ end
477
+ end
478
+ context 'global auto_highlight off' do
479
+ before(:each) do
480
+ @global.stub!(:auto_highlight => false)
481
+ end
482
+ context 'container auto_highlight on' do
483
+ before(:each) do
484
+ @item_container.stub!(:auto_highlight => true)
485
+ end
486
+ it {@item.send(:auto_highlight?).should be_false}
487
+ end
488
+ context 'container auto_highlight off' do
489
+ before(:each) do
490
+ @item_container.stub!(:auto_highlight => false)
491
+ end
492
+ it {@item.send(:auto_highlight?).should be_false}
493
+ end
494
+ end
495
+ end
496
+
497
+ describe 'autogenerated_item_id' do
498
+ context 'calls' do
499
+ before(:each) do
500
+ @id_generator = stub(:id_generator)
501
+ SimpleNavigation.config.stub!(:id_generator => @id_generator)
502
+ end
503
+ it "should call the configured generator with the key as param" do
504
+ @id_generator.should_receive(:call).with(:my_key)
505
+ @item.send(:autogenerated_item_id)
506
+ end
507
+ end
508
+ context 'default generator' do
509
+ it {@item.send(:autogenerated_item_id).should == 'my_key'}
510
+ end
511
+ end
512
+
513
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleNavigation::ItemsProvider do
4
+
5
+ before(:each) do
6
+ @provider = stub(:provider)
7
+ @items_provider = SimpleNavigation::ItemsProvider.new(@provider)
8
+ end
9
+
10
+ describe 'initialize' do
11
+ it "should set the provider" do
12
+ @items_provider.provider.should == @provider
13
+ end
14
+ end
15
+
16
+ describe 'items' do
17
+ before(:each) do
18
+ @items = stub(:items)
19
+ end
20
+ context 'provider is symbol' do
21
+ before(:each) do
22
+ @items_provider.instance_variable_set(:@provider, :provider_method)
23
+ @context = stub(:context, :provider_method => @items)
24
+ SimpleNavigation.stub!(:context_for_eval => @context)
25
+ end
26
+ it "should call the method specified by symbol on the context" do
27
+ @context.should_receive(:provider_method)
28
+ @items_provider.items
29
+ end
30
+ it "should return the items returned by the helper method" do
31
+ @items_provider.items.should == @items
32
+ end
33
+ end
34
+ context 'provider responds to items' do
35
+ before(:each) do
36
+ @provider.stub!(:items => @items)
37
+ end
38
+ it "should get the items from the items_provider" do
39
+ @provider.should_receive(:items)
40
+ @items_provider.items
41
+ end
42
+ it "should return the items of the provider" do
43
+ @items_provider.items.should == @items
44
+ end
45
+ end
46
+ context 'provider is a collection' do
47
+ before(:each) do
48
+ @items_collection = []
49
+ @items_provider.instance_variable_set(:@provider, @items_collection)
50
+ end
51
+ it "should return the collection itsself" do
52
+ @items_provider.items.should == @items_collection
53
+ end
54
+ end
55
+ context 'neither symbol nor items_provider.items nor collection' do
56
+ it {lambda {@items_provider.items}.should raise_error}
57
+ end
58
+ end
59
+
60
+ end