bootstrap-navbar 0.0.13 → 1.0.0.pre1

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.
@@ -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