twitter-bootstrap-rails 2.2.3 → 3.2.2

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 (204) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +460 -185
  3. data/Rakefile +7 -1
  4. data/app/assets/fonts/fontawesome-webfont.eot +0 -0
  5. data/app/assets/fonts/fontawesome-webfont.svg +640 -0
  6. data/app/assets/fonts/fontawesome-webfont.ttf +0 -0
  7. data/app/assets/fonts/fontawesome-webfont.woff +0 -0
  8. data/app/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  9. data/app/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  10. data/app/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  11. data/app/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  12. data/app/assets/javascripts/twitter/bootstrap.js +12 -0
  13. data/app/assets/javascripts/twitter/bootstrap/affix.js +142 -0
  14. data/app/assets/javascripts/twitter/bootstrap/alert.js +92 -0
  15. data/app/assets/javascripts/twitter/bootstrap/button.js +110 -0
  16. data/app/assets/javascripts/twitter/bootstrap/carousel.js +223 -0
  17. data/app/assets/javascripts/twitter/bootstrap/collapse.js +170 -0
  18. data/app/assets/javascripts/twitter/bootstrap/dropdown.js +151 -0
  19. data/app/assets/javascripts/twitter/bootstrap/modal.js +280 -0
  20. data/app/assets/javascripts/twitter/bootstrap/popover.js +113 -0
  21. data/app/assets/javascripts/twitter/bootstrap/scrollspy.js +170 -0
  22. data/app/assets/javascripts/twitter/bootstrap/tab.js +128 -0
  23. data/app/assets/javascripts/twitter/bootstrap/tooltip.js +457 -0
  24. data/app/assets/javascripts/twitter/bootstrap/transition.js +59 -0
  25. data/{vendor → app}/assets/javascripts/twitter/bootstrap_ujs.js +0 -0
  26. data/app/assets/stylesheets/twitter-bootstrap-static/bootstrap.css.erb +1 -0
  27. data/app/assets/stylesheets/twitter-bootstrap-static/fontawesome.css.erb +2026 -0
  28. data/app/assets/stylesheets/twitter-bootstrap-static/sprites.css.erb +1 -0
  29. data/app/helpers/badge_label_helper.rb +16 -0
  30. data/app/helpers/bootstrap_flash_helper.rb +20 -6
  31. data/app/helpers/form_errors_helper.rb +22 -0
  32. data/app/helpers/glyph_helper.rb +13 -5
  33. data/app/helpers/modal_helper.rb +37 -20
  34. data/app/helpers/navbar_helper.rb +209 -0
  35. data/app/helpers/twitter_breadcrumbs_helper.rb +11 -2
  36. data/app/views/twitter-bootstrap/_breadcrumbs.html.erb +9 -9
  37. data/lib/generators/bootstrap/install/install_generator.rb +13 -8
  38. data/lib/generators/bootstrap/install/templates/bootstrap.coffee +2 -3
  39. data/lib/generators/bootstrap/install/templates/bootstrap.js +2 -3
  40. data/lib/generators/bootstrap/install/templates/bootstrap_and_overrides.less +14 -13
  41. data/lib/generators/bootstrap/install/templates/en.bootstrap.yml +11 -5
  42. data/lib/generators/bootstrap/layout/layout_generator.rb +1 -4
  43. data/lib/generators/bootstrap/layout/templates/layout.html.erb +34 -58
  44. data/lib/generators/bootstrap/layout/templates/layout.html.haml +25 -44
  45. data/lib/generators/bootstrap/layout/templates/layout.html.slim +20 -39
  46. data/lib/generators/bootstrap/partial/templates/_login.html.erb +2 -3
  47. data/lib/generators/bootstrap/themed/templates/_form.html.erb +30 -10
  48. data/lib/generators/bootstrap/themed/templates/_form.html.haml +10 -8
  49. data/lib/generators/bootstrap/themed/templates/_form.html.slim +11 -9
  50. data/lib/generators/bootstrap/themed/templates/edit.html.erb +1 -2
  51. data/lib/generators/bootstrap/themed/templates/edit.html.haml +1 -1
  52. data/lib/generators/bootstrap/themed/templates/edit.html.slim +2 -2
  53. data/lib/generators/bootstrap/themed/templates/index.html.erb +3 -3
  54. data/lib/generators/bootstrap/themed/templates/index.html.haml +3 -3
  55. data/lib/generators/bootstrap/themed/templates/index.html.slim +5 -6
  56. data/lib/generators/bootstrap/themed/templates/new.html.erb +1 -2
  57. data/lib/generators/bootstrap/themed/templates/new.html.haml +1 -1
  58. data/lib/generators/bootstrap/themed/templates/new.html.slim +2 -2
  59. data/lib/generators/bootstrap/themed/templates/show.html.erb +6 -8
  60. data/lib/generators/bootstrap/themed/templates/show.html.haml +5 -5
  61. data/lib/generators/bootstrap/themed/templates/show.html.slim +7 -8
  62. data/lib/generators/bootstrap/themed/templates/simple_form/_form.html.erb +5 -5
  63. data/lib/generators/bootstrap/themed/templates/simple_form/_form.html.haml +3 -3
  64. data/lib/generators/bootstrap/themed/templates/simple_form/_form.html.slim +4 -4
  65. data/lib/generators/bootstrap/themed/themed_generator.rb +4 -4
  66. data/lib/twitter-bootstrap-rails.rb +4 -4
  67. data/lib/twitter/bootstrap/rails/breadcrumbs.rb +69 -0
  68. data/lib/twitter/bootstrap/rails/engine.rb +17 -7
  69. data/lib/twitter/bootstrap/rails/version.rb +1 -1
  70. data/spec/lib/breadcrumbs_spec.rb +99 -0
  71. data/spec/lib/twitter_bootstrap_rails/badge_label_helper_spec.rb +30 -0
  72. data/spec/lib/twitter_bootstrap_rails/bootstrap_flash_helper_spec.rb +128 -0
  73. data/spec/lib/twitter_bootstrap_rails/form_errors_helper_spec.rb +148 -0
  74. data/spec/lib/twitter_bootstrap_rails/glyph_helper_spec.rb +24 -0
  75. data/spec/lib/twitter_bootstrap_rails/modal_helper_spec.rb +62 -0
  76. data/spec/lib/twitter_bootstrap_rails/navbar_helper_spec.rb +396 -0
  77. data/spec/lib/twitter_bootstrap_rails/uri_state_spec.rb +49 -0
  78. data/spec/spec_helper.rb +21 -0
  79. data/vendor/assets/stylesheets/twitter-bootstrap-static/bootstrap.css.erb +5990 -195
  80. data/vendor/static-source/bootstrap.less +0 -1
  81. data/vendor/static-source/fontawesome.less +7 -6
  82. data/vendor/static-source/sprites.less +3 -3
  83. data/vendor/toolkit/fontawesome/bordered-pulled.less +16 -0
  84. data/vendor/toolkit/fontawesome/core.less +11 -0
  85. data/vendor/toolkit/fontawesome/fixed-width.less +6 -0
  86. data/vendor/toolkit/fontawesome/font-awesome.less +17 -0
  87. data/vendor/toolkit/fontawesome/icons.less +552 -0
  88. data/vendor/toolkit/fontawesome/larger.less +13 -0
  89. data/vendor/toolkit/fontawesome/list.less +19 -0
  90. data/vendor/toolkit/fontawesome/mixins.less +25 -0
  91. data/vendor/toolkit/fontawesome/path.less +14 -0
  92. data/vendor/toolkit/fontawesome/rotated-flipped.less +20 -0
  93. data/vendor/toolkit/fontawesome/spinning.less +29 -0
  94. data/vendor/toolkit/fontawesome/stacked.less +20 -0
  95. data/vendor/toolkit/fontawesome/variables.less +561 -0
  96. data/vendor/toolkit/twitter/bootstrap/alerts.less +47 -58
  97. data/vendor/toolkit/twitter/bootstrap/badges.less +55 -0
  98. data/vendor/toolkit/twitter/bootstrap/bootstrap.less +26 -39
  99. data/vendor/toolkit/twitter/bootstrap/breadcrumbs.less +11 -9
  100. data/vendor/toolkit/twitter/bootstrap/button-groups.less +168 -152
  101. data/vendor/toolkit/twitter/bootstrap/buttons.less +101 -170
  102. data/vendor/toolkit/twitter/bootstrap/carousel.less +150 -65
  103. data/vendor/toolkit/twitter/bootstrap/close.less +20 -19
  104. data/vendor/toolkit/twitter/bootstrap/code.less +38 -30
  105. data/vendor/toolkit/twitter/bootstrap/component-animations.less +12 -3
  106. data/vendor/toolkit/twitter/bootstrap/dropdowns.less +124 -146
  107. data/vendor/toolkit/twitter/bootstrap/forms.less +401 -547
  108. data/vendor/toolkit/twitter/bootstrap/glyphicons.less +234 -0
  109. data/vendor/toolkit/twitter/bootstrap/grid.less +74 -11
  110. data/vendor/toolkit/twitter/bootstrap/input-groups.less +166 -0
  111. data/vendor/toolkit/twitter/bootstrap/jumbotron.less +48 -0
  112. data/vendor/toolkit/twitter/bootstrap/labels.less +64 -0
  113. data/vendor/toolkit/twitter/bootstrap/list-group.less +132 -0
  114. data/vendor/toolkit/twitter/bootstrap/media.less +8 -7
  115. data/vendor/toolkit/twitter/bootstrap/mixins.less +36 -699
  116. data/vendor/toolkit/twitter/bootstrap/mixins/alerts.less +14 -0
  117. data/vendor/toolkit/twitter/bootstrap/mixins/background-variant.less +8 -0
  118. data/vendor/toolkit/twitter/bootstrap/mixins/border-radius.less +18 -0
  119. data/vendor/toolkit/twitter/bootstrap/mixins/buttons.less +52 -0
  120. data/vendor/toolkit/twitter/bootstrap/mixins/center-block.less +7 -0
  121. data/vendor/toolkit/twitter/bootstrap/mixins/clearfix.less +22 -0
  122. data/vendor/toolkit/twitter/bootstrap/mixins/forms.less +85 -0
  123. data/vendor/toolkit/twitter/bootstrap/mixins/gradients.less +59 -0
  124. data/vendor/toolkit/twitter/bootstrap/mixins/grid-framework.less +91 -0
  125. data/vendor/toolkit/twitter/bootstrap/mixins/grid.less +122 -0
  126. data/vendor/toolkit/twitter/bootstrap/mixins/hide-text.less +21 -0
  127. data/vendor/toolkit/twitter/bootstrap/mixins/image.less +33 -0
  128. data/vendor/toolkit/twitter/bootstrap/mixins/labels.less +12 -0
  129. data/vendor/toolkit/twitter/bootstrap/mixins/list-group.less +29 -0
  130. data/vendor/toolkit/twitter/bootstrap/mixins/nav-divider.less +10 -0
  131. data/vendor/toolkit/twitter/bootstrap/mixins/nav-vertical-align.less +9 -0
  132. data/vendor/toolkit/twitter/bootstrap/mixins/opacity.less +8 -0
  133. data/vendor/toolkit/twitter/bootstrap/mixins/pagination.less +23 -0
  134. data/vendor/toolkit/twitter/bootstrap/mixins/panels.less +24 -0
  135. data/vendor/toolkit/twitter/bootstrap/mixins/progress-bar.less +10 -0
  136. data/vendor/toolkit/twitter/bootstrap/mixins/reset-filter.less +8 -0
  137. data/vendor/toolkit/twitter/bootstrap/mixins/resize.less +6 -0
  138. data/vendor/toolkit/twitter/bootstrap/mixins/responsive-visibility.less +15 -0
  139. data/vendor/toolkit/twitter/bootstrap/mixins/size.less +10 -0
  140. data/vendor/toolkit/twitter/bootstrap/mixins/tab-focus.less +9 -0
  141. data/vendor/toolkit/twitter/bootstrap/mixins/table-row.less +28 -0
  142. data/vendor/toolkit/twitter/bootstrap/mixins/text-emphasis.less +8 -0
  143. data/vendor/toolkit/twitter/bootstrap/mixins/text-overflow.less +8 -0
  144. data/vendor/toolkit/twitter/bootstrap/mixins/vendor-prefixes.less +224 -0
  145. data/vendor/toolkit/twitter/bootstrap/modals.less +109 -54
  146. data/vendor/toolkit/twitter/bootstrap/navbar.less +542 -384
  147. data/vendor/toolkit/twitter/bootstrap/navs.less +192 -359
  148. data/vendor/toolkit/twitter/bootstrap/normalize.less +425 -0
  149. data/vendor/toolkit/twitter/bootstrap/pager.less +46 -34
  150. data/vendor/toolkit/twitter/bootstrap/pagination.less +70 -105
  151. data/vendor/toolkit/twitter/bootstrap/panels.less +248 -0
  152. data/vendor/toolkit/twitter/bootstrap/popovers.less +61 -61
  153. data/vendor/toolkit/twitter/bootstrap/print.less +101 -0
  154. data/vendor/toolkit/twitter/bootstrap/progress-bars.less +51 -73
  155. data/vendor/toolkit/twitter/bootstrap/responsive-embed.less +34 -0
  156. data/vendor/toolkit/twitter/bootstrap/responsive-utilities.less +177 -42
  157. data/vendor/toolkit/twitter/bootstrap/scaffolding.less +120 -23
  158. data/vendor/toolkit/twitter/bootstrap/tables.less +171 -182
  159. data/vendor/toolkit/twitter/bootstrap/theme.less +260 -0
  160. data/vendor/toolkit/twitter/bootstrap/thumbnails.less +26 -43
  161. data/vendor/toolkit/twitter/bootstrap/tooltip.less +49 -24
  162. data/vendor/toolkit/twitter/bootstrap/type.less +208 -147
  163. data/vendor/toolkit/twitter/bootstrap/utilities.less +33 -7
  164. data/vendor/toolkit/twitter/bootstrap/variables.less +761 -215
  165. data/vendor/toolkit/twitter/bootstrap/wells.less +7 -7
  166. metadata +199 -92
  167. data/lib/generators/bootstrap/partial/templates/_navbar.html.erb +0 -13
  168. data/lib/twitter/bootstrap/rails/twitter-bootstrap-breadcrumbs.rb +0 -42
  169. data/test/lib/breadcrumbs_test.rb +0 -75
  170. data/test/test_helper.rb +0 -8
  171. data/vendor/assets/fonts/fontawesome-webfont.eot +0 -0
  172. data/vendor/assets/fonts/fontawesome-webfont.ttf +0 -0
  173. data/vendor/assets/fonts/fontawesome-webfont.woff +0 -0
  174. data/vendor/assets/images/twitter/bootstrap/glyphicons-halflings-white.png +0 -0
  175. data/vendor/assets/images/twitter/bootstrap/glyphicons-halflings.png +0 -0
  176. data/vendor/assets/javascripts/twitter/bootstrap.js +0 -13
  177. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-affix.js +0 -117
  178. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-alert.js +0 -99
  179. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-button.js +0 -105
  180. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-carousel.js +0 -207
  181. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-collapse.js +0 -167
  182. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-dropdown.js +0 -165
  183. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-modal.js +0 -247
  184. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-popover.js +0 -114
  185. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-scrollspy.js +0 -162
  186. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-tab.js +0 -144
  187. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-tooltip.js +0 -353
  188. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-transition.js +0 -60
  189. data/vendor/assets/javascripts/twitter/bootstrap/bootstrap-typeahead.js +0 -335
  190. data/vendor/assets/stylesheets/twitter-bootstrap-static/fontawesome.css.erb +0 -531
  191. data/vendor/assets/stylesheets/twitter-bootstrap-static/sprites.css.erb +0 -146
  192. data/vendor/toolkit/fontawesome-ie7.less +0 -350
  193. data/vendor/toolkit/fontawesome.less +0 -532
  194. data/vendor/toolkit/twitter/bootstrap/accordion.less +0 -34
  195. data/vendor/toolkit/twitter/bootstrap/hero-unit.less +0 -25
  196. data/vendor/toolkit/twitter/bootstrap/labels-badges.less +0 -84
  197. data/vendor/toolkit/twitter/bootstrap/layouts.less +0 -16
  198. data/vendor/toolkit/twitter/bootstrap/reset.less +0 -216
  199. data/vendor/toolkit/twitter/bootstrap/responsive-1200px-min.less +0 -28
  200. data/vendor/toolkit/twitter/bootstrap/responsive-767px-max.less +0 -193
  201. data/vendor/toolkit/twitter/bootstrap/responsive-768px-979px.less +0 -19
  202. data/vendor/toolkit/twitter/bootstrap/responsive-navbar.less +0 -189
  203. data/vendor/toolkit/twitter/bootstrap/responsive.less +0 -48
  204. data/vendor/toolkit/twitter/bootstrap/sprites.less +0 -197
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe Twitter::Bootstrap::Breadcrumbs do
4
+ class TestModel
5
+ include ActiveModel::Model
6
+
7
+ def to_s
8
+ "test_model"
9
+ end
10
+ end
11
+
12
+ class BaseTestController < AbstractController::Base
13
+ include Twitter::Bootstrap::Breadcrumbs
14
+ include AbstractController::Callbacks
15
+ include AbstractController::UrlFor
16
+
17
+ add_breadcrumb 'base', '/base'
18
+ add_breadcrumb :base_i18n, '/base_i18n'
19
+
20
+ def breadcrumbs
21
+ @__bs_breadcrumbs
22
+ end
23
+ end
24
+
25
+ class TestController < BaseTestController
26
+ add_breadcrumb 'class', '/class'
27
+ add_breadcrumb :class_i18n, '/class_i18n'
28
+
29
+ def show
30
+ add_breadcrumb 'instance', '/instance'
31
+ add_breadcrumb :instance_i18n, '/instance_i18n'
32
+
33
+ test_model = TestModel.new
34
+ add_breadcrumb test_model
35
+
36
+ add_breadcrumb :symbolized
37
+ add_breadcrumb :show
38
+ end
39
+
40
+ def symbolized_path
41
+ '/symbolized'
42
+ end
43
+
44
+ def test_models_path
45
+ '/test_model'
46
+ end
47
+ end
48
+
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)
63
+ end
64
+
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
71
+
72
+ idx = @controller.breadcrumbs.index { |b| b[:name] == "show" && b[:url] == '' }
73
+ expect(idx).to be
74
+ end
75
+ end
76
+
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
95
+ end
96
+
97
+ end
98
+
99
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'action_view'
4
+ require 'active_support'
5
+ require_relative '../../../app/helpers/badge_label_helper'
6
+
7
+ include ActionView::Helpers
8
+ include ActionView::Context
9
+ include BadgeLabelHelper
10
+
11
+ describe BadgeLabelHelper, :type => :helper do
12
+ it "should return a basic bootstrap badge" do
13
+ expect(badge('New!').gsub(/\s/, '').downcase)
14
+ .to eql(BASIC_BADGE.gsub(/\s/, '').downcase)
15
+ end
16
+
17
+ it "should return a bootstrap badge with class" do
18
+ expect(badge('2', :warning).gsub(/\s/, '').downcase)
19
+ .to eql(BADGE_WITH_CLASS.gsub(/\s/, '').downcase)
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
26
+ end
27
+
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>}
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require_relative '../../../app/helpers/modal_helper'
4
+
5
+ include ActionView::Helpers
6
+ include ActionView::Context
7
+ include ModalHelper
8
+
9
+ describe ModalHelper, :type => :helper do
10
+ header_with_close = { :show_close => true, :dismiss => 'modal', :title => 'Modal header' }
11
+ header_without_close = { :show_close => false, :title => 'Modal header' }
12
+ options = { :id => "modal",
13
+ :header => header_with_close,
14
+ :body => { content: 'This is the body' },
15
+ :footer => { content: content_tag(:button, 'Save', :class => 'btn') }
16
+ }
17
+
18
+ it 'returns a complete modal' do
19
+ expect(modal_dialog(options).gsub(/\n/, "")).to eql BASIC_MODAL.gsub(/\n/, "")
20
+ end
21
+
22
+ it 'returns a modal header with a close button if show_close is true' do
23
+ expect(modal_header(header_with_close).gsub(/\n/, "")).to eql MODAL_HEADER_WITH_CLOSE.gsub(/\n/, "")
24
+ end
25
+
26
+ it 'renders a modal header without a close button' do
27
+ expect(modal_header(header_without_close).gsub(/\n/, "")).to eql MODAL_HEADER_WITHOUT_CLOSE.gsub(/\n/, "")
28
+ end
29
+
30
+ it 'renders a close button' do
31
+ expect(close_button('modal')).to eql "<button class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>"
32
+ end
33
+
34
+ it 'renders a modal toggle button' do
35
+ expect(modal_toggle('Save', :href => "#modal").gsub(/\n/, "")).to eql MODAL_TOGGLE.gsub(/\n/, "")
36
+ end
37
+
38
+ it 'renders a cancel button' do
39
+ expect(modal_cancel_button("Cancel", :data => {:dismiss => 'modal'}, :href => "#modal").gsub(/\n/, "")).to eql MODAL_CANCEL_BUTTON.gsub(/\n/, "")
40
+ end
41
+ end
42
+
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=\"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
+ HTML
46
+
47
+ MODAL_HEADER_WITHOUT_CLOSE = <<-HTML
48
+ <div class="modal-header"><h4 class=\"modal-title\">Modal header</h4></div>
49
+ HTML
50
+
51
+ MODAL_HEADER_WITH_CLOSE = <<-HTML
52
+ <div class="modal-header"><button class="close" data-dismiss="modal" aria-hidden=\"true\">&times;</button><h4 class=\"modal-title\">Modal header</h4></div>
53
+ HTML
54
+
55
+ MODAL_TOGGLE = <<-HTML
56
+ <a class="btn btn-default" data-toggle="modal" href="#modal">Save</a>
57
+ HTML
58
+
59
+ MODAL_CANCEL_BUTTON = <<-HTML
60
+ <a class="btn bootstrap-modal-cancel-button" data-dismiss="modal" href="#modal">Cancel</a>
61
+ HTML
62
+