sequel_notnaughty 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,4 @@
1
+ === 0.6.1 (2008-10-10)
2
+ * split from not-naughty gem
3
+ * added gemspecs for github
4
+ * added uniqueness validation with scope [resolves:#19650]
data/COPYING ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2007-2008 Florian Aßmann
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,119 @@
1
+ require "rake"
2
+ require "rake/clean"
3
+ require "rake/gempackagetask"
4
+ require "rake/rdoctask"
5
+ require "fileutils"
6
+ include FileUtils
7
+
8
+ ##############################################################################
9
+ # Configuration
10
+ ##############################################################################
11
+ NAME = "sequel_notnaughty"
12
+ VERS = "0.6.1"
13
+ CLEAN.include %w[ pkg doc coverage ]
14
+ RDOC_OPTS = [
15
+ "--quiet",
16
+ "--title", "Ruby Sequel adapater for NotNaughty: The Validation Framework",
17
+ "--opname", "index.html",
18
+ "--inline-source",
19
+ "--line-numbers",
20
+ "--main", "README.rdoc",
21
+ "--inline-source",
22
+ "--charset", "utf-8"
23
+ ]
24
+
25
+ ##############################################################################
26
+ # RDoc
27
+ ##############################################################################
28
+ task :doc => [:rdoc]
29
+
30
+ Rake::RDocTask.new do |rdoc|
31
+ rdoc.rdoc_dir = "doc"
32
+ rdoc.options += RDOC_OPTS
33
+ rdoc.main = "README.rdoc"
34
+ rdoc.title = "Ruby Sequel adapater for NotNaughty: The Validation Framework"
35
+ rdoc.rdoc_files.add %w[README.rdoc COPYING CHANGELOG.rdoc lib/**/*.rb]
36
+ end
37
+
38
+ ##############################################################################
39
+ # specs
40
+ ##############################################################################
41
+ require "spec/rake/spectask"
42
+
43
+ desc "Run specs with coverage"
44
+ Spec::Rake::SpecTask.new("spec") do |t|
45
+ t.spec_files = FileList["spec/**/*_spec.rb"]
46
+ t.spec_opts = File.read("spec/spec.opts").split("\n")
47
+ t.rcov_opts = File.read("spec/rcov.opts").split("\n")
48
+ t.rcov = true
49
+ end
50
+
51
+ desc "Run specs without coverage"
52
+ Spec::Rake::SpecTask.new("spec_no_cov") do |t|
53
+ t.spec_files = FileList["spec/**/*_spec.rb"]
54
+ t.spec_opts = File.read("spec/spec.opts").split("\n")
55
+ end
56
+
57
+ desc "check documentation coverage"
58
+ task :dcov do
59
+ sh "find lib -name '*.rb' | xargs dcov"
60
+ end
61
+
62
+ ##############################################################################
63
+ # Gem packaging
64
+ ##############################################################################
65
+ desc "Packages up Ruby Sequel adapter for NotNaughty."
66
+ task :default => [:package]
67
+ task :package => [:clean]
68
+
69
+ spec = Gem::Specification.new do |s|
70
+ s.name = NAME
71
+ s.rubyforge_project = NAME
72
+ s.version = VERS
73
+ s.platform = Gem::Platform::RUBY
74
+ s.has_rdoc = true
75
+ s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "COPYING"]
76
+ s.summary = "Gifts Ruby Sequel with heavily armed validations."
77
+ s.description = s.summary
78
+ s.author = "Florian Aßmann"
79
+ s.email = "boof@monkey-patch.me"
80
+ s.homepage = "http://monkey-patch.me/p/not-naughty"
81
+ s.required_ruby_version = ">= 1.8.6"
82
+ s.add_dependency("not-naughty", "= #{ VERS }")
83
+
84
+ s.files = %w(COPYING README.rdoc Rakefile) + Dir.glob("{spec,lib}/**/*")
85
+
86
+ s.require_path = "lib"
87
+ end
88
+
89
+ Rake::GemPackageTask.new(spec) do |p|
90
+ p.need_tar = true
91
+ p.gem_spec = spec
92
+ end
93
+
94
+ ##############################################################################
95
+ # installation & removal
96
+ ##############################################################################
97
+ task :install do
98
+ sh %{rake package}
99
+ sh %{sudo gem install pkg/#{NAME}-#{VERS}}
100
+ end
101
+
102
+ task :install_no_docs do
103
+ sh %{rake package}
104
+ sh %{sudo gem install pkg/#{NAME}-#{VERS} --no-rdoc --no-ri}
105
+ end
106
+
107
+ task :uninstall => [:clean] do
108
+ sh %{sudo gem uninstall #{NAME}}
109
+ end
110
+
111
+ ##############################################################################
112
+ # gem and rdoc release
113
+ ##############################################################################
114
+ task :release => [:package] do
115
+ sh %{rubyforge login}
116
+ sh %{rubyforge add_release not-naughty not-naughty #{VERS} pkg/#{NAME}-#{VERS}.tgz}
117
+ sh %{rubyforge add_file not-naughty not-naughty #{VERS} pkg/#{NAME}-#{VERS}.gem}
118
+ end
119
+
@@ -0,0 +1,72 @@
1
+ require 'rubygems'
2
+
3
+ gem 'sequel', '>= 2.5.0'
4
+ require 'sequel'
5
+
6
+ #gem 'not-naughty', '0.6.1'
7
+ require 'not_naughty'
8
+
9
+ ::NotNaughty::Validation.load(:acceptance, :confirmation, :format, :length, :numericality, :presence)
10
+ require "#{ File.dirname __FILE__ }/validations/uniqueness_validation.rb"
11
+
12
+ module Sequel #:nodoc:
13
+ module Plugins #:nodoc:
14
+ # == Adapter for Ruby Sequel
15
+ #
16
+ # Validate all your Ruby Sequel models with NotNaughty:
17
+ #
18
+ # class Sequel::Model
19
+ # is :notnaughty
20
+ # end
21
+ #
22
+ # Validate just specific models:
23
+ #
24
+ # class YourModel < Sequel::Model
25
+ # is :notnaughty
26
+ # end
27
+ class NotNaughty < NotNaughty::Validator
28
+
29
+ # Hook called by plugin api.
30
+ def self.apply(receiver, *args)
31
+ receiver.extend ::NotNaughty
32
+ receiver.validator self, :create, :update
33
+ end
34
+
35
+ # Returns state for given instance.
36
+ def get_state(instance)
37
+ if instance.new? then @states[:create] else @states[:update] end
38
+ end
39
+
40
+ # Ensures API compatibility.
41
+ module InstanceMethods
42
+ def validate #:nodoc:
43
+ errors.clear
44
+ return false if before_validation == false
45
+ self.class.validator.invoke self
46
+ after_validation
47
+ nil
48
+ end
49
+ end
50
+ # Ensures API compatibility.
51
+ module ClassMethods
52
+
53
+ def validations #:nodoc:
54
+ validator.states.
55
+ inject({}) do |validations, state_with_name|
56
+ validations.merge(state_with_name[1].validations) {|k,o,n| o|n}
57
+ end
58
+ end
59
+ def has_validations?() #:nodoc:
60
+ validator.has_validations?
61
+ end
62
+ def validate(instance) #:nodoc:
63
+ validator.invoke instance
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ # this isn't a one-liner...
70
+ Notnaughty = NotNaughty
71
+ end
72
+ end
@@ -0,0 +1,47 @@
1
+ module NotNaughty
2
+
3
+ # Validates only if the fields in the model (specified by atts) are
4
+ # unique in the database. You should also add a unique index in the
5
+ # database, as this suffers from a fairly obvious race condition.
6
+ #
7
+ # Possible Options:
8
+ # <tt>:in</tt>:: scope could be a single or multiple attributes
9
+ # <tt>:message</tt>:: see NotNaughty::Errors for details
10
+ # <tt>:if</tt>:: see NotNaughty::Validation::Condition for details
11
+ # <tt>:unless</tt>:: see NotNaughty::Validation::Condition for details
12
+ class UniquenessValidation < Validation
13
+
14
+ def initialize(valid, attributes) #:nodoc:
15
+ valid[:message] ||= '%s is already taken.'
16
+ valid[:in] = case valid[:in]
17
+ when Array; valid[:in].map { |scp| scp.to_sym }
18
+ when String, String; [ valid[:in].to_sym ]
19
+ else
20
+ []
21
+ end
22
+
23
+ if valid[:allow_blank] or valid[:allow_nil]
24
+ valid[:allow] = valid[:allow_blank] ? :blank? : :nil?
25
+
26
+ super valid, attributes do |obj, attr, value|
27
+ scope_values = obj.values.values_at(*valid[:in])
28
+ scope = Hash[*valid[:in].zip(scope_values).flatten]
29
+
30
+ value.send valid[:allow] or
31
+ obj.model.find(scope.merge(attr => value)).nil? or
32
+ obj.errors.add attr, valid[:message]
33
+ end
34
+ else
35
+
36
+ super valid, attributes do |obj, attr, value|
37
+ scope_values = obj.values.values_at(*valid[:in])
38
+ scope = Hash[*valid[:in].zip(scope_values).flatten]
39
+
40
+ obj.model.find(scope.merge(attr => value)).nil? or
41
+ obj.errors.add attr, valid[:message]
42
+ end
43
+ end
44
+ end
45
+
46
+ end
47
+ end
data/spec/rcov.opts ADDED
@@ -0,0 +1,4 @@
1
+ --exclude
2
+ gems
3
+ --exclude
4
+ spec
@@ -0,0 +1,16 @@
1
+ require "#{ File.dirname __FILE__ }/spec_helper.rb"
2
+
3
+ DB = Sequel::Model.db = Sequel.sqlite
4
+
5
+ Sequel::Model.instance_eval do
6
+ %w[validate valid?].
7
+ each {|m| undef_method m.to_sym}
8
+ end
9
+
10
+ (class << Sequel::Model; self; end).module_eval do
11
+ %w[validate validates validates_acceptance_of validates_confirmation_of
12
+ validates_each validates_format_of validates_length_of
13
+ validates_numericality_of validates_presence_of validations
14
+ has_validations?].
15
+ each {|m| undef_method m.to_sym}
16
+ end
@@ -0,0 +1,92 @@
1
+ require "#{ File.dirname __FILE__ }/sequel_spec_helper.rb"
2
+
3
+ describe Sequel::Plugins::NotNaughty do
4
+
5
+ before(:each) do
6
+ @obj = Class.new(Sequel::Model) { is :notnaughty }
7
+ end
8
+
9
+ it "should delegate validation methods in receiver" do
10
+ @instance = @obj.new
11
+
12
+ @obj.validator.should be_an_instance_of(Sequel::Plugins::NotNaughty)
13
+ @obj.validator.should_receive(:states).and_return({})
14
+ @obj.validator.should_receive(:has_validations?)
15
+ @obj.validator.should_receive(:invoke).with(@instance)
16
+
17
+ @instance.errors.should be_an_instance_of(subject::Violation)
18
+ @instance.should respond_to(:validate)
19
+ @instance.should respond_to(:valid?)
20
+
21
+ @obj.validations
22
+ @obj.has_validations?
23
+ @obj.validate @instance
24
+ end
25
+ it "should return validations" do
26
+ @obj.validations.should be_an_instance_of(Hash)
27
+ end
28
+ it "should not have validations" do
29
+ @obj.has_validations?.should == false
30
+ end
31
+ it "should add_validation instance of validation" do
32
+ validation = Class.new(subject::Validation)
33
+
34
+ @obj.validator.add_validation validation, :attribute
35
+
36
+ validations = @obj.validator.states[:create][:attribute]
37
+ validations.length.should == 1
38
+ validations.first.should be_an_instance_of(validation)
39
+
40
+ validations = @obj.validator.states[:update][:attribute]
41
+ validations.length.should == 1
42
+ validations.first.should be_an_instance_of(validation)
43
+
44
+ @obj.validator.add_validation validation, :attribute, :on => :create
45
+
46
+ validations = @obj.validator.states[:create][:attribute]
47
+ validations.length.should == 2
48
+ validations[0].should be_an_instance_of(validation)
49
+ validations[1].should be_an_instance_of(validation)
50
+
51
+ validations = @obj.validator.states[:update][:attribute]
52
+ validations.length.should == 1
53
+ validations.first.should be_an_instance_of(validation)
54
+ end
55
+ it "should have validations" do
56
+ validation = Class.new(subject::Validation)
57
+ @obj.validator.add_validation validation, :attribute
58
+
59
+ @obj.has_validations?.should == true
60
+ end
61
+ it "should add_validation blocks as Validation" do
62
+ @obj.validator.add_validation(:attribute) { |o, a, v| }
63
+
64
+ @obj.validator.states[:create][:attribute].first.
65
+ should be_kind_of(subject::Validation)
66
+ @obj.validator.states[:update][:attribute].first.
67
+ should be_kind_of(subject::Validation)
68
+ end
69
+ it "should run validations on object when it's invoked" do
70
+ probe = mock 'Probe', :new? => true
71
+ probe.should_receive(:attribute).and_return(1)
72
+ probe.should_receive(:test).with(:attribute, 1)
73
+
74
+ @obj.validator.add_validation(:attribute) { |o, a, v| o.test a, v }
75
+ @obj.validate probe
76
+ end
77
+ it "should validate if saved" do
78
+ x = rand
79
+ instance = @obj.new
80
+ instance.stub!(:save!).and_return(x)
81
+ @obj.validator.should_receive(:invoke).with(instance)
82
+ instance.save.should be(x)
83
+ end
84
+ it "should run hooks if validated" do
85
+ instance = @obj.new
86
+ instance.should_receive(:before_validation)
87
+ instance.should_receive(:after_validation)
88
+ instance.stub!(:save!)
89
+ instance.save
90
+ end
91
+
92
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --backtrace
3
+ --format
4
+ specdoc
5
+ --diff
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ require "#{ File.dirname __FILE__ }/../lib/sequel_notnaughty.rb"
5
+
6
+ def subject() ::NotNaughty end
7
+ def h(something)
8
+ puts '<pre>%s</pre>' %
9
+ something.inspect.gsub(/[<>]/) {|m| (m == '<')? '&lt;': '&gt;'}
10
+ end
@@ -0,0 +1,42 @@
1
+ require "#{ File.dirname __FILE__ }/sequel_spec_helper.rb"
2
+
3
+ Sequel.sqlite
4
+
5
+ class Item < Sequel::Model
6
+ is :notnaughty
7
+ validates_uniqueness_of :name, :in => [:category, :domain]
8
+
9
+ set_schema :items do
10
+ primary_key :id
11
+ column :name, :text
12
+ column :category, :text
13
+ column :domain, :text
14
+ end
15
+ create_table
16
+
17
+ end
18
+
19
+ describe Sequel::Plugins::NotNaughty do
20
+
21
+ before(:each) { Item.delete_all }
22
+
23
+ it "should not be valid when valid isn't unique" do
24
+ item = Item.new :name => 'abc'
25
+ proc { item.save }.should_not raise_error
26
+
27
+ item = Item.new :name => 'abc'
28
+ proc { item.save }.should raise_error(Sequel::Error)
29
+ end
30
+
31
+ it "should honor scopes" do
32
+ item = Item.new :name => 'abc', :category => 'efg'
33
+ proc { item.save }.should_not raise_error
34
+
35
+ item = Item.new :name => 'abc', :category => 'efg'
36
+ proc { item.save }.should raise_error(Sequel::Error)
37
+
38
+ item = Item.new :name => 'abc', :category => 'efg', :domain => 'hij'
39
+ proc { item.save }.should_not raise_error
40
+ end
41
+
42
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel_notnaughty
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.1
5
+ platform: ruby
6
+ authors:
7
+ - "Florian A\xC3\x9Fmann"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-10-10 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: not-naughty
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.6.1
24
+ version:
25
+ description: Gifts Ruby Sequel with heavily armed validations.
26
+ email: boof@monkey-patch.me
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ - CHANGELOG.rdoc
34
+ - COPYING
35
+ files:
36
+ - COPYING
37
+ - README.rdoc
38
+ - Rakefile
39
+ - spec/rcov.opts
40
+ - spec/sequel_spec_helper.rb
41
+ - spec/sequel_validated_spec.rb
42
+ - spec/spec.opts
43
+ - spec/spec_helper.rb
44
+ - spec/validations_spec.rb
45
+ - lib/sequel_notnaughty.rb
46
+ - lib/validations
47
+ - lib/validations/uniqueness_validation.rb
48
+ - CHANGELOG.rdoc
49
+ has_rdoc: true
50
+ homepage: http://monkey-patch.me/p/not-naughty
51
+ post_install_message:
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.8.6
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project: sequel_notnaughty
71
+ rubygems_version: 1.3.0
72
+ signing_key:
73
+ specification_version: 2
74
+ summary: Gifts Ruby Sequel with heavily armed validations.
75
+ test_files: []
76
+