not-naughty 0.6.0
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 +46 -0
 - data/COPYING +18 -0
 - data/README.rdoc +59 -0
 - data/Rakefile +126 -0
 - data/lib/core_extensions.rb +20 -0
 - data/lib/not_naughty.rb +86 -0
 - data/lib/not_naughty/builder.rb +68 -0
 - data/lib/not_naughty/error_handler.rb +48 -0
 - data/lib/not_naughty/instance_methods.rb +20 -0
 - data/lib/not_naughty/validation.rb +126 -0
 - data/lib/not_naughty/validations/acceptance_validation.rb +46 -0
 - data/lib/not_naughty/validations/confirmation_validation.rb +41 -0
 - data/lib/not_naughty/validations/format_validation.rb +55 -0
 - data/lib/not_naughty/validations/length_validation.rb +95 -0
 - data/lib/not_naughty/validations/numericality_validation.rb +43 -0
 - data/lib/not_naughty/validations/presence_validation.rb +31 -0
 - data/lib/not_naughty/validator.rb +125 -0
 - data/lib/not_naughty/violation.rb +36 -0
 - data/spec/builder_spec.rb +80 -0
 - data/spec/error_handler_spec.rb +21 -0
 - data/spec/not_naughty_spec.rb +82 -0
 - data/spec/rcov.opts +4 -0
 - data/spec/spec.opts +5 -0
 - data/spec/spec_helper.rb +7 -0
 - data/spec/validation_spec.rb +118 -0
 - data/spec/validations_spec.rb +267 -0
 - data/spec/validator_spec.rb +132 -0
 - data/spec/violation_spec.rb +36 -0
 - metadata +93 -0
 
    
        data/CHANGELOG.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            === 0.6 (2008-10-08)
         
     | 
| 
      
 2 
     | 
    
         
            +
            * fixed Rakefile
         
     | 
| 
      
 3 
     | 
    
         
            +
            * removed whitespaces
         
     | 
| 
      
 4 
     | 
    
         
            +
            * removed Ruby-Sequel adapter (becomes an extra gem)
         
     | 
| 
      
 5 
     | 
    
         
            +
            * removed assistance gem dependency
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            === 0.5.1 (2008-03-17)
         
     | 
| 
      
 8 
     | 
    
         
            +
            * fixed missing dependency
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            === 0.5 (2008-03-17)
         
     | 
| 
      
 11 
     | 
    
         
            +
            * added an error handler, can now handle SQL validation errors
         
     | 
| 
      
 12 
     | 
    
         
            +
            * renamed Errors to Violation and merged it with ValidationException
         
     | 
| 
      
 13 
     | 
    
         
            +
            * changed specs for 0.4.1
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            === 0.4.2 (2008-03-12)
         
     | 
| 
      
 16 
     | 
    
         
            +
            * fixed bug that causes infinite recursion in some apps that reload classes
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            === 0.4.1 (2008-03-12)
         
     | 
| 
      
 19 
     | 
    
         
            +
            * some minor changes in validator method
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            === 0.4 (2008-02-18)
         
     | 
| 
      
 22 
     | 
    
         
            +
            * completed documentation
         
     | 
| 
      
 23 
     | 
    
         
            +
            * added spec for :each in Builder::ValidationDelegator
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            === 0.3.1 (2008-02-14)
         
     | 
| 
      
 26 
     | 
    
         
            +
            * fixed missing require
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            === 0.3 (2008-02-09)
         
     | 
| 
      
 29 
     | 
    
         
            +
            * renamed to NotNaughty - The Validation Framework
         
     | 
| 
      
 30 
     | 
    
         
            +
            * made predefined Validation optional, you can load them with:
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
               ::NotNaughty::Validation.load '*'
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              or ordered (should be preferred):
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
               ::NotNaughty::Validation.load :acceptance, :confirmation, :format, :length,
         
     | 
| 
      
 37 
     | 
    
         
            +
                 :numericality, :presence
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            * specs pass, 100% code coverage, 2 not complete, so pending specs
         
     | 
