Skip to content

Commit

Permalink
:required => true now uses the not_null validator (not presence)
Browse files Browse the repository at this point in the history
Fixes #110
  • Loading branch information
ajselvig authored and nviennot committed Jan 1, 2015
1 parent 4360d70 commit 63255b8
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 17 deletions.
4 changes: 2 additions & 2 deletions lib/no_brainer/document.rb
Expand Up @@ -4,8 +4,8 @@ module NoBrainer::Document
extend ActiveSupport::Concern
extend NoBrainer::Autoload

autoload_and_include :Core, :StoreIn, :InjectionLayer, :Attributes, :Readonly, :Validation,
:Persistance, :Types, :Uniqueness, :Callbacks, :Dirty, :PrimaryKey,
autoload_and_include :Core, :StoreIn, :InjectionLayer, :Attributes, :Readonly,
:Persistance, :Validation, :Types, :Callbacks, :Dirty, :PrimaryKey,
:Association, :Serialization, :Criteria, :Polymorphic, :Index, :Aliases,
:MissingAttributes, :LazyFetch, :AtomicOps

Expand Down
7 changes: 5 additions & 2 deletions lib/no_brainer/document/validation.rb
@@ -1,8 +1,11 @@
module NoBrainer::Document::Validation
extend NoBrainer::Autoload
extend ActiveSupport::Concern
include ActiveModel::Validations
include ActiveModel::Validations::Callbacks

autoload_and_include :Uniqueness, :NotNull

included do
# We don't want before_validation returning false to halt the chain.
define_callbacks :validation, :skip_after_callbacks_if_terminated => true,
Expand All @@ -12,7 +15,7 @@ module NoBrainer::Document::Validation
def valid?(context=nil, options={})
context ||= new_record? ? :create : :update

# copy/pasted, because we need to have control on errors.clear
# XXX Monkey Patching, because we need to have control on errors.clear
current_context, self.validation_context = validation_context, context
errors.clear unless options[:clear_errors] == false
run_validations!
Expand All @@ -24,9 +27,9 @@ module ClassMethods
def _field(attr, options={})
super
validates(attr, :format => { :with => options[:format] }) if options.has_key?(:format)
validates(attr, :presence => options[:required]) if options.has_key?(:required)
validates(attr, :uniqueness => options[:unique]) if options.has_key?(:unique)
validates(attr, :uniqueness => options[:uniq]) if options.has_key?(:uniq)
validates(attr, :not_null => options[:required]) if options.has_key?(:required)
validates(attr, :inclusion => {:in => options[:in]}) if options.has_key?(:in)
validates(attr, options[:validates]) if options[:validates]
end
Expand Down
15 changes: 15 additions & 0 deletions lib/no_brainer/document/validation/not_null.rb
@@ -0,0 +1,15 @@
module NoBrainer::Document::Validation::NotNull
extend ActiveSupport::Concern

module ClassMethods
def validates_not_null(*attr_names)
validates_with(NotNullValidator, _merge_attributes(attr_names))
end
end

class NotNullValidator < ActiveModel::EachValidator
def validate_each(doc, attr, value)
doc.errors.add(attr, :undefined, options) if value.nil?
end
end
end
@@ -1,4 +1,4 @@
module NoBrainer::Document::Uniqueness
module NoBrainer::Document::Validation::Uniqueness
extend ActiveSupport::Concern

def _create(options={})
Expand Down Expand Up @@ -51,7 +51,7 @@ def unlock_unique_fields

module ClassMethods
def validates_uniqueness_of(*attr_names)
validates_with UniquenessValidator, _merge_attributes(attr_names)
validates_with(UniquenessValidator, _merge_attributes(attr_names))
end

def inherited(subclass)
Expand Down
1 change: 1 addition & 0 deletions lib/no_brainer/locale/en.yml
Expand Up @@ -3,3 +3,4 @@ en:
messages:
taken: "is already taken"
invalid_type: "should be a %{type}"
undefined: "must be defined"
82 changes: 82 additions & 0 deletions spec/integration/validation/definition_spec.rb
@@ -0,0 +1,82 @@
require 'spec_helper'

describe 'definition validator' do
before { load_simple_document }

shared_examples_for "not_null validation" do
it 'cannot save without setting a value' do
doc = SimpleDocument.new
doc.valid?.should == false
expect { doc.save }.to raise_error(NoBrainer::Error::DocumentInvalid)
doc.errors.full_messages.first.should == 'Field1 must be defined'
end

it 'cannot save a nil value' do
doc = SimpleDocument.new(:field1 => nil)
doc.valid?.should == false
expect { doc.save }.to raise_error(NoBrainer::Error::DocumentInvalid)
end

it 'can save an empty string' do
doc = SimpleDocument.new(:field1 => '')
doc.valid?.should == true
end

it 'can save a false value' do
doc = SimpleDocument.new(:field1 => false)
doc.valid?.should == true
end

it 'can save an empty array' do
doc = SimpleDocument.new(:field1 => [])
doc.valid?.should == true
end
end

shared_examples_for "presence validation" do
it 'cannot save without setting a value' do
doc = SimpleDocument.new
doc.valid?.should == false
expect { doc.save }.to raise_error(NoBrainer::Error::DocumentInvalid)
doc.errors.full_messages.first.should == "Field1 can't be blank"
end

it 'cannot save a nil value' do
doc = SimpleDocument.new(:field1 => nil)
doc.valid?.should == false
expect { doc.save }.to raise_error(NoBrainer::Error::DocumentInvalid)
end

it 'cannot save an empty string' do
doc = SimpleDocument.new(:field1 => '')
doc.valid?.should == false
expect { doc.save }.to raise_error(NoBrainer::Error::DocumentInvalid)
end

it 'cannot save a false value' do
doc = SimpleDocument.new(:field1 => false)
doc.valid?.should == false
expect { doc.save }.to raise_error(NoBrainer::Error::DocumentInvalid)
end

it 'cannot save an empty array' do
doc = SimpleDocument.new(:field1 => [])
doc.valid?.should == false
expect { doc.save }.to raise_error(NoBrainer::Error::DocumentInvalid)
end
end

context 'with validates_not_null' do
before { SimpleDocument.validates_not_null :field1 }
it_behaves_like "not_null validation"
end

context 'with validates_presence_of' do
before { SimpleDocument.validates_presence_of :field1 }
it_behaves_like "presence validation"
end

context 'with :required => true' do
before { SimpleDocument.field :field1, :required => :not_null }
end
end
@@ -1,6 +1,6 @@
require 'spec_helper'

describe 'NoBrainer callbacks' do
describe 'uniqueness validator' do
before { load_simple_document }

context 'with validates_uniqueness_of' do
Expand Down
@@ -1,6 +1,6 @@
require 'spec_helper'

describe 'NoBrainer callbacks' do
describe 'validations' do
before { load_simple_document }

context 'when using a simple validation' do
Expand Down Expand Up @@ -155,15 +155,6 @@ def some_validator
end
end

context 'when using required on the field' do
before { SimpleDocument.field :field1, :required => true }

it 'validates' do
SimpleDocument.new(:field1 => nil).valid?.should == false
SimpleDocument.new(:field1 => 'ohai').valid?.should == true
end
end

context 'when using format on the field' do
before { SimpleDocument.field :field1, :format => /\A[a-z]+\z/ }

Expand Down

0 comments on commit 63255b8

Please sign in to comment.