bootstrap-navbar 0.0.13 → 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,116 @@
1
+ module BootstrapNavbar::Helpers::Bootstrap3
2
+ def navbar(options = {}, &block)
3
+ navbar_wrapper options do
4
+ navbar_header options[:brand], options[:brand_link]
5
+ end
6
+ end
7
+
8
+ def navbar_group(options = {}, &block)
9
+ css_classes = %w(nav navbar-nav).tap do |css_classes|
10
+ css_classes << "navbar-#{options[:align]}" if options.has_key?(:align)
11
+ end
12
+ attributes = attribute_hash_to_string({ class: css_classes.join(' ') }.merge(options))
13
+ prepare_html <<-HTML.chomp!
14
+ <ul#{with_preceding_space attributes}>
15
+ #{capture(&block) if block_given?}
16
+ </ul>
17
+ HTML
18
+ end
19
+
20
+ def navbar_dropdown(text, &block)
21
+ prepare_html <<-HTML.chomp!
22
+ <li class="dropdown">
23
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">#{text} <b class="caret"></b></a>
24
+ <ul class="dropdown-menu">
25
+ #{capture(&block) if block_given?}
26
+ </ul>
27
+ </li>
28
+ HTML
29
+ end
30
+
31
+ def navbar_group_item(text, url)
32
+ attributes = {}
33
+ attributes[:class] = 'active' if current_url?(url)
34
+ attributes = attribute_hash_to_string(attributes)
35
+ prepare_html <<-HTML.chomp!
36
+ <li#{with_preceding_space attributes}>
37
+ <a href="#{url}">#{text}</a>
38
+ </li>
39
+ HTML
40
+ end
41
+
42
+ def navbar_form(options = {}, &block)
43
+ css_classes = %w(navbar-form).tap do |css_classes|
44
+ css_classes << "navbar-#{options[:align]}" if options.has_key?(:align)
45
+ end
46
+ attribute_hash = { class: css_classes.join(' '), role: 'form' }
47
+ attributes = attribute_hash_to_string(attribute_hash)
48
+ prepare_html <<-HTML.chomp!
49
+ <form#{with_preceding_space attributes}>
50
+ #{capture(&block) if block_given?}
51
+ </form>
52
+ HTML
53
+ end
54
+
55
+ def navbar_divider
56
+ prepare_html <<-HTML.chomp!
57
+ <li class="divider"></li>
58
+ HTML
59
+ end
60
+
61
+ def navbar_text(text = nil, &block)
62
+ raise StandardError, 'Please provide either the "text" parameter or a block.' if (text.nil? && !block_given?) || (!text.nil? && block_given?)
63
+ text ||= capture(&block)
64
+ prepare_html <<-HTML.chomp!
65
+ <p class="navbar-text">#{text}</p>
66
+ HTML
67
+ end
68
+
69
+ def navbar_button(text, options = {})
70
+ css_classes = %w(btn navbar-btn).tap do |css_classes|
71
+ css_classes << options[:class] if options.has_key?(:class)
72
+ end
73
+ attribute_hash = { class: css_classes.join(' '), type: 'button' }
74
+ attributes = attribute_hash_to_string(attribute_hash)
75
+ prepare_html <<-HTML.chomp!
76
+ <button#{with_preceding_space attributes}>#{text}</button>
77
+ HTML
78
+ end
79
+
80
+ private
81
+
82
+ def navbar_header(brand, brand_link)
83
+ prepare_html <<-HTML.chomp!
84
+ <div class="navbar-header">
85
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapsable">
86
+ <span class="sr-only">Toggle navigation</span>
87
+ <span class="icon-bar"></span>
88
+ <span class="icon-bar"></span>
89
+ <span class="icon-bar"></span>
90
+ </button>
91
+ #{brand_link brand, brand_link}
92
+ </div>
93
+ HTML
94
+ end
95
+
96
+ def brand_link(name, url = nil)
97
+ prepare_html %(<a href="#{url || '/'}" class="navbar-brand">#{name}</a>)
98
+ end
99
+
100
+ def navbar_wrapper(options, &block)
101
+ style = options[:inverse] ? 'inverse' : 'default'
102
+ css_classes = %w(navbar).tap do |css_classes|
103
+ css_classes << "navbar-fixed-#{options[:fixed]}" if options.has_key?(:fixed)
104
+ css_classes << 'navbar-static-top' if options[:static]
105
+ css_classes << 'navbar-inverse' if options[:inverse]
106
+ css_classes << "navbar-#{style}"
107
+ end
108
+ attribute_hash = { class: css_classes.join(' '), role: 'navigation' }
109
+ attributes = attribute_hash_to_string(attribute_hash)
110
+ prepare_html <<-HTML.chomp!
111
+ <nav#{with_preceding_space attributes}>
112
+ #{capture(&block) if block_given?}
113
+ </nav>
114
+ HTML
115
+ end
116
+ end
@@ -1,3 +1,3 @@
1
1
  module BootstrapNavbar
2
- VERSION = '0.0.13'
2
+ VERSION = '1.0.0.pre1'
3
3
  end
@@ -0,0 +1,424 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples 'active menu item' do
4
+ it 'generates the correct HTML' do
5
+ with_all_2_dot_x_versions do
6
+ paths_and_urls.each do |current_path_or_url|
7
+ paths_and_urls.each do |menu_path_or_url|
8
+ BootstrapNavbar.configuration.current_url_method = "'#{current_path_or_url}'"
9
+ expect(renderer.menu_item('foo', menu_path_or_url)).to have_tag(:li, with: { class: 'active' })
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ describe BootstrapNavbar::Helpers::Bootstrap2 do
17
+ before do
18
+ BootstrapNavbar.configuration.current_url_method = '"/"'
19
+ end
20
+
21
+ it 'includes the correct module' do
22
+ with_all_2_dot_x_versions do
23
+ expect(renderer.class.ancestors).to include(BootstrapNavbar::Helpers::Bootstrap2)
24
+ expect(renderer.class.ancestors).to_not include(BootstrapNavbar::Helpers::Bootstrap3)
25
+ end
26
+ end
27
+
28
+ describe '#navbar' do
29
+ context 'without parameters' do
30
+ it 'generates the correct HTML' do
31
+ with_all_2_dot_x_versions do
32
+ expect(renderer.navbar).to have_tag(:div, with: { class: 'navbar' }) do
33
+ with_tag :div, with: { class: 'navbar-inner' } do
34
+ with_tag :div, with: { class: 'container' }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ context 'with a block' do
42
+ it 'generates the correct HTML' do
43
+ with_all_2_dot_x_versions do
44
+ expect(renderer.navbar { 'foo' }).to have_tag(:div, with: { class: 'navbar' }, content: 'foo')
45
+ end
46
+ end
47
+ end
48
+
49
+ context 'with "static" parameter' do
50
+ it 'generates the correct HTML' do
51
+ with_all_2_dot_x_versions do
52
+ expect(renderer.navbar(static: 'top')).to have_tag(:div, with: { class: 'navbar navbar-static-top' })
53
+ expect(renderer.navbar(static: 'bottom')).to have_tag(:div, with: { class: 'navbar navbar-static-bottom' })
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'with "fixed" parameter' do
59
+ it 'generates the correct HTML' do
60
+ with_all_2_dot_x_versions do
61
+ expect(renderer.navbar(fixed: 'top')).to have_tag(:div, with: { class: 'navbar navbar-fixed-top' })
62
+ expect(renderer.navbar(fixed: 'bottom')).to have_tag(:div, with: { class: 'navbar navbar-fixed-bottom' })
63
+ end
64
+ end
65
+ end
66
+
67
+ context 'with "inverse" parameter' do
68
+ it 'generates the correct HTML' do
69
+ with_all_2_dot_x_versions do
70
+ expect(renderer.navbar(inverse: true)).to have_tag(:div, with: { class: 'navbar navbar-inverse' })
71
+ end
72
+ end
73
+ end
74
+
75
+ context 'with "brand" and "brank_link" parameters' do
76
+ it 'generates the correct HTML' do
77
+ with_all_2_dot_x_versions do
78
+ expect(renderer.navbar(brand: 'foo')).to have_tag(:a, with: { href: '/', class: 'brand' }, content: 'foo')
79
+ expect(renderer.navbar(brand: 'foo', brand_link: 'http://google.com')).to have_tag(:a, with: { href: 'http://google.com', class: 'brand' }, content: 'foo')
80
+ expect(renderer.navbar(brand_link: 'http://google.com')).to have_tag(:a, with: { href: 'http://google.com', class: 'brand' })
81
+ end
82
+ end
83
+ end
84
+
85
+ context 'with "responsive" parameter' do
86
+ it 'generates the correct HTML' do
87
+ with_all_2_dot_x_versions do
88
+ expect(renderer.navbar(responsive: true)).to have_tag(:a, with: { class: 'btn btn-navbar', :'data-toggle' => 'collapse', :'data-target' => '.nav-collapse' }) do
89
+ 3.times do
90
+ with_tag :span, with: { class: 'icon-bar' }
91
+ end
92
+ end
93
+ end
94
+ with_versions '2.2.0'...'3' do
95
+ expect(renderer.navbar(responsive: true)).to have_tag(:div, with: { class: 'nav-collapse collapse' })
96
+ end
97
+ with_versions '0'...'2.2.0' do
98
+ expect(renderer.navbar(responsive: true)).to have_tag(:div, with: { class: 'nav-collapse' })
99
+ end
100
+ end
101
+ end
102
+
103
+ context 'with "fluid" parameter' do
104
+ it 'generates the correct HTML' do
105
+ with_all_2_dot_x_versions do
106
+ expect(renderer.navbar(fluid: true)).to have_tag(:div, with: { class: 'container-fluid' })
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ describe '#menu_group' do
113
+ context 'without parameters' do
114
+ it 'generates the correct HTML' do
115
+ with_all_2_dot_x_versions do
116
+ expect(renderer.menu_group).to have_tag(:ul, with: { class: 'nav' })
117
+ expect(renderer.menu_group { 'foo' }).to have_tag(:ul, with: { class: 'nav' }, content: 'foo')
118
+ end
119
+ end
120
+ end
121
+
122
+ context 'with "pull" parameter' do
123
+ it 'generates the correct HTML' do
124
+ with_all_2_dot_x_versions do
125
+ expect(renderer.menu_group(pull: 'right')).to have_tag(:ul, with: { class: 'nav pull-right' })
126
+ end
127
+ end
128
+ end
129
+
130
+ context 'with "class" parameter' do
131
+ it 'generates the correct HTML' do
132
+ with_all_2_dot_x_versions do
133
+ expect(renderer.menu_group(class: 'foo')).to have_tag(:ul, with: { class: 'nav foo' })
134
+ end
135
+ end
136
+ end
137
+
138
+ context 'with random parameters' do
139
+ it 'generates the correct HTML' do
140
+ with_all_2_dot_x_versions do
141
+ expect(renderer.menu_group(:'data-foo' => 'bar')).to have_tag(:ul, with: { class: 'nav', :'data-foo' => 'bar' })
142
+ end
143
+ end
144
+ end
145
+
146
+ context 'with many parameters' do
147
+ it 'generates the correct HTML' do
148
+ with_all_2_dot_x_versions do
149
+ expect(renderer.menu_group(pull: 'right', class: 'foo', :'data-foo' => 'bar')).to have_tag(:ul, with: { class: 'nav foo pull-right', :'data-foo' => 'bar' })
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ describe '#menu_item' do
156
+ context 'with current URL or path' do
157
+ # With root URL or path
158
+ it_behaves_like 'active menu item' do
159
+ let(:paths_and_urls) do
160
+ %w(
161
+ http://www.foobar.com/
162
+ http://www.foobar.com
163
+ /
164
+ http://www.foobar.com/?foo=bar
165
+ http://www.foobar.com?foo=bar
166
+ /?foo=bar
167
+ http://www.foobar.com/#foo
168
+ http://www.foobar.com#foo
169
+ /#foo
170
+ http://www.foobar.com/#foo?foo=bar
171
+ http://www.foobar.com#foo?foo=bar
172
+ /#foo?foo=bar
173
+ )
174
+ end
175
+ end
176
+
177
+ # With sub URL or path
178
+ it_behaves_like 'active menu item' do
179
+ let(:paths_and_urls) do
180
+ %w(
181
+ http://www.foobar.com/foo
182
+ http://www.foobar.com/foo/
183
+ /foo
184
+ /foo/
185
+ http://www.foobar.com/foo?foo=bar
186
+ http://www.foobar.com/foo/?foo=bar
187
+ /foo?foo=bar
188
+ /foo/?foo=bar
189
+ http://www.foobar.com/foo#foo
190
+ http://www.foobar.com/foo/#foo
191
+ /foo#foo
192
+ /foo/#foo
193
+ http://www.foobar.com/foo#foo?foo=bar
194
+ http://www.foobar.com/foo/#foo?foo=bar
195
+ /foo#foo?foo=bar
196
+ /foo/#foo?foo=bar
197
+ )
198
+ end
199
+ end
200
+
201
+ context 'with list item options' do
202
+ it 'generates the correct HTML' do
203
+ with_all_2_dot_x_versions do
204
+ BootstrapNavbar.configuration.current_url_method = '"/"'
205
+ expect(renderer.menu_item('foo', '/', class: 'bar', id: 'baz')).to have_tag(:li, with: { class: 'active bar', id: 'baz' })
206
+ end
207
+ end
208
+ end
209
+
210
+ context 'with link options' do
211
+ it 'generates the correct HTML' do
212
+ with_all_2_dot_x_versions do
213
+ BootstrapNavbar.configuration.current_url_method = '"/"'
214
+ expect(renderer.menu_item('foo', '/', {}, class: 'pelle', id: 'fant')).to have_tag(:li, with: { class: 'active' }) do
215
+ with_tag :a, with: { href: '/', class: 'pelle', id: 'fant' }, content: 'foo'
216
+ end
217
+ end
218
+ end
219
+ end
220
+
221
+ context 'with list item options and link options' do
222
+ it 'generates the correct HTML' do
223
+ with_all_2_dot_x_versions do
224
+ BootstrapNavbar.configuration.current_url_method = '"/"'
225
+ expect(renderer.menu_item('foo', '/', { class: 'bar', id: 'baz' }, class: 'pelle', id: 'fant')).to have_tag(:li, with: { class: 'active bar', id: 'baz' }) do
226
+ with_tag :a, with: { href: '/', class: 'pelle', id: 'fant' }, content: 'foo'
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
232
+
233
+ context 'without current URL' do
234
+ it 'generates the correct HTML' do
235
+ with_all_2_dot_x_versions do
236
+ BootstrapNavbar.configuration.current_url_method = '"/foo"'
237
+ expect(renderer.menu_item('foo')).to have_tag(:li, without: { class: 'active' }) do
238
+ with_tag :a, with: { href: '#' }, content: 'foo'
239
+ end
240
+ expect(renderer.menu_item('foo', '/')).to have_tag(:li, without: { class: 'active' }) do
241
+ with_tag :a, with: { href: '/' }, content: 'foo'
242
+ end
243
+ expect(renderer.menu_item('foo', '/bar')).to have_tag(:li, without: { class: 'active' }) do
244
+ with_tag :a, with: { href: '/bar' }, content: 'foo'
245
+ end
246
+
247
+ BootstrapNavbar.configuration.current_url_method = '"/"'
248
+ expect(renderer.menu_item('foo', '/foo')).to have_tag(:li, without: { class: 'active' }) do
249
+ with_tag :a, with: { href: '/foo' }, content: 'foo'
250
+ end
251
+ end
252
+ end
253
+
254
+ context 'with list item options' do
255
+ it 'generates the correct HTML' do
256
+ with_all_2_dot_x_versions do
257
+ BootstrapNavbar.configuration.current_url_method = '"/foo"'
258
+ expect(renderer.menu_item('foo', '/', class: 'bar', id: 'baz')).to have_tag(:li, without: { class: 'active' }, with: { class: 'bar', id: 'baz' })
259
+ end
260
+ end
261
+ end
262
+ end
263
+
264
+ context 'with a block' do
265
+ it 'generates the correct HTML' do
266
+ with_all_2_dot_x_versions do
267
+ expect(renderer.menu_item { 'bar' }).to have_tag(:li) do
268
+ with_tag :a, with: { href: '#' }, content: 'bar'
269
+ end
270
+ end
271
+ end
272
+
273
+ context 'with list item options' do
274
+ it 'generates the correct HTML' do
275
+ with_all_2_dot_x_versions do
276
+ expect(renderer.menu_item('/foo', class: 'pelle', id: 'fant') { 'bar' }).to have_tag(:li, with: { class: 'pelle', id: 'fant' }) do
277
+ with_tag :a, with: { href: '/foo' }, content: 'bar'
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ context 'with link options' do
284
+ it 'generates the correct HTML' do
285
+ with_all_2_dot_x_versions do
286
+ expect(renderer.menu_item('/foo', {}, class: 'pelle', id: 'fant') { 'bar' }).to have_tag(:li) do
287
+ with_tag :a, with: { href: '/foo', class: 'pelle', id: 'fant' }, content: 'bar'
288
+ end
289
+ end
290
+ end
291
+ end
292
+
293
+ context 'with list item options and link options' do
294
+ it 'generates the correct HTML' do
295
+ with_all_2_dot_x_versions do
296
+ expect(renderer.menu_item('/foo', { class: 'bar', id: 'baz' }, class: 'pelle', id: 'fant') { 'shnoo' }).to have_tag(:li, with: { class: 'bar', id: 'baz' }) do
297
+ with_tag :a, with: { href: '/foo', class: 'pelle', id: 'fant' }, content: 'shnoo'
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+ end
304
+
305
+ context 'drop downs' do
306
+ def with_drop_down_menu(content = nil)
307
+ options = { with: { class: 'dropdown-menu' } }
308
+ options[:content] = content unless content.nil?
309
+ with_tag :ul, options
310
+ end
311
+
312
+ describe '#drop_down' do
313
+ it 'generates the correct HTML' do
314
+ with_all_2_dot_x_versions do
315
+ expect(renderer.drop_down('foo')).to have_tag(:li, with: { class: 'dropdown' }) do
316
+ with_tag :a, with: { href: '#', class: 'dropdown-toggle', :'data-toggle' => 'dropdown' } do
317
+ with_text /foo/
318
+ with_tag :b, with: { class: 'caret' }
319
+ end
320
+ with_drop_down_menu
321
+ end
322
+
323
+ expect(renderer.drop_down('foo') { 'bar' }).to have_tag(:li, with: { class: 'dropdown' }) do
324
+ with_tag :a, with: { href: '#', class: 'dropdown-toggle', :'data-toggle' => 'dropdown' } do
325
+ with_text /foo/
326
+ with_tag :b, with: { class: 'caret' }
327
+ end
328
+ with_drop_down_menu('bar')
329
+ end
330
+ end
331
+ end
332
+ end
333
+
334
+ describe '#sub_drop_down' do
335
+ it 'generates the correct HTML' do
336
+ with_all_2_dot_x_versions do
337
+ expect(renderer.sub_drop_down('foo')).to have_tag(:li, with: { class: 'dropdown-submenu' }) do
338
+ with_tag :a, with: { href: '#' }, content: 'foo'
339
+ with_drop_down_menu
340
+ end
341
+
342
+ expect(renderer.sub_drop_down('foo') { 'bar' }).to have_tag(:li, with: { class: 'dropdown-submenu' }) do
343
+ with_tag :a, with: { href: '#' }, content: 'foo'
344
+ with_drop_down_menu('bar')
345
+ end
346
+ end
347
+ end
348
+
349
+ context 'with list item options' do
350
+ it 'generates the correct HTML' do
351
+ with_all_2_dot_x_versions do
352
+ expect(renderer.sub_drop_down('foo', class: 'bar', id: 'baz')).to have_tag(:li, with: { class: 'dropdown-submenu bar', id: 'baz' }) do
353
+ with_tag :a, with: { href: '#' }, content: 'foo'
354
+ end
355
+ end
356
+ end
357
+ end
358
+
359
+ context 'with link options' do
360
+ it 'generates the correct HTML' do
361
+ with_all_2_dot_x_versions do
362
+ expect(renderer.sub_drop_down('foo', {}, class: 'pelle', id: 'fant')).to have_tag(:li, with: { class: 'dropdown-submenu' }) do
363
+ with_tag :a, with: { href: '#', class: 'pelle', id: 'fant' }, content: 'foo'
364
+ end
365
+ end
366
+ end
367
+ end
368
+
369
+ context 'with list item options and link options' do
370
+ it 'generates the correct HTML' do
371
+ with_all_2_dot_x_versions do
372
+ expect(renderer.sub_drop_down('foo', { class: 'bar', id: 'baz' }, class: 'pelle', id: 'fant')).to have_tag(:li, with: { class: 'dropdown-submenu bar', id: 'baz' }) do
373
+ with_tag :a, with: { href: '#', class: 'pelle', id: 'fant' }, content: 'foo'
374
+ end
375
+ end
376
+ end
377
+ end
378
+ end
379
+ end
380
+
381
+ describe '#drop_down_divider' do
382
+ it 'generates the correct HTML' do
383
+ with_all_2_dot_x_versions do
384
+ expect(renderer.drop_down_divider).to have_tag(:li, with: { class: 'divider' }, content: '')
385
+ end
386
+ end
387
+ end
388
+
389
+ describe '#drop_down_header' do
390
+ it 'generates the correct HTML' do
391
+ with_all_2_dot_x_versions do
392
+ expect(renderer.drop_down_header('foo')).to have_tag(:li, with: { class: 'nav-header' }, content: 'foo')
393
+ end
394
+ end
395
+ end
396
+
397
+ describe '#menu_divider' do
398
+ it 'generates the correct HTML' do
399
+ with_all_2_dot_x_versions do
400
+ expect(renderer.menu_divider).to have_tag(:li, with: { class: 'divider-vertical' }, content: '')
401
+ end
402
+ end
403
+ end
404
+
405
+ describe '#menu_text' do
406
+ it 'generates the correct HTML' do
407
+ with_all_2_dot_x_versions do
408
+ expect(renderer.menu_text('foo')).to have_tag(:p, with: { class: 'navbar-text' }, content: 'foo')
409
+ expect(renderer.menu_text { 'foo' }).to have_tag(:p, with: { class: 'navbar-text' }, content: 'foo')
410
+ expect(renderer.menu_text('foo', 'right')).to have_tag(:p, with: { class: 'navbar-text pull-right' }, content: 'foo')
411
+ expect(renderer.menu_text(nil, 'left') { 'foo' }).to have_tag(:p, with: { class: 'navbar-text pull-left' }, content: 'foo')
412
+ end
413
+ end
414
+ end
415
+
416
+ describe '#brand_link' do
417
+ it 'generates the correct HTML' do
418
+ with_all_2_dot_x_versions do
419
+ expect(renderer.brand_link('foo')).to have_tag(:a, with: { class: 'brand', href: '/' }, content: 'foo')
420
+ expect(renderer.brand_link('foo', '/foo')).to have_tag(:a, with: { class: 'brand', href: '/foo' }, content: 'foo')
421
+ end
422
+ end
423
+ end
424
+ end