| 
      
 40 
     | 
    
         
            +
            * docs added
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            === 0.2 (2008-02-09)
         
     | 
| 
      
 43 
     | 
    
         
            +
            * complete rewrite
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            === 0.1 (2008-02-06)
         
     | 
| 
      
 46 
     | 
    
         
            +
            * initial release
         
     | 
    
        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
    
    | 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = NotNaughty - The Validation Framework
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            NotNaughty extends your ruby Project with a highly custumizable validation API.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            == Features
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            <b>Easy to adapt:</b>
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
               require 'rubygems'
         
     | 
| 
      
 10 
     | 
    
         
            +
               require 'not_naughty'
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
               Person = Struct.new(:name) do
         
     | 
| 
      
 13 
     | 
    
         
            +
                 extend NotNaughty
         
     | 
| 
      
 14 
     | 
    
         
            +
                 validates(:name) { presence and length :minimum => 4 }
         
     | 
| 
      
 15 
     | 
    
         
            +
               end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
               Person.new('Horst').valid? # => true
         
     | 
| 
      
 18 
     | 
    
         
            +
               Person.new('Foo').valid? # => false
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            <b>Easy to extent:</b>
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
               class ExampleValidation < NotNaughty::Validation
         
     | 
| 
      
 23 
     | 
    
         
            +
                 def initialize(options, attributes)
         
     | 
| 
      
 24 
     | 
    
         
            +
                   msg = options[:message] || '#{"%s".humanize} is not an example.'
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                   super options, attributes do |record, attribute, value|
         
     | 
| 
      
 27 
     | 
    
         
            +
                     record.errors.add(attribute, msg) unless value.is_a? Example
         
     | 
| 
      
 28 
     | 
    
         
            +
                   end
         
     | 
| 
      
 29 
     | 
    
         
            +
                 end
         
     | 
| 
      
 30 
     | 
    
         
            +
               end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
               Person.instance_eval do
         
     | 
| 
      
 33 
     | 
    
         
            +
                 validates_example_of :example_attribute
         
     | 
| 
      
 34 
     | 
    
         
            +
               end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            <b>Handle SQL error gracefully:</b>
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
               Person.instance_eval do
         
     | 
| 
      
 39 
     | 
    
         
            +
                 validator.error_handler.handle(SQLError) { |err| '...' }
         
     | 
| 
      
 40 
     | 
    
         
            +
               end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            <b>Syntactical Sugar with Builder methods:</b>
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
               validates(:username, :password, :if => :new?) {length :minimum => 6}
         
     | 
| 
      
 45 
     | 
    
         
            +
               validates(:password, :allow_blank => 1) {confirmation and complexity :high}
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            <b>Beautiful error messages:</b>
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
               validates_presence_of :red_shoes,
         
     | 
| 
      
 50 
     | 
    
         
            +
                 :message => '#{"%s".humanize} are not here.' # => Red shoes are not here.
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            <b>Conditional Validations:</b>
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
               validates(:if => :necessary?) {...}
         
     | 
| 
      
 55 
     | 
    
         
            +
               validates(:unless => proc {|obj| obj.vip?}) { '...' }
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            == Copying
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            :include: COPYING
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,126 @@ 
     | 
|
| 
      
 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 = "not-naughty"
         
     | 
| 
      
 12 
     | 
    
         
            +
            VERS = "0.6.0"
         
     | 
| 
      
 13 
     | 
    
         
            +
            CLEAN.include %w[ pkg doc coverage ]
         
     | 
