From cb2d775bb15f514e647ca4269882123a6b8b8d0e Mon Sep 17 00:00:00 2001 From: Jim Menard Date: Thu, 8 Jan 2009 07:16:25 -0500 Subject: [PATCH] Fixed OrderedHash merge bug. New tests for OrderedHash. --- lib/mongo/util/ordered_hash.rb | 11 +++++ tests/test_ordered_hash.rb | 82 ++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 tests/test_ordered_hash.rb diff --git a/lib/mongo/util/ordered_hash.rb b/lib/mongo/util/ordered_hash.rb index d7307c2..568d7e5 100644 --- a/lib/mongo/util/ordered_hash.rb +++ b/lib/mongo/util/ordered_hash.rb @@ -34,9 +34,20 @@ class OrderedHash < Hash @ordered_keys.each { |k| yield k, self[k] } end + def values + collect { |k, v| v } + end + def merge(other) + oh = self.dup + oh.merge!(other) + oh + end + + def merge!(other) @ordered_keys ||= [] @ordered_keys += other.keys # unordered if not an OrderedHash + @ordered_keys.uniq! super(other) end diff --git a/tests/test_ordered_hash.rb b/tests/test_ordered_hash.rb new file mode 100644 index 0000000..3b6b7d5 --- /dev/null +++ b/tests/test_ordered_hash.rb @@ -0,0 +1,82 @@ +$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib') +require 'mongo/util/ordered_hash' +require 'test/unit' + +# NOTE: assumes Mongo is running +class OrderedHashTest < Test::Unit::TestCase + + def setup + @oh = OrderedHash.new + @oh['c'] = 1 + @oh['a'] = 2 + @oh['z'] = 3 + @ordered_keys = %w(c a z) + end + + def test_empty + assert_equal [], OrderedHash.new.keys + end + + def test_order_preserved + assert_equal @ordered_keys, @oh.keys + end + + def test_order_preserved_after_replace + @oh['a'] = 42 + assert_equal @ordered_keys, @oh.keys + @oh['c'] = 'foobar' + assert_equal @ordered_keys, @oh.keys + @oh['z'] = /huh?/ + assert_equal @ordered_keys, @oh.keys + end + + def test_each + keys = [] + @oh.each { |k, v| keys << k } + assert_equal keys, @oh.keys + + @oh['z'] = 42 + assert_equal keys, @oh.keys + end + + def test_values + assert_equal [1, 2, 3], @oh.values + end + + def test_merge + other = OrderedHash.new + other['f'] = 'foo' + noob = @oh.merge(other) + assert_equal @ordered_keys + ['f'], noob.keys + assert_equal [1, 2, 3, 'foo'], noob.values + end + + def test_merge_bang + other = OrderedHash.new + other['f'] = 'foo' + @oh.merge!(other) + assert_equal @ordered_keys + ['f'], @oh.keys + assert_equal [1, 2, 3, 'foo'], @oh.values + end + + def test_merge_bang_with_overlap + other = OrderedHash.new + other['a'] = 'apple' + other['c'] = 'crab' + other['f'] = 'foo' + @oh.merge!(other) + assert_equal @ordered_keys + ['f'], @oh.keys + assert_equal ['crab', 'apple', 3, 'foo'], @oh.values + end + + def test_merge_bang_with_hash_with_overlap + other = Hash.new + other['a'] = 'apple' + other['c'] = 'crab' + other['f'] = 'foo' + @oh.merge!(other) + assert_equal @ordered_keys + ['f'], @oh.keys + assert_equal ['crab', 'apple', 3, 'foo'], @oh.values + end + +end