twitter-bootstrap-rails 3.2.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of twitter-bootstrap-rails might be problematic. Click here for more details.

Files changed (148) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +263 -247
  3. data/app/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  4. data/app/assets/fonts/glyphicons-halflings-regular.svg +273 -214
  5. data/app/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  6. data/app/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  7. data/app/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
  8. data/app/assets/javascripts/twitter/bootstrap/affix.js +60 -35
  9. data/app/assets/javascripts/twitter/bootstrap/alert.js +15 -9
  10. data/app/assets/javascripts/twitter/bootstrap/button.js +33 -20
  11. data/app/assets/javascripts/twitter/bootstrap/carousel.js +79 -47
  12. data/app/assets/javascripts/twitter/bootstrap/collapse.js +84 -43
  13. data/app/assets/javascripts/twitter/bootstrap/dropdown.js +65 -47
  14. data/app/assets/javascripts/twitter/bootstrap/modal.js +138 -44
  15. data/app/assets/javascripts/twitter/bootstrap/popover.js +12 -14
  16. data/app/assets/javascripts/twitter/bootstrap/scrollspy.js +57 -38
  17. data/app/assets/javascripts/twitter/bootstrap/tab.js +54 -24
  18. data/app/assets/javascripts/twitter/bootstrap/tooltip.js +202 -87
  19. data/app/assets/javascripts/twitter/bootstrap/transition.js +19 -8
  20. data/app/assets/stylesheets/twitter-bootstrap-static/bootstrap.css.erb +1 -1
  21. data/app/assets/stylesheets/twitter-bootstrap-static/sprites.css.erb +1 -1
  22. data/app/helpers/bootstrap_flash_helper.rb +8 -3
  23. data/app/helpers/form_errors_helper.rb +11 -11
  24. data/app/helpers/glyph_helper.rb +7 -3
  25. data/app/helpers/modal_helper.rb +9 -13
  26. data/app/helpers/navbar_helper.rb +5 -2
  27. data/app/helpers/twitter_breadcrumbs_helper.rb +4 -1
  28. data/app/views/twitter-bootstrap/_breadcrumbs.html.erb +5 -5
  29. data/lib/generators/bootstrap/install/templates/bootstrap_and_overrides.css +3 -4
  30. data/lib/generators/bootstrap/install/templates/bootstrap_and_overrides.less +7 -15
  31. data/lib/generators/bootstrap/layout/templates/layout.html.erb +5 -5
  32. data/lib/generators/bootstrap/layout/templates/layout.html.haml +3 -3
  33. data/lib/generators/bootstrap/layout/templates/layout.html.slim +3 -5
  34. data/lib/generators/bootstrap/themed/templates/_form.html.erb +12 -9
  35. data/lib/generators/bootstrap/themed/templates/_form.html.haml +7 -5
  36. data/lib/generators/bootstrap/themed/templates/_form.html.slim +8 -6
  37. data/lib/generators/bootstrap/themed/templates/edit.html.slim +1 -1
  38. data/lib/generators/bootstrap/themed/templates/index.html.erb +2 -0
  39. data/lib/generators/bootstrap/themed/templates/index.html.haml +1 -0
  40. data/lib/generators/bootstrap/themed/templates/index.html.slim +4 -3
  41. data/lib/generators/bootstrap/themed/templates/new.html.slim +1 -1
  42. data/lib/generators/bootstrap/themed/templates/show.html.slim +1 -1
  43. data/lib/generators/bootstrap/themed/templates/simple_form/_form.html.haml +1 -1
  44. data/lib/twitter/bootstrap/rails/breadcrumbs.rb +24 -13
  45. data/lib/twitter/bootstrap/rails/engine.rb +17 -12
  46. data/lib/twitter/bootstrap/rails/version.rb +1 -1
  47. data/spec/lib/breadcrumbs_spec.rb +42 -17
  48. data/spec/lib/twitter_bootstrap_rails/badge_label_helper_spec.rb +10 -4
  49. data/spec/lib/twitter_bootstrap_rails/bootstrap_flash_helper_spec.rb +128 -0
  50. data/spec/lib/twitter_bootstrap_rails/form_errors_helper_spec.rb +148 -0
  51. data/spec/lib/twitter_bootstrap_rails/glyph_helper_spec.rb +24 -0
  52. data/spec/lib/twitter_bootstrap_rails/modal_helper_spec.rb +2 -2
  53. data/spec/lib/twitter_bootstrap_rails/navbar_helper_spec.rb +62 -12
  54. data/spec/spec_helper.rb +5 -1
  55. data/vendor/assets/stylesheets/twitter-bootstrap-static/bootstrap.css.erb +1 -3
  56. data/vendor/toolkit/twitter/bootstrap/alerts.less +5 -0
  57. data/vendor/toolkit/twitter/bootstrap/badges.less +14 -3
  58. data/vendor/toolkit/twitter/bootstrap/bootstrap.less +6 -1
  59. data/vendor/toolkit/twitter/bootstrap/breadcrumbs.less +0 -0
  60. data/vendor/toolkit/twitter/bootstrap/button-groups.less +13 -14
  61. data/vendor/toolkit/twitter/bootstrap/buttons.less +14 -7
  62. data/vendor/toolkit/twitter/bootstrap/carousel.less +34 -7
  63. data/vendor/toolkit/twitter/bootstrap/close.less +1 -0
  64. data/vendor/toolkit/twitter/bootstrap/code.less +0 -0
  65. data/vendor/toolkit/twitter/bootstrap/component-animations.less +3 -1
  66. data/vendor/toolkit/twitter/bootstrap/dropdowns.less +9 -8
  67. data/vendor/toolkit/twitter/bootstrap/forms.less +110 -41
  68. data/vendor/toolkit/twitter/bootstrap/glyphicons.less +75 -3
  69. data/vendor/toolkit/twitter/bootstrap/grid.less +0 -0
  70. data/vendor/toolkit/twitter/bootstrap/input-groups.less +8 -3
  71. data/vendor/toolkit/twitter/bootstrap/jumbotron.less +10 -4
  72. data/vendor/toolkit/twitter/bootstrap/labels.less +0 -0
  73. data/vendor/toolkit/twitter/bootstrap/list-group.less +11 -13
  74. data/vendor/toolkit/twitter/bootstrap/media.less +40 -30
  75. data/vendor/toolkit/twitter/bootstrap/mixins/alerts.less +0 -0
  76. data/vendor/toolkit/twitter/bootstrap/mixins/background-variant.less +2 -1
  77. data/vendor/toolkit/twitter/bootstrap/mixins/border-radius.less +0 -0
  78. data/vendor/toolkit/twitter/bootstrap/mixins/buttons.less +19 -6
  79. data/vendor/toolkit/twitter/bootstrap/mixins/center-block.less +0 -0
  80. data/vendor/toolkit/twitter/bootstrap/mixins/clearfix.less +0 -0
  81. data/vendor/toolkit/twitter/bootstrap/mixins/forms.less +0 -0
  82. data/vendor/toolkit/twitter/bootstrap/mixins/gradients.less +0 -0
  83. data/vendor/toolkit/twitter/bootstrap/mixins/grid-framework.less +4 -4
  84. data/vendor/toolkit/twitter/bootstrap/mixins/grid.less +4 -4
  85. data/vendor/toolkit/twitter/bootstrap/mixins/hide-text.less +2 -2
  86. data/vendor/toolkit/twitter/bootstrap/mixins/image.less +0 -0
  87. data/vendor/toolkit/twitter/bootstrap/mixins/labels.less +1 -1
  88. data/vendor/toolkit/twitter/bootstrap/mixins/list-group.less +2 -1
  89. data/vendor/toolkit/twitter/bootstrap/mixins/nav-divider.less +0 -0
  90. data/vendor/toolkit/twitter/bootstrap/mixins/nav-vertical-align.less +0 -0
  91. data/vendor/toolkit/twitter/bootstrap/mixins/opacity.less +0 -0
  92. data/vendor/toolkit/twitter/bootstrap/mixins/pagination.less +2 -1
  93. data/vendor/toolkit/twitter/bootstrap/mixins/panels.less +0 -0
  94. data/vendor/toolkit/twitter/bootstrap/mixins/progress-bar.less +0 -0
  95. data/vendor/toolkit/twitter/bootstrap/mixins/reset-filter.less +0 -0
  96. data/vendor/toolkit/twitter/bootstrap/mixins/reset-text.less +18 -0
  97. data/vendor/toolkit/twitter/bootstrap/mixins/resize.less +0 -0
  98. data/vendor/toolkit/twitter/bootstrap/mixins/responsive-visibility.less +1 -1
  99. data/vendor/toolkit/twitter/bootstrap/mixins/size.less +0 -0
  100. data/vendor/toolkit/twitter/bootstrap/mixins/tab-focus.less +0 -0
  101. data/vendor/toolkit/twitter/bootstrap/mixins/table-row.less +0 -0
  102. data/vendor/toolkit/twitter/bootstrap/mixins/text-emphasis.less +2 -1
  103. data/vendor/toolkit/twitter/bootstrap/mixins/text-overflow.less +0 -0
  104. data/vendor/toolkit/twitter/bootstrap/mixins/vendor-prefixes.less +8 -5
  105. data/vendor/toolkit/twitter/bootstrap/mixins.less +1 -0
  106. data/vendor/toolkit/twitter/bootstrap/modals.less +3 -3
  107. data/vendor/toolkit/twitter/bootstrap/navbar.less +6 -1
  108. data/vendor/toolkit/twitter/bootstrap/navs.less +1 -1
  109. data/vendor/toolkit/twitter/bootstrap/normalize.less +12 -13
  110. data/vendor/toolkit/twitter/bootstrap/pager.less +1 -2
  111. data/vendor/toolkit/twitter/bootstrap/pagination.less +5 -4
  112. data/vendor/toolkit/twitter/bootstrap/panels.less +27 -4
  113. data/vendor/toolkit/twitter/bootstrap/popovers.less +5 -7
  114. data/vendor/toolkit/twitter/bootstrap/print.less +96 -96
  115. data/vendor/toolkit/twitter/bootstrap/progress-bars.less +1 -14
  116. data/vendor/toolkit/twitter/bootstrap/responsive-embed.less +10 -9
  117. data/vendor/toolkit/twitter/bootstrap/responsive-utilities.less +0 -0
  118. data/vendor/toolkit/twitter/bootstrap/scaffolding.less +12 -1
  119. data/vendor/toolkit/twitter/bootstrap/tables.less +6 -5
  120. data/vendor/toolkit/twitter/bootstrap/theme.less +47 -16
  121. data/vendor/toolkit/twitter/bootstrap/thumbnails.less +1 -1
  122. data/vendor/toolkit/twitter/bootstrap/tooltip.less +13 -7
  123. data/vendor/toolkit/twitter/bootstrap/type.less +2 -8
  124. data/vendor/toolkit/twitter/bootstrap/utilities.less +0 -1
  125. data/vendor/toolkit/twitter/bootstrap/variables.less +36 -14
  126. data/vendor/toolkit/twitter/bootstrap/wells.less +0 -0
  127. metadata +76 -52
  128. data/app/assets/fonts/fontawesome-webfont.eot +0 -0
  129. data/app/assets/fonts/fontawesome-webfont.svg +0 -504
  130. data/app/assets/fonts/fontawesome-webfont.ttf +0 -0
  131. data/app/assets/fonts/fontawesome-webfont.woff +0 -0
  132. data/app/assets/images/twitter/bootstrap/glyphicons-halflings-white.png +0 -0
  133. data/app/assets/images/twitter/bootstrap/glyphicons-halflings.png +0 -0
  134. data/app/assets/stylesheets/twitter-bootstrap-static/fontawesome.css.erb +0 -4
  135. data/vendor/static-source/fontawesome.less +0 -8
  136. data/vendor/toolkit/fontawesome/bordered-pulled.less +0 -16
  137. data/vendor/toolkit/fontawesome/core.less +0 -12
  138. data/vendor/toolkit/fontawesome/fixed-width.less +0 -6
  139. data/vendor/toolkit/fontawesome/font-awesome.less +0 -17
  140. data/vendor/toolkit/fontawesome/icons.less +0 -506
  141. data/vendor/toolkit/fontawesome/larger.less +0 -13
  142. data/vendor/toolkit/fontawesome/list.less +0 -19
  143. data/vendor/toolkit/fontawesome/mixins.less +0 -20
  144. data/vendor/toolkit/fontawesome/path.less +0 -14
  145. data/vendor/toolkit/fontawesome/rotated-flipped.less +0 -9
  146. data/vendor/toolkit/fontawesome/spinning.less +0 -32
  147. data/vendor/toolkit/fontawesome/stacked.less +0 -20
  148. data/vendor/toolkit/fontawesome/variables.less +0 -515
