booter 0.3.1 → 1.0.0.rc1

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 (61) hide show
  1. data/.rspec +1 -0
  2. data/.travis.yml +5 -0
  3. data/CHANGELOG.md +5 -0
  4. data/README.md +68 -5
  5. data/Rakefile +8 -0
  6. data/app/assets/stylesheets/bootstrap-tweaks.css +1 -0
  7. data/app/assets/stylesheets/bootstrap.css.scss +3 -0
  8. data/app/form_builders/bootstrap_form_builder.rb +59 -7
  9. data/app/helpers/booter_helper.rb +6 -1
  10. data/app/views/booter/_modal_form.html.erb +19 -0
  11. data/booter.gemspec +6 -0
  12. data/config/locales/booter.en.yml +3 -0
  13. data/config/locales/booter.ru.yml +4 -0
  14. data/lib/booter/version.rb +1 -1
  15. data/spec/controllers/home_controller_spec.rb +127 -0
  16. data/spec/controllers/modal_controller_spec.rb +33 -0
  17. data/spec/dummy/.gitignore +3 -0
  18. data/spec/dummy/README.rdoc +261 -0
  19. data/spec/dummy/Rakefile +7 -0
  20. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  21. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  22. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  23. data/spec/dummy/app/controllers/home_controller.rb +24 -0
  24. data/spec/dummy/app/controllers/modal_controller.rb +7 -0
  25. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  26. data/spec/dummy/app/mailers/.gitkeep +0 -0
  27. data/spec/dummy/app/models/.gitkeep +0 -0
  28. data/spec/dummy/app/models/user.rb +6 -0
  29. data/spec/dummy/app/views/home/buttons.html.haml +6 -0
  30. data/spec/dummy/app/views/home/default_fields.html.haml +8 -0
  31. data/spec/dummy/app/views/home/errors_for.html.haml +2 -0
  32. data/spec/dummy/app/views/home/field_with_hint.html.haml +2 -0
  33. data/spec/dummy/app/views/home/submit_button.html.haml +3 -0
  34. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  35. data/spec/dummy/app/views/modal/simple.html.haml +5 -0
  36. data/spec/dummy/config.ru +4 -0
  37. data/spec/dummy/config/application.rb +57 -0
  38. data/spec/dummy/config/boot.rb +10 -0
  39. data/spec/dummy/config/database.yml +25 -0
  40. data/spec/dummy/config/environment.rb +5 -0
  41. data/spec/dummy/config/environments/development.rb +37 -0
  42. data/spec/dummy/config/environments/production.rb +67 -0
  43. data/spec/dummy/config/environments/test.rb +37 -0
  44. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  45. data/spec/dummy/config/initializers/inflections.rb +15 -0
  46. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  47. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  48. data/spec/dummy/config/initializers/session_store.rb +8 -0
  49. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  50. data/spec/dummy/config/locales/en.yml +5 -0
  51. data/spec/dummy/config/routes.rb +6 -0
  52. data/spec/dummy/db/migrate/20120406045208_create_user.rb +7 -0
  53. data/spec/dummy/lib/assets/.gitkeep +0 -0
  54. data/spec/dummy/log/.gitkeep +0 -0
  55. data/spec/dummy/public/404.html +26 -0
  56. data/spec/dummy/public/422.html +26 -0
  57. data/spec/dummy/public/500.html +25 -0
  58. data/spec/dummy/public/favicon.ico +0 -0
  59. data/spec/dummy/script/rails +6 -0
  60. data/spec/spec_helper.rb +24 -0
  61. metadata +114 -11
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ script:
5
+ - bundle exec rake db:prepare && bundle exec rspec
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## Booter (unreleased)
4
+
5
+ * Full refactoring and specs coverage
6
+ * Add modal forms support
7
+
3
8
  ## Booter 0.3.1 (April 5, 2012)
4
9
 
5
10
  * Custom classes for html inputs
data/README.md CHANGED
@@ -4,20 +4,83 @@ One more twitter bootstrap wrapper for Rails.
4
4
 
5
5
  ## Installation
6
6
 
7
- Add `gem "booter"` to your Gemfile and fire `bundle install`.
7
+ In your Gemfile, add the following dependencies:
8
8
 
