diff options
author | Eric Chapweske <eric@chapweske.com> | 2009-10-17 12:37:15 -0500 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2009-10-17 12:37:15 -0500 |
commit | f936a1f100e75082081e782e5cceb272885c2df7 (patch) | |
tree | 6c5091faa38f15765b3be153141b81d693b02d18 /activerecord/test/cases | |
parent | e13d232150921cdf0ec3d713caefa628d235152e (diff) | |
download | rails-f936a1f100e75082081e782e5cceb272885c2df7.tar.gz rails-f936a1f100e75082081e782e5cceb272885c2df7.tar.bz2 rails-f936a1f100e75082081e782e5cceb272885c2df7.zip |
Refactoring attributes/types [#3348 state:resolved]
Signed-off-by: Joshua Peek <josh@joshpeek.com>
Diffstat (limited to 'activerecord/test/cases')
-rw-r--r-- | activerecord/test/cases/attributes/aliasing_test.rb | 20 | ||||
-rw-r--r-- | activerecord/test/cases/attributes/typecasting_test.rb | 118 | ||||
-rw-r--r-- | activerecord/test/cases/types/number_test.rb | 30 | ||||
-rw-r--r-- | activerecord/test/cases/types/object_test.rb | 24 | ||||
-rw-r--r-- | activerecord/test/cases/types/serialize_test.rb | 20 | ||||
-rw-r--r-- | activerecord/test/cases/types/time_with_zone_test.rb | 42 | ||||
-rw-r--r-- | activerecord/test/cases/types/unknown_test.rb | 29 | ||||
-rw-r--r-- | activerecord/test/cases/types_test.rb | 32 |
8 files changed, 315 insertions, 0 deletions
diff --git a/activerecord/test/cases/attributes/aliasing_test.rb b/activerecord/test/cases/attributes/aliasing_test.rb new file mode 100644 index 0000000000..7ee25779f1 --- /dev/null +++ b/activerecord/test/cases/attributes/aliasing_test.rb @@ -0,0 +1,20 @@ +require "cases/helper" + +class AliasingTest < ActiveRecord::TestCase + + class AliasingAttributes < Hash + include ActiveRecord::Attributes::Aliasing + end + + test "attribute access with aliasing" do + attributes = AliasingAttributes.new + attributes[:name] = 'Batman' + attributes.aliases['nickname'] = 'name' + + assert_equal 'Batman', attributes[:name], "Symbols should point to Strings" + assert_equal 'Batman', attributes['name'] + assert_equal 'Batman', attributes['nickname'] + assert_equal 'Batman', attributes[:nickname] + end + +end diff --git a/activerecord/test/cases/attributes/typecasting_test.rb b/activerecord/test/cases/attributes/typecasting_test.rb new file mode 100644 index 0000000000..c712f224b2 --- /dev/null +++ b/activerecord/test/cases/attributes/typecasting_test.rb @@ -0,0 +1,118 @@ +require "cases/helper" + +class TypecastingTest < ActiveRecord::TestCase + + class TypecastingAttributes < Hash + include ActiveRecord::Attributes::Typecasting + end + + module MockType + class Object + + def cast(value) + value + end + + def precast(value) + value + end + + def boolean(value) + !value.blank? + end + + def appendable? + false + end + + end + + class Integer < Object + + def cast(value) + value.to_i + end + + def precast(value) + value ? value : 0 + end + + def boolean(value) + !Float(value).zero? + end + + end + + class Serialize < Object + + def cast(value) + YAML::load(value) rescue value + end + + def precast(value) + value + end + + def appendable? + true + end + + end + end + + def setup + @attributes = TypecastingAttributes.new + @attributes.types.default = MockType::Object.new + @attributes.types['comments_count'] = MockType::Integer.new + end + + test "typecast on read" do + attributes = @attributes.merge('comments_count' => '5') + assert_equal 5, attributes['comments_count'] + end + + test "typecast on write" do + @attributes['comments_count'] = false + + assert_equal 0, @attributes.to_h['comments_count'] + end + + test "serialized objects" do + attributes = @attributes.merge('tags' => [ 'peanut butter' ].to_yaml) + attributes.types['tags'] = MockType::Serialize.new + attributes['tags'] << 'jelly' + + assert_equal [ 'peanut butter', 'jelly' ], attributes['tags'] + end + + test "without typecasting" do + attributes = @attributes.without_typecast + attributes['comments_count'] = '5' + + assert_equal '5', attributes['comments_count'] + end + + test "typecast all attributes" do + attributes = @attributes.merge('title' => 'I love sandwiches', 'comments_count' => '5') + attributes.typecast! + + assert_equal({ 'title' => 'I love sandwiches', 'comments_count' => 5 }, attributes) + end + + test "query for has? value" do + attributes = @attributes.merge('comments_count' => '1') + + assert_equal true, attributes.has?('comments_count') + attributes['comments_count'] = '0' + assert_equal false, attributes.has?('comments_count') + end + + test "attributes to Hash" do + attributes_hash = { 'title' => 'I love sandwiches', 'comments_count' => '5' } + attributes = @attributes.merge(attributes_hash) + + assert_equal Hash, attributes.to_h.class + assert_equal attributes_hash, attributes.to_h + end + +end diff --git a/activerecord/test/cases/types/number_test.rb b/activerecord/test/cases/types/number_test.rb new file mode 100644 index 0000000000..ee7216a0f1 --- /dev/null +++ b/activerecord/test/cases/types/number_test.rb @@ -0,0 +1,30 @@ +require "cases/helper" + +class NumberTest < ActiveRecord::TestCase + + def setup + @column = ActiveRecord::ConnectionAdapters::Column.new('comments_count', 0, 'integer') + @number = ActiveRecord::Type::Number.new(@column) + end + + test "typecast" do + assert_equal 1, @number.cast(1) + assert_equal 1, @number.cast('1') + assert_equal 0, @number.cast('') + + assert_equal 0, @number.precast(false) + assert_equal 1, @number.precast(true) + assert_equal nil, @number.precast('') + assert_equal 0, @number.precast(0) + end + + test "cast as boolean" do + assert_equal true, @number.boolean('1') + assert_equal true, @number.boolean(1) + + assert_equal false, @number.boolean(0) + assert_equal false, @number.boolean('0') + assert_equal false, @number.boolean(nil) + end + +end diff --git a/activerecord/test/cases/types/object_test.rb b/activerecord/test/cases/types/object_test.rb new file mode 100644 index 0000000000..f2667a9b00 --- /dev/null +++ b/activerecord/test/cases/types/object_test.rb @@ -0,0 +1,24 @@ +require "cases/helper" + +class ObjectTest < ActiveRecord::TestCase + + def setup + @column = ActiveRecord::ConnectionAdapters::Column.new('name', '', 'date') + @object = ActiveRecord::Type::Object.new(@column) + end + + test "typecast with column" do + date = Date.new(2009, 7, 10) + assert_equal date, @object.cast('10-07-2009') + assert_equal nil, @object.cast('') + + assert_equal date, @object.precast(date) + end + + test "cast as boolean" do + assert_equal false, @object.boolean(nil) + assert_equal false, @object.boolean('false') + assert_equal true, @object.boolean('10-07-2009') + end + +end diff --git a/activerecord/test/cases/types/serialize_test.rb b/activerecord/test/cases/types/serialize_test.rb new file mode 100644 index 0000000000..e9423a5b9d --- /dev/null +++ b/activerecord/test/cases/types/serialize_test.rb @@ -0,0 +1,20 @@ +require "cases/helper" + +class SerializeTest < ActiveRecord::TestCase + + test "typecast" do + serializer = ActiveRecord::Type::Serialize.new(column = nil, :serialize => Array) + + assert_equal [], serializer.cast([].to_yaml) + assert_equal ['1'], serializer.cast(['1'].to_yaml) + assert_equal nil, serializer.cast(nil.to_yaml) + end + + test "cast as boolean" do + serializer = ActiveRecord::Type::Serialize.new(column = nil, :serialize => Array) + + assert_equal true, serializer.boolean(['1'].to_yaml) + assert_equal false, serializer.boolean([].to_yaml) + end + +end
\ No newline at end of file diff --git a/activerecord/test/cases/types/time_with_zone_test.rb b/activerecord/test/cases/types/time_with_zone_test.rb new file mode 100644 index 0000000000..b3de79a6c8 --- /dev/null +++ b/activerecord/test/cases/types/time_with_zone_test.rb @@ -0,0 +1,42 @@ +require "cases/helper" + +class TimeWithZoneTest < ActiveRecord::TestCase + + def setup + @column = ActiveRecord::ConnectionAdapters::Column.new('created_at', 0, 'datetime') + @time_with_zone = ActiveRecord::Type::TimeWithZone.new(@column) + end + + test "typecast" do + Time.use_zone("Pacific Time (US & Canada)") do + time_string = "2009-10-07 21:29:10" + time = Time.zone.parse(time_string) + + # assert_equal time, @time_with_zone.cast(time_string) + assert_equal nil, @time_with_zone.cast('') + assert_equal nil, @time_with_zone.cast(nil) + + assert_equal time, @time_with_zone.precast(time) + assert_equal time, @time_with_zone.precast(time_string) + assert_equal time, @time_with_zone.precast(time.to_time) + # assert_equal "#{time.to_date.to_s} 00:00:00 -0700", @time_with_zone.precast(time.to_date).to_s + end + end + + test "cast as boolean" do + Time.use_zone('Central Time (US & Canada)') do + time = Time.zone.now + + assert_equal true, @time_with_zone.boolean(time) + assert_equal true, @time_with_zone.boolean(time.to_date) + assert_equal true, @time_with_zone.boolean(time.to_time) + + assert_equal true, @time_with_zone.boolean(time.to_s) + assert_equal true, @time_with_zone.boolean(time.to_date.to_s) + assert_equal true, @time_with_zone.boolean(time.to_time.to_s) + + assert_equal false, @time_with_zone.boolean('') + end + end + +end diff --git a/activerecord/test/cases/types/unknown_test.rb b/activerecord/test/cases/types/unknown_test.rb new file mode 100644 index 0000000000..230d67b2fb --- /dev/null +++ b/activerecord/test/cases/types/unknown_test.rb @@ -0,0 +1,29 @@ +require "cases/helper" + +class UnknownTest < ActiveRecord::TestCase + + test "typecast attributes does't modify values" do + unkown = ActiveRecord::Type::Unknown.new + person = { 'name' => '0' } + + assert_equal person['name'], unkown.cast(person['name']) + assert_equal person['name'], unkown.precast(person['name']) + end + + test "cast as boolean" do + person = { 'id' => 0, 'name' => ' ', 'admin' => 'false', 'votes' => '0' } + unkown = ActiveRecord::Type::Unknown.new + + assert_equal false, unkown.boolean(person['votes']) + assert_equal false, unkown.boolean(person['admin']) + assert_equal false, unkown.boolean(person['name']) + assert_equal false, unkown.boolean(person['id']) + + person = { 'id' => 5, 'name' => 'Eric', 'admin' => 'true', 'votes' => '25' } + assert_equal true, unkown.boolean(person['votes']) + assert_equal true, unkown.boolean(person['admin']) + assert_equal true, unkown.boolean(person['name']) + assert_equal true, unkown.boolean(person['id']) + end + +end
\ No newline at end of file diff --git a/activerecord/test/cases/types_test.rb b/activerecord/test/cases/types_test.rb new file mode 100644 index 0000000000..403a9a6e02 --- /dev/null +++ b/activerecord/test/cases/types_test.rb @@ -0,0 +1,32 @@ +require "cases/helper" +require 'models/topic' + +class TypesTest < ActiveRecord::TestCase + + test "attribute types from columns" do + begin + ActiveRecord::Base.time_zone_aware_attributes = true + attribute_type_classes = {} + Topic.attribute_types.each { |key, type| attribute_type_classes[key] = type.class } + + expected = { "id" => ActiveRecord::Type::Number, + "replies_count" => ActiveRecord::Type::Number, + "parent_id" => ActiveRecord::Type::Number, + "content" => ActiveRecord::Type::Serialize, + "written_on" => ActiveRecord::Type::TimeWithZone, + "title" => ActiveRecord::Type::Object, + "author_name" => ActiveRecord::Type::Object, + "approved" => ActiveRecord::Type::Object, + "parent_title" => ActiveRecord::Type::Object, + "bonus_time" => ActiveRecord::Type::Object, + "type" => ActiveRecord::Type::Object, + "last_read" => ActiveRecord::Type::Object, + "author_email_address" => ActiveRecord::Type::Object } + + assert_equal expected, attribute_type_classes + ensure + ActiveRecord::Base.time_zone_aware_attributes = false + end + end + +end |