twin_validator 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format documentation
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Nathan Kleyn
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.
data/README.rdoc ADDED
@@ -0,0 +1,24 @@
1
+ = twin_validator
2
+
3
+ A simple twin field validator for Rails 3.
4
+
5
+ gem sources -a http://gemcutter.org/
6
+ gem install twin_validator
7
+
8
+ == What is a twin field?
9
+
10
+ A twin field is a field that has a useless value unless a previous field has been set. This often manifiests itself as checkbox/text field or select/text field pair. Think in terms of a select box with one option for 'Other'; the 'Other' option should show a text box, validated only when it it set as such.
11
+
12
+ You can validate the text field only when the previous field is set to your chosen value. Jump into your model and validate like so:
13
+
14
+ validates :field, :inclusion => { :in => [true, false }
15
+ validates :other_field, :twin => { :twins => [:field] }
16
+
17
+ For now, the only options you can use are:
18
+
19
+ :twins # An Enumerable of symbols to resolve as attributes of the model.
20
+ :check_against # A value that, if the twins are set to, this model should be validated as a result.
21
+
22
+ == Copyright
23
+
24
+ Copyright (c) 2010 Nathan Kleyn. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "twin_validator"
8
+ gem.summary = "A simple twin field validator for Rails 3."
9
+ gem.description = "A simple twin field validator for Rails 3."
10
+ gem.email = "nathan@unfinitydesign.com"
11
+ gem.homepage = "http://github.com/nathankleyn/twin_validator"
12
+ gem.authors = ["Nathan Kleyn"]
13
+
14
+ gem.add_dependency 'activemodel', '>= 3.0.0.beta4'
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+
22
+ # Rake RSpec2 task stuff
23
+ gem 'rspec', '>= 2.0.0.beta.12'
24
+ gem 'rspec-expectations'
25
+
26
+ require 'rspec/core/rake_task'
27
+
28
+ desc "Run the specs under spec"
29
+ RSpec::Core::RakeTask.new do |t|
30
+
31
+ end
32
+
33
+ task :default => :spec
34
+
35
+ require 'rake/rdoctask'
36
+ Rake::RDocTask.new do |rdoc|
37
+ if File.exist?('VERSION')
38
+ version = File.read('VERSION')
39
+ else
40
+ version = ""
41
+ end
42
+
43
+
44
+ rdoc.rdoc_dir = 'rdoc'
45
+ rdoc.title = "twin_validator #{version}"
46
+ rdoc.rdoc_files.include('README*')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
48
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1
@@ -0,0 +1,28 @@
1
+ require 'active_model'
2
+
3
+ module ActiveModel
4
+ module Validations
5
+ class TwinValidator < ActiveModel::EachValidator
6
+ def check_validity!
7
+ raise ArgumentError, "An Enumerable object is required and must be supplied as the " <<
8
+ ":twins option of the configuration hash" unless options[:twins].respond_to?(:each)
9
+ end
10
+
11
+ def validate_each(record, attribute, value)
12
+ options[:twins].each do |twin|
13
+ value = record.send(:read_attribute_for_validation, twin)
14
+ record.errors.add_on_blank(attribute, options[:message]) if value
15
+ end
16
+ end
17
+
18
+ module HelperMethods
19
+
20
+ def validates_twin_of(*attr_names)
21
+ validates_with TwinValidator, _merge_attributes(attr_names)
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
28
+ end
data/locales/en.yml ADDED
@@ -0,0 +1,6 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+
4
+ en:
5
+ errors:
6
+ messages:
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
4
+ require 'rubygems'
5
+ require 'active_model'
6
+
7
+ require 'lib/date_validator'
8
+ require 'rspec'
9
+ require 'rspec/autorun'
10
+
11
+ I18n.load_path += Dir[File.join('locales', '*.{rb,yml}')]
12
+
13
+ class TestRecord
14
+ include ActiveModel::Validations
15
+ attr_accessor :expiration_date
16
+
17
+ def initialize(expiration_date)
18
+ @expiration_date = expiration_date
19
+ end
20
+ end
@@ -0,0 +1,109 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ require 'active_support/time' # For testing Date and TimeWithZone objects
4
+
5
+ describe "DateValidator" do
6
+
7
+ before(:each) do
8
+ TestRecord.reset_callbacks(:validate)
9
+ end
10
+
11
+ it "should check validity of the arguments" do
12
+ [3, "foo", 1..6].each do |wrong_argument|
13
+ expect {
14
+ TestRecord.validates :expiration_date, :date => {:before => wrong_argument}
15
+ }.to raise_error(ArgumentError, ":before must be a time, a date, a time_with_zone, a symbol or a proc")
16
+ end
17
+ end
18
+
19
+ [:valid,:invalid].each do |should_be|
20
+
21
+ _context = should_be == :valid ? 'when value validates correctly' : 'when value does not match validation requirements'
22
+
23
+ context _context do
24
+
25
+ [:after, :before, :after_or_equal_to, :before_or_equal_to].each do |check|
26
+
27
+ now = Time.now.to_datetime
28
+
29
+ model_date = case check
30
+ when :after then should_be == :valid ? now + 21000 : now - 1
31
+ when :before then should_be == :valid ? now - 21000 : now + 1
32
+ when :after_or_equal_to then should_be == :valid ? now : now - 21000
33
+ when :before_or_equal_to then should_be == :valid ? now : now + 21000
34
+ end
35
+
36
+ it "should ensure that an attribute is #{should_be} when #{should_be == :valid ? 'respecting' : 'offending' } the #{check} check" do
37
+ TestRecord.validates :expiration_date, :date => {:"#{check}" => Time.now}
38
+ model = TestRecord.new(model_date)
39
+ should_be == :valid ? model.should(be_valid, "an attribute should be valid when respecting the #{check} check") : model.should_not(be_valid, "an attribute should be invalidwhen offending the #{check} check")
40
+ end
41
+
42
+ if _context == 'when value does not match validation requirements'
43
+
44
+ it "should yield a default error message indicating that value must be #{check} validation requirements" do
45
+ TestRecord.validates :expiration_date, :date => {:"#{check}" => Time.now}
46
+ model = TestRecord.new(model_date)
47
+ model.should_not be_valid
48
+ model.errors[:expiration_date].should == ["must be " + check.to_s.gsub('_',' ') + " #{Time.now}"]
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
55
+ if _context == 'when value does not match validation requirements'
56
+
57
+ it "should allow for a custom validation message" do
58
+ TestRecord.validates :expiration_date, :date => {:before_or_equal_to => Time.now, :message => 'must be after Christmas'}
59
+ model = TestRecord.new(Time.now + 21000)
60
+ model.should_not be_valid
61
+ model.errors[:expiration_date].should == ["must be after Christmas"]
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ extra_types = [:proc, :symbol]
71
+ extra_types.push(:date) if defined?(Date) and defined?(DateTime)
72
+ extra_types.push(:time_with_zone) if defined?(ActiveSupport::TimeWithZone)
73
+
74
+ extra_types.each do |type|
75
+ it "should accept a #{type} as an argument to a check" do
76
+ case type
77
+ when :proc then
78
+ expect {
79
+ TestRecord.validates :expiration_date, :date => {:after => Proc.new{Time.now + 21000}}
80
+ }.to_not raise_error
81
+ when :symbol then
82
+ expect {
83
+ TestRecord.send(:define_method, :min_date, lambda { Time.now + 21000 })
84
+ TestRecord.validates :expiration_date, :date => {:after => :min_date}
85
+ }.to_not raise_error
86
+ when :date then
87
+ expect {
88
+ TestRecord.validates :expiration_date, :date => {:after => Time.now.to_date}
89
+ }.to_not raise_error
90
+ when :time_with_zone then
91
+ expect {
92
+ Time.zone = "Hawaii"
93
+ TestRecord.validates :expiration_date, :date => {:before => Time.zone.parse((Time.now + 21000).to_s)}
94
+ }.to_not raise_error
95
+ end
96
+ end
97
+ end
98
+
99
+ it "should gracefully handle an unexpected result from a proc argument evaluation" do
100
+ TestRecord.validates :expiration_date, :date => {:after => Proc.new{ nil }}
101
+ TestRecord.new(Time.now).should_not be_valid
102
+ end
103
+
104
+ it "should gracefully handle an unexpected result from a symbol argument evaluation" do
105
+ TestRecord.send(:define_method, :min_date, lambda { nil })
106
+ TestRecord.validates :expiration_date, :date => {:after => :min_date}
107
+ TestRecord.new(Time.now).should_not be_valid
108
+ end
109
+ end
@@ -0,0 +1,56 @@
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{twin_validator}
8
+ s.version = "0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Nathan Kleyn"]
12
+ s.date = %q{2010-07-19}
13
+ s.description = %q{A simple twin field validator for Rails 3.}
14
+ s.email = %q{nathan@unfinitydesign.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ ".rspec",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "twin_validator.gemspec",
28
+ "lib/twin_validator.rb",
29
+ "locales/en.yml",
30
+ "spec/twin_validator_spec.rb",
31
+ "spec/spec_helper.rb"
32
+ ]
33
+ s.homepage = %q{http://github.com/nathankleyn/twin_validator}
34
+ s.rdoc_options = ["--charset=UTF-8"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = %q{1.3.7}
37
+ s.summary = %q{A simple twin field validator for Rails 3.}
38
+ s.test_files = [
39
+ "spec/twin_validator_spec.rb",
40
+ "spec/spec_helper.rb"
41
+ ]
42
+
43
+ if s.respond_to? :specification_version then
44
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
45
+ s.specification_version = 3
46
+
47
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
48
+ s.add_runtime_dependency(%q<activemodel>, [">= 3.0.0.beta4"])
49
+ else
50
+ s.add_dependency(%q<activemodel>, [">= 3.0.0.beta4"])
51
+ end
52
+ else
53
+ s.add_dependency(%q<activemodel>, [">= 3.0.0.beta4"])
54
+ end
55
+ end
56
+
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: twin_validator
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Nathan Kleyn
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-07-19 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activemodel
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 299253624
29
+ segments:
30
+ - 3
31
+ - 0
32
+ - 0
33
+ - beta4
34
+ version: 3.0.0.beta4
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description: A simple twin field validator for Rails 3.
38
+ email: nathan@unfinitydesign.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - LICENSE
45
+ - README.rdoc
46
+ files:
47
+ - .document
48
+ - .gitignore
49
+ - .rspec
50
+ - LICENSE
51
+ - README.rdoc
52
+ - Rakefile
53
+ - VERSION
54
+ - twin_validator.gemspec
55
+ - lib/twin_validator.rb
56
+ - locales/en.yml
57
+ - spec/twin_validator_spec.rb
58
+ - spec/spec_helper.rb
59
+ has_rdoc: true
60
+ homepage: http://github.com/nathankleyn/twin_validator
61
+ licenses: []
62
+
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --charset=UTF-8
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ requirements: []
87
+
88
+ rubyforge_project:
89
+ rubygems_version: 1.3.7
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: A simple twin field validator for Rails 3.
93
+ test_files:
94
+ - spec/twin_validator_spec.rb
95
+ - spec/spec_helper.rb