client_side_validations-rails_2 0.0.1

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 (36) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/HISTORY +5 -0
  4. data/README.markdown +45 -0
  5. data/Rakefile +21 -0
  6. data/client_side_validations-rails_2.gemspec +35 -0
  7. data/generators/client_side_validations/client_side_validations_generator.rb +14 -0
  8. data/lib/client_side_validations/rails_2.rb +5 -0
  9. data/lib/client_side_validations/rails_2/action_view.rb +7 -0
  10. data/lib/client_side_validations/rails_2/action_view/form_helper.rb +11 -0
  11. data/lib/client_side_validations/rails_2/action_view/form_tag_helper.rb +6 -0
  12. data/lib/client_side_validations/rails_2/active_record.rb +14 -0
  13. data/lib/client_side_validations/rails_2/active_record/active_model.rb +12 -0
  14. data/lib/client_side_validations/rails_2/active_record/active_model/validations.rb +51 -0
  15. data/lib/client_side_validations/rails_2/active_record/active_model/validations/base.rb +25 -0
  16. data/lib/client_side_validations/rails_2/active_record/active_model/validations/numericality.rb +5 -0
  17. data/lib/client_side_validations/rails_2/active_record/middleware.rb +42 -0
  18. data/lib/client_side_validations/rails_2/active_record/validations.rb +23 -0
  19. data/lib/client_side_validations/rails_2/middleware.rb +22 -0
  20. data/lib/client_side_validations/rails_2/version.rb +5 -0
  21. data/test/action_view/cases/helper.rb +155 -0
  22. data/test/action_view/cases/test_helpers.rb +516 -0
  23. data/test/action_view/cases/test_legacy_helpers.rb +140 -0
  24. data/test/action_view/models.rb +2 -0
  25. data/test/action_view/models/comment.rb +26 -0
  26. data/test/action_view/models/post.rb +31 -0
  27. data/test/active_record/cases/helper.rb +13 -0
  28. data/test/active_record/cases/test_base.rb +10 -0
  29. data/test/active_record/cases/test_middleware.rb +157 -0
  30. data/test/active_record/cases/test_validation_reflection.rb +144 -0
  31. data/test/active_record/cases/test_validations.rb +27 -0
  32. data/test/active_record/models/guid.rb +7 -0
  33. data/test/active_record/models/user.rb +11 -0
  34. data/test/base_helper.rb +10 -0
  35. data/test/middleware/cases/helper.rb +6 -0
  36. metadata +237 -0
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in client_side_validations-rails_2.gemspec
4
+ gemspec
data/HISTORY ADDED
@@ -0,0 +1,5 @@
1
+ == 0.0.1
2
+ Wrapper for ClientSideValidations
3
+ Added ActiveModel API to ActiveRecord 2.x
4
+ concat script from form_for ClientSideValidations
5
+ Wrote ActiveRecord 2.x middleware for Uniqueness
data/README.markdown ADDED
@@ -0,0 +1,45 @@
1
+ # ClientSideValidations for Rails 2.x #
2
+
3
+ This gem provides a thin wrapper for [ClientSideValidations](https://github.com/bcardarella/client_side_validations)
4
+
5
+ ## Installation ##
6
+
7
+ *This gem requires the [jquery-ujs](https://github.com/rails/jquery-ujs) gem. Please install that before continuing.*
8
+
9
+ Add the gem to your `config/environment.rb` file:
10
+
11
+ ```ruby
12
+ config.gem 'client_side_validations-rails_2', :lib => 'client_side_validations/rails_2'
13
+ ```
14
+
15
+ Run the `gems:install` `rake` task:
16
+
17
+ ```
18
+ rake gems:install
19
+ ```
20
+
21
+ Run the generator
22
+
23
+ ```
24
+ script/generate client_side_validations
25
+ ```
26
+
27
+ This will install two files
28
+
29
+ ```
30
+ config/initializers/client_side_validations.rb
31
+ public/javascripts/rails.validations.js
32
+ ```
33
+
34
+ ## Usage ##
35
+
36
+ Please follow the instructions for [Rails 3.0 on the ClientSideValidations README](https://github.com/bcardarella/client_side_validations)
37
+
38
+ ## Legal ##
39
+
40
+ Brian Cardarella © 2011
41
+
42
+ [@bcardarella](http://twitter.com/bcardarella)
43
+
44
+ [Licensed under the MIT license](http://www.opensource.org/licenses/mit-license.php)
45
+
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ multitask :default => 'test:ruby'
5
+
6
+ require 'rake/testtask'
7
+ namespace :test do
8
+ desc %(Run all tests)
9
+ multitask :all => ['test:all_rubies']
10
+
11
+ desc %(Test Ruby code)
12
+ Rake::TestTask.new(:ruby) do |test|
13
+ test.libs << 'lib' << 'test'
14
+ test.pattern = 'test/*/cases/**/test_*.rb'
15
+ test.verbose = true
16
+ end
17
+
18
+ task :all_rubies do
19
+ system "rvm ruby-1.8.7@client_side_validations-rails_2,ruby-1.9.2@client_side_validations-rails_2 rake test:ruby"
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "client_side_validations/rails_2/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "client_side_validations-rails_2"
7
+ s.version = ClientSideValidations::Rails2::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Brian Cardarella"]
10
+ s.email = ["bcardarella@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Client Side Validations support for Rails 2.x}
13
+ s.description = %q{Client Side Validations support for Rails 2.x}
14
+
15
+ s.files = `git ls-files -- {lib/*,generators/*,*.gemspec}`.split("\n")
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'activesupport', '~> 2.3.0'
22
+ s.add_dependency 'client_side_validations', '3.1.0.beta.2'
23
+
24
+ s.add_development_dependency 'activerecord', '~> 2.3.0'
25
+ s.add_development_dependency 'actionpack', '~> 2.3.0'
26
+ s.add_development_dependency 'sqlite3'
27
+ s.add_development_dependency 'mocha'
28
+ s.add_development_dependency 'rack-test'
29
+
30
+ if RUBY_VERSION >= "1.9"
31
+ s.add_development_dependency 'ruby-debug19'
32
+ else
33
+ s.add_development_dependency 'ruby-debug'
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ require 'client_side_validations/files'
2
+
3
+ class ClientSideValidationsGenerator < Rails::Generator::Base
4
+ def manifest
5
+ record do |c|
6
+ c.file(ClientSideValidations::Files::Initializer, 'config/initializers/client_side_validations.rb')
7
+ c.file(ClientSideValidations::Files::Javascript, 'public/javascripts/rails.validations.js')
8
+ end
9
+ end
10
+
11
+ def source_path(relative_path)
12
+ relative_path
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ module ClientSideValidations::Rails2; end
2
+
3
+ require 'client_side_validations/rails_2/middleware'
4
+ require 'client_side_validations/rails_2/action_view'
5
+ require 'client_side_validations/rails_2/active_record'
@@ -0,0 +1,7 @@
1
+ module ClientSideValidations::Rails2::ActionView; end
2
+
3
+ require 'client_side_validations/action_view'
4
+ require 'client_side_validations/rails_2/action_view/form_helper'
5
+
6
+ ActionView::Base.send(:include, ClientSideValidations::Rails2::ActionView::Helpers::FormHelper)
7
+
@@ -0,0 +1,11 @@
1
+ module ClientSideValidations::Rails2::ActionView::Helpers
2
+ module FormHelper
3
+ def form_for(record_or_name_or_array, *args, &proc)
4
+ html = super
5
+ if match = html.match(/<script.+$/)
6
+ concat(match[0])
7
+ end
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,6 @@
1
+ module ClientSideValidations::Rails2::ActionView::Helpers
2
+ module FormTagHelper
3
+
4
+ end
5
+ end
6
+
@@ -0,0 +1,14 @@
1
+ module ClientSideValidations::Rails2
2
+ module ActiveRecord; end
3
+ end
4
+
5
+ require 'client_side_validations/rails_2/active_record/active_model'
6
+ require 'client_side_validations/rails_2/active_record/validations'
7
+ require 'client_side_validations/rails_2/active_record/middleware'
8
+
9
+ require 'client_side_validations/active_model'
10
+
11
+ ActiveModel::Validations::BaseValidator.send(:include, ActiveModel::Validator)
12
+ ActiveRecord::Base.send(:include, ActiveModel::Validations)
13
+ ActiveRecord::Base.send(:extend, ActiveModel::Validations::ClassMethods)
14
+
@@ -0,0 +1,12 @@
1
+ # This is to backport the ActiveModel namespacing to ActiveRecord 2.x
2
+
3
+ module ActiveModel
4
+ module Validator; end
5
+ module Validations; end
6
+ class Errors
7
+ CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank]
8
+ end
9
+ end
10
+
11
+ require 'client_side_validations/rails_2/active_record/active_model/validations'
12
+
@@ -0,0 +1,51 @@
1
+ module ActiveModel::Validations
2
+ module ClassMethods
3
+ def _validators
4
+ @_validators ||= Hash.new { |hash, key| hash[key] = [] }
5
+ end
6
+ end
7
+
8
+ def _validators
9
+ self.class._validators
10
+ end
11
+ end
12
+
13
+ require 'client_side_validations/rails_2/active_record/active_model/validations/base'
14
+
15
+ %w{
16
+ acceptance
17
+ confirmation
18
+ exclusion
19
+ format
20
+ inclusion
21
+ length
22
+ numericality
23
+ presence
24
+ }.each do |validator|
25
+ eval <<-MODULE
26
+
27
+ module ActiveModel::Validations
28
+ const_set '#{validator.capitalize}Validator', Class.new(BaseValidator)
29
+
30
+ module ClassMethods
31
+ define_method "validates_#{validator}_of" do |*attr_names|
32
+ options = attr_names.extract_options!
33
+ attr_names.each do |name|
34
+ self._validators[name] << #{validator.capitalize}Validator.new(name, options)
35
+ end
36
+
37
+ super(*((attr_names << options).compact))
38
+ end
39
+ end
40
+ end
41
+ MODULE
42
+ end
43
+
44
+ require 'client_side_validations/rails_2/active_record/active_model/validations/numericality'
45
+
46
+ module ActiveModel::Validations::ClassMethods
47
+ def validates_size_of(*attr_names)
48
+ validates_length_of(*attr_names)
49
+ end
50
+ end
51
+
@@ -0,0 +1,25 @@
1
+ module ActiveModel::Validations
2
+ class BaseValidator
3
+ attr_accessor :attributes, :options
4
+
5
+ def initialize(attributes, options = {})
6
+ self.attributes = attributes
7
+ self.options = options
8
+ end
9
+
10
+ def ==(other)
11
+ class_equality = self.class == other.class
12
+ attribute_equality = self.attributes == other.attributes
13
+ options_equality = self.options == other.options
14
+ class_equality && attribute_equality && options_equality
15
+ end
16
+
17
+ def self.kind
18
+ @kind ||= name.split('::').last.underscore.sub(/_validator$/, '').to_sym
19
+ end
20
+
21
+ def kind
22
+ self.class.kind
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ class ActiveModel::Validations::NumericalityValidator
2
+ CHECKS = { :greater_than => :>, :greater_than_or_equal_to => :>=,
3
+ :equal_to => :==, :less_than => :<, :less_than_or_equal_to => :<=,
4
+ :odd => :odd?, :even => :even? }.freeze
5
+ end
@@ -0,0 +1,42 @@
1
+ module ClientSideValidations::ActiveRecord
2
+ class Middleware
3
+
4
+ def self.is_unique?(finder_class, attr_name, value, params)
5
+ column = finder_class.columns_hash[attr_name.to_s]
6
+ connection = finder_class.connection
7
+
8
+ if value.nil?
9
+ comparison_operator = "IS ?"
10
+ elsif column.text?
11
+ comparison_operator = "#{connection.case_sensitive_equality_operator} ?"
12
+ value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s
13
+ else
14
+ comparison_operator = "= ?"
15
+ end
16
+
17
+ sql_attribute = "#{finder_class.quoted_table_name}.#{connection.quote_column_name(attr_name)}"
18
+
19
+ if value.nil? || (params[:case_sensitive] == 'true' || !column.text?)
20
+ condition_sql = "#{sql_attribute} #{comparison_operator}"
21
+ condition_params = [value]
22
+ else
23
+ condition_sql = "LOWER(#{sql_attribute}) #{comparison_operator}"
24
+ condition_params = [value.mb_chars.downcase]
25
+ end
26
+
27
+ (params[:scope] || {}).each do |scope_item, scope_value|
28
+ condition_sql << " AND " << finder_class.send(:attribute_condition, "#{finder_class.quoted_table_name}.#{connection.quote_column_name(scope_item)}", scope_value)
29
+ condition_params << scope_value
30
+ end
31
+
32
+ if params[:id]
33
+ condition_sql << " AND #{finder_class.quoted_table_name}.#{finder_class.primary_key} <> ?"
34
+ condition_params << params[:id]
35
+ end
36
+
37
+ finder_class.send(:with_exclusive_scope) do
38
+ !finder_class.exists?([condition_sql, *condition_params])
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,23 @@
1
+ require 'client_side_validations/active_record/uniqueness'
2
+
3
+ module ActiveRecord::Validations
4
+ class UniquenessValidator < ActiveModel::Validations::BaseValidator
5
+ include ClientSideValidations::ActiveRecord::Uniqueness
6
+ end
7
+ end
8
+
9
+ module ClientSideValidations::Rails2::ActiveRecord::Validations
10
+ module ClassMethods
11
+ def validates_uniqueness_of(*attr_names)
12
+ options = attr_names.extract_options!
13
+ attr_names.each do |name|
14
+ self._validators[name] << ::ActiveRecord::Validations::UniquenessValidator.new(name, options)
15
+ end
16
+
17
+ super(*((attr_names << options).compact))
18
+ end
19
+ end
20
+ end
21
+
22
+ ActiveRecord::Base.send(:extend, ClientSideValidations::Rails2::ActiveRecord::Validations::ClassMethods)
23
+
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'client_side_validations/middleware'
4
+
5
+ module ClientSideValidations
6
+
7
+ module Middleware
8
+ class Base
9
+ def initialize(env)
10
+ self.body = ''
11
+ self.status = 200
12
+ self.request = ActionController::Request.new(env)
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ if defined?(Rails)
19
+ Rails.configuration.after_initialize do
20
+ Rails.configuration.middleware.use ClientSideValidations::Middleware::Validators
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module ClientSideValidations
2
+ module Rails2
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,155 @@
1
+ require 'base_helper'
2
+ require 'action_view'
3
+ require 'action_controller'
4
+ require 'action_view/test_case'
5
+ require 'client_side_validations/rails_2/action_view'
6
+ require 'action_view/models'
7
+
8
+ module ActionViewTestSetup
9
+ include ::ClientSideValidations::ActionView::Helpers::FormHelper
10
+ include ::ClientSideValidations::ActionView::Helpers::FormTagHelper
11
+ include ::ClientSideValidations::Rails2::ActionView::Helpers::FormHelper
12
+
13
+ def setup
14
+ super
15
+
16
+ # Create "label" locale for testing I18n label helpers
17
+ I18n.backend.store_translations 'label', {
18
+ :activemodel => {
19
+ :attributes => {
20
+ :post => {
21
+ :cost => "Total cost"
22
+ }
23
+ }
24
+ },
25
+ :helpers => {
26
+ :label => {
27
+ :post => {
28
+ :body => "Write entire text here"
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ # Create "submit" locale for testing I18n submit helpers
35
+ I18n.backend.store_translations 'submit', {
36
+ :helpers => {
37
+ :submit => {
38
+ :create => 'Create %{model}',
39
+ :update => 'Confirm %{model} changes',
40
+ :submit => 'Save changes',
41
+ :another_post => {
42
+ :update => 'Update your %{model}'
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ @post = Post.new
49
+ @comment = Comment.new
50
+ def @post.errors()
51
+ Class.new{
52
+ def [](field); field == "author_name" ? ["can't be empty"] : [] end
53
+ def empty?() false end
54
+ def count() 1 end
55
+ def full_messages() [ "Author name can't be empty" ] end
56
+ }.new
57
+ end
58
+ def @post.id; 123; end
59
+ def @post.id_before_type_cast; 123; end
60
+ def @post.to_param; '123'; end
61
+
62
+ @post.persisted = true
63
+ @post.title = "Hello World"
64
+ @post.author_name = ""
65
+ @post.body = "Back to the hill and over it again!"
66
+ @post.secret = 1
67
+ @post.written_on = Date.new(2004, 6, 15)
68
+ end
69
+
70
+ def url_for(object)
71
+ @url_for_options = object
72
+ if object.is_a?(Hash)
73
+ "http://www.example.com"
74
+ else
75
+ super
76
+ end
77
+ end
78
+
79
+ def snowman(method = nil)
80
+ txt = %{<div style="margin:0;padding:0;display:inline">}
81
+ txt << %{<input name="_method" type="hidden" value="#{method}" />} if method
82
+ txt << %{</div>}
83
+ end
84
+
85
+ def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil, validators = nil)
86
+ txt = %{<form action="#{action}"}
87
+ txt << %{ data-remote="true"} if remote
88
+ txt << %{ class="#{html_class}"} if html_class
89
+ txt << %{ data-validate="true"} if validators
90
+ txt << %{ id="#{id}"} if id
91
+ txt << %{ method="post"}
92
+ txt << %{ novalidate="novalidate"} if validators
93
+ txt << %{>}
94
+ end
95
+
96
+ def whole_form(action = "http://www.example.com", id = nil, html_class = nil, options = nil)
97
+ contents = block_given? ? yield : ""
98
+
99
+ if options.is_a?(Hash)
100
+ method, remote, validators = options.values_at(:method, :remote, :validators)
101
+ else
102
+ method = options
103
+ end
104
+
105
+ html = form_text(action, id, html_class, remote, validators) + snowman(method) + (contents || "") + "</form>"
106
+
107
+ if options.is_a?(Hash) && options[:validators]
108
+ build_script_tag(html, id, options[:validators])
109
+ else
110
+ html
111
+ end
112
+ end
113
+
114
+ def build_script_tag(html, id, validators)
115
+ (html || "") + %Q{<script>window['#{id}'] = #{client_side_form_settings_helper.merge(:validators => validators).to_json};</script>}
116
+ end
117
+
118
+ protected
119
+ def comments_path(post)
120
+ "/posts/#{post.id}/comments"
121
+ end
122
+ alias_method :post_comments_path, :comments_path
123
+
124
+ def comment_path(post, comment)
125
+ "/posts/#{post.id}/comments/#{comment.id}"
126
+ end
127
+ alias_method :post_comment_path, :comment_path
128
+
129
+ def admin_comments_path(post)
130
+ "/admin/posts/#{post.id}/comments"
131
+ end
132
+ alias_method :admin_post_comments_path, :admin_comments_path
133
+
134
+ def admin_comment_path(post, comment)
135
+ "/admin/posts/#{post.id}/comments/#{comment.id}"
136
+ end
137
+ alias_method :admin_post_comment_path, :admin_comment_path
138
+
139
+ def posts_path
140
+ "/posts"
141
+ end
142
+
143
+ def post_path(post, options = {})
144
+ if options[:format]
145
+ "/posts/#{post.id}.#{options[:format]}"
146
+ else
147
+ "/posts/#{post.id}"
148
+ end
149
+ end
150
+
151
+ def protect_against_forgery?
152
+ false
153
+ end
154
+
155
+ end