diff --git a/Gemfile b/Gemfile index 1371e8b46..0d9c53835 100644 --- a/Gemfile +++ b/Gemfile @@ -10,6 +10,7 @@ DO_VERSION = '~> 0.10.6' DM_DO_ADAPTERS = %w[ sqlite postgres mysql oracle sqlserver ] gem 'addressable', '~> 2.2.6' +gem 'virtus', '~> 0.0.8' group :development do diff --git a/dm-core.gemspec b/dm-core.gemspec index d735436ee..9c9a2d5b6 100644 --- a/dm-core.gemspec +++ b/dm-core.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version= s.authors = ["Dan Kubb"] - s.date = "2011-09-09" + s.date = "2011-09-12" s.description = "Faster, Better, Simpler." s.email = "dan.kubb@gmail.com" s.extra_rdoc_files = [ @@ -64,8 +64,6 @@ Gem::Specification.new do |s| "lib/dm-core/property/string.rb", "lib/dm-core/property/text.rb", "lib/dm-core/property/time.rb", - "lib/dm-core/property/typecast/numeric.rb", - "lib/dm-core/property/typecast/time.rb", "lib/dm-core/property_set.rb", "lib/dm-core/query.rb", "lib/dm-core/query/conditions/comparison.rb", @@ -282,17 +280,20 @@ Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q, ["~> 2.2.6"]) + s.add_runtime_dependency(%q, ["~> 0.0.8"]) s.add_development_dependency(%q, ["~> 1.6.4"]) s.add_development_dependency(%q, ["~> 0.9.2"]) s.add_development_dependency(%q, ["~> 1.3.2"]) else s.add_dependency(%q, ["~> 2.2.6"]) + s.add_dependency(%q, ["~> 0.0.8"]) s.add_dependency(%q, ["~> 1.6.4"]) s.add_dependency(%q, ["~> 0.9.2"]) s.add_dependency(%q, ["~> 1.3.2"]) end else s.add_dependency(%q, ["~> 2.2.6"]) + s.add_dependency(%q, ["~> 0.0.8"]) s.add_dependency(%q, ["~> 1.6.4"]) s.add_dependency(%q, ["~> 0.9.2"]) s.add_dependency(%q, ["~> 1.3.2"]) diff --git a/lib/dm-core.rb b/lib/dm-core.rb index 1c2e9171d..9fee658a8 100644 --- a/lib/dm-core.rb +++ b/lib/dm-core.rb @@ -11,6 +11,14 @@ module DataMapper module Undefined; end end +require 'virtus' + +class Virtus::Coercion::Object + def self.to_string(value) + value.nil? ? value : value.to_s + end +end + require 'dm-core/support/ext/blank' require 'dm-core/support/ext/hash' require 'dm-core/support/ext/object' @@ -61,8 +69,6 @@ module Undefined; end require 'dm-core/resource/persistence_state/dirty' require 'dm-core/property' -require 'dm-core/property/typecast/numeric' -require 'dm-core/property/typecast/time' require 'dm-core/property/object' require 'dm-core/property/string' require 'dm-core/property/binary' diff --git a/lib/dm-core/associations/many_to_one.rb b/lib/dm-core/associations/many_to_one.rb index ac9b3c12f..f0e94ba72 100644 --- a/lib/dm-core/associations/many_to_one.rb +++ b/lib/dm-core/associations/many_to_one.rb @@ -266,7 +266,7 @@ def source_key_options(target_property) :unique => @unique ) - if target_property.primitive == Integer + if target_property.instance_of?(Property::Integer) min = target_property.min max = target_property.max diff --git a/lib/dm-core/property.rb b/lib/dm-core/property.rb index 67e53e731..42b3b40e9 100644 --- a/lib/dm-core/property.rb +++ b/lib/dm-core/property.rb @@ -300,24 +300,6 @@ module DataMapper # * You may declare a Property with the data-type of Class. # see SingleTableInheritance for more on how to use Class columns. class Property - module PassThroughLoadDump - # @api semipublic - def load(value) - typecast(value) unless value.nil? - end - - # Stub instance method for dumping - # - # @param value [Object, nil] value to dump - # - # @return [Object] Dumped object - # - # @api semipublic - def dump(value) - value - end - end - include DataMapper::Assertions include Subject extend Equalizer @@ -337,6 +319,7 @@ def dump(value) ].to_set.freeze OPTIONS = [ + :load_as, :dump_as, :coercion_method, :accessor, :reader, :writer, :lazy, :default, :key, :field, :index, :unique_index, @@ -352,10 +335,14 @@ def dump(value) Query::OPTIONS.to_a ).map { |name| name.to_s } - attr_reader :primitive, :model, :name, :instance_variable_name, + attr_reader :load_as, :dump_as, :coercion_method, + :model, :name, :instance_variable_name, :reader_visibility, :writer_visibility, :options, :default, :repository_name, :allow_nil, :allow_blank, :required + alias_method :load_class, :load_as + alias_method :dump_class, :dump_as + class << self extend Deprecate @@ -460,9 +447,15 @@ def options end options end + + # @api deprecated + def primitive(*args) + warn "DataMapper::Property.primitive is deprecated, use .load_as instead (#{caller.first})" + load_as(*args) + end end - accept_options :primitive, *Property::OPTIONS + accept_options *Property::OPTIONS # A hook to allow properties to extend or modify the model it's bound to. # Implementations are not supposed to modify the state of the property @@ -680,11 +673,7 @@ def properties # @api semipublic def typecast(value) - if value.nil? || primitive?(value) - value - elsif respond_to?(:typecast_to_primitive) - typecast_to_primitive(value) - end + Virtus::Coercion[value.class].send(coercion_method, value) end # Test the value to see if it is a valid value for this Property @@ -702,7 +691,7 @@ def valid?(value, negated = false) if required? && dumped_value.nil? negated || false else - primitive?(dumped_value) || (dumped_value.nil? && (allow_nil? || negated)) + value_dumped?(dumped_value) || (dumped_value.nil? && (allow_nil? || negated)) end end @@ -726,7 +715,23 @@ def inspect # # @api semipublic def primitive?(value) - value.kind_of?(primitive) + warn "#primitive? is deprecated, use #value_dumped? instead (#{caller.first})" + value_dumped?(value) + end + + def primitive + warn "#primitive is deprecated, use #dump_as instead (#{caller.first})" + dump_as + end + + # @api semipublic + def value_dumped?(value) + value.kind_of?(dump_as) + end + + # @api semipublic + def value_loaded?(value) + value.kind_of?(load_as) end protected @@ -749,10 +754,13 @@ def initialize(model, name, options = {}) @name = name.to_s.chomp('?').to_sym @options = predefined_options.merge(options).freeze @instance_variable_name = "@#{@name}".freeze + @coercion_method = @options.fetch(:coercion_method) + + @load_as = self.class.load_as + @dump_as = self.class.dump_as - @primitive = self.class.primitive - @field = @options[:field].freeze unless @options[:field].nil? - @default = @options[:default] + @field = @options[:field].freeze unless @options[:field].nil? + @default = @options[:default] @serial = @options.fetch(:serial, false) @key = @options.fetch(:key, @serial) diff --git a/lib/dm-core/property/binary.rb b/lib/dm-core/property/binary.rb index fcfde79fe..ff9567dab 100644 --- a/lib/dm-core/property/binary.rb +++ b/lib/dm-core/property/binary.rb @@ -1,7 +1,7 @@ module DataMapper class Property class Binary < String - include PassThroughLoadDump + end # class Binary end # class Property end # module DataMapper diff --git a/lib/dm-core/property/boolean.rb b/lib/dm-core/property/boolean.rb index 8254034e3..3f5393503 100644 --- a/lib/dm-core/property/boolean.rb +++ b/lib/dm-core/property/boolean.rb @@ -1,31 +1,20 @@ module DataMapper class Property class Boolean < Object - include PassThroughLoadDump + load_as ::TrueClass + dump_as ::TrueClass + coercion_method :to_boolean - primitive ::TrueClass - - TRUE_VALUES = [ 1, '1', 't', 'T', 'true', 'TRUE' ].freeze - FALSE_VALUES = [ 0, '0', 'f', 'F', 'false', 'FALSE' ].freeze - BOOLEAN_MAP = Hash[ - TRUE_VALUES.product([ true ]) + FALSE_VALUES.product([ false ]) ].freeze + # @api semipublic + def value_dumped?(value) + value_loaded?(value) + end - def primitive?(value) + # @api semipublic + def value_loaded?(value) value == true || value == false end - # Typecast a value to a true or false - # - # @param [Integer, #to_str] value - # value to typecast - # - # @return [Boolean] - # true or false constructed from value - # - # @api private - def typecast_to_primitive(value) - BOOLEAN_MAP.fetch(value, value) - end end # class Boolean end # class Property end # module DataMapper diff --git a/lib/dm-core/property/class.rb b/lib/dm-core/property/class.rb index 77086ade6..29e799dd3 100644 --- a/lib/dm-core/property/class.rb +++ b/lib/dm-core/property/class.rb @@ -1,24 +1,17 @@ module DataMapper class Property class Class < Object - include PassThroughLoadDump + load_as ::Class + dump_as ::Class + coercion_method :to_constant - primitive ::Class - - # Typecast a value to a Class - # - # @param [#to_s] value - # value to typecast - # - # @return [Class] - # Class constructed from value - # - # @api private - def typecast_to_primitive(value) - DataMapper::Ext::Module.find_const(model, value.to_s) + # @api semipublic + def typecast(value) + DataMapper::Ext::Module.find_const(model, value.to_s) unless value.nil? rescue NameError value end + end # class Class end # class Property end # module DataMapper diff --git a/lib/dm-core/property/date.rb b/lib/dm-core/property/date.rb index b6e99499d..353d2886c 100644 --- a/lib/dm-core/property/date.rb +++ b/lib/dm-core/property/date.rb @@ -1,45 +1,10 @@ module DataMapper class Property class Date < Object - include PassThroughLoadDump - include Typecast::Time + load_as ::Date + dump_as ::Date + coercion_method :to_date - primitive ::Date - - # Typecasts an arbitrary value to a Date - # Handles both Hashes and Date instances. - # - # @param [Hash, #to_mash, #to_s] value - # value to be typecast - # - # @return [Date] - # Date constructed from value - # - # @api private - def typecast_to_primitive(value) - if value.respond_to?(:to_date) - value.to_date - elsif value.is_a?(::Hash) || value.respond_to?(:to_mash) - typecast_hash_to_date(value) - else - ::Date.parse(value.to_s) - end - rescue ArgumentError - value - end - - # Creates a Date instance from a Hash with keys :year, :month, :day - # - # @param [Hash, #to_mash] value - # value to be typecast - # - # @return [Date] - # Date constructed from hash - # - # @api private - def typecast_hash_to_date(value) - ::Date.new(*extract_time(value)[0, 3]) - end end # class Date end # class Property end # module DataMapper diff --git a/lib/dm-core/property/date_time.rb b/lib/dm-core/property/date_time.rb index c9909c22c..503d89a06 100644 --- a/lib/dm-core/property/date_time.rb +++ b/lib/dm-core/property/date_time.rb @@ -1,44 +1,10 @@ module DataMapper class Property class DateTime < Object - include PassThroughLoadDump - include Typecast::Time + load_as ::DateTime + dump_as ::DateTime + coercion_method :to_datetime - primitive ::DateTime - - # Typecasts an arbitrary value to a DateTime. - # Handles both Hashes and DateTime instances. - # - # @param [Hash, #to_mash, #to_s] value - # value to be typecast - # - # @return [DateTime] - # DateTime constructed from value - # - # @api private - def typecast_to_primitive(value) - if value.is_a?(::Hash) || value.respond_to?(:to_mash) - typecast_hash_to_datetime(value) - else - ::DateTime.parse(value.to_s) - end - rescue ArgumentError - value - end - - # Creates a DateTime instance from a Hash with keys :year, :month, :day, - # :hour, :min, :sec - # - # @param [Hash, #to_mash] value - # value to be typecast - # - # @return [DateTime] - # DateTime constructed from hash - # - # @api private - def typecast_hash_to_datetime(value) - ::DateTime.new(*extract_time(value)) - end end # class DateTime end # class Property end # module DataMapper diff --git a/lib/dm-core/property/decimal.rb b/lib/dm-core/property/decimal.rb index f7470e58f..756d1b3e3 100644 --- a/lib/dm-core/property/decimal.rb +++ b/lib/dm-core/property/decimal.rb @@ -1,7 +1,9 @@ module DataMapper class Property class Decimal < Numeric - primitive BigDecimal + load_as BigDecimal + dump_as BigDecimal + coercion_method :to_decimal DEFAULT_PRECISION = 10 DEFAULT_SCALE = 0 @@ -9,7 +11,7 @@ class Decimal < Numeric precision(DEFAULT_PRECISION) scale(DEFAULT_SCALE) - protected + protected def initialize(model, name, options = {}) super @@ -29,22 +31,6 @@ def initialize(model, name, options = {}) end end - # Typecast a value to a BigDecimal - # - # @param [#to_str, #to_d, Integer] value - # value to typecast - # - # @return [BigDecimal] - # BigDecimal constructed from value - # - # @api private - def typecast_to_primitive(value) - if value.kind_of?(::Integer) - value.to_s.to_d - else - typecast_to_numeric(value, :to_d) - end - end end # class Decimal end # class Property end # module DataMapper diff --git a/lib/dm-core/property/discriminator.rb b/lib/dm-core/property/discriminator.rb index a57e98d20..172e56366 100644 --- a/lib/dm-core/property/discriminator.rb +++ b/lib/dm-core/property/discriminator.rb @@ -1,8 +1,6 @@ module DataMapper class Property class Discriminator < Class - include PassThroughLoadDump - default lambda { |resource, property| resource.model } required true @@ -22,7 +20,7 @@ def new(*args, &block) discriminator = properties(repository_name).discriminator if discriminator_value = args.first[discriminator.name] - model = discriminator.typecast_to_primitive(discriminator_value) + model = discriminator.typecast(discriminator_value) if model.kind_of?(Model) && !model.equal?(self) return model.new(*args, &block) diff --git a/lib/dm-core/property/float.rb b/lib/dm-core/property/float.rb index 47f206d71..d4cf86456 100644 --- a/lib/dm-core/property/float.rb +++ b/lib/dm-core/property/float.rb @@ -1,7 +1,9 @@ module DataMapper class Property class Float < Numeric - primitive ::Float + load_as ::Float + dump_as ::Float + coercion_method :to_float DEFAULT_PRECISION = 10 DEFAULT_SCALE = nil @@ -9,20 +11,6 @@ class Float < Numeric precision(DEFAULT_PRECISION) scale(DEFAULT_SCALE) - protected - - # Typecast a value to a Float - # - # @param [#to_str, #to_f] value - # value to typecast - # - # @return [Float] - # Float constructed from value - # - # @api private - def typecast_to_primitive(value) - typecast_to_numeric(value, :to_f) - end end # class Float end # class Property end # module DataMapper diff --git a/lib/dm-core/property/integer.rb b/lib/dm-core/property/integer.rb index 49cd1575e..2bb73ab7b 100644 --- a/lib/dm-core/property/integer.rb +++ b/lib/dm-core/property/integer.rb @@ -1,11 +1,13 @@ module DataMapper class Property class Integer < Numeric - primitive ::Integer + load_as ::Integer + dump_as ::Integer + coercion_method :to_integer accept_options :serial - protected + protected # @api semipublic def initialize(model, name, options = {}) @@ -15,18 +17,6 @@ def initialize(model, name, options = {}) super end - # Typecast a value to an Integer - # - # @param [#to_str, #to_i] value - # value to typecast - # - # @return [Integer] - # Integer constructed from value - # - # @api private - def typecast_to_primitive(value) - typecast_to_numeric(value, :to_i) - end end # class Integer end # class Property end # module DataMapper diff --git a/lib/dm-core/property/lookup.rb b/lib/dm-core/property/lookup.rb index 7273a4739..fd0535646 100644 --- a/lib/dm-core/property/lookup.rb +++ b/lib/dm-core/property/lookup.rb @@ -2,7 +2,7 @@ module DataMapper class Property module Lookup - protected + protected # # Provides transparent access to the Properties defined in @@ -24,6 +24,7 @@ module Lookup def const_missing(name) Property.find_class(name.to_s) || super end - end - end -end + + end # module Lookup + end # class Property +end # module DataMapper diff --git a/lib/dm-core/property/numeric.rb b/lib/dm-core/property/numeric.rb index 6f6a83dbd..66d59cd10 100644 --- a/lib/dm-core/property/numeric.rb +++ b/lib/dm-core/property/numeric.rb @@ -1,21 +1,19 @@ module DataMapper class Property class Numeric < Object - include PassThroughLoadDump - include Typecast::Numeric - accept_options :precision, :scale, :min, :max + attr_reader :precision, :scale, :min, :max DEFAULT_NUMERIC_MIN = 0 DEFAULT_NUMERIC_MAX = 2**31-1 - protected + protected def initialize(model, name, options = {}) super - if @primitive == BigDecimal || @primitive == ::Float + if kind_of?(Decimal) || kind_of?(Float) @precision = @options.fetch(:precision) @scale = @options.fetch(:scale) diff --git a/lib/dm-core/property/object.rb b/lib/dm-core/property/object.rb index a6be62c70..b4479c22b 100644 --- a/lib/dm-core/property/object.rb +++ b/lib/dm-core/property/object.rb @@ -1,22 +1,28 @@ module DataMapper class Property class Object < Property - primitive ::Object + load_as ::Object + dump_as ::Object + coercion_method :to_object # @api semipublic def dump(value) - return if value.nil? - [ Marshal.dump(value) ].pack('m') + instance_of?(Object) ? marshal(value) : value end # @api semipublic def load(value) - case value - when ::String - Marshal.load(value.unpack('m').first) - when ::Object - value - end + typecast(instance_of?(Object) ? unmarshal(value) : value) + end + + # @api semipublic + def marshal(value) + [ Marshal.dump(value) ].pack('m') unless value.nil? + end + + # @api semipublic + def unmarshal(value) + Marshal.load(value.unpack('m').first) unless value.nil? end # @api private diff --git a/lib/dm-core/property/serial.rb b/lib/dm-core/property/serial.rb index 7d296f17b..f61adfa44 100644 --- a/lib/dm-core/property/serial.rb +++ b/lib/dm-core/property/serial.rb @@ -1,8 +1,8 @@ module DataMapper class Property class Serial < Integer - serial true - min 1 + serial true + min 1 # @api private def to_child_key diff --git a/lib/dm-core/property/string.rb b/lib/dm-core/property/string.rb index c74aff48e..35e79615b 100644 --- a/lib/dm-core/property/string.rb +++ b/lib/dm-core/property/string.rb @@ -1,9 +1,9 @@ module DataMapper class Property class String < Object - include PassThroughLoadDump - - primitive ::String + load_as ::String + dump_as ::String + coercion_method :to_string accept_options :length @@ -26,25 +26,13 @@ def length end end - protected + protected def initialize(model, name, options = {}) super @length = @options.fetch(:length) end - # Typecast a value to a String - # - # @param [#to_s] value - # value to typecast - # - # @return [String] - # String constructed from value - # - # @api private - def typecast_to_primitive(value) - value.to_s - end end # class String end # class Property end # module DataMapper diff --git a/lib/dm-core/property/text.rb b/lib/dm-core/property/text.rb index 5ac5af5d6..8e02df9e9 100644 --- a/lib/dm-core/property/text.rb +++ b/lib/dm-core/property/text.rb @@ -1,12 +1,9 @@ module DataMapper class Property class Text < String - length 65535 - lazy true + length 65535 + lazy true - def primitive?(value) - value.kind_of?(::String) - end end # class Text end # class Property end # module DataMapper diff --git a/lib/dm-core/property/time.rb b/lib/dm-core/property/time.rb index 3d1506a2a..2e63c3e99 100644 --- a/lib/dm-core/property/time.rb +++ b/lib/dm-core/property/time.rb @@ -1,46 +1,10 @@ module DataMapper class Property class Time < Object - include PassThroughLoadDump - include Typecast::Time + load_as ::Time + dump_as ::Time + coercion_method :to_time - primitive ::Time - - # Typecasts an arbitrary value to a Time - # Handles both Hashes and Time instances. - # - # @param [Hash, #to_mash, #to_s] value - # value to be typecast - # - # @return [Time] - # Time constructed from value - # - # @api private - def typecast_to_primitive(value) - if value.respond_to?(:to_time) - value.to_time - elsif value.is_a?(::Hash) || value.respond_to?(:to_mash) - typecast_hash_to_time(value) - else - ::Time.parse(value.to_s) - end - rescue ArgumentError - value - end - - # Creates a Time instance from a Hash with keys :year, :month, :day, - # :hour, :min, :sec - # - # @param [Hash, #to_mash] value - # value to be typecast - # - # @return [Time] - # Time constructed from hash - # - # @api private - def typecast_hash_to_time(value) - ::Time.local(*extract_time(value)) - end end # class Time end # class Property end # module DataMapper diff --git a/lib/dm-core/property/typecast/numeric.rb b/lib/dm-core/property/typecast/numeric.rb deleted file mode 100644 index c8aeaf208..000000000 --- a/lib/dm-core/property/typecast/numeric.rb +++ /dev/null @@ -1,32 +0,0 @@ -module DataMapper - class Property - module Typecast - module Numeric - # Match numeric string - # - # @param [#to_str, Numeric] value - # value to typecast - # @param [Symbol] method - # method to typecast with - # - # @return [Numeric] - # number if matched, value if no match - # - # @api private - def typecast_to_numeric(value, method) - if value.respond_to?(:to_str) - if value.to_str =~ /\A(-?(?:0|[1-9]\d*)(?:\.\d+)?|(?:\.\d+))\z/ - $1.send(method) - else - value - end - elsif value.respond_to?(method) - value.send(method) - else - value - end - end - end # Numeric - end # Typecast - end # Property -end # DataMapper diff --git a/lib/dm-core/property/typecast/time.rb b/lib/dm-core/property/typecast/time.rb deleted file mode 100644 index 5e24ce9e9..000000000 --- a/lib/dm-core/property/typecast/time.rb +++ /dev/null @@ -1,33 +0,0 @@ -module DataMapper - class Property - module Typecast - module Time - include Numeric - - # Extracts the given args from the hash. If a value does not exist, it - # uses the value of Time.now. - # - # @param [Hash, #to_mash] value - # value to extract time args from - # - # @return [Array] - # Extracted values - # - # @api private - def extract_time(value) - mash = if value.respond_to?(:to_mash) - value.to_mash - else - DataMapper::Ext::Hash.to_mash(value) - end - - now = ::Time.now - - [ :year, :month, :day, :hour, :min, :sec ].map do |segment| - typecast_to_numeric(mash.fetch(segment, now.send(segment)), :to_i) - end - end - end # Time - end # Typecast - end # Property -end # DataMapper diff --git a/lib/dm-core/spec/shared/public/property_spec.rb b/lib/dm-core/spec/shared/public/property_spec.rb index 577f250c2..4cec71ee1 100644 --- a/lib/dm-core/spec/shared/public/property_spec.rb +++ b/lib/dm-core/spec/shared/public/property_spec.rb @@ -1,6 +1,6 @@ share_examples_for 'A public Property' do before :all do - %w[ @type @primitive @name @value @other_value ].each do |ivar| + %w[ @type @load_as @name @value @other_value ].each do |ivar| raise "+#{ivar}+ should be defined in before block" unless instance_variable_defined?(ivar) end @@ -101,16 +101,16 @@ class ::ChildSubType < @subtype end end - describe ".primitive" do - it "should return the primitive class" do + describe ".load_as" do + it "should return the load_as" do [@type, @subtype].each do |type| - type.primitive.should be(@primitive) + type.load_as.should be(@load_as) end end - it "should change the primitive class" do - @subtype.primitive Object - @subtype.primitive.should be(Object) + it "should change the load_as class" do + @subtype.load_as Object + @subtype.load_as.should be(Object) end end end diff --git a/lib/dm-core/spec/shared/semipublic/property_spec.rb b/lib/dm-core/spec/shared/semipublic/property_spec.rb index f5185cf52..2164a6cc8 100644 --- a/lib/dm-core/spec/shared/semipublic/property_spec.rb +++ b/lib/dm-core/spec/shared/semipublic/property_spec.rb @@ -22,8 +22,8 @@ class Article @property.should be_kind_of(@type) end - it 'should set the primitive' do - @property.primitive.should be(@type.primitive) + it 'should set the load_as' do + @property.load_as.should be(@type.load_as) end it 'should set the model' do @@ -50,8 +50,8 @@ class Article @property.model.should equal(@model) end - it 'should set the primitive' do - @property.primitive.should be(@type.primitive) + it 'should set the load_as' do + @property.load_as.should be(@type.load_as) end it "should set the options to #{options.inspect}" do @@ -89,14 +89,6 @@ class Article end describe "#typecast" do - describe "when is able to do typecasting on it's own" do - it 'delegates all the work to the type' do - return_value = mock(@other_value) - @property.should_receive(:typecast_to_primitive).with(@invalid_value).and_return(return_value) - @property.typecast(@invalid_value) - end - end - describe 'when value is nil' do it 'returns value unchanged' do @property.typecast(nil).should be(nil) diff --git a/spec/public/property/binary_spec.rb b/spec/public/property/binary_spec.rb index d87c821f8..57541654d 100644 --- a/spec/public/property/binary_spec.rb +++ b/spec/public/property/binary_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :title @type = described_class - @primitive = String + @load_as = String @value = 'value' @other_value = 'return value' @invalid_value = 1 @@ -17,6 +17,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive, :length => 50) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_string, :length => 50) } end end diff --git a/spec/public/property/boolean_spec.rb b/spec/public/property/boolean_spec.rb index 7c0b04675..f3cf3be22 100644 --- a/spec/public/property/boolean_spec.rb +++ b/spec/public/property/boolean_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :active @type = described_class - @primitive = TrueClass + @load_as = TrueClass @value = true @other_value = false @invalid_value = 1 @@ -17,6 +17,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_boolean) } end end diff --git a/spec/public/property/class_spec.rb b/spec/public/property/class_spec.rb index 0615bd6cb..a3b0dc65e 100644 --- a/spec/public/property/class_spec.rb +++ b/spec/public/property/class_spec.rb @@ -10,7 +10,7 @@ class ::Bar; end @name = :type @type = described_class - @primitive = Class + @load_as = Class @value = Foo @other_value = Bar @invalid_value = 1 @@ -23,6 +23,6 @@ class ::Bar; end it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_constant) } end end diff --git a/spec/public/property/date_spec.rb b/spec/public/property/date_spec.rb index 2fe5eae0f..b85f66b9d 100644 --- a/spec/public/property/date_spec.rb +++ b/spec/public/property/date_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :created_on @type = described_class - @primitive = Date + @load_as = Date @value = Date.today @other_value = Date.today + 1 @invalid_value = 1 @@ -17,6 +17,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_date) } end end diff --git a/spec/public/property/date_time_spec.rb b/spec/public/property/date_time_spec.rb index 6524efb38..dd95d79a2 100644 --- a/spec/public/property/date_time_spec.rb +++ b/spec/public/property/date_time_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :created_at @type = described_class - @primitive = DateTime + @load_as = DateTime @value = DateTime.now @other_value = DateTime.now + 15 @invalid_value = 1 @@ -17,6 +17,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_datetime) } end end diff --git a/spec/public/property/decimal_spec.rb b/spec/public/property/decimal_spec.rb index 78cd677a0..0a3cc365b 100644 --- a/spec/public/property/decimal_spec.rb +++ b/spec/public/property/decimal_spec.rb @@ -5,7 +5,7 @@ @name = :rate @type = described_class @options = { :precision => 5, :scale => 2 } - @primitive = BigDecimal + @load_as = BigDecimal @value = BigDecimal('1.0') @other_value = BigDecimal('2.0') @invalid_value = true @@ -18,6 +18,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive, :precision => 10, :scale => 0) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_decimal, :precision => 10, :scale => 0) } end end diff --git a/spec/public/property/discriminator_spec.rb b/spec/public/property/discriminator_spec.rb index d9c74ea38..9c737718d 100644 --- a/spec/public/property/discriminator_spec.rb +++ b/spec/public/property/discriminator_spec.rb @@ -28,7 +28,7 @@ class Release < Announcement; end it { should be_kind_of(Hash) } - it { should include(:primitive => Class, :required => true) } + it { should include(:load_as => Class, :required => true) } end it 'should typecast to a Model' do diff --git a/spec/public/property/float_spec.rb b/spec/public/property/float_spec.rb index 4528a0954..e08c0005f 100644 --- a/spec/public/property/float_spec.rb +++ b/spec/public/property/float_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :rating @type = described_class - @primitive = Float + @load_as = Float @value = 0.1 @other_value = 0.2 @invalid_value = '1' @@ -17,6 +17,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive, :precision => 10, :scale => nil) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_float, :precision => 10, :scale => nil) } end end diff --git a/spec/public/property/integer_spec.rb b/spec/public/property/integer_spec.rb index de02dbbb2..925f9c187 100644 --- a/spec/public/property/integer_spec.rb +++ b/spec/public/property/integer_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :age @type = described_class - @primitive = Integer + @load_as = Integer @value = 1 @other_value = 2 @invalid_value = '1' @@ -17,6 +17,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_integer) } end end diff --git a/spec/public/property/object_spec.rb b/spec/public/property/object_spec.rb index fbf1e3e26..5f4b2e44d 100644 --- a/spec/public/property/object_spec.rb +++ b/spec/public/property/object_spec.rb @@ -62,7 +62,7 @@ class Article it { should respond_to(:valid?) } describe '#valid?' do - describe 'with a valid primitive' do + describe 'with a valid load_as' do subject { @property.valid?('lang' => 'en_CA') } it { should be(true) } diff --git a/spec/public/property/serial_spec.rb b/spec/public/property/serial_spec.rb index 093ce9883..9b1d8fd84 100644 --- a/spec/public/property/serial_spec.rb +++ b/spec/public/property/serial_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :id @type = described_class - @primitive = Integer + @load_as = Integer @value = 1 @other_value = 2 @invalid_value = 'foo' @@ -17,6 +17,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive, :min => 1, :serial => true) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_integer, :min => 1, :serial => true) } end end diff --git a/spec/public/property/string_spec.rb b/spec/public/property/string_spec.rb index d1479539f..d8c09cdac 100644 --- a/spec/public/property/string_spec.rb +++ b/spec/public/property/string_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :name @type = described_class - @primitive = String + @load_as = String @value = 'value' @other_value = 'return value' @invalid_value = 1 @@ -17,6 +17,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive, :length => 50) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_string, :length => 50) } end end diff --git a/spec/public/property/text_spec.rb b/spec/public/property/text_spec.rb index b76d2dc00..3152210cc 100644 --- a/spec/public/property/text_spec.rb +++ b/spec/public/property/text_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :title @type = described_class - @primitive = String + @load_as = String @value = 'value' @other_value = 'return value' @invalid_value = 1 @@ -17,7 +17,7 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive, :length => 65535, :lazy => true) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_string, :length => 65535, :lazy => true) } end describe 'migration with an index' do diff --git a/spec/public/property/time_spec.rb b/spec/public/property/time_spec.rb index 95621f12a..8ac930a0b 100644 --- a/spec/public/property/time_spec.rb +++ b/spec/public/property/time_spec.rb @@ -4,7 +4,7 @@ before :all do @name = :deleted_at @type = described_class - @primitive = Time + @load_as = Time @value = Time.now @other_value = Time.now + 15 @invalid_value = 1 @@ -17,6 +17,6 @@ it { should be_kind_of(Hash) } - it { should eql(:primitive => @primitive) } + it { should eql(:load_as => @load_as, :dump_as => @load_as, :coercion_method => :to_time) } end end diff --git a/spec/semipublic/property/boolean_spec.rb b/spec/semipublic/property/boolean_spec.rb index 66c7bfeb8..69c19cd16 100644 --- a/spec/semipublic/property/boolean_spec.rb +++ b/spec/semipublic/property/boolean_spec.rb @@ -43,7 +43,7 @@ end end - describe '#typecast_to_primitive' do + describe '#typecast' do [ true, 'true', 'TRUE', '1', 1, 't', 'T' ].each do |value| it "returns true when value is #{value.inspect}" do @property.typecast(value).should be(true) diff --git a/spec/semipublic/property/class_spec.rb b/spec/semipublic/property/class_spec.rb index e01bfd7b7..78e6f180e 100644 --- a/spec/semipublic/property/class_spec.rb +++ b/spec/semipublic/property/class_spec.rb @@ -17,7 +17,7 @@ class ::Bar; end it_should_behave_like 'A semipublic Property' - describe '#typecast_to_primitive' do + describe '#typecast' do it 'returns same value if a class' do @property.typecast(@model).should equal(@model) end diff --git a/spec/semipublic/property/date_spec.rb b/spec/semipublic/property/date_spec.rb index 1ef5e1501..3a3de1bec 100644 --- a/spec/semipublic/property/date_spec.rb +++ b/spec/semipublic/property/date_spec.rb @@ -11,13 +11,13 @@ it_should_behave_like 'A semipublic Property' - describe '#typecast_to_primitive' do + describe '#typecast' do describe 'and value given as a hash with keys like :year, :month, etc' do it 'builds a Date instance from hash values' do result = @property.typecast( - 'year' => '2007', - 'month' => '3', - 'day' => '25' + :year => '2007', + :month => '3', + :day => '25' ) result.should be_kind_of(Date) diff --git a/spec/semipublic/property/date_time_spec.rb b/spec/semipublic/property/date_time_spec.rb index bfc05dda9..4d1559863 100644 --- a/spec/semipublic/property/date_time_spec.rb +++ b/spec/semipublic/property/date_time_spec.rb @@ -11,16 +11,16 @@ it_should_behave_like 'A semipublic Property' - describe '#typecast_to_primitive' do + describe '#typecast' do describe 'and value given as a hash with keys like :year, :month, etc' do it 'builds a DateTime instance from hash values' do result = @property.typecast( - 'year' => '2006', - 'month' => '11', - 'day' => '23', - 'hour' => '12', - 'min' => '0', - 'sec' => '0' + :year => '2006', + :month => '11', + :day => '23', + :hour => '12', + :min => '0', + :sec => '0' ) result.should be_kind_of(DateTime) diff --git a/spec/semipublic/property/decimal_spec.rb b/spec/semipublic/property/decimal_spec.rb index 897b7e398..63af6bffa 100644 --- a/spec/semipublic/property/decimal_spec.rb +++ b/spec/semipublic/property/decimal_spec.rb @@ -12,7 +12,7 @@ it_should_behave_like 'A semipublic Property' - describe '#typecast_to_primitive' do + describe '#typecast' do it 'returns same value if a decimal' do @value = BigDecimal('24.0') @property.typecast(@value).should equal(@value) diff --git a/spec/semipublic/property/float_spec.rb b/spec/semipublic/property/float_spec.rb index 9d5f247af..6d124178c 100644 --- a/spec/semipublic/property/float_spec.rb +++ b/spec/semipublic/property/float_spec.rb @@ -11,7 +11,7 @@ it_should_behave_like 'A semipublic Property' - describe '#typecast_to_primitive' do + describe '#typecast' do it 'returns same value if a float' do @value = 24.0 @property.typecast(@value).should equal(@value) diff --git a/spec/semipublic/property/integer_spec.rb b/spec/semipublic/property/integer_spec.rb index 97b6db2ba..b64d44ffd 100644 --- a/spec/semipublic/property/integer_spec.rb +++ b/spec/semipublic/property/integer_spec.rb @@ -11,7 +11,7 @@ it_should_behave_like 'A semipublic Property' - describe '#typecast_to_primitive' do + describe '#typecast' do it 'returns same value if an integer' do @value = 24 @property.typecast(@value).should equal(@value) diff --git a/spec/semipublic/property/time_spec.rb b/spec/semipublic/property/time_spec.rb index 7c567d161..d7ea6fd17 100644 --- a/spec/semipublic/property/time_spec.rb +++ b/spec/semipublic/property/time_spec.rb @@ -11,16 +11,16 @@ it_should_behave_like 'A semipublic Property' - describe '#typecast_to_primitive' do + describe '#typecast' do describe 'and value given as a hash with keys like :year, :month, etc' do it 'builds a Time instance from hash values' do result = @property.typecast( - 'year' => '2006', - 'month' => '11', - 'day' => '23', - 'hour' => '12', - 'min' => '0', - 'sec' => '0' + :year => '2006', + :month => '11', + :day => '23', + :hour => '12', + :min => '0', + :sec => '0' ) result.should be_kind_of(Time)