diff options
Diffstat (limited to 'activesupport/test')
65 files changed, 2989 insertions, 762 deletions
diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb index 40e25ce0cd..8a67b148c3 100644 --- a/activesupport/test/abstract_unit.rb +++ b/activesupport/test/abstract_unit.rb @@ -7,9 +7,6 @@ ensure $VERBOSE = old end -lib = File.expand_path("#{File.dirname(__FILE__)}/../lib") -$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib) - require 'active_support/core_ext/kernel/reporting' require 'active_support/core_ext/string/encoding' @@ -21,20 +18,8 @@ end require 'minitest/autorun' require 'empty_bool' -silence_warnings { require 'mocha' } - ENV['NO_RELOAD'] = '1' require 'active_support' -def uses_memcached(test_name) - require 'memcache' - begin - MemCache.new('localhost:11211').stats - yield - rescue MemCache::MemCacheError - $stderr.puts "Skipping #{test_name} tests. Start memcached and try again." - end -end - # Show backtraces for deprecated behavior for quicker cleanup. ActiveSupport::Deprecation.debug = true diff --git a/activesupport/test/autoload.rb b/activesupport/test/autoload_test.rb index 5d8026a9ca..7d02d835a8 100644 --- a/activesupport/test/autoload.rb +++ b/activesupport/test/autoload_test.rb @@ -28,15 +28,6 @@ class TestAutoloadModule < ActiveSupport::TestCase assert_nothing_raised { ::Fixtures::Autoload::SomeClass } end - test ":eager constants can be triggered via ActiveSupport::Autoload.eager_autoload!" do - module ::Fixtures::Autoload - autoload :SomeClass, "fixtures/autoload/some_class" - end - ActiveSupport::Autoload.eager_autoload! - assert $LOADED_FEATURES.include?("fixtures/autoload/some_class.rb") - assert_nothing_raised { ::Fixtures::Autoload::SomeClass } - end - test "the location of autoloaded constants defaults to :name.underscore" do module ::Fixtures::Autoload autoload :SomeClass @@ -51,8 +42,7 @@ class TestAutoloadModule < ActiveSupport::TestCase autoload :SomeClass end - ActiveSupport::Autoload.eager_autoload! - assert $LOADED_FEATURES.include?("fixtures/autoload/some_class.rb") + ::Fixtures::Autoload.eager_load! assert_nothing_raised { ::Fixtures::Autoload::SomeClass } end diff --git a/activesupport/test/autoloading_fixtures/circular1.rb b/activesupport/test/autoloading_fixtures/circular1.rb new file mode 100644 index 0000000000..a45761f066 --- /dev/null +++ b/activesupport/test/autoloading_fixtures/circular1.rb @@ -0,0 +1,6 @@ +silence_warnings do + Circular2 +end + +class Circular1 +end diff --git a/activesupport/test/autoloading_fixtures/circular2.rb b/activesupport/test/autoloading_fixtures/circular2.rb new file mode 100644 index 0000000000..c847fa5001 --- /dev/null +++ b/activesupport/test/autoloading_fixtures/circular2.rb @@ -0,0 +1,4 @@ +Circular1 + +class Circular2 +end diff --git a/activesupport/test/autoloading_fixtures/class_folder/class_folder_subclass.rb b/activesupport/test/autoloading_fixtures/class_folder/class_folder_subclass.rb index ef66ddaac7..402609c583 100644 --- a/activesupport/test/autoloading_fixtures/class_folder/class_folder_subclass.rb +++ b/activesupport/test/autoloading_fixtures/class_folder/class_folder_subclass.rb @@ -1,3 +1,3 @@ class ClassFolder::ClassFolderSubclass < ClassFolder - ConstantInClassFolder + ConstantInClassFolder = 'indeed' end diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index b03865da93..71cd9d81b3 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -69,6 +69,10 @@ class CacheKeyTest < ActiveSupport::TestCase def test_expand_cache_key_of_true assert_equal 'true', ActiveSupport::Cache.expand_cache_key(true) end + + def test_expand_cache_key_of_array_like_object + assert_equal 'foo/bar/baz', ActiveSupport::Cache.expand_cache_key(%w{foo bar baz}.to_enum) + end end class CacheStoreSettingTest < ActiveSupport::TestCase @@ -79,20 +83,20 @@ class CacheStoreSettingTest < ActiveSupport::TestCase end def test_mem_cache_fragment_cache_store - MemCache.expects(:new).with(%w[localhost], {}) + Dalli::Client.expects(:new).with(%w[localhost], {}) store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost" assert_kind_of(ActiveSupport::Cache::MemCacheStore, store) end def test_mem_cache_fragment_cache_store_with_given_mem_cache - mem_cache = MemCache.new - MemCache.expects(:new).never + mem_cache = Dalli::Client.new + Dalli::Client.expects(:new).never store = ActiveSupport::Cache.lookup_store :mem_cache_store, mem_cache assert_kind_of(ActiveSupport::Cache::MemCacheStore, store) end def test_mem_cache_fragment_cache_store_with_given_mem_cache_like_object - MemCache.expects(:new).never + Dalli::Client.expects(:new).never memcache = Object.new def memcache.get() true end store = ActiveSupport::Cache.lookup_store :mem_cache_store, memcache @@ -100,13 +104,13 @@ class CacheStoreSettingTest < ActiveSupport::TestCase end def test_mem_cache_fragment_cache_store_with_multiple_servers - MemCache.expects(:new).with(%w[localhost 192.168.1.1], {}) + Dalli::Client.expects(:new).with(%w[localhost 192.168.1.1], {}) store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1' assert_kind_of(ActiveSupport::Cache::MemCacheStore, store) end def test_mem_cache_fragment_cache_store_with_options - MemCache.expects(:new).with(%w[localhost 192.168.1.1], { :timeout => 10 }) + Dalli::Client.expects(:new).with(%w[localhost 192.168.1.1], { :timeout => 10 }) store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost", '192.168.1.1', :namespace => 'foo', :timeout => 10 assert_kind_of(ActiveSupport::Cache::MemCacheStore, store) assert_equal 'foo', store.options[:namespace] @@ -443,6 +447,7 @@ module CacheIncrementDecrementBehavior assert_equal 2, @cache.read('foo').to_i assert_equal 3, @cache.increment('foo') assert_equal 3, @cache.read('foo').to_i + assert_nil @cache.increment('bar') end def test_decrement @@ -452,6 +457,7 @@ module CacheIncrementDecrementBehavior assert_equal 2, @cache.read('foo').to_i assert_equal 1, @cache.decrement('foo') assert_equal 1, @cache.read('foo').to_i + assert_nil @cache.decrement('bar') end end @@ -549,6 +555,9 @@ class FileStoreTest < ActiveSupport::TestCase @cache = ActiveSupport::Cache.lookup_store(:file_store, cache_dir, :expires_in => 60) @peek = ActiveSupport::Cache.lookup_store(:file_store, cache_dir, :expires_in => 60) @cache_with_pathname = ActiveSupport::Cache.lookup_store(:file_store, Pathname.new(cache_dir), :expires_in => 60) + + @buffer = StringIO.new + @cache.logger = ActiveSupport::Logger.new(@buffer) end def teardown @@ -564,6 +573,13 @@ class FileStoreTest < ActiveSupport::TestCase include CacheDeleteMatchedBehavior include CacheIncrementDecrementBehavior + def test_clear + filepath = File.join(cache_dir, ".gitkeep") + FileUtils.touch(filepath) + @cache.clear + assert File.exist?(filepath) + end + def test_key_transformation key = @cache.send(:key_file_path, "views/index?id=1") assert_equal "views/index?id=1", @cache.send(:file_path_key, key) @@ -575,6 +591,16 @@ class FileStoreTest < ActiveSupport::TestCase assert_equal "views/index?id=1", @cache_with_pathname.send(:file_path_key, key) end + # Test that generated cache keys are short enough to have Tempfile stuff added to them and + # remain valid + def test_filename_max_size + key = "#{'A' * ActiveSupport::Cache::FileStore::FILENAME_MAX_SIZE}" + path = @cache.send(:key_file_path, key) + Dir::Tmpname.create(path) do |tmpname, n, opts| + assert File.basename(tmpname+'.lock').length <= 255, "Temp filename too long: #{File.basename(tmpname+'.lock').length}" + end + end + # Because file systems have a maximum filename size, filenames > max size should be split in to directories # If filename is 'AAAAB', where max size is 4, the returned path should be AAAA/B def test_key_transformation_max_filename_size @@ -591,6 +617,12 @@ class FileStoreTest < ActiveSupport::TestCase ActiveSupport::Cache::FileStore.new('/test/cache/directory').delete_matched(/does_not_exist/) end end + + def test_log_exception_when_cache_read_fails + File.expects(:exist?).raises(StandardError, "failed") + @cache.send(:read_entry, "winston", {}) + assert_present @buffer.string + end end class MemoryStoreTest < ActiveSupport::TestCase @@ -663,55 +695,74 @@ class MemoryStoreTest < ActiveSupport::TestCase assert @cache.exist?(2) assert !@cache.exist?(1) end + + def test_write_with_unless_exist + assert_equal true, @cache.write(1, "aaaaaaaaaa") + assert_equal false, @cache.write(1, "aaaaaaaaaa", :unless_exist => true) + @cache.write(1, nil) + assert_equal false, @cache.write(1, "aaaaaaaaaa", :unless_exist => true) + end end -uses_memcached 'memcached backed store' do - class MemCacheStoreTest < ActiveSupport::TestCase - def setup - @cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :expires_in => 60) - @peek = ActiveSupport::Cache.lookup_store(:mem_cache_store) - @data = @cache.instance_variable_get(:@data) - @cache.clear - @cache.silence! - @cache.logger = ActiveSupport::Logger.new("/dev/null") - end +class MemCacheStoreTest < ActiveSupport::TestCase + require 'dalli' - include CacheStoreBehavior - include LocalCacheBehavior - include CacheIncrementDecrementBehavior - include EncodedKeyCacheBehavior + begin + ss = Dalli::Client.new('localhost:11211').stats + raise Dalli::DalliError unless ss['localhost:11211'] + + MEMCACHE_UP = true + rescue Dalli::DalliError + $stderr.puts "Skipping memcached tests. Start memcached and try again." + MEMCACHE_UP = false + end - def test_raw_values - cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true) - cache.clear + def setup + skip "memcache server is not up" unless MEMCACHE_UP + + @cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :expires_in => 60) + @peek = ActiveSupport::Cache.lookup_store(:mem_cache_store) + @data = @cache.instance_variable_get(:@data) + @cache.clear + @cache.silence! + @cache.logger = ActiveSupport::Logger.new("/dev/null") + end + + include CacheStoreBehavior + include LocalCacheBehavior + include CacheIncrementDecrementBehavior + include EncodedKeyCacheBehavior + + def test_raw_values + cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true) + cache.clear + cache.write("foo", 2) + assert_equal "2", cache.read("foo") + end + + def test_raw_values_with_marshal + cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true) + cache.clear + cache.write("foo", Marshal.dump([])) + assert_equal [], cache.read("foo") + end + + def test_local_cache_raw_values + cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true) + cache.clear + cache.with_local_cache do cache.write("foo", 2) assert_equal "2", cache.read("foo") end + end - def test_raw_values_with_marshal - cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true) - cache.clear + def test_local_cache_raw_values_with_marshal + cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true) + cache.clear + cache.with_local_cache do cache.write("foo", Marshal.dump([])) assert_equal [], cache.read("foo") end - - def test_local_cache_raw_values - cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true) - cache.clear - cache.with_local_cache do - cache.write("foo", 2) - assert_equal "2", cache.read("foo") - end - end - - def test_local_cache_raw_values_with_marshal - cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, :raw => true) - cache.clear - cache.with_local_cache do - cache.write("foo", Marshal.dump([])) - assert_equal [], cache.read("foo") - end - end end end diff --git a/activesupport/test/callback_inheritance_test.rb b/activesupport/test/callback_inheritance_test.rb index e5ac9511df..6be8ea8b84 100644 --- a/activesupport/test/callback_inheritance_test.rb +++ b/activesupport/test/callback_inheritance_test.rb @@ -29,7 +29,7 @@ class GrandParent end def dispatch - run_callbacks(:dispatch, action_name) do + run_callbacks :dispatch do @log << action_name end self diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb index 25688a9da5..b7c3b130c3 100644 --- a/activesupport/test/callbacks_test.rb +++ b/activesupport/test/callbacks_test.rb @@ -112,7 +112,7 @@ module CallbacksTest end def dispatch - run_callbacks :dispatch, action_name do + run_callbacks :dispatch do @logger << "Done" end self @@ -153,7 +153,7 @@ module CallbacksTest end def save - run_callbacks :save, :action + run_callbacks :save end end @@ -338,7 +338,7 @@ module CallbacksTest end def save - run_callbacks :save, "hyphen-ated" do + run_callbacks :save do @stuff end end diff --git a/activesupport/test/clean_backtrace_test.rb b/activesupport/test/clean_backtrace_test.rb index 32e346bb48..b14950acb3 100644 --- a/activesupport/test/clean_backtrace_test.rb +++ b/activesupport/test/clean_backtrace_test.rb @@ -6,8 +6,10 @@ class BacktraceCleanerFilterTest < ActiveSupport::TestCase @bc.add_filter { |line| line.gsub("/my/prefix", '') } end - test "backtrace should not contain prefix when it has been filtered out" do - assert_equal "/my/class.rb", @bc.clean([ "/my/prefix/my/class.rb" ]).first + test "backtrace should filter all lines in a backtrace, removing prefixes" do + assert_equal \ + ["/my/class.rb", "/my/module.rb"], + @bc.clean(["/my/prefix/my/class.rb", "/my/prefix/my/module.rb"]) end test "backtrace cleaner should allow removing filters" do @@ -19,11 +21,6 @@ class BacktraceCleanerFilterTest < ActiveSupport::TestCase assert_equal "/my/other_prefix/my/class.rb", @bc.clean([ "/my/other_prefix/my/class.rb" ]).first end - test "backtrace should filter all lines in a backtrace" do - assert_equal \ - ["/my/class.rb", "/my/module.rb"], - @bc.clean([ "/my/prefix/my/class.rb", "/my/prefix/my/module.rb" ]) - end end class BacktraceCleanerSilencerTest < ActiveSupport::TestCase diff --git a/activesupport/test/configurable_test.rb b/activesupport/test/configurable_test.rb index 2e5ea2c360..215a6e06b0 100644 --- a/activesupport/test/configurable_test.rb +++ b/activesupport/test/configurable_test.rb @@ -5,7 +5,8 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase class Parent include ActiveSupport::Configurable config_accessor :foo - config_accessor :bar, :instance_reader => false, :instance_writer => false + config_accessor :bar, instance_reader: false, instance_writer: false + config_accessor :baz, instance_accessor: false end class Child < Parent @@ -19,13 +20,13 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase end test "adds a configuration hash" do - assert_equal({ :foo => :bar }, Parent.config) + assert_equal({ foo: :bar }, Parent.config) end test "adds a configuration hash to a module as well" do mixin = Module.new { include ActiveSupport::Configurable } mixin.config.foo = :bar - assert_equal({ :foo => :bar }, mixin.config) + assert_equal({ foo: :bar }, mixin.config) end test "configuration hash is inheritable" do @@ -39,8 +40,24 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase test "configuration accessors is not available on instance" do instance = Parent.new + assert !instance.respond_to?(:bar) assert !instance.respond_to?(:bar=) + + assert !instance.respond_to?(:baz) + assert !instance.respond_to?(:baz=) + end + + test "configuration accessors can take a default value" do + parent = Class.new do + include ActiveSupport::Configurable + config_accessor :hair_colors, :tshirt_colors do + [:black, :blue, :white] + end + end + + assert_equal [:black, :blue, :white], parent.hair_colors + assert_equal [:black, :blue, :white], parent.tshirt_colors end test "configuration hash is available on instance" do @@ -71,6 +88,15 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase assert_method_defined child.new.config, :bar end + test "should raise name error if attribute name is invalid" do + assert_raises NameError do + Class.new do + include ActiveSupport::Configurable + config_accessor "invalid attribute name" + end + end + end + def assert_method_defined(object, method) methods = object.public_methods.map(&:to_s) assert methods.include?(method.to_s), "Expected #{methods.inspect} to include #{method.to_s.inspect}" diff --git a/activesupport/test/constantize_test_cases.rb b/activesupport/test/constantize_test_cases.rb index 135f894056..ec05213409 100644 --- a/activesupport/test/constantize_test_cases.rb +++ b/activesupport/test/constantize_test_cases.rb @@ -1,16 +1,41 @@ module Ace module Base class Case + class Dice + end + end + class Fase < Case + end + end + class Gas + include Base + end +end + +class Object + module AddtlGlobalConstants + class Case + class Dice + end end end + include AddtlGlobalConstants end module ConstantizeTestCases def run_constantize_tests_on assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") } assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") } + assert_nothing_raised { assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") } + assert_nothing_raised { assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") } + assert_nothing_raised { assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") } + assert_nothing_raised { assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice") } + assert_nothing_raised { assert_equal Case::Dice, yield("Case::Dice") } + assert_nothing_raised { assert_equal Case::Dice, yield("Object::Case::Dice") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } + assert_nothing_raised { assert_equal Object, yield("") } + assert_nothing_raised { assert_equal Object, yield("::") } assert_raise(NameError) { yield("UnknownClass") } assert_raise(NameError) { yield("UnknownClass::Ace") } assert_raise(NameError) { yield("UnknownClass::Ace::Base") } @@ -18,13 +43,23 @@ module ConstantizeTestCases assert_raise(NameError) { yield("InvalidClass\n") } assert_raise(NameError) { yield("Ace::ConstantizeTestCases") } assert_raise(NameError) { yield("Ace::Base::ConstantizeTestCases") } + assert_raise(NameError) { yield("Ace::Gas::Base") } + assert_raise(NameError) { yield("Ace::Gas::ConstantizeTestCases") } end def run_safe_constantize_tests_on assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") } assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") } + assert_nothing_raised { assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") } + assert_nothing_raised { assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") } + assert_nothing_raised { assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") } + assert_nothing_raised { assert_equal Ace::Gas::Case::Dice, yield("Ace::Gas::Case::Dice") } + assert_nothing_raised { assert_equal Case::Dice, yield("Case::Dice") } + assert_nothing_raised { assert_equal Case::Dice, yield("Object::Case::Dice") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } + assert_nothing_raised { assert_equal Object, yield("") } + assert_nothing_raised { assert_equal Object, yield("::") } assert_nothing_raised { assert_equal nil, yield("UnknownClass") } assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace") } assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace::Base") } @@ -33,6 +68,8 @@ module ConstantizeTestCases assert_nothing_raised { assert_equal nil, yield("blargle") } assert_nothing_raised { assert_equal nil, yield("Ace::ConstantizeTestCases") } assert_nothing_raised { assert_equal nil, yield("Ace::Base::ConstantizeTestCases") } + assert_nothing_raised { assert_equal nil, yield("Ace::Gas::Base") } + assert_nothing_raised { assert_equal nil, yield("Ace::Gas::ConstantizeTestCases") } assert_nothing_raised { assert_equal nil, yield("#<Class:0x7b8b718b>::Nested_1") } end end diff --git a/activesupport/test/core_ext/array_ext_test.rb b/activesupport/test/core_ext/array_ext_test.rb index 58835c0ac5..9dfa2cbf11 100644 --- a/activesupport/test/core_ext/array_ext_test.rb +++ b/activesupport/test/core_ext/array_ext_test.rb @@ -90,6 +90,12 @@ class ArrayExtToSentenceTests < ActiveSupport::TestCase def test_one_non_string_element assert_equal '1', [1].to_sentence end + + def test_does_not_modify_given_hash + options = { words_connector: ' ' } + assert_equal "one two, and three", ['one', 'two', 'three'].to_sentence(options) + assert_equal({ words_connector: ' ' }, options) + end end class ArrayExtToSTests < ActiveSupport::TestCase diff --git a/activesupport/test/core_ext/bigdecimal_test.rb b/activesupport/test/core_ext/bigdecimal_test.rb index e24a089650..a5987044b9 100644 --- a/activesupport/test/core_ext/bigdecimal_test.rb +++ b/activesupport/test/core_ext/bigdecimal_test.rb @@ -14,4 +14,9 @@ class BigDecimalTest < ActiveSupport::TestCase bd = BigDecimal.new '10' assert_equal bd, bd.to_d end + + def test_to_s + bd = BigDecimal.new '0.01' + assert_equal '0.01', bd.to_s + end end diff --git a/activesupport/test/core_ext/class/attribute_accessor_test.rb b/activesupport/test/core_ext/class/attribute_accessor_test.rb index 3822e7af66..8d827f054e 100644 --- a/activesupport/test/core_ext/class/attribute_accessor_test.rb +++ b/activesupport/test/core_ext/class/attribute_accessor_test.rb @@ -42,4 +42,18 @@ class ClassAttributeAccessorTest < ActiveSupport::TestCase assert !@object.respond_to?(:camp) assert !@object.respond_to?(:camp=) end + + def test_should_raise_name_error_if_attribute_name_is_invalid + assert_raises NameError do + Class.new do + cattr_reader "invalid attribute name" + end + end + + assert_raises NameError do + Class.new do + cattr_writer "invalid attribute name" + end + end + end end diff --git a/activesupport/test/core_ext/class/attribute_test.rb b/activesupport/test/core_ext/class/attribute_test.rb index e290a6e012..1c3ba8a7a0 100644 --- a/activesupport/test/core_ext/class/attribute_test.rb +++ b/activesupport/test/core_ext/class/attribute_test.rb @@ -66,6 +66,13 @@ class ClassAttributeTest < ActiveSupport::TestCase assert_raise(NoMethodError) { object.setting? } end + test 'disabling both instance writer and reader' do + object = Class.new { class_attribute :setting, :instance_accessor => false }.new + assert_raise(NoMethodError) { object.setting } + assert_raise(NoMethodError) { object.setting? } + assert_raise(NoMethodError) { object.setting = 'boom' } + end + test 'works well with singleton classes' do object = @klass.new object.singleton_class.setting = 'foo' diff --git a/activesupport/test/core_ext/date_and_time_behavior.rb b/activesupport/test/core_ext/date_and_time_behavior.rb new file mode 100644 index 0000000000..9927856aa2 --- /dev/null +++ b/activesupport/test/core_ext/date_and_time_behavior.rb @@ -0,0 +1,236 @@ +require 'abstract_unit' + +module DateAndTimeBehavior + def test_yesterday + assert_equal date_time_init(2005,2,21,10,10,10), date_time_init(2005,2,22,10,10,10).yesterday + assert_equal date_time_init(2005,2,28,10,10,10), date_time_init(2005,3,2,10,10,10).yesterday.yesterday + end + + def test_tomorrow + assert_equal date_time_init(2005,2,23,10,10,10), date_time_init(2005,2,22,10,10,10).tomorrow + assert_equal date_time_init(2005,3,2,10,10,10), date_time_init(2005,2,28,10,10,10).tomorrow.tomorrow + end + + def test_days_ago + assert_equal date_time_init(2005,6,4,10,10,10), date_time_init(2005,6,5,10,10,10).days_ago(1) + assert_equal date_time_init(2005,5,31,10,10,10), date_time_init(2005,6,5,10,10,10).days_ago(5) + end + + def test_days_since + assert_equal date_time_init(2005,6,6,10,10,10), date_time_init(2005,6,5,10,10,10).days_since(1) + assert_equal date_time_init(2005,1,1,10,10,10), date_time_init(2004,12,31,10,10,10).days_since(1) + end + + def test_weeks_ago + assert_equal date_time_init(2005,5,29,10,10,10), date_time_init(2005,6,5,10,10,10).weeks_ago(1) + assert_equal date_time_init(2005,5,1,10,10,10), date_time_init(2005,6,5,10,10,10).weeks_ago(5) + assert_equal date_time_init(2005,4,24,10,10,10), date_time_init(2005,6,5,10,10,10).weeks_ago(6) + assert_equal date_time_init(2005,2,27,10,10,10), date_time_init(2005,6,5,10,10,10).weeks_ago(14) + assert_equal date_time_init(2004,12,25,10,10,10), date_time_init(2005,1,1,10,10,10).weeks_ago(1) + end + + def test_weeks_since + assert_equal date_time_init(2005,7,14,10,10,10), date_time_init(2005,7,7,10,10,10).weeks_since(1) + assert_equal date_time_init(2005,7,14,10,10,10), date_time_init(2005,7,7,10,10,10).weeks_since(1) + assert_equal date_time_init(2005,7,4,10,10,10), date_time_init(2005,6,27,10,10,10).weeks_since(1) + assert_equal date_time_init(2005,1,4,10,10,10), date_time_init(2004,12,28,10,10,10).weeks_since(1) + end + + def test_months_ago + assert_equal date_time_init(2005,5,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_ago(1) + assert_equal date_time_init(2004,11,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_ago(7) + assert_equal date_time_init(2004,12,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_ago(6) + assert_equal date_time_init(2004,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_ago(12) + assert_equal date_time_init(2003,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_ago(24) + end + + def test_months_since + assert_equal date_time_init(2005,7,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_since(1) + assert_equal date_time_init(2006,1,5,10,10,10), date_time_init(2005,12,5,10,10,10).months_since(1) + assert_equal date_time_init(2005,12,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_since(6) + assert_equal date_time_init(2006,6,5,10,10,10), date_time_init(2005,12,5,10,10,10).months_since(6) + assert_equal date_time_init(2006,1,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_since(7) + assert_equal date_time_init(2006,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_since(12) + assert_equal date_time_init(2007,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).months_since(24) + assert_equal date_time_init(2005,4,30,10,10,10), date_time_init(2005,3,31,10,10,10).months_since(1) + assert_equal date_time_init(2005,2,28,10,10,10), date_time_init(2005,1,29,10,10,10).months_since(1) + assert_equal date_time_init(2005,2,28,10,10,10), date_time_init(2005,1,30,10,10,10).months_since(1) + assert_equal date_time_init(2005,2,28,10,10,10), date_time_init(2005,1,31,10,10,10).months_since(1) + end + + def test_years_ago + assert_equal date_time_init(2004,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).years_ago(1) + assert_equal date_time_init(1998,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).years_ago(7) + assert_equal date_time_init(2003,2,28,10,10,10), date_time_init(2004,2,29,10,10,10).years_ago(1) # 1 year ago from leap day + end + + def test_years_since + assert_equal date_time_init(2006,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).years_since(1) + assert_equal date_time_init(2012,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).years_since(7) + assert_equal date_time_init(2005,2,28,10,10,10), date_time_init(2004,2,29,10,10,10).years_since(1) # 1 year since leap day + assert_equal date_time_init(2182,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).years_since(177) + end + + def test_beginning_of_month + assert_equal date_time_init(2005,2,1,0,0,0), date_time_init(2005,2,22,10,10,10).beginning_of_month + end + + def test_beginning_of_quarter + assert_equal date_time_init(2005,1,1,0,0,0), date_time_init(2005,2,15,10,10,10).beginning_of_quarter + assert_equal date_time_init(2005,1,1,0,0,0), date_time_init(2005,1,1,0,0,0).beginning_of_quarter + assert_equal date_time_init(2005,10,1,0,0,0), date_time_init(2005,12,31,10,10,10).beginning_of_quarter + assert_equal date_time_init(2005,4,1,0,0,0), date_time_init(2005,6,30,23,59,59).beginning_of_quarter + end + + def test_end_of_quarter + assert_equal date_time_init(2007,3,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,2,15,10,10,10).end_of_quarter + assert_equal date_time_init(2007,3,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,3,31,0,0,0).end_of_quarter + assert_equal date_time_init(2007,12,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,12,21,10,10,10).end_of_quarter + assert_equal date_time_init(2007,6,30,23,59,59,Rational(999999999, 1000)), date_time_init(2007,4,1,0,0,0).end_of_quarter + assert_equal date_time_init(2008,6,30,23,59,59,Rational(999999999, 1000)), date_time_init(2008,5,31,0,0,0).end_of_quarter + end + + def test_beginning_of_year + assert_equal date_time_init(2005,1,1,0,0,0), date_time_init(2005,2,22,10,10,10).beginning_of_year + end + + def test_next_week + assert_equal date_time_init(2005,2,28,0,0,0), date_time_init(2005,2,22,15,15,10).next_week + assert_equal date_time_init(2005,3,4,0,0,0), date_time_init(2005,2,22,15,15,10).next_week(:friday) + assert_equal date_time_init(2006,10,30,0,0,0), date_time_init(2006,10,23,0,0,0).next_week + assert_equal date_time_init(2006,11,1,0,0,0), date_time_init(2006,10,23,0,0,0).next_week(:wednesday) + end + + def test_next_week_with_default_beginning_of_week_set + with_bw_default(:tuesday) do + assert_equal Time.local(2012, 3, 28), Time.local(2012, 3, 21).next_week(:wednesday) + assert_equal Time.local(2012, 3, 31), Time.local(2012, 3, 21).next_week(:saturday) + assert_equal Time.local(2012, 3, 27), Time.local(2012, 3, 21).next_week(:tuesday) + assert_equal Time.local(2012, 4, 02), Time.local(2012, 3, 21).next_week(:monday) + end + end + + def test_next_month_on_31st + assert_equal date_time_init(2005,9,30,15,15,10), date_time_init(2005,8,31,15,15,10).next_month + end + + def test_next_quarter_on_31st + assert_equal date_time_init(2005,11,30,15,15,10), date_time_init(2005,8,31,15,15,10).next_quarter + end + + def test_next_year + assert_equal date_time_init(2006,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).next_year + end + + def test_prev_week + assert_equal date_time_init(2005,2,21,0,0,0), date_time_init(2005,3,1,15,15,10).prev_week + assert_equal date_time_init(2005,2,22,0,0,0), date_time_init(2005,3,1,15,15,10).prev_week(:tuesday) + assert_equal date_time_init(2005,2,25,0,0,0), date_time_init(2005,3,1,15,15,10).prev_week(:friday) + assert_equal date_time_init(2006,10,30,0,0,0), date_time_init(2006,11,6,0,0,0).prev_week + assert_equal date_time_init(2006,11,15,0,0,0), date_time_init(2006,11,23,0,0,0).prev_week(:wednesday) + end + + def test_prev_week_with_default_beginning_of_week + with_bw_default(:tuesday) do + assert_equal Time.local(2012, 3, 14), Time.local(2012, 3, 21).prev_week(:wednesday) + assert_equal Time.local(2012, 3, 17), Time.local(2012, 3, 21).prev_week(:saturday) + assert_equal Time.local(2012, 3, 13), Time.local(2012, 3, 21).prev_week(:tuesday) + assert_equal Time.local(2012, 3, 19), Time.local(2012, 3, 21).prev_week(:monday) + end + end + + def test_prev_month_on_31st + assert_equal date_time_init(2004,2,29,10,10,10), date_time_init(2004,3,31,10,10,10).prev_month + end + + def test_prev_quarter_on_31st + assert_equal date_time_init(2004,2,29,10,10,10), date_time_init(2004,5,31,10,10,10).prev_quarter + end + + def test_prev_year + assert_equal date_time_init(2004,6,5,10,10,10), date_time_init(2005,6,5,10,10,10).prev_year + end + + def test_days_to_week_start + assert_equal 0, date_time_init(2011,11,01,0,0,0).days_to_week_start(:tuesday) + assert_equal 1, date_time_init(2011,11,02,0,0,0).days_to_week_start(:tuesday) + assert_equal 2, date_time_init(2011,11,03,0,0,0).days_to_week_start(:tuesday) + assert_equal 3, date_time_init(2011,11,04,0,0,0).days_to_week_start(:tuesday) + assert_equal 4, date_time_init(2011,11,05,0,0,0).days_to_week_start(:tuesday) + assert_equal 5, date_time_init(2011,11,06,0,0,0).days_to_week_start(:tuesday) + assert_equal 6, date_time_init(2011,11,07,0,0,0).days_to_week_start(:tuesday) + + assert_equal 3, date_time_init(2011,11,03,0,0,0).days_to_week_start(:monday) + assert_equal 3, date_time_init(2011,11,04,0,0,0).days_to_week_start(:tuesday) + assert_equal 3, date_time_init(2011,11,05,0,0,0).days_to_week_start(:wednesday) + assert_equal 3, date_time_init(2011,11,06,0,0,0).days_to_week_start(:thursday) + assert_equal 3, date_time_init(2011,11,07,0,0,0).days_to_week_start(:friday) + assert_equal 3, date_time_init(2011,11,8,0,0,0).days_to_week_start(:saturday) + assert_equal 3, date_time_init(2011,11,9,0,0,0).days_to_week_start(:sunday) + end + + def test_days_to_week_start_with_default_set + with_bw_default(:friday) do + assert_equal 6, Time.local(2012,03,8,0,0,0).days_to_week_start + assert_equal 5, Time.local(2012,03,7,0,0,0).days_to_week_start + assert_equal 4, Time.local(2012,03,6,0,0,0).days_to_week_start + assert_equal 3, Time.local(2012,03,5,0,0,0).days_to_week_start + assert_equal 2, Time.local(2012,03,4,0,0,0).days_to_week_start + assert_equal 1, Time.local(2012,03,3,0,0,0).days_to_week_start + assert_equal 0, Time.local(2012,03,2,0,0,0).days_to_week_start + end + end + + def test_beginning_of_week + assert_equal date_time_init(2005,1,31,0,0,0), date_time_init(2005,2,4,10,10,10).beginning_of_week + assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,11,28,0,0,0).beginning_of_week #monday + assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,11,29,0,0,0).beginning_of_week #tuesday + assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,11,30,0,0,0).beginning_of_week #wednesday + assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,12,01,0,0,0).beginning_of_week #thursday + assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,12,02,0,0,0).beginning_of_week #friday + assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,12,03,0,0,0).beginning_of_week #saturday + assert_equal date_time_init(2005,11,28,0,0,0), date_time_init(2005,12,04,0,0,0).beginning_of_week #sunday + end + + def test_end_of_week + assert_equal date_time_init(2008,1,6,23,59,59,Rational(999999999, 1000)), date_time_init(2007,12,31,10,10,10).end_of_week + assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,27,0,0,0).end_of_week #monday + assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,28,0,0,0).end_of_week #tuesday + assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,29,0,0,0).end_of_week #wednesday + assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,30,0,0,0).end_of_week #thursday + assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,8,31,0,0,0).end_of_week #friday + assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,9,01,0,0,0).end_of_week #saturday + assert_equal date_time_init(2007,9,2,23,59,59,Rational(999999999, 1000)), date_time_init(2007,9,02,0,0,0).end_of_week #sunday + end + + def test_end_of_month + assert_equal date_time_init(2005,3,31,23,59,59,Rational(999999999, 1000)), date_time_init(2005,3,20,10,10,10).end_of_month + assert_equal date_time_init(2005,2,28,23,59,59,Rational(999999999, 1000)), date_time_init(2005,2,20,10,10,10).end_of_month + assert_equal date_time_init(2005,4,30,23,59,59,Rational(999999999, 1000)), date_time_init(2005,4,20,10,10,10).end_of_month + end + + def test_end_of_year + assert_equal date_time_init(2007,12,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,2,22,10,10,10).end_of_year + assert_equal date_time_init(2007,12,31,23,59,59,Rational(999999999, 1000)), date_time_init(2007,12,31,10,10,10).end_of_year + end + + def test_monday_with_default_beginning_of_week_set + with_bw_default(:saturday) do + assert_equal date_time_init(2012,9,17,0,0,0), date_time_init(2012,9,18,0,0,0).monday + end + end + + def test_sunday_with_default_beginning_of_week_set + with_bw_default(:wednesday) do + assert_equal date_time_init(2012,9,23,23,59,59, Rational(999999999, 1000)), date_time_init(2012,9,19,0,0,0).sunday + end + end + + def with_bw_default(bw = :monday) + old_bw = Date.beginning_of_week + Date.beginning_of_week = bw + yield + ensure + Date.beginning_of_week = old_bw + end +end diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index 6e91fdedce..7ae1f67785 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -1,7 +1,22 @@ require 'abstract_unit' require 'active_support/time' +require 'core_ext/date_and_time_behavior' class DateExtCalculationsTest < ActiveSupport::TestCase + def date_time_init(year,month,day,*args) + Date.new(year,month,day) + end + + include DateAndTimeBehavior + + def test_yesterday_in_calendar_reform + assert_equal Date.new(1582,10,4), Date.new(1582,10,15).yesterday + end + + def test_tomorrow_in_calendar_reform + assert_equal Date.new(1582,10,15), Date.new(1582,10,4).tomorrow + end + def test_to_s date = Date.new(2005, 2, 21) assert_equal "2005-02-21", date.to_s @@ -46,22 +61,6 @@ class DateExtCalculationsTest < ActiveSupport::TestCase assert_equal Date.new(2005,6,22), Date.new(2005,2,22).change(:month => 6) end - def test_beginning_of_week - assert_equal Date.new(2005,1,31), Date.new(2005,2,4).beginning_of_week - assert_equal Date.new(2005,11,28), Date.new(2005,11,28).beginning_of_week #monday - assert_equal Date.new(2005,11,28), Date.new(2005,11,29).beginning_of_week #tuesday - assert_equal Date.new(2005,11,28), Date.new(2005,11,30).beginning_of_week #wednesday - assert_equal Date.new(2005,11,28), Date.new(2005,12,01).beginning_of_week #thursday - assert_equal Date.new(2005,11,28), Date.new(2005,12,02).beginning_of_week #friday - assert_equal Date.new(2005,11,28), Date.new(2005,12,03).beginning_of_week #saturday - assert_equal Date.new(2005,11,28), Date.new(2005,12,04).beginning_of_week #sunday - end - - def test_monday - assert_equal Date.new(2005,11,28), Date.new(2005,11,28).monday - assert_equal Date.new(2005,11,28), Date.new(2005,12,01).monday - end - def test_sunday assert_equal Date.new(2008,3,2), Date.new(2008,3,02).sunday assert_equal Date.new(2008,3,2), Date.new(2008,2,29).sunday @@ -71,41 +70,10 @@ class DateExtCalculationsTest < ActiveSupport::TestCase assert_equal Date.new(1582,10,1), Date.new(1582,10,15).beginning_of_week #friday end - def test_beginning_of_month - assert_equal Date.new(2005,2,1), Date.new(2005,2,22).beginning_of_month - end - - def test_beginning_of_quarter - assert_equal Date.new(2005,1,1), Date.new(2005,2,15).beginning_of_quarter - assert_equal Date.new(2005,1,1), Date.new(2005,1,1).beginning_of_quarter - assert_equal Date.new(2005,10,1), Date.new(2005,12,31).beginning_of_quarter - assert_equal Date.new(2005,4,1), Date.new(2005,6,30).beginning_of_quarter - end - - def test_end_of_week - assert_equal Date.new(2008,2,24), Date.new(2008,2,22).end_of_week - assert_equal Date.new(2008,3,2), Date.new(2008,2,25).end_of_week #monday - assert_equal Date.new(2008,3,2), Date.new(2008,2,26).end_of_week #tuesday - assert_equal Date.new(2008,3,2), Date.new(2008,2,27).end_of_week #wednesday - assert_equal Date.new(2008,3,2), Date.new(2008,2,28).end_of_week #thursday - assert_equal Date.new(2008,3,2), Date.new(2008,2,29).end_of_week #friday - assert_equal Date.new(2008,3,2), Date.new(2008,3,01).end_of_week #saturday - assert_equal Date.new(2008,3,2), Date.new(2008,3,02).end_of_week #sunday - end - def test_end_of_week_in_calendar_reform assert_equal Date.new(1582,10,17), Date.new(1582,10,4).end_of_week #thursday end - def test_end_of_quarter - assert_equal Date.new(2008,3,31), Date.new(2008,2,15).end_of_quarter - assert_equal Date.new(2008,3,31), Date.new(2008,3,31).end_of_quarter - assert_equal Date.new(2008,12,31), Date.new(2008,10,8).end_of_quarter - assert_equal Date.new(2008,6,30), Date.new(2008,4,14).end_of_quarter - assert_equal Date.new(2008,6,30), Date.new(2008,5,31).end_of_quarter - assert_equal Date.new(2008,9,30), Date.new(2008,8,21).end_of_quarter - end - def test_end_of_year assert_equal Date.new(2008,12,31).to_s, Date.new(2008,2,22).end_of_year.to_s end @@ -116,57 +84,6 @@ class DateExtCalculationsTest < ActiveSupport::TestCase assert_equal Date.new(2005,4,30), Date.new(2005,4,20).end_of_month end - def test_beginning_of_year - assert_equal Date.new(2005,1,1).to_s, Date.new(2005,2,22).beginning_of_year.to_s - end - - def test_weeks_ago - assert_equal Date.new(2005,5,10), Date.new(2005,5,17).weeks_ago(1) - assert_equal Date.new(2005,5,10), Date.new(2005,5,24).weeks_ago(2) - assert_equal Date.new(2005,5,10), Date.new(2005,5,31).weeks_ago(3) - assert_equal Date.new(2005,5,10), Date.new(2005,6,7).weeks_ago(4) - assert_equal Date.new(2006,12,31), Date.new(2007,2,4).weeks_ago(5) - end - - def test_months_ago - assert_equal Date.new(2005,5,5), Date.new(2005,6,5).months_ago(1) - assert_equal Date.new(2004,11,5), Date.new(2005,6,5).months_ago(7) - assert_equal Date.new(2004,12,5), Date.new(2005,6,5).months_ago(6) - assert_equal Date.new(2004,6,5), Date.new(2005,6,5).months_ago(12) - assert_equal Date.new(2003,6,5), Date.new(2005,6,5).months_ago(24) - end - - def test_months_since - assert_equal Date.new(2005,7,5), Date.new(2005,6,5).months_since(1) - assert_equal Date.new(2006,1,5), Date.new(2005,12,5).months_since(1) - assert_equal Date.new(2005,12,5), Date.new(2005,6,5).months_since(6) - assert_equal Date.new(2006,6,5), Date.new(2005,12,5).months_since(6) - assert_equal Date.new(2006,1,5), Date.new(2005,6,5).months_since(7) - assert_equal Date.new(2006,6,5), Date.new(2005,6,5).months_since(12) - assert_equal Date.new(2007,6,5), Date.new(2005,6,5).months_since(24) - assert_equal Date.new(2005,4,30), Date.new(2005,3,31).months_since(1) - assert_equal Date.new(2005,2,28), Date.new(2005,1,29).months_since(1) - assert_equal Date.new(2005,2,28), Date.new(2005,1,30).months_since(1) - assert_equal Date.new(2005,2,28), Date.new(2005,1,31).months_since(1) - end - - def test_years_ago - assert_equal Date.new(2004,6,5), Date.new(2005,6,5).years_ago(1) - assert_equal Date.new(1998,6,5), Date.new(2005,6,5).years_ago(7) - assert_equal Date.new(2003,2,28), Date.new(2004,2,29).years_ago(1) # 1 year ago from leap day - end - - def test_years_since - assert_equal Date.new(2006,6,5), Date.new(2005,6,5).years_since(1) - assert_equal Date.new(2012,6,5), Date.new(2005,6,5).years_since(7) - assert_equal Date.new(2182,6,5), Date.new(2005,6,5).years_since(177) - assert_equal Date.new(2005,2,28), Date.new(2004,2,29).years_since(1) # 1 year since leap day - end - - def test_prev_year - assert_equal Date.new(2004,6,5), Date.new(2005,6,5).prev_year - end - def test_prev_year_in_leap_years assert_equal Date.new(1999,2,28), Date.new(2000,2,29).prev_year end @@ -175,34 +92,24 @@ class DateExtCalculationsTest < ActiveSupport::TestCase assert_equal Date.new(1582,10,4), Date.new(1583,10,14).prev_year end - def test_next_year - assert_equal Date.new(2006,6,5), Date.new(2005,6,5).next_year + def test_last_year + assert_equal Date.new(2004,6,5), Date.new(2005,6,5).last_year end - def test_next_year_in_leap_years - assert_equal Date.new(2001,2,28), Date.new(2000,2,29).next_year + def test_last_year_in_leap_years + assert_equal Date.new(1999,2,28), Date.new(2000,2,29).last_year end - def test_next_year_in_calendar_reform - assert_equal Date.new(1582,10,4), Date.new(1581,10,10).next_year + def test_last_year_in_calendar_reform + assert_equal Date.new(1582,10,4), Date.new(1583,10,14).last_year end - def test_yesterday - assert_equal Date.new(2005,2,21), Date.new(2005,2,22).yesterday - assert_equal Date.new(2005,2,28), Date.new(2005,3,2).yesterday.yesterday - end - - def test_yesterday_in_calendar_reform - assert_equal Date.new(1582,10,4), Date.new(1582,10,15).yesterday - end - - def test_tomorrow - assert_equal Date.new(2005,2,23), Date.new(2005,2,22).tomorrow - assert_equal Date.new(2005,3,2), Date.new(2005,2,28).tomorrow.tomorrow + def test_next_year_in_leap_years + assert_equal Date.new(2001,2,28), Date.new(2000,2,29).next_year end - def test_tomorrow_in_calendar_reform - assert_equal Date.new(1582,10,15), Date.new(1582,10,4).tomorrow + def test_next_year_in_calendar_reform + assert_equal Date.new(1582,10,4), Date.new(1581,10,10).next_year end def test_advance @@ -237,19 +144,12 @@ class DateExtCalculationsTest < ActiveSupport::TestCase end end - def test_prev_week - assert_equal Date.new(2005,5,9), Date.new(2005,5,17).prev_week - assert_equal Date.new(2006,12,25), Date.new(2007,1,7).prev_week - assert_equal Date.new(2010,2,12), Date.new(2010,2,19).prev_week(:friday) - assert_equal Date.new(2010,2,13), Date.new(2010,2,19).prev_week(:saturday) - assert_equal Date.new(2010,2,27), Date.new(2010,3,4).prev_week(:saturday) - end - - def test_next_week - assert_equal Date.new(2005,2,28), Date.new(2005,2,22).next_week - assert_equal Date.new(2005,3,4), Date.new(2005,2,22).next_week(:friday) - assert_equal Date.new(2006,10,30), Date.new(2006,10,23).next_week - assert_equal Date.new(2006,11,1), Date.new(2006,10,23).next_week(:wednesday) + def test_last_week + assert_equal Date.new(2005,5,9), Date.new(2005,5,17).last_week + assert_equal Date.new(2006,12,25), Date.new(2007,1,7).last_week + assert_equal Date.new(2010,2,12), Date.new(2010,2,19).last_week(:friday) + assert_equal Date.new(2010,2,13), Date.new(2010,2,19).last_week(:saturday) + assert_equal Date.new(2010,2,27), Date.new(2010,3,4).last_week(:saturday) end def test_next_week_in_calendar_reform @@ -257,12 +157,12 @@ class DateExtCalculationsTest < ActiveSupport::TestCase assert_equal Date.new(1582,10,18), Date.new(1582,10,4).next_week end - def test_next_month_on_31st - assert_equal Date.new(2005, 9, 30), Date.new(2005, 8, 31).next_month + def test_last_month_on_31st + assert_equal Date.new(2004, 2, 29), Date.new(2004, 3, 31).last_month end - def test_prev_month_on_31st - assert_equal Date.new(2004, 2, 29), Date.new(2004, 3, 31).prev_month + def test_last_quarter_on_31st + assert_equal Date.new(2004, 2, 29), Date.new(2004, 5, 31).last_quarter end def test_yesterday_constructor @@ -350,14 +250,14 @@ class DateExtCalculationsTest < ActiveSupport::TestCase end def test_end_of_day - assert_equal Time.local(2005,2,21,23,59,59,999999.999), Date.new(2005,2,21).end_of_day + assert_equal Time.local(2005,2,21,23,59,59,Rational(999999999, 1000)), Date.new(2005,2,21).end_of_day end def test_end_of_day_when_zone_is_set zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] with_env_tz 'UTC' do with_tz_default zone do - assert_equal zone.local(2005,2,21,23,59,59,999999.999), Date.new(2005,2,21).end_of_day + assert_equal zone.local(2005,2,21,23,59,59,Rational(999999999, 1000)), Date.new(2005,2,21).end_of_day assert_equal zone, Date.new(2005,2,21).end_of_day.time_zone end end @@ -384,13 +284,6 @@ class DateExtCalculationsTest < ActiveSupport::TestCase end end - def test_today - Date.stubs(:current).returns(Date.new(2000, 1, 1)) - assert_equal false, Date.new(1999, 12, 31).today? - assert_equal true, Date.new(2000,1,1).today? - assert_equal false, Date.new(2000,1,2).today? - end - def test_past Date.stubs(:current).returns(Date.new(2000, 1, 1)) assert_equal true, Date.new(1999, 12, 31).past? diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb index 57b5b95a66..b1d1e8ecb4 100644 --- a/activesupport/test/core_ext/date_time_ext_test.rb +++ b/activesupport/test/core_ext/date_time_ext_test.rb @@ -1,7 +1,14 @@ require 'abstract_unit' require 'active_support/time' +require 'core_ext/date_and_time_behavior' class DateTimeExtCalculationsTest < ActiveSupport::TestCase + def date_time_init(year,month,day,hour,minute,second,*args) + DateTime.civil(year,month,day,hour,minute,second) + end + + include DateAndTimeBehavior + def test_to_s datetime = DateTime.new(2005, 2, 21, 14, 30, 0, 0) assert_equal "2005-02-21 14:30:00", datetime.to_s(:db) @@ -54,35 +61,6 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase assert_equal 86399,DateTime.civil(2005,1,1,23,59,59).seconds_since_midnight end - def test_days_to_week_start - assert_equal 0, Time.local(2011,11,01,0,0,0).days_to_week_start(:tuesday) - assert_equal 1, Time.local(2011,11,02,0,0,0).days_to_week_start(:tuesday) - assert_equal 2, Time.local(2011,11,03,0,0,0).days_to_week_start(:tuesday) - assert_equal 3, Time.local(2011,11,04,0,0,0).days_to_week_start(:tuesday) - assert_equal 4, Time.local(2011,11,05,0,0,0).days_to_week_start(:tuesday) - assert_equal 5, Time.local(2011,11,06,0,0,0).days_to_week_start(:tuesday) - assert_equal 6, Time.local(2011,11,07,0,0,0).days_to_week_start(:tuesday) - - assert_equal 3, Time.local(2011,11,03,0,0,0).days_to_week_start(:monday) - assert_equal 3, Time.local(2011,11,04,0,0,0).days_to_week_start(:tuesday) - assert_equal 3, Time.local(2011,11,05,0,0,0).days_to_week_start(:wednesday) - assert_equal 3, Time.local(2011,11,06,0,0,0).days_to_week_start(:thursday) - assert_equal 3, Time.local(2011,11,07,0,0,0).days_to_week_start(:friday) - assert_equal 3, Time.local(2011,11,8,0,0,0).days_to_week_start(:saturday) - assert_equal 3, Time.local(2011,11,9,0,0,0).days_to_week_start(:sunday) - end - - def test_beginning_of_week - assert_equal DateTime.civil(2005,1,31), DateTime.civil(2005,2,4,10,10,10).beginning_of_week - assert_equal DateTime.civil(2005,11,28), DateTime.civil(2005,11,28,0,0,0).beginning_of_week #monday - assert_equal DateTime.civil(2005,11,28), DateTime.civil(2005,11,29,0,0,0).beginning_of_week #tuesday - assert_equal DateTime.civil(2005,11,28), DateTime.civil(2005,11,30,0,0,0).beginning_of_week #wednesday - assert_equal DateTime.civil(2005,11,28), DateTime.civil(2005,12,01,0,0,0).beginning_of_week #thursday - assert_equal DateTime.civil(2005,11,28), DateTime.civil(2005,12,02,0,0,0).beginning_of_week #friday - assert_equal DateTime.civil(2005,11,28), DateTime.civil(2005,12,03,0,0,0).beginning_of_week #saturday - assert_equal DateTime.civil(2005,11,28), DateTime.civil(2005,12,04,0,0,0).beginning_of_week #sunday - end - def test_beginning_of_day assert_equal DateTime.civil(2005,2,4,0,0,0), DateTime.civil(2005,2,4,10,10,10).beginning_of_day end @@ -91,15 +69,12 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase assert_equal DateTime.civil(2005,2,4,23,59,59), DateTime.civil(2005,2,4,10,10,10).end_of_day end - def test_beginning_of_month - assert_equal DateTime.civil(2005,2,1,0,0,0), DateTime.civil(2005,2,22,10,10,10).beginning_of_month + def test_beginning_of_hour + assert_equal DateTime.civil(2005,2,4,19,0,0), DateTime.civil(2005,2,4,19,30,10).beginning_of_hour end - def test_beginning_of_quarter - assert_equal DateTime.civil(2005,1,1,0,0,0), DateTime.civil(2005,2,15,10,10,10).beginning_of_quarter - assert_equal DateTime.civil(2005,1,1,0,0,0), DateTime.civil(2005,1,1,0,0,0).beginning_of_quarter - assert_equal DateTime.civil(2005,10,1,0,0,0), DateTime.civil(2005,12,31,10,10,10).beginning_of_quarter - assert_equal DateTime.civil(2005,4,1,0,0,0), DateTime.civil(2005,6,30,23,59,59).beginning_of_quarter + def test_end_of_hour + assert_equal DateTime.civil(2005,2,4,19,59,59), DateTime.civil(2005,2,4,19,30,10).end_of_hour end def test_end_of_month @@ -108,59 +83,8 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase assert_equal DateTime.civil(2005,4,30,23,59,59), DateTime.civil(2005,4,20,10,10,10).end_of_month end - def test_beginning_of_year - assert_equal DateTime.civil(2005,1,1,0,0,0), DateTime.civil(2005,2,22,10,10,10).beginning_of_year - end - - def test_weeks_ago - assert_equal DateTime.civil(2005,5,29,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(1) - assert_equal DateTime.civil(2005,5,1,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(5) - assert_equal DateTime.civil(2005,4,24,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(6) - assert_equal DateTime.civil(2005,2,27,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(14) - assert_equal DateTime.civil(2004,12,25,10), DateTime.civil(2005,1,1,10,0,0).weeks_ago(1) - end - - def test_months_ago - assert_equal DateTime.civil(2005,5,5,10), DateTime.civil(2005,6,5,10,0,0).months_ago(1) - assert_equal DateTime.civil(2004,11,5,10), DateTime.civil(2005,6,5,10,0,0).months_ago(7) - assert_equal DateTime.civil(2004,12,5,10), DateTime.civil(2005,6,5,10,0,0).months_ago(6) - assert_equal DateTime.civil(2004,6,5,10), DateTime.civil(2005,6,5,10,0,0).months_ago(12) - assert_equal DateTime.civil(2003,6,5,10), DateTime.civil(2005,6,5,10,0,0).months_ago(24) - end - - def test_months_since - assert_equal DateTime.civil(2005,7,5,10), DateTime.civil(2005,6,5,10,0,0).months_since(1) - assert_equal DateTime.civil(2006,1,5,10), DateTime.civil(2005,12,5,10,0,0).months_since(1) - assert_equal DateTime.civil(2005,12,5,10), DateTime.civil(2005,6,5,10,0,0).months_since(6) - assert_equal DateTime.civil(2006,6,5,10), DateTime.civil(2005,12,5,10,0,0).months_since(6) - assert_equal DateTime.civil(2006,1,5,10), DateTime.civil(2005,6,5,10,0,0).months_since(7) - assert_equal DateTime.civil(2006,6,5,10), DateTime.civil(2005,6,5,10,0,0).months_since(12) - assert_equal DateTime.civil(2007,6,5,10), DateTime.civil(2005,6,5,10,0,0).months_since(24) - assert_equal DateTime.civil(2005,4,30,10), DateTime.civil(2005,3,31,10,0,0).months_since(1) - assert_equal DateTime.civil(2005,2,28,10), DateTime.civil(2005,1,29,10,0,0).months_since(1) - assert_equal DateTime.civil(2005,2,28,10), DateTime.civil(2005,1,30,10,0,0).months_since(1) - assert_equal DateTime.civil(2005,2,28,10), DateTime.civil(2005,1,31,10,0,0).months_since(1) - end - - def test_years_ago - assert_equal DateTime.civil(2004,6,5,10), DateTime.civil(2005,6,5,10,0,0).years_ago(1) - assert_equal DateTime.civil(1998,6,5,10), DateTime.civil(2005,6,5,10,0,0).years_ago(7) - assert_equal DateTime.civil(2003,2,28,10), DateTime.civil(2004,2,29,10,0,0).years_ago(1) # 1 year ago from leap day - end - - def test_years_since - assert_equal DateTime.civil(2006,6,5,10), DateTime.civil(2005,6,5,10,0,0).years_since(1) - assert_equal DateTime.civil(2012,6,5,10), DateTime.civil(2005,6,5,10,0,0).years_since(7) - assert_equal DateTime.civil(2182,6,5,10), DateTime.civil(2005,6,5,10,0,0).years_since(177) - assert_equal DateTime.civil(2005,2,28,10), DateTime.civil(2004,2,29,10,0,0).years_since(1) # 1 year since leap day - end - - def test_prev_year - assert_equal DateTime.civil(2004,6,5,10), DateTime.civil(2005,6,5,10,0,0).prev_year - end - - def test_next_year - assert_equal DateTime.civil(2006,6,5,10), DateTime.civil(2005,6,5,10,0,0).next_year + def test_last_year + assert_equal DateTime.civil(2004,6,5,10), DateTime.civil(2005,6,5,10,0,0).last_year end def test_ago @@ -179,16 +103,6 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase assert_equal DateTime.civil(2005,2,22,10,10,12), DateTime.civil(2005,2,22,10,10,10).since(1.667) end - def test_yesterday - assert_equal DateTime.civil(2005,2,21,10,10,10), DateTime.civil(2005,2,22,10,10,10).yesterday - assert_equal DateTime.civil(2005,2,28,10,10,10), DateTime.civil(2005,3,2,10,10,10).yesterday.yesterday - end - - def test_tomorrow - assert_equal DateTime.civil(2005,2,23,10,10,10), DateTime.civil(2005,2,22,10,10,10).tomorrow - assert_equal DateTime.civil(2005,3,2,10,10,10), DateTime.civil(2005,2,28,10,10,10).tomorrow.tomorrow - end - def test_change assert_equal DateTime.civil(2006,2,22,15,15,10), DateTime.civil(2005,2,22,15,15,10).change(:year => 2006) assert_equal DateTime.civil(2005,6,22,15,15,10), DateTime.civil(2005,2,22,15,15,10).change(:month => 6) @@ -224,27 +138,20 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase assert_equal DateTime.civil(2010, 3, 29), DateTime.civil(2010, 2, 28, 22, 58, 59).advance(:months => 1, :hours => 1, :minutes => 1, :seconds => 1) end - def test_prev_week - assert_equal DateTime.civil(2005,2,21), DateTime.civil(2005,3,1,15,15,10).prev_week - assert_equal DateTime.civil(2005,2,22), DateTime.civil(2005,3,1,15,15,10).prev_week(:tuesday) - assert_equal DateTime.civil(2005,2,25), DateTime.civil(2005,3,1,15,15,10).prev_week(:friday) - assert_equal DateTime.civil(2006,10,30), DateTime.civil(2006,11,6,0,0,0).prev_week - assert_equal DateTime.civil(2006,11,15), DateTime.civil(2006,11,23,0,0,0).prev_week(:wednesday) - end - - def test_next_week - assert_equal DateTime.civil(2005,2,28), DateTime.civil(2005,2,22,15,15,10).next_week - assert_equal DateTime.civil(2005,3,4), DateTime.civil(2005,2,22,15,15,10).next_week(:friday) - assert_equal DateTime.civil(2006,10,30), DateTime.civil(2006,10,23,0,0,0).next_week - assert_equal DateTime.civil(2006,11,1), DateTime.civil(2006,10,23,0,0,0).next_week(:wednesday) + def test_last_week + assert_equal DateTime.civil(2005,2,21), DateTime.civil(2005,3,1,15,15,10).last_week + assert_equal DateTime.civil(2005,2,22), DateTime.civil(2005,3,1,15,15,10).last_week(:tuesday) + assert_equal DateTime.civil(2005,2,25), DateTime.civil(2005,3,1,15,15,10).last_week(:friday) + assert_equal DateTime.civil(2006,10,30), DateTime.civil(2006,11,6,0,0,0).last_week + assert_equal DateTime.civil(2006,11,15), DateTime.civil(2006,11,23,0,0,0).last_week(:wednesday) end - def test_next_month_on_31st - assert_equal DateTime.civil(2005, 9, 30), DateTime.civil(2005, 8, 31).next_month + def test_last_month_on_31st + assert_equal DateTime.civil(2004, 2, 29), DateTime.civil(2004, 3, 31).last_month end - def test_prev_month_on_31st - assert_equal DateTime.civil(2004, 2, 29), DateTime.civil(2004, 3, 31).prev_month + def test_last_quarter_on_31st + assert_equal DateTime.civil(2004, 2, 29), DateTime.civil(2004, 5, 31).last_quarter end def test_xmlschema @@ -391,6 +298,7 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase def test_to_i assert_equal 946684800, DateTime.civil(2000).to_i + assert_equal 946684800, DateTime.civil(1999,12,31,19,0,0,Rational(-5,24)).to_i end protected diff --git a/activesupport/test/core_ext/deep_dup_test.rb b/activesupport/test/core_ext/deep_dup_test.rb new file mode 100644 index 0000000000..91d558dbb5 --- /dev/null +++ b/activesupport/test/core_ext/deep_dup_test.rb @@ -0,0 +1,53 @@ +require 'abstract_unit' +require 'active_support/core_ext/object' + +class DeepDupTest < ActiveSupport::TestCase + + def test_array_deep_dup + array = [1, [2, 3]] + dup = array.deep_dup + dup[1][2] = 4 + assert_equal nil, array[1][2] + assert_equal 4, dup[1][2] + end + + def test_hash_deep_dup + hash = { :a => { :b => 'b' } } + dup = hash.deep_dup + dup[:a][:c] = 'c' + assert_equal nil, hash[:a][:c] + assert_equal 'c', dup[:a][:c] + end + + def test_array_deep_dup_with_hash_inside + array = [1, { :a => 2, :b => 3 } ] + dup = array.deep_dup + dup[1][:c] = 4 + assert_equal nil, array[1][:c] + assert_equal 4, dup[1][:c] + end + + def test_hash_deep_dup_with_array_inside + hash = { :a => [1, 2] } + dup = hash.deep_dup + dup[:a][2] = 'c' + assert_equal nil, hash[:a][2] + assert_equal 'c', dup[:a][2] + end + + def test_deep_dup_initialize + zero_hash = Hash.new 0 + hash = { :a => zero_hash } + dup = hash.deep_dup + assert_equal 0, dup[:a][44] + end + + def test_object_deep_dup + object = Object.new + dup = object.deep_dup + dup.instance_variable_set(:@a, 1) + assert !object.instance_variable_defined?(:@a) + assert dup.instance_variable_defined?(:@a) + end + +end diff --git a/activesupport/test/core_ext/duplicable_test.rb b/activesupport/test/core_ext/duplicable_test.rb index 3e54266051..e0566e012c 100644 --- a/activesupport/test/core_ext/duplicable_test.rb +++ b/activesupport/test/core_ext/duplicable_test.rb @@ -4,9 +4,17 @@ require 'active_support/core_ext/object/duplicable' require 'active_support/core_ext/numeric/time' class DuplicableTest < ActiveSupport::TestCase - RAISE_DUP = [nil, false, true, :symbol, 1, 2.3, BigDecimal.new('4.56'), 5.seconds] - YES = ['1', Object.new, /foo/, [], {}, Time.now] - NO = [Class.new, Module.new] + RAISE_DUP = [nil, false, true, :symbol, 1, 2.3, 5.seconds] + YES = ['1', Object.new, /foo/, [], {}, Time.now, Class.new, Module.new] + NO = [] + + begin + bd = BigDecimal.new('4.56') + YES << bd.dup + rescue TypeError + RAISE_DUP << bd + end + def test_duplicable (RAISE_DUP + NO).each do |v| @@ -14,7 +22,7 @@ class DuplicableTest < ActiveSupport::TestCase end YES.each do |v| - assert v.duplicable? + assert v.duplicable?, "#{v.class} should be duplicable" end (YES + NO).each do |v| diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb index 0bf48dd378..0a1abac767 100644 --- a/activesupport/test/core_ext/enumerable_test.rb +++ b/activesupport/test/core_ext/enumerable_test.rb @@ -84,6 +84,11 @@ class EnumerableTests < ActiveSupport::TestCase assert_equal 10, (1..4.5).sum assert_equal 6, (1...4).sum assert_equal 'abc', ('a'..'c').sum + assert_equal 50_000_005_000_000, (0..10_000_000).sum + assert_equal 0, (10..0).sum + assert_equal 5, (10..0).sum(5) + assert_equal 10, (10..10).sum + assert_equal 42, (10...10).sum(42) end def test_index_by diff --git a/activesupport/test/core_ext/file_test.rb b/activesupport/test/core_ext/file_test.rb index 50c9c57aa6..2c04e9687c 100644 --- a/activesupport/test/core_ext/file_test.rb +++ b/activesupport/test/core_ext/file_test.rb @@ -30,7 +30,7 @@ class AtomicWriteTest < ActiveSupport::TestCase assert File.exist?(file_name) end assert File.exist?(file_name) - assert_equal 0100755, file_mode + assert_equal 0100755 & ~File.umask, file_mode assert_equal contents, File.read(file_name) File.atomic_write(file_name, Dir.pwd) do |file| @@ -38,7 +38,7 @@ class AtomicWriteTest < ActiveSupport::TestCase assert File.exist?(file_name) end assert File.exist?(file_name) - assert_equal 0100755, file_mode + assert_equal 0100755 & ~File.umask, file_mode assert_equal contents, File.read(file_name) ensure File.unlink(file_name) rescue nil @@ -51,7 +51,7 @@ class AtomicWriteTest < ActiveSupport::TestCase assert !File.exist?(file_name) end assert File.exist?(file_name) - assert_equal 0100666 ^ File.umask, file_mode + assert_equal File.probe_stat_in(Dir.pwd).mode, file_mode assert_equal contents, File.read(file_name) ensure File.unlink(file_name) rescue nil diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index a0f261ebdb..01934dd2c3 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -4,6 +4,7 @@ require 'bigdecimal' require 'active_support/core_ext/string/access' require 'active_support/ordered_hash' require 'active_support/core_ext/object/conversions' +require 'active_support/core_ext/object/deep_dup' require 'active_support/inflections' class HashExtTest < ActiveSupport::TestCase @@ -24,56 +25,207 @@ class HashExtTest < ActiveSupport::TestCase def setup @strings = { 'a' => 1, 'b' => 2 } + @nested_strings = { 'a' => { 'b' => { 'c' => 3 } } } @symbols = { :a => 1, :b => 2 } + @nested_symbols = { :a => { :b => { :c => 3 } } } @mixed = { :a => 1, 'b' => 2 } + @nested_mixed = { 'a' => { :b => { 'c' => 3 } } } @fixnums = { 0 => 1, 1 => 2 } + @nested_fixnums = { 0 => { 1 => { 2 => 3} } } @illegal_symbols = { [] => 3 } + @nested_illegal_symbols = { [] => { [] => 3} } + @upcase_strings = { 'A' => 1, 'B' => 2 } + @nested_upcase_strings = { 'A' => { 'B' => { 'C' => 3 } } } end def test_methods h = {} + assert_respond_to h, :transform_keys + assert_respond_to h, :transform_keys! + assert_respond_to h, :deep_transform_keys + assert_respond_to h, :deep_transform_keys! assert_respond_to h, :symbolize_keys assert_respond_to h, :symbolize_keys! + assert_respond_to h, :deep_symbolize_keys + assert_respond_to h, :deep_symbolize_keys! assert_respond_to h, :stringify_keys assert_respond_to h, :stringify_keys! + assert_respond_to h, :deep_stringify_keys + assert_respond_to h, :deep_stringify_keys! assert_respond_to h, :to_options assert_respond_to h, :to_options! end + def test_transform_keys + assert_equal @upcase_strings, @strings.transform_keys{ |key| key.to_s.upcase } + assert_equal @upcase_strings, @symbols.transform_keys{ |key| key.to_s.upcase } + assert_equal @upcase_strings, @mixed.transform_keys{ |key| key.to_s.upcase } + end + + def test_transform_keys_not_mutates + transformed_hash = @mixed.dup + transformed_hash.transform_keys{ |key| key.to_s.upcase } + assert_equal @mixed, transformed_hash + end + + def test_deep_transform_keys + assert_equal @nested_upcase_strings, @nested_symbols.deep_transform_keys{ |key| key.to_s.upcase } + assert_equal @nested_upcase_strings, @nested_strings.deep_transform_keys{ |key| key.to_s.upcase } + assert_equal @nested_upcase_strings, @nested_mixed.deep_transform_keys{ |key| key.to_s.upcase } + end + + def test_deep_transform_keys_not_mutates + transformed_hash = @nested_mixed.deep_dup + transformed_hash.deep_transform_keys{ |key| key.to_s.upcase } + assert_equal @nested_mixed, transformed_hash + end + + def test_transform_keys! + assert_equal @upcase_strings, @symbols.dup.transform_keys!{ |key| key.to_s.upcase } + assert_equal @upcase_strings, @strings.dup.transform_keys!{ |key| key.to_s.upcase } + assert_equal @upcase_strings, @mixed.dup.transform_keys!{ |key| key.to_s.upcase } + end + + def test_transform_keys_with_bang_mutates + transformed_hash = @mixed.dup + transformed_hash.transform_keys!{ |key| key.to_s.upcase } + assert_equal @upcase_strings, transformed_hash + assert_equal @mixed, { :a => 1, "b" => 2 } + end + + def test_deep_transform_keys! + assert_equal @nested_upcase_strings, @nested_symbols.deep_dup.deep_transform_keys!{ |key| key.to_s.upcase } + assert_equal @nested_upcase_strings, @nested_strings.deep_dup.deep_transform_keys!{ |key| key.to_s.upcase } + assert_equal @nested_upcase_strings, @nested_mixed.deep_dup.deep_transform_keys!{ |key| key.to_s.upcase } + end + + def test_deep_transform_keys_with_bang_mutates + transformed_hash = @nested_mixed.deep_dup + transformed_hash.deep_transform_keys!{ |key| key.to_s.upcase } + assert_equal @nested_upcase_strings, transformed_hash + assert_equal @nested_mixed, { 'a' => { :b => { 'c' => 3 } } } + end + def test_symbolize_keys assert_equal @symbols, @symbols.symbolize_keys assert_equal @symbols, @strings.symbolize_keys assert_equal @symbols, @mixed.symbolize_keys end + def test_symbolize_keys_not_mutates + transformed_hash = @mixed.dup + transformed_hash.symbolize_keys + assert_equal @mixed, transformed_hash + end + + def test_deep_symbolize_keys + assert_equal @nested_symbols, @nested_symbols.deep_symbolize_keys + assert_equal @nested_symbols, @nested_strings.deep_symbolize_keys + assert_equal @nested_symbols, @nested_mixed.deep_symbolize_keys + end + + def test_deep_symbolize_keys_not_mutates + transformed_hash = @nested_mixed.deep_dup + transformed_hash.deep_symbolize_keys + assert_equal @nested_mixed, transformed_hash + end + def test_symbolize_keys! assert_equal @symbols, @symbols.dup.symbolize_keys! assert_equal @symbols, @strings.dup.symbolize_keys! assert_equal @symbols, @mixed.dup.symbolize_keys! end + def test_symbolize_keys_with_bang_mutates + transformed_hash = @mixed.dup + transformed_hash.deep_symbolize_keys! + assert_equal @symbols, transformed_hash + assert_equal @mixed, { :a => 1, "b" => 2 } + end + + def test_deep_symbolize_keys! + assert_equal @nested_symbols, @nested_symbols.deep_dup.deep_symbolize_keys! + assert_equal @nested_symbols, @nested_strings.deep_dup.deep_symbolize_keys! + assert_equal @nested_symbols, @nested_mixed.deep_dup.deep_symbolize_keys! + end + + def test_deep_symbolize_keys_with_bang_mutates + transformed_hash = @nested_mixed.deep_dup + transformed_hash.deep_symbolize_keys! + assert_equal @nested_symbols, transformed_hash + assert_equal @nested_mixed, { 'a' => { :b => { 'c' => 3 } } } + end + def test_symbolize_keys_preserves_keys_that_cant_be_symbolized assert_equal @illegal_symbols, @illegal_symbols.symbolize_keys assert_equal @illegal_symbols, @illegal_symbols.dup.symbolize_keys! end + def test_deep_symbolize_keys_preserves_keys_that_cant_be_symbolized + assert_equal @nested_illegal_symbols, @nested_illegal_symbols.deep_symbolize_keys + assert_equal @nested_illegal_symbols, @nested_illegal_symbols.deep_dup.deep_symbolize_keys! + end + def test_symbolize_keys_preserves_fixnum_keys assert_equal @fixnums, @fixnums.symbolize_keys assert_equal @fixnums, @fixnums.dup.symbolize_keys! end + def test_deep_symbolize_keys_preserves_fixnum_keys + assert_equal @nested_fixnums, @nested_fixnums.deep_symbolize_keys + assert_equal @nested_fixnums, @nested_fixnums.deep_dup.deep_symbolize_keys! + end + def test_stringify_keys assert_equal @strings, @symbols.stringify_keys assert_equal @strings, @strings.stringify_keys assert_equal @strings, @mixed.stringify_keys end + def test_stringify_keys_not_mutates + transformed_hash = @mixed.dup + transformed_hash.stringify_keys + assert_equal @mixed, transformed_hash + end + + def test_deep_stringify_keys + assert_equal @nested_strings, @nested_symbols.deep_stringify_keys + assert_equal @nested_strings, @nested_strings.deep_stringify_keys + assert_equal @nested_strings, @nested_mixed.deep_stringify_keys + end + + def test_deep_stringify_keys_not_mutates + transformed_hash = @nested_mixed.deep_dup + transformed_hash.deep_stringify_keys + assert_equal @nested_mixed, transformed_hash + end + def test_stringify_keys! assert_equal @strings, @symbols.dup.stringify_keys! assert_equal @strings, @strings.dup.stringify_keys! assert_equal @strings, @mixed.dup.stringify_keys! end + def test_stringify_keys_with_bang_mutates + transformed_hash = @mixed.dup + transformed_hash.stringify_keys! + assert_equal @strings, transformed_hash + assert_equal @mixed, { :a => 1, "b" => 2 } + end + + def test_deep_stringify_keys! + assert_equal @nested_strings, @nested_symbols.deep_dup.deep_stringify_keys! + assert_equal @nested_strings, @nested_strings.deep_dup.deep_stringify_keys! + assert_equal @nested_strings, @nested_mixed.deep_dup.deep_stringify_keys! + end + + def test_deep_stringify_keys_with_bang_mutates + transformed_hash = @nested_mixed.deep_dup + transformed_hash.deep_stringify_keys! + assert_equal @nested_strings, transformed_hash + assert_equal @nested_mixed, { 'a' => { :b => { 'c' => 3 } } } + end + def test_symbolize_keys_for_hash_with_indifferent_access assert_instance_of Hash, @symbols.with_indifferent_access.symbolize_keys assert_equal @symbols, @symbols.with_indifferent_access.symbolize_keys @@ -81,22 +233,46 @@ class HashExtTest < ActiveSupport::TestCase assert_equal @symbols, @mixed.with_indifferent_access.symbolize_keys end + def test_deep_symbolize_keys_for_hash_with_indifferent_access + assert_instance_of Hash, @nested_symbols.with_indifferent_access.deep_symbolize_keys + assert_equal @nested_symbols, @nested_symbols.with_indifferent_access.deep_symbolize_keys + assert_equal @nested_symbols, @nested_strings.with_indifferent_access.deep_symbolize_keys + assert_equal @nested_symbols, @nested_mixed.with_indifferent_access.deep_symbolize_keys + end + + def test_symbolize_keys_bang_for_hash_with_indifferent_access assert_raise(NoMethodError) { @symbols.with_indifferent_access.dup.symbolize_keys! } assert_raise(NoMethodError) { @strings.with_indifferent_access.dup.symbolize_keys! } assert_raise(NoMethodError) { @mixed.with_indifferent_access.dup.symbolize_keys! } end + def test_deep_symbolize_keys_bang_for_hash_with_indifferent_access + assert_raise(NoMethodError) { @nested_symbols.with_indifferent_access.deep_dup.deep_symbolize_keys! } + assert_raise(NoMethodError) { @nested_strings.with_indifferent_access.deep_dup.deep_symbolize_keys! } + assert_raise(NoMethodError) { @nested_mixed.with_indifferent_access.deep_dup.deep_symbolize_keys! } + end + def test_symbolize_keys_preserves_keys_that_cant_be_symbolized_for_hash_with_indifferent_access assert_equal @illegal_symbols, @illegal_symbols.with_indifferent_access.symbolize_keys assert_raise(NoMethodError) { @illegal_symbols.with_indifferent_access.dup.symbolize_keys! } end + def test_deep_symbolize_keys_preserves_keys_that_cant_be_symbolized_for_hash_with_indifferent_access + assert_equal @nested_illegal_symbols, @nested_illegal_symbols.with_indifferent_access.deep_symbolize_keys + assert_raise(NoMethodError) { @nested_illegal_symbols.with_indifferent_access.deep_dup.deep_symbolize_keys! } + end + def test_symbolize_keys_preserves_fixnum_keys_for_hash_with_indifferent_access assert_equal @fixnums, @fixnums.with_indifferent_access.symbolize_keys assert_raise(NoMethodError) { @fixnums.with_indifferent_access.dup.symbolize_keys! } end + def test_deep_symbolize_keys_preserves_fixnum_keys_for_hash_with_indifferent_access + assert_equal @nested_fixnums, @nested_fixnums.with_indifferent_access.deep_symbolize_keys + assert_raise(NoMethodError) { @nested_fixnums.with_indifferent_access.deep_dup.deep_symbolize_keys! } + end + def test_stringify_keys_for_hash_with_indifferent_access assert_instance_of ActiveSupport::HashWithIndifferentAccess, @symbols.with_indifferent_access.stringify_keys assert_equal @strings, @symbols.with_indifferent_access.stringify_keys @@ -104,6 +280,13 @@ class HashExtTest < ActiveSupport::TestCase assert_equal @strings, @mixed.with_indifferent_access.stringify_keys end + def test_deep_stringify_keys_for_hash_with_indifferent_access + assert_instance_of ActiveSupport::HashWithIndifferentAccess, @nested_symbols.with_indifferent_access.deep_stringify_keys + assert_equal @nested_strings, @nested_symbols.with_indifferent_access.deep_stringify_keys + assert_equal @nested_strings, @nested_strings.with_indifferent_access.deep_stringify_keys + assert_equal @nested_strings, @nested_mixed.with_indifferent_access.deep_stringify_keys + end + def test_stringify_keys_bang_for_hash_with_indifferent_access assert_instance_of ActiveSupport::HashWithIndifferentAccess, @symbols.with_indifferent_access.dup.stringify_keys! assert_equal @strings, @symbols.with_indifferent_access.dup.stringify_keys! @@ -111,6 +294,13 @@ class HashExtTest < ActiveSupport::TestCase assert_equal @strings, @mixed.with_indifferent_access.dup.stringify_keys! end + def test_deep_stringify_keys_bang_for_hash_with_indifferent_access + assert_instance_of ActiveSupport::HashWithIndifferentAccess, @nested_symbols.with_indifferent_access.dup.deep_stringify_keys! + assert_equal @nested_strings, @nested_symbols.with_indifferent_access.deep_dup.deep_stringify_keys! + assert_equal @nested_strings, @nested_strings.with_indifferent_access.deep_dup.deep_stringify_keys! + assert_equal @nested_strings, @nested_mixed.with_indifferent_access.deep_dup.deep_stringify_keys! + end + def test_nested_under_indifferent_access foo = { "foo" => SubclassingHash.new.tap { |h| h["bar"] = "baz" } }.with_indifferent_access assert_kind_of ActiveSupport::HashWithIndifferentAccess, foo["foo"] @@ -238,6 +428,29 @@ class HashExtTest < ActiveSupport::TestCase assert_equal 2, hash['b'] end + def test_indifferent_merging_with_block + hash = HashWithIndifferentAccess.new + hash[:a] = 1 + hash['b'] = 3 + + other = { 'a' => 4, :b => 2, 'c' => 10 } + + merged = hash.merge(other) { |key, old, new| old > new ? old : new } + + assert_equal HashWithIndifferentAccess, merged.class + assert_equal 4, merged[:a] + assert_equal 3, merged['b'] + assert_equal 10, merged[:c] + + other_indifferent = HashWithIndifferentAccess.new('a' => 9, :b => 2) + + merged = hash.merge(other_indifferent) { |key, old, new| old + new } + + assert_equal HashWithIndifferentAccess, merged.class + assert_equal 10, merged[:a] + assert_equal 5, merged[:b] + end + def test_indifferent_reverse_merging hash = HashWithIndifferentAccess.new('some' => 'value', 'other' => 'value') hash.reverse_merge!(:some => 'noclobber', :another => 'clobber') @@ -267,6 +480,13 @@ class HashExtTest < ActiveSupport::TestCase assert_equal '1234', roundtrip.default end + def test_lookup_returns_the_same_object_that_is_stored_in_hash_indifferent_access + hash = HashWithIndifferentAccess.new {|h, k| h[k] = []} + hash[:a] << 1 + + assert_equal [1], hash[:a] + end + def test_indifferent_hash_with_array_of_hashes hash = { "urls" => { "url" => [ { "address" => "1" }, { "address" => "2" } ] }}.with_indifferent_access assert_equal "1", hash[:urls][:url].first[:address] @@ -297,6 +517,17 @@ class HashExtTest < ActiveSupport::TestCase assert_equal 1, h[:first] end + def test_deep_stringify_and_deep_symbolize_keys_on_indifferent_preserves_hash + h = HashWithIndifferentAccess.new + h[:first] = 1 + h = h.deep_stringify_keys + assert_equal 1, h['first'] + h = HashWithIndifferentAccess.new + h['first'] = 1 + h = h.deep_symbolize_keys + assert_equal 1, h[:first] + end + def test_to_options_on_indifferent_preserves_hash h = HashWithIndifferentAccess.new h['first'] = 1 @@ -351,6 +582,16 @@ class HashExtTest < ActiveSupport::TestCase assert_equal expected, hash_1 end + def test_deep_merge_with_block + hash_1 = { :a => "a", :b => "b", :c => { :c1 => "c1", :c2 => "c2", :c3 => { :d1 => "d1" } } } + hash_2 = { :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } } + expected = { :a => [:a, "a", 1], :b => "b", :c => { :c1 => [:c1, "c1", 2], :c2 => "c2", :c3 => { :d1 => "d1", :d2 => "d2" } } } + assert_equal(expected, hash_1.deep_merge(hash_2) { |k,o,n| [k, o, n] }) + + hash_1.deep_merge!(hash_2) { |k,o,n| [k, o, n] } + assert_equal expected, hash_1 + end + def test_deep_merge_on_indifferent_access hash_1 = HashWithIndifferentAccess.new({ :a => "a", :b => "b", :c => { :c1 => "c1", :c2 => "c2", :c3 => { :d1 => "d1" } } }) hash_2 = HashWithIndifferentAccess.new({ :a => 1, :c => { :c1 => 2, :c3 => { :d2 => "d2" } } }) @@ -363,21 +604,6 @@ class HashExtTest < ActiveSupport::TestCase assert_equal expected, hash_1 end - def test_deep_dup - hash = { :a => { :b => 'b' } } - dup = hash.deep_dup - dup[:a][:c] = 'c' - assert_equal nil, hash[:a][:c] - assert_equal 'c', dup[:a][:c] - end - - def test_deep_dup_initialize - zero_hash = Hash.new 0 - hash = { :a => zero_hash } - dup = hash.deep_dup - assert_equal 0, dup[:a][44] - end - def test_store_on_indifferent_access hash = HashWithIndifferentAccess.new hash.store(:test1, 1) @@ -388,6 +614,15 @@ class HashExtTest < ActiveSupport::TestCase assert_equal expected, hash end + def test_constructor_on_indifferent_access + hash = HashWithIndifferentAccess[:foo, 1] + assert_equal 1, hash[:foo] + assert_equal 1, hash['foo'] + hash[:foo] = 3 + assert_equal 3, hash[:foo] + assert_equal 3, hash['foo'] + end + def test_reverse_merge defaults = { :a => "x", :b => "y", :c => 10 }.freeze options = { :a => 1, :b => 2 } @@ -486,19 +721,32 @@ class HashExtTest < ActiveSupport::TestCase assert_equal 'bender', slice['login'] end + def test_extract + original = {:a => 1, :b => 2, :c => 3, :d => 4} + expected = {:a => 1, :b => 2} + + assert_equal expected, original.extract!(:a, :b) + end + def test_except original = { :a => 'x', :b => 'y', :c => 10 } expected = { :a => 'x', :b => 'y' } - # Should return a new hash with only the given keys. + # Should return a new hash without the given keys. assert_equal expected, original.except(:c) assert_not_equal expected, original - # Should replace the hash with only the given keys. + # Should replace the hash without the given keys. assert_equal expected, original.except!(:c) assert_equal expected, original end + def test_except_with_more_than_one_argument + original = { :a => 'x', :b => 'y', :c => 10 } + expected = { :a => 'x' } + assert_equal expected, original.except(:b, :c) + end + def test_except_with_original_frozen original = { :a => 'x', :b => 'y' } original.freeze @@ -550,7 +798,7 @@ class HashExtToParamTests < ActiveSupport::TestCase end def test_to_param_orders_by_key_in_ascending_order - assert_equal 'a=2&b=1&c=0', ActiveSupport::OrderedHash[*%w(b 1 c 0 a 2)].to_param + assert_equal 'a=2&b=1&c=0', Hash[*%w(b 1 c 0 a 2)].to_param end end @@ -610,7 +858,7 @@ class HashToXmlTest < ActiveSupport::TestCase assert_equal "<person>", xml.first(8) assert xml.include?(%(<street>Paulina</street>)) assert xml.include?(%(<name>David</name>)) - assert xml.include?(%(<age nil="true"></age>)) + assert xml.include?(%(<age nil="true"/>)) end def test_one_level_with_skipping_types @@ -618,7 +866,7 @@ class HashToXmlTest < ActiveSupport::TestCase assert_equal "<person>", xml.first(8) assert xml.include?(%(<street>Paulina</street>)) assert xml.include?(%(<name>David</name>)) - assert xml.include?(%(<age nil="true"></age>)) + assert xml.include?(%(<age nil="true"/>)) end def test_one_level_with_yielding @@ -665,8 +913,8 @@ class HashToXmlTest < ActiveSupport::TestCase :created_at => Time.utc(1999,2,2), :local_created_at => Time.utc(1999,2,2).in_time_zone('Eastern Time (US & Canada)') }.to_xml(@xml_options) - assert_match %r{<created-at type=\"datetime\">1999-02-02T00:00:00Z</created-at>}, xml - assert_match %r{<local-created-at type=\"datetime\">1999-02-01T19:00:00-05:00</local-created-at>}, xml + assert_match %r{<created-at type=\"dateTime\">1999-02-02T00:00:00Z</created-at>}, xml + assert_match %r{<local-created-at type=\"dateTime\">1999-02-01T19:00:00-05:00</local-created-at>}, xml end def test_multiple_records_from_xml_with_attributes_other_than_type_ignores_them_without_exploding diff --git a/activesupport/test/core_ext/kernel_test.rb b/activesupport/test/core_ext/kernel_test.rb index e90b9d454f..439bc87323 100644 --- a/activesupport/test/core_ext/kernel_test.rb +++ b/activesupport/test/core_ext/kernel_test.rb @@ -101,10 +101,10 @@ class KernelDebuggerTest < ActiveSupport::TestCase @logger ||= MockStdErr.new end end - Object.const_set("Rails", rails) + Object.const_set(:Rails, rails) debugger assert_match(/Debugger requested/, rails.logger.output.first) ensure - Object.send(:remove_const, "Rails") + Object.send(:remove_const, :Rails) end end diff --git a/activesupport/test/core_ext/module/attribute_accessor_test.rb b/activesupport/test/core_ext/module/attribute_accessor_test.rb index 6a2ad2f241..a577f90bdd 100644 --- a/activesupport/test/core_ext/module/attribute_accessor_test.rb +++ b/activesupport/test/core_ext/module/attribute_accessor_test.rb @@ -44,4 +44,18 @@ class ModuleAttributeAccessorTest < ActiveSupport::TestCase assert !@object.respond_to?(:camp) assert !@object.respond_to?(:camp=) end + + def test_should_raise_name_error_if_attribute_name_is_invalid + assert_raises NameError do + Class.new do + mattr_reader "invalid attribute name" + end + end + + assert_raises NameError do + Class.new do + mattr_writer "invalid attribute name" + end + end + end end diff --git a/activesupport/test/core_ext/module/qualified_const_test.rb b/activesupport/test/core_ext/module/qualified_const_test.rb index 8af0b9a023..343a848a42 100644 --- a/activesupport/test/core_ext/module/qualified_const_test.rb +++ b/activesupport/test/core_ext/module/qualified_const_test.rb @@ -67,17 +67,24 @@ class QualifiedConstTest < ActiveSupport::TestCase end test "qualified_const_set" do - m = Module.new - assert_equal m, Object.qualified_const_set("QualifiedConstTestMod2", m) - assert_equal m, ::QualifiedConstTestMod2 - - # We are going to assign to existing constants on purpose, so silence warnings. - silence_warnings do - assert_equal true, QualifiedConstTestMod.qualified_const_set("QualifiedConstTestMod::X", true) - assert_equal true, QualifiedConstTestMod::X - - assert_equal 10, QualifiedConstTestMod::M.qualified_const_set("X", 10) - assert_equal 10, QualifiedConstTestMod::M::X + begin + m = Module.new + assert_equal m, Object.qualified_const_set("QualifiedConstTestMod2", m) + assert_equal m, ::QualifiedConstTestMod2 + + # We are going to assign to existing constants on purpose, so silence warnings. + silence_warnings do + assert_equal true, QualifiedConstTestMod.qualified_const_set("QualifiedConstTestMod::X", true) + assert_equal true, QualifiedConstTestMod::X + + assert_equal 10, QualifiedConstTestMod::M.qualified_const_set("X", 10) + assert_equal 10, QualifiedConstTestMod::M::X + end + ensure + silence_warnings do + QualifiedConstTestMod.qualified_const_set('QualifiedConstTestMod::X', false) + QualifiedConstTestMod::M.qualified_const_set('X', 1) + end end end diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb index 09ca4e7296..82249ddd1b 100644 --- a/activesupport/test/core_ext/module_test.rb +++ b/activesupport/test/core_ext/module_test.rb @@ -34,6 +34,12 @@ class Someone < Struct.new(:name, :place) delegate :street, :city, :to_f, :to => :place delegate :name=, :to => :place, :prefix => true delegate :upcase, :to => "place.city" + delegate :table_name, :to => :class + delegate :table_name, :to => :class, :prefix => true + + def self.table_name + 'some_table' + end FAILED_DELEGATE_LINE = __LINE__ + 1 delegate :foo, :to => :place @@ -60,6 +66,14 @@ Tester = Struct.new(:client) do delegate :name, :to => :client, :prefix => false end +class ParameterSet + delegate :[], :[]=, :to => :@params + + def initialize + @params = {:foo => "bar"} + end +end + class Name delegate :upcase, :to => :@full_name @@ -83,6 +97,17 @@ class ModuleTest < ActiveSupport::TestCase assert_equal "Fred", @david.place.name end + def test_delegation_to_index_get_method + @params = ParameterSet.new + assert_equal "bar", @params[:foo] + end + + def test_delegation_to_index_set_method + @params = ParameterSet.new + @params[:foo] = "baz" + assert_equal "baz", @params[:foo] + end + def test_delegation_down_hierarchy assert_equal "CHICAGO", @david.upcase end @@ -92,6 +117,11 @@ class ModuleTest < ActiveSupport::TestCase assert_equal "DAVID HANSSON", david.upcase end + def test_delegation_to_class_method + assert_equal 'some_table', @david.table_name + assert_equal 'some_table', @david.class_table_name + end + def test_missing_delegation_target assert_raise(ArgumentError) do Name.send :delegate, :nowhere @@ -215,7 +245,7 @@ class ModuleTest < ActiveSupport::TestCase def test_local_constant_names ActiveSupport::Deprecation.silence do - assert_equal %w(Constant1 Constant3), Ab.local_constant_names + assert_equal %w(Constant1 Constant3), Ab.local_constant_names.sort.map(&:to_s) end end end diff --git a/activesupport/test/core_ext/numeric_ext_test.rb b/activesupport/test/core_ext/numeric_ext_test.rb index 1cb1e25d4c..435f4aa5a1 100644 --- a/activesupport/test/core_ext/numeric_ext_test.rb +++ b/activesupport/test/core_ext/numeric_ext_test.rb @@ -186,3 +186,264 @@ class NumericExtSizeTest < ActiveSupport::TestCase assert_equal 3458764513820540928, 3.exabyte end end + +class NumericExtFormattingTest < ActiveSupport::TestCase + def kilobytes(number) + number * 1024 + end + + def megabytes(number) + kilobytes(number) * 1024 + end + + def gigabytes(number) + megabytes(number) * 1024 + end + + def terabytes(number) + gigabytes(number) * 1024 + end + + def test_to_s__phone + assert_equal("555-1234", 5551234.to_s(:phone)) + assert_equal("800-555-1212", 8005551212.to_s(:phone)) + assert_equal("(800) 555-1212", 8005551212.to_s(:phone, :area_code => true)) + assert_equal("800 555 1212", 8005551212.to_s(:phone, :delimiter => " ")) + assert_equal("(800) 555-1212 x 123", 8005551212.to_s(:phone, :area_code => true, :extension => 123)) + assert_equal("800-555-1212", 8005551212.to_s(:phone, :extension => " ")) + assert_equal("555.1212", 5551212.to_s(:phone, :delimiter => '.')) + assert_equal("+1-800-555-1212", 8005551212.to_s(:phone, :country_code => 1)) + assert_equal("+18005551212", 8005551212.to_s(:phone, :country_code => 1, :delimiter => '')) + assert_equal("22-555-1212", 225551212.to_s(:phone)) + assert_equal("+45-22-555-1212", 225551212.to_s(:phone, :country_code => 45)) + end + + def test_to_s__currency + assert_equal("$1,234,567,890.50", 1234567890.50.to_s(:currency)) + assert_equal("$1,234,567,890.51", 1234567890.506.to_s(:currency)) + assert_equal("-$1,234,567,890.50", -1234567890.50.to_s(:currency)) + assert_equal("-$ 1,234,567,890.50", -1234567890.50.to_s(:currency, :format => "%u %n")) + assert_equal("($1,234,567,890.50)", -1234567890.50.to_s(:currency, :negative_format => "(%u%n)")) + assert_equal("$1,234,567,892", 1234567891.50.to_s(:currency, :precision => 0)) + assert_equal("$1,234,567,890.5", 1234567890.50.to_s(:currency, :precision => 1)) + assert_equal("£1234567890,50", 1234567890.50.to_s(:currency, :unit => "£", :separator => ",", :delimiter => "")) + end + + + def test_to_s__rounded + assert_equal("-111.235", -111.2346.to_s(:rounded)) + assert_equal("111.235", 111.2346.to_s(:rounded)) + assert_equal("31.83", 31.825.to_s(:rounded, :precision => 2)) + assert_equal("111.23", 111.2346.to_s(:rounded, :precision => 2)) + assert_equal("111.00", 111.to_s(:rounded, :precision => 2)) + assert_equal("3268", (32.6751 * 100.00).to_s(:rounded, :precision => 0)) + assert_equal("112", 111.50.to_s(:rounded, :precision => 0)) + assert_equal("1234567892", 1234567891.50.to_s(:rounded, :precision => 0)) + assert_equal("0", 0.to_s(:rounded, :precision => 0)) + assert_equal("0.00100", 0.001.to_s(:rounded, :precision => 5)) + assert_equal("0.001", 0.00111.to_s(:rounded, :precision => 3)) + assert_equal("10.00", 9.995.to_s(:rounded, :precision => 2)) + assert_equal("11.00", 10.995.to_s(:rounded, :precision => 2)) + assert_equal("0.00", -0.001.to_s(:rounded, :precision => 2)) + end + + def test_to_s__percentage + assert_equal("100.000%", 100.to_s(:percentage)) + assert_equal("100%", 100.to_s(:percentage, :precision => 0)) + assert_equal("302.06%", 302.0574.to_s(:percentage, :precision => 2)) + assert_equal("123.4%", 123.400.to_s(:percentage, :precision => 3, :strip_insignificant_zeros => true)) + assert_equal("1.000,000%", 1000.to_s(:percentage, :delimiter => '.', :separator => ',')) + assert_equal("1000.000 %", 1000.to_s(:percentage, :format => "%n %")) + end + + def test_to_s__delimited + assert_equal("12,345,678", 12345678.to_s(:delimited)) + assert_equal("0", 0.to_s(:delimited)) + assert_equal("123", 123.to_s(:delimited)) + assert_equal("123,456", 123456.to_s(:delimited)) + assert_equal("123,456.78", 123456.78.to_s(:delimited)) + assert_equal("123,456.789", 123456.789.to_s(:delimited)) + assert_equal("123,456.78901", 123456.78901.to_s(:delimited)) + assert_equal("123,456,789.78901", 123456789.78901.to_s(:delimited)) + assert_equal("0.78901", 0.78901.to_s(:delimited)) + end + + def test_to_s__delimited__with_options_hash + assert_equal '12 345 678', 12345678.to_s(:delimited, :delimiter => ' ') + assert_equal '12,345,678-05', 12345678.05.to_s(:delimited, :separator => '-') + assert_equal '12.345.678,05', 12345678.05.to_s(:delimited, :separator => ',', :delimiter => '.') + assert_equal '12.345.678,05', 12345678.05.to_s(:delimited, :delimiter => '.', :separator => ',') + end + + + def test_to_s__rounded_with_custom_delimiter_and_separator + assert_equal '31,83', 31.825.to_s(:rounded, :precision => 2, :separator => ',') + assert_equal '1.231,83', 1231.825.to_s(:rounded, :precision => 2, :separator => ',', :delimiter => '.') + end + + def test_to_s__rounded__with_significant_digits + assert_equal "124000", 123987.to_s(:rounded, :precision => 3, :significant => true) + assert_equal "120000000", 123987876.to_s(:rounded, :precision => 2, :significant => true ) + assert_equal "9775", 9775.to_s(:rounded, :precision => 4, :significant => true ) + assert_equal "5.4", 5.3923.to_s(:rounded, :precision => 2, :significant => true ) + assert_equal "5", 5.3923.to_s(:rounded, :precision => 1, :significant => true ) + assert_equal "1", 1.232.to_s(:rounded, :precision => 1, :significant => true ) + assert_equal "7", 7.to_s(:rounded, :precision => 1, :significant => true ) + assert_equal "1", 1.to_s(:rounded, :precision => 1, :significant => true ) + assert_equal "53", 52.7923.to_s(:rounded, :precision => 2, :significant => true ) + assert_equal "9775.00", 9775.to_s(:rounded, :precision => 6, :significant => true ) + assert_equal "5.392900", 5.3929.to_s(:rounded, :precision => 7, :significant => true ) + assert_equal "0.0", 0.to_s(:rounded, :precision => 2, :significant => true ) + assert_equal "0", 0.to_s(:rounded, :precision => 1, :significant => true ) + assert_equal "0.0001", 0.0001.to_s(:rounded, :precision => 1, :significant => true ) + assert_equal "0.000100", 0.0001.to_s(:rounded, :precision => 3, :significant => true ) + assert_equal "0.0001", 0.0001111.to_s(:rounded, :precision => 1, :significant => true ) + assert_equal "10.0", 9.995.to_s(:rounded, :precision => 3, :significant => true) + assert_equal "9.99", 9.994.to_s(:rounded, :precision => 3, :significant => true) + assert_equal "11.0", 10.995.to_s(:rounded, :precision => 3, :significant => true) + end + + def test_to_s__rounded__with_strip_insignificant_zeros + assert_equal "9775.43", 9775.43.to_s(:rounded, :precision => 4, :strip_insignificant_zeros => true ) + assert_equal "9775.2", 9775.2.to_s(:rounded, :precision => 6, :significant => true, :strip_insignificant_zeros => true ) + assert_equal "0", 0.to_s(:rounded, :precision => 6, :significant => true, :strip_insignificant_zeros => true ) + end + + def test_to_s__rounded__with_significant_true_and_zero_precision + # Zero precision with significant is a mistake (would always return zero), + # so we treat it as if significant was false (increases backwards compatibility for number_to_human_size) + assert_equal "124", 123.987.to_s(:rounded, :precision => 0, :significant => true) + assert_equal "12", 12.to_s(:rounded, :precision => 0, :significant => true ) + end + + def test_to_s__human_size + assert_equal '0 Bytes', 0.to_s(:human_size) + assert_equal '1 Byte', 1.to_s(:human_size) + assert_equal '3 Bytes', 3.14159265.to_s(:human_size) + assert_equal '123 Bytes', 123.0.to_s(:human_size) + assert_equal '123 Bytes', 123.to_s(:human_size) + assert_equal '1.21 KB', 1234.to_s(:human_size) + assert_equal '12.1 KB', 12345.to_s(:human_size) + assert_equal '1.18 MB', 1234567.to_s(:human_size) + assert_equal '1.15 GB', 1234567890.to_s(:human_size) + assert_equal '1.12 TB', 1234567890123.to_s(:human_size) + assert_equal '1030 TB', terabytes(1026).to_s(:human_size) + assert_equal '444 KB', kilobytes(444).to_s(:human_size) + assert_equal '1020 MB', megabytes(1023).to_s(:human_size) + assert_equal '3 TB', terabytes(3).to_s(:human_size) + assert_equal '1.2 MB', 1234567.to_s(:human_size, :precision => 2) + assert_equal '3 Bytes', 3.14159265.to_s(:human_size, :precision => 4) + assert_equal '1 KB', kilobytes(1.0123).to_s(:human_size, :precision => 2) + assert_equal '1.01 KB', kilobytes(1.0100).to_s(:human_size, :precision => 4) + assert_equal '10 KB', kilobytes(10.000).to_s(:human_size, :precision => 4) + assert_equal '1 Byte', 1.1.to_s(:human_size) + assert_equal '10 Bytes', 10.to_s(:human_size) + end + + def test_to_s__human_size_with_si_prefix + assert_equal '3 Bytes', 3.14159265.to_s(:human_size, :prefix => :si) + assert_equal '123 Bytes', 123.0.to_s(:human_size, :prefix => :si) + assert_equal '123 Bytes', 123.to_s(:human_size, :prefix => :si) + assert_equal '1.23 KB', 1234.to_s(:human_size, :prefix => :si) + assert_equal '12.3 KB', 12345.to_s(:human_size, :prefix => :si) + assert_equal '1.23 MB', 1234567.to_s(:human_size, :prefix => :si) + assert_equal '1.23 GB', 1234567890.to_s(:human_size, :prefix => :si) + assert_equal '1.23 TB', 1234567890123.to_s(:human_size, :prefix => :si) + end + + def test_to_s__human_size_with_options_hash + assert_equal '1.2 MB', 1234567.to_s(:human_size, :precision => 2) + assert_equal '3 Bytes', 3.14159265.to_s(:human_size, :precision => 4) + assert_equal '1 KB', kilobytes(1.0123).to_s(:human_size, :precision => 2) + assert_equal '1.01 KB', kilobytes(1.0100).to_s(:human_size, :precision => 4) + assert_equal '10 KB', kilobytes(10.000).to_s(:human_size, :precision => 4) + assert_equal '1 TB', 1234567890123.to_s(:human_size, :precision => 1) + assert_equal '500 MB', 524288000.to_s(:human_size, :precision=>3) + assert_equal '10 MB', 9961472.to_s(:human_size, :precision=>0) + assert_equal '40 KB', 41010.to_s(:human_size, :precision => 1) + assert_equal '40 KB', 41100.to_s(:human_size, :precision => 2) + assert_equal '1.0 KB', kilobytes(1.0123).to_s(:human_size, :precision => 2, :strip_insignificant_zeros => false) + assert_equal '1.012 KB', kilobytes(1.0123).to_s(:human_size, :precision => 3, :significant => false) + assert_equal '1 KB', kilobytes(1.0123).to_s(:human_size, :precision => 0, :significant => true) #ignores significant it precision is 0 + end + + def test_to_s__human_size_with_custom_delimiter_and_separator + assert_equal '1,01 KB', kilobytes(1.0123).to_s(:human_size, :precision => 3, :separator => ',') + assert_equal '1,01 KB', kilobytes(1.0100).to_s(:human_size, :precision => 4, :separator => ',') + assert_equal '1.000,1 TB', terabytes(1000.1).to_s(:human_size, :precision => 5, :delimiter => '.', :separator => ',') + end + + def test_number_to_human + assert_equal '-123', -123.to_s(:human) + assert_equal '-0.5', -0.5.to_s(:human) + assert_equal '0', 0.to_s(:human) + assert_equal '0.5', 0.5.to_s(:human) + assert_equal '123', 123.to_s(:human) + assert_equal '1.23 Thousand', 1234.to_s(:human) + assert_equal '12.3 Thousand', 12345.to_s(:human) + assert_equal '1.23 Million', 1234567.to_s(:human) + assert_equal '1.23 Billion', 1234567890.to_s(:human) + assert_equal '1.23 Trillion', 1234567890123.to_s(:human) + assert_equal '1.23 Quadrillion', 1234567890123456.to_s(:human) + assert_equal '1230 Quadrillion', 1234567890123456789.to_s(:human) + assert_equal '490 Thousand', 489939.to_s(:human, :precision => 2) + assert_equal '489.9 Thousand', 489939.to_s(:human, :precision => 4) + assert_equal '489 Thousand', 489000.to_s(:human, :precision => 4) + assert_equal '489.0 Thousand', 489000.to_s(:human, :precision => 4, :strip_insignificant_zeros => false) + assert_equal '1.2346 Million', 1234567.to_s(:human, :precision => 4, :significant => false) + assert_equal '1,2 Million', 1234567.to_s(:human, :precision => 1, :significant => false, :separator => ',') + assert_equal '1 Million', 1234567.to_s(:human, :precision => 0, :significant => true, :separator => ',') #significant forced to false + end + + def test_number_to_human_with_custom_units + #Only integers + volume = {:unit => "ml", :thousand => "lt", :million => "m3"} + assert_equal '123 lt', 123456.to_s(:human, :units => volume) + assert_equal '12 ml', 12.to_s(:human, :units => volume) + assert_equal '1.23 m3', 1234567.to_s(:human, :units => volume) + + #Including fractionals + distance = {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"} + assert_equal '1.23 mm', 0.00123.to_s(:human, :units => distance) + assert_equal '1.23 cm', 0.0123.to_s(:human, :units => distance) + assert_equal '1.23 dm', 0.123.to_s(:human, :units => distance) + assert_equal '1.23 m', 1.23.to_s(:human, :units => distance) + assert_equal '1.23 dam', 12.3.to_s(:human, :units => distance) + assert_equal '1.23 hm', 123.to_s(:human, :units => distance) + assert_equal '1.23 km', 1230.to_s(:human, :units => distance) + assert_equal '1.23 km', 1230.to_s(:human, :units => distance) + assert_equal '1.23 km', 1230.to_s(:human, :units => distance) + assert_equal '12.3 km', 12300.to_s(:human, :units => distance) + + #The quantifiers don't need to be a continuous sequence + gangster = {:hundred => "hundred bucks", :million => "thousand quids"} + assert_equal '1 hundred bucks', 100.to_s(:human, :units => gangster) + assert_equal '25 hundred bucks', 2500.to_s(:human, :units => gangster) + assert_equal '25 thousand quids', 25000000.to_s(:human, :units => gangster) + assert_equal '12300 thousand quids', 12345000000.to_s(:human, :units => gangster) + + #Spaces are stripped from the resulting string + assert_equal '4', 4.to_s(:human, :units => {:unit => "", :ten => 'tens '}) + assert_equal '4.5 tens', 45.to_s(:human, :units => {:unit => "", :ten => ' tens '}) + end + + def test_number_to_human_with_custom_format + assert_equal '123 times Thousand', 123456.to_s(:human, :format => "%n times %u") + volume = {:unit => "ml", :thousand => "lt", :million => "m3"} + assert_equal '123.lt', 123456.to_s(:human, :units => volume, :format => "%n.%u") + end + + def test_to_s__injected_on_proper_types + assert_equal Fixnum, 1230.class + assert_equal '1.23 Thousand', 1230.to_s(:human) + + assert_equal Float, Float(1230).class + assert_equal '1.23 Thousand', Float(1230).to_s(:human) + + assert_equal Bignum, (100**10).class + assert_equal '100000 Quadrillion', (100**10).to_s(:human) + + assert_equal BigDecimal, BigDecimal("1000010").class + assert_equal '1 Million', BigDecimal("1000010").to_s(:human) + end +end diff --git a/activesupport/test/core_ext/object/to_query_test.rb b/activesupport/test/core_ext/object/to_query_test.rb index 6a26e1fa4f..c34647c1df 100644 --- a/activesupport/test/core_ext/object/to_query_test.rb +++ b/activesupport/test/core_ext/object/to_query_test.rb @@ -28,12 +28,12 @@ class ToQueryTest < ActiveSupport::TestCase def test_nested_conversion assert_query_equal 'person%5Blogin%5D=seckar&person%5Bname%5D=Nicholas', - :person => ActiveSupport::OrderedHash[:login, 'seckar', :name, 'Nicholas'] + :person => Hash[:login, 'seckar', :name, 'Nicholas'] end def test_multiple_nested assert_query_equal 'account%5Bperson%5D%5Bid%5D=20&person%5Bid%5D=10', - ActiveSupport::OrderedHash[:account, {:person => {:id => 20}}, :person, {:id => 10}] + Hash[:account, {:person => {:id => 20}}, :person, {:id => 10}] end def test_array_values diff --git a/activesupport/test/core_ext/object_and_class_ext_test.rb b/activesupport/test/core_ext/object_and_class_ext_test.rb index b027fccab3..ec7dd6d4fb 100644 --- a/activesupport/test/core_ext/object_and_class_ext_test.rb +++ b/activesupport/test/core_ext/object_and_class_ext_test.rb @@ -99,13 +99,25 @@ class ObjectTryTest < ActiveSupport::TestCase def test_nonexisting_method method = :undefined_method assert !@string.respond_to?(method) - assert_raise(NoMethodError) { @string.try(method) } + assert_nil @string.try(method) end - + def test_nonexisting_method_with_arguments method = :undefined_method assert !@string.respond_to?(method) - assert_raise(NoMethodError) { @string.try(method, 'llo', 'y') } + assert_nil @string.try(method, 'llo', 'y') + end + + def test_nonexisting_method_bang + method = :undefined_method + assert !@string.respond_to?(method) + assert_raise(NoMethodError) { @string.try!(method) } + end + + def test_nonexisting_method_with_arguments_bang + method = :undefined_method + assert !@string.respond_to?(method) + assert_raise(NoMethodError) { @string.try!(method, 'llo', 'y') } end def test_valid_method @@ -138,4 +150,28 @@ class ObjectTryTest < ActiveSupport::TestCase nil.try { ran = true } assert_equal false, ran end + + def test_try_with_private_method_bang + klass = Class.new do + private + + def private_method + 'private method' + end + end + + assert_raise(NoMethodError) { klass.new.try!(:private_method) } + end + + def test_try_with_private_method + klass = Class.new do + private + + def private_method + 'private method' + end + end + + assert_nil klass.new.try(:private_method) + end end diff --git a/activesupport/test/core_ext/proc_test.rb b/activesupport/test/core_ext/proc_test.rb index 690bfd3bf8..c4d5592196 100644 --- a/activesupport/test/core_ext/proc_test.rb +++ b/activesupport/test/core_ext/proc_test.rb @@ -3,10 +3,12 @@ require 'active_support/core_ext/proc' class ProcTests < ActiveSupport::TestCase def test_bind_returns_method_with_changed_self - block = Proc.new { self } - assert_equal self, block.call - bound_block = block.bind("hello") - assert_not_equal block, bound_block - assert_equal "hello", bound_block.call + assert_deprecated do + block = Proc.new { self } + assert_equal self, block.call + bound_block = block.bind("hello") + assert_not_equal block, bound_block + assert_equal "hello", bound_block.call + end end end diff --git a/activesupport/test/core_ext/range_ext_test.rb b/activesupport/test/core_ext/range_ext_test.rb index cf1ec448c2..f0cdc0bfd4 100644 --- a/activesupport/test/core_ext/range_ext_test.rb +++ b/activesupport/test/core_ext/range_ext_test.rb @@ -41,6 +41,18 @@ class RangeTest < ActiveSupport::TestCase assert((1..10).include?(1...10)) end + def test_should_compare_identical_inclusive + assert((1..10) === (1..10)) + end + + def test_should_compare_identical_exclusive + assert((1...10) === (1...10)) + end + + def test_should_compare_other_with_exlusive_end + assert((1..10) === (1...10)) + end + def test_exclusive_end_should_not_include_identical_with_inclusive_end assert !(1...10).include?(1..10) end @@ -57,16 +69,6 @@ class RangeTest < ActiveSupport::TestCase assert((1.0...10.0).include?(1.0...10.0)) end - def test_blockless_step - assert_equal [1,3,5,7,9], (1..10).step(2) - end - - def test_original_step - array = [] - (1..10).step(2) {|i| array << i } - assert_equal [1,3,5,7,9], array - end - def test_cover_is_not_override range = (1..3) assert range.method(:include?) != range.method(:cover?) diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index 6c2828b74e..6720ed42f0 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -9,6 +9,7 @@ require 'active_support/core_ext/string' require 'active_support/time' require 'active_support/core_ext/string/strip' require 'active_support/core_ext/string/output_safety' +require 'active_support/core_ext/string/indent' module Ace module Base @@ -279,11 +280,21 @@ class StringInflectionsTest < ActiveSupport::TestCase assert_equal "Hello Big[...]", "Hello Big World!".truncate(15, :omission => "[...]", :separator => ' ') end + def test_truncate_with_omission_and_regexp_seperator + assert_equal "Hello[...]", "Hello Big World!".truncate(13, :omission => "[...]", :separator => /\s/) + assert_equal "Hello Big[...]", "Hello Big World!".truncate(14, :omission => "[...]", :separator => /\s/) + assert_equal "Hello Big[...]", "Hello Big World!".truncate(15, :omission => "[...]", :separator => /\s/) + end + def test_truncate_multibyte assert_equal "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding('UTF-8'), "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8').truncate(10) end + def test_truncate_should_not_be_html_safe + assert !"Hello World!".truncate(12).html_safe? + end + def test_constantize run_constantize_tests_on do |string| string.constantize @@ -433,6 +444,37 @@ class OutputSafetyTest < ActiveSupport::TestCase assert @other_string.html_safe? end + test "Concatting safe onto unsafe with % yields unsafe" do + @other_string = "other%s" + string = @string.html_safe + + @other_string = @other_string % string + assert !@other_string.html_safe? + end + + test "Concatting unsafe onto safe with % yields escaped safe" do + @other_string = "other%s".html_safe + string = @other_string % "<foo>" + + assert_equal "other<foo>", string + assert string.html_safe? + end + + test "Concatting safe onto safe with % yields safe" do + @other_string = "other%s".html_safe + string = @string.html_safe + + @other_string = @other_string % string + assert @other_string.html_safe? + end + + test "Concatting with % doesn't modify a string" do + @other_string = ["<p>", "<b>", "<h1>"] + _ = "%s %s %s".html_safe % @other_string + + assert_equal ["<p>", "<b>", "<h1>"], @other_string + end + test "Concatting a fixnum to safe always yields safe" do string = @string.html_safe string = string.concat(13) @@ -457,8 +499,8 @@ class OutputSafetyTest < ActiveSupport::TestCase end test "ERB::Util.html_escape should escape unsafe characters" do - string = '<>&"' - expected = '<>&"' + string = '<>&"\'' + expected = '<>&"'' assert_equal expected, ERB::Util.html_escape(string) end @@ -480,3 +522,58 @@ class StringExcludeTest < ActiveSupport::TestCase assert_equal true, 'foo'.exclude?('p') end end + +class StringIndentTest < ActiveSupport::TestCase + test 'does not indent strings that only contain newlines (edge cases)' do + ['', "\n", "\n" * 7].each do |str| + assert_nil str.indent!(8) + assert_equal str, str.indent(8) + assert_equal str, str.indent(1, "\t") + end + end + + test "by default, indents with spaces if the existing indentation uses them" do + assert_equal " foo\n bar", "foo\n bar".indent(4) + end + + test "by default, indents with tabs if the existing indentation uses them" do + assert_equal "\tfoo\n\t\t\bar", "foo\n\t\bar".indent(1) + end + + test "by default, indents with spaces as a fallback if there is no indentation" do + assert_equal " foo\n bar\n baz", "foo\nbar\nbaz".indent(3) + end + + # Nothing is said about existing indentation that mixes spaces and tabs, so + # there is nothing to test. + + test 'uses the indent char if passed' do + assert_equal <<EXPECTED, <<ACTUAL.indent(4, '.') +.... def some_method(x, y) +.... some_code +.... end +EXPECTED + def some_method(x, y) + some_code + end +ACTUAL + + assert_equal <<EXPECTED, <<ACTUAL.indent(2, ' ') + def some_method(x, y) + some_code + end +EXPECTED + def some_method(x, y) + some_code + end +ACTUAL + end + + test "does not indent blank lines by default" do + assert_equal " foo\n\n bar", "foo\n\nbar".indent(1) + end + + test 'indents blank lines if told so' do + assert_equal " foo\n \n bar", "foo\n\nbar".indent(1, nil, true) + end +end diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index eda8066579..6d6757a1b6 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -1,7 +1,14 @@ require 'abstract_unit' require 'active_support/time' +require 'core_ext/date_and_time_behavior' class TimeExtCalculationsTest < ActiveSupport::TestCase + def date_time_init(year,month,day,hour,minute,second,usec=0) + Time.local(year,month,day,hour,minute,second,usec) + end + + include DateAndTimeBehavior + def test_seconds_since_midnight assert_equal 1,Time.local(2005,1,1,0,0,1).seconds_since_midnight assert_equal 60,Time.local(2005,1,1,0,1,0).seconds_since_midnight @@ -50,37 +57,6 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase end end - def test_beginning_of_week - assert_equal Time.local(2005,1,31), Time.local(2005,2,4,10,10,10).beginning_of_week - assert_equal Time.local(2005,11,28), Time.local(2005,11,28,0,0,0).beginning_of_week #monday - assert_equal Time.local(2005,11,28), Time.local(2005,11,29,0,0,0).beginning_of_week #tuesday - assert_equal Time.local(2005,11,28), Time.local(2005,11,30,0,0,0).beginning_of_week #wednesday - assert_equal Time.local(2005,11,28), Time.local(2005,12,01,0,0,0).beginning_of_week #thursday - assert_equal Time.local(2005,11,28), Time.local(2005,12,02,0,0,0).beginning_of_week #friday - assert_equal Time.local(2005,11,28), Time.local(2005,12,03,0,0,0).beginning_of_week #saturday - assert_equal Time.local(2005,11,28), Time.local(2005,12,04,0,0,0).beginning_of_week #sunday - - end - - def test_days_to_week_start - assert_equal 0, Time.local(2011,11,01,0,0,0).days_to_week_start(:tuesday) - assert_equal 1, Time.local(2011,11,02,0,0,0).days_to_week_start(:tuesday) - assert_equal 2, Time.local(2011,11,03,0,0,0).days_to_week_start(:tuesday) - assert_equal 3, Time.local(2011,11,04,0,0,0).days_to_week_start(:tuesday) - assert_equal 4, Time.local(2011,11,05,0,0,0).days_to_week_start(:tuesday) - assert_equal 5, Time.local(2011,11,06,0,0,0).days_to_week_start(:tuesday) - assert_equal 6, Time.local(2011,11,07,0,0,0).days_to_week_start(:tuesday) - - assert_equal 3, Time.local(2011,11,03,0,0,0).days_to_week_start(:monday) - assert_equal 3, Time.local(2011,11,04,0,0,0).days_to_week_start(:tuesday) - assert_equal 3, Time.local(2011,11,05,0,0,0).days_to_week_start(:wednesday) - assert_equal 3, Time.local(2011,11,06,0,0,0).days_to_week_start(:thursday) - assert_equal 3, Time.local(2011,11,07,0,0,0).days_to_week_start(:friday) - assert_equal 3, Time.local(2011,11,8,0,0,0).days_to_week_start(:saturday) - assert_equal 3, Time.local(2011,11,9,0,0,0).days_to_week_start(:sunday) - end - - def test_beginning_of_day assert_equal Time.local(2005,2,4,0,0,0), Time.local(2005,2,4,10,10,10).beginning_of_day with_env_tz 'US/Eastern' do @@ -93,113 +69,28 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase end end - def test_beginning_of_month - assert_equal Time.local(2005,2,1,0,0,0), Time.local(2005,2,22,10,10,10).beginning_of_month - end - - def test_beginning_of_quarter - assert_equal Time.local(2005,1,1,0,0,0), Time.local(2005,2,15,10,10,10).beginning_of_quarter - assert_equal Time.local(2005,1,1,0,0,0), Time.local(2005,1,1,0,0,0).beginning_of_quarter - assert_equal Time.local(2005,10,1,0,0,0), Time.local(2005,12,31,10,10,10).beginning_of_quarter - assert_equal Time.local(2005,4,1,0,0,0), Time.local(2005,6,30,23,59,59).beginning_of_quarter + def test_beginning_of_hour + assert_equal Time.local(2005,2,4,19,0,0), Time.local(2005,2,4,19,30,10).beginning_of_hour end def test_end_of_day - assert_equal Time.local(2007,8,12,23,59,59,999999.999), Time.local(2007,8,12,10,10,10).end_of_day + assert_equal Time.local(2007,8,12,23,59,59,Rational(999999999, 1000)), Time.local(2007,8,12,10,10,10).end_of_day with_env_tz 'US/Eastern' do - assert_equal Time.local(2007,4,2,23,59,59,999999.999), Time.local(2007,4,2,10,10,10).end_of_day, 'start DST' - assert_equal Time.local(2007,10,29,23,59,59,999999.999), Time.local(2007,10,29,10,10,10).end_of_day, 'ends DST' + assert_equal Time.local(2007,4,2,23,59,59,Rational(999999999, 1000)), Time.local(2007,4,2,10,10,10).end_of_day, 'start DST' + assert_equal Time.local(2007,10,29,23,59,59,Rational(999999999, 1000)), Time.local(2007,10,29,10,10,10).end_of_day, 'ends DST' end with_env_tz 'NZ' do - assert_equal Time.local(2006,3,19,23,59,59,999999.999), Time.local(2006,3,19,10,10,10).end_of_day, 'ends DST' - assert_equal Time.local(2006,10,1,23,59,59,999999.999), Time.local(2006,10,1,10,10,10).end_of_day, 'start DST' + assert_equal Time.local(2006,3,19,23,59,59,Rational(999999999, 1000)), Time.local(2006,3,19,10,10,10).end_of_day, 'ends DST' + assert_equal Time.local(2006,10,1,23,59,59,Rational(999999999, 1000)), Time.local(2006,10,1,10,10,10).end_of_day, 'start DST' end end - def test_end_of_week - assert_equal Time.local(2008,1,6,23,59,59,999999.999), Time.local(2007,12,31,10,10,10).end_of_week - assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,27,0,0,0).end_of_week #monday - assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,28,0,0,0).end_of_week #tuesday - assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,29,0,0,0).end_of_week #wednesday - assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,30,0,0,0).end_of_week #thursday - assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,8,31,0,0,0).end_of_week #friday - assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,9,01,0,0,0).end_of_week #saturday - assert_equal Time.local(2007,9,2,23,59,59,999999.999), Time.local(2007,9,02,0,0,0).end_of_week #sunday - end - - def test_end_of_month - assert_equal Time.local(2005,3,31,23,59,59,999999.999), Time.local(2005,3,20,10,10,10).end_of_month - assert_equal Time.local(2005,2,28,23,59,59,999999.999), Time.local(2005,2,20,10,10,10).end_of_month - assert_equal Time.local(2005,4,30,23,59,59,999999.999), Time.local(2005,4,20,10,10,10).end_of_month - end - - def test_end_of_quarter - assert_equal Time.local(2007,3,31,23,59,59,999999.999), Time.local(2007,2,15,10,10,10).end_of_quarter - assert_equal Time.local(2007,3,31,23,59,59,999999.999), Time.local(2007,3,31,0,0,0).end_of_quarter - assert_equal Time.local(2007,12,31,23,59,59,999999.999), Time.local(2007,12,21,10,10,10).end_of_quarter - assert_equal Time.local(2007,6,30,23,59,59,999999.999), Time.local(2007,4,1,0,0,0).end_of_quarter - assert_equal Time.local(2008,6,30,23,59,59,999999.999), Time.local(2008,5,31,0,0,0).end_of_quarter - end - - def test_end_of_year - assert_equal Time.local(2007,12,31,23,59,59,999999.999), Time.local(2007,2,22,10,10,10).end_of_year - assert_equal Time.local(2007,12,31,23,59,59,999999.999), Time.local(2007,12,31,10,10,10).end_of_year - end - - def test_beginning_of_year - assert_equal Time.local(2005,1,1,0,0,0), Time.local(2005,2,22,10,10,10).beginning_of_year - end - - def test_weeks_ago - assert_equal Time.local(2005,5,29,10), Time.local(2005,6,5,10,0,0).weeks_ago(1) - assert_equal Time.local(2005,5,1,10), Time.local(2005,6,5,10,0,0).weeks_ago(5) - assert_equal Time.local(2005,4,24,10), Time.local(2005,6,5,10,0,0).weeks_ago(6) - assert_equal Time.local(2005,2,27,10), Time.local(2005,6,5,10,0,0).weeks_ago(14) - assert_equal Time.local(2004,12,25,10), Time.local(2005,1,1,10,0,0).weeks_ago(1) - end - - def test_months_ago - assert_equal Time.local(2005,5,5,10), Time.local(2005,6,5,10,0,0).months_ago(1) - assert_equal Time.local(2004,11,5,10), Time.local(2005,6,5,10,0,0).months_ago(7) - assert_equal Time.local(2004,12,5,10), Time.local(2005,6,5,10,0,0).months_ago(6) - assert_equal Time.local(2004,6,5,10), Time.local(2005,6,5,10,0,0).months_ago(12) - assert_equal Time.local(2003,6,5,10), Time.local(2005,6,5,10,0,0).months_ago(24) - end - - def test_months_since - assert_equal Time.local(2005,7,5,10), Time.local(2005,6,5,10,0,0).months_since(1) - assert_equal Time.local(2006,1,5,10), Time.local(2005,12,5,10,0,0).months_since(1) - assert_equal Time.local(2005,12,5,10), Time.local(2005,6,5,10,0,0).months_since(6) - assert_equal Time.local(2006,6,5,10), Time.local(2005,12,5,10,0,0).months_since(6) - assert_equal Time.local(2006,1,5,10), Time.local(2005,6,5,10,0,0).months_since(7) - assert_equal Time.local(2006,6,5,10), Time.local(2005,6,5,10,0,0).months_since(12) - assert_equal Time.local(2007,6,5,10), Time.local(2005,6,5,10,0,0).months_since(24) - assert_equal Time.local(2005,4,30,10), Time.local(2005,3,31,10,0,0).months_since(1) - assert_equal Time.local(2005,2,28,10), Time.local(2005,1,29,10,0,0).months_since(1) - assert_equal Time.local(2005,2,28,10), Time.local(2005,1,30,10,0,0).months_since(1) - assert_equal Time.local(2005,2,28,10), Time.local(2005,1,31,10,0,0).months_since(1) + def test_end_of_hour + assert_equal Time.local(2005,2,4,19,59,59,Rational(999999999, 1000)), Time.local(2005,2,4,19,30,10).end_of_hour end - def test_years_ago - assert_equal Time.local(2004,6,5,10), Time.local(2005,6,5,10,0,0).years_ago(1) - assert_equal Time.local(1998,6,5,10), Time.local(2005,6,5,10,0,0).years_ago(7) - assert_equal Time.local(2003,2,28,10), Time.local(2004,2,29,10,0,0).years_ago(1) # 1 year ago from leap day - end - - def test_years_since - assert_equal Time.local(2006,6,5,10), Time.local(2005,6,5,10,0,0).years_since(1) - assert_equal Time.local(2012,6,5,10), Time.local(2005,6,5,10,0,0).years_since(7) - assert_equal Time.local(2005,2,28,10), Time.local(2004,2,29,10,0,0).years_since(1) # 1 year since leap day - # Failure because of size limitations of numeric? - # assert_equal Time.local(2182,6,5,10), Time.local(2005,6,5,10,0,0).years_since(177) - end - - def test_prev_year - assert_equal Time.local(2004,6,5,10), Time.local(2005,6,5,10,0,0).prev_year - end - - def test_next_year - assert_equal Time.local(2006,6,5,10), Time.local(2005,6,5,10,0,0).next_year + def test_last_year + assert_equal Time.local(2004,6,5,10), Time.local(2005,6,5,10,0,0).last_year end def test_ago @@ -414,16 +305,6 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase end end - def test_yesterday - assert_equal Time.local(2005,2,21,10,10,10), Time.local(2005,2,22,10,10,10).yesterday - assert_equal Time.local(2005,2,28,10,10,10), Time.local(2005,3,2,10,10,10).yesterday.yesterday - end - - def test_tomorrow - assert_equal Time.local(2005,2,23,10,10,10), Time.local(2005,2,22,10,10,10).tomorrow - assert_equal Time.local(2005,3,2,10,10,10), Time.local(2005,2,28,10,10,10).tomorrow.tomorrow - end - def test_change assert_equal Time.local(2006,2,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:year => 2006) assert_equal Time.local(2005,6,22,15,15,10), Time.local(2005,2,22,15,15,10).change(:month => 6) @@ -447,6 +328,15 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase assert_equal Time.utc(2005,2,22,15,45), Time.utc(2005,2,22,15,15,10).change(:min => 45) end + def test_offset_change + assert_equal Time.new(2006,2,22,15,15,10,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:year => 2006) + assert_equal Time.new(2005,6,22,15,15,10,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:month => 6) + assert_equal Time.new(2012,9,22,15,15,10,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:year => 2012, :month => 9) + assert_equal Time.new(2005,2,22,16,0,0,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:hour => 16) + assert_equal Time.new(2005,2,22,16,45,0,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:hour => 16, :min => 45) + assert_equal Time.new(2005,2,22,15,45,0,"-08:00"), Time.new(2005,2,22,15,15,10,"-08:00").change(:min => 45) + end + def test_advance assert_equal Time.local(2006,2,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 1) assert_equal Time.local(2005,6,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:months => 4) @@ -491,28 +381,40 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase assert_equal Time.utc(2013,10,17,20,22,19), Time.utc(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9) end + def test_offset_advance + assert_equal Time.new(2006,2,22,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:years => 1) + assert_equal Time.new(2005,6,22,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:months => 4) + assert_equal Time.new(2005,3,21,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:weeks => 3) + assert_equal Time.new(2005,3,25,3,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:weeks => 3.5) + assert_in_delta Time.new(2005,3,26,12,51,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:weeks => 3.7), 1 + assert_equal Time.new(2005,3,5,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:days => 5) + assert_equal Time.new(2005,3,6,3,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:days => 5.5) + assert_in_delta Time.new(2005,3,6,8,3,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:days => 5.7), 1 + assert_equal Time.new(2012,9,22,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:years => 7, :months => 7) + assert_equal Time.new(2013,10,3,15,15,10,'-08:00'), Time.new(2005,2,22,15,15,10,'-08:00').advance(:years => 7, :months => 19, :days => 11) + assert_equal Time.new(2013,10,17,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:years => 7, :months => 19, :weeks => 2, :days => 5) + assert_equal Time.new(2001,12,27,15,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:years => -3, :months => -2, :days => -1) + assert_equal Time.new(2005,2,28,15,15,10,'-08:00'), Time.new(2004,2,29,15,15,10,'-08:00').advance(:years => 1) #leap day plus one year + assert_equal Time.new(2005,2,28,20,15,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:hours => 5) + assert_equal Time.new(2005,2,28,15,22,10,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:minutes => 7) + assert_equal Time.new(2005,2,28,15,15,19,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:seconds => 9) + assert_equal Time.new(2005,2,28,20,22,19,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:hours => 5, :minutes => 7, :seconds => 9) + assert_equal Time.new(2005,2,28,10,8,1,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:hours => -5, :minutes => -7, :seconds => -9) + assert_equal Time.new(2013,10,17,20,22,19,'-08:00'), Time.new(2005,2,28,15,15,10,'-08:00').advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9) + end + def test_advance_with_nsec t = Time.at(0, Rational(108635108, 1000)) assert_equal t, t.advance(:months => 0) end - def test_prev_week - with_env_tz 'US/Eastern' do - assert_equal Time.local(2005,2,21), Time.local(2005,3,1,15,15,10).prev_week - assert_equal Time.local(2005,2,22), Time.local(2005,3,1,15,15,10).prev_week(:tuesday) - assert_equal Time.local(2005,2,25), Time.local(2005,3,1,15,15,10).prev_week(:friday) - assert_equal Time.local(2006,10,30), Time.local(2006,11,6,0,0,0).prev_week - assert_equal Time.local(2006,11,15), Time.local(2006,11,23,0,0,0).prev_week(:wednesday) - end - end - - def test_next_week + def test_last_week with_env_tz 'US/Eastern' do - assert_equal Time.local(2005,2,28), Time.local(2005,2,22,15,15,10).next_week - assert_equal Time.local(2005,3,1), Time.local(2005,2,22,15,15,10).next_week(:tuesday) - assert_equal Time.local(2005,3,4), Time.local(2005,2,22,15,15,10).next_week(:friday) - assert_equal Time.local(2006,10,30), Time.local(2006,10,23,0,0,0).next_week - assert_equal Time.local(2006,11,1), Time.local(2006,10,23,0,0,0).next_week(:wednesday) + assert_equal Time.local(2005,2,21), Time.local(2005,3,1,15,15,10).last_week + assert_equal Time.local(2005,2,22), Time.local(2005,3,1,15,15,10).last_week(:tuesday) + assert_equal Time.local(2005,2,25), Time.local(2005,3,1,15,15,10).last_week(:friday) + assert_equal Time.local(2006,10,30), Time.local(2006,11,6,0,0,0).last_week + assert_equal Time.local(2006,11,15), Time.local(2006,11,23,0,0,0).last_week(:wednesday) end end @@ -535,12 +437,14 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase end def test_to_s - time = Time.utc(2005, 2, 21, 17, 44, 30) + time = Time.utc(2005, 2, 21, 17, 44, 30.12345678901) assert_equal time.to_default_s, time.to_s assert_equal time.to_default_s, time.to_s(:doesnt_exist) assert_equal "2005-02-21 17:44:30", time.to_s(:db) assert_equal "21 Feb 17:44", time.to_s(:short) assert_equal "17:44", time.to_s(:time) + assert_equal "20050221174430", time.to_s(:number) + assert_equal "20050221174430123456789", time.to_s(:nsec) assert_equal "February 21, 2005 17:44", time.to_s(:long) assert_equal "February 21st, 2005 17:44", time.to_s(:long_ordinal) with_env_tz "UTC" do @@ -654,12 +558,8 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase end end - def test_next_month_on_31st - assert_equal Time.local(2005, 9, 30), Time.local(2005, 8, 31).next_month - end - - def test_prev_month_on_31st - assert_equal Time.local(2004, 2, 29), Time.local(2004, 3, 31).prev_month + def test_last_month_on_31st + assert_equal Time.local(2004, 2, 29), Time.local(2004, 3, 31).last_month end def test_xmlschema_is_available @@ -802,24 +702,32 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase end def test_all_day - assert_equal Time.local(2011,6,7,0,0,0)..Time.local(2011,6,7,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_day + assert_equal Time.local(2011,6,7,0,0,0)..Time.local(2011,6,7,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_day + end + + def test_all_day_with_timezone + beginning_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011,6,7,0,0,0)) + end_of_day = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], Time.local(2011,6,7,23,59,59,Rational(999999999, 1000))) + + assert_equal beginning_of_day, ActiveSupport::TimeWithZone.new(Time.local(2011,6,7,10,10,10), ActiveSupport::TimeZone["Hawaii"]).all_day.begin + assert_equal end_of_day, ActiveSupport::TimeWithZone.new(Time.local(2011,6,7,10,10,10), ActiveSupport::TimeZone["Hawaii"]).all_day.end end def test_all_week - assert_equal Time.local(2011,6,6,0,0,0)..Time.local(2011,6,12,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_week - assert_equal Time.local(2011,6,5,0,0,0)..Time.local(2011,6,11,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_week(:sunday) + assert_equal Time.local(2011,6,6,0,0,0)..Time.local(2011,6,12,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_week + assert_equal Time.local(2011,6,5,0,0,0)..Time.local(2011,6,11,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_week(:sunday) end def test_all_month - assert_equal Time.local(2011,6,1,0,0,0)..Time.local(2011,6,30,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_month + assert_equal Time.local(2011,6,1,0,0,0)..Time.local(2011,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_month end def test_all_quarter - assert_equal Time.local(2011,4,1,0,0,0)..Time.local(2011,6,30,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_quarter + assert_equal Time.local(2011,4,1,0,0,0)..Time.local(2011,6,30,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_quarter end def test_all_year - assert_equal Time.local(2011,1,1,0,0,0)..Time.local(2011,12,31,23,59,59,999999.999), Time.local(2011,6,7,10,10,10).all_year + assert_equal Time.local(2011,1,1,0,0,0)..Time.local(2011,12,31,23,59,59,Rational(999999999, 1000)), Time.local(2011,6,7,10,10,10).all_year end protected @@ -870,4 +778,8 @@ class TimeExtMarshalingTest < ActiveSupport::TestCase assert_equal t.to_f, unmarshaled.to_f assert_equal t, unmarshaled end + + def test_last_quarter_on_31st + assert_equal Time.local(2004, 2, 29), Time.local(2004, 5, 31).last_quarter + end end diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb index 7cf3842a16..1293f104e5 100644 --- a/activesupport/test/core_ext/time_with_zone_test.rb +++ b/activesupport/test/core_ext/time_with_zone_test.rb @@ -80,6 +80,14 @@ class TimeWithZoneTest < ActiveSupport::TestCase ActiveSupport.use_standard_json_time_format = old end + def test_nsec + local = Time.local(2011,6,7,23,59,59,Rational(999999999, 1000)) + with_zone = ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone["Hawaii"], local) + + assert_equal local.nsec, with_zone.nsec + assert_equal with_zone.nsec, 999999999 + end + def test_strftime assert_equal '1999-12-31 19:00:00 EST -0500', @twz.strftime('%Y-%m-%d %H:%M:%S %Z %z') end @@ -191,7 +199,7 @@ class TimeWithZoneTest < ActiveSupport::TestCase end end - def future_with_time_current_as_time_with_zone + def test_future_with_time_current_as_time_with_zone twz = ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,45) ) Time.stubs(:current).returns(twz) assert_equal false, ActiveSupport::TimeWithZone.new( nil, @time_zone, Time.local(2005,2,10,15,30,44)).future? @@ -450,6 +458,7 @@ class TimeWithZoneTest < ActiveSupport::TestCase def test_ruby_19_weekday_name_query_methods %w(sunday? monday? tuesday? wednesday? thursday? friday? saturday?).each do |name| assert_respond_to @twz, name + assert_equal @twz.send(name), @twz.method(name).call end end @@ -482,36 +491,50 @@ class TimeWithZoneTest < ActiveSupport::TestCase assert_equal "Fri, 31 Dec 1999 19:00:30 EST -05:00", @twz.advance(:seconds => 30).inspect end - def beginning_of_year + def test_beginning_of_year assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 01 Jan 1999 00:00:00 EST -05:00", @twz.beginning_of_year.inspect end - def end_of_year + def test_end_of_year assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_year.inspect end - def beginning_of_month + def test_beginning_of_month assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect - assert_equal "Fri, 01 Dec 1999 00:00:00 EST -05:00", @twz.beginning_of_month.inspect + assert_equal "Wed, 01 Dec 1999 00:00:00 EST -05:00", @twz.beginning_of_month.inspect end - def end_of_month + def test_end_of_month assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_month.inspect end - def beginning_of_day + def test_beginning_of_day assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 31 Dec 1999 00:00:00 EST -05:00", @twz.beginning_of_day.inspect end - def end_of_day + def test_end_of_day assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", @twz.inspect assert_equal "Fri, 31 Dec 1999 23:59:59 EST -05:00", @twz.end_of_day.inspect end + def test_beginning_of_hour + utc = Time.utc(2000, 1, 1, 0, 30) + twz = ActiveSupport::TimeWithZone.new(utc, @time_zone) + assert_equal "Fri, 31 Dec 1999 19:30:00 EST -05:00", twz.inspect + assert_equal "Fri, 31 Dec 1999 19:00:00 EST -05:00", twz.beginning_of_hour.inspect + end + + def test_end_of_hour + utc = Time.utc(2000, 1, 1, 0, 30) + twz = ActiveSupport::TimeWithZone.new(utc, @time_zone) + assert_equal "Fri, 31 Dec 1999 19:30:00 EST -05:00", twz.inspect + assert_equal "Fri, 31 Dec 1999 19:59:59 EST -05:00", twz.end_of_hour.inspect + end + def test_since assert_equal "Fri, 31 Dec 1999 19:00:01 EST -05:00", @twz.since(1).inspect end diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb index 081e6a16fd..e5bc806397 100644 --- a/activesupport/test/dependencies_test.rb +++ b/activesupport/test/dependencies_test.rb @@ -39,6 +39,19 @@ class DependenciesTest < ActiveSupport::TestCase with_loading 'autoloading_fixtures', &block end + def test_depend_on_path + skip "LoadError#path does not exist" if RUBY_VERSION < '2.0.0' + + expected = assert_raises(LoadError) do + Kernel.require 'omgwtfbbq' + end + + e = assert_raises(LoadError) do + ActiveSupport::Dependencies.depend_on 'omgwtfbbq' + end + assert_equal expected.path, e.path + end + def test_tracking_loaded_files require_dependency 'dependencies/service_one' require_dependency 'dependencies/service_two' @@ -60,10 +73,6 @@ class DependenciesTest < ActiveSupport::TestCase assert_raise(MissingSourceFile) { require_dependency("missing_service") } end - def test_missing_association_raises_nothing - assert_nothing_raised { require_association("missing_model") } - end - def test_dependency_which_raises_exception_isnt_added_to_loaded_set with_loading do filename = 'dependencies/raises_exception' @@ -136,6 +145,12 @@ class DependenciesTest < ActiveSupport::TestCase end end + def test_circular_autoloading_detection + with_autoloading_fixtures do + assert_raise(RuntimeError, "Circular dependency detected while autoloading constant Circular1") { Circular1 } + end + end + def test_module_loading with_autoloading_fixtures do assert_kind_of Module, A @@ -670,6 +685,8 @@ class DependenciesTest < ActiveSupport::TestCase assert_equal true, M.unloadable assert_equal false, M.unloadable end + ensure + Object.class_eval { remove_const :M } end def test_unloadable_constants_should_receive_callback diff --git a/activesupport/test/deprecation_test.rb b/activesupport/test/deprecation_test.rb index e821a285d7..c081103cc7 100644 --- a/activesupport/test/deprecation_test.rb +++ b/activesupport/test/deprecation_test.rb @@ -93,6 +93,37 @@ class DeprecationTest < ActiveSupport::TestCase assert_match(/foo=nil/, @b) end + def test_default_stderr_behavior + ActiveSupport::Deprecation.behavior = :stderr + behavior = ActiveSupport::Deprecation.behavior.first + + content = capture(:stderr) { + assert_nil behavior.call('Some error!', ['call stack!']) + } + assert_match(/Some error!/, content) + assert_match(/call stack!/, content) + end + + def test_default_stderr_behavior_with_warn_method + ActiveSupport::Deprecation.behavior = :stderr + + content = capture(:stderr) { + ActiveSupport::Deprecation.warn('Instance error!', ['instance call stack!']) + } + + assert_match(/Instance error!/, content) + assert_match(/instance call stack!/, content) + end + + def test_default_silence_behavior + ActiveSupport::Deprecation.behavior = :silence + behavior = ActiveSupport::Deprecation.behavior.first + + assert_blank capture(:stderr) { + assert_nil behavior.call('Some error!', ['call stack!']) + } + end + def test_deprecated_instance_variable_proxy assert_not_deprecated { @dtc.request.size } @@ -166,4 +197,142 @@ class DeprecationTest < ActiveSupport::TestCase def test_deprecation_with_explicit_message assert_deprecated(/you now need to do something extra for this one/) { @dtc.d } end + + def test_deprecation_in_other_object + messages = [] + + klass = Class.new do + delegate :warn, :behavior=, to: ActiveSupport::Deprecation + end + + o = klass.new + o.behavior = Proc.new { |message, callstack| messages << message } + assert_difference("messages.size") do + o.warn("warning") + end + end + + def test_deprecated_method_with_custom_method_warning + deprecator = deprecator_with_messages + + class << deprecator + private + def deprecated_method_warning(method, message) + "deprecator.deprecated_method_warning.#{method}" + end + end + + deprecatee = Class.new do + def method + end + deprecate :method, deprecator: deprecator + end + + deprecatee.new.method + assert deprecator.messages.first.match("DEPRECATION WARNING: deprecator.deprecated_method_warning.method") + end + + def test_deprecate_with_custom_deprecator + custom_deprecator = mock('Deprecator') do + expects(:deprecation_warning) + end + + klass = Class.new do + def method + end + deprecate :method, deprecator: custom_deprecator + end + + klass.new.method + end + + def test_deprecated_constant_with_deprecator_given + deprecator = deprecator_with_messages + klass = Class.new + klass.const_set(:OLD, ActiveSupport::Deprecation::DeprecatedConstantProxy.new('klass::OLD', 'Object', deprecator) ) + assert_difference("deprecator.messages.size") do + klass::OLD.to_s + end + end + + def test_deprecated_instance_variable_with_instance_deprecator + deprecator = deprecator_with_messages + + klass = Class.new() do + def initialize(deprecator) + @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator) + @_request = :a_request + end + def request; @_request end + def old_request; @request end + end + + assert_difference("deprecator.messages.size") { klass.new(deprecator).old_request.to_s } + end + + def test_deprecated_instance_variable_with_given_deprecator + deprecator = deprecator_with_messages + + klass = Class.new do + define_method(:initialize) do + @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, deprecator) + @_request = :a_request + end + def request; @_request end + def old_request; @request end + end + + assert_difference("deprecator.messages.size") { klass.new.old_request.to_s } + end + + def test_delegate_deprecator_instance + klass = Class.new do + attr_reader :last_message + delegate :warn, :behavior=, to: ActiveSupport::Deprecation + + def initialize + self.behavior = [Proc.new { |message| @last_message = message }] + end + + def deprecated_method + warn(deprecated_method_warning(:deprecated_method, "You are calling deprecated method")) + end + + private + def deprecated_method_warning(method_name, message = nil) + message || "#{method_name} is deprecated and will be removed from This Library" + end + end + + object = klass.new + object.deprecated_method + assert_match(/You are calling deprecated method/, object.last_message) + end + + def test_default_gem_name + deprecator = ActiveSupport::Deprecation.new + + deprecator.send(:deprecated_method_warning, :deprecated_method, "You are calling deprecated method").tap do |message| + assert_match(/is deprecated and will be removed from Rails/, message) + end + end + + def test_custom_gem_name + deprecator = ActiveSupport::Deprecation.new('2.0', 'Custom') + + deprecator.send(:deprecated_method_warning, :deprecated_method, "You are calling deprecated method").tap do |message| + assert_match(/is deprecated and will be removed from Custom/, message) + end + end + + private + def deprecator_with_messages + klass = Class.new(ActiveSupport::Deprecation) + deprecator = klass.new + deprecator.behavior = Proc.new{|message, callstack| deprecator.messages << message} + def deprecator.messages + @messages ||= [] + end + deprecator + end end diff --git a/activesupport/test/file_update_checker_test.rb b/activesupport/test/file_update_checker_test.rb index dd2483287b..bd1df0f858 100644 --- a/activesupport/test/file_update_checker_test.rb +++ b/activesupport/test/file_update_checker_test.rb @@ -1,5 +1,6 @@ require 'abstract_unit' require 'fileutils' +require 'thread' MTIME_FIXTURES_PATH = File.expand_path("../fixtures", __FILE__) @@ -43,8 +44,23 @@ class FileUpdateCheckerWithEnumerableTest < ActiveSupport::TestCase i = 0 checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 } FileUtils.rm(FILES) - assert !checker.execute_if_updated - assert_equal 0, i + assert checker.execute_if_updated + assert_equal 1, i + end + + def test_should_be_robust_to_handle_files_with_wrong_modified_time + i = 0 + now = Time.now + time = Time.mktime(now.year + 1, now.month, now.day) # wrong mtime from the future + File.utime time, time, FILES[2] + + checker = ActiveSupport::FileUpdateChecker.new(FILES){ i += 1 } + + sleep(1) + FileUtils.touch(FILES[0..1]) + + assert checker.execute_if_updated + assert_equal 1, i end def test_should_cache_updated_result_until_execute @@ -79,4 +95,18 @@ class FileUpdateCheckerWithEnumerableTest < ActiveSupport::TestCase assert !checker.execute_if_updated assert_equal 0, i end + + def test_should_not_block_if_a_strange_filename_used + FileUtils.mkdir_p("tmp_watcher/valid,yetstrange,path,") + FileUtils.touch(FILES.map { |file_name| "tmp_watcher/valid,yetstrange,path,/#{file_name}" }) + + test = Thread.new do + ActiveSupport::FileUpdateChecker.new([],"tmp_watcher/valid,yetstrange,path," => :txt) { i += 1 } + Thread.exit + end + test.priority = -1 + test.join(5) + + assert !test.alive? + end end diff --git a/activesupport/test/i18n_test.rb b/activesupport/test/i18n_test.rb index 4f2027f4eb..ddbba444cf 100644 --- a/activesupport/test/i18n_test.rb +++ b/activesupport/test/i18n_test.rb @@ -97,4 +97,9 @@ class I18nTest < ActiveSupport::TestCase I18n.backend.store_translations 'en', :support => { :array => { :two_words_connector => default_two_words_connector } } I18n.backend.store_translations 'en', :support => { :array => { :last_word_connector => default_last_word_connector } } end + + def test_to_sentence_with_empty_i18n_store + I18n.backend.store_translations 'empty', {} + assert_equal 'a, b, and c', %w[a b c].to_sentence(locale: 'empty') + end end diff --git a/activesupport/test/inflector_test.rb b/activesupport/test/inflector_test.rb index 7b012f7caa..aa41e57928 100644 --- a/activesupport/test/inflector_test.rb +++ b/activesupport/test/inflector_test.rb @@ -26,23 +26,20 @@ class InflectorTest < ActiveSupport::TestCase end def test_uncountable_word_is_not_greedy - uncountable_word = "ors" - countable_word = "sponsor" + with_dup do + uncountable_word = "ors" + countable_word = "sponsor" - cached_uncountables = ActiveSupport::Inflector.inflections.uncountables + ActiveSupport::Inflector.inflections.uncountable << uncountable_word - ActiveSupport::Inflector.inflections.uncountable << uncountable_word + assert_equal uncountable_word, ActiveSupport::Inflector.singularize(uncountable_word) + assert_equal uncountable_word, ActiveSupport::Inflector.pluralize(uncountable_word) + assert_equal ActiveSupport::Inflector.pluralize(uncountable_word), ActiveSupport::Inflector.singularize(uncountable_word) - assert_equal uncountable_word, ActiveSupport::Inflector.singularize(uncountable_word) - assert_equal uncountable_word, ActiveSupport::Inflector.pluralize(uncountable_word) - assert_equal ActiveSupport::Inflector.pluralize(uncountable_word), ActiveSupport::Inflector.singularize(uncountable_word) - - assert_equal "sponsor", ActiveSupport::Inflector.singularize(countable_word) - assert_equal "sponsors", ActiveSupport::Inflector.pluralize(countable_word) - assert_equal "sponsor", ActiveSupport::Inflector.singularize(ActiveSupport::Inflector.pluralize(countable_word)) - - ensure - ActiveSupport::Inflector.inflections.instance_variable_set :@uncountables, cached_uncountables + assert_equal "sponsor", ActiveSupport::Inflector.singularize(countable_word) + assert_equal "sponsors", ActiveSupport::Inflector.pluralize(countable_word) + assert_equal "sponsor", ActiveSupport::Inflector.singularize(ActiveSupport::Inflector.pluralize(countable_word)) + end end SingularToPlural.each do |singular, plural| @@ -65,14 +62,14 @@ class InflectorTest < ActiveSupport::TestCase assert_equal(plural.capitalize, ActiveSupport::Inflector.pluralize(plural.capitalize)) end end - + SingularToPlural.each do |singular, plural| define_method "test_singularize_singular_#{singular}" do assert_equal(singular, ActiveSupport::Inflector.singularize(singular)) assert_equal(singular.capitalize, ActiveSupport::Inflector.singularize(singular.capitalize)) end end - + def test_overwrite_previous_inflectors assert_equal("series", ActiveSupport::Inflector.singularize("series")) @@ -172,11 +169,11 @@ class InflectorTest < ActiveSupport::TestCase def test_underscore_acronym_sequence ActiveSupport::Inflector.inflections do |inflect| inflect.acronym("API") - inflect.acronym("HTML5") + inflect.acronym("JSON") inflect.acronym("HTML") end - assert_equal("html5_html_api", ActiveSupport::Inflector.underscore("HTML5HTMLAPI")) + assert_equal("json_html_api", ActiveSupport::Inflector.underscore("JSONHTMLAPI")) end def test_underscore @@ -303,7 +300,7 @@ class InflectorTest < ActiveSupport::TestCase ActiveSupport::Inflector.constantize(string) end end - + def test_safe_constantize run_safe_constantize_tests_on do |string| ActiveSupport::Inflector.safe_constantize(string) @@ -349,56 +346,79 @@ class InflectorTest < ActiveSupport::TestCase %w{plurals singulars uncountables humans}.each do |inflection_type| class_eval <<-RUBY, __FILE__, __LINE__ + 1 def test_clear_#{inflection_type} - cached_values = ActiveSupport::Inflector.inflections.#{inflection_type} - ActiveSupport::Inflector.inflections.clear :#{inflection_type} - assert ActiveSupport::Inflector.inflections.#{inflection_type}.empty?, \"#{inflection_type} inflections should be empty after clear :#{inflection_type}\" - ActiveSupport::Inflector.inflections.instance_variable_set :@#{inflection_type}, cached_values + with_dup do + ActiveSupport::Inflector.inflections.clear :#{inflection_type} + assert ActiveSupport::Inflector.inflections.#{inflection_type}.empty?, \"#{inflection_type} inflections should be empty after clear :#{inflection_type}\" + end end RUBY end - def test_clear_all - cached_values = ActiveSupport::Inflector.inflections.plurals.dup, ActiveSupport::Inflector.inflections.singulars.dup, ActiveSupport::Inflector.inflections.uncountables.dup, ActiveSupport::Inflector.inflections.humans.dup - ActiveSupport::Inflector.inflections do |inflect| - # ensure any data is present - inflect.plural(/(quiz)$/i, '\1zes') - inflect.singular(/(database)s$/i, '\1') - inflect.uncountable('series') - inflect.human("col_rpted_bugs", "Reported bugs") + def test_inflector_locality + ActiveSupport::Inflector.inflections(:es) do |inflect| + inflect.plural(/$/, 's') + inflect.plural(/z$/i, 'ces') + + inflect.singular(/s$/, '') + inflect.singular(/es$/, '') + + inflect.irregular('el', 'los') + end + + assert_equal('hijos', 'hijo'.pluralize(:es)) + assert_equal('luces', 'luz'.pluralize(:es)) + assert_equal('luzs', 'luz'.pluralize) + + assert_equal('sociedad', 'sociedades'.singularize(:es)) + assert_equal('sociedade', 'sociedades'.singularize) - inflect.clear :all + assert_equal('los', 'el'.pluralize(:es)) + assert_equal('els', 'el'.pluralize) - assert inflect.plurals.empty? - assert inflect.singulars.empty? - assert inflect.uncountables.empty? - assert inflect.humans.empty? + ActiveSupport::Inflector.inflections(:es) { |inflect| inflect.clear } + + assert ActiveSupport::Inflector.inflections(:es).plurals.empty? + assert ActiveSupport::Inflector.inflections(:es).singulars.empty? + assert !ActiveSupport::Inflector.inflections.plurals.empty? + assert !ActiveSupport::Inflector.inflections.singulars.empty? + end + + def test_clear_all + with_dup do + ActiveSupport::Inflector.inflections do |inflect| + # ensure any data is present + inflect.plural(/(quiz)$/i, '\1zes') + inflect.singular(/(database)s$/i, '\1') + inflect.uncountable('series') + inflect.human("col_rpted_bugs", "Reported bugs") + + inflect.clear :all + + assert inflect.plurals.empty? + assert inflect.singulars.empty? + assert inflect.uncountables.empty? + assert inflect.humans.empty? + end end - ActiveSupport::Inflector.inflections.instance_variable_set :@plurals, cached_values[0] - ActiveSupport::Inflector.inflections.instance_variable_set :@singulars, cached_values[1] - ActiveSupport::Inflector.inflections.instance_variable_set :@uncountables, cached_values[2] - ActiveSupport::Inflector.inflections.instance_variable_set :@humans, cached_values[3] end def test_clear_with_default - cached_values = ActiveSupport::Inflector.inflections.plurals.dup, ActiveSupport::Inflector.inflections.singulars.dup, ActiveSupport::Inflector.inflections.uncountables.dup, ActiveSupport::Inflector.inflections.humans.dup - ActiveSupport::Inflector.inflections do |inflect| - # ensure any data is present - inflect.plural(/(quiz)$/i, '\1zes') - inflect.singular(/(database)s$/i, '\1') - inflect.uncountable('series') - inflect.human("col_rpted_bugs", "Reported bugs") - - inflect.clear - - assert inflect.plurals.empty? - assert inflect.singulars.empty? - assert inflect.uncountables.empty? - assert inflect.humans.empty? + with_dup do + ActiveSupport::Inflector.inflections do |inflect| + # ensure any data is present + inflect.plural(/(quiz)$/i, '\1zes') + inflect.singular(/(database)s$/i, '\1') + inflect.uncountable('series') + inflect.human("col_rpted_bugs", "Reported bugs") + + inflect.clear + + assert inflect.plurals.empty? + assert inflect.singulars.empty? + assert inflect.uncountables.empty? + assert inflect.humans.empty? + end end - ActiveSupport::Inflector.inflections.instance_variable_set :@plurals, cached_values[0] - ActiveSupport::Inflector.inflections.instance_variable_set :@singulars, cached_values[1] - ActiveSupport::Inflector.inflections.instance_variable_set :@uncountables, cached_values[2] - ActiveSupport::Inflector.inflections.instance_variable_set :@humans, cached_values[3] end Irregularities.each do |irregularity| @@ -422,6 +442,16 @@ class InflectorTest < ActiveSupport::TestCase end end + Irregularities.each do |irregularity| + singular, plural = *irregularity + ActiveSupport::Inflector.inflections do |inflect| + define_method("test_singularize_of_irregularity_#{singular}_should_be_the_same") do + inflect.irregular(singular, plural) + assert_equal singular, ActiveSupport::Inflector.singularize(singular) + end + end + end + [ :all, [] ].each do |scope| ActiveSupport::Inflector.inflections do |inflect| define_method("test_clear_inflections_with_#{scope.kind_of?(Array) ? "no_arguments" : scope}") do @@ -447,26 +477,28 @@ class InflectorTest < ActiveSupport::TestCase end end - { :singulars => :singular, :plurals => :plural, :uncountables => :uncountable, :humans => :human }.each do |scope, method| + %w(plurals singulars uncountables humans acronyms).each do |scope| ActiveSupport::Inflector.inflections do |inflect| define_method("test_clear_inflections_with_#{scope}") do - # save the inflections - values = inflect.send(scope) - - # clear the inflections - inflect.clear(scope) - - assert_equal [], inflect.send(scope) - - # restore the inflections - if scope == :uncountables - inflect.send(method, values) - else - values.reverse.each { |value| inflect.send(method, *value) } + with_dup do + # clear the inflections + inflect.clear(scope) + assert_equal [], inflect.send(scope) end - - assert_equal values, inflect.send(scope) end end end + + # Dups the singleton and yields, restoring the original inflections later. + # Use this in tests what modify the state of the singleton. + # + # This helper is implemented by setting @__instance__ because in some tests + # there are module functions that access ActiveSupport::Inflector.inflections, + # so we need to replace the singleton itself. + def with_dup + original = ActiveSupport::Inflector::Inflections.instance_variable_get(:@__instance__) + ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original.dup) + ensure + ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, original) + end end diff --git a/activesupport/test/inflector_test_cases.rb b/activesupport/test/inflector_test_cases.rb index 809b8b46c9..ca4efd2e59 100644 --- a/activesupport/test/inflector_test_cases.rb +++ b/activesupport/test/inflector_test_cases.rb @@ -47,6 +47,7 @@ module InflectorTestCases "medium" => "media", "stadium" => "stadia", "analysis" => "analyses", + "my_analysis" => "my_analyses", "node_child" => "node_children", "child" => "children", @@ -109,7 +110,9 @@ module InflectorTestCases # regression tests against improper inflection regexes "|ice" => "|ices", - "|ouse" => "|ouses" + "|ouse" => "|ouses", + "slice" => "slices", + "police" => "police" } CamelToUnderscore = { @@ -211,16 +214,22 @@ module InflectorTestCases } MixtureToTitleCase = { - 'active_record' => 'Active Record', - 'ActiveRecord' => 'Active Record', - 'action web service' => 'Action Web Service', - 'Action Web Service' => 'Action Web Service', - 'Action web service' => 'Action Web Service', - 'actionwebservice' => 'Actionwebservice', - 'Actionwebservice' => 'Actionwebservice', - "david's code" => "David's Code", - "David's code" => "David's Code", - "david's Code" => "David's Code" + 'active_record' => 'Active Record', + 'ActiveRecord' => 'Active Record', + 'action web service' => 'Action Web Service', + 'Action Web Service' => 'Action Web Service', + 'Action web service' => 'Action Web Service', + 'actionwebservice' => 'Actionwebservice', + 'Actionwebservice' => 'Actionwebservice', + "david's code" => "David's Code", + "David's code" => "David's Code", + "david's Code" => "David's Code", + "sgt. pepper's" => "Sgt. Pepper's", + "i've just seen a face" => "I've Just Seen A Face", + "maybe you'll be there" => "Maybe You'll Be There", + "¿por qué?" => '¿Por Qué?', + "Fred’s" => "Fred’s", + "Fred`s" => "Fred`s" } OrdinalNumbers = { @@ -299,5 +308,7 @@ module InflectorTestCases 'child' => 'children', 'sex' => 'sexes', 'move' => 'moves', + 'cow' => 'kine', + 'zombie' => 'zombies', } end diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index a2e61d88d5..7ed71f9abc 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -27,6 +27,10 @@ class TestJSONEncoding < ActiveSupport::TestCase NilTests = [[ nil, %(null) ]] NumericTests = [[ 1, %(1) ], [ 2.5, %(2.5) ], + [ 0.0/0.0, %(null) ], + [ 1.0/0.0, %(null) ], + [ -1.0/0.0, %(null) ], + [ BigDecimal('0.0')/BigDecimal('0.0'), %(null) ], [ BigDecimal('2.5'), %("#{BigDecimal('2.5').to_s}") ]] StringTests = [[ 'this is the <string>', %("this is the \\u003Cstring\\u003E")], @@ -50,8 +54,6 @@ class TestJSONEncoding < ActiveSupport::TestCase HashlikeTests = [[ Hashlike.new, %({\"a\":1}) ]] CustomTests = [[ Custom.new, '"custom"' ]] - VariableTests = [[ ActiveSupport::JSON::Variable.new('foo'), 'foo'], - [ ActiveSupport::JSON::Variable.new('alert("foo")'), 'alert("foo")']] RegexpTests = [[ /^a/, '"(?-mix:^a)"' ], [/^\w{1,2}[a-z]+/ix, '"(?ix-m:^\\\\w{1,2}[a-z]+)"']] DateTests = [[ Date.new(2005,2,1), %("2005/02/01") ]] @@ -83,6 +85,13 @@ class TestJSONEncoding < ActiveSupport::TestCase end end + def test_json_variable + assert_deprecated do + assert_equal ActiveSupport::JSON::Variable.new('foo'), 'foo' + assert_equal ActiveSupport::JSON::Variable.new('alert("foo")'), 'alert("foo")' + end + end + def test_hash_encoding assert_equal %({\"a\":\"b\"}), ActiveSupport::JSON.encode(:a => :b) assert_equal %({\"a\":1}), ActiveSupport::JSON.encode('a' => 1) @@ -270,6 +279,23 @@ class TestJSONEncoding < ActiveSupport::TestCase JSON.parse(json_string_and_date)) end + def test_opt_out_big_decimal_string_serialization + big_decimal = BigDecimal('2.5') + + begin + ActiveSupport.encode_big_decimal_as_string = false + assert_equal big_decimal.to_s, big_decimal.to_json + ensure + ActiveSupport.encode_big_decimal_as_string = true + end + end + + def test_nil_true_and_false_represented_as_themselves + assert_equal nil, nil.as_json + assert_equal true, true.as_json + assert_equal false, false.as_json + end + protected def object_keys(json_object) diff --git a/activesupport/test/lazy_load_hooks_test.rb b/activesupport/test/lazy_load_hooks_test.rb index 58ccc14324..7851634dbf 100644 --- a/activesupport/test/lazy_load_hooks_test.rb +++ b/activesupport/test/lazy_load_hooks_test.rb @@ -8,6 +8,16 @@ class LazyLoadHooksTest < ActiveSupport::TestCase assert_equal 1, i end + def test_basic_hook_with_two_registrations + i = 0 + ActiveSupport.on_load(:basic_hook_with_two) { i += incr } + assert_equal 0, i + ActiveSupport.run_load_hooks(:basic_hook_with_two, FakeContext.new(2)) + assert_equal 2, i + ActiveSupport.run_load_hooks(:basic_hook_with_two, FakeContext.new(5)) + assert_equal 7, i + end + def test_hook_registered_after_run i = 0 ActiveSupport.run_load_hooks(:registered_after) @@ -16,6 +26,25 @@ class LazyLoadHooksTest < ActiveSupport::TestCase assert_equal 1, i end + def test_hook_registered_after_run_with_two_registrations + i = 0 + ActiveSupport.run_load_hooks(:registered_after_with_two, FakeContext.new(2)) + ActiveSupport.run_load_hooks(:registered_after_with_two, FakeContext.new(5)) + assert_equal 0, i + ActiveSupport.on_load(:registered_after_with_two) { i += incr } + assert_equal 7, i + end + + def test_hook_registered_interleaved_run_with_two_registrations + i = 0 + ActiveSupport.run_load_hooks(:registered_interleaved_with_two, FakeContext.new(2)) + assert_equal 0, i + ActiveSupport.on_load(:registered_interleaved_with_two) { i += incr } + assert_equal 2, i + ActiveSupport.run_load_hooks(:registered_interleaved_with_two, FakeContext.new(5)) + assert_equal 7, i + end + def test_hook_receives_a_context i = 0 ActiveSupport.on_load(:contextual) { i += incr } diff --git a/activesupport/test/log_subscriber_test.rb b/activesupport/test/log_subscriber_test.rb index 8e160714b1..2a0e8d20ed 100644 --- a/activesupport/test/log_subscriber_test.rb +++ b/activesupport/test/log_subscriber_test.rb @@ -11,7 +11,7 @@ class MyLogSubscriber < ActiveSupport::LogSubscriber def foo(event) debug "debug" - info "info" + info { "info" } warn "warn" end diff --git a/activesupport/test/buffered_logger_test.rb b/activesupport/test/logger_test.rb index 615635607c..eedeca30a8 100644 --- a/activesupport/test/buffered_logger_test.rb +++ b/activesupport/test/logger_test.rb @@ -3,11 +3,9 @@ require 'multibyte_test_helpers' require 'stringio' require 'fileutils' require 'tempfile' -require 'active_support/testing/deprecation' -class BufferedLoggerTest < ActiveSupport::TestCase +class LoggerTest < ActiveSupport::TestCase include MultibyteTestHelpers - include ActiveSupport::Testing::Deprecation Logger = ActiveSupport::Logger diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb index 90aa13b3e6..ef289692bc 100644 --- a/activesupport/test/multibyte_chars_test.rb +++ b/activesupport/test/multibyte_chars_test.rb @@ -110,7 +110,7 @@ class MultibyteCharsUTF8BehaviourTest < ActiveSupport::TestCase end %w{capitalize downcase lstrip reverse rstrip swapcase upcase}.each do |method| - class_eval(<<-EOTESTS) + class_eval(<<-EOTESTS, __FILE__, __LINE__ + 1) def test_#{method}_bang_should_return_self_when_modifying_wrapped_string chars = ' él piDió Un bUen café ' assert_equal chars.object_id, chars.send("#{method}!").object_id @@ -458,6 +458,15 @@ class MultibyteCharsUTF8BehaviourTest < ActiveSupport::TestCase assert !''.mb_chars.respond_to?(:undefined_method) # Not defined end + def test_method_works_for_proxyed_methods + assert_equal 'll', 'hello'.mb_chars.method(:slice).call(2..3) # Defined on Chars + chars = 'hello'.mb_chars + assert_equal 'Hello', chars.method(:capitalize!).call # Defined on Chars + assert_equal 'Hello', chars + assert_equal 'jello', 'hello'.mb_chars.method(:gsub).call(/h/, 'j') # Defined on String + assert_raise(NameError){ ''.mb_chars.method(:undefined_method) } # Not defined + end + def test_acts_like_string assert 'Bambi'.mb_chars.acts_like_string? end diff --git a/activesupport/test/notifications/evented_notification_test.rb b/activesupport/test/notifications/evented_notification_test.rb new file mode 100644 index 0000000000..f690ad43fc --- /dev/null +++ b/activesupport/test/notifications/evented_notification_test.rb @@ -0,0 +1,87 @@ +require 'abstract_unit' + +module ActiveSupport + module Notifications + class EventedTest < ActiveSupport::TestCase + class Listener + attr_reader :events + + def initialize + @events = [] + end + + def start(name, id, payload) + @events << [:start, name, id, payload] + end + + def finish(name, id, payload) + @events << [:finish, name, id, payload] + end + end + + class ListenerWithTimedSupport < Listener + def call(name, start, finish, id, payload) + @events << [:call, name, start, finish, id, payload] + end + end + + def test_evented_listener + notifier = Fanout.new + listener = Listener.new + notifier.subscribe 'hi', listener + notifier.start 'hi', 1, {} + notifier.start 'hi', 2, {} + notifier.finish 'hi', 2, {} + notifier.finish 'hi', 1, {} + + assert_equal 4, listener.events.length + assert_equal [ + [:start, 'hi', 1, {}], + [:start, 'hi', 2, {}], + [:finish, 'hi', 2, {}], + [:finish, 'hi', 1, {}], + ], listener.events + end + + def test_evented_listener_no_events + notifier = Fanout.new + listener = Listener.new + notifier.subscribe 'hi', listener + notifier.start 'world', 1, {} + assert_equal 0, listener.events.length + end + + def test_listen_to_everything + notifier = Fanout.new + listener = Listener.new + notifier.subscribe nil, listener + notifier.start 'hello', 1, {} + notifier.start 'world', 1, {} + notifier.finish 'world', 1, {} + notifier.finish 'hello', 1, {} + + assert_equal 4, listener.events.length + assert_equal [ + [:start, 'hello', 1, {}], + [:start, 'world', 1, {}], + [:finish, 'world', 1, {}], + [:finish, 'hello', 1, {}], + ], listener.events + end + + def test_evented_listener_priority + notifier = Fanout.new + listener = ListenerWithTimedSupport.new + notifier.subscribe 'hi', listener + + notifier.start 'hi', 1, {} + notifier.finish 'hi', 1, {} + + assert_equal [ + [:start, 'hi', 1, {}], + [:finish, 'hi', 1, {}] + ], listener.events + end + end + end +end diff --git a/activesupport/test/notifications_test.rb b/activesupport/test/notifications_test.rb index fc9fa90d07..bcb393c7bc 100644 --- a/activesupport/test/notifications_test.rb +++ b/activesupport/test/notifications_test.rb @@ -221,13 +221,15 @@ module Notifications assert_equal Hash[:payload => :bar], event.payload end - def test_event_is_parent_based_on_time_frame + def test_event_is_parent_based_on_children time = Time.utc(2009, 01, 01, 0, 0, 1) parent = event(:foo, Time.utc(2009), Time.utc(2009) + 100, random_id, {}) child = event(:foo, time, time + 10, random_id, {}) not_child = event(:foo, time, time + 100, random_id, {}) + parent.children << child + assert parent.parent_of?(child) assert !child.parent_of?(parent) assert !parent.parent_of?(not_child) diff --git a/activesupport/test/number_helper_i18n_test.rb b/activesupport/test/number_helper_i18n_test.rb new file mode 100644 index 0000000000..65aecece71 --- /dev/null +++ b/activesupport/test/number_helper_i18n_test.rb @@ -0,0 +1,156 @@ +require 'abstract_unit' +require 'active_support/number_helper' + +module ActiveSupport + class NumberHelperI18nTest < ActiveSupport::TestCase + include ActiveSupport::NumberHelper + + def setup + I18n.backend.store_translations 'ts', + :number => { + :format => { :precision => 3, :delimiter => ',', :separator => '.', :significant => false, :strip_insignificant_zeros => false }, + :currency => { :format => { :unit => '&$', :format => '%u - %n', :negative_format => '(%u - %n)', :precision => 2 } }, + :human => { + :format => { + :precision => 2, + :significant => true, + :strip_insignificant_zeros => true + }, + :storage_units => { + :format => "%n %u", + :units => { + :byte => "b", + :kb => "k" + } + }, + :decimal_units => { + :format => "%n %u", + :units => { + :deci => {:one => "Tenth", :other => "Tenths"}, + :unit => "u", + :ten => {:one => "Ten", :other => "Tens"}, + :thousand => "t", + :million => "m", + :billion =>"b", + :trillion =>"t" , + :quadrillion =>"q" + } + } + }, + :percentage => { :format => {:delimiter => '', :precision => 2, :strip_insignificant_zeros => true} }, + :precision => { :format => {:delimiter => '', :significant => true} } + }, + :custom_units_for_number_to_human => {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"} + end + + def test_number_to_i18n_currency + assert_equal("&$ - 10.00", number_to_currency(10, :locale => 'ts')) + assert_equal("(&$ - 10.00)", number_to_currency(-10, :locale => 'ts')) + assert_equal("-10.00 - &$", number_to_currency(-10, :locale => 'ts', :format => "%n - %u")) + end + + def test_number_to_currency_with_empty_i18n_store + I18n.backend.store_translations 'empty', {} + + assert_equal("$10.00", number_to_currency(10, :locale => 'empty')) + assert_equal("-$10.00", number_to_currency(-10, :locale => 'empty')) + end + + def test_locale_default_format_has_precedence_over_helper_defaults + I18n.backend.store_translations 'ts', + { :number => { :format => { :separator => ";" } } } + + assert_equal("&$ - 10;00", number_to_currency(10, :locale => 'ts')) + end + + def test_number_to_currency_without_currency_negative_format + I18n.backend.store_translations 'no_negative_format', :number => { + :currency => { :format => { :unit => '@', :format => '%n %u' } } + } + + assert_equal("-10.00 @", number_to_currency(-10, :locale => 'no_negative_format')) + end + + def test_number_with_i18n_precision + #Delimiter was set to "" + assert_equal("10000", number_to_rounded(10000, :locale => 'ts')) + + #Precision inherited and significant was set + assert_equal("1.00", number_to_rounded(1.0, :locale => 'ts')) + end + + def test_number_with_i18n_precision_and_empty_i18n_store + I18n.backend.store_translations 'empty', {} + + assert_equal("123456789.123", number_to_rounded(123456789.123456789, :locale => 'empty')) + assert_equal("1.000", number_to_rounded(1.0000, :locale => 'empty')) + end + + def test_number_with_i18n_delimiter + #Delimiter "," and separator "." + assert_equal("1,000,000.234", number_to_delimited(1000000.234, :locale => 'ts')) + end + + def test_number_with_i18n_delimiter_and_empty_i18n_store + I18n.backend.store_translations 'empty', {} + + assert_equal("1,000,000.234", number_to_delimited(1000000.234, :locale => 'empty')) + end + + def test_number_to_i18n_percentage + # to see if strip_insignificant_zeros is true + assert_equal("1%", number_to_percentage(1, :locale => 'ts')) + # precision is 2, significant should be inherited + assert_equal("1.24%", number_to_percentage(1.2434, :locale => 'ts')) + # no delimiter + assert_equal("12434%", number_to_percentage(12434, :locale => 'ts')) + end + + def test_number_to_i18n_percentage_and_empty_i18n_store + I18n.backend.store_translations 'empty', {} + + assert_equal("1.000%", number_to_percentage(1, :locale => 'empty')) + assert_equal("1.243%", number_to_percentage(1.2434, :locale => 'empty')) + assert_equal("12434.000%", number_to_percentage(12434, :locale => 'empty')) + end + + def test_number_to_i18n_human_size + #b for bytes and k for kbytes + assert_equal("2 k", number_to_human_size(2048, :locale => 'ts')) + assert_equal("42 b", number_to_human_size(42, :locale => 'ts')) + end + + def test_number_to_i18n_human_size_with_empty_i18n_store + I18n.backend.store_translations 'empty', {} + + assert_equal("2 KB", number_to_human_size(2048, :locale => 'empty')) + assert_equal("42 Bytes", number_to_human_size(42, :locale => 'empty')) + end + + def test_number_to_human_with_default_translation_scope + #Using t for thousand + assert_equal "2 t", number_to_human(2000, :locale => 'ts') + #Significant was set to true with precision 2, using b for billion + assert_equal "1.2 b", number_to_human(1234567890, :locale => 'ts') + #Using pluralization (Ten/Tens and Tenth/Tenths) + assert_equal "1 Tenth", number_to_human(0.1, :locale => 'ts') + assert_equal "1.3 Tenth", number_to_human(0.134, :locale => 'ts') + assert_equal "2 Tenths", number_to_human(0.2, :locale => 'ts') + assert_equal "1 Ten", number_to_human(10, :locale => 'ts') + assert_equal "1.2 Ten", number_to_human(12, :locale => 'ts') + assert_equal "2 Tens", number_to_human(20, :locale => 'ts') + end + + def test_number_to_human_with_empty_i18n_store + I18n.backend.store_translations 'empty', {} + + assert_equal "2 Thousand", number_to_human(2000, :locale => 'empty') + assert_equal "1.23 Billion", number_to_human(1234567890, :locale => 'empty') + end + + def test_number_to_human_with_custom_translation_scope + #Significant was set to true with precision 2, with custom translated units + assert_equal "4.3 cm", number_to_human(0.0432, :locale => 'ts', :units => :custom_units_for_number_to_human) + end + end +end diff --git a/activesupport/test/number_helper_test.rb b/activesupport/test/number_helper_test.rb new file mode 100644 index 0000000000..5f54587f93 --- /dev/null +++ b/activesupport/test/number_helper_test.rb @@ -0,0 +1,374 @@ +require 'abstract_unit' +require 'active_support/number_helper' + +module ActiveSupport + module NumberHelper + class NumberHelperTest < ActiveSupport::TestCase + + class TestClassWithInstanceNumberHelpers + include ActiveSupport::NumberHelper + end + + class TestClassWithClassNumberHelpers + extend ActiveSupport::NumberHelper + end + + def setup + @instance_with_helpers = TestClassWithInstanceNumberHelpers.new + end + + def kilobytes(number) + number * 1024 + end + + def megabytes(number) + kilobytes(number) * 1024 + end + + def gigabytes(number) + megabytes(number) * 1024 + end + + def terabytes(number) + gigabytes(number) * 1024 + end + + def test_number_to_phone + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal("555-1234", number_helper.number_to_phone(5551234)) + assert_equal("800-555-1212", number_helper.number_to_phone(8005551212)) + assert_equal("(800) 555-1212", number_helper.number_to_phone(8005551212, {:area_code => true})) + assert_equal("", number_helper.number_to_phone("", {:area_code => true})) + assert_equal("800 555 1212", number_helper.number_to_phone(8005551212, {:delimiter => " "})) + assert_equal("(800) 555-1212 x 123", number_helper.number_to_phone(8005551212, {:area_code => true, :extension => 123})) + assert_equal("800-555-1212", number_helper.number_to_phone(8005551212, :extension => " ")) + assert_equal("555.1212", number_helper.number_to_phone(5551212, :delimiter => '.')) + assert_equal("800-555-1212", number_helper.number_to_phone("8005551212")) + assert_equal("+1-800-555-1212", number_helper.number_to_phone(8005551212, :country_code => 1)) + assert_equal("+18005551212", number_helper.number_to_phone(8005551212, :country_code => 1, :delimiter => '')) + assert_equal("22-555-1212", number_helper.number_to_phone(225551212)) + assert_equal("+45-22-555-1212", number_helper.number_to_phone(225551212, :country_code => 45)) + end + end + + def test_number_to_currency + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal("$1,234,567,890.50", number_helper.number_to_currency(1234567890.50)) + assert_equal("$1,234,567,890.51", number_helper.number_to_currency(1234567890.506)) + assert_equal("-$1,234,567,890.50", number_helper.number_to_currency(-1234567890.50)) + assert_equal("-$ 1,234,567,890.50", number_helper.number_to_currency(-1234567890.50, {:format => "%u %n"})) + assert_equal("($1,234,567,890.50)", number_helper.number_to_currency(-1234567890.50, {:negative_format => "(%u%n)"})) + assert_equal("$1,234,567,892", number_helper.number_to_currency(1234567891.50, {:precision => 0})) + assert_equal("$1,234,567,890.5", number_helper.number_to_currency(1234567890.50, {:precision => 1})) + assert_equal("£1234567890,50", number_helper.number_to_currency(1234567890.50, {:unit => "£", :separator => ",", :delimiter => ""})) + assert_equal("$1,234,567,890.50", number_helper.number_to_currency("1234567890.50")) + assert_equal("1,234,567,890.50 Kč", number_helper.number_to_currency("1234567890.50", {:unit => "Kč", :format => "%n %u"})) + assert_equal("1,234,567,890.50 - Kč", number_helper.number_to_currency("-1234567890.50", {:unit => "Kč", :format => "%n %u", :negative_format => "%n - %u"})) + assert_equal("0.00", number_helper.number_to_currency(+0.0, {:unit => "", :negative_format => "(%n)"})) + assert_equal("(0.00)", number_helper.number_to_currency(-0.0, {:unit => "", :negative_format => "(%n)"})) + end + end + + def test_number_to_percentage + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal("100.000%", number_helper.number_to_percentage(100)) + assert_equal("100%", number_helper.number_to_percentage(100, {:precision => 0})) + assert_equal("302.06%", number_helper.number_to_percentage(302.0574, {:precision => 2})) + assert_equal("100.000%", number_helper.number_to_percentage("100")) + assert_equal("1000.000%", number_helper.number_to_percentage("1000")) + assert_equal("123.4%", number_helper.number_to_percentage(123.400, :precision => 3, :strip_insignificant_zeros => true)) + assert_equal("1.000,000%", number_helper.number_to_percentage(1000, :delimiter => '.', :separator => ',')) + assert_equal("1000.000 %", number_helper.number_to_percentage(1000, :format => "%n %")) + end + end + + def test_to_delimited + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal("12,345,678", number_helper.number_to_delimited(12345678)) + assert_equal("0", number_helper.number_to_delimited(0)) + assert_equal("123", number_helper.number_to_delimited(123)) + assert_equal("123,456", number_helper.number_to_delimited(123456)) + assert_equal("123,456.78", number_helper.number_to_delimited(123456.78)) + assert_equal("123,456.789", number_helper.number_to_delimited(123456.789)) + assert_equal("123,456.78901", number_helper.number_to_delimited(123456.78901)) + assert_equal("123,456,789.78901", number_helper.number_to_delimited(123456789.78901)) + assert_equal("0.78901", number_helper.number_to_delimited(0.78901)) + assert_equal("123,456.78", number_helper.number_to_delimited("123456.78")) + end + end + + def test_to_delimited_with_options_hash + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal '12 345 678', number_helper.number_to_delimited(12345678, :delimiter => ' ') + assert_equal '12,345,678-05', number_helper.number_to_delimited(12345678.05, :separator => '-') + assert_equal '12.345.678,05', number_helper.number_to_delimited(12345678.05, :separator => ',', :delimiter => '.') + assert_equal '12.345.678,05', number_helper.number_to_delimited(12345678.05, :delimiter => '.', :separator => ',') + end + end + + def test_to_rounded + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal("-111.235", number_helper.number_to_rounded(-111.2346)) + assert_equal("111.235", number_helper.number_to_rounded(111.2346)) + assert_equal("31.83", number_helper.number_to_rounded(31.825, :precision => 2)) + assert_equal("111.23", number_helper.number_to_rounded(111.2346, :precision => 2)) + assert_equal("111.00", number_helper.number_to_rounded(111, :precision => 2)) + assert_equal("111.235", number_helper.number_to_rounded("111.2346")) + assert_equal("31.83", number_helper.number_to_rounded("31.825", :precision => 2)) + assert_equal("3268", number_helper.number_to_rounded((32.6751 * 100.00), :precision => 0)) + assert_equal("112", number_helper.number_to_rounded(111.50, :precision => 0)) + assert_equal("1234567892", number_helper.number_to_rounded(1234567891.50, :precision => 0)) + assert_equal("0", number_helper.number_to_rounded(0, :precision => 0)) + assert_equal("0.00100", number_helper.number_to_rounded(0.001, :precision => 5)) + assert_equal("0.001", number_helper.number_to_rounded(0.00111, :precision => 3)) + assert_equal("10.00", number_helper.number_to_rounded(9.995, :precision => 2)) + assert_equal("11.00", number_helper.number_to_rounded(10.995, :precision => 2)) + assert_equal("0.00", number_helper.number_to_rounded(-0.001, :precision => 2)) + end + end + + def test_to_rounded_with_custom_delimiter_and_separator + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal '31,83', number_helper.number_to_rounded(31.825, :precision => 2, :separator => ',') + assert_equal '1.231,83', number_helper.number_to_rounded(1231.825, :precision => 2, :separator => ',', :delimiter => '.') + end + end + + def test_to_rounded_with_significant_digits + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal "124000", number_helper.number_to_rounded(123987, :precision => 3, :significant => true) + assert_equal "120000000", number_helper.number_to_rounded(123987876, :precision => 2, :significant => true ) + assert_equal "40000", number_helper.number_to_rounded("43523", :precision => 1, :significant => true ) + assert_equal "9775", number_helper.number_to_rounded(9775, :precision => 4, :significant => true ) + assert_equal "5.4", number_helper.number_to_rounded(5.3923, :precision => 2, :significant => true ) + assert_equal "5", number_helper.number_to_rounded(5.3923, :precision => 1, :significant => true ) + assert_equal "1", number_helper.number_to_rounded(1.232, :precision => 1, :significant => true ) + assert_equal "7", number_helper.number_to_rounded(7, :precision => 1, :significant => true ) + assert_equal "1", number_helper.number_to_rounded(1, :precision => 1, :significant => true ) + assert_equal "53", number_helper.number_to_rounded(52.7923, :precision => 2, :significant => true ) + assert_equal "9775.00", number_helper.number_to_rounded(9775, :precision => 6, :significant => true ) + assert_equal "5.392900", number_helper.number_to_rounded(5.3929, :precision => 7, :significant => true ) + assert_equal "0.0", number_helper.number_to_rounded(0, :precision => 2, :significant => true ) + assert_equal "0", number_helper.number_to_rounded(0, :precision => 1, :significant => true ) + assert_equal "0.0001", number_helper.number_to_rounded(0.0001, :precision => 1, :significant => true ) + assert_equal "0.000100", number_helper.number_to_rounded(0.0001, :precision => 3, :significant => true ) + assert_equal "0.0001", number_helper.number_to_rounded(0.0001111, :precision => 1, :significant => true ) + assert_equal "10.0", number_helper.number_to_rounded(9.995, :precision => 3, :significant => true) + assert_equal "9.99", number_helper.number_to_rounded(9.994, :precision => 3, :significant => true) + assert_equal "11.0", number_helper.number_to_rounded(10.995, :precision => 3, :significant => true) + end + end + + def test_to_rounded_with_strip_insignificant_zeros + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal "9775.43", number_helper.number_to_rounded(9775.43, :precision => 4, :strip_insignificant_zeros => true ) + assert_equal "9775.2", number_helper.number_to_rounded(9775.2, :precision => 6, :significant => true, :strip_insignificant_zeros => true ) + assert_equal "0", number_helper.number_to_rounded(0, :precision => 6, :significant => true, :strip_insignificant_zeros => true ) + end + end + + def test_to_rounded_with_significant_true_and_zero_precision + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + # Zero precision with significant is a mistake (would always return zero), + # so we treat it as if significant was false (increases backwards compatibility for number_to_human_size) + assert_equal "124", number_helper.number_to_rounded(123.987, :precision => 0, :significant => true) + assert_equal "12", number_helper.number_to_rounded(12, :precision => 0, :significant => true ) + assert_equal "12", number_helper.number_to_rounded("12.3", :precision => 0, :significant => true ) + end + end + + def test_number_number_to_human_size + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal '0 Bytes', number_helper.number_to_human_size(0) + assert_equal '1 Byte', number_helper.number_to_human_size(1) + assert_equal '3 Bytes', number_helper.number_to_human_size(3.14159265) + assert_equal '123 Bytes', number_helper.number_to_human_size(123.0) + assert_equal '123 Bytes', number_helper.number_to_human_size(123) + assert_equal '1.21 KB', number_helper.number_to_human_size(1234) + assert_equal '12.1 KB', number_helper.number_to_human_size(12345) + assert_equal '1.18 MB', number_helper.number_to_human_size(1234567) + assert_equal '1.15 GB', number_helper.number_to_human_size(1234567890) + assert_equal '1.12 TB', number_helper.number_to_human_size(1234567890123) + assert_equal '1030 TB', number_helper.number_to_human_size(terabytes(1026)) + assert_equal '444 KB', number_helper.number_to_human_size(kilobytes(444)) + assert_equal '1020 MB', number_helper.number_to_human_size(megabytes(1023)) + assert_equal '3 TB', number_helper.number_to_human_size(terabytes(3)) + assert_equal '1.2 MB', number_helper.number_to_human_size(1234567, :precision => 2) + assert_equal '3 Bytes', number_helper.number_to_human_size(3.14159265, :precision => 4) + assert_equal '123 Bytes', number_helper.number_to_human_size('123') + assert_equal '1 KB', number_helper.number_to_human_size(kilobytes(1.0123), :precision => 2) + assert_equal '1.01 KB', number_helper.number_to_human_size(kilobytes(1.0100), :precision => 4) + assert_equal '10 KB', number_helper.number_to_human_size(kilobytes(10.000), :precision => 4) + assert_equal '1 Byte', number_helper.number_to_human_size(1.1) + assert_equal '10 Bytes', number_helper.number_to_human_size(10) + end + end + + def test_number_to_human_size_with_si_prefix + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal '3 Bytes', number_helper.number_to_human_size(3.14159265, :prefix => :si) + assert_equal '123 Bytes', number_helper.number_to_human_size(123.0, :prefix => :si) + assert_equal '123 Bytes', number_helper.number_to_human_size(123, :prefix => :si) + assert_equal '1.23 KB', number_helper.number_to_human_size(1234, :prefix => :si) + assert_equal '12.3 KB', number_helper.number_to_human_size(12345, :prefix => :si) + assert_equal '1.23 MB', number_helper.number_to_human_size(1234567, :prefix => :si) + assert_equal '1.23 GB', number_helper.number_to_human_size(1234567890, :prefix => :si) + assert_equal '1.23 TB', number_helper.number_to_human_size(1234567890123, :prefix => :si) + end + end + + def test_number_to_human_size_with_options_hash + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal '1.2 MB', number_helper.number_to_human_size(1234567, :precision => 2) + assert_equal '3 Bytes', number_helper.number_to_human_size(3.14159265, :precision => 4) + assert_equal '1 KB', number_helper.number_to_human_size(kilobytes(1.0123), :precision => 2) + assert_equal '1.01 KB', number_helper.number_to_human_size(kilobytes(1.0100), :precision => 4) + assert_equal '10 KB', number_helper.number_to_human_size(kilobytes(10.000), :precision => 4) + assert_equal '1 TB', number_helper.number_to_human_size(1234567890123, :precision => 1) + assert_equal '500 MB', number_helper.number_to_human_size(524288000, :precision=>3) + assert_equal '10 MB', number_helper.number_to_human_size(9961472, :precision=>0) + assert_equal '40 KB', number_helper.number_to_human_size(41010, :precision => 1) + assert_equal '40 KB', number_helper.number_to_human_size(41100, :precision => 2) + assert_equal '1.0 KB', number_helper.number_to_human_size(kilobytes(1.0123), :precision => 2, :strip_insignificant_zeros => false) + assert_equal '1.012 KB', number_helper.number_to_human_size(kilobytes(1.0123), :precision => 3, :significant => false) + assert_equal '1 KB', number_helper.number_to_human_size(kilobytes(1.0123), :precision => 0, :significant => true) #ignores significant it precision is 0 + end + end + + def test_number_to_human_size_with_custom_delimiter_and_separator + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal '1,01 KB', number_helper.number_to_human_size(kilobytes(1.0123), :precision => 3, :separator => ',') + assert_equal '1,01 KB', number_helper.number_to_human_size(kilobytes(1.0100), :precision => 4, :separator => ',') + assert_equal '1.000,1 TB', number_helper.number_to_human_size(terabytes(1000.1), :precision => 5, :delimiter => '.', :separator => ',') + end + end + + def test_number_to_human + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal '-123', number_helper.number_to_human(-123) + assert_equal '-0.5', number_helper.number_to_human(-0.5) + assert_equal '0', number_helper.number_to_human(0) + assert_equal '0.5', number_helper.number_to_human(0.5) + assert_equal '123', number_helper.number_to_human(123) + assert_equal '1.23 Thousand', number_helper.number_to_human(1234) + assert_equal '12.3 Thousand', number_helper.number_to_human(12345) + assert_equal '1.23 Million', number_helper.number_to_human(1234567) + assert_equal '1.23 Billion', number_helper.number_to_human(1234567890) + assert_equal '1.23 Trillion', number_helper.number_to_human(1234567890123) + assert_equal '1.23 Quadrillion', number_helper.number_to_human(1234567890123456) + assert_equal '1230 Quadrillion', number_helper.number_to_human(1234567890123456789) + assert_equal '490 Thousand', number_helper.number_to_human(489939, :precision => 2) + assert_equal '489.9 Thousand', number_helper.number_to_human(489939, :precision => 4) + assert_equal '489 Thousand', number_helper.number_to_human(489000, :precision => 4) + assert_equal '489.0 Thousand', number_helper.number_to_human(489000, :precision => 4, :strip_insignificant_zeros => false) + assert_equal '1.2346 Million', number_helper.number_to_human(1234567, :precision => 4, :significant => false) + assert_equal '1,2 Million', number_helper.number_to_human(1234567, :precision => 1, :significant => false, :separator => ',') + assert_equal '1 Million', number_helper.number_to_human(1234567, :precision => 0, :significant => true, :separator => ',') #significant forced to false + end + end + + def test_number_to_human_with_custom_units + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + #Only integers + volume = {:unit => "ml", :thousand => "lt", :million => "m3"} + assert_equal '123 lt', number_helper.number_to_human(123456, :units => volume) + assert_equal '12 ml', number_helper.number_to_human(12, :units => volume) + assert_equal '1.23 m3', number_helper.number_to_human(1234567, :units => volume) + + #Including fractionals + distance = {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"} + assert_equal '1.23 mm', number_helper.number_to_human(0.00123, :units => distance) + assert_equal '1.23 cm', number_helper.number_to_human(0.0123, :units => distance) + assert_equal '1.23 dm', number_helper.number_to_human(0.123, :units => distance) + assert_equal '1.23 m', number_helper.number_to_human(1.23, :units => distance) + assert_equal '1.23 dam', number_helper.number_to_human(12.3, :units => distance) + assert_equal '1.23 hm', number_helper.number_to_human(123, :units => distance) + assert_equal '1.23 km', number_helper.number_to_human(1230, :units => distance) + assert_equal '1.23 km', number_helper.number_to_human(1230, :units => distance) + assert_equal '1.23 km', number_helper.number_to_human(1230, :units => distance) + assert_equal '12.3 km', number_helper.number_to_human(12300, :units => distance) + + #The quantifiers don't need to be a continuous sequence + gangster = {:hundred => "hundred bucks", :million => "thousand quids"} + assert_equal '1 hundred bucks', number_helper.number_to_human(100, :units => gangster) + assert_equal '25 hundred bucks', number_helper.number_to_human(2500, :units => gangster) + assert_equal '25 thousand quids', number_helper.number_to_human(25000000, :units => gangster) + assert_equal '12300 thousand quids', number_helper.number_to_human(12345000000, :units => gangster) + + #Spaces are stripped from the resulting string + assert_equal '4', number_helper.number_to_human(4, :units => {:unit => "", :ten => 'tens '}) + assert_equal '4.5 tens', number_helper.number_to_human(45, :units => {:unit => "", :ten => ' tens '}) + end + end + + def test_number_to_human_with_custom_format + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal '123 times Thousand', number_helper.number_to_human(123456, :format => "%n times %u") + volume = {:unit => "ml", :thousand => "lt", :million => "m3"} + assert_equal '123.lt', number_helper.number_to_human(123456, :units => volume, :format => "%n.%u") + end + end + + def test_number_helpers_should_return_nil_when_given_nil + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_nil number_helper.number_to_phone(nil) + assert_nil number_helper.number_to_currency(nil) + assert_nil number_helper.number_to_percentage(nil) + assert_nil number_helper.number_to_delimited(nil) + assert_nil number_helper.number_to_rounded(nil) + assert_nil number_helper.number_to_human_size(nil) + assert_nil number_helper.number_to_human(nil) + end + end + + def test_number_helpers_do_not_mutate_options_hash + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + options = { 'raise' => true } + + number_helper.number_to_phone(1, options) + assert_equal({ 'raise' => true }, options) + + number_helper.number_to_currency(1, options) + assert_equal({ 'raise' => true }, options) + + number_helper.number_to_percentage(1, options) + assert_equal({ 'raise' => true }, options) + + number_helper.number_to_delimited(1, options) + assert_equal({ 'raise' => true }, options) + + number_helper.number_to_rounded(1, options) + assert_equal({ 'raise' => true }, options) + + number_helper.number_to_human_size(1, options) + assert_equal({ 'raise' => true }, options) + + number_helper.number_to_human(1, options) + assert_equal({ 'raise' => true }, options) + end + end + + def test_number_helpers_should_return_non_numeric_param_unchanged + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert_equal("+1-x x 123", number_helper.number_to_phone("x", :country_code => 1, :extension => 123)) + assert_equal("x", number_helper.number_to_phone("x")) + assert_equal("$x.", number_helper.number_to_currency("x.")) + assert_equal("$x", number_helper.number_to_currency("x")) + assert_equal("x%", number_helper.number_to_percentage("x")) + assert_equal("x", number_helper.number_to_delimited("x")) + assert_equal("x.", number_helper.number_to_rounded("x.")) + assert_equal("x", number_helper.number_to_rounded("x")) + assert_equal "x", number_helper.number_to_human_size('x') + assert_equal "x", number_helper.number_to_human('x') + end + end + + def test_extending_or_including_number_helper_correctly_hides_private_methods + [@instance_with_helpers, TestClassWithClassNumberHelpers, ActiveSupport::NumberHelper].each do |number_helper| + assert !number_helper.respond_to?(:valid_float?) + assert number_helper.respond_to?(:valid_float?, true) + end + end + end + end +end diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb index e8defd396b..ac85ba1f21 100644 --- a/activesupport/test/ordered_hash_test.rb +++ b/activesupport/test/ordered_hash_test.rb @@ -226,12 +226,8 @@ class OrderedHashTest < ActiveSupport::TestCase end def test_alternate_initialization_raises_exception_on_odd_length_args - begin + assert_raises ArgumentError do ActiveSupport::OrderedHash[1,2,3,4,5] - flunk "Hash::[] should have raised an exception on initialization " + - "with an odd number of parameters" - rescue ArgumentError => e - assert_equal "odd number of arguments for Hash", e.message end end diff --git a/activesupport/test/ordered_options_test.rb b/activesupport/test/ordered_options_test.rb index 0eee991e20..f60f9a58e3 100644 --- a/activesupport/test/ordered_options_test.rb +++ b/activesupport/test/ordered_options_test.rb @@ -1,4 +1,5 @@ require 'abstract_unit' +require 'active_support/ordered_options' class OrderedOptionsTest < ActiveSupport::TestCase def test_usage @@ -76,4 +77,12 @@ class OrderedOptionsTest < ActiveSupport::TestCase assert copy.kind_of?(original.class) assert_not_equal copy.object_id, original.object_id end + + def test_introspection + a = ActiveSupport::OrderedOptions.new + assert a.respond_to?(:blah) + assert a.respond_to?(:blah=) + assert_equal 42, a.method(:blah=).call(42) + assert_equal 42, a.method(:blah).call + end end diff --git a/activesupport/test/queueing/container_test.rb b/activesupport/test/queueing/container_test.rb new file mode 100644 index 0000000000..7afc11e7a9 --- /dev/null +++ b/activesupport/test/queueing/container_test.rb @@ -0,0 +1,28 @@ +require 'abstract_unit' +require 'active_support/queueing' + +module ActiveSupport + class ContainerTest < ActiveSupport::TestCase + def test_delegates_to_default + q = Queue.new + container = QueueContainer.new q + job = Object.new + + container.push job + assert_equal job, q.pop + end + + def test_access_default + q = Queue.new + container = QueueContainer.new q + assert_equal q, container[:default] + end + + def test_assign_queue + container = QueueContainer.new Object.new + q = Object.new + container[:foo] = q + assert_equal q, container[:foo] + end + end +end diff --git a/activesupport/test/queueing/synchronous_queue_test.rb b/activesupport/test/queueing/synchronous_queue_test.rb new file mode 100644 index 0000000000..86c39d0f6c --- /dev/null +++ b/activesupport/test/queueing/synchronous_queue_test.rb @@ -0,0 +1,27 @@ +require 'abstract_unit' +require 'active_support/queueing' + +class SynchronousQueueTest < ActiveSupport::TestCase + class Job + attr_reader :ran + def run; @ran = true end + end + + class ExceptionRaisingJob + def run; raise end + end + + def setup + @queue = ActiveSupport::SynchronousQueue.new + end + + def test_runs_jobs_immediately + job = Job.new + @queue.push job + assert job.ran + + assert_raises RuntimeError do + @queue.push ExceptionRaisingJob.new + end + end +end diff --git a/activesupport/test/queueing/test_queue_test.rb b/activesupport/test/queueing/test_queue_test.rb new file mode 100644 index 0000000000..e398a48bea --- /dev/null +++ b/activesupport/test/queueing/test_queue_test.rb @@ -0,0 +1,102 @@ +require 'abstract_unit' +require 'active_support/queueing' + +class TestQueueTest < ActiveSupport::TestCase + def setup + @queue = ActiveSupport::TestQueue.new + end + + class ExceptionRaisingJob + def run + raise + end + end + + def test_drain_raises_exceptions_from_running_jobs + @queue.push ExceptionRaisingJob.new + assert_raises(RuntimeError) { @queue.drain } + end + + def test_jobs + @queue.push 1 + @queue.push 2 + assert_equal [1,2], @queue.jobs + end + + class EquivalentJob + def initialize + @initial_id = self.object_id + end + + def run + end + + def ==(other) + other.same_initial_id?(@initial_id) + end + + def same_initial_id?(other_id) + other_id == @initial_id + end + end + + def test_contents + job = EquivalentJob.new + assert @queue.empty? + @queue.push job + refute @queue.empty? + assert_equal job, @queue.pop + end + + class ProcessingJob + def self.clear_processed + @processed = [] + end + + def self.processed + @processed + end + + def initialize(object) + @object = object + end + + def run + self.class.processed << @object + end + end + + def test_order + ProcessingJob.clear_processed + job1 = ProcessingJob.new(1) + job2 = ProcessingJob.new(2) + + @queue.push job1 + @queue.push job2 + @queue.drain + + assert_equal [1,2], ProcessingJob.processed + end + + class ThreadTrackingJob + attr_reader :thread_id + + def run + @thread_id = Thread.current.object_id + end + + def ran? + @thread_id + end + end + + def test_drain + @queue.push ThreadTrackingJob.new + job = @queue.jobs.last + @queue.drain + + assert @queue.empty? + assert job.ran?, "The job runs synchronously when the queue is drained" + assert_equal job.thread_id, Thread.current.object_id + end +end diff --git a/activesupport/test/queueing/threaded_consumer_test.rb b/activesupport/test/queueing/threaded_consumer_test.rb new file mode 100644 index 0000000000..fc43cb555a --- /dev/null +++ b/activesupport/test/queueing/threaded_consumer_test.rb @@ -0,0 +1,92 @@ +require 'abstract_unit' +require 'active_support/queueing' +require "active_support/log_subscriber/test_helper" + +class TestThreadConsumer < ActiveSupport::TestCase + class Job + attr_reader :id + def initialize(id = 1, &block) + @id = id + @block = block + end + + def run + @block.call if @block + end + end + + def setup + @logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new + @queue = ActiveSupport::Queue.new(logger: @logger) + end + + def teardown + @queue.drain + end + + test "the jobs are executed" do + ran = false + job = Job.new { ran = true } + + @queue.push job + @queue.drain + + assert_equal true, ran + end + + test "the jobs are not executed synchronously" do + run, ran = Queue.new, Queue.new + job = Job.new { ran.push run.pop } + + @queue.consumer.start + @queue.push job + assert ran.empty? + + run.push true + assert_equal true, ran.pop + end + + test "shutting down the queue synchronously drains the jobs" do + ran = false + job = Job.new do + sleep 0.1 + ran = true + end + + @queue.consumer.start + @queue.push job + assert_equal false, ran + + @queue.consumer.shutdown + assert_equal true, ran + end + + test "log job that raises an exception" do + job = Job.new { raise "RuntimeError: Error!" } + + @queue.push job + @queue.drain + + assert_equal 1, @logger.logged(:error).size + assert_match 'Job Error: RuntimeError: Error!', @logger.logged(:error).last + end + + test "test overriding exception handling" do + @queue.consumer.instance_eval do + def handle_exception(job, exception) + @last_error = exception.message + end + + def last_error + @last_error + end + end + + job = Job.new { raise "RuntimeError: Error!" } + + @queue.push job + @queue.drain + + assert_equal "RuntimeError: Error!", @queue.consumer.last_error + end +end diff --git a/activesupport/test/safe_buffer_test.rb b/activesupport/test/safe_buffer_test.rb index bdde5141a9..047b89be2a 100644 --- a/activesupport/test/safe_buffer_test.rb +++ b/activesupport/test/safe_buffer_test.rb @@ -84,13 +84,13 @@ class SafeBufferTest < ActiveSupport::TestCase assert_equal "hello<>", clean + @buffer end - test "Should concat as a normal string when dirty" do + test "Should concat as a normal string when safe" do clean = "hello".html_safe @buffer.gsub!('', '<>') assert_equal "<>hello", @buffer + clean end - test "Should preserve dirty? status on copy" do + test "Should preserve html_safe? status on copy" do @buffer.gsub!('', '<>') assert !@buffer.dup.html_safe? end @@ -102,20 +102,42 @@ class SafeBufferTest < ActiveSupport::TestCase assert_equal "<script>", result_buffer end - test "Should raise an error when safe_concat is called on dirty buffers" do + test "Should raise an error when safe_concat is called on unsafe buffers" do @buffer.gsub!('', '<>') assert_raise ActiveSupport::SafeBuffer::SafeConcatError do @buffer.safe_concat "BUSTED" end end - test "should not fail if the returned object is not a string" do + test "Should not fail if the returned object is not a string" do assert_kind_of NilClass, @buffer.slice("chipchop") end - test "Should initialize @dirty to false for new instance when sliced" do - dirty = @buffer[0,0].send(:dirty?) - assert_not_nil dirty - assert !dirty + test "clone_empty returns an empty buffer" do + assert_equal '', ActiveSupport::SafeBuffer.new('foo').clone_empty + end + + test "clone_empty keeps the original dirtyness" do + assert @buffer.clone_empty.html_safe? + assert !@buffer.gsub!('', '').clone_empty.html_safe? + end + + test "Should be safe when sliced if original value was safe" do + new_buffer = @buffer[0,0] + assert_not_nil new_buffer + assert new_buffer.html_safe?, "should be safe" + end + + test "Should continue unsafe on slice" do + x = 'foo'.html_safe.gsub!('f', '<script>alert("lolpwnd");</script>') + + # calling gsub! makes the dirty flag true + assert !x.html_safe?, "should not be safe" + + # getting a slice of it + y = x[0..-1] + + # should still be unsafe + assert !y.html_safe?, "should not be safe" end end diff --git a/activesupport/test/string_inquirer_test.rb b/activesupport/test/string_inquirer_test.rb index bb15916e9e..94d5fe197d 100644 --- a/activesupport/test/string_inquirer_test.rb +++ b/activesupport/test/string_inquirer_test.rb @@ -1,15 +1,23 @@ require 'abstract_unit' class StringInquirerTest < ActiveSupport::TestCase + def setup + @string_inquirer = ActiveSupport::StringInquirer.new('production') + end + def test_match - assert ActiveSupport::StringInquirer.new("production").production? + assert @string_inquirer.production? end def test_miss - assert !ActiveSupport::StringInquirer.new("production").development? + refute @string_inquirer.development? end def test_missing_question_mark - assert_raise(NoMethodError) { ActiveSupport::StringInquirer.new("production").production } + assert_raise(NoMethodError) { @string_inquirer.production } + end + + def test_respond_to + assert_respond_to @string_inquirer, :development? end end diff --git a/activesupport/test/tagged_logging_test.rb b/activesupport/test/tagged_logging_test.rb index dd4ae319e5..43cf1a8e4f 100644 --- a/activesupport/test/tagged_logging_test.rb +++ b/activesupport/test/tagged_logging_test.rb @@ -18,7 +18,7 @@ class TaggedLoggingTest < ActiveSupport::TestCase @logger.tagged("BCX") { @logger.info "Funky time" } assert_equal "[BCX] Funky time\n", @output.string end - + test "tagged twice" do @logger.tagged("BCX") { @logger.tagged("Jason") { @logger.info "Funky time" } } assert_equal "[BCX] [Jason] Funky time\n", @output.string @@ -29,6 +29,16 @@ class TaggedLoggingTest < ActiveSupport::TestCase assert_equal "[BCX] [Jason] [New] Funky time\n", @output.string end + test "does not strip message content" do + @logger.info " Hello" + assert_equal " Hello\n", @output.string + end + + test "provides access to the logger instance" do + @logger.tagged("BCX") { |logger| logger.info "Funky time" } + assert_equal "[BCX] Funky time\n", @output.string + end + test "tagged once with blank and nil" do @logger.tagged(nil, "", "New") { @logger.info "Funky time" } assert_equal "[New] Funky time\n", @output.string diff --git a/activesupport/test/test_case_test.rb b/activesupport/test/test_case_test.rb index e5b5547478..c02bfa8497 100644 --- a/activesupport/test/test_case_test.rb +++ b/activesupport/test/test_case_test.rb @@ -18,11 +18,9 @@ module ActiveSupport end end - def test_callback_with_exception + def test_standard_error_raised_within_setup_callback_is_puked tc = Class.new(TestCase) do - def self.name - nil - end + def self.name; nil; end setup :bad_callback def bad_callback; raise 'oh noes' end @@ -41,11 +39,9 @@ module ActiveSupport assert_equal 'oh noes', exception.message end - def test_teardown_callback_with_exception + def test_standard_error_raised_within_teardown_callback_is_puked tc = Class.new(TestCase) do - def self.name - nil - end + def self.name; nil; end teardown :bad_callback def bad_callback; raise 'oh noes' end @@ -63,5 +59,51 @@ module ActiveSupport assert_equal test_name, name assert_equal 'oh noes', exception.message end + + def test_passthrough_exception_raised_within_test_method_is_not_rescued + tc = Class.new(TestCase) do + def self.name; nil; end + + def test_which_raises_interrupt; raise Interrupt; end + end + + test_name = 'test_which_raises_interrupt' + fr = FakeRunner.new + + test = tc.new test_name + assert_raises(Interrupt) { test.run fr } + end + + def test_passthrough_exception_raised_within_setup_callback_is_not_rescued + tc = Class.new(TestCase) do + def self.name; nil; end + + setup :callback_which_raises_interrupt + def callback_which_raises_interrupt; raise Interrupt; end + def test_true; assert true end + end + + test_name = 'test_true' + fr = FakeRunner.new + + test = tc.new test_name + assert_raises(Interrupt) { test.run fr } + end + + def test_passthrough_exception_raised_within_teardown_callback_is_not_rescued + tc = Class.new(TestCase) do + def self.name; nil; end + + teardown :callback_which_raises_interrupt + def callback_which_raises_interrupt; raise Interrupt; end + def test_true; assert true end + end + + test_name = 'test_true' + fr = FakeRunner.new + + test = tc.new test_name + assert_raises(Interrupt) { test.run fr } + end end end diff --git a/activesupport/test/test_test.rb b/activesupport/test/test_test.rb index 11506554a9..2473cec384 100644 --- a/activesupport/test/test_test.rb +++ b/activesupport/test/test_test.rb @@ -15,68 +15,64 @@ class AssertDifferenceTest < ActiveSupport::TestCase @object.num = 0 end - if lambda { }.respond_to?(:binding) - def test_assert_no_difference - assert_no_difference '@object.num' do - # ... - end + def test_assert_no_difference + assert_no_difference '@object.num' do + # ... end + end - def test_assert_difference - assert_difference '@object.num', +1 do - @object.increment - end + def test_assert_difference + assert_difference '@object.num', +1 do + @object.increment end + end - def test_assert_difference_with_implicit_difference - assert_difference '@object.num' do - @object.increment - end + def test_assert_difference_with_implicit_difference + assert_difference '@object.num' do + @object.increment end + end - def test_arbitrary_expression - assert_difference '@object.num + 1', +2 do - @object.increment - @object.increment - end + def test_arbitrary_expression + assert_difference '@object.num + 1', +2 do + @object.increment + @object.increment end + end - def test_negative_differences - assert_difference '@object.num', -1 do - @object.decrement - end + def test_negative_differences + assert_difference '@object.num', -1 do + @object.decrement end + end - def test_expression_is_evaluated_in_the_appropriate_scope - silence_warnings do - local_scope = local_scope = 'foo' - assert_difference('local_scope; @object.num') { @object.increment } - end + def test_expression_is_evaluated_in_the_appropriate_scope + silence_warnings do + local_scope = local_scope = 'foo' + assert_difference('local_scope; @object.num') { @object.increment } end + end - def test_array_of_expressions - assert_difference [ '@object.num', '@object.num + 1' ], +1 do - @object.increment - end + def test_array_of_expressions + assert_difference [ '@object.num', '@object.num + 1' ], +1 do + @object.increment end + end - def test_array_of_expressions_identify_failure - assert_raises(MiniTest::Assertion) do - assert_difference ['@object.num', '1 + 1'] do - @object.increment - end + def test_array_of_expressions_identify_failure + assert_raises(MiniTest::Assertion) do + assert_difference ['@object.num', '1 + 1'] do + @object.increment end end + end - def test_array_of_expressions_identify_failure_when_message_provided - assert_raises(MiniTest::Assertion) do - assert_difference ['@object.num', '1 + 1'], 1, 'something went wrong' do - @object.increment - end + def test_array_of_expressions_identify_failure_when_message_provided + assert_raises(MiniTest::Assertion) do + assert_difference ['@object.num', '1 + 1'], 1, 'something went wrong' do + @object.increment end end - else - def default_test; end end end diff --git a/activesupport/test/testing/performance_test.rb b/activesupport/test/testing/performance_test.rb new file mode 100644 index 0000000000..53073cb8db --- /dev/null +++ b/activesupport/test/testing/performance_test.rb @@ -0,0 +1,59 @@ +require 'abstract_unit' +require 'active_support/testing/performance' + + +module ActiveSupport + module Testing + class PerformanceTest < ActiveSupport::TestCase + def test_amount_format + amount_metric = ActiveSupport::Testing::Performance::Metrics[:amount].new + assert_equal "0", amount_metric.format(0) + assert_equal "1", amount_metric.format(1.23) + assert_equal "40,000,000", amount_metric.format(40000000) + end + + def test_time_format + time_metric = ActiveSupport::Testing::Performance::Metrics[:time].new + assert_equal "0 ms", time_metric.format(0) + assert_equal "40 ms", time_metric.format(0.04) + assert_equal "41 ms", time_metric.format(0.0415) + assert_equal "1.23 sec", time_metric.format(1.23) + assert_equal "40000.00 sec", time_metric.format(40000) + assert_equal "-5000 ms", time_metric.format(-5) + end + + def test_space_format + space_metric = ActiveSupport::Testing::Performance::Metrics[:digital_information_unit].new + assert_equal "0 Bytes", space_metric.format(0) + assert_equal "0 Bytes", space_metric.format(0.4) + assert_equal "1 Byte", space_metric.format(1.23) + assert_equal "123 Bytes", space_metric.format(123) + assert_equal "123 Bytes", space_metric.format(123.45) + assert_equal "12 KB", space_metric.format(12345) + assert_equal "1.2 MB", space_metric.format(1234567) + assert_equal "9.3 GB", space_metric.format(10**10) + assert_equal "91 TB", space_metric.format(10**14) + assert_equal "910000 TB", space_metric.format(10**18) + end + + def test_environment_format_without_rails + metric = ActiveSupport::Testing::Performance::Metrics[:time].new + benchmarker = ActiveSupport::Testing::Performance::Benchmarker.new(self, metric) + assert_equal "#{RUBY_ENGINE}-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL},#{RUBY_PLATFORM}", benchmarker.environment + end + + def test_environment_format_with_rails + rails, version = Module.new, Module.new + version.const_set :STRING, "4.0.0" + rails.const_set :VERSION, version + Object.const_set :Rails, rails + + metric = ActiveSupport::Testing::Performance::Metrics[:time].new + benchmarker = ActiveSupport::Testing::Performance::Benchmarker.new(self, metric) + assert_equal "rails-4.0.0,#{RUBY_ENGINE}-#{RUBY_VERSION}.#{RUBY_PATCHLEVEL},#{RUBY_PLATFORM}", benchmarker.environment + ensure + Object.send :remove_const, :Rails + end + end + end +end
\ No newline at end of file diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb index e26256f9c6..bfd6863e40 100644 --- a/activesupport/test/time_zone_test.rb +++ b/activesupport/test/time_zone_test.rb @@ -48,8 +48,8 @@ class TimeZoneTest < ActiveSupport::TestCase def test_now with_env_tz 'US/Eastern' do - Time.stubs(:now).returns(Time.local(2000)) - zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'].dup + def zone.time_now; Time.local(2000); end assert_instance_of ActiveSupport::TimeWithZone, zone.now assert_equal Time.utc(2000,1,1,5), zone.now.utc assert_equal Time.utc(2000), zone.now.time @@ -59,8 +59,11 @@ class TimeZoneTest < ActiveSupport::TestCase def test_now_enforces_spring_dst_rules with_env_tz 'US/Eastern' do - Time.stubs(:now).returns(Time.local(2006,4,2,2)) # 2AM springs forward to 3AM - zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'].dup + def zone.time_now + Time.local(2006,4,2,2) # 2AM springs forward to 3AM + end + assert_equal Time.utc(2006,4,2,3), zone.now.time assert_equal true, zone.now.dst? end @@ -68,8 +71,10 @@ class TimeZoneTest < ActiveSupport::TestCase def test_now_enforces_fall_dst_rules with_env_tz 'US/Eastern' do - Time.stubs(:now).returns(Time.at(1162098000)) # equivalent to 1AM DST - zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'] + zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)'].dup + def zone.time_now + Time.at(1162098000) # equivalent to 1AM DST + end assert_equal Time.utc(2006,10,29,1), zone.now.time assert_equal true, zone.now.dst? end @@ -198,6 +203,24 @@ class TimeZoneTest < ActiveSupport::TestCase assert_equal Time.utc(1999,12,31,19), twz.time end + def test_parse_should_not_black_out_system_timezone_dst_jump + zone = ActiveSupport::TimeZone['Pacific Time (US & Canada)'] + zone.stubs(:now).returns(zone.now) + Time.stubs(:parse).with('2012-03-25 03:29', zone.now). + returns(Time.local(0,29,4,25,3,2012,nil,nil,true,"+03:00")) + twz = zone.parse('2012-03-25 03:29') + assert_equal [0, 29, 3, 25, 3, 2012], twz.to_a[0,6] + end + + def test_parse_should_black_out_app_timezone_dst_jump + zone = ActiveSupport::TimeZone['Pacific Time (US & Canada)'] + zone.stubs(:now).returns(zone.now) + Time.stubs(:parse).with('2012-03-11 02:29', zone.now). + returns(Time.local(0,29,2,11,3,2012,nil,nil,false,"+02:00")) + twz = zone.parse('2012-03-11 02:29') + assert_equal [0, 29, 3, 11, 3, 2012], twz.to_a[0,6] + end + def test_utc_offset_lazy_loaded_from_tzinfo_when_not_passed_in_to_initialize tzinfo = TZInfo::Timezone.get('America/New_York') zone = ActiveSupport::TimeZone.create(tzinfo.name, nil, tzinfo) @@ -235,6 +258,14 @@ class TimeZoneTest < ActiveSupport::TestCase assert_equal "-0500", zone.formatted_offset(false) end + def test_z_format_strings + zone = ActiveSupport::TimeZone['Tokyo'] + twz = zone.now + assert_equal '+0900', twz.strftime('%z') + assert_equal '+09:00', twz.strftime('%:z') + assert_equal '+09:00:00', twz.strftime('%::z') + end + def test_formatted_offset_zero zone = ActiveSupport::TimeZone['London'] assert_equal "+00:00", zone.formatted_offset diff --git a/activesupport/test/transliterate_test.rb b/activesupport/test/transliterate_test.rb index b7076e9e58..b5d8142458 100644 --- a/activesupport/test/transliterate_test.rb +++ b/activesupport/test/transliterate_test.rb @@ -1,7 +1,6 @@ # encoding: utf-8 require 'abstract_unit' require 'active_support/inflector/transliterate' -require 'active_support/core_ext/object/inclusion' class TransliterateTest < ActiveSupport::TestCase @@ -16,7 +15,7 @@ class TransliterateTest < ActiveSupport::TestCase # create string with range of Unicode"s western characters with # diacritics, excluding the division and multiplication signs which for # some reason or other are floating in the middle of all the letters. - string = (0xC0..0x17E).to_a.reject {|c| c.in?([0xD7, 0xF7])}.pack("U*") + string = (0xC0..0x17E).to_a.reject {|c| [0xD7, 0xF7].include?(c)}.pack("U*") string.each_char do |char| assert_match %r{^[a-zA-Z']*$}, ActiveSupport::Inflector.transliterate(string) end diff --git a/activesupport/test/ts_isolated.rb b/activesupport/test/ts_isolated.rb index 1d96c20bb6..2c217157d3 100644 --- a/activesupport/test/ts_isolated.rb +++ b/activesupport/test/ts_isolated.rb @@ -1,5 +1,3 @@ -$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib') - require 'minitest/autorun' require 'active_support/test_case' require 'rbconfig' @@ -12,7 +10,7 @@ class TestIsolated < ActiveSupport::TestCase define_method("test #{file}") do command = "#{ruby} -Ilib:test #{file}" result = silence_stderr { `#{command}` } - assert_block("#{command}\n#{result}") { $?.to_i.zero? } + assert $?.to_i.zero?, "#{command}\n#{result}" end end end |