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.
Files changed (46) hide show
  1. data/.gitignore +6 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +4 -0
  4. data/CHANGELOG +11 -0
  5. data/Gemfile +2 -16
  6. data/Guardfile +5 -0
  7. data/LICENSE +22 -0
  8. data/README.md +40 -0
  9. data/Rakefile +6 -39
  10. data/generators/navigation_config/templates/config/navigation.rb +7 -5
  11. data/init.rb +1 -0
  12. data/install.rb +5 -0
  13. data/lib/simple_navigation/adapters/rails.rb +5 -1
  14. data/lib/simple_navigation/core/configuration.rb +5 -1
  15. data/lib/simple_navigation/core/item.rb +2 -1
  16. data/lib/simple_navigation/core/item_adapter.rb +4 -4
  17. data/lib/simple_navigation/core/item_container.rb +6 -1
  18. data/lib/simple_navigation/rendering/renderer/breadcrumbs.rb +2 -2
  19. data/lib/simple_navigation/rendering/renderer/links.rb +2 -2
  20. data/lib/simple_navigation/rendering/renderer/list.rb +1 -1
  21. data/lib/simple_navigation/version.rb +3 -0
  22. data/lib/simple_navigation.rb +1 -0
  23. data/simple-navigation.gemspec +40 -0
  24. data/spec/initializers/have_css_matcher.rb +13 -0
  25. data/spec/lib/simple_navigation/adapters/padrino_spec.rb +23 -25
  26. data/spec/lib/simple_navigation/adapters/rails_spec.rb +276 -250
  27. data/spec/lib/simple_navigation/adapters/sinatra_spec.rb +64 -53
  28. data/spec/lib/simple_navigation/core/configuration_spec.rb +128 -106
  29. data/spec/lib/simple_navigation/core/item_adapter_spec.rb +144 -168
  30. data/spec/lib/simple_navigation/core/item_container_spec.rb +361 -339
  31. data/spec/lib/simple_navigation/core/item_spec.rb +571 -434
  32. data/spec/lib/simple_navigation/core/items_provider_spec.rb +35 -49
  33. data/spec/lib/simple_navigation/rails_controller_methods_spec.rb +194 -173
  34. data/spec/lib/simple_navigation/rendering/helpers_spec.rb +381 -225
  35. data/spec/lib/simple_navigation/rendering/renderer/base_spec.rb +205 -164
  36. data/spec/lib/simple_navigation/rendering/renderer/breadcrumbs_spec.rb +87 -67
  37. data/spec/lib/simple_navigation/rendering/renderer/json_spec.rb +52 -31
  38. data/spec/lib/simple_navigation/rendering/renderer/links_spec.rb +75 -48
  39. data/spec/lib/simple_navigation/rendering/renderer/list_spec.rb +62 -174
  40. data/spec/lib/simple_navigation/rendering/renderer/text_spec.rb +41 -28
  41. data/spec/lib/simple_navigation_spec.rb +207 -225
  42. data/spec/spec_helper.rb +53 -82
  43. data/uninstall.rb +1 -0
  44. metadata +100 -22
  45. data/README +0 -22
  46. data/VERSION +0 -1
@@ -1,60 +1,46 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe SimpleNavigation::ItemsProvider do
3
+ module SimpleNavigation
4
+ describe ItemsProvider do
5
+ let(:items_provider) { ItemsProvider.new(provider) }
4
6
 
5
- before(:each) do
6
- @provider = stub(:provider)
7
- @items_provider = SimpleNavigation::ItemsProvider.new(@provider)
8
- end
7
+ describe '#items' do
8
+ let(:items) { double(:items) }
9
9
 
10
- describe 'initialize' do
11
- it "should set the provider" do
12
- @items_provider.provider.should == @provider
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
- describe 'items' do
17
- before(:each) do
18
- @items = stub(:items)
19
- end
20
- context 'provider is symbol' do
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
- it "should return the items of the provider" do
43
- @items_provider.items.should == @items
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
- end
46
- context 'provider is a collection' do
47
- before(:each) do
48
- @items_collection = []
49
- @items_provider.instance_variable_set(:@provider, @items_collection)
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
- it "should return the collection itsself" do
52
- @items_provider.items.should == @items_collection
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
- describe 'explicit navigation in rails' do
4
- require 'simple_navigation/rails_controller_methods'
4
+ class TestController
5
+ include SimpleNavigation::ControllerMethods
5
6
 
6
- it 'should have enhanced the ActionController after loading the extensions' do
7
- ActionController::Base.instance_methods.map {|m| m.to_s}.should include('current_navigation')
7
+ def self.helper_method(*args)
8
+ @helper_methods = args
8
9
  end
9
10
 
10
- describe SimpleNavigation::ControllerMethods do
11
+ def self.before_filter(*args)
12
+ @before_filters = args
13
+ end
14
+ end
11
15
 
12
- def stub_loading_config
13
- SimpleNavigation::Configuration.stub!(:load)
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
- before(:each) do
17
- stub_loading_config
18
- class TestController
19
- class << self
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 being included' do
33
- it "should extend the ClassMethods" do
34
- @controller.class.should respond_to(:navigation)
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
- it "should include the InstanceMethods" do
37
- @controller.should respond_to(:current_navigation)
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
- describe 'class_methods' do
42
-
43
- describe 'navigation' do
40
+ module ControllerMethods
41
+ describe ClassMethods do
42
+ let(:controller) { TestController.new }
44
43
 
