simple-navigation 4.4.1 → 4.5.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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +84 -0
- data/.rspec +1 -2
- data/.rubocop.yml +49 -0
- data/.rubocop_todo.yml +38 -0
- data/Appraisals +55 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +21 -0
- data/Guardfile +4 -2
- data/README.md +11 -23
- data/Rakefile +2 -27
- data/bin/_guard-core +16 -0
- data/bin/appraisal +16 -0
- data/bin/guard +16 -0
- data/bin/rake +16 -0
- data/bin/rspec +16 -0
- data/bin/rubocop +16 -0
- data/gemfiles/rails_6.1.gemfile +35 -0
- data/gemfiles/rails_7.0.gemfile +23 -0
- data/gemfiles/rails_7.1.gemfile +23 -0
- data/gemfiles/rails_7.2.gemfile +23 -0
- data/gemfiles/rails_8.0.gemfile +23 -0
- data/gemfiles/rails_8.1.gemfile +23 -0
- data/generators/navigation_config/navigation_config_generator.rb +2 -0
- data/generators/navigation_config/templates/config/navigation.rb +30 -26
- data/lib/generators/navigation_config/navigation_config_generator.rb +2 -0
- data/lib/simple-navigation.rb +3 -1
- data/lib/simple_navigation/adapters/base.rb +2 -0
- data/lib/simple_navigation/adapters/nanoc.rb +8 -3
- data/lib/simple_navigation/adapters/padrino.rb +3 -1
- data/lib/simple_navigation/adapters/rails.rb +12 -14
- data/lib/simple_navigation/adapters/sinatra.rb +4 -6
- data/lib/simple_navigation/config_file.rb +1 -1
- data/lib/simple_navigation/config_file_finder.rb +3 -3
- data/lib/simple_navigation/configuration.rb +5 -5
- data/lib/simple_navigation/helpers.rb +9 -11
- data/lib/simple_navigation/item.rb +26 -20
- data/lib/simple_navigation/item_adapter.rb +16 -5
- data/lib/simple_navigation/item_container.rb +13 -7
- data/lib/simple_navigation/items_provider.rb +6 -4
- data/lib/simple_navigation/railtie.rb +3 -1
- data/lib/simple_navigation/renderer/base.rb +5 -5
- data/lib/simple_navigation/renderer/breadcrumbs.rb +4 -3
- data/lib/simple_navigation/renderer/json.rb +1 -1
- data/lib/simple_navigation/renderer/links.rb +2 -0
- data/lib/simple_navigation/renderer/list.rb +5 -5
- data/lib/simple_navigation/renderer/text.rb +3 -1
- data/lib/simple_navigation/version.rb +3 -1
- data/lib/simple_navigation.rb +32 -24
- data/simple-navigation.gemspec +16 -27
- data/spec/fake_app/config/navigation.rb +4 -2
- data/spec/fake_app/rails_app.rb +5 -3
- data/spec/integration/rendering_navigation_spec.rb +7 -5
- data/spec/simple_navigation/adapters/nanoc_spec.rb +97 -0
- data/spec/simple_navigation/adapters/padrino_spec.rb +41 -22
- data/spec/simple_navigation/adapters/rails_spec.rb +199 -206
- data/spec/simple_navigation/adapters/sinatra_spec.rb +21 -5
- data/spec/simple_navigation/config_file_finder_spec.rb +32 -28
- data/spec/simple_navigation/config_file_spec.rb +14 -14
- data/spec/simple_navigation/configuration_spec.rb +128 -121
- data/spec/simple_navigation/helpers_spec.rb +282 -284
- data/spec/simple_navigation/item_adapter_spec.rb +109 -122
- data/spec/simple_navigation/item_container_spec.rb +407 -408
- data/spec/simple_navigation/item_spec.rb +333 -301
- data/spec/simple_navigation/items_provider_spec.rb +30 -27
- data/spec/simple_navigation/renderer/base_spec.rb +166 -168
- data/spec/simple_navigation/renderer/breadcrumbs_spec.rb +81 -83
- data/spec/simple_navigation/renderer/json_spec.rb +49 -56
- data/spec/simple_navigation/renderer/links_spec.rb +81 -83
- data/spec/simple_navigation/renderer/list_spec.rb +111 -91
- data/spec/simple_navigation/renderer/text_spec.rb +37 -39
- data/spec/simple_navigation_spec.rb +54 -47
- data/spec/spec_helper.rb +146 -53
- metadata +25 -164
- data/.travis.yml +0 -23
- data/gemfiles/rails-3-2-stable.gemfile +0 -11
- data/gemfiles/rails-4-1-stable.gemfile +0 -7
- data/gemfiles/rails-4-2-stable.gemfile +0 -7
- data/gemfiles/rails-5-2-stable.gemfile +0 -7
- data/gemfiles/rails-6-0-stable.gemfile +0 -9
- data/gemfiles/rails-6-1-stable.gemfile +0 -9
- data/init.rb +0 -1
- data/install.rb +0 -5
- data/lib/simple_navigation/adapters.rb +0 -10
- data/lib/simple_navigation/renderer.rb +0 -12
- data/spec/initializers/coveralls.rb +0 -3
- data/spec/initializers/have_css_matcher.rb +0 -19
- data/spec/initializers/memfs.rb +0 -7
- data/spec/initializers/rails.rb +0 -4
- data/spec/initializers/rspec.rb +0 -7
- data/uninstall.rb +0 -1
|
@@ -1,473 +1,505 @@
|
|
|
1
|
-
|
|
2
|
-
describe Item do
|
|
3
|
-
let!(:item_container) { ItemContainer.new }
|
|
1
|
+
# frozen_string_literal: true
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let(:item) { Item.new(*item_args) }
|
|
8
|
-
let(:options) { Hash.new }
|
|
9
|
-
let(:url) { 'url' }
|
|
3
|
+
RSpec.describe SimpleNavigation::Item do
|
|
4
|
+
let!(:item_container) { SimpleNavigation::ItemContainer.new }
|
|
10
5
|
|
|
11
|
-
|
|
6
|
+
let(:adapter) { double(:adapter) }
|
|
7
|
+
let(:item_args) { [item_container, :my_key, 'name', url, options] }
|
|
8
|
+
let(:item) { described_class.new(*item_args) }
|
|
9
|
+
let(:options) { {} }
|
|
10
|
+
let(:url) { 'url' }
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
let(:options) {{ highlights_on: :test }}
|
|
12
|
+
before { allow(SimpleNavigation).to receive_messages(adapter: adapter) }
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
describe '#highlights_on' do
|
|
15
|
+
let(:options) { { highlights_on: :test } }
|
|
16
|
+
|
|
17
|
+
it "returns the item's highlights_on option" do
|
|
18
|
+
expect(item.highlights_on).to eq :test
|
|
19
19
|
end
|
|
20
|
+
end
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
describe '#initialize' do
|
|
23
|
+
context 'when there is a sub_navigation' do
|
|
24
|
+
let(:subnav_container) { double(:subnav_container).as_null_object }
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end
|
|
26
|
+
shared_examples 'creating sub navigation container' do
|
|
27
|
+
it 'creates a sub navigation container with a level+1' do
|
|
28
|
+
expect(item.sub_navigation.level).to eq 2
|
|
29
29
|
end
|
|
30
|
+
end
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
context 'when a block is given' do
|
|
33
|
+
it_behaves_like 'creating sub navigation container' do
|
|
34
|
+
let(:item) { described_class.new(*item_args) {} } # rubocop:disable Lint/EmptyBlock
|
|
35
|
+
end
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
it 'calls the block' do
|
|
38
|
+
allow(SimpleNavigation::ItemContainer).to receive_messages(new: subnav_container)
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
end
|
|
40
|
+
expect do |blk|
|
|
41
|
+
described_class.new(*item_args, &blk)
|
|
42
|
+
end.to yield_with_args(subnav_container)
|
|
43
43
|
end
|
|
44
|
+
end
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
context 'when no block is given' do
|
|
47
|
+
context 'when items are given' do
|
|
48
|
+
let(:items) { [] }
|
|
49
|
+
let(:options) { { items: items } }
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
it_behaves_like 'creating sub navigation container'
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
end
|
|
53
|
+
it 'sets the items on the subnav_container' do
|
|
54
|
+
expect(item.sub_navigation.items).to eq items
|
|
55
55
|
end
|
|
56
|
+
end
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
end
|
|
58
|
+
context 'when no items are given' do
|
|
59
|
+
it "doesn't create a new ItemContainer" do
|
|
60
|
+
item = described_class.new(*item_args)
|
|
61
|
+
expect(item.sub_navigation).to be_nil
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
|
+
end
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
context 'when a :method option is given' do
|
|
68
|
+
let(:options) { { method: :delete } }
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
end
|
|
70
|
+
it "sets the item's method" do
|
|
71
|
+
expect(item.method).to eq :delete
|
|
72
72
|
end
|
|
73
|
+
end
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
end
|
|
75
|
+
context 'when no :method option is given' do
|
|
76
|
+
it "sets the item's method to nil" do
|
|
77
|
+
expect(item.method).to be_nil
|
|
78
78
|
end
|
|
79
|
+
end
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
context 'when an :highlights_on option is given' do
|
|
82
|
+
let(:highlights_on) { double(:highlights_on) }
|
|
83
|
+
let(:options) { { highlights_on: highlights_on } }
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
end
|
|
85
|
+
it "sets the item's highlights_on" do
|
|
86
|
+
expect(item.highlights_on).to eq highlights_on
|
|
87
87
|
end
|
|
88
|
+
end
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
end
|
|
90
|
+
context 'when no :highlights_on option is given' do
|
|
91
|
+
it "sets the item's highlights_on to nil" do
|
|
92
|
+
expect(item.highlights_on).to be_nil
|
|
93
93
|
end
|
|
94
|
+
end
|
|
94
95
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
end
|
|
96
|
+
context 'when a url is given' do
|
|
97
|
+
context 'when it is a string' do
|
|
98
|
+
it "sets the item's url accordingly" do
|
|
99
|
+
expect(item.url).to eq 'url'
|
|
100
100
|
end
|
|
101
|
+
end
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
context 'when it is a proc' do
|
|
104
|
+
let(:url) { proc { 'my_url' } }
|
|
104
105
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
end
|
|
106
|
+
it "sets the item's url accordingly" do
|
|
107
|
+
expect(item.url).to eq 'my_url'
|
|
108
108
|
end
|
|
109
|
+
end
|
|
109
110
|
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
context 'when it is nil' do
|
|
112
|
+
let(:url) { nil }
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
end
|
|
114
|
+
it "sets the item's url accordingly" do
|
|
115
|
+
expect(item.url).to be_nil
|
|
116
116
|
end
|
|
117
117
|
end
|
|
118
|
+
end
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
context 'when no url nor options is specified' do
|
|
121
|
+
let(:item_args) { [item_container, :my_key, 'name'] }
|
|
121
122
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
end
|
|
123
|
+
it "sets the item's url to nil" do
|
|
124
|
+
expect(item.url).to be_nil
|
|
125
125
|
end
|
|
126
|
+
end
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
context 'when only a url is given' do
|
|
129
|
+
let(:item_args) { [item_container, :my_key, 'name', 'url'] }
|
|
129
130
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
end
|
|
131
|
+
it "set the item's url accordingly" do
|
|
132
|
+
expect(item.url).to eq 'url'
|
|
133
133
|
end
|
|
134
|
+
end
|
|
134
135
|
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
context 'when url and options are given' do
|
|
137
|
+
let(:options) { { html: { option: true } } }
|
|
137
138
|
|
|
138
|
-
|
|
139
|
+
before { allow(adapter).to receive_messages(current_page?: false) }
|
|
139
140
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
it "set the item's url accordingly" do
|
|
142
|
+
expect(item.url).to eq 'url'
|
|
143
|
+
end
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
end
|
|
145
|
+
it "sets the item's html_options accordingly" do
|
|
146
|
+
allow(item).to \
|
|
147
|
+
receive_messages(selected_by_subnav?: false,
|
|
148
|
+
selected_by_condition?: false)
|
|
149
|
+
expect(item.html_options).to include(option: true)
|
|
150
150
|
end
|
|
151
151
|
end
|
|
152
|
+
end
|
|
152
153
|
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
describe '#link_html_options' do
|
|
155
|
+
let(:options) { { link_html: { class: 'test' } } }
|
|
155
156
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
end
|
|
157
|
+
before do
|
|
158
|
+
allow(item).to receive_messages(selected?: false, selected_by_condition?: false, selected_by_subnav?: false)
|
|
159
159
|
end
|
|
160
160
|
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
it "returns the item's link_html option" do
|
|
162
|
+
expect(item.link_html_options).to eq({ class: 'test' })
|
|
163
|
+
end
|
|
163
164
|
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
it "doesn't add an `aria-current` attribute" do
|
|
166
|
+
expect(item.link_html_options).not_to have_key(:'aria-current')
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
context 'when the item is selected by condition but not by subnav (i.e. a selected leaf)' do
|
|
170
|
+
before do
|
|
171
|
+
allow(item).to receive_messages(selected?: true, selected_by_condition?: true, selected_by_subnav?: false)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it 'adds an `aria-current` attribute' do
|
|
175
|
+
expect(item.link_html_options[:'aria-current']).to eq 'page'
|
|
166
176
|
end
|
|
167
177
|
end
|
|
168
178
|
|
|
169
|
-
|
|
179
|
+
context 'when the item is selected by subnav and not by condition' do
|
|
170
180
|
before do
|
|
171
|
-
allow(
|
|
172
|
-
receive_messages(name_generator: proc{ |name| "<span>#{name}</span>" })
|
|
181
|
+
allow(item).to receive_messages(selected?: true, selected_by_condition?: false, selected_by_subnav?: true)
|
|
173
182
|
end
|
|
174
183
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
end
|
|
184
|
+
it "doesn't add an `aria-current` attribute" do
|
|
185
|
+
expect(item.link_html_options).not_to have_key(:'aria-current')
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
181
189
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
allow(SimpleNavigation.config).to \
|
|
185
|
-
receive_messages(name_generator: proc{ |name, item| "<span>#{item.key}</span>" })
|
|
186
|
-
end
|
|
190
|
+
describe '#method' do
|
|
191
|
+
let(:options) { { method: :test } }
|
|
187
192
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
193
|
+
it "returns the item's method option" do
|
|
194
|
+
expect(item.method).to eq :test
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
describe '#name' do
|
|
199
|
+
before do
|
|
200
|
+
allow(SimpleNavigation.config).to \
|
|
201
|
+
receive_messages(name_generator: proc { |name| "<span>#{name}</span>" })
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
context 'when no option is given' do
|
|
205
|
+
context 'when the name_generator uses only the name' do
|
|
206
|
+
it 'uses the default name_generator' do
|
|
207
|
+
expect(item.name).to eq '<span>name</span>'
|
|
191
208
|
end
|
|
192
209
|
end
|
|
193
210
|
|
|
194
|
-
context 'when the
|
|
195
|
-
|
|
196
|
-
|
|
211
|
+
context 'when the name_generator uses only the item itself' do
|
|
212
|
+
before do
|
|
213
|
+
allow(SimpleNavigation.config).to \
|
|
214
|
+
receive_messages(name_generator: proc { |_name, item| "<span>#{item.key}</span>" })
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it 'uses the default name_generator' do
|
|
218
|
+
expect(item.name).to eq '<span>my_key</span>'
|
|
197
219
|
end
|
|
198
220
|
end
|
|
221
|
+
end
|
|
199
222
|
|
|
200
|
-
|
|
201
|
-
|
|
223
|
+
context 'when the :apply_generator is false' do
|
|
224
|
+
it "returns the item's name" do
|
|
225
|
+
expect(item.name(apply_generator: false)).to eq 'name'
|
|
226
|
+
end
|
|
227
|
+
end
|
|
202
228
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
229
|
+
context 'when a block is given' do
|
|
230
|
+
let(:item_args) { [item_container, :my_key, -> { 'Name in block' }, url, options] }
|
|
231
|
+
|
|
232
|
+
it "returns the item's name that is defined in the block" do
|
|
233
|
+
expect(item.name).to include 'Name in block'
|
|
206
234
|
end
|
|
207
235
|
end
|
|
236
|
+
end
|
|
208
237
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
238
|
+
describe '#selected?' do
|
|
239
|
+
context 'when the item has no :highlights_on option' do
|
|
240
|
+
before { allow(SimpleNavigation).to receive_messages(config: config) }
|
|
212
241
|
|
|
213
|
-
|
|
214
|
-
|
|
242
|
+
context 'when auto highlighting is off' do
|
|
243
|
+
let(:config) { double(:config, auto_highlight: false) }
|
|
215
244
|
|
|
216
|
-
|
|
217
|
-
|
|
245
|
+
it 'returns false' do
|
|
246
|
+
expect(item.selected?).to be false
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
context 'when auto highlighting is on' do
|
|
251
|
+
let(:config) do
|
|
252
|
+
double(:config, ignore_query_params_on_auto_highlight: true, ignore_anchors_on_auto_highlight: true,
|
|
253
|
+
auto_highlight: true)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
context "when the current url matches the item's url" do
|
|
257
|
+
before { allow(adapter).to receive_messages(current_page?: true) }
|
|
258
|
+
|
|
259
|
+
it 'returns true' do
|
|
260
|
+
expect(item.selected?).to be true
|
|
218
261
|
end
|
|
219
262
|
end
|
|
220
263
|
|
|
221
|
-
context
|
|
222
|
-
let(:config)
|
|
264
|
+
context "when the current url does not match the item's url" do
|
|
265
|
+
let(:config) do
|
|
266
|
+
double(:config, auto_highlight: false, highlight_on_subpath: false)
|
|
267
|
+
end
|
|
223
268
|
|
|
224
|
-
|
|
225
|
-
before { allow(adapter).to receive_messages(current_page?: true) }
|
|
269
|
+
before { allow(adapter).to receive_messages(current_page?: false) }
|
|
226
270
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
end
|
|
271
|
+
it 'returns false' do
|
|
272
|
+
expect(item.selected?).to be false
|
|
230
273
|
end
|
|
274
|
+
end
|
|
231
275
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
276
|
+
context 'when highlights_on_subpath is on' do
|
|
277
|
+
let(:config) do
|
|
278
|
+
double(:config, auto_highlight: true, highlight_on_subpath: true,
|
|
279
|
+
ignore_query_params_on_auto_highlight: true, ignore_anchors_on_auto_highlight: true)
|
|
280
|
+
end
|
|
236
281
|
|
|
237
|
-
|
|
282
|
+
context 'when item has no url' do
|
|
283
|
+
let(:url) { nil }
|
|
238
284
|
|
|
239
285
|
it 'returns false' do
|
|
240
286
|
expect(item.selected?).to be false
|
|
241
287
|
end
|
|
242
288
|
end
|
|
243
289
|
|
|
244
|
-
context
|
|
245
|
-
|
|
246
|
-
|
|
290
|
+
context "when the current url is a sub path of the item's url" do
|
|
291
|
+
before do
|
|
292
|
+
allow(adapter).to \
|
|
293
|
+
receive_messages(current_page?: false, request_uri: 'url/test')
|
|
247
294
|
end
|
|
248
295
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
it 'returns false' do
|
|
253
|
-
expect(item.selected?).to be false
|
|
254
|
-
end
|
|
296
|
+
it 'returns true' do
|
|
297
|
+
expect(item.selected?).to be true
|
|
255
298
|
end
|
|
299
|
+
end
|
|
256
300
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
it 'returns true' do
|
|
264
|
-
expect(item.selected?).to be true
|
|
265
|
-
end
|
|
301
|
+
context "when the current url is not a sub path of the item's url" do
|
|
302
|
+
before do
|
|
303
|
+
allow(adapter).to \
|
|
304
|
+
receive_messages(current_page?: false, request_uri: 'other/test')
|
|
266
305
|
end
|
|
267
306
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
allow(adapter).to \
|
|
271
|
-
receive_messages(current_page?: false, request_uri: 'other/test')
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
it 'returns false' do
|
|
275
|
-
expect(item.selected?).to be false
|
|
276
|
-
end
|
|
307
|
+
it 'returns false' do
|
|
308
|
+
expect(item.selected?).to be false
|
|
277
309
|
end
|
|
278
310
|
end
|
|
279
311
|
end
|
|
280
312
|
end
|
|
313
|
+
end
|
|
281
314
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
315
|
+
context 'when the item has a :highlights_on option' do
|
|
316
|
+
context 'when it is a regular expression' do
|
|
317
|
+
before { allow(adapter).to receive_messages(request_uri: '/test') }
|
|
285
318
|
|
|
286
|
-
|
|
287
|
-
|
|
319
|
+
context 'when the current url matches the expression' do
|
|
320
|
+
let(:options) { { highlights_on: /test/ } }
|
|
288
321
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
end
|
|
322
|
+
it 'returns true' do
|
|
323
|
+
expect(item.selected?).to be true
|
|
292
324
|
end
|
|
325
|
+
end
|
|
293
326
|
|
|
294
|
-
|
|
295
|
-
|
|
327
|
+
context 'when the current url does not match the expression' do
|
|
328
|
+
let(:options) { { highlights_on: /other/ } }
|
|
296
329
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
end
|
|
330
|
+
it 'returns false' do
|
|
331
|
+
expect(item.selected?).to be false
|
|
300
332
|
end
|
|
301
333
|
end
|
|
334
|
+
end
|
|
302
335
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
336
|
+
context 'when it is a callable object' do
|
|
337
|
+
context 'when the call returns true' do
|
|
338
|
+
let(:options) { { highlights_on: -> { true } } }
|
|
306
339
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
end
|
|
340
|
+
it 'returns true' do
|
|
341
|
+
expect(item.selected?).to be true
|
|
310
342
|
end
|
|
343
|
+
end
|
|
311
344
|
|
|
312
|
-
|
|
313
|
-
|
|
345
|
+
context 'when the call returns false' do
|
|
346
|
+
let(:options) { { highlights_on: -> { false } } }
|
|
314
347
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
end
|
|
348
|
+
it 'returns false' do
|
|
349
|
+
expect(item.selected?).to be false
|
|
318
350
|
end
|
|
319
351
|
end
|
|
352
|
+
end
|
|
320
353
|
|
|
321
|
-
|
|
322
|
-
|
|
354
|
+
context 'when it is the :subpath symbol' do
|
|
355
|
+
let(:options) { { highlights_on: :subpath } }
|
|
323
356
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
357
|
+
context "when the current url is a sub path of the item's url" do
|
|
358
|
+
before do
|
|
359
|
+
allow(adapter).to receive_messages(request_uri: 'url/test')
|
|
360
|
+
end
|
|
328
361
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
end
|
|
362
|
+
it 'returns true' do
|
|
363
|
+
expect(item.selected?).to be true
|
|
332
364
|
end
|
|
365
|
+
end
|
|
333
366
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
367
|
+
context "when the current url is not a sub path of the item's url" do
|
|
368
|
+
before do
|
|
369
|
+
allow(adapter).to receive_messages(request_uri: 'other/test')
|
|
370
|
+
end
|
|
338
371
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
end
|
|
372
|
+
it 'returns false' do
|
|
373
|
+
expect(item.selected?).to be false
|
|
342
374
|
end
|
|
343
375
|
end
|
|
376
|
+
end
|
|
344
377
|
|
|
345
|
-
|
|
346
|
-
|
|
378
|
+
context 'when it is non usable' do
|
|
379
|
+
let(:options) { { highlights_on: :hello } }
|
|
347
380
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
end
|
|
381
|
+
it 'raises an exception' do
|
|
382
|
+
expect { item.selected? }.to raise_error(ArgumentError, ':highlights_on must be a Regexp, Proc or :subpath')
|
|
351
383
|
end
|
|
352
384
|
end
|
|
353
385
|
end
|
|
386
|
+
end
|
|
354
387
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
388
|
+
describe '#selected_class' do
|
|
389
|
+
context 'when the item is selected' do
|
|
390
|
+
before { allow(item).to receive_messages(selected?: true) }
|
|
358
391
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
392
|
+
it 'returns the default selected_class' do
|
|
393
|
+
expect(item.selected_class).to eq 'selected'
|
|
394
|
+
end
|
|
362
395
|
|
|
363
|
-
|
|
364
|
-
|
|
396
|
+
context 'when selected_class is defined in the context' do
|
|
397
|
+
before { allow(item_container).to receive_messages(selected_class: 'defined') }
|
|
365
398
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
end
|
|
399
|
+
it "returns the context's selected_class" do
|
|
400
|
+
expect(item.selected_class).to eq 'defined'
|
|
369
401
|
end
|
|
370
402
|
end
|
|
403
|
+
end
|
|
371
404
|
|
|
372
|
-
|
|
373
|
-
|
|
405
|
+
context 'when the item is not selected' do
|
|
406
|
+
before { allow(item).to receive_messages(selected?: false) }
|
|
374
407
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
end
|
|
408
|
+
it 'returns nil' do
|
|
409
|
+
expect(item.selected_class).to be_nil
|
|
378
410
|
end
|
|
379
411
|
end
|
|
412
|
+
end
|
|
380
413
|
|
|
381
|
-
|
|
382
|
-
|
|
414
|
+
describe ':html_options argument' do
|
|
415
|
+
let(:selected_classes) { 'selected simple-navigation-active-leaf' }
|
|
383
416
|
|
|
384
|
-
|
|
385
|
-
|
|
417
|
+
context 'when the :class option is given' do
|
|
418
|
+
let(:options) { { html: { class: 'my_class' } } }
|
|
386
419
|
|
|
387
|
-
|
|
388
|
-
|
|
420
|
+
context 'when the item is selected' do
|
|
421
|
+
before { allow(item).to receive_messages(selected?: true, selected_by_condition?: true) }
|
|
389
422
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
423
|
+
it "adds the specified class to the item's html classes" do
|
|
424
|
+
expect(item.html_options[:class]).to include('my_class')
|
|
425
|
+
end
|
|
393
426
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
end
|
|
427
|
+
it "doesn't replace the default html classes of a selected item" do
|
|
428
|
+
expect(item.html_options[:class]).to include(selected_classes)
|
|
397
429
|
end
|
|
430
|
+
end
|
|
398
431
|
|
|
399
|
-
|
|
400
|
-
|
|
432
|
+
context "when the item isn't selected" do
|
|
433
|
+
before { allow(item).to receive_messages(selected?: false, selected_by_condition?: false) }
|
|
401
434
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
end
|
|
435
|
+
it "sets the specified class as the item's html classes" do
|
|
436
|
+
expect(item.html_options[:class]).to include('my_class')
|
|
405
437
|
end
|
|
406
438
|
end
|
|
439
|
+
end
|
|
407
440
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
441
|
+
context "when the :class option isn't given" do
|
|
442
|
+
context 'when the item is selected' do
|
|
443
|
+
before { allow(item).to receive_messages(selected?: true, selected_by_condition?: true) }
|
|
411
444
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
end
|
|
445
|
+
it 'sets the default html classes of a selected item' do
|
|
446
|
+
expect(item.html_options[:class]).to include(selected_classes)
|
|
415
447
|
end
|
|
448
|
+
end
|
|
416
449
|
|
|
417
|
-
|
|
418
|
-
|
|
450
|
+
context "when the item isn't selected" do
|
|
451
|
+
before { allow(item).to receive_messages(selected?: false, selected_by_condition?: false) }
|
|
419
452
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
end
|
|
453
|
+
it "doesn't set any html class on the item" do
|
|
454
|
+
expect(item.html_options[:class]).to be_blank
|
|
423
455
|
end
|
|
424
456
|
end
|
|
457
|
+
end
|
|
425
458
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
end
|
|
459
|
+
shared_examples 'generating id' do |id|
|
|
460
|
+
it "sets the item's html id to the specified id" do
|
|
461
|
+
expect(item.html_options[:id]).to eq id
|
|
430
462
|
end
|
|
463
|
+
end
|
|
431
464
|
|
|
432
|
-
|
|
433
|
-
|
|
465
|
+
describe 'when the :id option is given' do
|
|
466
|
+
let(:options) { { html: { id: 'my_id' } } }
|
|
434
467
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
468
|
+
before do
|
|
469
|
+
allow(SimpleNavigation.config).to receive_messages(autogenerate_item_ids: generate_ids)
|
|
470
|
+
allow(item).to receive_messages(selected?: false, selected_by_condition?: false)
|
|
471
|
+
end
|
|
439
472
|
|
|
440
|
-
|
|
441
|
-
|
|
473
|
+
context 'when :autogenerate_item_ids is true' do
|
|
474
|
+
let(:generate_ids) { true }
|
|
442
475
|
|
|
443
|
-
|
|
444
|
-
|
|
476
|
+
it_behaves_like 'generating id', 'my_id'
|
|
477
|
+
end
|
|
445
478
|
|
|
446
|
-
|
|
447
|
-
|
|
479
|
+
context 'when :autogenerate_item_ids is false' do
|
|
480
|
+
let(:generate_ids) { false }
|
|
448
481
|
|
|
449
|
-
|
|
450
|
-
end
|
|
482
|
+
it_behaves_like 'generating id', 'my_id'
|
|
451
483
|
end
|
|
484
|
+
end
|
|
452
485
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
486
|
+
context "when the :id option isn't given" do
|
|
487
|
+
before do
|
|
488
|
+
allow(SimpleNavigation.config).to receive_messages(autogenerate_item_ids: generate_ids)
|
|
489
|
+
allow(item).to receive_messages(selected?: false, selected_by_condition?: false)
|
|
490
|
+
end
|
|
458
491
|
|
|
459
|
-
|
|
460
|
-
|
|
492
|
+
context 'when :autogenerate_item_ids is true' do
|
|
493
|
+
let(:generate_ids) { true }
|
|
461
494
|
|
|
462
|
-
|
|
463
|
-
|
|
495
|
+
it_behaves_like 'generating id', 'my_key'
|
|
496
|
+
end
|
|
464
497
|
|
|
465
|
-
|
|
466
|
-
|
|
498
|
+
context 'when :autogenerate_item_ids is false' do
|
|
499
|
+
let(:generate_ids) { false }
|
|
467
500
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
end
|
|
501
|
+
it "doesn't set any html id on the item" do
|
|
502
|
+
expect(item.html_options[:id]).to be_blank
|
|
471
503
|
end
|
|
472
504
|
end
|
|
473
505
|
end
|