sequel_notnaughty 0.6.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/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
+