simple-navigation 3.14.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +10 -2
  5. data/CHANGELOG.md +400 -0
  6. data/Guardfile +4 -2
  7. data/README.md +1 -1
  8. data/gemfiles/.bundle/config +2 -0
  9. data/gemfiles/rails-3-2-stable.gemfile +10 -0
  10. data/gemfiles/rails-4-1-stable.gemfile +6 -0
  11. data/gemfiles/rails-4-2-stable.gemfile +7 -0
  12. data/generators/navigation_config/navigation_config_generator.rb +0 -1
  13. data/generators/navigation_config/templates/config/navigation.rb +18 -15
  14. data/lib/simple_navigation.rb +25 -42
  15. data/lib/simple_navigation/adapters/rails.rb +1 -24
  16. data/lib/simple_navigation/adapters/sinatra.rb +2 -11
  17. data/lib/simple_navigation/config_file.rb +36 -0
  18. data/lib/simple_navigation/config_file_finder.rb +42 -0
  19. data/lib/simple_navigation/{core/configuration.rb → configuration.rb} +7 -1
  20. data/lib/simple_navigation/{rendering/helpers.rb → helpers.rb} +0 -4
  21. data/lib/simple_navigation/{core/item.rb → item.rb} +76 -85
  22. data/lib/simple_navigation/{core/item_adapter.rb → item_adapter.rb} +3 -17
  23. data/lib/simple_navigation/{core/item_container.rb → item_container.rb} +23 -14
  24. data/lib/simple_navigation/{core/items_provider.rb → items_provider.rb} +0 -0
  25. data/lib/simple_navigation/railtie.rb +7 -0
  26. data/lib/simple_navigation/renderer.rb +12 -0
  27. data/lib/simple_navigation/{rendering/renderer → renderer}/base.rb +1 -1
  28. data/lib/simple_navigation/{rendering/renderer → renderer}/breadcrumbs.rb +0 -0
  29. data/lib/simple_navigation/{rendering/renderer → renderer}/json.rb +2 -0
  30. data/lib/simple_navigation/{rendering/renderer → renderer}/links.rb +0 -0
  31. data/lib/simple_navigation/{rendering/renderer → renderer}/list.rb +0 -0
  32. data/lib/simple_navigation/{rendering/renderer → renderer}/text.rb +0 -0
  33. data/lib/simple_navigation/version.rb +1 -1
  34. data/simple-navigation.gemspec +5 -4
  35. data/spec/fake_app/config/navigation.rb +6 -0
  36. data/spec/fake_app/rails_app.rb +35 -0
  37. data/spec/initializers/coveralls.rb +3 -0
  38. data/spec/initializers/have_css_matcher.rb +8 -3
  39. data/spec/initializers/memfs.rb +7 -0
  40. data/spec/initializers/rails.rb +4 -0
  41. data/spec/initializers/rspec.rb +7 -0
  42. data/spec/integration/rendering_navigation_spec.rb +12 -0
  43. data/spec/{lib/simple_navigation → simple_navigation}/adapters/padrino_spec.rb +0 -2
  44. data/spec/{lib/simple_navigation → simple_navigation}/adapters/rails_spec.rb +36 -93
  45. data/spec/{lib/simple_navigation → simple_navigation}/adapters/sinatra_spec.rb +4 -6
  46. data/spec/simple_navigation/config_file_finder_spec.rb +50 -0
  47. data/spec/simple_navigation/config_file_spec.rb +25 -0
  48. data/spec/{lib/simple_navigation/core → simple_navigation}/configuration_spec.rb +29 -19
  49. data/spec/{lib/simple_navigation/rendering → simple_navigation}/helpers_spec.rb +10 -13
  50. data/spec/{lib/simple_navigation/core → simple_navigation}/item_adapter_spec.rb +14 -11
  51. data/spec/{lib/simple_navigation/core → simple_navigation}/item_container_spec.rb +130 -42
  52. data/spec/simple_navigation/item_spec.rb +467 -0
  53. data/spec/{lib/simple_navigation/core → simple_navigation}/items_provider_spec.rb +1 -3
  54. data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/base_spec.rb +34 -36
  55. data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/breadcrumbs_spec.rb +4 -7
  56. data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/json_spec.rb +5 -11
  57. data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/links_spec.rb +5 -8
  58. data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/list_spec.rb +4 -7
  59. data/spec/{lib/simple_navigation/rendering → simple_navigation}/renderer/text_spec.rb +4 -7
  60. data/spec/simple_navigation_spec.rb +190 -0
  61. data/spec/spec_helper.rb +29 -35
  62. metadata +103 -68
  63. data/CHANGELOG +0 -292
  64. data/lib/simple_navigation/core.rb +0 -5
  65. data/lib/simple_navigation/rails_controller_methods.rb +0 -164
  66. data/lib/simple_navigation/rendering.rb +0 -12
  67. data/rails/init.rb +0 -1
  68. data/spec/lib/simple_navigation/core/item_spec.rb +0 -703
  69. data/spec/lib/simple_navigation/rails_controller_methods_spec.rb +0 -270
  70. data/spec/lib/simple_navigation_spec.rb +0 -300