@@ -18,7 +18,7 @@ describe Twitter::Bootstrap::Breadcrumbs do
18
18
  add_breadcrumb :base_i18n, '/base_i18n'
19
19
 
20
20
  def breadcrumbs
21
- @breadcrumbs
21
+ @__bs_breadcrumbs
22
22
  end
23
23
  end
24
24
 
@@ -46,29 +46,54 @@ describe Twitter::Bootstrap::Breadcrumbs do
46
46
  end
47
47
  end
48
48
 
49
- before do
50
- options = { :scope => [:breadcrumbs, 'test'] }
51
- [:class_i18n, :instance_i18n, :show, :symbolized].each do |name|
52
- I18n.expects(:t).with(name, options).returns(name.to_s)
49
+ describe 'Breadcrumbs generation' do
50
+
51
+ before do
52
+ options = { :scope => [:breadcrumbs, 'test'] }
53
+ [:class_i18n, :instance_i18n, :show, :symbolized].each do |name|
54
+ I18n.expects(:t).with(name, options).returns(name.to_s)
55
+ end
56
+
57
+ name = :base_i18n
58
+ options = { :scope => [:breadcrumbs, 'base_test'] }
59
+ I18n.expects(:t).with(name, options).returns(name)
60
+
61
+ @controller = TestController.new
62
+ @controller.process(:show)
53
63
  end
