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,566 +1,703 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
module SimpleNavigation
|
4
|
+
describe Item do
|
5
|
+
let!(:item_container) { ItemContainer.new }
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
60
|
-
|
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 '
|
65
|
-
it
|
66
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
90
|
-
|
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
|
-
|
93
|
-
|
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 '
|
98
|
-
|
99
|
-
|
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
118
|
-
|
119
|
-
|
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
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
-
|
140
|
-
|
141
|
-
|
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
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
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
|
-
|
154
|
-
|
155
|
-
|
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
|
-
|
164
|
-
|
165
|
-
|
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
|
-
|
176
|
-
|
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
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
202
|
-
|
203
|
-
|
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
|
-
|
208
|
-
|
209
|
-
|
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
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
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
|
-
|
231
|
-
|
295
|
+
|
296
|
+
context 'when the item is not selected' do
|
297
|
+
before { item.stub(selected?: false) }
|
232
298
|
|
233
|
-
|
234
|
-
|
235
|
-
|
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
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
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
|
256
|
-
before(
|
257
|
-
|
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
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
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
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
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
|
-
|
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
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
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
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
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 '
|
299
|
-
|
300
|
-
|
301
|
-
|
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
|
307
|
-
before
|
308
|
-
|
309
|
-
|
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
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
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 '
|
319
|
-
|
320
|
-
|
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
|
-
|
401
|
+
describe '#selected_by_subnav?' do
|
402
|
+
before { item.stub(sub_navigation: sub_navigation) }
|
330
403
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
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
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
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
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
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
|
-
|
369
|
-
|
370
|
-
|
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
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
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
|
-
|
383
|
-
|
384
|
-
|
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
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
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
|
-
|
401
|
-
|
402
|
-
|
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
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
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
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
it
|
418
|
-
|
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
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
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
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
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
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
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
|
-
|
466
|
-
|
467
|
-
|
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
|
-
|
482
|
-
|
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
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
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
|
-
|
525
|
-
|
526
|
-
|
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
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
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
|
-
|
542
|
-
|
543
|
-
|
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
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
SimpleNavigation.config.stub
|
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
|
-
|
557
|
-
|
558
|
-
|
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
|