@@ -1,16 +1,14 @@
1
- require 'spec_helper'
2
-
3
1
  describe SimpleNavigation::Adapters::Sinatra do
4
2
  let(:adapter) { SimpleNavigation::Adapters::Sinatra.new(context) }
5
3
  let(:context) { double(:context) }
6
4
  let(:request) { double(:request, fullpath: '/full?param=true', path: '/full') }
7
5
 
8
- before { context.stub(request: request) }
6
+ before { allow(context).to receive_messages(request: request) }
9
7
 
10
8
  describe '#context_for_eval' do
11
9
  context "when adapter's context is not set" do
12
10
  it 'raises an exception' do
13
- adapter.stub(context: nil)
11
+ allow(adapter).to receive_messages(context: nil)
14
12
  expect{ adapter.context_for_eval }.to raise_error
15
13
  end
16
14
  end
@@ -35,7 +33,7 @@ describe SimpleNavigation::Adapters::Sinatra do
35
33
  end
36
34
 
37
35
  describe '#current_page?' do
38
- before { request.stub(scheme: 'http', host_with_port: 'my_host:5000') }
36
+ before { allow(request).to receive_messages(scheme: 'http', host_with_port: 'my_host:5000') }
39
37
 
40
38
  shared_examples 'detecting current page' do |url, expected|
41
39
  context "when url is #{url}" do
@@ -59,7 +57,7 @@ describe SimpleNavigation::Adapters::Sinatra do
59
57
 
60
58
  context 'when URL is encoded' do
61
59
  before do
