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,60 +1,46 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
module SimpleNavigation
|
4
|
+
describe ItemsProvider do
|
5
|
+
let(:items_provider) { ItemsProvider.new(provider) }
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
@items_provider = SimpleNavigation::ItemsProvider.new(@provider)
|
8
|
-
end
|
7
|
+
describe '#items' do
|
8
|
+
let(:items) { double(:items) }
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
end
|
10
|
+
context 'when provider is a symbol' do
|
11
|
+
let(:context) { double(:context, provider_method: items) }
|
12
|
+
let(:provider) { :provider_method }
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
before(:each) do
|
22
|
-
@items_provider.instance_variable_set(:@provider, :provider_method)
|
23
|
-
@context = stub(:context, :provider_method => @items)
|
24
|
-
SimpleNavigation.stub!(:context_for_eval => @context)
|
25
|
-
end
|
26
|
-
it "should call the method specified by symbol on the context" do
|
27
|
-
@context.should_receive(:provider_method)
|
28
|
-
@items_provider.items
|
29
|
-
end
|
30
|
-
it "should return the items returned by the helper method" do
|
31
|
-
@items_provider.items.should == @items
|
32
|
-
end
|
33
|
-
end
|
34
|
-
context 'provider responds to items' do
|
35
|
-
before(:each) do
|
36
|
-
@provider.stub!(:items => @items)
|
37
|
-
end
|
38
|
-
it "should get the items from the items_provider" do
|
39
|
-
@provider.should_receive(:items)
|
40
|
-
@items_provider.items
|
14
|
+
before { SimpleNavigation.stub(context_for_eval: context) }
|
15
|
+
|
16
|
+
it 'retrieves the items from the evaluation context' do
|
17
|
+
expect(items_provider.items).to eq items
|
18
|
+
end
|
41
19
|
end
|
42
|
-
|
43
|
-
|
20
|
+
|
21
|
+
context 'when provider responds to :items' do
|
22
|
+
let(:provider) { double(:provider, items: items) }
|
23
|
+
|
24
|
+
it 'retrieves the items from the provider object' do
|
25
|
+
expect(items_provider.items).to eq items
|
26
|
+
end
|
44
27
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
28
|
+
|
29
|
+
context 'provider is a collection' do
|
30
|
+
let(:provider) { [] }
|
31
|
+
|
32
|
+
it 'retrieves the items by returning the provider' do
|
33
|
+
expect(items_provider.items).to eq provider
|
34
|
+
end
|
50
35
|
end
|
51
|
-
|
52
|
-
|
36
|
+
|
37
|
+
context 'when provider is something else' do
|
38
|
+
let(:provider) { double(:provider) }
|
39
|
+
|
40
|
+
it 'raises an exception' do
|
41
|
+
expect{ items_provider.items }.to raise_error
|
42
|
+
end
|
53
43
|
end
|
54
44
|
end
|
55
|
-
context 'neither symbol nor items_provider.items nor collection' do
|
56
|
-
it {lambda {@items_provider.items}.should raise_error}
|
57
|
-
end
|
58
45
|
end
|
59
|
-
|
60
|
-
end
|
46
|
+
end
|
@@ -1,249 +1,270 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'simple_navigation/rails_controller_methods'
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
class TestController
|
5
|
+
include SimpleNavigation::ControllerMethods
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
def self.helper_method(*args)
|
8
|
+
@helper_methods = args
|
8
9
|
end
|
9
10
|
|
10
|
-
|
11
|
+
def self.before_filter(*args)
|
12
|
+
@before_filters = args
|
13
|
+
end
|
14
|
+
end
|
11
15
|
|
12
|
-
|
13
|
-
|
16
|
+
module SimpleNavigation
|
17
|
+
describe 'Explicit navigation in rails' do
|
18
|
+
it 'enhances ActionController after loading the extensions' do
|
19
|
+
methods = ActionController::Base.instance_methods.map(&:to_s)
|
20
|
+
expect(methods).to include 'current_navigation'
|
14
21
|
end
|
22
|
+
end
|
15
23
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
def helper_method(*args)
|
21
|
-
@helper_methods = args
|
22
|
-
end
|
23
|
-
def before_filter(*args)
|
24
|
-
@before_filters = args
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
TestController.send(:include, SimpleNavigation::ControllerMethods)
|
29
|
-
@controller = TestController.new
|
30
|
-
end
|
24
|
+
describe ControllerMethods do
|
25
|
+
let(:controller) { TestController.new }
|
26
|
+
|
27
|
+
before { SimpleNavigation::Configuration.stub(:load) }
|
31
28
|
|
32
|
-
describe 'when
|
33
|
-
it
|
34
|
-
|
29
|
+
describe 'when the module is included' do
|
30
|
+
it 'extends the ClassMethods module' do
|
31
|
+
expect(controller.class).to respond_to(:navigation)
|
35
32
|
end
|
36
|
-
|
37
|
-
|
33
|
+
|
34
|
+
it "includes the InstanceMethods module" do
|
35
|
+
expect(controller).to respond_to(:current_navigation)
|
38
36
|
end
|
39
37
|
end
|
38
|
+
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
module ControllerMethods
|
41
|
+
describe ClassMethods do
|
42
|
+
let(:controller) { TestController.new }
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
describe '#navigation' do
|
45
|
+
context 'when the navigation method is not called' do
|
46
|
+
it "doesn't have any instance method called 'sn_set_navigation'" do
|
47
|
+
has_method = controller.respond_to?(:sn_set_navigation, true)
|
48
|
+
expect(has_method).to be_false
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
52
|
+
context 'when the navigation method is called' do
|
53
|
+
before do
|
54
|
+
controller.class_eval { navigation(:primary, :secondary) }
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'creates an instance method called "sn_set_navigation"' do
|
58
|
+
has_method = controller.respond_to?(:sn_set_navigation, true)
|
59
|
+
expect(has_method).to be_true
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'does not create a public method' do
|
63
|
+
methods = controller.public_methods.map(&:to_s)
|
64
|
+
expect(methods).not_to include 'sn_set_navigation'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'creates a protected method' do
|
68
|
+
methods = controller.protected_methods.map(&:to_s)
|
69
|
+
expect(methods).to include 'sn_set_navigation'
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'creates a method that calls current_navigation with the specified keys' do
|
73
|
+
expect(controller).to receive(:current_navigation)
|
74
|
+
.with(:primary, :secondary)
|
75
|
+
controller.send(:sn_set_navigation)
|
76
|
+
end
|
70
77
|
end
|
71
78
|
end
|
72
|
-
|
73
79
|
end
|
74
80
|
|
75
|
-
describe
|
81
|
+
describe InstanceMethods do
|
82
|
+
let(:controller) { TestController.new }
|
76
83
|
|
77
|
-
describe 'current_navigation' do
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
@controller.instance_variable_get(:@sn_current_navigation_args).should == [:first, :second]
|
84
|
+
describe '#current_navigation' do
|
85
|
+
shared_examples 'setting the correct sn_current_navigation_args' do |args|
|
86
|
+
it 'sets the sn_current_navigation_args as specified' do
|
87
|
+
controller.current_navigation(*args)
|
88
|
+
args = controller.instance_variable_get(:@sn_current_navigation_args)
|
89
|
+
expect(args).to eq args
|
90
|
+
end
|
85
91
|
end
|
86
|
-
end
|
87
92
|
|
93
|
+
it_behaves_like 'setting the correct sn_current_navigation_args', [:first]
|
94
|
+
it_behaves_like 'setting the correct sn_current_navigation_args', [:first, :second]
|
95
|
+
end
|
88
96
|
end
|
89
|
-
|
90
97
|
end
|
91
98
|
|
92
99
|
describe 'SimpleNavigation module additions' do
|
100
|
+
let(:adapter) { double(:adapter, controller: controller) }
|
101
|
+
let(:controller) { double(:controller) }
|
102
|
+
let(:simple_navigation) { SimpleNavigation }
|
103
|
+
|
104
|
+
before { simple_navigation.stub(adapter: adapter) }
|
93
105
|
|
94
|
-
describe 'handle_explicit_navigation' do
|
106
|
+
describe '.handle_explicit_navigation' do
|
95
107
|
def args(*args)
|
96
|
-
|
108
|
+
keys = args.compact.empty? ? nil : args
|
109
|
+
simple_navigation.stub(explicit_navigation_args: keys)
|
97
110
|
end
|
98
111
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
SimpleNavigation.stub!(:adapter => @adapter)
|
103
|
-
end
|
112
|
+
context 'when there is an explicit navigation set' do
|
113
|
+
context 'and it is a list of navigations' do
|
114
|
+
before { args :first, :second, :third }
|
104
115
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
end
|
110
|
-
it "should set the correct instance var in the controller" do
|
111
|
-
@controller.should_receive(:instance_variable_set).with(:@sn_current_navigation_3, :third)
|
112
|
-
SimpleNavigation.handle_explicit_navigation
|
116
|
+
it 'sets the correct instance var in the controller' do
|
117
|
+
expect(controller).to receive(:instance_variable_set)
|
118
|
+
.with(:@sn_current_navigation_3, :third)
|
119
|
+
simple_navigation.handle_explicit_navigation
|
113
120
|
end
|
114
121
|
end
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
122
|
+
|
123
|
+
context 'and it is a single navigation' do
|
124
|
+
context 'and the specified key is a valid navigation item' do
|
125
|
+
let(:primary) { double(:primary, level_for_item: 2) }
|
126
|
+
|
127
|
+
before do
|
128
|
+
simple_navigation.stub(primary_navigation: primary)
|
120
129
|
args :key
|
121
130
|
end
|
122
|
-
|
123
|
-
|
124
|
-
|
131
|
+
|
132
|
+
it 'sets the correct instance var in the controller' do
|
133
|
+
expect(controller).to receive(:instance_variable_set)
|
134
|
+
.with(:@sn_current_navigation_2, :key)
|
135
|
+
simple_navigation.handle_explicit_navigation
|
125
136
|
end
|
126
137
|
end
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
138
|
+
|
139
|
+
context 'and the specified key is an invalid navigation item' do
|
140
|
+
let(:primary) { double(:primary, level_for_item: nil) }
|
141
|
+
|
142
|
+
before do
|
143
|
+
subject.stub(primary_navigation: primary)
|
131
144
|
args :key
|
132
145
|
end
|
133
|
-
|
134
|
-
|
146
|
+
|
147
|
+
it 'raises an exception' do
|
148
|
+
expect{ subject.handle_explicit_navigation }.to raise_error
|
135
149
|
end
|
136
150
|
end
|
137
151
|
end
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
it
|
143
|
-
|
144
|
-
|
152
|
+
|
153
|
+
context 'and the argument is a one-level hash' do
|
154
|
+
before { args level_2: :key }
|
155
|
+
|
156
|
+
it 'sets the correct instance var in the controller' do
|
157
|
+
expect(controller).to receive(:instance_variable_set)
|
158
|
+
.with(:@sn_current_navigation_2, :key)
|
159
|
+
simple_navigation.handle_explicit_navigation
|
145
160
|
end
|
146
161
|
end
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
it
|
152
|
-
|
153
|
-
|
162
|
+
|
163
|
+
context 'when the argument is a multiple levels hash' do
|
164
|
+
before { args level_2: :key, level_1: :bla }
|
165
|
+
|
166
|
+
it 'sets the correct instance var in the controller' do
|
167
|
+
expect(controller).to receive(:instance_variable_set)
|
168
|
+
.with(:@sn_current_navigation_2, :key)
|
169
|
+
simple_navigation.handle_explicit_navigation
|
154
170
|
end
|
155
171
|
end
|
156
172
|
end
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
it "
|
162
|
-
|
163
|
-
|
173
|
+
|
174
|
+
context 'when no explicit navigation is set' do
|
175
|
+
before { args nil }
|
176
|
+
|
177
|
+
it "doesn't set the current_navigation instance var in the controller" do
|
178
|
+
expect(controller).not_to receive(:instance_variable_set)
|
179
|
+
simple_navigation.handle_explicit_navigation
|
164
180
|
end
|
165
181
|
end
|
166
182
|
end
|
167
183
|
|
168
|
-
describe 'current_navigation_for' do
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
end
|
174
|
-
it "should access the correct instance_var in the controller" do
|
175
|
-
@controller.should_receive(:instance_variable_get).with(:@sn_current_navigation_1)
|
176
|
-
SimpleNavigation.current_navigation_for(1)
|
184
|
+
describe '#current_navigation_for' do
|
185
|
+
it 'accesses the correct instance var in the controller' do
|
186
|
+
expect(controller).to receive(:instance_variable_get)
|
187
|
+
.with(:@sn_current_navigation_1)
|
188
|
+
simple_navigation.current_navigation_for(1)
|
177
189
|
end
|
178
190
|
end
|
191
|
+
end
|
179
192
|
|
180
|
-
|
193
|
+
describe Item do
|
194
|
+
let(:item) { Item.new(item_container, :my_key, 'name', 'url', {}) }
|
195
|
+
let(:item_container) { double(:item_container, level: 1) }
|
196
|
+
let(:simple_navigation) { SimpleNavigation }
|
181
197
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
@item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {})
|
186
|
-
|
198
|
+
before do
|
199
|
+
item_container.stub(:dom_attributes=)
|
200
|
+
simple_navigation.stub(current_navigation_for: navigation_key)
|
187
201
|
end
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
202
|
+
|
203
|
+
describe '#selected_by_config?' do
|
204
|
+
context 'when the navigation explicitly set' do
|
205
|
+
context 'when current matches the key' do
|
206
|
+
let(:navigation_key) { :my_key }
|
207
|
+
|
208
|
+
it 'selects the item' do
|
209
|
+
expect(item).to be_selected_by_config
|
210
|
+
end
|
193
211
|
end
|
194
|
-
|
195
|
-
|
196
|
-
|
212
|
+
|
213
|
+
context "when current doesn't match the key" do
|
214
|
+
let(:navigation_key) { :other_key }
|
215
|
+
|
216
|
+
it "doesn't select the item" do
|
217
|
+
expect(item).not_to be_selected_by_config
|
218
|
+
end
|
197
219
|
end
|
198
220
|
end
|
199
|
-
|
200
|
-
|
201
|
-
|
221
|
+
|
222
|
+
context 'when the navigation is not explicitly set' do
|
223
|
+
let(:navigation_key) { nil }
|
224
|
+
|
225
|
+
it "doesn't select the item" do
|
226
|
+
expect(item).not_to be_selected_by_config
|
202
227
|
end
|
203
|
-
it {@item.should_not be_selected_by_config}
|
204
228
|
end
|
205
229
|
end
|
206
230
|
end
|
207
|
-
|
208
|
-
describe
|
209
|
-
describe 'selected_item' do
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
231
|
+
|
232
|
+
describe ItemContainer do
|
233
|
+
describe '#selected_item' do
|
234
|
+
let(:item_container) { SimpleNavigation::ItemContainer.new }
|
235
|
+
let(:item_1) { double(:item, selected?: false) }
|
236
|
+
let(:item_2) { double(:item, selected?: false) }
|
237
|
+
|
238
|
+
before do
|
239
|
+
SimpleNavigation.stub(:current_navigation_for)
|
240
|
+
item_container.instance_variable_set(:@items, [item_1, item_2])
|
217
241
|
end
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
it
|
223
|
-
|
242
|
+
|
243
|
+
context 'when a navigation is explicitely set' do
|
244
|
+
before { item_container.stub(:[] => item_1) }
|
245
|
+
|
246
|
+
it 'returns the explicitely selected item' do
|
247
|
+
expect(item_container.selected_item).to be item_1
|
224
248
|
end
|
225
249
|
end
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
context 'no item selected' do
|
231
|
-
it
|
232
|
-
|
250
|
+
|
251
|
+
context 'when no navigation is explicitely set' do
|
252
|
+
before { item_container.stub(:[] => nil) }
|
253
|
+
|
254
|
+
context 'and no item is selected' do
|
255
|
+
it 'returns nil' do
|
256
|
+
expect(item_container.selected_item).to be_nil
|
233
257
|
end
|
234
258
|
end
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
it
|
240
|
-
|
259
|
+
|
260
|
+
context 'and one item is selected' do
|
261
|
+
before { item_1.stub(selected?: true) }
|
262
|
+
|
263
|
+
it 'returns the selected item' do
|
264
|
+
expect(item_container.selected_item).to be item_1
|
241
265
|
end
|
242
266
|
end
|
243
267
|
end
|
244
268
|
end
|
245
|
-
|
246
269
|
end
|
247
|
-
|
248
270
|
end
|
249
|
-
|