twin_validator 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.
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