62
- request.stub(fullpath: '/full%20with%20spaces?param=true',
60
+ allow(request).to receive_messages(fullpath: '/full%20with%20spaces?param=true',
63
61
  path: '/full%20with%20spaces')
64
62
  end
65
63
 
@@ -0,0 +1,50 @@
1
+ require 'fileutils'
2
+ require 'simple_navigation/config_file_finder'
3
+
4
+ module SimpleNavigation
5
+ describe ConfigFileFinder do
6
+ subject(:finder) { ConfigFileFinder.new(paths) }
7
+
8
+ let(:paths) { ['/path/one', '/path/two'] }
9
+
10
+ describe '#find', memfs: true do
11
+ before { FileUtils.mkdir_p(paths) }
12
+
13
+ context 'when the context is :default' do
14
+ let(:context) { :default }
15
+
16
+ context 'and a navigation.rb file is found in one of the paths' do
17
+ before { FileUtils.touch('/path/one/navigation.rb') }
18
+
19
+ it 'returns its full path' do
20
+ expect(finder.find(context)).to eq '/path/one/navigation.rb'
21
+ end
22
+ end
23
+
24
+ context 'and no navigation.rb file is found in the paths' do
25
+ it 'raises an exception' do
26
+ expect{ finder.find(context) }.to raise_error
27
+ end
28
+ end
29
+ end
30
+
31
+ context 'when the context is :other' do
32
+ let(:context) { :other }
33
+
34
+ context 'and a other_navigation.rb file is found in one of the paths' do
35
+ before { FileUtils.touch('/path/two/other_navigation.rb') }
36
+
37
+ it 'returns its full path' do
38
+ expect(finder.find(context)).to eq '/path/two/other_navigation.rb'
39
+ end
40
+ end
41
+
42
+ context 'and no other_navigation.rb file is found in the paths' do
43
+ it 'raise an exception' do
44
+ expect{ finder.find(context) }.to raise_error
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,25 @@
1
+ require 'simple_navigation/config_file'
2
+
3
+ module SimpleNavigation
4
+ describe ConfigFile do
5
+ subject(:config_file) { ConfigFile.new(context) }
6
+
7
+ let(:context) { :default }
8
+
9
+ describe '#name' do
10
+ context 'when the context is :default' do
11
+ it 'returns navigation.rb' do
12
+ expect(config_file.name).to eq 'navigation.rb'
13
+ end
14
+ end
15
+
16
+ context 'when the context is different from :default' do
17
+ let(:context) { :HelloWorld }
18
+
19
+ it 'returns UNDERSCORED_CONTEXT_navigation.rb' do
20
+ expect(config_file.name).to eq 'hello_world_navigation.rb'
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  module SimpleNavigation
4
2
  describe Configuration do
5
3
  subject(:config) { Configuration.instance }
@@ -15,20 +13,20 @@ module SimpleNavigation
15
13
  let(:eval_context) { double(:eval_context) }
16
14
 
17
15
  before do
18
- eval_context.stub(:instance_eval)
19
- SimpleNavigation.stub(context_for_eval: eval_context,
20
- config_files: config_files)
16
+ allow(eval_context).to receive(:instance_eval)
17
+ allow(SimpleNavigation).to \
18
+ receive_messages(context_for_eval: eval_context, config_files: config_files)
21
19
  end
22
20
 
23
21
  context "with default navigation context" do
24
- it "should instance_eval the default config_file-string inside the context" do
22
+ it "calls instance_eval with the default config_file-string inside the context" do
25
23
  expect(eval_context).to receive(:instance_eval).with('default')
26
24
  Configuration.eval_config
27
25
  end
28
26
  end
29
27
 
30
28
  context 'with non default navigation context' do
31
- it "should instance_eval the specified config_file-string inside the context" do
29
+ it "calls instance_eval with the specified config_file-string inside the context" do
32
30
  expect(eval_context).to receive(:instance_eval).with('my_context')
33
31
  Configuration.eval_config(:my_context)
34
32
  end
@@ -49,30 +47,42 @@ module SimpleNavigation
49
47
  end
50
48
 
51
49
  it 'sets autogenerate_item_ids to true as default' do
52
- expect(config.autogenerate_item_ids).to be_true
50
+ expect(config.autogenerate_item_ids).to be true
53
51
  end
54
52
 
55
53
  it 'sets auto_highlight to true as default' do
56
- expect(config.auto_highlight).to be_true
54
+ expect(config.auto_highlight).to be true
55
+ end
56
+
57
+ it 'sets the id_generator to a callable object' do
58
+ expect(config.id_generator).to respond_to(:call)
57
59
  end
58
60
 
59
- it 'should set the id_generator' do
60
- expect(config.id_generator).not_to be_nil
61
+ it 'sets the name_generator to a callable object' do
62
+ expect(config.name_generator).to respond_to(:call)
61
63
  end
62
64
 
63
- it 'should set the name_generator' do
64
- expect(config.name_generator).not_to be_nil
65
+ it 'sets the consider_item_names_as_safe to false' do
66
+ expect(config.consider_item_names_as_safe).to be false
67
+ end
68
+
69
+ it 'sets highlights_on_subpath to false as default' do
70
+ expect(config.highlight_on_subpath).to be false
65
71
  end
66
72
 
67
- it 'should set the consider_item_names_as_safe to false' do
68
- expect(config.consider_item_names_as_safe).to be_false
73
+ it 'sets ignore_query_params_on_auto_highlight to true as default' do
74
+ expect(config.ignore_query_params_on_auto_highlight).to be true
75
+ end
76
+
77
+ it 'sets ignore_anchors_on_auto_highlight to true as default' do
78
+ expect(config.ignore_anchors_on_auto_highlight).to be true
69
79
  end
70
80
  end
71
81
 
72
82
  describe '#items' do
73
83
  let(:container) { double(:items_container) }
74
84
 
75
- before { ItemContainer.stub(:new).and_return(container) }
85
+ before { allow(ItemContainer).to receive_messages(new: container) }
76
86
 
77
87
  context 'when a block is given' do
78
88
  context 'and items_provider is specified' do
@@ -107,8 +117,8 @@ module SimpleNavigation
107
117
  let(:items_provider) { double(:items_provider, items: items) }
108
118
 
109
119
  before do
110
- SimpleNavigation::ItemsProvider.stub(new: items_provider)
111
- container.stub(:items=)
120
+ allow(SimpleNavigation::ItemsProvider).to receive_messages(new: items_provider)
121
+ allow(container).to receive(:items=)
112
122
  end
113
123
 
114
124
  it 'creates a new Provider object for the specified provider' do
@@ -144,7 +154,7 @@ module SimpleNavigation
144
154
  end
145
155
 
146
156
  context 'when primary_nav is not set' do
147
- it "should return false if no primary_nav is set" do
157
+ it 'returns false if no primary_nav is set' do
148
158
  config.instance_variable_set(:@primary_navigation, nil)
149
159
  expect(config).not_to be_loaded
150
160
  end
@@ -1,21 +1,18 @@
1
- require 'spec_helper'
2
-
3
- class TestController
4
- include SimpleNavigation::Helpers
5
- end
6
-
7
1
  module SimpleNavigation
8
2
  describe Helpers do
9
- subject(:controller) { TestController.new }
3
+ subject(:controller) { test_controller_class.new }
10
4
 
11
5
  let(:invoices_item) { navigation[:invoices] }
12
6
  let(:item) { nil }
13
7
  let(:navigation) { setup_navigation('nav_id', 'nav_class') }
8
+ let(:test_controller_class) do
9
+ Class.new { include SimpleNavigation::Helpers }
10
+ end
14
11
  let(:unpaid_item) { invoices_item.sub_navigation[:unpaid] }
15
12
 
16
13
  before do
17
- Configuration.stub(:eval_config)
18
- SimpleNavigation.stub(load_config: nil,
14
+ allow(Configuration).to receive(:eval_config)
15
+ allow(SimpleNavigation).to receive_messages(load_config: nil,
19
16
  primary_navigation: navigation,
20
17
  config_file?: true,
21
18
  context_for_eval: controller)
@@ -357,7 +354,7 @@ module SimpleNavigation
357
354
  let(:item_container) { double(:container).as_null_object }
358
355
 
359
356
  before do
360
- SimpleNavigation.stub(active_item_container_for: item_container)
357
+ allow(SimpleNavigation).to receive_messages(active_item_container_for: item_container)
361
358
  end
362
359
 
363
360
  it 'finds the selected sub navigation for the specified level' do
@@ -391,7 +388,7 @@ module SimpleNavigation
391
388
  end
392
389
 
393
390
  context 'when the :levels option is set' do
394
- before { SimpleNavigation.stub(active_item_container_for: navigation) }
391
+ before { allow(SimpleNavigation).to receive_messages(active_item_container_for: navigation) }
395
392
 
396
393
  it 'treats it like the :level option' do
397
394
  expect(navigation).to receive(:render).with(level: 2)
@@ -408,7 +405,7 @@ module SimpleNavigation
408
405
  end
409
406
 
410
407
  context 'when no primary configuration is defined' do
411
- before { SimpleNavigation.stub(primary_navigation: nil) }
408
+ before { allow(SimpleNavigation).to receive_messages(primary_navigation: nil) }
412
409
 
413
410
  it 'raises an exception' do
414
411
  expect{controller.render_navigation}.to raise_error
@@ -419,7 +416,7 @@ module SimpleNavigation
419
416
  let(:active_item_container) { double(:container).as_null_object }
420
417
 
421
418
  before do
422
- SimpleNavigation.stub(active_item_container_for: active_item_container)
419
+ allow(SimpleNavigation).to receive_messages(active_item_container_for: active_item_container)
423
420
  end
424
421
 
425
422
  it 'calls render on the active_item_container' do
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  module SimpleNavigation
4
2
  describe ItemAdapter do
5
3
  let(:item_adapter) { ItemAdapter.new(item) }
@@ -28,7 +26,7 @@ module SimpleNavigation
28
26
  context 'when item responds to options' do
29
27
  let(:options) { double(:options) }
30
28
 
31
- before { item.stub(options: options) }
29
+ before { allow(item).to receive_messages(options: options) }
32
30
 
33
31
  it "returns the item's options" do
34
32
  expect(item_adapter.options).to be options
@@ -45,7 +43,7 @@ module SimpleNavigation
45
43
  describe '#items' do
46
44
  context 'when item responds to items' do
47
45
  context 'and items is nil' do
48
- before { item.stub(items: nil) }
46
+ before { allow(item).to receive_messages(items: nil) }
49
47
 
50
48
  it 'returns nil' do
51
49
  expect(item_adapter.items).to be_nil
@@ -54,7 +52,7 @@ module SimpleNavigation
54
52
 
55
53
  context 'when items is not nil' do
56
54
  context 'and items is empty' do
57
- before { item.stub(items: []) }
55
+ before { allow(item).to receive_messages(items: []) }
58
56
 
59
57
  it 'returns nil' do
60
58
  expect(item_adapter.items).to be_nil
@@ -64,7 +62,7 @@ module SimpleNavigation
64
62
  context 'and items is not empty' do
65
63
  let(:items) { [true] }
66
64
 
67
- before { item.stub(items: items) }
65
+ before { allow(item).to receive_messages(items: items) }
68
66
 
69
67
  it 'returns the items' do
70
68
  expect(item_adapter.items).to eq items
@@ -83,11 +81,11 @@ module SimpleNavigation
83
81
  describe '#to_simple_navigation_item' do
84
82
  let(:container) { double(:container) }
85
83
 
86
- before { item.stub(items: [], options: {}) }
84
+ before { allow(item).to receive_messages(items: [], options: {}) }
87
85
 
88
86
  it 'creates an Item' do
89
87
  expect(Item).to receive(:new)
90
- .with(container, 'key', 'name', 'url', {}, nil)
88
+ .with(container, 'key', 'name', 'url', {})
91
89
  item_adapter.to_simple_navigation_item(container)
92
90
  end
93
91
  end
@@ -172,13 +170,18 @@ module SimpleNavigation
172
170
  describe '#to_simple_navigation_item' do
173
171
  let(:container) { double(:container) }
174
172
 
175
- before { item.merge(items: [], options: {}) }
173
+ before { item.merge(options: {}) }
176
174
 
177
- it 'creates an Item' do
175
+ it 'passes the right arguments to Item' do
178
176
  expect(Item).to receive(:new)
179
- .with(container, 'key', 'name', 'url', {}, nil)
177
+ .with(container, 'key', 'name', 'url', {})
180
178
  item_adapter.to_simple_navigation_item(container)
181
179
  end
180
+
181
+ it 'creates an Item' do
182
+ created_item = item_adapter.to_simple_navigation_item(container)
183
+ expect(created_item).to be_an(Item)
184
+ end
182
185
  end
183
186
  end
184
187
  end
@@ -1,12 +1,10 @@
1
- require 'spec_helper'
2
-
3
1
  module SimpleNavigation
4
2
  describe ItemContainer do
5
3
  subject(:item_container) { ItemContainer.new }
6
4
 
7
5
  shared_examples 'adding the item to the list' do
8
6
  it 'adds the item to the list' do
9
- Item.stub(:new).and_return(item)
7
+ allow(Item).to receive_messages(new: item)
10
8
  item_container.item(*args)
11
9
  expect(item_container.items).to include(item)
12
10
  end
@@ -14,7 +12,7 @@ module SimpleNavigation
14
12
 
15
13
  shared_examples 'not adding the item to the list' do
16
14
  it "doesn't add the item to the list" do
17
- Item.stub(:new).and_return(item)
15
+ allow(Item).to receive_messages(new: item)
18
16
  item_container.item(*args)
19
17
  expect(item_container.items).not_to include(item)
20
18
  end
@@ -75,12 +73,14 @@ module SimpleNavigation
75
73
  let(:real_item) { double(:real_item) }
76
74
 
77
75
  before do
78
- ItemAdapter.stub(:new).and_return(item_adapter)
79
- item_adapter.stub(to_simple_navigation_item: real_item)
76
+ allow(ItemAdapter).to receive_messages(new: item_adapter)
77
+ allow(item_adapter).to receive(:to_simple_navigation_item)
78
+ .with(item_container)
79
+ .and_return(real_item)
80
80
  end
81
81
 
82
82
  context 'when the item should be added' do
83
- before { item_container.stub(should_add_item?: true) }
83
+ before { allow(item_container).to receive_messages(should_add_item?: true) }
84
84
 
85
85
  it 'converts it to an Item and adds it to the items collection' do
86
86
  item_container.items = items
@@ -89,7 +89,7 @@ module SimpleNavigation
89
89
  end
90
90
 
91
91
  context 'when the item should not be added' do
92
- before { item_container.stub(should_add_item?: false) }
92
+ before { allow(item_container).to receive_messages(should_add_item?: false) }
93
93
 
94
94
  it "doesn't add it to the items collection" do
95
95
  item_container.items = items
@@ -114,7 +114,7 @@ module SimpleNavigation
114
114
 
115
115
  context 'when an item is selected' do
116
116
  it 'returns true' do
117
- item_1.stub(selected?: true)
117
+ allow(item_1).to receive_messages(selected?: true)
118
118
  expect(item_container).to be_selected
119
119
  end
120
120
  end
@@ -125,8 +125,8 @@ module SimpleNavigation
125
125
  let(:item_2) { double(:item, selected?: false) }
126
126
 
127
127
  before(:each) do
128
- SimpleNavigation.stub(current_navigation_for: :nav)
129
- item_container.stub(:[] => nil)
128
+ allow(SimpleNavigation).to receive_messages(current_navigation_for: :nav)
129
+ allow(item_container).to receive_messages(:[] => nil)
130
130
  item_container.instance_variable_set(:@items, [item_1, item_2])
131
131
  end
132
132
 
@@ -138,7 +138,7 @@ module SimpleNavigation
138
138
  end
139
139
 
140
140
  context 'and an item selected' do
141
- before { item_1.stub(selected?: true) }
141
+ before { allow(item_1).to receive_messages(selected?: true) }
142
142
 
143
143
  it 'returns the selected item' do
144
144
  expect(item_container.selected_item).to be item_1
@@ -156,7 +156,7 @@ module SimpleNavigation
156
156
 
157
157
  context "when the desired level is different than the container's" do
158
158
  context 'and no subnavigation is selected' do
159
- before { item_container.stub(selected_sub_navigation?: false) }
159
+ before { allow(item_container).to receive_messages(selected_sub_navigation?: false) }
160
160
 
161
161
  it 'returns nil' do
162
162
  expect(item_container.active_item_container_for(2)).to be_nil
@@ -168,9 +168,9 @@ module SimpleNavigation
168
168
  let(:selected_item) { double(:selected_item) }
169
169
 
170
170
  before do
171
- item_container.stub(selected_sub_navigation?: true,
172
- selected_item: selected_item)
173
- selected_item.stub(sub_navigation: sub_navigation)
171
+ allow(item_container).to \
172
+ receive_messages(selected_sub_navigation?: true, selected_item: selected_item)
173
+ allow(selected_item).to receive_messages(sub_navigation: sub_navigation)
174
174
  end
175
175
 
176
176
  it 'calls recursively on the sub_navigation' do
@@ -188,9 +188,9 @@ module SimpleNavigation
188
188
  let(:selected_item) { double(:selected_item) }
189
189
 
190
190
  before do
191
- item_container.stub(selected_sub_navigation?: true,
191
+ allow(item_container).to receive_messages(selected_sub_navigation?: true,
192
192
  selected_item: selected_item)
193
- selected_item.stub(sub_navigation: sub_navigation)
193
+ allow(selected_item).to receive_messages(sub_navigation: sub_navigation)
194
194
  end
195
195
 
196
196
  it 'calls recursively on the sub_navigation' do
@@ -200,7 +200,7 @@ module SimpleNavigation
200
200
  end
201
201
 
202
202
  context 'when the current container is the leaf already' do
203
- before { item_container.stub(selected_sub_navigation?: false) }
203
+ before { allow(item_container).to receive_messages(selected_sub_navigation?: false) }
204
204
 
205
205
  it 'returns itsself' do
206
206
  expect(item_container.active_leaf_container).to be item_container
@@ -217,9 +217,8 @@ module SimpleNavigation
217
217
  let(:sub_container) { double(:sub_container) }
218
218
 
219
219
  it 'yields a new ItemContainer' do
220
- Item.any_instance
221
- .stub(:sub_navigation)
222
- .and_return(sub_container)
220
+ allow_any_instance_of(Item).to \
221
+ receive_messages(sub_navigation: sub_container)
223
222
 
224
223
  expect{ |blk|
225
224
  item_container.item('key', 'name', 'url', options, &blk)
@@ -227,9 +226,9 @@ module SimpleNavigation
227
226
  end
228
227
 
229
228
  it "creates a new Item with the given params and block" do
230
- Item.stub(:new)
231
- .with(item_container, 'key', 'name', 'url', options, nil, &block)
232
- .and_return(item)
229
+ allow(Item).to receive(:new)
230
+ .with(item_container, 'key', 'name', 'url', options, &block)
231
+ .and_return(item)
233
232
  item_container.item('key', 'name', 'url', options, &block)
234
233
  expect(item_container.items).to include(item)
235
234
  end
@@ -242,15 +241,15 @@ module SimpleNavigation
242
241
 
243
242
  context 'when no block is given' do
244
243
  it 'creates a new Item with the given params and no sub navigation' do
245
- Item.stub(:new)
246
- .with(item_container, 'key', 'name', 'url', options, nil)
247
- .and_return(item)
244
+ allow(Item).to receive(:new)
245
+ .with(item_container, 'key', 'name', 'url', options)
246
+ .and_return(item)
248
247
  item_container.item('key', 'name', 'url', options)
249
248
  expect(item_container.items).to include(item)
250
249
  end
251
250
 
252
251
  it 'adds the created item to the list of items' do
253
- Item.stub(:new).and_return(item)
252
+ allow(Item).to receive_messages(new: item)
254
253
  item_container.item('key', 'name', 'url', options) {}
255
254
  expect(item_container.items).to include(item)
256
255
  end
@@ -278,13 +277,13 @@ module SimpleNavigation
278
277
 
279
278
  context 'and options contains a negative condition' do
280
279
  it_behaves_like 'not adding the item to the list' do
281
- let(:args) { ['key', 'name', { if: ->{ false }, option: true }] }
280
+ let(:args) { ['key', 'name', nil, { if: ->{ false }, option: true }] }
282
281
  end
283
282
  end
284
283
 
285
284
  context 'and options contains a positive condition' do
286
285
  it_behaves_like 'adding the item to the list' do
287
- let(:args) { ['key', 'name', { if: ->{ true }, option: true }] }
286
+ let(:args) { ['key', 'name', nil, { if: ->{ true }, option: true }] }
288
287
  end
289
288
  end
290
289
  end
@@ -308,6 +307,105 @@ module SimpleNavigation
308
307
  end
309
308
  end
310
309
  end
310
+
311
+ context 'when a frozen options hash is given' do
312
+ let(:options) do
313
+ { html: { id: 'test' } }.freeze
314
+ end
315
+
316
+ it 'does not raise an exception' do
317
+ expect{
318
+ item_container.item('key', 'name', 'url', options)
319
+ }.not_to raise_error
320
+ end
321
+ end
322
+
323
+ describe "container options" do
324
+ before do
325
+ allow(item_container).to receive_messages(should_add_item?: add_item)
326
+ item_container.item :key, 'name', 'url', options
327
+ end
328
+
329
+ context 'when the container :id option is specified' do
330
+ let(:options) {{ container: { id: 'c_id' } }}
331
+
332
+ context 'and the item should be added' do
333
+ let(:add_item) { true }
334
+
335
+ it 'changes its dom_id' do
336
+ expect(item_container.dom_id).to eq 'c_id'
337
+ end
338
+ end
339
+
340
+ context "and the item shouldn't be added" do
341
+ let(:add_item) { false }
342
+
343
+ it "doesn't change its dom_id" do
344
+ expect(item_container.dom_id).to be_nil
345
+ end
346
+ end
347
+ end
348
+
349
+ context 'when the container :class option is specified' do
350
+ let(:options) {{ container: { class: 'c_class' } }}
351
+
352
+ context 'and the item should be added' do
353
+ let(:add_item) { true }
354
+
355
+ it 'changes its dom_class' do
356
+ expect(item_container.dom_class).to eq 'c_class'
357
+ end
358
+ end
359
+
360
+ context "and the item shouldn't be added" do
361
+ let(:add_item) { false }
362
+
363
+ it "doesn't change its dom_class" do
364
+ expect(item_container.dom_class).to be_nil
365
+ end
366
+ end
367
+ end
368
+
369
+ context 'when the container :attributes option is specified' do
370
+ let(:options) {{ container: { attributes: { option: true } } }}
371
+
372
+ context 'and the item should be added' do
373
+ let(:add_item) { true }
374
+
375
+ it 'changes its dom_attributes' do
376
+ expect(item_container.dom_attributes).to eq(option: true)
377
+ end
378
+ end
379
+
380
+ context "and the item shouldn't be added" do
381
+ let(:add_item) { false }
382
+
383
+ it "doesn't change its dom_attributes" do
384
+ expect(item_container.dom_attributes).to eq({})
385
+ end
386
+ end
387
+ end
388
+
389
+ context 'when the container :selected_class option is specified' do
390
+ let(:options) {{ container: { selected_class: 'sel_class' } }}
391
+
392
+ context 'and the item should be added' do
393
+ let(:add_item) { true }
394
+
395
+ it 'changes its selected_class' do
396
+ expect(item_container.selected_class).to eq 'sel_class'
397
+ end
398
+ end
399
+
400
+ context "and the item shouldn't be added" do
401
+ let(:add_item) { false }
402
+
403
+ it "doesn't change its selected_class" do
404
+ expect(item_container.selected_class).to be_nil
405
+ end
406
+ end
407
+ end
408
+ end
311
409
  end
312
410
 
313
411
  describe 'Conditions' do
@@ -315,11 +413,6 @@ module SimpleNavigation
315
413
  let(:options) {{ if: proc{condition} }}
316
414
  let(:condition) { nil }
317
415
 
318
- it 'removes :if from the options' do
319
- item_container.item('key', 'name', 'url', options)
320
- expect(options).not_to have_key(:if)
321
- end
322
-
323
416
  context 'and it evals to true' do
324
417
  let(:condition) { true }
325
418
 
@@ -351,11 +444,6 @@ module SimpleNavigation
351
444
  let(:options) {{ unless: proc{condition} }}
352
445
  let(:condition) { nil }
353
446
 
354
- it "removes :unless from the options" do
355
- item_container.item('key', 'name', 'url', options)
356
- expect(options).not_to have_key(:unless)
357
- end
358
-
359
447
  context 'and it evals to false' do
360
448
  let(:condition) { false }
361
449
 
@@ -436,7 +524,7 @@ module SimpleNavigation
436
524
  context 'when no renderer is specified' do
437
525
  let(:options) { Hash.new }
438
526
 
439
- before { item_container.stub(renderer: renderer_class) }
527
+ before { allow(item_container).to receive_messages(renderer: renderer_class) }
440
528
 
441
529
  it "instantiates the container's renderer with the options" do
442
530
  expect(renderer_class).to receive(:new).with(options)