54
64
 
55
- name = :base_i18n
56
- options = { :scope => [:breadcrumbs, 'base_test'] }
57
- I18n.expects(:t).with(name, options).returns(name)
65
+ it "have breadcrumbs" do
66
+ [:base, :base_i18n, :class, :class_i18n, :instance, :instance_i18n, :test_model, :symbolized].each do |name|
67
+ path = "/#{name}"
68
+ idx = @controller.breadcrumbs.index { |b| b[:name] == name.to_s && b[:url] == path }
69
+ expect(idx).to be, -> { name }
70
+ end
58
71
 
59
- @controller = TestController.new
60
- @controller.process(:show)
72
+ idx = @controller.breadcrumbs.index { |b| b[:name] == "show" && b[:url] == '' }
73
+ expect(idx).to be
74
+ end
61
75
  end
62
76
 
63
- it "have breadcrumbs" do
64
- [:base, :base_i18n, :class, :class_i18n, :instance, :instance_i18n, :test_model, :symbolized].each do |name|
65
- path = "/#{name}"
66
- idx = @controller.breadcrumbs.index { |b| b[:name] == name.to_s && b[:url] == path }
67
- idx.should be, -> { name }
77
+ describe 'BreadcrumbsOnRails compatibility' do
78
+ class SomeController < AbstractController::Base
79
+ end
80
+ let(:logger) { double('logger').as_null_object }
81
+ before { allow(::Rails).to receive(:logger).and_return(logger) }
82
+
83
+ context 'when BreadcrumbsOnRails is defined' do
84
+ before do
85
+ stub_const('BreadcrumbsOnRails', 1)
86
+ expect(defined?(::BreadcrumbsOnRails)).to be_truthy
87
+ expect(logger).to receive(:info).with /BreadcrumbsOnRails detected/
88
+ SomeController.send(:include, Twitter::Bootstrap::Breadcrumbs)
89
+ end
90
+
91
+ it 'does not define aliases' do
92
+ expect(SomeController).to respond_to :add_bootstrap_breadcrumb
93
+ expect(SomeController).not_to respond_to :add_breadcrumb
94
+ end
68
95
  end