9
- Include <tt>bootstrap.css</tt> to your <tt>application.css</tt> and optionally
10
- <tt>bootstrap.js</tt> to <tt>application.js</tt>.
9
+ ``` ruby
10
+ gem 'booter'
11
+ ```
12
+
13
+ Run:
14
+
15
+ ```
16
+ $ bundle install
17
+ ```
18
+
19
+ Add `bootstrap` in your application.css:
20
+
21
+ ``` css
22
+ /*
23
+ *= require bootstrap
24
+ * ...
25
+ */
26
+ ```
27
+
28
+ And optionally add 'bootstrap' in your application.js:
29
+
30
+ ``` javascript
31
+ //= require jquery
32
+ //= require jquery_ujs
33
+ //= require bootstrap
34
+ //= ...
35
+ ```
11
36
 
12
37
  ## Usage
13
38
 
14
39
  Use <tt>nice_form_for</tt> helper method to draw nice bootstrap forms:
15
40
 
16
41
  ``` haml
17
- = nice_form_for @user do
42
+ -# Simple
43
+ = nice_form_for @user do |f|
18
44
  = f.errors_for
19
45
  = f.email_field :email
20
46
  = f.password_field :password
47
+ = f.submit 'Sign in'
48
+
49
+ -# Complex
50
+ = nice_form_for @user do |f|
51
+ = f.errors_for
52
+
53
+ = f.email_field :email, class: 'input-medium'
54
+ = f.password_field :password
21
55
  = f.check_box :remember_me
22
- = f.submit "Sign in"
56
+
57
+ = f.actions do
58
+ = f.submit 'Sign in'
59
+ = f.button 'Cancel'
60
+
61
+ = f.button 'Danger button', style: :danger
62
+ = f.submit 'Submit without the primary class', style: :none
63
+
64
+
65
+ -# Modal
66
+ = nice_form_for @user, modal: true, id: 'auth' do |f|
67
+ = f.errors_for
68
+ = f.email_field :email
69
+ = f.password_field :password
70
+ = f.submit 'Sign in'
71
+
72
+ %p= link_to 'Open auth form', '#auth-modal', data: { toggle: 'modal' }
23
73
  ```
