diff options
Diffstat (limited to 'activesupport')
17 files changed, 271 insertions, 161 deletions
diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index 46ca9f93df..b6c8be37c5 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -39,7 +39,6 @@ require 'active_support/cache' require 'active_support/dependencies' require 'active_support/deprecation' -require 'active_support/typed_array' require 'active_support/ordered_hash' require 'active_support/ordered_options' require 'active_support/option_merger' diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb index cedc1afe7f..6553d72b4f 100644 --- a/activesupport/lib/active_support/buffered_logger.rb +++ b/activesupport/lib/active_support/buffered_logger.rb @@ -33,11 +33,10 @@ module ActiveSupport attr_accessor :level attr_reader :auto_flushing - attr_reader :buffer def initialize(log, level = DEBUG) @level = level - @buffer = [] + @buffer = {} @auto_flushing = 1 @guard = Mutex.new @@ -60,9 +59,7 @@ module ActiveSupport # If a newline is necessary then create a new message ending with a newline. # Ensures that the original message is not mutated. message = "#{message}\n" unless message[-1] == ?\n - @guard.synchronize do - buffer << message - end + buffer << message auto_flush message end @@ -96,8 +93,8 @@ module ActiveSupport def flush @guard.synchronize do unless buffer.empty? - old_buffer = @buffer - @buffer = [] + old_buffer = buffer + clear_buffer @log.write(old_buffer.join) end end @@ -113,5 +110,13 @@ module ActiveSupport def auto_flush flush if buffer.size >= @auto_flushing end + + def buffer + @buffer[Thread.current] ||= [] + end + + def clear_buffer + @buffer[Thread.current] = [] + end end end diff --git a/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb b/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb index 9470ac9f66..0bff6cf9ad 100644 --- a/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb @@ -1,14 +1,14 @@ module ActiveSupport module Cache class CompressedMemCacheStore < MemCacheStore - def read(name, options = {}) - if value = super(name, options.merge(:raw => true)) + def read(name, options = nil) + if value = super(name, (options || {}).merge(:raw => true)) Marshal.load(ActiveSupport::Gzip.decompress(value)) end end - def write(name, value, options = {}) - super(name, ActiveSupport::Gzip.compress(Marshal.dump(value)), options.merge(:raw => true)) + def write(name, value, options = nil) + super(name, ActiveSupport::Gzip.compress(Marshal.dump(value)), (options || {}).merge(:raw => true)) end end end diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index 7b6ca39091..659bde64f0 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -9,15 +9,15 @@ module ActiveSupport def read(name, options = nil) super - File.open(real_file_path(name), 'rb') { |f| f.read } rescue nil + File.open(real_file_path(name), 'rb') { |f| Marshal.load(f) } rescue nil end def write(name, value, options = nil) super ensure_cache_path(File.dirname(real_file_path(name))) - File.atomic_write(real_file_path(name), cache_path) { |f| f.write(value) } + File.atomic_write(real_file_path(name), cache_path) { |f| Marshal.dump(value, f) } rescue => e - RAILS_DEFAULT_LOGGER.error "Couldn't create cache directory: #{name} (#{e.message})" if RAILS_DEFAULT_LOGGER + logger.error "Couldn't create cache directory: #{name} (#{e.message})" if logger end def delete(name, options = nil) @@ -67,4 +67,4 @@ module ActiveSupport end end end -end
\ No newline at end of file +end diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb index a44f877414..f3e4b8c13b 100644 --- a/activesupport/lib/active_support/cache/memory_store.rb +++ b/activesupport/lib/active_support/cache/memory_store.rb @@ -3,51 +3,63 @@ module ActiveSupport class MemoryStore < Store def initialize @data = {} - @mutex = Mutex.new + @guard = Monitor.new end def fetch(key, options = {}) - @mutex.synchronize do + @guard.synchronize do super end end def read(name, options = nil) - super - @data[name] + @guard.synchronize do + super + @data[name] + end end def write(name, value, options = nil) - super - @data[name] = value + @guard.synchronize do + super + @data[name] = value.freeze + end end def delete(name, options = nil) - @data.delete(name) + @guard.synchronize do + @data.delete(name) + end end def delete_matched(matcher, options = nil) - @data.delete_if { |k,v| k =~ matcher } + @guard.synchronize do + @data.delete_if { |k,v| k =~ matcher } + end end def exist?(name,options = nil) - @data.has_key?(name) + @guard.synchronize do + @data.has_key?(name) + end end def increment(key, amount = 1) - @mutex.synchronize do + @guard.synchronize do super end end def decrement(key, amount = 1) - @mutex.synchronize do + @guard.synchronize do super end end def clear - @data.clear + @guard.synchronize do + @data.clear + end end end end diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 9c59b7ac76..7b905930bb 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -96,15 +96,12 @@ module ActiveSupport end end - def |(chain) - if chain.is_a?(CallbackChain) - chain.each { |callback| self | callback } + # TODO: Decompose into more Array like behavior + def replace_or_append!(chain) + if index = index(chain) + self[index] = chain else - if (found_callback = find(chain)) && (index = index(chain)) - self[index] = chain - else - self << chain - end + self << chain end self end @@ -157,6 +154,14 @@ module ActiveSupport self.class.new(@kind, @method, @options.dup) end + def hash + if @identifier + @identifier.hash + else + @method.hash + end + end + def call(*args, &block) evaluate_method(method, *args, &block) if should_run_callback?(*args) rescue LocalJumpError diff --git a/activesupport/lib/active_support/core_ext/kernel/debugger.rb b/activesupport/lib/active_support/core_ext/kernel/debugger.rb index c74d6cf884..4007a647be 100644 --- a/activesupport/lib/active_support/core_ext/kernel/debugger.rb +++ b/activesupport/lib/active_support/core_ext/kernel/debugger.rb @@ -2,12 +2,12 @@ module Kernel unless respond_to?(:debugger) # Starts a debugging session if ruby-debug has been loaded (call script/server --debugger to do load it). def debugger - RAILS_DEFAULT_LOGGER.info "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n" + Rails.logger.info "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n" end end - + def breakpoint - RAILS_DEFAULT_LOGGER.info "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n" + Rails.logger.info "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n" debugger end -end
\ No newline at end of file +end diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index a3f5f799a2..3d871eec11 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -39,6 +39,10 @@ module ActiveSupport #:nodoc: mattr_accessor :explicitly_unloadable_constants self.explicitly_unloadable_constants = [] + # The logger is used for generating information on the action run-time (including benchmarking) if available. + # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers. + mattr_accessor :logger + # Set to true to enable logging of const_missing and file loads mattr_accessor :log_activity self.log_activity = false @@ -584,7 +588,7 @@ module ActiveSupport #:nodoc: protected def log_call(*args) - if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER && log_activity + if logger && log_activity arg_str = args.collect { |arg| arg.inspect } * ', ' /in `([a-z_\?\!]+)'/ =~ caller(1).first selector = $1 || '<unknown>' @@ -593,8 +597,8 @@ module ActiveSupport #:nodoc: end def log(msg) - if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER && log_activity - RAILS_DEFAULT_LOGGER.debug "Dependencies: #{msg}" + if logger && log_activity + logger.debug "Dependencies: #{msg}" end end end diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb index e6049d9496..6506238ac0 100644 --- a/activesupport/lib/active_support/memoizable.rb +++ b/activesupport/lib/active_support/memoizable.rb @@ -10,25 +10,37 @@ module ActiveSupport end def freeze_with_memoizable - unless frozen? - methods.each do |method| - if method.to_s =~ /^_unmemoized_(.*)/ - begin - __send__($1) - rescue ArgumentError - end + memoize_all unless frozen? + freeze_without_memoizable + end + + def memoize_all + methods.each do |m| + if m.to_s =~ /^_unmemoized_(.*)/ + if method(m).arity == 0 + __send__($1) + else + ivar = :"@_memoized_#{$1}" + instance_variable_set(ivar, {}) end end end + end - freeze_without_memoizable + def unmemoize_all + methods.each do |m| + if m.to_s =~ /^_unmemoized_(.*)/ + ivar = :"@_memoized_#{$1}" + instance_variable_get(ivar).clear if instance_variable_defined?(ivar) + end + end end end def memoize(*symbols) symbols.each do |symbol| - original_method = "_unmemoized_#{symbol}" - memoized_ivar = "@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}" + original_method = :"_unmemoized_#{symbol}" + memoized_ivar = :"@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}" class_eval <<-EOS, __FILE__, __LINE__ include Freezable @@ -38,21 +50,24 @@ module ActiveSupport if instance_method(:#{symbol}).arity == 0 def #{symbol}(reload = false) - if !reload && defined? #{memoized_ivar} - #{memoized_ivar} - else - #{memoized_ivar} = #{original_method}.freeze + if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? + #{memoized_ivar} = [#{original_method}.freeze] end + #{memoized_ivar}[0] end else def #{symbol}(*args) - #{memoized_ivar} ||= {} + #{memoized_ivar} ||= {} unless frozen? reload = args.pop if args.last == true || args.last == :reload - if !reload && #{memoized_ivar} && #{memoized_ivar}.has_key?(args) - #{memoized_ivar}[args] + if #{memoized_ivar} + if !reload && #{memoized_ivar}.has_key?(args) + #{memoized_ivar}[args] + elsif #{memoized_ivar} + #{memoized_ivar}[args] = #{original_method}(*args).freeze + end else - #{memoized_ivar}[args] = #{original_method}(*args).freeze + #{original_method}(*args) end end end diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index 70a7f84023..3ad7289571 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -25,7 +25,7 @@ module ActiveSupport def self.included(base) base.class_inheritable_hash :profile_options - base.profile_options = DEFAULTS.dup + base.profile_options = DEFAULTS end def full_test_name @@ -34,6 +34,7 @@ module ActiveSupport def run(result) return if method_name =~ /^default_test$/ + self.profile_options ||= DEFAULTS yield(self.class::STARTED, name) @_result = result @@ -43,8 +44,6 @@ module ActiveSupport if klass = Metrics[metric_name.to_sym] run_profile(klass.new) result.add_run - else - $stderr.puts '%20s: unsupported' % metric_name.to_s end end @@ -164,7 +163,14 @@ module ActiveSupport end class Profiler < Performer + def initialize(*args) + super + @supported = @metric.measure_mode rescue false + end + def run + return unless @supported + RubyProf.measure_mode = @metric.measure_mode RubyProf.start RubyProf.pause @@ -173,7 +179,17 @@ module ActiveSupport @total = @data.threads.values.sum(0) { |method_infos| method_infos.sort.last.total_time } end + def report + if @supported + super + else + '%20s: unsupported' % @metric.name + end + end + def record + return unless @supported + klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact klasses.each do |klass| @@ -202,8 +218,7 @@ module ActiveSupport module Metrics def self.[](name) - klass = const_get(name.to_s.camelize) - klass if klass::Mode + const_get(name.to_s.camelize) rescue NameError nil end @@ -250,6 +265,16 @@ module ActiveSupport ensure GC.disable_stats end + elsif defined?(GC::Profiler) + def with_gc_stats + GC.start + GC.disable + GC::Profiler.enable + yield + ensure + GC::Profiler.disable + GC.enable + end else def with_gc_stats yield @@ -310,7 +335,7 @@ module ActiveSupport RubyProf.measure_memory / 1024.0 end - # Ruby 1.8 + adymo patch + # Ruby 1.8 + railsbench patch elsif GC.respond_to?(:allocated_size) def measure GC.allocated_size / 1024.0 @@ -322,11 +347,27 @@ module ActiveSupport GC.heap_info['heap_current_memory'] / 1024.0 end + # Ruby 1.9 with total_malloc_allocated_size patch + elsif GC.respond_to?(:malloc_total_allocated_size) + def measure + GC.total_malloc_allocated_size / 1024.0 + end + # Ruby 1.9 unpatched elsif GC.respond_to?(:malloc_allocated_size) def measure GC.malloc_allocated_size / 1024.0 end + + # Ruby 1.9 + GC profiler patch + elsif defined?(GC::Profiler) + def measure + GC.enable + GC.start + kb = GC::Profiler.data.last[:HEAP_USE_SIZE] / 1024.0 + GC.disable + kb + end end def format(measurement) @@ -341,10 +382,23 @@ module ActiveSupport def measure RubyProf.measure_allocations end + + # Ruby 1.8 + railsbench patch elsif ObjectSpace.respond_to?(:allocated_objects) def measure ObjectSpace.allocated_objects end + + # Ruby 1.9 + GC profiler patch + elsif defined?(GC::Profiler) + def measure + GC.enable + GC.start + last = GC::Profiler.data.last + count = last[:HEAP_LIVE_OBJECTS] + last[:HEAP_FREE_OBJECTS] + GC.disable + count + end end def format(measurement) diff --git a/activesupport/lib/active_support/typed_array.rb b/activesupport/lib/active_support/typed_array.rb deleted file mode 100644 index 1a4d8a8faf..0000000000 --- a/activesupport/lib/active_support/typed_array.rb +++ /dev/null @@ -1,31 +0,0 @@ -module ActiveSupport - class TypedArray < Array - def self.type_cast(obj) - obj - end - - def initialize(*args) - super(*args).map! { |obj| self.class.type_cast(obj) } - end - - def <<(obj) - super(self.class.type_cast(obj)) - end - - def concat(array) - super(array.map! { |obj| self.class.type_cast(obj) }) - end - - def insert(index, obj) - super(index, self.class.type_cast(obj)) - end - - def push(*objs) - super(*objs.map { |obj| self.class.type_cast(obj) }) - end - - def unshift(*objs) - super(*objs.map { |obj| self.class.type_cast(obj) }) - end - end -end diff --git a/activesupport/test/buffered_logger_test.rb b/activesupport/test/buffered_logger_test.rb index 97649518b7..6319c09210 100644 --- a/activesupport/test/buffered_logger_test.rb +++ b/activesupport/test/buffered_logger_test.rb @@ -70,7 +70,7 @@ class BufferedLoggerTest < Test::Unit::TestCase end @logger.flush - assert !@output.string.empty?, @logger.buffer.size + assert !@output.string.empty?, @logger.send(:buffer).size end define_method "test_disabling_auto_flush_with_#{disable.inspect}_should_flush_at_max_buffer_size_as_failsafe" do @@ -83,10 +83,10 @@ class BufferedLoggerTest < Test::Unit::TestCase end @logger.info 'there it is.' - assert !@output.string.empty?, @logger.buffer.size + assert !@output.string.empty?, @logger.send(:buffer).size end end - + def test_should_know_if_its_loglevel_is_below_a_given_level ActiveSupport::BufferedLogger::Severity.constants.each do |level| @logger.level = ActiveSupport::BufferedLogger::Severity.const_get(level) - 1 @@ -105,7 +105,7 @@ class BufferedLoggerTest < Test::Unit::TestCase @logger.info 'there it is.' assert !@output.string.empty?, @output.string end - + def test_should_create_the_log_directory_if_it_doesnt_exist tmp_directory = File.join(File.dirname(__FILE__), "tmp") log_file = File.join(tmp_directory, "development.log") @@ -115,4 +115,25 @@ class BufferedLoggerTest < Test::Unit::TestCase ensure FileUtils.rm_rf(tmp_directory) end + + def test_logger_should_maintain_separate_buffers_for_each_thread + @logger.auto_flushing = false + + a = Thread.new do + @logger.info("a"); Thread.pass; + @logger.info("b"); Thread.pass; + @logger.info("c"); @logger.flush + end + + b = Thread.new do + @logger.info("x"); Thread.pass; + @logger.info("y"); Thread.pass; + @logger.info("z"); @logger.flush + end + + a.join + b.join + + assert_equal "a\nb\nc\nx\ny\nz\n", @output.string + end end diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb index f3220d27aa..9ea9389448 100644 --- a/activesupport/test/caching_test.rb +++ b/activesupport/test/caching_test.rb @@ -70,3 +70,60 @@ uses_mocha 'high-level cache store tests' do end end end + +class FileStoreTest < Test::Unit::TestCase + def setup + @cache = ActiveSupport::Cache.lookup_store(:file_store, Dir.pwd) + end + + def test_should_read_and_write_strings + @cache.write('foo', 'bar') + assert_equal 'bar', @cache.read('foo') + ensure + File.delete("foo.cache") + end + + def test_should_read_and_write_hash + @cache.write('foo', {:a => "b"}) + assert_equal({:a => "b"}, @cache.read('foo')) + ensure + File.delete("foo.cache") + end + + def test_should_read_and_write_nil + @cache.write('foo', nil) + assert_equal nil, @cache.read('foo') + ensure + File.delete("foo.cache") + end +end + +class MemoryStoreTest < Test::Unit::TestCase + def setup + @cache = ActiveSupport::Cache.lookup_store(:memory_store) + end + + def test_should_read_and_write + @cache.write('foo', 'bar') + assert_equal 'bar', @cache.read('foo') + end + + def test_fetch_without_cache_miss + @cache.write('foo', 'bar') + assert_equal 'bar', @cache.fetch('foo') { 'baz' } + end + + def test_fetch_with_cache_miss + assert_equal 'baz', @cache.fetch('foo') { 'baz' } + end + + def test_fetch_with_forced_cache_miss + @cache.fetch('foo', :force => true) { 'bar' } + end + + def test_store_objects_should_be_immutable + @cache.write('foo', 'bar') + assert_raise(ActiveSupport::FrozenObjectError) { @cache.read('foo').gsub!(/.*/, 'baz') } + assert_equal 'bar', @cache.read('foo') + end +end diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb index 7f71ca2262..25b8eecef5 100644 --- a/activesupport/test/callbacks_test.rb +++ b/activesupport/test/callbacks_test.rb @@ -134,10 +134,10 @@ class CallbackChainTest < Test::Unit::TestCase assert_equal :bacon, @chain.find(:bacon).method end - def test_union - assert_equal [:bacon, :lettuce, :tomato], (@chain | Callback.new(:make, :bacon)).map(&:method) - assert_equal [:bacon, :lettuce, :tomato, :turkey], (@chain | CallbackChain.build(:make, :bacon, :lettuce, :tomato, :turkey)).map(&:method) - assert_equal [:bacon, :lettuce, :tomato, :turkey, :mayo], (@chain | Callback.new(:make, :mayo)).map(&:method) + def test_replace_or_append + assert_equal [:bacon, :lettuce, :tomato], (@chain.replace_or_append!(Callback.new(:make, :bacon))).map(&:method) + assert_equal [:bacon, :lettuce, :tomato, :turkey], (@chain.replace_or_append!(Callback.new(:make, :turkey))).map(&:method) + assert_equal [:bacon, :lettuce, :tomato, :turkey, :mayo], (@chain.replace_or_append!(Callback.new(:make, :mayo))).map(&:method) end def test_delete diff --git a/activesupport/test/core_ext/file_test.rb b/activesupport/test/core_ext/file_test.rb index 63b470684f..eedc6b592b 100644 --- a/activesupport/test/core_ext/file_test.rb +++ b/activesupport/test/core_ext/file_test.rb @@ -29,7 +29,7 @@ class AtomicWriteTest < Test::Unit::TestCase assert File.exist?(file_name) end assert File.exist?(file_name) - assert_equal "100755", file_mode + assert_equal 0100755, file_mode assert_equal contents, File.read(file_name) File.atomic_write(file_name, Dir.pwd) do |file| @@ -37,7 +37,7 @@ class AtomicWriteTest < Test::Unit::TestCase assert File.exist?(file_name) end assert File.exist?(file_name) - assert_equal "100755", file_mode + assert_equal 0100755, file_mode assert_equal contents, File.read(file_name) ensure File.unlink(file_name) rescue nil @@ -50,7 +50,7 @@ class AtomicWriteTest < Test::Unit::TestCase assert !File.exist?(file_name) end assert File.exist?(file_name) - assert_equal "100644", file_mode + assert_equal 0100666 ^ File.umask, file_mode assert_equal contents, File.read(file_name) ensure File.unlink(file_name) rescue nil @@ -62,6 +62,6 @@ class AtomicWriteTest < Test::Unit::TestCase end def file_mode - sprintf("%o", File.stat(file_name).mode) + File.stat(file_name).mode end end diff --git a/activesupport/test/memoizable_test.rb b/activesupport/test/memoizable_test.rb index 01631dc5e1..135d56f14a 100644 --- a/activesupport/test/memoizable_test.rb +++ b/activesupport/test/memoizable_test.rb @@ -110,6 +110,11 @@ uses_mocha 'Memoizable' do assert_equal 1, @person.age_calls end + def test_memorized_results_are_immutable + assert_equal "Josh", @person.name + assert_raise(ActiveSupport::FrozenObjectError) { @person.name.gsub!("Josh", "Gosh") } + end + def test_reloadable counter = @calculator.counter assert_equal 1, @calculator.counter @@ -119,6 +124,21 @@ uses_mocha 'Memoizable' do assert_equal 3, @calculator.counter end + def test_unmemoize_all + assert_equal 1, @calculator.counter + + assert @calculator.instance_variable_get(:@_memoized_counter).any? + @calculator.unmemoize_all + assert @calculator.instance_variable_get(:@_memoized_counter).empty? + + assert_equal 2, @calculator.counter + end + + def test_memoize_all + @calculator.memoize_all + assert @calculator.instance_variable_defined?(:@_memoized_counter) + end + def test_memoization_cache_is_different_for_each_instance assert_equal 1, @calculator.counter assert_equal 2, @calculator.counter(:reload) diff --git a/activesupport/test/typed_array_test.rb b/activesupport/test/typed_array_test.rb deleted file mode 100644 index 023f3a1b84..0000000000 --- a/activesupport/test/typed_array_test.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'abstract_unit' - -class TypedArrayTest < Test::Unit::TestCase - class StringArray < ActiveSupport::TypedArray - def self.type_cast(obj) - obj.to_s - end - end - - def setup - @array = StringArray.new - end - - def test_string_array_initialize - assert_equal ["1", "2", "3"], StringArray.new([1, "2", :"3"]) - end - - def test_string_array_append - @array << 1 - @array << "2" - @array << :"3" - assert_equal ["1", "2", "3"], @array - end - - def test_string_array_concat - @array.concat([1, "2"]) - @array.concat([:"3"]) - assert_equal ["1", "2", "3"], @array - end - - def test_string_array_insert - @array.insert(0, 1) - @array.insert(1, "2") - @array.insert(2, :"3") - assert_equal ["1", "2", "3"], @array - end - - def test_string_array_push - @array.push(1) - @array.push("2") - @array.push(:"3") - assert_equal ["1", "2", "3"], @array - end - - def test_string_array_unshift - @array.unshift(:"3") - @array.unshift("2") - @array.unshift(1) - assert_equal ["1", "2", "3"], @array - end -end |