69
96
 
70
- idx = @controller.breadcrumbs.index { |b| b[:name] == "show" && b[:url] == '' }
71
- idx.should be
72
97
  end
73
98
 
74
99
  end
@@ -10,15 +10,21 @@ include BadgeLabelHelper
10
10
 
11
11
  describe BadgeLabelHelper, :type => :helper do
12
12
  it "should return a basic bootstrap badge" do
13
- expect(badge('test').gsub(/\s/, '').downcase)
13
+ expect(badge('New!').gsub(/\s/, '').downcase)
14
14
  .to eql(BASIC_BADGE.gsub(/\s/, '').downcase)
15
15
  end
16
16
 
17
17
  it "should return a bootstrap badge with class" do
18
- expect(badge('waning', :warning).gsub(/\s/, '').downcase)
18
+ expect(badge('2', :warning).gsub(/\s/, '').downcase)
19
19
  .to eql(BADGE_WITH_CLASS.gsub(/\s/, '').downcase)
20
20
  end
21
+
22
+ it "should take a Number as its first parameter" do
23
+ expect(badge(12).gsub(/\s/, '').downcase)
24
+ .to eql(BADGE_WITH_NUMBER_PARAM.gsub(/\s/, '').downcase)
25
+ end
21
26
  end
22
27
 