| 
      
 14 
     | 
    
         
            +
            RDOC_OPTS = [
         
     | 
| 
      
 15 
     | 
    
         
            +
              "--quiet",
         
     | 
| 
      
 16 
     | 
    
         
            +
              "--title", "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 = "NotNaughty: The Validation Framework"
         
     | 
| 
      
 35 
     | 
    
         
            +
              rdoc.rdoc_files.add %w[README.rdoc COPYING CHANGELOG.rdoc lib/**/*.rb]
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            task :doc_rforge => [:doc]
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            desc "Update docs and upload to rubyforge.org"
         
     | 
| 
      
 41 
     | 
    
         
            +
            task :doc_rforge do
         
     | 
| 
      
 42 
     | 
    
         
            +
              sh %{scp -r doc/rdoc/* boof@rubyforge.org:/var/www/gforge-projects/not-naughty}
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            ##############################################################################
         
     | 
| 
      
 46 
     | 
    
         
            +
            # specs
         
     | 
| 
      
 47 
     | 
    
         
            +
            ##############################################################################
         
     | 
| 
      
 48 
     | 
    
         
            +
            require "spec/rake/spectask"
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            desc "Run specs with coverage"
         
     | 
| 
      
 51 
     | 
    
         
            +
            Spec::Rake::SpecTask.new("spec") do |t|
         
     | 
| 
      
 52 
     | 
    
         
            +
              t.spec_files = FileList["spec/**/*_spec.rb"]
         
     | 
| 
      
 53 
     | 
    
         
            +
              t.spec_opts  = File.read("spec/spec.opts").split("\n")
         
     | 
| 
      
 54 
     | 
    
         
            +
              t.rcov_opts  = File.read("spec/rcov.opts").split("\n")
         
     | 
| 
      
 55 
     | 
    
         
            +
              t.rcov = true
         
     | 
| 
      
 56 
     | 
    
         
            +
            end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            desc "Run specs without coverage"
         
     | 
| 
      
 59 
     | 
    
         
            +
            Spec::Rake::SpecTask.new("spec_no_cov") do |t|
         
     | 
| 
      
 60 
     | 
    
         
            +
              t.spec_files = FileList["spec/**/*_spec.rb"]
         
     | 
| 
      
 61 
     | 
    
         
            +
              t.spec_opts  = File.read("spec/spec.opts").split("\n")
         
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            desc "check documentation coverage"
         
     | 
| 
      
 65 
     | 
    
         
            +
            task :dcov do
         
     | 
| 
      
 66 
     | 
    
         
            +
              sh "find lib -name '*.rb' | xargs dcov"
         
     | 
| 
      
 67 
     | 
    
         
            +
            end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            ##############################################################################
         
     | 
| 
      
 70 
     | 
    
         
            +
            # Gem packaging
         
     | 
| 
      
 71 
     | 
    
         
            +
            ##############################################################################
         
     | 
| 
      
 72 
     | 
    
         
            +
            desc "Packages up NotNaughty."
         
     | 
| 
      
 73 
     | 
    
         
            +
            task :default => [:package]
         
     | 
| 
      
 74 
     | 
    
         
            +
            task :package => [:clean]
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            spec = Gem::Specification.new do |s|
         
     | 
| 
      
 77 
     | 
    
         
            +
              s.name = NAME
         
     | 
| 
      
 78 
     | 
    
         
            +
              s.rubyforge_project = NAME
         
     | 
| 
      
 79 
     | 
    
         
            +
              s.version = VERS
         
     | 
| 
      
 80 
     | 
    
         
            +
              s.platform = Gem::Platform::RUBY
         
     | 
| 
      
 81 
     | 
    
         
            +
              s.has_rdoc = true
         
     | 
| 
      
 82 
     | 
    
         
            +
              s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "COPYING"]
         
     | 
| 
      
 83 
     | 
    
         
            +
              s.summary = "Heavily armed validation framework."
         
     | 
| 
      
 84 
     | 
    
         
            +
              s.description = s.summary
         
     | 
| 
      
 85 
     | 
    
         
            +
              s.author = "Florian Aßmann"
         
     | 
| 
      
 86 
     | 
    
         
            +
              s.email = "boof@monkey-patch.me"
         
     | 
| 
      
 87 
     | 
    
         
            +
              s.homepage = "http://monkey-patch.me/p/notnaughty"
         
     | 
| 
      
 88 
     | 
    
         
            +
              s.required_ruby_version = ">= 1.8.6"
         
     | 
| 
      
 89 
     | 
    
         
            +
              s.add_dependency("rubytree", ">= 0.5.2")
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
              s.files = %w(COPYING README.rdoc Rakefile) + Dir.glob("{spec,lib}/**/*")
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
              s.require_path = "lib"
         
     | 
| 
      
 94 
     | 
    
         
            +
            end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            Rake::GemPackageTask.new(spec) do |p|
         
     | 
| 
      
 97 
     | 
    
         
            +
              p.need_tar = true
         
     | 
| 
      
 98 
     | 
    
         
            +
              p.gem_spec = spec
         
     | 
| 
      
 99 
     | 
    
         
            +
            end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            ##############################################################################
         
     | 
| 
      
 102 
     | 
    
         
            +
            # installation & removal
         
     | 
| 
      
 103 
     | 
    
         
            +
            ##############################################################################
         
     | 
| 
      
 104 
     | 
    
         
            +
            task :install do
         
     | 
| 
      
 105 
     | 
    
         
            +
              sh %{rake package}
         
     | 
| 
      
 106 
     | 
    
         
            +
              sh %{sudo gem install pkg/#{NAME}-#{VERS}}
         
     | 
| 
      
 107 
     | 
    
         
            +
            end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            task :install_no_docs do
         
     | 
| 
      
 110 
     | 
    
         
            +
              sh %{rake package}
         
     | 
| 
      
 111 
     | 
    
         
            +
              sh %{sudo gem install pkg/#{NAME}-#{VERS} --no-rdoc --no-ri}
         
     | 
| 
      
 112 
     | 
    
         
            +
            end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
            task :uninstall => [:clean] do
         
     | 
| 
      
 115 
     | 
    
         
            +
              sh %{sudo gem uninstall #{NAME}}
         
     | 
| 
      
 116 
     | 
    
         
            +
            end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            ##############################################################################
         
     | 
| 
      
 119 
     | 
    
         
            +
            # gem and rdoc release
         
     | 
| 
      
 120 
     | 
    
         
            +
            ##############################################################################
         
     | 
| 
      
 121 
     | 
    
         
            +
            task :release => [:package] do
         
     | 
| 
      
 122 
     | 
    
         
            +
              sh %{rubyforge login}
         
     | 
| 
      
 123 
     | 
    
         
            +
              sh %{rubyforge add_release #{NAME} #{NAME} #{VERS} pkg/#{NAME}-#{VERS}.tgz}
         
     | 
| 
      
 124 
     | 
    
         
            +
              sh %{rubyforge add_file #{NAME} #{NAME} #{VERS} pkg/#{NAME}-#{VERS}.gem}
         
     | 
| 
      
 125 
     | 
    
         
            +
            end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Array #:nodoc:
         
     | 
| 
      
 2 
     | 
    
         
            +
              instance_methods.include? 'extract_options!' or
         
     | 
| 
      
 3 
     | 
    
         
            +
              define_method(:extract_options!) { Hash === last ? pop : {} }
         
     | 
| 
      
 4 
     | 
    
         
            +
            end
         
     | 
| 
      
 5 
     | 
    
         
            +
            class Object #:nodoc:
         
     | 
| 
      
 6 
     | 
    
         
            +
              instance_methods.include? 'blank?' or
         
     | 
| 
      
 7 
     | 
    
         
            +
              define_method(:blank?) { respond_to?(:empty?) ? empty? : !self }
         
     | 
| 
      
 8 
     | 
    
         
            +
            end
         
     | 
| 
      
 9 
     | 
    
         
            +
            class String #:nodoc:
         
     | 
| 
      
 10 
     | 
    
         
            +
              instance_methods.include? 'blank?' or
         
     | 
| 
      
 11 
     | 
    
         
            +
              define_method(:blank?) { self !~ /\S/ }
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
      
 13 
     | 
    
         
            +
            class Numeric #:nodoc:
         
     | 
| 
      
 14 
     | 
    
         
            +
              instance_methods.include? 'blank?' or
         
     | 
| 
      
 15 
     | 
    
         
            +
              define_method(:blank?) { false }
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            def nil.blank?() true end unless nil.respond_to? :blank?
         
     | 
| 
      
 19 
     | 
    
         
            +
            def true.blank?() false end unless true.respond_to? :blank?
         
     | 
| 
      
 20 
     | 
    
         
            +
            def false.blank?() true end unless false.respond_to? :blank?
         
     | 
    
        data/lib/not_naughty.rb
    ADDED
    
    | 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'delegate'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'forwardable'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'observer'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 6 
     | 
    
         
            +
            gem 'rubytree', '>= 0.5.2'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'tree'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            $:.unshift File.dirname(__FILE__)
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'core_extensions'
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            module NotNaughty
         
     | 
| 
      
 13 
     | 
    
         
            +
              require 'not_naughty/validator'
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              require 'not_naughty/builder'
         
     | 
| 
      
 16 
     | 
    
         
            +
              require 'not_naughty/validation'
         
     | 
| 
      
 17 
     | 
    
         
            +
              Validation.add_observer Builder
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              require 'not_naughty/violation'
         
     | 
| 
      
 20 
     | 
    
         
            +
              require 'not_naughty/error_handler'
         
     | 
| 
      
 21 
     | 
    
         
            +
              require 'not_naughty/instance_methods'
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              # Extended classes get NotNaughty::Builder and NotNaughty::InstanceMethods.
         
     | 
| 
      
 24 
     | 
    
         
            +
              def self.extended(base)
         
     | 
| 
      
 25 
     | 
    
         
            +
                base.instance_eval do
         
     | 
| 
      
 26 
     | 
    
         
            +
                  include InstanceMethods
         
     | 
| 
      
 27 
     | 
    
         
            +
                  extend Builder
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              # call-seq:
         
     | 
| 
      
 32 
     | 
    
         
            +
              # validator(validator_klass = NotNaughty::Validator, *states = [:default])
         
     | 
| 
      
 33 
     | 
    
         
            +
              #
         
     | 
| 
      
 34 
     | 
    
         
            +
              # Returns instance of Validator. This is either the validator's clone of
         
     | 
| 
      
 35 
     | 
    
         
            +
              # superclass, an instance of the the given descendant of or the
         
     | 
| 
      
 36 
     | 
    
         
            +
              # <tt>NotNaughty:Validator</tt> himself.
         
     | 
| 
      
 37 
     | 
    
         
            +
              #
         
     | 
| 
      
 38 
     | 
    
         
            +
              # <b>Examples:</b>
         
     | 
| 
      
 39 
     | 
    
         
            +
              #   validator # => Instance of NotNaughty::Validator with :default state
         
     | 
| 
      
 40 
     | 
    
         
            +
              #   validator :create, :update # ~ - but with :create and :update states
         
     | 
| 
      
 41 
     | 
    
         
            +
              #   validator AnotherValidator # Instance of AnotherValidator
         
     | 
| 
      
 42 
     | 
    
         
            +
              #
         
     | 
| 
      
 43 
     | 
    
         
            +
              #   validator AnotherValidator, :state_a, :state_b
         
     | 
| 
      
 44 
     | 
    
         
            +
              #
         
     | 
| 
      
 45 
     | 
    
         
            +
              # The above examples work as long validator is not already called. To reset
         
     | 
| 
      
 46 
     | 
    
         
            +
              # an already assigned validator set <tt>@validator</tt> to nil.
         
     | 
| 
      
 47 
     | 
    
         
            +
              def validator(*states)
         
     | 
| 
      
 48 
     | 
    
         
            +
                @validator ||= if !states.empty?
         
     | 
| 
      
 49 
     | 
    
         
            +
                  validator_klass =
         
     | 
| 
      
 50 
     | 
    
         
            +
                    if states.first.is_a? Class and states.first <= NotNaughty::Validator
         
     | 
| 
      
 51 
     | 
    
         
            +
                      states.shift
         
     | 
| 
      
 52 
     | 
    
         
            +
                    else
         
     | 
| 
      
 53 
     | 
    
         
            +
                      NotNaughty::Validator
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  validator_klass.new(*states)
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                elsif superclass.respond_to? :validator
         
     | 
| 
      
 59 
     | 
    
         
            +
                  superclass.validator.clone
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                else
         
     | 
| 
      
 62 
     | 
    
         
            +
                  NotNaughty::Validator.new
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              # Prepends a call for validation before then given method. If, on call, the
         
     | 
| 
      
 68 
     | 
    
         
            +
              # validation passes the method is called. Otherwise it raises an
         
     | 
| 
      
 69 
     | 
    
         
            +
              # NotNaughty::ValidationException or returns false.
         
     | 
| 
      
 70 
     | 
    
         
            +
              #
         
     | 
| 
      
 71 
     | 
    
         
            +
              # <b>Example:</b>
         
     | 
| 
      
 72 
     | 
    
         
            +
              #   validated_before :save # raise ValidationException unless valid?
         
     | 
| 
      
 73 
     | 
    
         
            +
              def validated_before(method)
         
     | 
| 
      
 74 
     | 
    
         
            +
                __method = :"#{method}_without_validations"
         
     | 
| 
      
 75 
     | 
    
         
            +
                alias_method __method, method
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                define_method method do |*params|
         
     | 
| 
      
 78 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 79 
     | 
    
         
            +
                    if valid? then send __method else raise errors end
         
     | 
| 
      
 80 
     | 
    
         
            +
                  rescue Exception => error
         
     | 
| 
      
 81 
     | 
    
         
            +
                    self.class.validator.error_handler.raise error
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,68 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module NotNaughty
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              # == Builder that builds
         
     | 
| 
      
 4 
     | 
    
         
            +
              #
         
     | 
| 
      
 5 
     | 
    
         
            +
              # With this you get syntactical sugar for all descendants of Validation, see
         
     | 
| 
      
 6 
     | 
    
         
            +
              # validates for examples.
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Builder
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                # Observer method that creates Validation builder methods.
         
     | 
| 
      
 10 
     | 
    
         
            +
                #
         
     | 
| 
      
 11 
     | 
    
         
            +
                # A Validation with the class name TestValidation will get the
         
     | 
| 
      
 12 
     | 
    
         
            +
                # builder method <tt>validate_test_of</tt> that adds a validation via
         
     | 
| 
      
 13 
     | 
    
         
            +
                # add_validation in the current <tt>validator</tt>.
         
     | 
| 
      
 14 
     | 
    
         
            +
                def self.update(validation)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  if basename = validation.name[/([^:]+)Validation$/, 1]
         
     | 
| 
      
 16 
     | 
    
         
            +
                    define_method 'validates_%s_of' % basename.downcase do |*params|
         
     | 
| 
      
 17 
     | 
    
         
            +
                      validator.add_validation(validation, *params)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # == Syntactic sugar.
         
     | 
| 
      
 23 
     | 
    
         
            +
                #
         
     | 
| 
      
 24 
     | 
    
         
            +
                # <b>Example:</b>
         
     | 
| 
      
 25 
     | 
    
         
            +
                #   validates { presence_of :example, :if => :reading? }
         
     | 
| 
      
 26 
     | 
    
         
            +
                #     # => validate_presence_of :example, :if => :reading?
         
     | 
| 
      
 27 
     | 
    
         
            +
                #   validates(:name) { presence and length :minimum => 6 }
         
     | 
| 
      
 28 
     | 
    
         
            +
                #     # => validates_presence_of :name
         
     | 
| 
      
 29 
     | 
    
         
            +
                #          validates_length_of :name, :minimum => 6
         
     | 
| 
      
 30 
     | 
    
         
            +
                #   validates(:temp, :if => water?) { value :lt => 100 }
         
     | 
| 
      
 31 
     | 
    
         
            +
                #     # => validates_value_of :temp, :lt => 100, :if => water?
         
     | 
| 
      
 32 
     | 
    
         
            +
                def validates(*params, &block)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  ValidationDelegator.new(self, *params).instance_eval(&block)
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                # Allows adding validations the legacy way.
         
     | 
| 
      
 37 
     | 
    
         
            +
                def validates_each(*attributes, &block)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  validator.add_validation(*attributes, &block)
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                class ValidationDelegator < SimpleDelegator #:nodoc:all
         
     | 
| 
      
 42 
     | 
    
         
            +
                  def initialize(receiver, *params)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @_sd_obj_opts   = params.extract_options!
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @_sd_obj_params = params
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    super receiver
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  def method_missing(method_sym, *params) #:nodoc:
         
     | 
| 
      
 49 
     | 
    
         
            +
                    method_sym, params = unless @_sd_obj_params.empty?
         
     | 
| 
      
 50 
     | 
    
         
            +
                      opts = @_sd_obj_opts.update params.extract_options!
         
     | 
| 
      
 51 
     | 
    
         
            +
                      [:"validates_#{method_sym}_of", @_sd_obj_params + [opts]]
         
     | 
| 
      
 52 
     | 
    
         
            +
                    else
         
     | 
| 
      
 53 
     | 
    
         
            +
                      opts = @_sd_obj_opts.update params.extract_options!
         
     | 
| 
      
 54 
     | 
    
         
            +
                      [:"validates_#{method_sym}", params + [opts]]
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                    if @_sd_obj.respond_to? method_sym
         
     | 
| 
      
 58 
     | 
    
         
            +
                      @_sd_obj.send(method_sym, *params)
         
     | 
| 
      
 59 
     | 
    
         
            +
                      return true
         
     | 
| 
      
 60 
     | 
    
         
            +
                    else
         
     | 
| 
      
 61 
     | 
    
         
            +
                      raise NoMethodError,
         
     | 
| 
      
 62 
     | 
    
         
            +
                        "unable to evaluate ´#{method_sym}(*#{params.inspect})'"
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Tree #:nodoc:
         
     | 
| 
      
 2 
     | 
    
         
            +
              class TreeNode #:nodoc:
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                def closest(obj)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  if @name == obj then self
         
     | 
| 
      
 6 
     | 
    
         
            +
                  elsif @name > obj
         
     | 
| 
      
 7 
     | 
    
         
            +
                    closest = self
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @children.any? { |child| node = child.closest(obj) and closest = node }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    closest
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            module NotNaughty
         
     | 
| 
      
 18 
     | 
    
         
            +
              class ErrorHandler
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def initialize(handler = Kernel)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @handles = Tree::TreeNode.new Exception, proc { |e| handler.raise e }
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                # Calls closest handle with exception.
         
     | 
| 
      
 25 
     | 
    
         
            +
                def raise(exception)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  handle = @handles.closest exception.class
         
     | 
| 
      
 27 
     | 
    
         
            +
                  handle.content.call exception
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                # Inserts handle into the ordered tree.
         
     | 
| 
      
 31 
     | 
    
         
            +
                def handle(exception_class, &block)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  closest_handle = @handles.closest exception_class
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  if closest_handle == exception_class then closest_handle.content = block
         
     | 
| 
      
 35 
     | 
    
         
            +
                  else
         
     | 
| 
      
 36 
     | 
    
         
            +
                    new_handle = Tree::TreeNode.new exception_class, block
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    closest_handle.children do |child|
         
     | 
| 
      
 39 
     | 
    
         
            +
                      exception_class > child.name and
         
     | 
| 
      
 40 
     | 
    
         
            +
                      new_handle << closest_handle.remove!(child)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                    closest_handle << new_handle
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     |