liangzan-validation_reflection 0.3.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ .DS_STORE
2
+ *~
3
+ pkg*
4
+ validation_reflection*.gem
@@ -0,0 +1,54 @@
1
+ == 0.3.8 2010-07-30
2
+ * Enhancement from Sutto:
3
+ ** Fix reload bug
4
+
5
+ == 0.3.7 2010-06-11
6
+ * Enhancement from Sutto:
7
+ ** Use Rails.root if available over RAILS_ROOT
8
+
9
+ == 0.3.6 2010-02-14
10
+ * Enhancement from skoppensboer:
11
+ ** Changes Jeweler spec to reflect only Gemcutter
12
+ * Enhancement from duritong:
13
+ ** fix remembering of attributes defined as an array
14
+
15
+ == 0.3.5, 2009-10-09
16
+ * version bump
17
+
18
+ == 0.3.4, 2009-10-09
19
+ * Enhancements from Jonas Grimfelt
20
+ ** Don't include instead of explicit namespaces to make the code much DRY:er and readable
21
+ ** Avoid mutable strings
22
+ ** Be clear about the namespaces for external classes (to avoid Ruby 1.9.x issues)
23
+ ** Fixing gem loading issues on Ruby 1.9.x
24
+ ** Removed the freezing of validations
25
+
26
+ == 0.3.3, 2009-09-12
27
+ * version bump
28
+
29
+ == 0.3.2, 2009-09-12
30
+ * gemified by Christopher Redinger
31
+
32
+ == 0.3.1, 2008-01-03
33
+ * require 'ostruct'; thanks to Georg Friedrich.
34
+
35
+ == 0.3, 2008-01-01
36
+ * Added configurability in config/plugins/validation_reflection.rb
37
+
38
+ == 0.2.1, 2006-12-28
39
+ * Moved lib files into subfolder boiler_plate.
40
+
41
+ == 0.2, 2006-08-06
42
+ ?
43
+
44
+ = Deprecation Notice
45
+
46
+ Version 0.1 had supplied three methods
47
+
48
+ - validates_presence_of_mandatory_content_columns
49
+ - validates_lengths_of_string_attributes
50
+ - validates_all_associated
51
+
52
+ These have been removed. Please use the Enforce Schema Rules plugin instead
53
+
54
+ http://enforce-schema-rules.googlecode.com/svn/trunk/enforce_schema_rules/
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2009 Christopher Redinger
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README ADDED
@@ -0,0 +1,68 @@
1
+ Validation Reflection
2
+ =====================
3
+
4
+ Version 0.3.8, 2010-07-30
5
+
6
+ This plugin adds reflective access to validations
7
+
8
+ - ModelClass.reflect_on_all_validations
9
+ - ModelClass.reflect_on_validations_for(:property)
10
+
11
+ Both of these methods return arrays containing instances of
12
+ ActiveRecord::Reflection::MacroReflection. For example
13
+
14
+ class Person < ActiveRecord::Base
15
+ validates_presence_of :name
16
+ validates_numericality_of :size, :only_integer => true
17
+ end
18
+
19
+ refl = Person.reflect_on_validations_for(:name)
20
+ refl[0].macro
21
+ # => :validates_presence_of
22
+
23
+ refl = Person.reflect_on_validations_for(:size)
24
+ refl[0].macro
25
+ # => :validates_numericality_of
26
+ refl[0].options
27
+ # => { :only_integer => true }
28
+
29
+
30
+ == Customization
31
+
32
+ Usually, all the standard Rails validations are reflected.
33
+ You can change this -- add or remove validations -- in an
34
+ application-specific configuration file,
35
+
36
+ config/plugins/validation_reflection.rb
37
+
38
+ In that file change config.reflected_validations to suit your
39
+ needs. Say, you have a custom validation for email addresses,
40
+ validates_as_email, then you could add it like this
41
+
42
+ config.reflected_validations << :validates_as_email
43
+
44
+ If validates_as_email is implemented in terms of other validation
45
+ methods, these validations are added to the reflection metadata,
46
+ too. As that may not be what you want, you can disable reflection
47
+ for these subordinate validations
48
+
49
+ config.reflected_validations << {
50
+ :method => :validates_as_email,
51
+ :ignore_subvalidations => true
52
+ }
53
+
54
+ You have to make sure that all reflected validations are defined
55
+ before this plugin is loaded. To this end, you may have to
56
+ explicitly set the load order of plugins somewhere in the environment
57
+ configuration using
58
+
59
+ config.plugins = [...]
60
+
61
+
62
+ == Special Thanks
63
+
64
+ To Michael Schuerig, michael@schuerig.de for his initial concept and implementation of this plugin.
65
+
66
+ == License
67
+
68
+ ValidationReflection uses the MIT license. Please check the LICENSE file for more details.
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ desc 'Default: run unit tests.'
7
+ task :default => :test
8
+
9
+ desc 'Test the validation_reflection plugin.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the validation_reflection plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'ValidationReflection'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ begin
26
+ require 'jeweler'
27
+ Jeweler::Tasks.new do |gemspec|
28
+ gemspec.name = "liangzan-validation_reflection"
29
+ gemspec.summary = "Adds reflective access to validations"
30
+ gemspec.description = "Adds reflective access to validations"
31
+ gemspec.email = "liangzan@gmail.com"
32
+ gemspec.homepage = "http://github.com/liangzan/validation_reflection"
33
+ gemspec.authors = ["Christopher Redinger", "Wong Liang Zan"]
34
+ end
35
+ Jeweler::RubyforgeTasks.new
36
+ rescue LoadError
37
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
38
+ end
@@ -0,0 +1,5 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 3
4
+ :build:
5
+ :patch: 9
@@ -0,0 +1,51 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{liangzan-validation_reflection}
8
+ s.version = "0.3.9"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Christopher Redinger", "Wong Liang Zan"]
12
+ s.date = %q{2010-08-29}
13
+ s.description = %q{Adds reflective access to validations}
14
+ s.email = %q{liangzan@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "CHANGELOG",
21
+ "MIT-LICENSE",
22
+ "README",
23
+ "Rakefile",
24
+ "VERSION.yml",
25
+ "liangzan-validation_reflection.gemspec",
26
+ "lib/validation_reflection.rb",
27
+ "rails/init.rb",
28
+ "test/test_helper.rb",
29
+ "test/validation_reflection_test.rb"
30
+ ]
31
+ s.homepage = %q{http://github.com/liangzan/validation_reflection}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.3.7}
35
+ s.summary = %q{Adds reflective access to validations}
36
+ s.test_files = [
37
+ "test/test_helper.rb",
38
+ "test/validation_reflection_test.rb"
39
+ ]
40
+
41
+ if s.respond_to? :specification_version then
42
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
+ s.specification_version = 3
44
+
45
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
+ else
47
+ end
48
+ else
49
+ end
50
+ end
51
+
@@ -0,0 +1,127 @@
1
+ require 'active_record/reflection'
2
+ require 'ostruct'
3
+
4
+ # Based on code by Sebastian Kanthak
5
+ # See http://dev.rubyonrails.org/ticket/861
6
+ #
7
+ module ActiveRecordExtensions # :nodoc:
8
+ module ValidationReflection # :nodoc:
9
+
10
+ extend self
11
+
12
+ require_path = ::File.join((defined?(Rails) ? Rails.root : RAILS_ROOT), 'config', '**', 'validation_reflection.rb').to_s rescue ''
13
+
14
+ # Look for config/initializer here in:
15
+ CONFIG_PATH = ::Dir.glob(require_path).first || ''
16
+ CORE_VALIDATONS = [
17
+ :validates_acceptance_of,
18
+ :validates_associated,
19
+ :validates_confirmation_of,
20
+ :validates_exclusion_of,
21
+ :validates_format_of,
22
+ :validates_inclusion_of,
23
+ :validates_length_of,
24
+ :validates_size_of,
25
+ :validates_numericality_of,
26
+ :validates_presence_of,
27
+ :validates_uniqueness_of,
28
+ ].freeze
29
+
30
+ @@reflected_validations = CORE_VALIDATONS.dup
31
+ @@in_ignored_subvalidation = false
32
+
33
+ mattr_accessor :reflected_validations,
34
+ :in_ignored_subvalidation
35
+
36
+ def included(base) # :nodoc:
37
+ return if base.kind_of?(::ActiveRecordExtensions::ValidationReflection::ClassMethods)
38
+ base.extend(ClassMethods)
39
+ end
40
+
41
+ # Load config/initializer on load, where ValidationReflection defaults
42
+ # (such as which validations to reflect upon) cane be overridden/extended.
43
+ #
44
+ def load_config
45
+ if ::File.file?(CONFIG_PATH)
46
+ config = ::OpenStruct.new
47
+ config.reflected_validations = @@reflected_validations
48
+ silence_warnings do
49
+ eval(::IO.read(CONFIG_PATH), binding, CONFIG_PATH)
50
+ end
51
+ end
52
+ end
53
+
54
+ # Iterate through all validations and store/cache the info
55
+ # for later easy access.
56
+ #
57
+ def install(base)
58
+ @@reflected_validations.each do |validation_type|
59
+ next if base.respond_to?(:"#{validation_type}_with_reflection")
60
+ ignore_subvalidations = false
61
+
62
+ if validation_type.kind_of?(::Hash)
63
+ ignore_subvalidations = validation_type[:ignore_subvalidations]
64
+ validation_type = validation_type[:method]
65
+ end
66
+
67
+ base.class_eval %{
68
+ class << self
69
+ def #{validation_type}_with_reflection(*attr_names)
70
+ ignoring_subvalidations(#{ignore_subvalidations}) do
71
+ #{validation_type}_without_reflection(*attr_names)
72
+ remember_validation_metadata(:#{validation_type}, *attr_names)
73
+ end
74
+ end
75
+ alias_method_chain :#{validation_type}, :reflection
76
+ end
77
+ }, __FILE__, __LINE__
78
+ end
79
+ end
80
+
81
+ module ClassMethods
82
+
83
+ include ::ActiveRecordExtensions::ValidationReflection
84
+
85
+ # Returns an array of MacroReflection objects for all validations in the class
86
+ def reflect_on_all_validations
87
+ self.read_inheritable_attribute(:validations) || []
88
+ end
89
+
90
+ # Returns an array of MacroReflection objects for all validations defined for the field +attr_name+.
91
+ def reflect_on_validations_for(attr_name)
92
+ self.reflect_on_all_validations.select do |reflection|
93
+ reflection.name == attr_name.to_sym
94
+ end
95
+ end
96
+
97
+ private
98
+
99
+ # Store validation info for easy and fast access.
100
+ #
101
+ def remember_validation_metadata(validation_type, *attr_names)
102
+ configuration = attr_names.last.is_a?(::Hash) ? attr_names.pop : {}
103
+ attr_names.flatten.each do |attr_name|
104
+ self.write_inheritable_array :validations,
105
+ [::ActiveRecord::Reflection::MacroReflection.new(validation_type, attr_name.to_sym, configuration, self)]
106
+ end
107
+ end
108
+
109
+ def ignoring_subvalidations(ignore)
110
+ save_ignore = self.in_ignored_subvalidation
111
+ unless self.in_ignored_subvalidation
112
+ self.in_ignored_subvalidation = ignore
113
+ yield
114
+ end
115
+ ensure
116
+ self.in_ignored_subvalidation = save_ignore
117
+ end
118
+
119
+ end
120
+ end
121
+ end
122
+
123
+ ActiveRecord::Base.class_eval do
124
+ include ::ActiveRecordExtensions::ValidationReflection
125
+ ::ActiveRecordExtensions::ValidationReflection.load_config
126
+ ::ActiveRecordExtensions::ValidationReflection.install(self)
127
+ end
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require 'validation_reflection'
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ ENV['RAILS_ENV'] = 'test'
3
+ RAILS_ROOT = File.join(File.dirname(__FILE__))
4
+
5
+ require 'rubygems'
6
+
7
+ begin
8
+ require 'active_record'
9
+ rescue LoadError
10
+ gem 'activerecord', '>= 1.2.3'
11
+ require 'active_record'
12
+ end
13
+
14
+ begin
15
+ require 'test/unit'
16
+ rescue LoadError
17
+ gem 'test-unit', '>= 1.2.3'
18
+ require 'test/unit'
19
+ end
@@ -0,0 +1,133 @@
1
+ # encoding: utf-8
2
+ require File.join(File.dirname(__FILE__), 'test_helper')
3
+
4
+ ActiveRecord::Base.class_eval do
5
+ def self.validates_something_weird(*cols)
6
+ cols.each do |col|
7
+ validates_format_of col, :with => /weird/
8
+ end
9
+ end
10
+ def self.validates_something_selfcontained(*cols)
11
+ cols.each do |col|
12
+ validates_format_of col, :with => /blablabla/
13
+ end
14
+ end
15
+ end
16
+
17
+ require 'validation_reflection'
18
+
19
+ ActiveRecord::Base.class_eval do
20
+ include ::ActiveRecordExtensions::ValidationReflection
21
+ ::ActiveRecordExtensions::ValidationReflection.reflected_validations << :validates_something_weird
22
+ ::ActiveRecordExtensions::ValidationReflection.reflected_validations << {
23
+ :method => :validates_something_selfcontained,
24
+ :ignore_subvalidations => true
25
+ }
26
+ ::ActiveRecordExtensions::ValidationReflection.install(self)
27
+ end
28
+
29
+
30
+ class ValidationReflectionTest < Test::Unit::TestCase
31
+
32
+ class Dummy < ActiveRecord::Base
33
+ class << self
34
+
35
+ def create_fake_column(name, null = true, limit = nil)
36
+ sql_type = limit ? "varchar (#{limit})" : nil
37
+ col = ActiveRecord::ConnectionAdapters::Column.new(name, nil, sql_type, null)
38
+ col
39
+ end
40
+
41
+ def columns
42
+ [
43
+ create_fake_column('col0'),
44
+ create_fake_column('col1'),
45
+ create_fake_column('col1a'),
46
+ create_fake_column('col1b'),
47
+ create_fake_column('col2', false, 100),
48
+ create_fake_column('col3'),
49
+ create_fake_column('col4'),
50
+ create_fake_column('col5'),
51
+ create_fake_column('col6'),
52
+ create_fake_column('col7'),
53
+ create_fake_column('col8')
54
+ ]
55
+ end
56
+ end
57
+
58
+ has_one :nothing
59
+
60
+ validates_presence_of :col1
61
+ validates_presence_of [ :col1a, :col1b ]
62
+ validates_length_of :col2, :maximum => 100
63
+ validates_format_of :col3, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
64
+ validates_numericality_of :col4, :only_integer => true
65
+ validates_numericality_of :col5, :less_than => 5
66
+ validates_something_weird :col6
67
+ validates_something_selfcontained :col7
68
+ validates_size_of :col8, :is => 5
69
+ end
70
+
71
+ def test_sanity
72
+ assert_equal [], Dummy.reflect_on_validations_for(:col0)
73
+ end
74
+
75
+ def test_validates_presence_of_is_reflected
76
+ reflections = Dummy.reflect_on_validations_for(:col1)
77
+ assert reflections.all? { |r| r.name.to_s == 'col1' }
78
+ assert reflections.find { |r| r.macro == :validates_presence_of }
79
+ end
80
+
81
+ def test_string_limit_is_reflected
82
+ reflections = Dummy.reflect_on_validations_for(:col2)
83
+ assert reflections.any? { |r| r.macro == :validates_length_of && r.options[:maximum] == 100 }
84
+ end
85
+
86
+ def test_format_is_reflected
87
+ reflections = Dummy.reflect_on_validations_for(:col3)
88
+ assert reflections.any? { |r| r.macro == :validates_format_of && r.options[:with] == /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i }
89
+ end
90
+
91
+ def test_numeric_integer_is_reflected
92
+ reflections = Dummy.reflect_on_validations_for(:col4)
93
+ assert reflections.any? { |r| r.macro == :validates_numericality_of && r.options[:only_integer] }
94
+ end
95
+
96
+ def test_numeric_is_reflected
97
+ reflections = Dummy.reflect_on_validations_for(:col5)
98
+ assert reflections.any? { |r| r.macro == :validates_numericality_of }
99
+ end
100
+
101
+ def test_validation_options_are_reflected
102
+ reflections = Dummy.reflect_on_validations_for(:col5)
103
+ refl = reflections[0]
104
+ assert_equal 5, refl.options[:less_than]
105
+ end
106
+
107
+ def test_custom_validations_are_reflected
108
+ reflections = Dummy.reflect_on_validations_for(:col6)
109
+ assert reflections.any? { |r| r.macro == :validates_something_weird }
110
+ assert reflections.any? { |r| r.macro == :validates_format_of }
111
+ end
112
+
113
+ def test_custom_validations_with_options_are_reflected
114
+ reflections = Dummy.reflect_on_validations_for(:col7)
115
+ assert reflections.any? { |r| r.macro == :validates_something_selfcontained }
116
+ end
117
+
118
+ def test_subvalidations_are_reflected
119
+ reflections = Dummy.reflect_on_validations_for(:col6)
120
+ assert_equal 2, reflections.size
121
+ end
122
+
123
+ def test_ignored_subvalidations_are_not_reflected
124
+ reflections = Dummy.reflect_on_validations_for(:col7)
125
+ assert_equal 1, reflections.size
126
+ end
127
+
128
+ def test_string_size_is_reflected
129
+ reflections = Dummy.reflect_on_validations_for(:col8)
130
+ assert reflections.any? { |r| r.macro == :validates_size_of && r.options[:is] == 5 }
131
+ end
132
+
133
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: liangzan-validation_reflection
3
+ version: !ruby/object:Gem::Version
4
+ hash: 1
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 9
10
+ version: 0.3.9
11
+ platform: ruby
12
+ authors:
13
+ - Christopher Redinger
14
+ - Wong Liang Zan
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-08-29 00:00:00 +08:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description: Adds reflective access to validations
24
+ email: liangzan@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files:
30
+ - README
31
+ files:
32
+ - .gitignore
33
+ - CHANGELOG
34
+ - MIT-LICENSE
35
+ - README
36
+ - Rakefile
37
+ - VERSION.yml
38
+ - liangzan-validation_reflection.gemspec
39
+ - lib/validation_reflection.rb
40
+ - rails/init.rb
41
+ - test/test_helper.rb
42
+ - test/validation_reflection_test.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/liangzan/validation_reflection
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ hash: 3
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.7
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: Adds reflective access to validations
77
+ test_files:
78
+ - test/test_helper.rb
79
+ - test/validation_reflection_test.rb