23
- BASIC_BADGE = %{<span class="badge">test</span>}
24
- BADGE_WITH_CLASS = %{<span class="badge badge-warning">waning</span>}
28
+ BASIC_BADGE = %{<span class="badge">New!</span>}
29
+ BADGE_WITH_CLASS = %{<span class="badge badge-warning">2</span>}
30
+ BADGE_WITH_NUMBER_PARAM = %{<span class="badge">12</span>}
@@ -0,0 +1,128 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'action_view'
4
+ require 'active_support'
5
+ require_relative '../../../app/helpers/bootstrap_flash_helper'
6
+
7
+ include ActionView::Helpers
8
+ include ActionView::Context
9
+ include BootstrapFlashHelper
10
+
11
+ describe BootstrapFlashHelper, type: :helper do
12
+ before do
13
+ allow(self).to receive(:uri_state) { :inactive }
14
+ allow(self).to receive(:root_url) { '/' }
15
+ end
16
+
17
+ describe "bootstrap_flash" do
18
+ it "should not return anything without flashes" do
19
+ allow(self).to receive(:flash) { {} }
20
+
21
+ element = bootstrap_flash
22
+
23
+ expect(element).to eql("")
24
+ end
25
+
26
+ it "should work with a notice" do
27
+ allow(self).to receive(:flash) { {notice: "Hello"} }
28
+
29
+ element = bootstrap_flash
30
+
31
+ expect(element).to have_tag(:div,
32
+ text: "×Hello",
33
+ with: {class: "alert fade in alert-success"}) {
34
+
35
+ with_tag(:button,
36
+ text: "×",
37
+ with: {
38
+ class: "close",
39
+ "data-dismiss" => "alert"
40
+ }
41
+ )
42
+
43
+ }
44
+ end
45
+
46
+ it "should work with a notice and an extra class" do
47
+ allow(self).to receive(:flash) { {notice: "Hello"} }
48
+
49
+ element = bootstrap_flash(class: "extra-class")
50
+
51
+ expect(element).to have_tag(:div,
52
+ text: "×Hello",
53
+ with: {class: "alert fade in alert-success extra-class"}) {
54
+
55
+ with_tag(:button,
56
+ text: "×",
57
+ with: {
58
+ class: "close",
59
+ "data-dismiss" => "alert"
60
+ }
61
+ )
62
+
63
+ }
64
+ end
65
+
66
+ it "should work with a notice and an extra class and an extra attribute" do
67
+ allow(self).to receive(:flash) { {notice: "Hello"} }
68
+
69
+ element = bootstrap_flash(class: "extra-class", "data-no-transition-cache" => true)
70
+
71
+ expect(element).to have_tag(:div,
72
+ text: "×Hello",
73
+ with: {
74
+ class: "alert fade in alert-success extra-class",
75
+ "data-no-transition-cache" => true
76
+ }) {
77
+
78
+ with_tag(:button,
79
+ text: "×",
80
+ with: {
81
+ class: "close",
82
+ "data-dismiss" => "alert"
83
+ }
84
+ )
85
+
86
+ }
87
+ end
88
+
89
+ it "should escape javascript if not marked as safe by user" do
90
+ allow(self).to receive(:flash) { {notice: "<script>alert(1)</script>"} }
91
+
92
+ element = bootstrap_flash
93
+
94
+ expect(element).to have_tag(:div,
95
+ text: "×<script>alert(1)</script>",
96
+ with: {class: "alert fade in alert-success"}) {
97
+ with_tag(:button,
98
+ text: "×",
99
+ with: {
100
+ class: "close",
101
+ "data-dismiss" => "alert"
102
+ }
103
+ )
104
+ }
105
+ end
106
+
107
+ it "should not escape a link if marked as safe by user" do
108
+ allow(self).to receive(:flash) { {notice: "<a href='example.com'>awesome link!</a>".html_safe} }
109
+
110
+ element = bootstrap_flash
111
+
112
+ expect(element).to have_tag(:div,
113
+ text: "×awesome link!",
114
+ with: {class: "alert fade in alert-success"}) { [
115
+ with_tag(:button,
116
+ text: "×",
117
+ with: {
118
+ class: "close",
119
+ "data-dismiss" => "alert"
120
+ }
121
+ ),
122
+ with_tag(:a,
123
+ text: 'awesome link!')
124
+ ]
125
+ }
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,148 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'action_view'
4
+ require 'active_support'
5
+ require 'rspec/active_model/mocks'
6
+
7
+ require_relative '../../../app/helpers/form_errors_helper'
8
+
9
+ include ActionView::Helpers
10
+ include ActionView::Context
11
+ include FormErrorsHelper
12
+
13
+ describe FormErrorsHelper, :type => :helper do
14
+
15
+ before do
16
+ @base_errors = ['base error message', 'nasty error']
17
+ @base_error = 'one base error'
18
+
19
+
20
+ @title_errors = ["can't be blank", 'is too short (minimum is 5 characters)']
21
+ @title_error = "can't be blank"
22
+
23
+ @errors = double('errors')
24
+ @new_post = mock_model( 'Post' )
25
+ allow(@new_post).to receive_messages(:errors => @errors)
26
+ allow(self).to receive_messages(:post_path => '/post/1')
27
+ allow(self).to receive_messages(:protect_against_forgery? => false)
28
+ allow(self).to receive_messages(:polymorphic_path => '')
29
+
30
+ @default_class = 'help-block'
31
+ @default_error_class = 'has-error'
32
+ end
33
+
34
+
35
+ describe 'error[:base] is a string' do
36
+
37
+ before do
38
+ allow(@errors).to receive(:[]).with(:base).and_return(@base_error)
39
+ end
40
+
41
+ it 'should render base error on :base key' do
42
+ form_for(@new_post) do |builder|
43
+ expect(builder.error_span(:base)).to have_tag("div.#{@default_error_class}") do
44
+ with_tag("span.#{@default_class}", :text => @base_error)
45
+ end
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+
52
+ describe 'when there is only one error on base' do
53
+
54
+ before do
55
+ allow(@errors).to receive(:[]).with(:base).and_return(@base_error)
56
+ end
57
+
58
+ it 'should render base error on :base key' do
59
+ form_for(@new_post) do |builder|
60
+ expect(builder.error_span(:base)).to have_tag("div.#{@default_error_class}") do
61
+ with_tag("span.#{@default_class}", :text => @base_error)
62
+ end
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ describe 'when there is only one error on title' do
69
+
70
+ before do
71
+ allow(@errors).to receive(:[]).with(:title).and_return(@title_error)
72
+ end
73
+
74
+ it 'should render base errors join with comma' do
75
+ form_for(@new_post) do |builder|
76
+ expect(builder.error_span(:title)).to have_tag("div.#{@default_error_class}") do
77
+ with_tag("span.#{@default_class}", :text => @title_error)
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+
84
+
85
+ describe 'when there is more than one error on title' do
86
+
87
+ before do
88
+ allow(@errors).to receive(:[]).with(:title).and_return(@title_errors)
89
+ end
90
+
91
+ it 'should render base errors join with comma' do
92
+ form_for(@new_post) do |builder|
93
+ expect(builder.error_span(:title)).to have_tag("div.#{@default_error_class}") do
94
+ with_tag("span.#{@default_class}", :text => @title_errors.join(', '))
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+
101
+ describe 'when there are no errors' do
102
+ before do
103
+ allow(@errors).to receive(:[]).with(:title).and_return(nil)
104
+ end
105
+
106
+ it 'should return nil' do
107
+ form_for(@new_post) do |builder|
108
+ expect(builder.error_span(:title)).to be_nil
109
+ end
110
+ end
111
+ end
112
+
113
+ describe 'when :error_class option is passed' do
114
+ let(:error_class) { 'has_warning' }
115
+
116
+ before do
117
+ allow(@errors).to receive(:[]).with(:title).and_return(@title_error)
118
+ end
119
+
120
+ it "should render with passed error class " do
121
+ form_for(@new_post) do |builder|
122
+ expect(builder.error_span(:title, :error_class => error_class))
123
+ .to have_tag("div.#{error_class}") do
124
+ with_tag("span.#{@default_class}", :text => @title_error)
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ describe 'when :error_class option is passed' do
131
+ let(:span_class) { 'help-inline' }
132
+
133
+ before do
134
+ allow(@errors).to receive(:[]).with(:title).and_return(@title_error)
135
+ end
136
+
137
+ it "should render with passed error class " do
138
+ form_for(@new_post) do |builder|
139
+ expect(builder.error_span(:title, :span_class => span_class))
140
+ .to have_tag("div.#{@default_error_class}") do
141
+ with_tag("span.#{span_class}", :text => @title_error)
142
+ end
143
+ end
144
+ end
145
+
146
+ end
147
+
148
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'action_view'
4
+ require 'active_support'
5
+ require_relative '../../../app/helpers/glyph_helper'
6
+
7
+ include ActionView::Helpers
8
+ include ActionView::Context
9
+ include GlyphHelper
10
+
11
+ describe GlyphHelper, :type => :helper do
12
+ it "should return a basic bootstrap glyph" do
13
+ expect(glyph(:thumbs_up).gsub(/\s/, '').downcase)
14
+ .to eql(BASIC_GLYPH.gsub(/\s/, '').downcase)
15
+ end
16
+
17
+ it "should return a bootstrap glyph with span" do
18
+ expect(glyph(:thumbs_up, {:tag => :span}).gsub(/\s/, '').downcase)
19
+ .to eql(GLYPH_WITH_SPAN.gsub(/\s/, '').downcase)
20
+ end
21
+ end
22
+
23
+ BASIC_GLYPH = %{<iclass=\"glyphiconglyphicon-thumbs-up\"></i>}
24
+ GLYPH_WITH_SPAN = %{<spanclass=\"glyphiconglyphicon-thumbs-up\"></span>}
@@ -36,12 +36,12 @@ describe ModalHelper, :type => :helper do
36
36
  end
37
37
 
38
38
  it 'renders a cancel button' do
39
- expect(modal_cancel_button("Cancel", :href => "#modal", :data => {:dismiss => 'modal'}).gsub(/\n/, "")).to eql MODAL_CANCEL_BUTTON.gsub(/\n/, "")
39
+ expect(modal_cancel_button("Cancel", :data => {:dismiss => 'modal'}, :href => "#modal").gsub(/\n/, "")).to eql MODAL_CANCEL_BUTTON.gsub(/\n/, "")
40
40
  end
41
41
  end
42
42
 
43
43
  BASIC_MODAL = <<-HTML
44
- <div class=\"bootstrap-modal modal fade\" id=\"modal\"><div class=\"modal-dialog \"><div class=\"modal-content\"><div class=\"modal-header\"><button class=\"close\" data-dismiss=\"true\" aria-hidden=\"true\">&times;</button><h4 class=\"modal-title\"></h4></div><div class=\"modal-body\"></div><div class=\"modal-footer\"></div></div></div></div>
44
+ <div class=\"bootstrap-modal modal fade\" id=\"modal\"><div class=\"modal-dialog \"><div class=\"modal-content\"><div class=\"modal-header\"><button class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button><h4 class=\"modal-title\">Modal header</h4></div><div class=\"modal-body\">This is the body</div><div class=\"modal-footer\"><button class="btn">Save</button></div></div></div></div>
45
45
  HTML
46
46
 
47
47
  MODAL_HEADER_WITHOUT_CLOSE = <<-HTML
@@ -82,44 +82,94 @@ describe NavbarHelper, :type => :helper do
82
82
 
83
83
  describe "menu_group" do
84
84
  it "should return a ul with the class 'nav'" do
85
- ele = menu_group do
85
+ element = menu_group do
86
86
  menu_item("Home", "/") + menu_item("Products", "/products")
87
87
  end
88
- expect(ele).to eql '<ul class="nav navbar-nav "><li><a href="/">Home</a></li><li><a href="/products">Products</a></li></ul>'
88
+
89
+ expect(element).to have_tag(:ul, with: {class: "nav navbar-nav"}) {
90
+ with_tag(:li) {
91
+ with_tag(:a, text: "Home", with: {href: "/"})
92
+ }
93
+ with_tag(:li) {
94
+ with_tag(:a, text: "Products", with: {href: "/products"})
95
+ }
96
+ }
89
97
  end
90
98
 
91
- it "should return a ul with class .navbar-left when passed the {:pull => :left} option" do
92
- ele = menu_group(:pull => :left) do
99
+ it "should return a ul with class .navbar-left when passed the {pull: :left} option" do
100
+ element = menu_group(pull: :left) do
93
101
  menu_item("Home", "/")
94
102
  end
95
- expect(ele).to eql('<ul class="nav navbar-nav navbar-left"><li><a href="/">Home</a></li></ul>')
103
+
104
+ expect(element).to have_tag(:ul, with: {class: "nav navbar-nav navbar-left"}) {
105
+ with_tag(:li) {
106
+ with_tag(:a, text: "Home", with: {href: "/"})
107
+ }
108
+ }
96
109
  end
97
110
  end
98
111
 
99
112
  describe "menu_item" do
100
113
  it "should return a link within an li tag" do
101
114
  allow(self).to receive(:current_page?) { false }
102
- expect(menu_item("Home", "/")).to eql('<li><a href="/">Home</a></li>')
115
+
116
+ element = menu_item("Home", "/")
117
+ expect(element).to have_tag(:li) {
118
+ with_tag(:a, text: "Home", with: { href: "/" })
119
+ }
103
120
  end
121
+
104
122
  it "should return the link with class 'active' if on current page" do
105
123
  allow(self).to receive(:uri_state) { :active }
106
- expect(menu_item("Home", "/")).to eql('<li class="active"><a href="/">Home</a></li>')
124
+
125
+ element = menu_item("Home", "/")
126
+ expect(element).to have_tag(:li, with: {class: "active"}) {
127
+ with_tag(:a, text: "Home", with: { href: "/" })
128
+ }
107
129
  end
130
+
108
131
  it "should pass any other options through to the link_to method" do
109
- self.stub("uri_state").and_return(:active)
110
- expect(menu_item("Log out", "/users/sign_out", :class => "home_link", :method => :delete)).to eql('<li class="active"><a class="home_link" data-method="delete" href="/users/sign_out" rel="nofollow">Log out</a></li>')
132
+ allow(self).to receive_message_chain("uri_state").and_return(:active)
133
+
134
+ element = menu_item("Log out", "/users/sign_out", class: "home_link", method: :delete)
135
+ expect(element).to have_tag(:li, with: {class: "active"}) {
136
+ with_tag(:a, text: "Log out", with: {
137
+ href: "/users/sign_out",
138
+ class: "home_link",
139
+ rel: "nofollow",
140
+ "data-method" => "delete"
141
+ })
142
+ }
111
143
  end
144
+
112
145
  it "should pass a block but no name if a block is present" do
113
146
  allow(self).to receive(:current_page?) { false }
114
- expect(menu_item("/"){content_tag("i", "", :class => "icon-home") + " Home"}).to eql('<li><a href="/"><i class="icon-home"></i> Home</a></li>')
147
+
148
+ element = menu_item("/"){ content_tag("i", "", :class => "icon-home") + " Home" }
149
+ expect(element).to have_tag(:li) {
150
+ with_tag(:i, with: { class: "icon-home"})
151
+ with_tag(:a, text: " Home", with: { href: "/"})
152
+ }
115
153
  end
154
+
116
155
  it "should work with just a block" do
117
156
  allow(self).to receive(:current_page?) { false }
118
- expect(menu_item{ content_tag("i", "", :class => "icon-home") + " Home" }).to eql('<li><a href="#"><i class="icon-home"></i> Home</a></li>')
157
+
158
+ element = menu_item{ content_tag("i", "", :class => "icon-home") + " Home" }
159
+ expect(element).to have_tag(:li) {
160
+ with_tag(:i, with: { class: "icon-home"})
161
+ with_tag(:a, text: " Home", with: { href: "#"})
162
+ }
119
163
  end
164
+
120
165
  it "should return the link with class 'active' if on current page with a block" do
121
166
  allow(self).to receive(:uri_state) { :active }
122
- expect(menu_item("/"){ content_tag("i", "", :class => "icon-home") + " Home" }).to eql('<li class="active"><a href="/"><i class="icon-home"></i> Home</a></li>')
167
+
168
+ element = menu_item("/"){ content_tag("i", "", :class => "icon-home") + " Home" }
169
+ expect(element).to have_tag(:li, with: {class: "active"}) {
170
+ with_tag(:i, with: { class: "icon-home"})
171
+ with_tag(:a, text: " Home", with: { href: "/"})
172
+ }
123
173
  end
124
174
  end
125
175
 
data/spec/spec_helper.rb CHANGED
@@ -14,4 +14,8 @@ require 'twitter-bootstrap-rails'
14
14
  require 'abstract_controller'
15
15
  require 'action_controller'
16
16
  require 'mocha/api'
17
- require 'pry'
17
+ require 'pry'
18
+
19
+ RSpec.configure do |config|
20
+ config.include RSpecHtmlMatchers
21
+ end