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.
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/CHANGELOG +11 -0
- data/Gemfile +2 -16
- data/Guardfile +5 -0
- data/LICENSE +22 -0
- data/README.md +40 -0
- data/Rakefile +6 -39
- data/generators/navigation_config/templates/config/navigation.rb +7 -5
- data/init.rb +1 -0
- data/install.rb +5 -0
- data/lib/simple_navigation/adapters/rails.rb +5 -1
- data/lib/simple_navigation/core/configuration.rb +5 -1
- data/lib/simple_navigation/core/item.rb +2 -1
- data/lib/simple_navigation/core/item_adapter.rb +4 -4
- data/lib/simple_navigation/core/item_container.rb +6 -1
- data/lib/simple_navigation/rendering/renderer/breadcrumbs.rb +2 -2
- data/lib/simple_navigation/rendering/renderer/links.rb +2 -2
- data/lib/simple_navigation/rendering/renderer/list.rb +1 -1
- data/lib/simple_navigation/version.rb +3 -0
- data/lib/simple_navigation.rb +1 -0
- data/simple-navigation.gemspec +40 -0
- data/spec/initializers/have_css_matcher.rb +13 -0
- data/spec/lib/simple_navigation/adapters/padrino_spec.rb +23 -25
- data/spec/lib/simple_navigation/adapters/rails_spec.rb +276 -250
- data/spec/lib/simple_navigation/adapters/sinatra_spec.rb +64 -53
- data/spec/lib/simple_navigation/core/configuration_spec.rb +128 -106
- data/spec/lib/simple_navigation/core/item_adapter_spec.rb +144 -168
- data/spec/lib/simple_navigation/core/item_container_spec.rb +361 -339
- data/spec/lib/simple_navigation/core/item_spec.rb +571 -434
- data/spec/lib/simple_navigation/core/items_provider_spec.rb +35 -49
- data/spec/lib/simple_navigation/rails_controller_methods_spec.rb +194 -173
- data/spec/lib/simple_navigation/rendering/helpers_spec.rb +381 -225
- data/spec/lib/simple_navigation/rendering/renderer/base_spec.rb +205 -164
- data/spec/lib/simple_navigation/rendering/renderer/breadcrumbs_spec.rb +87 -67
- data/spec/lib/simple_navigation/rendering/renderer/json_spec.rb +52 -31
- data/spec/lib/simple_navigation/rendering/renderer/links_spec.rb +75 -48
- data/spec/lib/simple_navigation/rendering/renderer/list_spec.rb +62 -174
- data/spec/lib/simple_navigation/rendering/renderer/text_spec.rb +41 -28
- data/spec/lib/simple_navigation_spec.rb +207 -225
- data/spec/spec_helper.rb +53 -82
- data/uninstall.rb +1 -0
- metadata +100 -22
- data/README +0 -22
- data/VERSION +0 -1
@@ -1,451 +1,473 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
end
|
7
|
-
describe 'initialize' do
|
8
|
-
it "should set the renderer to the globally-configured renderer per default" do
|
9
|
-
SimpleNavigation::Configuration.instance.should_receive(:renderer)
|
10
|
-
@item_container = SimpleNavigation::ItemContainer.new
|
11
|
-
end
|
12
|
-
it "should have an empty items-array" do
|
13
|
-
@item_container = SimpleNavigation::ItemContainer.new
|
14
|
-
@item_container.items.should be_empty
|
15
|
-
end
|
16
|
-
end
|
3
|
+
module SimpleNavigation
|
4
|
+
describe ItemContainer do
|
5
|
+
let(:item_container) { ItemContainer.new }
|
17
6
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@item_adapter = stub(:item_adapter).as_null_object
|
23
|
-
SimpleNavigation::ItemAdapter.stub(:new => @item_adapter)
|
24
|
-
@item_container.stub!(:should_add_item? => true)
|
25
|
-
end
|
26
|
-
it "should wrap each item in an ItemAdapter" do
|
27
|
-
SimpleNavigation::ItemAdapter.should_receive(:new)
|
28
|
-
@item_container.items = @items
|
29
|
-
end
|
30
|
-
context 'item should be added' do
|
31
|
-
before(:each) do
|
32
|
-
@item_container.stub!(:should_add_item? => true)
|
33
|
-
@simple_navigation_item = stub(:simple_navigation_item)
|
34
|
-
@item_adapter.stub!(:to_simple_navigation_item => @simple_navigation_item)
|
35
|
-
end
|
36
|
-
it "should convert the item to a SimpleNavigation::Item" do
|
37
|
-
@item_adapter.should_receive(:to_simple_navigation_item).with(@item_container)
|
38
|
-
@item_container.items = @items
|
7
|
+
describe '#initialize' do
|
8
|
+
it 'sets the renderer to the globally-configured renderer per default' do
|
9
|
+
expect(Configuration.instance).to receive(:renderer)
|
10
|
+
ItemContainer.new
|
39
11
|
end
|
40
|
-
|
41
|
-
|
42
|
-
|
12
|
+
|
13
|
+
it "sets an empty items array" do
|
14
|
+
expect(item_container.items).to be_empty
|
43
15
|
end
|
44
16
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
17
|
+
|
18
|
+
describe '#items=' do
|
19
|
+
let(:item) { double(:item) }
|
20
|
+
let(:items) { [item] }
|
21
|
+
let(:item_adapter) { double(:item_adapter).as_null_object }
|
22
|
+
|
23
|
+
before do
|
24
|
+
ItemAdapter.stub(new: item_adapter)
|
25
|
+
item_container.stub(should_add_item?: true)
|
52
26
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
27
|
+
|
28
|
+
it 'wraps each item in an ItemAdapter' do
|
29
|
+
expect(ItemAdapter).to receive(:new)
|
30
|
+
item_container.items = items
|
56
31
|
end
|
57
|
-
end
|
58
|
-
end
|
59
32
|
|
60
|
-
|
61
|
-
|
62
|
-
@item_1 = stub(:item, :selected? => false)
|
63
|
-
@item_2 = stub(:item, :selected? => false)
|
64
|
-
@item_container.instance_variable_set(:@items, [@item_1, @item_2])
|
65
|
-
end
|
66
|
-
it "should return nil if no item is selected" do
|
67
|
-
@item_container.should_not be_selected
|
68
|
-
end
|
69
|
-
it "should return true if one item is selected" do
|
70
|
-
@item_1.stub!(:selected? => true)
|
71
|
-
@item_container.should be_selected
|
72
|
-
end
|
73
|
-
end
|
33
|
+
context 'when item should be added' do
|
34
|
+
let(:simple_navigation_item) { double(:simple_navigation_item) }
|
74
35
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
@item_container.stub!(:[] => nil)
|
79
|
-
@item_1 = stub(:item, :selected? => false)
|
80
|
-
@item_2 = stub(:item, :selected? => false)
|
81
|
-
@item_container.instance_variable_set(:@items, [@item_1, @item_2])
|
82
|
-
end
|
83
|
-
context 'navigation not explicitely set' do
|
84
|
-
context 'no item selected' do
|
85
|
-
it "should return nil" do
|
86
|
-
@item_container.selected_item.should be_nil
|
36
|
+
before do
|
37
|
+
item_container.stub(should_add_item?: true)
|
38
|
+
item_adapter.stub(to_simple_navigation_item: simple_navigation_item)
|
87
39
|
end
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
40
|
+
|
41
|
+
it 'converts the item to an Item' do
|
42
|
+
expect(item_adapter).to receive(:to_simple_navigation_item)
|
43
|
+
.with(item_container)
|
44
|
+
item_container.items = items
|
92
45
|
end
|
93
|
-
|
94
|
-
|
46
|
+
|
47
|
+
it 'adds the item to the items-collection' do
|
48
|
+
expect(item_container.items).to receive(:<<)
|
49
|
+
.with(simple_navigation_item)
|
50
|
+
item_container.items = items
|
95
51
|
end
|
96
52
|
end
|
97
|
-
end
|
98
|
-
end
|
99
53
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
context 'selected item has sub_navigation' do
|
107
|
-
before(:each) do
|
108
|
-
@sub_navigation = stub(:sub_navigation)
|
109
|
-
@selected_item.stub!(:sub_navigation => @sub_navigation)
|
54
|
+
context 'when item should not be added' do
|
55
|
+
before { item_container.stub(should_add_item?: false) }
|
56
|
+
|
57
|
+
it "doesn't convert the item to an Item" do
|
58
|
+
expect(item_adapter).not_to receive(:to_simple_navigation_item)
|
59
|
+
item_container.items = items
|
110
60
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
@selected_item.stub!(:sub_navigation => nil)
|
61
|
+
|
62
|
+
it "doesn't add the item to the items-collection" do
|
63
|
+
expect(item_container.items).not_to receive(:<<)
|
64
|
+
item_container.items = items
|
116
65
|
end
|
117
|
-
it {@item_container.send(:selected_sub_navigation?).should be_false}
|
118
66
|
end
|
119
67
|
end
|
120
|
-
context 'without an item selected' do
|
121
|
-
before(:each) do
|
122
|
-
@item_container.stub!(:selected_item => nil)
|
123
|
-
end
|
124
|
-
it {@item_container.send(:selected_sub_navigation?).should be_false}
|
125
|
-
end
|
126
68
|
|
127
|
-
|
69
|
+
describe '#selected?' do
|
70
|
+
let(:item_1) { double(:item, selected?: false) }
|
71
|
+
let(:item_2) { double(:item, selected?: false) }
|
128
72
|
|
129
|
-
|
130
|
-
|
131
|
-
it {@item_container.active_item_container_for(1).should == @item_container}
|
132
|
-
end
|
133
|
-
context "the desired level is different than the container's" do
|
134
|
-
context 'with no selected subnavigation' do
|
135
|
-
before(:each) do
|
136
|
-
@item_container.stub!(:selected_sub_navigation? => false)
|
137
|
-
end
|
138
|
-
it {@item_container.active_item_container_for(2).should be_nil}
|
73
|
+
before do
|
74
|
+
item_container.instance_variable_set(:@items, [item_1, item_2])
|
139
75
|
end
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
@selected_item = stub(:selected_item)
|
145
|
-
@item_container.stub!(:selected_item => @selected_item)
|
146
|
-
@selected_item.stub!(:sub_navigation => @sub_nav)
|
147
|
-
end
|
148
|
-
it "should call recursively on the sub_navigation" do
|
149
|
-
@sub_nav.should_receive(:active_item_container_for).with(2)
|
150
|
-
@item_container.active_item_container_for(2)
|
76
|
+
|
77
|
+
context 'when no item is selected' do
|
78
|
+
it 'returns nil' do
|
79
|
+
expect(item_container).not_to be_selected
|
151
80
|
end
|
152
81
|
end
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
@item_container.stub!(:selected_sub_navigation? => true)
|
160
|
-
@sub_nav = stub(:sub_nav)
|
161
|
-
@selected_item = stub(:selected_item)
|
162
|
-
@item_container.stub!(:selected_item => @selected_item)
|
163
|
-
@selected_item.stub!(:sub_navigation => @sub_nav)
|
164
|
-
end
|
165
|
-
it "should call recursively on the sub_navigation" do
|
166
|
-
@sub_nav.should_receive(:active_leaf_container)
|
167
|
-
@item_container.active_leaf_container
|
168
|
-
end
|
169
|
-
end
|
170
|
-
context 'the current container is the leaf already' do
|
171
|
-
before(:each) do
|
172
|
-
@item_container.stub!(:selected_sub_navigation? => false)
|
173
|
-
end
|
174
|
-
it "should return itsself" do
|
175
|
-
@item_container.active_leaf_container.should == @item_container
|
82
|
+
|
83
|
+
context 'when an item is selected' do
|
84
|
+
it 'returns true' do
|
85
|
+
item_1.stub(selected?: true)
|
86
|
+
expect(item_container).to be_selected
|
87
|
+
end
|
176
88
|
end
|
177
89
|
end
|
178
|
-
end
|
179
90
|
|
180
|
-
|
181
|
-
|
182
|
-
|
91
|
+
describe '#selected_item' do
|
92
|
+
let(:item_1) { double(:item, selected?: false) }
|
93
|
+
let(:item_2) { double(:item, selected?: false) }
|
183
94
|
|
184
95
|
before(:each) do
|
185
|
-
|
186
|
-
|
96
|
+
SimpleNavigation.stub(current_navigation_for: :nav)
|
97
|
+
item_container.stub(:[] => nil)
|
98
|
+
item_container.instance_variable_set(:@items, [item_1, item_2])
|
187
99
|
end
|
188
100
|
|
189
|
-
context
|
190
|
-
|
191
|
-
|
192
|
-
|
101
|
+
context "when navigation isn't explicitely set" do
|
102
|
+
context 'and no item is selected' do
|
103
|
+
it 'returns nil' do
|
104
|
+
expect(item_container.selected_item).to be_nil
|
105
|
+
end
|
193
106
|
end
|
194
107
|
|
195
|
-
|
196
|
-
|
197
|
-
|
108
|
+
context 'and an item selected' do
|
109
|
+
before { item_1.stub(selected?: true) }
|
110
|
+
|
111
|
+
it 'returns the selected item' do
|
112
|
+
expect(item_container.selected_item).to be item_1
|
198
113
|
end
|
199
114
|
end
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#active_item_container_for' do
|
119
|
+
context "when the desired level is the same as the container's" do
|
120
|
+
it 'returns the container itself' do
|
121
|
+
expect(item_container.active_item_container_for(1)).to be item_container
|
207
122
|
end
|
208
123
|
end
|
209
124
|
|
210
|
-
context
|
211
|
-
|
212
|
-
|
213
|
-
|
125
|
+
context "when the desired level is different than the container's" do
|
126
|
+
context 'and no subnavigation is selected' do
|
127
|
+
before { item_container.stub(selected_sub_navigation?: false) }
|
128
|
+
|
129
|
+
it 'returns nil' do
|
130
|
+
expect(item_container.active_item_container_for(2)).to be_nil
|
131
|
+
end
|
214
132
|
end
|
215
|
-
|
216
|
-
|
217
|
-
|
133
|
+
|
134
|
+
context 'and a subnavigation is selected' do
|
135
|
+
let(:sub_navigation) { double(:sub_navigation) }
|
136
|
+
let(:selected_item) { double(:selected_item) }
|
137
|
+
|
138
|
+
before do
|
139
|
+
item_container.stub(selected_sub_navigation?: true,
|
140
|
+
selected_item: selected_item)
|
141
|
+
selected_item.stub(sub_navigation: sub_navigation)
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'calls recursively on the sub_navigation' do
|
145
|
+
expect(sub_navigation).to receive(:active_item_container_for)
|
146
|
+
.with(2)
|
147
|
+
item_container.active_item_container_for(2)
|
148
|
+
end
|
218
149
|
end
|
219
150
|
end
|
220
|
-
|
221
151
|
end
|
222
152
|
|
223
|
-
|
224
|
-
context '
|
225
|
-
|
226
|
-
|
227
|
-
|
153
|
+
describe '#active_leaf_container' do
|
154
|
+
context 'when the current container has a selected subnavigation' do
|
155
|
+
let(:sub_navigation) { double(:sub_navigation) }
|
156
|
+
let(:selected_item) { double(:selected_item) }
|
157
|
+
|
158
|
+
before do
|
159
|
+
item_container.stub(selected_sub_navigation?: true,
|
160
|
+
selected_item: selected_item)
|
161
|
+
selected_item.stub(sub_navigation: sub_navigation)
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'calls recursively on the sub_navigation' do
|
165
|
+
expect(sub_navigation).to receive(:active_leaf_container)
|
166
|
+
item_container.active_leaf_container
|
228
167
|
end
|
229
168
|
end
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
169
|
+
|
170
|
+
context 'when the current container is the leaf already' do
|
171
|
+
before { item_container.stub(selected_sub_navigation?: false) }
|
172
|
+
|
173
|
+
it 'returns itsself' do
|
174
|
+
expect(item_container.active_leaf_container).to be item_container
|
234
175
|
end
|
235
176
|
end
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
177
|
+
end
|
178
|
+
|
179
|
+
describe '#item' do
|
180
|
+
context 'when the item has no :if or :unless option' do
|
181
|
+
let(:options) { Hash.new }
|
182
|
+
|
183
|
+
before { item_container.stub(:should_add_item?).and_return(true) }
|
184
|
+
|
185
|
+
context 'when a block is given' do
|
186
|
+
let(:sub_container) { double(:sub_container) }
|
187
|
+
let(:block) { proc{} }
|
188
|
+
|
189
|
+
before { ItemContainer.stub(:new).with(2).and_return(sub_container) }
|
190
|
+
|
191
|
+
it 'yields a new ItemContainer' do
|
192
|
+
expect{ |blk|
|
193
|
+
item_container.item('key', 'name', 'url', options, &blk)
|
194
|
+
}.to yield_with_args(sub_container)
|
241
195
|
end
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
196
|
+
|
197
|
+
it "creates a new Navigation-Item with the given params and block" do
|
198
|
+
expect(Item).to receive(:new)
|
199
|
+
.with(item_container, 'key', 'name', 'url',
|
200
|
+
options, nil, &block)
|
201
|
+
item_container.item('key', 'name', 'url', options, &block)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'adds the created item to the list of items' do
|
205
|
+
expect(item_container.items).to receive(:<<)
|
206
|
+
item_container.item('key', 'name', 'url', options) {}
|
247
207
|
end
|
248
208
|
end
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
209
|
+
|
210
|
+
context 'when no block is given' do
|
211
|
+
it "creates a new Navigation_item with the given params and nil as sub_navigation" do
|
212
|
+
expect(Item).to receive(:new)
|
213
|
+
.with(item_container, 'key', 'name', 'url', options, nil)
|
214
|
+
item_container.item('key', 'name', 'url', options)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'adds the created item to the list of items' do
|
218
|
+
expect(item_container.items).to receive(:<<)
|
219
|
+
item_container.item('key', 'name', 'url', options)
|
253
220
|
end
|
254
221
|
end
|
255
222
|
end
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
223
|
+
|
224
|
+
describe 'Optional url and optional options' do
|
225
|
+
shared_examples 'adding the item to the list' do
|
226
|
+
it 'adds the item to the list' do
|
227
|
+
expect(item_container.items).to receive(:<<)
|
228
|
+
item_container.item(*args)
|
261
229
|
end
|
262
230
|
end
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
231
|
+
|
232
|
+
shared_examples 'not adding the item to the list' do
|
233
|
+
it "doesn't add the item to the list" do
|
234
|
+
expect(item_container.items).not_to receive(:<<)
|
235
|
+
item_container.item(*args)
|
267
236
|
end
|
268
237
|
end
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
238
|
+
|
239
|
+
context 'when item specifed without url or options' do
|
240
|
+
it_behaves_like 'adding the item to the list' do
|
241
|
+
let(:args) { ['key', 'name'] }
|
273
242
|
end
|
274
243
|
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
context 'conditions given for item' do
|
279
244
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
245
|
+
context 'when item is specified with only a url' do
|
246
|
+
it_behaves_like 'adding the item to the list' do
|
247
|
+
let(:args) { ['key', 'name', 'url'] }
|
248
|
+
end
|
284
249
|
end
|
285
250
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
251
|
+
context 'when item is specified with only options' do
|
252
|
+
context 'and options do not contain any condition' do
|
253
|
+
it_behaves_like 'adding the item to the list' do
|
254
|
+
let(:args) { ['key', 'name', { option: true }] }
|
255
|
+
end
|
256
|
+
end
|
290
257
|
|
291
|
-
|
292
|
-
|
293
|
-
|
258
|
+
context 'and options contains a negative condition' do
|
259
|
+
it_behaves_like 'not adding the item to the list' do
|
260
|
+
let(:args) { ['key', 'name', { if: ->{ false }, option: true }] }
|
261
|
+
end
|
294
262
|
end
|
295
|
-
|
296
|
-
|
297
|
-
|
263
|
+
|
264
|
+
context 'and options contains a positive condition' do
|
265
|
+
it_behaves_like 'adding the item to the list' do
|
266
|
+
let(:args) { ['key', 'name', { if: ->{ true }, option: true }] }
|
267
|
+
end
|
298
268
|
end
|
299
269
|
end
|
300
270
|
|
301
|
-
context '
|
302
|
-
|
303
|
-
|
271
|
+
context 'when item is specified with a url and options' do
|
272
|
+
context 'and options do not contain any condition' do
|
273
|
+
it_behaves_like 'adding the item to the list' do
|
274
|
+
let(:args) { ['key', 'name', 'url', { option: true }] }
|
275
|
+
end
|
304
276
|
end
|
305
|
-
|
306
|
-
|
307
|
-
|
277
|
+
|
278
|
+
context 'and options contains a negative condition' do
|
279
|
+
it_behaves_like 'not adding the item to the list' do
|
280
|
+
let(:args) { ['key', 'name', 'url', { if: ->{ false }, option: true }] }
|
281
|
+
end
|
308
282
|
end
|
309
|
-
end
|
310
283
|
|
311
|
-
|
312
|
-
|
313
|
-
|
284
|
+
context 'and options contains a positive condition' do
|
285
|
+
it_behaves_like 'adding the item to the list' do
|
286
|
+
let(:args) { ['key', 'name', 'url', { if: ->{ true }, option: true }] }
|
287
|
+
end
|
314
288
|
end
|
315
289
|
end
|
290
|
+
end
|
316
291
|
|
317
|
-
|
292
|
+
describe 'Conditions' do
|
293
|
+
context 'when an :if option is given' do
|
294
|
+
let(:options) {{ if: proc{condition} }}
|
295
|
+
let(:condition) { nil }
|
318
296
|
|
319
|
-
|
320
|
-
|
297
|
+
it 'removes :if from the options' do
|
298
|
+
item_container.item('key', 'name', 'url', options)
|
299
|
+
expect(options).not_to have_key(:if)
|
321
300
|
end
|
322
301
|
|
302
|
+
context 'and it evals to true' do
|
303
|
+
let(:condition) { true }
|
323
304
|
|
324
|
-
|
325
|
-
|
326
|
-
|
305
|
+
it 'creates a new Navigation-Item' do
|
306
|
+
expect(Item).to receive(:new)
|
307
|
+
item_container.item('key', 'name', 'url', options)
|
308
|
+
end
|
327
309
|
end
|
328
310
|
|
329
|
-
context '
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
@item_container.item('key', 'name', 'url', @options)
|
311
|
+
context 'and it evals to false' do
|
312
|
+
let(:condition) { false }
|
313
|
+
|
314
|
+
it "doesn't create a new Navigation-Item" do
|
315
|
+
expect(Item).not_to receive(:new)
|
316
|
+
item_container.item('key', 'name', 'url', options)
|
336
317
|
end
|
337
318
|
end
|
338
319
|
|
339
|
-
context '
|
340
|
-
|
341
|
-
|
320
|
+
context 'and it is not a proc or a method' do
|
321
|
+
it 'raises an error' do
|
322
|
+
expect{
|
323
|
+
item_container.item('key', 'name', 'url', { if: 'text' })
|
324
|
+
}.to raise_error
|
342
325
|
end
|
343
|
-
|
344
|
-
|
345
|
-
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
context 'when an :unless option is given' do
|
330
|
+
let(:options) {{ unless: proc{condition} }}
|
331
|
+
let(:condition) { nil }
|
332
|
+
|
333
|
+
it "removes :unless from the options" do
|
334
|
+
item_container.item('key', 'name', 'url', options)
|
335
|
+
expect(options).not_to have_key(:unless)
|
336
|
+
end
|
337
|
+
|
338
|
+
context 'and it evals to false' do
|
339
|
+
let(:condition) { false }
|
340
|
+
|
341
|
+
it 'creates a new Navigation-Item' do
|
342
|
+
expect(Item).to receive(:new)
|
343
|
+
item_container.item('key', 'name', 'url', options)
|
346
344
|
end
|
347
345
|
end
|
348
346
|
|
347
|
+
context 'and it evals to true' do
|
348
|
+
let(:condition) { true }
|
349
|
+
|
350
|
+
it "doesn't create a new Navigation-Item" do
|
351
|
+
expect(Item).not_to receive(:new)
|
352
|
+
item_container.item('key', 'name', 'url', options)
|
353
|
+
end
|
354
|
+
end
|
349
355
|
end
|
350
356
|
end
|
351
357
|
end
|
352
|
-
end
|
353
358
|
|
354
|
-
|
359
|
+
describe '#[]' do
|
360
|
+
before do
|
361
|
+
item_container.item(:first, 'first', 'bla')
|
362
|
+
item_container.item(:second, 'second', 'bla')
|
363
|
+
item_container.item(:third, 'third', 'bla')
|
364
|
+
end
|
355
365
|
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
@item_container.item(:third, 'third', 'bla')
|
360
|
-
end
|
366
|
+
it 'returns the item with the specified navi_key' do
|
367
|
+
expect(item_container[:second].name).to eq 'second'
|
368
|
+
end
|
361
369
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
370
|
+
context 'when no item exists for the specified navi_key' do
|
371
|
+
it 'returns nil' do
|
372
|
+
expect(item_container[:invalid]).to be_nil
|
373
|
+
end
|
374
|
+
end
|
367
375
|
end
|
368
|
-
end
|
369
376
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
377
|
+
describe '#render' do
|
378
|
+
# TODO
|
379
|
+
let(:renderer_instance) { double(:renderer).as_null_object }
|
380
|
+
let(:renderer_class) { double(:renderer_class, new: renderer_instance) }
|
381
|
+
|
382
|
+
context 'when renderer is specified as an option' do
|
383
|
+
context 'and is specified as a class' do
|
384
|
+
it 'instantiates the passed renderer_class with the options' do
|
385
|
+
expect(renderer_class).to receive(:new)
|
386
|
+
.with(renderer: renderer_class)
|
387
|
+
item_container.render(renderer: renderer_class)
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'calls render on the renderer and passes self' do
|
391
|
+
expect(renderer_instance).to receive(:render).with(item_container)
|
392
|
+
item_container.render(renderer: renderer_class)
|
393
|
+
end
|
382
394
|
end
|
383
|
-
|
384
|
-
|
395
|
+
|
396
|
+
context 'and is specified as a symbol' do
|
397
|
+
before do
|
398
|
+
SimpleNavigation.registered_renderers = {
|
399
|
+
my_renderer: renderer_class
|
400
|
+
}
|
401
|
+
end
|
402
|
+
|
403
|
+
it "instantiates the passed renderer_class with the options" do
|
404
|
+
expect(renderer_class).to receive(:new).with(renderer: :my_renderer)
|
405
|
+
item_container.render(renderer: :my_renderer)
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'calls render on the renderer and passes self' do
|
409
|
+
expect(renderer_instance).to receive(:render).with(item_container)
|
410
|
+
item_container.render(renderer: :my_renderer)
|
411
|
+
end
|
385
412
|
end
|
386
413
|
end
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
414
|
+
|
415
|
+
context 'when no renderer is specified' do
|
416
|
+
let(:options) { Hash.new }
|
417
|
+
|
418
|
+
before { item_container.stub(renderer: renderer_class) }
|
419
|
+
|
420
|
+
it "instantiates the container's renderer with the options" do
|
421
|
+
expect(renderer_class).to receive(:new).with(options)
|
422
|
+
item_container.render(options)
|
396
423
|
end
|
397
|
-
|
398
|
-
|
424
|
+
|
425
|
+
it 'calls render on the renderer and passes self' do
|
426
|
+
expect(renderer_instance).to receive(:render).with(item_container)
|
427
|
+
item_container.render(options)
|
399
428
|
end
|
400
429
|
end
|
401
430
|
end
|
402
|
-
|
431
|
+
|
432
|
+
describe '#level_for_item' do
|
403
433
|
before(:each) do
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
434
|
+
item_container.item(:p1, 'p1', 'p1')
|
435
|
+
item_container.item(:p2, 'p2', 'p2') do |p2|
|
436
|
+
p2.item(:s1, 's1', 's1')
|
437
|
+
p2.item(:s2, 's2', 's2') do |s2|
|
438
|
+
s2.item(:ss1, 'ss1', 'ss1')
|
439
|
+
s2.item(:ss2, 'ss2', 'ss2')
|
440
|
+
end
|
441
|
+
p2.item(:s3, 's3', 's3')
|
442
|
+
end
|
443
|
+
item_container.item(:p3, 'p3', 'p3')
|
412
444
|
end
|
413
|
-
|
414
|
-
|
445
|
+
|
446
|
+
shared_examples 'returning the level of an item' do |item, level|
|
447
|
+
specify{ expect(item_container.level_for_item(item)).to eq level }
|
415
448
|
end
|
449
|
+
|
450
|
+
it_behaves_like 'returning the level of an item', :p1, 1
|
451
|
+
it_behaves_like 'returning the level of an item', :p3, 1
|
452
|
+
it_behaves_like 'returning the level of an item', :s1, 2
|
453
|
+
it_behaves_like 'returning the level of an item', :ss1, 3
|
454
|
+
it_behaves_like 'returning the level of an item', :x, nil
|
416
455
|
end
|
417
|
-
end
|
418
456
|
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
p2.item(:s2, 's2', 's2') do |s2|
|
425
|
-
s2.item(:ss1, 'ss1', 'ss1')
|
426
|
-
s2.item(:ss2, 'ss2', 'ss2')
|
457
|
+
describe '#empty?' do
|
458
|
+
context 'when there are no items' do
|
459
|
+
it 'returns true' do
|
460
|
+
item_container.instance_variable_set(:@items, [])
|
461
|
+
expect(item_container).to be_empty
|
427
462
|
end
|
428
|
-
p2.item(:s3, 's3', 's3')
|
429
463
|
end
|
430
|
-
@item_container.item(:p3, 'p3', 'p3')
|
431
|
-
end
|
432
|
-
it {@item_container.level_for_item(:p1).should == 1}
|
433
|
-
it {@item_container.level_for_item(:p3).should == 1}
|
434
|
-
it {@item_container.level_for_item(:s1).should == 2}
|
435
|
-
it {@item_container.level_for_item(:ss1).should == 3}
|
436
|
-
it {@item_container.level_for_item(:x).should be_nil}
|
437
|
-
|
438
|
-
end
|
439
464
|
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
@item_container.instance_variable_set(:@items, [stub(:item)])
|
447
|
-
@item_container.should_not be_empty
|
465
|
+
context 'when there are some items' do
|
466
|
+
it 'returns false' do
|
467
|
+
item_container.instance_variable_set(:@items, [double(:item)])
|
468
|
+
expect(item_container).not_to be_empty
|
469
|
+
end
|
470
|
+
end
|
448
471
|
end
|
449
472
|
end
|
450
|
-
|
451
473
|
end
|