74
+
75
+ ## Demo
76
+
77
+ See [live demo](http://growing-cloud-6915.heroku.com) or browse [source code](https://github.com/boshie/booter-demo)
78
+
79
+ ## Contributors
80
+
81
+ * Alexey Vakhov - [https://github.com/avakhov](https://github.com/avakhov)
82
+ * Alexey Yurchenko - [https://github.com/alexesDev](https://github.com/alexesDev)
83
+
84
+ ## Status
85
+
86
+ [<img src="https://secure.travis-ci.org/boshie/booter.png"/>](http://travis-ci.org/boshie/booter)
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
+
4
+ namespace :db do
5
+ desc "prepare db for specs"
6
+ task "prepare" do
7
+ `cd spec/dummy && bundle exec rake db:drop`
8
+ `cd spec/dummy && bundle exec rake db:create db:migrate db:test:prepare`
9
+ end
10
+ end
@@ -0,0 +1 @@
1
+ div.modal form {margin-bottom: 0}
@@ -1,3 +1,6 @@
1
+ //= require_self
2
+ //= require bootstrap-tweaks
3
+
1
4
  /*!
2
5
  * Bootstrap v2.0.2
3
6
  *
@@ -1,5 +1,16 @@
1
1
  class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
2
2
  delegate :content_tag, :safe_join, to: :@template
3
+ attr_reader :form_actions_content # only for modal forms
4
+
5
+ def modal_title
6
+ if @options[:modal]
7
+ if @options[:modal].is_a?(Hash) and @options[:modal].key?(:title)
8
+ @options[:modal][:title]
9
+ else
10
+ I18n.t('booter.modal.title.' + @object.class.model_name, default: @object.class.model_name.human)
11
+ end
12
+ end
13
+ end
3
14
 
4
15
  def errors_for
5
16
  return "" if @object.errors.empty?
@@ -21,17 +32,19 @@ class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
21
32
  html.html_safe
22
33
  end
23
34
 
24
- %w[email_field password_field text_field text_area].each do |method_name|
35
+ %w[email_field file_field password_field text_field text_area].each do |method_name|
25
36
  define_method method_name do |*args|
26
37
  options = args.extract_options!
27
38
  name = args.first
28
39
 
29
40
  wrapper name, options.slice(:hint) do
30
41
  options = options.except(:hint)
31
- options[:class] = [options[:class], 'input-xxlarge'].compact
32
42
 
33
43
  if method_name == 'text_area'
34
- super(name, options.merge(rows: 7))
44
+ options[:rows] ||= 7
45
+ options[:cols] ||= 40
46
+
47
+ super(name, options)
35
48
  else
36
49
  super(name, options)
37
50
  end
@@ -39,6 +52,16 @@ class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
39
52
  end
40
53
  end
41
54
 
55
+ def actions &block
56
+ begin
57
+ @actions_scope = true
58
+ content = @template.capture(&block)
59
+ ensure
60
+ @actions_scope = false
61
+ end
62
+ form_actions_wrapper content
63
+ end
64
+
42
65
  def select(name, choices, options = {})
43
66
  wrapper name do
44
67
  super
@@ -53,10 +76,12 @@ class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
53
76
  end
54
77
  end
55
78
 
56
- def submit(value=nil)
57
- content_tag :div, class: 'form-actions' do
58
- super value, class: 'btn btn-primary'
59
- end
79
+ def submit value = nil, *args
80
+ form_actions_wrapper super(value, make_button_options(args, style: :primary))
81
+ end
82
+
83
+ def button value = nil, *args
84
+ form_actions_wrapper super(value, make_button_options(args))
60
85
  end
61
86
 
62
87
  def wrapper(name, options = {}, &block)
@@ -72,4 +97,31 @@ class BootstrapFormBuilder < ActionView::Helpers::FormBuilder
72
97
  ]
73
98
  end
74
99
  end
100
+
101
+ private
102
+
103
+ def form_actions_wrapper(content)
104
+ if @actions_scope
105
+ content
106
+ else
107
+ if @options[:modal]
108
+ @form_actions_content = content
109
+ ''
110
+ else
111
+ content_tag :div, content, class: 'form-actions'
112
+ end
113
+ end
114
+ end
115
+
116
+ def make_button_options args, *default_args
117
+ options = default_args.extract_options!
118
+ options.merge! args.extract_options!
119
+ options[:class] ||= 'btn'
120
+
121
+ if options[:style] && options[:style].to_sym != :none
122
+ options[:class] += " btn-#{options[:style]}"
123
+ end
124
+
125
+ options.except(:style)
126
+ end
75
127
  end
@@ -3,6 +3,11 @@ module BooterHelper
3
3
  options[:builder] = BootstrapFormBuilder
4
4
  options[:html] ||= {}
5
5
  options[:html][:class] = 'form-horizontal'
6
- form_for(object, options, &block)
6
+
7
+ if options[:modal]
8
+ render 'booter/modal_form', object: object, options: options, block: block
9
+ else
10
+ form_for(object, options, &block)
11
+ end
7
12
  end
8
13
  end
@@ -0,0 +1,19 @@
1
+ <div class="modal hide fade" id="<%= options[:id] || object.class.name.gsub('::', '').underscore %>-modal">
2
+ <%= form_for object, options do |f| %>
3
+ <div class="modal-header">
4
+ <a class="close" data-dismiss="modal">×</a>
5
+ <h3><%= f.modal_title %></h3>
6
+ </div>
7
+ <div class="modal-body">
8
+ <%= capture f, &block %>
9
+ </div>
10
+ <div class="modal-footer">
11
+ <div class="pull-left">
12
+ <a href="#" data-dismiss="modal" class="btn"><%= t('booter.modal.close') %></a>
13
+ </div>
14
+ <div class="pull-right">
15
+ <%= f.form_actions_content %>
16
+ </div>
17
+ </div>
18
+ <% end %>
19
+ </div>
@@ -16,4 +16,10 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Booter::VERSION
17
17
 
18
18
  gem.add_dependency 'rails', '~> 3.2'
19
+
20
+ gem.add_development_dependency 'haml'
21
+ gem.add_development_dependency 'sqlite3'
22
+ gem.add_development_dependency 'rspec-rails'
23
+ gem.add_development_dependency 'factory_girl_rails'
24
+ gem.add_development_dependency 'database_cleaner'
19
25
  end
@@ -1,4 +1,7 @@
1
1
  en:
2
+ booter:
3
+ modal:
4
+ close: Close
2
5
  errors:
3
6
  template:
4
7
  header:
@@ -0,0 +1,4 @@
1
+ ru:
2
+ booter:
3
+ modal:
4
+ close: Закрыть
@@ -1,3 +1,3 @@
1
1
  module Booter
2
- VERSION = "0.3.1"
2
+ VERSION = "1.0.0.rc1"
3
3
  end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe HomeController do
4
+ render_views
5
+
6
+ it 'renders default field' do
7
+ get :default_fields
8
+ response.should be_success
9
+
10
+ assert_select "form[class=?]", /form-horizontal/ do
11
+ assert_select "div.control-group" do
12
+ assert_select 'label.control-label', 'Email'
13
+ assert_select 'div.controls' do
14
+ assert_select 'input[type=email]'
15
+ end
16
+ end
17
+
18
+ assert_select "div.control-group" do
19
+ assert_select 'label.control-label', 'Avatar'
20
+ assert_select 'div.controls' do
21
+ assert_select 'input[type=file]'
22
+ end
23
+ end
24
+
25
+ assert_select "div.control-group" do
26
+ assert_select 'label.control-label', 'Password'
27
+ assert_select 'div.controls' do
28
+ assert_select 'input[type=password]'
29
+ end
30
+ end
31
+
32
+ assert_select "div.control-group" do
33
+ assert_select 'label.control-label', 'Motto'
34
+ assert_select 'div.controls' do
35
+ assert_select 'input[type=text]'
36
+ end
37
+ end
38
+
39
+ assert_select "div.control-group" do
40
+ assert_select 'label.control-label', 'About'
41
+ assert_select 'div.controls' do
42
+ assert_select 'textarea[rows=?][cols=?]', 7, 40
43
+ end
44
+ end
45
+
46
+ assert_select "div.control-group" do
47
+ assert_select 'label.control-label', 'Role'
48
+ assert_select 'div.controls' do
49
+ assert_select 'select'
50
+ end
51
+ end
52
+
53
+ assert_select "div.control-group" do
54
+ assert_select 'label.control-label', 'Remember me'
55
+ assert_select 'div.controls' do
56
+ assert_select 'label.checkbox' do
57
+ assert_select 'input[type=hidden][value=?]', 0
58
+ assert_select 'input[type=checkbox][value=?]', 1
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ it 'renders error message' do
66
+ get :errors_for
67
+ response.should be_success
68
+
69
+ assert_select "form[class=?]", /form-horizontal/ do
70
+ assert_select 'div.alert.alert-error' do
71
+ assert_select 'p' do
72
+ assert_select 'b', 'User: not saved because of 1 error'
73
+ end
74
+ assert_select 'ul' do
75
+ assert_select 'li', 'Email should be email'
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ it 'renders field with hint' do
82
+ get :field_with_hint
83
+ response.should be_success
84
+
85
+ assert_select "form" do
86
+ assert_select 'div.control-group' do
87
+ assert_select 'label.control-label', 'Email'
88
+ assert_select 'div.controls' do
89
+ assert_select 'input[type=email]'
90
+ assert_select 'p.help-block', 'Enter proper email address'
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ it 'renders different buttons' do
97
+ get :buttons
98
+ response.should be_success
99
+
100
+ assert_select "form" do
101
+ assert_select 'div.form-actions' do
102
+ assert_select 'input.btn.btn-primary[type=?][value=?]', 'submit', 'Sign in'
103
+ assert_select 'button.btn[type=?]', 'submit', 'Cancel'
104
+ assert_select 'button.btn.btn-danger[type=?]', 'submit', 'Danger button'
105
+ assert_select 'input.btn[type=?][value=?]', 'submit', 'Submit without the primary class'
106
+ end
107
+ end
108
+ end
109
+
110
+ it 'renders submit buttons wrapped in div.form-actions' do
111
+ get :submit_button
112
+ response.should be_success
113
+
114
+ assert_select "form" do
115
+ assert_select "div.control-group" do
116
+ assert_select 'label.control-label', 'Email'
117
+ assert_select 'div.controls' do
118
+ assert_select 'input[type=email]'
119
+ end
120
+ end
121
+
122
+ assert_select 'div.form-actions' do
123
+ assert_select 'input.btn.btn-primary[type=?][value=?]', 'submit', 'Create User'
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe ModalController do
4
+ render_views
5
+
6
+ it 'renders' do
7
+ get :simple
8
+ response.should be_success
9
+
10
+ assert_select 'div.modal.hide.fade#auth-modal' do
11
+ assert_select 'form[class=?]', 'form-horizontal' do
12
+ assert_select '.modal-header' do
13
+ assert 'a.close[data-dismiss=?]', 'modal'
14
+ assert_select 'h3', 'User'
15
+ end
16
+
17
+ assert_select '.modal-body' do
18
+ assert_select 'input[type=email]'
19
+ assert_select 'input[type=password]'
20
+ end
21
+
22
+ assert_select '.modal-footer' do
23
+ assert_select '.pull-left' do
24
+ assert_select 'a[href=#][data-dismiss=?][class=?]', 'modal', 'btn'
25
+ end
26
+ assert_select '.pull-right' do
27
+ assert_select 'input[type=submit][class=?][value=?]', 'btn btn-primary', 'Sign in'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end