diff options
Diffstat (limited to 'activemodel/test/cases')
-rw-r--r-- | activemodel/test/cases/attribute_assignment_test.rb | 2 | ||||
-rw-r--r-- | activemodel/test/cases/helper.rb | 3 | ||||
-rw-r--r-- | activemodel/test/cases/type/decimal_test.rb | 57 | ||||
-rw-r--r-- | activemodel/test/cases/type/integer_test.rb | 108 | ||||
-rw-r--r-- | activemodel/test/cases/type/registry_test.rb | 39 | ||||
-rw-r--r-- | activemodel/test/cases/type/string_test.rb | 20 | ||||
-rw-r--r-- | activemodel/test/cases/type/unsigned_integer_test.rb | 18 | ||||
-rw-r--r-- | activemodel/test/cases/types_test.rb | 122 | ||||
-rw-r--r-- | activemodel/test/cases/validations/confirmation_validation_test.rb | 14 | ||||
-rw-r--r-- | activemodel/test/cases/validations/validations_context_test.rb | 19 |
10 files changed, 398 insertions, 4 deletions
diff --git a/activemodel/test/cases/attribute_assignment_test.rb b/activemodel/test/cases/attribute_assignment_test.rb index 64a85e01eb..3336691841 100644 --- a/activemodel/test/cases/attribute_assignment_test.rb +++ b/activemodel/test/cases/attribute_assignment_test.rb @@ -70,7 +70,7 @@ class AttributeAssignmentTest < ActiveModel::TestCase end end - test "an ArgumentError is raised if a non-hash-like obejct is passed" do + test "an ArgumentError is raised if a non-hash-like object is passed" do assert_raises(ArgumentError) do Model.new(1) end diff --git a/activemodel/test/cases/helper.rb b/activemodel/test/cases/helper.rb index c100646837..27fdbc739c 100644 --- a/activemodel/test/cases/helper.rb +++ b/activemodel/test/cases/helper.rb @@ -1,6 +1,5 @@ require File.expand_path('../../../../load_paths', __FILE__) -require 'config' require 'active_model' require 'active_support/core_ext/string/access' @@ -13,8 +12,6 @@ I18n.enforce_available_locales = false require 'active_support/testing/autorun' require 'active_support/testing/method_call_assertions' -require 'minitest/mock' - # Skips the current run on Rubinius using Minitest::Assertions#skip def rubinius_skip(message = '') skip message if RUBY_ENGINE == 'rbx' diff --git a/activemodel/test/cases/type/decimal_test.rb b/activemodel/test/cases/type/decimal_test.rb new file mode 100644 index 0000000000..353dbf84ad --- /dev/null +++ b/activemodel/test/cases/type/decimal_test.rb @@ -0,0 +1,57 @@ +require "cases/helper" +require "active_model/type" + +module ActiveModel + module Type + class DecimalTest < ActiveModel::TestCase + def test_type_cast_decimal + type = Decimal.new + assert_equal BigDecimal.new("0"), type.cast(BigDecimal.new("0")) + assert_equal BigDecimal.new("123"), type.cast(123.0) + assert_equal BigDecimal.new("1"), type.cast(:"1") + end + + def test_type_cast_decimal_from_float_with_large_precision + type = Decimal.new(precision: ::Float::DIG + 2) + assert_equal BigDecimal.new("123.0"), type.cast(123.0) + end + + def test_type_cast_from_float_with_unspecified_precision + type = Decimal.new + assert_equal 22.68.to_d, type.cast(22.68) + end + + def test_type_cast_decimal_from_rational_with_precision + type = Decimal.new(precision: 2) + assert_equal BigDecimal("0.33"), type.cast(Rational(1, 3)) + end + + def test_type_cast_decimal_from_rational_with_precision_and_scale + type = Decimal.new(precision: 4, scale: 2) + assert_equal BigDecimal("0.33"), type.cast(Rational(1, 3)) + end + + def test_type_cast_decimal_from_rational_without_precision_defaults_to_18_36 + type = Decimal.new + assert_equal BigDecimal("0.333333333333333333E0"), type.cast(Rational(1, 3)) + end + + def test_type_cast_decimal_from_object_responding_to_d + value = Object.new + def value.to_d + BigDecimal.new("1") + end + type = Decimal.new + assert_equal BigDecimal("1"), type.cast(value) + end + + def test_changed? + type = Decimal.new + + assert type.changed?(5.0, 5.0, '5.0wibble') + assert_not type.changed?(5.0, 5.0, '5.0') + assert_not type.changed?(-5.0, -5.0, '-5.0') + end + end + end +end diff --git a/activemodel/test/cases/type/integer_test.rb b/activemodel/test/cases/type/integer_test.rb new file mode 100644 index 0000000000..dac922db42 --- /dev/null +++ b/activemodel/test/cases/type/integer_test.rb @@ -0,0 +1,108 @@ +require "cases/helper" +require "active_model/type" + +module ActiveModel + module Type + class IntegerTest < ActiveModel::TestCase + test "simple values" do + type = Type::Integer.new + assert_equal 1, type.cast(1) + assert_equal 1, type.cast('1') + assert_equal 1, type.cast('1ignore') + assert_equal 0, type.cast('bad1') + assert_equal 0, type.cast('bad') + assert_equal 1, type.cast(1.7) + assert_equal 0, type.cast(false) + assert_equal 1, type.cast(true) + assert_nil type.cast(nil) + end + + test "random objects cast to nil" do + type = Type::Integer.new + assert_nil type.cast([1,2]) + assert_nil type.cast({1 => 2}) + assert_nil type.cast(1..2) + end + + test "casting objects without to_i" do + type = Type::Integer.new + assert_nil type.cast(::Object.new) + end + + test "casting nan and infinity" do + type = Type::Integer.new + assert_nil type.cast(::Float::NAN) + assert_nil type.cast(1.0/0.0) + end + + test "casting booleans for database" do + type = Type::Integer.new + assert_equal 1, type.serialize(true) + assert_equal 0, type.serialize(false) + end + + test "changed?" do + type = Type::Integer.new + + assert type.changed?(5, 5, '5wibble') + assert_not type.changed?(5, 5, '5') + assert_not type.changed?(5, 5, '5.0') + assert_not type.changed?(-5, -5, '-5') + assert_not type.changed?(-5, -5, '-5.0') + assert_not type.changed?(nil, nil, nil) + end + + test "values below int min value are out of range" do + assert_raises(::RangeError) do + Integer.new.serialize(-2147483649) + end + end + + test "values above int max value are out of range" do + assert_raises(::RangeError) do + Integer.new.serialize(2147483648) + end + end + + test "very small numbers are out of range" do + assert_raises(::RangeError) do + Integer.new.serialize(-9999999999999999999999999999999) + end + end + + test "very large numbers are out of range" do + assert_raises(::RangeError) do + Integer.new.serialize(9999999999999999999999999999999) + end + end + + test "normal numbers are in range" do + type = Integer.new + assert_equal(0, type.serialize(0)) + assert_equal(-1, type.serialize(-1)) + assert_equal(1, type.serialize(1)) + end + + test "int max value is in range" do + assert_equal(2147483647, Integer.new.serialize(2147483647)) + end + + test "int min value is in range" do + assert_equal(-2147483648, Integer.new.serialize(-2147483648)) + end + + test "columns with a larger limit have larger ranges" do + type = Integer.new(limit: 8) + + assert_equal(9223372036854775807, type.serialize(9223372036854775807)) + assert_equal(-9223372036854775808, type.serialize(-9223372036854775808)) + assert_raises(::RangeError) do + type.serialize(-9999999999999999999999999999999) + end + assert_raises(::RangeError) do + type.serialize(9999999999999999999999999999999) + end + end + end + end +end diff --git a/activemodel/test/cases/type/registry_test.rb b/activemodel/test/cases/type/registry_test.rb new file mode 100644 index 0000000000..2a48998a62 --- /dev/null +++ b/activemodel/test/cases/type/registry_test.rb @@ -0,0 +1,39 @@ +require "cases/helper" +require "active_model/type" + +module ActiveModel + class RegistryTest < ActiveModel::TestCase + test "a class can be registered for a symbol" do + registry = Type::Registry.new + registry.register(:foo, ::String) + registry.register(:bar, ::Array) + + assert_equal "", registry.lookup(:foo) + assert_equal [], registry.lookup(:bar) + end + + test "a block can be registered" do + registry = Type::Registry.new + registry.register(:foo) do |*args| + [*args, "block for foo"] + end + registry.register(:bar) do |*args| + [*args, "block for bar"] + end + + assert_equal [:foo, 1, "block for foo"], registry.lookup(:foo, 1) + assert_equal [:foo, 2, "block for foo"], registry.lookup(:foo, 2) + assert_equal [:bar, 1, 2, 3, "block for bar"], registry.lookup(:bar, 1, 2, 3) + end + + test "a reasonable error is given when no type is found" do + registry = Type::Registry.new + + e = assert_raises(ArgumentError) do + registry.lookup(:foo) + end + + assert_equal "Unknown type :foo", e.message + end + end +end diff --git a/activemodel/test/cases/type/string_test.rb b/activemodel/test/cases/type/string_test.rb new file mode 100644 index 0000000000..8ec771ea42 --- /dev/null +++ b/activemodel/test/cases/type/string_test.rb @@ -0,0 +1,20 @@ +require "cases/helper" +require "active_model/type" + +module ActiveModel + class StringTypeTest < ActiveModel::TestCase + test "type casting" do + type = Type::String.new + assert_equal "t", type.cast(true) + assert_equal "f", type.cast(false) + assert_equal "123", type.cast(123) + end + + test "values are duped coming out" do + s = "foo" + type = Type::String.new + assert_not_same s, type.cast(s) + assert_not_same s, type.deserialize(s) + end + end +end diff --git a/activemodel/test/cases/type/unsigned_integer_test.rb b/activemodel/test/cases/type/unsigned_integer_test.rb new file mode 100644 index 0000000000..16301b3ac0 --- /dev/null +++ b/activemodel/test/cases/type/unsigned_integer_test.rb @@ -0,0 +1,18 @@ +require "cases/helper" +require "active_model/type" + +module ActiveModel + module Type + class UnsignedIntegerTest < ActiveModel::TestCase + test "unsigned int max value is in range" do + assert_equal(4294967295, UnsignedInteger.new.serialize(4294967295)) + end + + test "minus value is out of range" do + assert_raises(::RangeError) do + UnsignedInteger.new.serialize(-1) + end + end + end + end +end diff --git a/activemodel/test/cases/types_test.rb b/activemodel/test/cases/types_test.rb new file mode 100644 index 0000000000..f937208580 --- /dev/null +++ b/activemodel/test/cases/types_test.rb @@ -0,0 +1,122 @@ +require "cases/helper" +require "active_model/type" +require "active_support/core_ext/numeric/time" + +module ActiveModel + class TypesTest < ActiveModel::TestCase + def test_type_cast_boolean + type = Type::Boolean.new + assert type.cast('').nil? + assert type.cast(nil).nil? + + assert type.cast(true) + assert type.cast(1) + assert type.cast('1') + assert type.cast('t') + assert type.cast('T') + assert type.cast('true') + assert type.cast('TRUE') + assert type.cast('on') + assert type.cast('ON') + assert type.cast(' ') + assert type.cast("\u3000\r\n") + assert type.cast("\u0000") + assert type.cast('SOMETHING RANDOM') + + # explicitly check for false vs nil + assert_equal false, type.cast(false) + assert_equal false, type.cast(0) + assert_equal false, type.cast('0') + assert_equal false, type.cast('f') + assert_equal false, type.cast('F') + assert_equal false, type.cast('false') + assert_equal false, type.cast('FALSE') + assert_equal false, type.cast('off') + assert_equal false, type.cast('OFF') + end + + def test_type_cast_float + type = Type::Float.new + assert_equal 1.0, type.cast("1") + end + + def test_changing_float + type = Type::Float.new + + assert type.changed?(5.0, 5.0, '5wibble') + assert_not type.changed?(5.0, 5.0, '5') + assert_not type.changed?(5.0, 5.0, '5.0') + assert_not type.changed?(nil, nil, nil) + end + + def test_type_cast_binary + type = Type::Binary.new + assert_equal nil, type.cast(nil) + assert_equal "1", type.cast("1") + assert_equal 1, type.cast(1) + end + + def test_type_cast_time + type = Type::Time.new + assert_equal nil, type.cast(nil) + assert_equal nil, type.cast('') + assert_equal nil, type.cast('ABC') + + time_string = Time.now.utc.strftime("%T") + assert_equal time_string, type.cast(time_string).strftime("%T") + end + + def test_type_cast_datetime_and_timestamp + type = Type::DateTime.new + assert_equal nil, type.cast(nil) + assert_equal nil, type.cast('') + assert_equal nil, type.cast(' ') + assert_equal nil, type.cast('ABC') + + datetime_string = Time.now.utc.strftime("%FT%T") + assert_equal datetime_string, type.cast(datetime_string).strftime("%FT%T") + end + + def test_type_cast_date + type = Type::Date.new + assert_equal nil, type.cast(nil) + assert_equal nil, type.cast('') + assert_equal nil, type.cast(' ') + assert_equal nil, type.cast('ABC') + + date_string = Time.now.utc.strftime("%F") + assert_equal date_string, type.cast(date_string).strftime("%F") + end + + def test_type_cast_duration_to_integer + type = Type::Integer.new + assert_equal 1800, type.cast(30.minutes) + assert_equal 7200, type.cast(2.hours) + end + + def test_string_to_time_with_timezone + ["UTC", "US/Eastern"].each do |zone| + with_timezone_config default: zone do + type = Type::DateTime.new + assert_equal Time.utc(2013, 9, 4, 0, 0, 0), type.cast("Wed, 04 Sep 2013 03:00:00 EAT") + end + end + end + + def test_type_equality + assert_equal Type::Value.new, Type::Value.new + assert_not_equal Type::Value.new, Type::Integer.new + assert_not_equal Type::Value.new(precision: 1), Type::Value.new(precision: 2) + end + + private + + def with_timezone_config(default:) + old_zone_default = ::Time.zone_default + ::Time.zone_default = ::Time.find_zone(default) + yield + ensure + ::Time.zone_default = old_zone_default + end + end +end diff --git a/activemodel/test/cases/validations/confirmation_validation_test.rb b/activemodel/test/cases/validations/confirmation_validation_test.rb index c1431548f7..c56bf1c0ad 100644 --- a/activemodel/test/cases/validations/confirmation_validation_test.rb +++ b/activemodel/test/cases/validations/confirmation_validation_test.rb @@ -104,4 +104,18 @@ class ConfirmationValidationTest < ActiveModel::TestCase assert_equal "expected title", model.title_confirmation, "confirmation validation should not override the writer" end + + def test_title_confirmation_with_case_sensitive_option_true + Topic.validates_confirmation_of(:title, case_sensitive: true) + + t = Topic.new(title: "title", title_confirmation: "Title") + assert t.invalid? + end + + def test_title_confirmation_with_case_sensitive_option_false + Topic.validates_confirmation_of(:title, case_sensitive: false) + + t = Topic.new(title: "title", title_confirmation: "Title") + assert t.valid? + end end diff --git a/activemodel/test/cases/validations/validations_context_test.rb b/activemodel/test/cases/validations/validations_context_test.rb index 150dce379f..b901a1523e 100644 --- a/activemodel/test/cases/validations/validations_context_test.rb +++ b/activemodel/test/cases/validations/validations_context_test.rb @@ -8,6 +8,7 @@ class ValidationsContextTest < ActiveModel::TestCase end ERROR_MESSAGE = "Validation error from validator" + ANOTHER_ERROR_MESSAGE = "Another validation error from validator" class ValidatorThatAddsErrors < ActiveModel::Validator def validate(record) @@ -15,6 +16,12 @@ class ValidationsContextTest < ActiveModel::TestCase end end + class AnotherValidatorThatAddsErrors < ActiveModel::Validator + def validate(record) + record.errors[:base] << ANOTHER_ERROR_MESSAGE + end + end + test "with a class that adds errors on create and validating a new model with no arguments" do Topic.validates_with(ValidatorThatAddsErrors, on: :create) topic = Topic.new @@ -46,4 +53,16 @@ class ValidationsContextTest < ActiveModel::TestCase assert topic.invalid?(:context2), "Validation did not run on context2 when 'on' is set to context1 and context2" assert topic.errors[:base].include?(ERROR_MESSAGE) end + + test "with a class that validating a model for a multiple contexts" do + Topic.validates_with(ValidatorThatAddsErrors, on: :context1) + Topic.validates_with(AnotherValidatorThatAddsErrors, on: :context2) + + topic = Topic.new + assert topic.valid?, "Validation ran with no context given when 'on' is set to context1 and context2" + + assert topic.invalid?([:context1, :context2]), "Validation did not run on context1 when 'on' is set to context1 and context2" + assert topic.errors[:base].include?(ERROR_MESSAGE) + assert topic.errors[:base].include?(ANOTHER_ERROR_MESSAGE) + end end |