Skip to content

Commit

Permalink
Merge branch 'master' into 0.2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
jodosha committed Jan 8, 2015
2 parents c03c4a1 + 9d88e6d commit 9f75263
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 14 deletions.
49 changes: 35 additions & 14 deletions lib/lotus/validations/attribute_definer.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require 'set'
require 'lotus/utils/class_attribute'
require 'lotus/utils/attributes'

module Lotus
Expand Down Expand Up @@ -32,17 +31,22 @@ module ClassMethods
# @api private
#
# @see http://www.ruby-doc.org/core/Module.html#method-i-extended
def self.extended(base)
base.class_eval do
include Utils::ClassAttribute
def included(base)
super
base.defined_attributes.merge(defined_attributes)
end

# Lotus::Controller compatibility
#
# @since 0.2.2
# @api private
class_attribute :defined_attributes
self.defined_attributes = Set.new
end
# Override Ruby's hook for modules.
#
# @param base [Class] the target class
#
# @since 0.2.2
# @api private
#
# @see http://www.ruby-doc.org/core/Module.html#method-i-extended
def inherited(base)
super
base.defined_attributes.merge(defined_attributes)
end

# Define an attribute
Expand Down Expand Up @@ -233,6 +237,10 @@ def attribute(name, options = {})
validates(name, options)
end

def defined_attributes
@defined_attributes ||= Set.new
end

private

# @since 0.2.2
Expand All @@ -243,7 +251,9 @@ def define_attribute(name, options)
defined_attributes.add(name.to_s)

if options[:confirmation]
define_accessor("#{ name }_confirmation", type)
confirmation_accessor = "#{ name }_confirmation"
define_accessor(confirmation_accessor, type)
defined_attributes.add(confirmation_accessor)
end
end

Expand All @@ -267,12 +277,16 @@ def define_coerced_writer(name, type)
end
end

# @since 0.2.2
# @api private
def define_writer(name)
define_method("#{ name }=") do |value|
@attributes.set(name, value)
end
end

# @since 0.2.2
# @api private
def define_reader(name)
define_method(name) do
@attributes.get(name)
Expand Down Expand Up @@ -323,11 +337,18 @@ def define_reader(name)
# signup.name # => "Luca"
def initialize(attributes)
@attributes ||= Utils::Attributes.new

attributes.to_h.each do |key, value|
writer = "#{ key }="
public_send(writer, value) if respond_to?(writer)
public_send("#{ key }=", value) if assign_attribute?(key)
end
end

private
# @since 0.2.2
# @api private
def assign_attribute?(attr)
self.class.defined_attributes.include?(attr.to_s)
end
end
end
end
29 changes: 29 additions & 0 deletions test/fixtures.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,20 @@ def [](key)
end
end

class MethodAssignmentTest
include Lotus::Validations
attribute :name

def ==(other)
@equal_param = other
true
end

def equal_param
@equal_param
end
end

class UniquenessAttributeTest
include Lotus::Validations
extend Lotus::Validations::ValidationIntrospection
Expand Down Expand Up @@ -219,3 +233,18 @@ class EnumerableValidator

attribute :name
end

class CustomAttributesValidator
include Lotus::Validations

attribute :name

def initialize(attributes)
@attributes = Lotus::Utils::Attributes.new({ already: 'initialized' })
super
end

def to_h
@attributes.to_h
end
end
5 changes: 5 additions & 0 deletions test/inheritance_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,10 @@
subclass.valid?.must_equal false
subclass.errors.for(:name).must_include Lotus::Validations::Error.new(:name, :presence, true, nil)
end

it "receives attributes from the super class" do
subclass = SubclassValidatorTest.new({age: 32, name: 'Luca'})
subclass.to_h.must_equal({age: 32, name: 'Luca'})
end
end
end
15 changes: 15 additions & 0 deletions test/initialize_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,20 @@
validator['a'].must_be_nil
validator['b'].must_be_nil
end

it "doesn't assign to unknown attributes that are methods" do
validator = MethodAssignmentTest.new('==' => 1)
validator.equal_param.must_be_nil
end

it "respects already initialized set of attributes" do
validator = CustomAttributesValidator.new(name: 'Luca', language: 'it')
serialized = validator.to_h

serialized.fetch('already').must_equal('initialized')
serialized.fetch('name').must_equal('Luca')

serialized['language'].must_be_nil
end
end
end

0 comments on commit 9f75263

Please sign in to comment.