45
- def call_navigation(key1, key2=nil)
46
- @controller.class_eval do
47
- navigation key1, key2
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
- it "should not have an instance-method 'sn_set_navigation' if navigation-method has not been called" do
52
- @controller.respond_to?(:sn_set_navigation).should be_false
53
- end
54
- it 'should create an instance-method "sn_set_navigation" when being called' do
55
- call_navigation(:key)
56
- @controller.respond_to?(:sn_set_navigation, true).should be_true
57
- end
58
- it "the created method should not be public" do
59
- call_navigation(:key)
60
- @controller.public_methods.map(&:to_sym).should_not include(:sn_set_navigation)
61
- end
62
- it "the created method should be protected" do
63
- call_navigation(:key)
64
- @controller.protected_methods.map(&:to_sym).should include(:sn_set_navigation)
65
- end
66
- it 'the created method should call current_navigation with the specified keys' do
67
- call_navigation(:primary, :secondary)
68
- @controller.should_receive(:current_navigation).with(:primary, :secondary)
69
- @controller.send(:sn_set_navigation)
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 'instance_methods' do
81
+ describe InstanceMethods do
82
+ let(:controller) { TestController.new }
76
83
 
77
- describe 'current_navigation' do
78
- it "should set the sn_current_navigation_args as specified" do
79
- @controller.current_navigation(:first)
80
- @controller.instance_variable_get(:@sn_current_navigation_args).should == [:first]
81
- end
82
- it "should set the sn_current_navigation_args as specified" do
83
- @controller.current_navigation(:first, :second)
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
- SimpleNavigation.stub!(:explicit_navigation_args => args.compact.empty? ? nil : args)
108
+ keys = args.compact.empty? ? nil : args
109
+ simple_navigation.stub(explicit_navigation_args: keys)
97
110
  end
98
111
 
99
- before(:each) do
100
- @controller = stub(:controller)
101
- @adapter = stub(:adapter, :controller => @controller)
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
- context 'with explicit navigation set' do
106
- context 'list of navigations' do
107
- before(:each) do
108
- args :first, :second, :third
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
- context 'single navigation' do
116
- context 'specified key is a valid navigation item' do
117
- before(:each) do
118
- @primary = stub(:primary, :level_for_item => 2)
119
- SimpleNavigation.stub!(:primary_navigation => @primary)
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
- it "should set the correct instance var in the controller" do
123
- @controller.should_receive(:instance_variable_set).with(:@sn_current_navigation_2, :key)
124
- SimpleNavigation.handle_explicit_navigation
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
- context 'specified key is an invalid navigation item' do
128
- before(:each) do
129
- @primary = stub(:primary, :level_for_item => nil)
130
- SimpleNavigation.stub!(:primary_navigation => @primary)
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
- it "should raise an ArgumentError" do
134
- lambda {SimpleNavigation.handle_explicit_navigation}.should raise_error(ArgumentError)
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
- context 'hash with level' do
139
- before(:each) do
140
- args :level_2 => :key
141
- end
142
- it "should set the correct instance var in the controller" do
143
- @controller.should_receive(:instance_variable_set).with(:@sn_current_navigation_2, :key)
144
- SimpleNavigation.handle_explicit_navigation
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
- context 'hash with multiple_levels' do
148
- before(:each) do
149
- args :level_2 => :key, :level_1 => :bla
150
- end
151
- it "should set the correct instance var in the controller" do
152
- @controller.should_receive(:instance_variable_set).with(:@sn_current_navigation_2, :key)
153
- SimpleNavigation.handle_explicit_navigation
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
- context 'without explicit navigation set' do
158
- before(:each) do
159
- args nil
160
- end
161
- it "should not set the current_navigation instance var in the controller" do
162
- @controller.should_not_receive(:instance_variable_set)
163
- SimpleNavigation.handle_explicit_navigation
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
- before(:each) do
170
- @controller = stub(:controller)
171
- @adapter = stub(:adapter, :controller => @controller)
172
- SimpleNavigation.stub!(:adapter => @adapter)
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
- end
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
- describe SimpleNavigation::Item do
183
- before(:each) do
184
- @item_container = stub(:item_container, :level => 1)
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
- describe 'selected_by_config?' do
189
- context 'navigation explicitly set' do
190
- it "should return true if current matches key" do
191
- SimpleNavigation.stub!(:current_navigation_for => :my_key)
192
- @item.should be_selected_by_config
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
- it "should return false if current does not match key" do
195
- SimpleNavigation.stub!(:current_navigation_for => :other_key)
196
- @item.should_not be_selected_by_config
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
- context 'navigation not explicitly set' do
200
- before(:each) do
201
- SimpleNavigation.stub!(:current_navigation_for => nil)
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 SimpleNavigation::ItemContainer do
209
- describe 'selected_item' do
210
- before(:each) do
211
- SimpleNavigation.stub!(:current_navigation_for)
212
- @item_container = SimpleNavigation::ItemContainer.new
213
-
214
- @item_1 = stub(:item, :selected? => false)
215
- @item_2 = stub(:item, :selected? => false)
216
- @item_container.instance_variable_set(:@items, [@item_1, @item_2])
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
- context 'navigation explicitely set' do
219
- before(:each) do
220
- @item_container.stub!(:[] => @item_1)
221
- end
222
- it "should return the explicitely selected item" do
223
- @item_container.selected_item.should == @item_1
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
- context 'navigation not explicitely set' do
227
- before(:each) do
228
- @item_container.stub!(:[] => nil)
229
- end
230
- context 'no item selected' do
231
- it "should return nil" do
232
- @item_container.selected_item.should be_nil
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
- context 'one item selected' do
236
- before(:each) do
237
- @item_1.stub!(:selected? => true)
238
- end
239
- it "should return the selected item" do
240
- @item_container.selected_item.should == @item_1
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
-