monkey_forms 0.0.16 → 0.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (25) hide show
  1. data/lib/monkey_forms/vendor/deep_merge/.gitignore +2 -0
  2. data/lib/monkey_forms/vendor/deep_merge/CHANGELOG +34 -0
  3. data/lib/monkey_forms/vendor/deep_merge/README +88 -0
  4. data/lib/monkey_forms/vendor/deep_merge/Rakefile +20 -0
  5. data/lib/monkey_forms/vendor/deep_merge/VERSION +1 -0
  6. data/lib/monkey_forms/vendor/deep_merge/lib/deep_merge.rb +2 -0
  7. data/lib/monkey_forms/vendor/deep_merge/lib/deep_merge/core.rb +187 -0
  8. data/lib/monkey_forms/vendor/deep_merge/lib/deep_merge/deep_merge_hash.rb +28 -0
  9. data/lib/monkey_forms/vendor/deep_merge/lib/deep_merge/rails_compat.rb +27 -0
  10. data/lib/monkey_forms/vendor/deep_merge/test/test_deep_merge.rb +572 -0
  11. data/lib/monkey_forms/vendor/grouped_validations/.gitignore +3 -0
  12. data/lib/monkey_forms/vendor/grouped_validations/.rspec +2 -0
  13. data/lib/monkey_forms/vendor/grouped_validations/Gemfile +7 -0
  14. data/lib/monkey_forms/vendor/grouped_validations/MIT-LICENSE +20 -0
  15. data/lib/monkey_forms/vendor/grouped_validations/README.rdoc +146 -0
  16. data/lib/monkey_forms/vendor/grouped_validations/Rakefile +26 -0
  17. data/lib/monkey_forms/vendor/grouped_validations/grouped_validations.gemspec +23 -0
  18. data/lib/monkey_forms/vendor/grouped_validations/init.rb +1 -0
  19. data/lib/monkey_forms/vendor/grouped_validations/lib/grouped_validations.rb +93 -0
  20. data/lib/monkey_forms/vendor/grouped_validations/lib/grouped_validations/active_model.rb +34 -0
  21. data/lib/monkey_forms/vendor/grouped_validations/lib/grouped_validations/version.rb +3 -0
  22. data/lib/monkey_forms/vendor/grouped_validations/spec/grouped_validations_spec.rb +252 -0
  23. data/lib/monkey_forms/vendor/grouped_validations/spec/spec_helper.rb +32 -0
  24. data/lib/monkey_forms/version.rb +1 -1
  25. metadata +42 -19
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ .bundle
3
+ .rvmrc
@@ -0,0 +1,2 @@
1
+ --format nested
2
+ --color
@@ -0,0 +1,7 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gem 'rspec', '~> 2.0.0'
5
+ gem 'activesupport', '~> 3.0.0'
6
+ gem 'activemodel', '~> 3.0.0'
7
+ gem 'ruby-debug'
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Adam Meehan
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.
@@ -0,0 +1,146 @@
1
+ = Grouped Validations
2
+
3
+ Allows you to define ActiveModel validation groups for more control over what validations you want to run.
4
+
5
+ This can be useful for multi-page forms or wizard style data entry.
6
+
7
+ Works with Rails 3.
8
+
9
+ For Rails 2.x support, try version 0.2.2.
10
+
11
+ == Installation
12
+
13
+ Just install the gem
14
+
15
+ gem install grouped_validations
16
+
17
+ Add it to your Rails environment gems
18
+
19
+ config.gem 'grouped_validations'
20
+
21
+
22
+ == Usage
23
+
24
+ Define validations as you would normally but inside a validation_group block which you pass a group
25
+ name to.
26
+
27
+ class Person < ActiveRecord::Base
28
+ validation_group :name do
29
+ validates_presence_of :first_name
30
+ validates_presence_of :last_name
31
+ end
32
+
33
+ validates_presence_of :sex
34
+ end
35
+
36
+ You can define validations outside the group as normal.
37
+
38
+ To check for errors for only a certain group of validations
39
+
40
+ p = Person.new
41
+ p.group_valid?(:name) # => false
42
+ p.first_name = 'John'
43
+ p.last_name = 'Smith'
44
+ p.group_valid?(:name) # => true
45
+
46
+ If you run the normal valid? method all validations, inside and outside validation groups, will be run.
47
+
48
+ p.valid? # => false because sex is not present
49
+
50
+ You can also check validation for multiple groups
51
+
52
+ p.groups_valid?(:group1, :group2)
53
+
54
+
55
+ To define validation blocks just use the respective group validation method, like so
56
+
57
+ class Person < ActiveRecord::Base
58
+ validation_group :name do
59
+ validates_presence_of :first_name
60
+ validates_presence_of :last_name
61
+ end
62
+
63
+ validate_name {|r| # something custom on save }
64
+ validate_name_on_create {|r| # something custom on create }
65
+ validate_name_on_update {|r| # something custom on update }
66
+ end
67
+
68
+
69
+ == Group Options
70
+
71
+ You can use a validation group like similar to the with_options method, but for validation methods only.
72
+
73
+ If you pass in an options hash, those options will be applied to each valiation method in the block.
74
+
75
+ validation_group :name, :if => :ready? do
76
+ validates_presence_of :first_name
77
+ validates_presence_of :last_name
78
+ end
79
+
80
+ Which effectively the same as doing the following:
81
+
82
+ validates_presence_of :first_name, :if => :ready?
83
+ validates_presence_of :last_name, :if => :ready?
84
+
85
+ If you set an option for a specific validation method, it will not be overriden with the validation group
86
+ options.
87
+
88
+ validation_group :name, :if => :ready? do
89
+ validates_presence_of :first_name
90
+ validates_presence_of :last_name, :if => {|r| !r.popstar? }
91
+ end
92
+
93
+ The last_name attribute will be required unless the person is a popstar.
94
+
95
+ The options should work for any validation method which calls the validate class method internally. This includes
96
+ all the default validations.
97
+
98
+ For more precision on when to merge the groups options you can pass an argument to the block and use it like a
99
+ with_options call. Then only those validation methods call on the argument will have the options merged in.
100
+
101
+ validation_group :name, :if => :ready? do |options|
102
+ # Options merged
103
+ options.validates_presence_of :first_name
104
+
105
+ # No options merged
106
+ validates_presence_of :last_name
107
+ end
108
+
109
+
110
+ == Grouped Errors
111
+
112
+ The errors for the model can be returned as hash with the group names as the keys. If you have a number of groups
113
+ you can deal with the error messages in specific ways per group.
114
+
115
+ validation_group :name do
116
+ validates_presence_of :first_name
117
+ validates_presence_of :last_name
118
+ end
119
+
120
+ validates_presence_of :sex
121
+
122
+ To access all errors outside of a validation group, use nil as the key:
123
+
124
+ person.grouped_errors[nil]
125
+
126
+ Use the group name as the key for all errors in that group:
127
+
128
+ person.grouped_errors[:name]
129
+
130
+ Be aware that the validations will all be run. If you have just called <tt>valid?</tt> then the same validations will be run
131
+ again and the current state of the object is used. This is for consideration if the validations are expensive, time
132
+ sensitive or you have changed the object after calling <tt>valid?</tt>.
133
+
134
+ You can use the <tt>grouped_errors</tt> method instead of <tt>valid?</tt> to check on a valid object like so:
135
+
136
+ # Validations all run
137
+ if person.grouped_errors.empty?
138
+ # object is valid
139
+ end
140
+
141
+
142
+ == Credits
143
+
144
+ * Adam Meehan (http://github.com/adzap)
145
+
146
+ Copyright (c) 2010-2011 Adam Meehan, released under the MIT license
@@ -0,0 +1,26 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/rdoctask'
5
+ require 'rspec/core/rake_task'
6
+
7
+ desc 'Default: run specs.'
8
+ task :default => :spec
9
+
10
+ desc "Run specs"
11
+ RSpec::Core::RakeTask.new(:spec)
12
+
13
+ desc "Generate code coverage"
14
+ RSpec::Core::RakeTask.new(:coverage) do |t|
15
+ t.rcov = true
16
+ t.rcov_opts = ['--exclude', 'spec']
17
+ end
18
+
19
+ desc 'Generate documentation for plugin.'
20
+ Rake::RDocTask.new(:rdoc) do |rdoc|
21
+ rdoc.rdoc_dir = 'rdoc'
22
+ rdoc.title = 'GroupedValidations'
23
+ rdoc.options << '--line-numbers' << '--inline-source'
24
+ rdoc.rdoc_files.include('README')
25
+ rdoc.rdoc_files.include('lib/**/*.rb')
26
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "grouped_validations/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{grouped_validations}
8
+ s.version = GroupedValidations::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Adam Meehan"]
11
+ s.email = %q{adam.meehan@gmail.com}
12
+ s.homepage = %q{http://github.com/adzap/grouped_validations}
13
+ s.summary = %q{Define validation groups in a model for greater control over which validations are run.}
14
+ s.description = s.summary
15
+
16
+ s.rubyforge_project = %q{grouped_validations}
17
+
18
+ s.files = `git ls-files`.split("\n") - %w{ .gitignore .rspec autotest }
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.extra_rdoc_files = ["README.rdoc"]
21
+ s.require_paths = ["lib"]
22
+ s.autorequire = %q{grouped_validations}
23
+ end
@@ -0,0 +1 @@
1
+ require 'grouped_validations'
@@ -0,0 +1,93 @@
1
+ require 'active_model/validations'
2
+ require 'grouped_validations/active_model'
3
+
4
+ module GroupedValidations
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_attribute :validation_groups
9
+ self.validation_groups = []
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ def validate(*args, &block)
15
+ return super unless @_current_validation_group
16
+
17
+ options = args.extract_options!.dup
18
+ unless @_current_validation_group[:with_options]
19
+ options.reverse_merge!(@_current_validation_group.except(:name))
20
+ end
21
+
22
+ if options.key?(:on)
23
+ options = options.dup
24
+ options[:if] = Array.wrap(options[:if])
25
+ options[:if] << "validation_context == :#{options[:on]}"
26
+ end
27
+ args << options
28
+ set_callback(:"validate_#{@_current_validation_group[:name]}", *args, &block)
29
+ end
30
+
31
+ def _define_group_validation_callbacks(group)
32
+ define_callbacks :"validate_#{group}", :scope => 'validate'
33
+ end
34
+
35
+ end
36
+
37
+ module InstanceMethods
38
+
39
+ def valid?(context=nil)
40
+ super
41
+ validation_groups.each do |group|
42
+ _run_group_validation_callbacks(group, context)
43
+ end
44
+ errors.empty?
45
+ end
46
+
47
+ def groups_valid?(*groups)
48
+ options = groups.extract_options!
49
+ errors.clear
50
+ groups.each do |group|
51
+ raise "Validation group '#{group}' not defined" unless validation_groups.include?(group)
52
+ _run_group_validation_callbacks(group, options[:context])
53
+ end
54
+ errors.empty?
55
+ end
56
+ alias_method :group_valid?, :groups_valid?
57
+
58
+ def grouped_errors(context=nil)
59
+ original_errors = @errors.dup if @errors
60
+ @errors = nil
61
+ grouped = {}
62
+
63
+ with_validation_context(context) do
64
+ _run_validate_callbacks
65
+ grouped[nil] = @errors
66
+
67
+ validation_groups.each do |group|
68
+ @errors = nil
69
+ send(:"_run_validate_#{group}_callbacks")
70
+ grouped[group] = @errors
71
+ end
72
+ end
73
+ grouped.values.all?(&:empty?) ? {} : grouped
74
+ ensure
75
+ @errors = original_errors
76
+ end
77
+
78
+ def _run_group_validation_callbacks(group, context=nil)
79
+ with_validation_context(context) do
80
+ send(:"_run_validate_#{group}_callbacks")
81
+ end
82
+ end
83
+
84
+ def with_validation_context(context)
85
+ context ||= (persisted? ? :update : :create)
86
+ current_context, self.validation_context = validation_context, context
87
+ yield
88
+ ensure
89
+ self.validation_context = current_context
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,34 @@
1
+ module ActiveModel
2
+ module Validations
3
+
4
+ module ClassMethods
5
+
6
+ def validation_group(group, options={}, &block)
7
+ raise "The validation_group method requires a block" unless block_given?
8
+
9
+ unless include?(GroupedValidations)
10
+ include GroupedValidations
11
+ end
12
+
13
+ self.validation_groups += [ group ]
14
+
15
+ _define_group_validation_callbacks(group)
16
+
17
+ options[:name] = group
18
+
19
+ if block.arity == 1
20
+ @_current_validation_group = options.merge(:with_options => true)
21
+ with_options(options.except(:name)) do |config|
22
+ yield config
23
+ end
24
+ else
25
+ @_current_validation_group = options
26
+ yield
27
+ end
28
+ @_current_validation_group = nil
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module GroupedValidations
2
+ VERSION = '0.3.0'
3
+ end
@@ -0,0 +1,252 @@
1
+ require 'spec_helper'
2
+
3
+ describe GroupedValidations do
4
+ let(:person) { Person.new }
5
+
6
+ before do
7
+ reset_class Person
8
+ end
9
+
10
+ it "should add validation_group class method" do
11
+ Person.should respond_to(:validation_group)
12
+ end
13
+
14
+ describe ".validation_group" do
15
+ it "should store defined validation group names" do
16
+ Person.class_eval do
17
+ validation_group(:dummy) { }
18
+ end
19
+ Person.validation_groups.should == [:dummy]
20
+ end
21
+
22
+ it "it should add group_valid? method which takes a group name param" do
23
+ Person.class_eval do
24
+ validation_group(:dummy) { }
25
+ end
26
+
27
+ person.group_valid?(:dummy)
28
+ end
29
+
30
+ context "with options" do
31
+ context "as implicit block" do
32
+ it 'should pass options for group to validations' do
33
+ Person.class_eval do
34
+ validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do
35
+ validates_presence_of :first_name
36
+ end
37
+ end
38
+
39
+ person.group_valid?(:name)
40
+ person.should have(1).errors
41
+
42
+ person.last_name = 'smith'
43
+ person.group_valid?(:name)
44
+ person.should have(0).errors
45
+ end
46
+
47
+ it 'should not override explicit validation method options' do
48
+ Person.class_eval do
49
+ validation_group(:name, :if => lambda { true }) do
50
+ validates_presence_of :first_name, :if => lambda { false }
51
+ end
52
+ end
53
+
54
+ person.group_valid?(:name)
55
+ person.should have(0).errors
56
+ end
57
+ end
58
+
59
+ context "as block argument" do
60
+ it 'should pass options for group to validations' do
61
+ Person.class_eval do
62
+ validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do |options|
63
+ options.validates_presence_of :first_name
64
+ end
65
+ end
66
+
67
+ person.group_valid?(:name)
68
+ person.should have(1).errors
69
+
70
+ person.last_name = 'smith'
71
+ person.group_valid?(:name)
72
+ person.should have(0).errors
73
+ end
74
+
75
+ it 'should not override explicit options' do
76
+ Person.class_eval do
77
+ validation_group(:name, :if => lambda {|r| r.last_name.nil? }) do |options|
78
+ options.validates_presence_of :first_name, :if => lambda { false }
79
+ end
80
+ end
81
+
82
+ person.group_valid?(:name)
83
+ person.should have(0).errors
84
+ end
85
+
86
+ it 'should not apply options to validations methods not using block argument' do
87
+ Person.class_eval do
88
+ validation_group(:name, :if => lambda { false }) do |options|
89
+ options.validates_presence_of :first_name
90
+ validates_presence_of :last_name
91
+ end
92
+ end
93
+
94
+ person.group_valid?(:name)
95
+ person.errors[:first_name].should be_empty
96
+ person.errors[:last_name].should_not be_empty
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ describe "#group_valid?" do
103
+ it "should run the validations defined inside the validation group" do
104
+ Person.class_eval do
105
+ validation_group :name do
106
+ validates_presence_of :first_name
107
+ validates_presence_of :last_name
108
+ end
109
+ end
110
+
111
+ person.group_valid?(:name)
112
+ person.should have(2).errors
113
+
114
+ person.first_name = 'Dave'
115
+ person.last_name = 'Smith'
116
+ person.group_valid?(:name)
117
+ person.should have(0).errors
118
+ end
119
+
120
+ it "should raise exception if valiation group not defined" do
121
+ expect { person.group_valid?(:dummy) }.should raise_exception
122
+ end
123
+
124
+ it "should run all validation groups passed to groups_valid?" do
125
+ Person.class_eval do
126
+ validation_group :first_name_group do
127
+ validates_presence_of :first_name
128
+ end
129
+ validation_group :last_name_group do
130
+ validates_presence_of :last_name
131
+ end
132
+ end
133
+
134
+ person.groups_valid?(:first_name_group, :last_name_group)
135
+ person.should have(2).errors
136
+ end
137
+
138
+ context "with validation context" do
139
+ it "should run only validations for explicit context" do
140
+ Person.class_eval do
141
+ validation_group :name do
142
+ validates_presence_of :last_name, :on => :update
143
+ end
144
+ end
145
+
146
+ person.persisted = false
147
+ person.last_name = nil
148
+ person.group_valid?(:name, :context => :create)
149
+ person.should have(0).errors
150
+
151
+ person.persisted = true
152
+ person.group_valid?(:name, :context => :update)
153
+ person.should have(1).errors
154
+
155
+ person.last_name = 'Smith'
156
+ person.group_valid?(:name)
157
+ person.should have(0).errors
158
+ end
159
+
160
+ it "should run only validations for implicit model context" do
161
+ Person.class_eval do
162
+ validation_group :name do
163
+ validates_presence_of :first_name, :on => :create
164
+ end
165
+ end
166
+
167
+ person.persisted = false
168
+ person.group_valid?(:name)
169
+ person.should have(1).errors
170
+
171
+ person.first_name = 'Dave'
172
+ person.group_valid?(:name)
173
+ person.should have(0).errors
174
+
175
+ person.persisted = true
176
+ person.first_name = nil
177
+ person.group_valid?(:name)
178
+ person.should have(0).errors
179
+ end
180
+
181
+ end
182
+ end
183
+
184
+ describe "#valid?" do
185
+ it "should run all validation including groups when valid? method called" do
186
+ Person.class_eval do
187
+ validation_group :first_name_group do
188
+ validates_presence_of :first_name
189
+ end
190
+ validation_group :last_name_group do
191
+ validates_presence_of :last_name
192
+ end
193
+ validates_presence_of :sex
194
+ end
195
+
196
+ person.valid?
197
+ person.should have(3).errors
198
+ end
199
+ end
200
+
201
+ describe "#grouped_errors" do
202
+ before do
203
+ Person.class_eval do
204
+ validation_group :first_name_group do
205
+ validates_presence_of :first_name
206
+ end
207
+ validation_group :last_name_group do
208
+ validates_presence_of :last_name
209
+ end
210
+ validates_presence_of :sex
211
+ end
212
+ end
213
+
214
+ it 'should return hash of error hashes with validation groups as keys' do
215
+ errors = person.grouped_errors
216
+ errors[:first_name_group].should == {:first_name => ["can't be blank"]}
217
+ errors[:last_name_group].should == {:last_name => ["can't be blank"]}
218
+ end
219
+
220
+ it 'should return hash of errors for validations outside a validation group, for nil key' do
221
+ errors = person.grouped_errors
222
+ errors[nil][:sex].should == ["can't be blank"]
223
+ end
224
+
225
+ it 'should be empty if no errors' do
226
+ person.first_name = 'Dave'
227
+ person.last_name = 'Smith'
228
+ person.sex = 'Male'
229
+
230
+ person.grouped_errors.should be_empty
231
+ end
232
+
233
+ end
234
+
235
+ # Can no longer be done. Unless I find a work around.
236
+ # it "should allow a validation group to appended with subsequent blocks" do
237
+ # Person.class_eval do
238
+ # validation_group :name do
239
+ # validates_presence_of :first_name
240
+ # end
241
+ # validation_group :name do
242
+ # validates_presence_of :last_name
243
+ # end
244
+ # end
245
+
246
+ #
247
+ # person.group_valid?(:name)
248
+ # puts person.errors.inspect
249
+ # person.should have(2).errors
250
+ # end
251
+
252
+ end