booter 0.3.1 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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