deep_merge 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +88 -0
 - data/lib/deep_merge.rb +206 -0
 - data/test/test_deep_merge.rb +553 -0
 - metadata +55 -0
 
    
        data/README
    ADDED
    
    | 
         @@ -0,0 +1,88 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            DeepMerge Overview
         
     | 
| 
      
 2 
     | 
    
         
            +
            ==================
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            Deep Merge is a simple set of utility functions for Hash. It permits
         
     | 
| 
      
 5 
     | 
    
         
            +
            you to merge elements inside a hash together recursively. The manner
         
     | 
| 
      
 6 
     | 
    
         
            +
            by which it does this is somewhat arbitrary (since there is no defining 
         
     | 
| 
      
 7 
     | 
    
         
            +
            standard for this) but it should end up being pretty intuitive and do what
         
     | 
| 
      
 8 
     | 
    
         
            +
            you expect.
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            You can learn a lot more about this by reading the test file. It's pretty
         
     | 
| 
      
 11 
     | 
    
         
            +
            well documented and has many examples of various merges from very simple
         
     | 
| 
      
 12 
     | 
    
         
            +
            to pretty complex.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            The primary need that caused me to write this library is the merging of elements
         
     | 
| 
      
 15 
     | 
    
         
            +
            coming from HTTP parameters and related stored parameters in session. This lets
         
     | 
| 
      
 16 
     | 
    
         
            +
            a user build up a set of parameters over time, modifying individual items.
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            Deep Merge Core Documentation
         
     | 
| 
      
 19 
     | 
    
         
            +
            =============================
         
     | 
| 
      
 20 
     | 
    
         
            +
             deep_merge! method permits merging of arbitrary child elements. The two top level
         
     | 
| 
      
 21 
     | 
    
         
            +
             elements must be hashes. These hashes can contain unlimited (to stack limit) levels
         
     | 
| 
      
 22 
     | 
    
         
            +
             of child elements. These child elements to not have to be of the same types.
         
     | 
| 
      
 23 
     | 
    
         
            +
             Where child elements are of the same type, deep_merge will attempt to merge them together.
         
     | 
| 
      
 24 
     | 
    
         
            +
             Where child elements are not of the same type, deep_merge will skip or optionally overwrite
         
     | 
| 
      
 25 
     | 
    
         
            +
             the destination element with the contents of the source element at that level.
         
     | 
| 
      
 26 
     | 
    
         
            +
             So if you have two hashes like this:
         
     | 
| 
      
 27 
     | 
    
         
            +
               source = {:x => [1,2,3], :y => 2}
         
     | 
| 
      
 28 
     | 
    
         
            +
               dest =   {:x => [4,5,'6'], :y => [7,8,9]}
         
     | 
| 
      
 29 
     | 
    
         
            +
               dest.deep_merge!(source)
         
     | 
| 
      
 30 
     | 
    
         
            +
               Results: {:x => [1,2,3,4,5,'6'], :y => 2}
         
     | 
| 
      
 31 
     | 
    
         
            +
             By default, "deep_merge!" will overwrite any unmergeables and merge everything else.
         
     | 
| 
      
 32 
     | 
    
         
            +
             To avoid this, use "deep_merge" (no bang/exclamation mark)
         
     | 
| 
      
 33 
     | 
    
         
            +
             
         
     | 
| 
      
 34 
     | 
    
         
            +
             Options:
         
     | 
| 
      
 35 
     | 
    
         
            +
               Options are specified in the last parameter passed, which should be in hash format:
         
     | 
| 
      
 36 
     | 
    
         
            +
               hash.deep_merge!({:x => [1,2]}, {:knockout_prefix => '--'})
         
     | 
| 
      
 37 
     | 
    
         
            +
               :preserve_unmergeables  DEFAULT: false
         
     | 
| 
      
 38 
     | 
    
         
            +
                  Set to true to skip any unmergeable elements from source
         
     | 
| 
      
 39 
     | 
    
         
            +
               :knockout_prefix        DEFAULT: nil
         
     | 
| 
      
 40 
     | 
    
         
            +
                  Set to string value to signify prefix which deletes elements from existing element
         
     | 
| 
      
 41 
     | 
    
         
            +
               :sort_merged_arrays     DEFAULT: false
         
     | 
| 
      
 42 
     | 
    
         
            +
                  Set to true to sort all arrays that are merged together
         
     | 
| 
      
 43 
     | 
    
         
            +
               :unpack_arrays          DEFAULT: nil
         
     | 
| 
      
 44 
     | 
    
         
            +
                  Set to string value to run "Array::join" then "String::split" against all arrays
         
     | 
| 
      
 45 
     | 
    
         
            +
               :merge_debug            DEFAULT: false
         
     | 
| 
      
 46 
     | 
    
         
            +
                  Set to true to get console output of merge process for debugging
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
             Selected Options Details:
         
     | 
| 
      
 49 
     | 
    
         
            +
             :knockout_prefix => The purpose of this is to provide a way to remove elements 
         
     | 
| 
      
 50 
     | 
    
         
            +
               from existing Hash by specifying them in a special way in incoming hash
         
     | 
| 
      
 51 
     | 
    
         
            +
                source = {:x => ['--1', '2']}
         
     | 
| 
      
 52 
     | 
    
         
            +
                dest   = {:x => ['1', '3']}
         
     | 
| 
      
 53 
     | 
    
         
            +
                dest.ko_deep_merge!(source)
         
     | 
| 
      
 54 
     | 
    
         
            +
                Results: {:x => ['2','3']}
         
     | 
| 
      
 55 
     | 
    
         
            +
               Additionally, if the knockout_prefix is passed alone as a string, it will cause
         
     | 
| 
      
 56 
     | 
    
         
            +
               the entire element to be removed:
         
     | 
| 
      
 57 
     | 
    
         
            +
                source = {:x => '--'}
         
     | 
| 
      
 58 
     | 
    
         
            +
                dest   = {:x => [1,2,3]}
         
     | 
| 
      
 59 
     | 
    
         
            +
                dest.ko_deep_merge!(source)
         
     | 
| 
      
 60 
     | 
    
         
            +
                Results: {:x => ""}
         
     | 
| 
      
 61 
     | 
    
         
            +
             :unpack_arrays => The purpose of this is to permit compound elements to be passed
         
     | 
| 
      
 62 
     | 
    
         
            +
               in as strings and to be converted into discrete array elements
         
     | 
| 
      
 63 
     | 
    
         
            +
               irsource = {:x => ['1,2,3', '4']}
         
     | 
| 
      
 64 
     | 
    
         
            +
               dest   = {:x => ['5','6','7,8']}
         
     | 
| 
      
 65 
     | 
    
         
            +
               dest.deep_merge!(source, {:unpack_arrays => ','})
         
     | 
| 
      
 66 
     | 
    
         
            +
               Results: {:x => ['1','2','3','4','5','6','7','8'}
         
     | 
| 
      
 67 
     | 
    
         
            +
               Why: If receiving data from an HTML form, this makes it easy for a checkbox 
         
     | 
| 
      
 68 
     | 
    
         
            +
                to pass multiple values from within a single HTML element
         
     | 
| 
      
 69 
     | 
    
         
            +
             
         
     | 
| 
      
 70 
     | 
    
         
            +
             There are many tests for this library - and you can learn more about the features
         
     | 
| 
      
 71 
     | 
    
         
            +
             and usages of deep_merge! by just browsing the test examples
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            Simple Example Code
         
     | 
| 
      
 75 
     | 
    
         
            +
            ===================
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            require 'deep_merge'
         
     | 
| 
      
 78 
     | 
    
         
            +
            x = {:x => [3,4,5]}
         
     | 
| 
      
 79 
     | 
    
         
            +
            y = {:x => [1,2,3]}
         
     | 
| 
      
 80 
     | 
    
         
            +
            y.deep_merge!(x)
         
     | 
| 
      
 81 
     | 
    
         
            +
            # results: y = {:x => [1,2,3,4,5]}
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            Availablility
         
     | 
| 
      
 84 
     | 
    
         
            +
            =============
         
     | 
| 
      
 85 
     | 
    
         
            +
            SVN Repo here:  http://trac.misuse.org/science/wiki/DeepMerge
         
     | 
| 
      
 86 
     | 
    
         
            +
            Contact author: http://www.misuse.org/science
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            Copyright (c) 2008 Steve Midgley, released under the MIT license
         
     | 
    
        data/lib/deep_merge.rb
    ADDED
    
    | 
         @@ -0,0 +1,206 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module DeepMerge
         
     | 
| 
      
 2 
     | 
    
         
            +
              
         
     | 
| 
      
 3 
     | 
    
         
            +
              class InvalidParameter < StandardError; end
         
     | 
| 
      
 4 
     | 
    
         
            +
              
         
     | 
| 
      
 5 
     | 
    
         
            +
              DEFAULT_FIELD_KNOCKOUT_PREFIX = '--'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              module DeepMergeHash
         
     | 
| 
      
 8 
     | 
    
         
            +
                # ko_hash_merge! will merge and knockout elements prefixed with DEFAULT_FIELD_KNOCKOUT_PREFIX
         
     | 
| 
      
 9 
     | 
    
         
            +
                def ko_deep_merge!(source, options = {})
         
     | 
| 
      
 10 
     | 
    
         
            +
                  default_opts = {:knockout_prefix => "--", :preserve_unmergeables => false}
         
     | 
| 
      
 11 
     | 
    
         
            +
                  DeepMerge::deep_merge!(source, self, default_opts.merge(options))
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                # deep_merge! will merge and overwrite any unmergeables in destination hash
         
     | 
| 
      
 15 
     | 
    
         
            +
                def deep_merge!(source, options = {})
         
     | 
| 
      
 16 
     | 
    
         
            +
                  default_opts = {:preserve_unmergeables => false}
         
     | 
| 
      
 17 
     | 
    
         
            +
                  DeepMerge::deep_merge!(source, self, default_opts.merge(options))
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                # deep_merge will merge and skip any unmergeables in destination hash
         
     | 
| 
      
 21 
     | 
    
         
            +
                def deep_merge(source, options = {})
         
     | 
| 
      
 22 
     | 
    
         
            +
                  default_opts = {:preserve_unmergeables => true}
         
     | 
| 
      
 23 
     | 
    
         
            +
                  DeepMerge::deep_merge!(source, self, default_opts.merge(options))
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              end # DeepMergeHashExt
         
     | 
| 
      
 27 
     | 
    
         
            +
              
         
     | 
| 
      
 28 
     | 
    
         
            +
              # Deep Merge core documentation.
         
     | 
| 
      
 29 
     | 
    
         
            +
              # deep_merge! method permits merging of arbitrary child elements. The two top level
         
     | 
| 
      
 30 
     | 
    
         
            +
              # elements must be hashes. These hashes can contain unlimited (to stack limit) levels
         
     | 
| 
      
 31 
     | 
    
         
            +
              # of child elements. These child elements to not have to be of the same types.
         
     | 
| 
      
 32 
     | 
    
         
            +
              # Where child elements are of the same type, deep_merge will attempt to merge them together.
         
     | 
| 
      
 33 
     | 
    
         
            +
              # Where child elements are not of the same type, deep_merge will skip or optionally overwrite
         
     | 
| 
      
 34 
     | 
    
         
            +
              # the destination element with the contents of the source element at that level.
         
     | 
| 
      
 35 
     | 
    
         
            +
              # So if you have two hashes like this:
         
     | 
| 
      
 36 
     | 
    
         
            +
              #   source = {:x => [1,2,3], :y => 2}
         
     | 
| 
      
 37 
     | 
    
         
            +
              #   dest =   {:x => [4,5,'6'], :y => [7,8,9]}
         
     | 
| 
      
 38 
     | 
    
         
            +
              #   dest.deep_merge!(source)
         
     | 
| 
      
 39 
     | 
    
         
            +
              #   Results: {:x => [1,2,3,4,5,'6'], :y => 2}
         
     | 
| 
      
 40 
     | 
    
         
            +
              # By default, "deep_merge!" will overwrite any unmergeables and merge everything else.
         
     | 
| 
      
 41 
     | 
    
         
            +
              # To avoid this, use "deep_merge" (no bang/exclamation mark)
         
     | 
| 
      
 42 
     | 
    
         
            +
              # 
         
     | 
| 
      
 43 
     | 
    
         
            +
              # Options:
         
     | 
| 
      
 44 
     | 
    
         
            +
              #   Options are specified in the last parameter passed, which should be in hash format:
         
     | 
| 
      
 45 
     | 
    
         
            +
              #   hash.deep_merge!({:x => [1,2]}, {:knockout_prefix => '--'})
         
     | 
| 
      
 46 
     | 
    
         
            +
              #   :preserve_unmergeables  DEFAULT: false
         
     | 
| 
      
 47 
     | 
    
         
            +
              #      Set to true to skip any unmergeable elements from source
         
     | 
| 
      
 48 
     | 
    
         
            +
              #   :knockout_prefix        DEFAULT: nil
         
     | 
| 
      
 49 
     | 
    
         
            +
              #      Set to string value to signify prefix which deletes elements from existing element
         
     | 
| 
      
 50 
     | 
    
         
            +
              #   :sort_merged_arrays     DEFAULT: false
         
     | 
| 
      
 51 
     | 
    
         
            +
              #      Set to true to sort all arrays that are merged together
         
     | 
| 
      
 52 
     | 
    
         
            +
              #   :unpack_arrays          DEFAULT: nil
         
     | 
| 
      
 53 
     | 
    
         
            +
              #      Set to string value to run "Array::join" then "String::split" against all arrays
         
     | 
| 
      
 54 
     | 
    
         
            +
              #   :merge_debug            DEFAULT: false
         
     | 
| 
      
 55 
     | 
    
         
            +
              #      Set to true to get console output of merge process for debugging
         
     | 
| 
      
 56 
     | 
    
         
            +
              #
         
     | 
| 
      
 57 
     | 
    
         
            +
              # Selected Options Details:
         
     | 
| 
      
 58 
     | 
    
         
            +
              # :knockout_prefix => The purpose of this is to provide a way to remove elements 
         
     | 
| 
      
 59 
     | 
    
         
            +
              #   from existing Hash by specifying them in a special way in incoming hash
         
     | 
| 
      
 60 
     | 
    
         
            +
              #    source = {:x => ['--1', '2']}
         
     | 
| 
      
 61 
     | 
    
         
            +
              #    dest   = {:x => ['1', '3']}
         
     | 
| 
      
 62 
     | 
    
         
            +
              #    dest.ko_deep_merge!(source)
         
     | 
| 
      
 63 
     | 
    
         
            +
              #    Results: {:x => ['2','3']}
         
     | 
| 
      
 64 
     | 
    
         
            +
              #   Additionally, if the knockout_prefix is passed alone as a string, it will cause
         
     | 
| 
      
 65 
     | 
    
         
            +
              #   the entire element to be removed:
         
     | 
| 
      
 66 
     | 
    
         
            +
              #    source = {:x => '--'}
         
     | 
| 
      
 67 
     | 
    
         
            +
              #    dest   = {:x => [1,2,3]}
         
     | 
| 
      
 68 
     | 
    
         
            +
              #    dest.ko_deep_merge!(source)
         
     | 
| 
      
 69 
     | 
    
         
            +
              #    Results: {:x => ""}
         
     | 
| 
      
 70 
     | 
    
         
            +
              # :unpack_arrays => The purpose of this is to permit compound elements to be passed
         
     | 
| 
      
 71 
     | 
    
         
            +
              #   in as strings and to be converted into discrete array elements
         
     | 
| 
      
 72 
     | 
    
         
            +
              #   irsource = {:x => ['1,2,3', '4']}
         
     | 
| 
      
 73 
     | 
    
         
            +
              #   dest   = {:x => ['5','6','7,8']}
         
     | 
| 
      
 74 
     | 
    
         
            +
              #   dest.deep_merge!(source, {:unpack_arrays => ','})
         
     | 
| 
      
 75 
     | 
    
         
            +
              #   Results: {:x => ['1','2','3','4','5','6','7','8'}
         
     | 
| 
      
 76 
     | 
    
         
            +
              #   Why: If receiving data from an HTML form, this makes it easy for a checkbox 
         
     | 
| 
      
 77 
     | 
    
         
            +
              #    to pass multiple values from within a single HTML element
         
     | 
| 
      
 78 
     | 
    
         
            +
              # 
         
     | 
| 
      
 79 
     | 
    
         
            +
              # There are many tests for this library - and you can learn more about the features
         
     | 
| 
      
 80 
     | 
    
         
            +
              # and usages of deep_merge! by just browsing the test examples
         
     | 
| 
      
 81 
     | 
    
         
            +
              def DeepMerge.deep_merge!(source, dest, options = {})
         
     | 
| 
      
 82 
     | 
    
         
            +
                # turn on this line for stdout debugging text
         
     | 
| 
      
 83 
     | 
    
         
            +
                merge_debug = options[:merge_debug] || false
         
     | 
| 
      
 84 
     | 
    
         
            +
                overwrite_unmergeable = !options[:preserve_unmergeables]
         
     | 
| 
      
 85 
     | 
    
         
            +
                knockout_prefix = options[:knockout_prefix] || nil
         
     | 
| 
      
 86 
     | 
    
         
            +
                if knockout_prefix == "" : raise InvalidParameter, "knockout_prefix cannot be an empty string in deep_merge!"; end
         
     | 
| 
      
 87 
     | 
    
         
            +
                if knockout_prefix && !overwrite_unmergeable : raise InvalidParameter, "overwrite_unmergeable must be true if knockout_prefix is specified in deep_merge!"; end
         
     | 
| 
      
 88 
     | 
    
         
            +
                # if present: we will split and join arrays on this char before merging
         
     | 
| 
      
 89 
     | 
    
         
            +
                array_split_char = options[:unpack_arrays] || false
         
     | 
| 
      
 90 
     | 
    
         
            +
                # request that we sort together any arrays when they are merged
         
     | 
| 
      
 91 
     | 
    
         
            +
                sort_merged_arrays = options[:sort_merged_arrays] || false
         
     | 
| 
      
 92 
     | 
    
         
            +
                di = options[:debug_indent] || ''
         
     | 
| 
      
 93 
     | 
    
         
            +
                # do nothing if source is nil
         
     | 
| 
      
 94 
     | 
    
         
            +
                if !source || (source.respond_to?(:blank?) && source.blank?) : return dest; end
         
     | 
| 
      
 95 
     | 
    
         
            +
                # if dest doesn't exist, then simply copy source to it
         
     | 
| 
      
 96 
     | 
    
         
            +
                if !(dest) && overwrite_unmergeable : dest = source; return dest; end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                puts "#{di}Source class: #{source.class.inspect} :: Dest class: #{dest.class.inspect}" if merge_debug
         
     | 
| 
      
 99 
     | 
    
         
            +
                if source.kind_of?(Hash)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  puts "#{di}Hashes: #{source.inspect} :: #{dest.inspect}" if merge_debug
         
     | 
| 
      
 101 
     | 
    
         
            +
                  source.each do |src_key, src_value|
         
     | 
| 
      
 102 
     | 
    
         
            +
                    if dest.kind_of?(Hash)
         
     | 
| 
      
 103 
     | 
    
         
            +
                      puts "#{di} looping: #{src_key.inspect} => #{src_value.inspect} :: #{dest.inspect}" if merge_debug
         
     | 
| 
      
 104 
     | 
    
         
            +
                      if dest[src_key]
         
     | 
| 
      
 105 
     | 
    
         
            +
                        puts "#{di} ==>merging: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug
         
     | 
| 
      
 106 
     | 
    
         
            +
                        dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(:debug_indent => di + '  '))
         
     | 
| 
      
 107 
     | 
    
         
            +
                      else # dest[src_key] doesn't exist so we want to create and overwrite it (but we do this via deep_merge!)
         
     | 
| 
      
 108 
     | 
    
         
            +
                        puts "#{di} ==>merging over: #{src_key.inspect} => #{src_value.inspect}" if merge_debug
         
     | 
| 
      
 109 
     | 
    
         
            +
                        # note: we rescue here b/c some classes respond to "dup" but don't implement it (Numeric, TrueClass, FalseClass, NilClass among maybe others)
         
     | 
| 
      
 110 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 111 
     | 
    
         
            +
                          src_dup = src_value.dup # we dup src_value if possible because we're going to merge into it (since dest is empty)
         
     | 
| 
      
 112 
     | 
    
         
            +
                        rescue TypeError
         
     | 
| 
      
 113 
     | 
    
         
            +
                          src_dup = src_value
         
     | 
| 
      
 114 
     | 
    
         
            +
                        end
         
     | 
| 
      
 115 
     | 
    
         
            +
                        dest[src_key] = deep_merge!(src_value, src_dup, options.merge(:debug_indent => di + '  '))
         
     | 
| 
      
 116 
     | 
    
         
            +
                      end
         
     | 
| 
      
 117 
     | 
    
         
            +
                    else # dest isn't a hash, so we overwrite it completely (if permitted)
         
     | 
| 
      
 118 
     | 
    
         
            +
                      if overwrite_unmergeable
         
     | 
| 
      
 119 
     | 
    
         
            +
                        puts "#{di}  overwriting dest: #{src_key.inspect} => #{src_value.inspect} -over->  #{dest.inspect}" if merge_debug
         
     | 
| 
      
 120 
     | 
    
         
            +
                        dest = overwrite_unmergeables(source, dest, options)
         
     | 
| 
      
 121 
     | 
    
         
            +
                      end
         
     | 
| 
      
 122 
     | 
    
         
            +
                    end
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
                elsif source.kind_of?(Array)
         
     | 
| 
      
 125 
     | 
    
         
            +
                  puts "#{di}Arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
         
     | 
| 
      
 126 
     | 
    
         
            +
                  # if we are instructed, join/split any source arrays before processing
         
     | 
| 
      
 127 
     | 
    
         
            +
                  if array_split_char
         
     | 
| 
      
 128 
     | 
    
         
            +
                    puts "#{di} split/join on source: #{source.inspect}" if merge_debug
         
     | 
| 
      
 129 
     | 
    
         
            +
                    source = source.join(array_split_char).split(array_split_char)
         
     | 
| 
      
 130 
     | 
    
         
            +
                    if dest.kind_of?(Array) : dest = dest.join(array_split_char).split(array_split_char); end
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 132 
     | 
    
         
            +
                  # if there's a naked knockout_prefix in source, that means we are to truncate dest
         
     | 
| 
      
 133 
     | 
    
         
            +
                  if source.index(knockout_prefix) : dest = clear_or_nil(dest); source.delete(knockout_prefix); end
         
     | 
| 
      
 134 
     | 
    
         
            +
                  if dest.kind_of?(Array)
         
     | 
| 
      
 135 
     | 
    
         
            +
                    if knockout_prefix
         
     | 
| 
      
 136 
     | 
    
         
            +
                      print "#{di} knocking out: " if merge_debug
         
     | 
| 
      
 137 
     | 
    
         
            +
                      # remove knockout prefix items from both source and dest
         
     | 
| 
      
 138 
     | 
    
         
            +
                      source.delete_if do |ko_item|
         
     | 
| 
      
 139 
     | 
    
         
            +
                        retval = false
         
     | 
| 
      
 140 
     | 
    
         
            +
                        item = ko_item.respond_to?(:gsub) ? ko_item.gsub(%r{^#{knockout_prefix}}, "") : ko_item
         
     | 
| 
      
 141 
     | 
    
         
            +
                        if item != ko_item
         
     | 
| 
      
 142 
     | 
    
         
            +
                          print "#{ko_item} - " if merge_debug
         
     | 
| 
      
 143 
     | 
    
         
            +
                          dest.delete(item)
         
     | 
| 
      
 144 
     | 
    
         
            +
                          dest.delete(ko_item)
         
     | 
| 
      
 145 
     | 
    
         
            +
                          retval = true
         
     | 
| 
      
 146 
     | 
    
         
            +
                        end
         
     | 
| 
      
 147 
     | 
    
         
            +
                        retval
         
     | 
| 
      
 148 
     | 
    
         
            +
                      end
         
     | 
| 
      
 149 
     | 
    
         
            +
                      puts if merge_debug
         
     | 
| 
      
 150 
     | 
    
         
            +
                    end
         
     | 
| 
      
 151 
     | 
    
         
            +
                    puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
         
     | 
| 
      
 152 
     | 
    
         
            +
                    dest = dest | source
         
     | 
| 
      
 153 
     | 
    
         
            +
                    if sort_merged_arrays : dest.sort!; end
         
     | 
| 
      
 154 
     | 
    
         
            +
                  elsif overwrite_unmergeable
         
     | 
| 
      
 155 
     | 
    
         
            +
                    puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
         
     | 
| 
      
 156 
     | 
    
         
            +
                    dest = overwrite_unmergeables(source, dest, options)
         
     | 
| 
      
 157 
     | 
    
         
            +
                  end
         
     | 
| 
      
 158 
     | 
    
         
            +
                else # src_hash is not an array or hash, so we'll have to overwrite dest
         
     | 
| 
      
 159 
     | 
    
         
            +
                  puts "#{di}Others: #{source.inspect} :: #{dest.inspect}" if merge_debug
         
     | 
| 
      
 160 
     | 
    
         
            +
                  dest = overwrite_unmergeables(source, dest, options)
         
     | 
| 
      
 161 
     | 
    
         
            +
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
                puts "#{di}Returning #{dest.inspect}" if merge_debug
         
     | 
| 
      
 163 
     | 
    
         
            +
                dest
         
     | 
| 
      
 164 
     | 
    
         
            +
              end # deep_merge!
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
              # allows deep_merge! to uniformly handle overwriting of unmergeable entities
         
     | 
| 
      
 167 
     | 
    
         
            +
              def DeepMerge::overwrite_unmergeables(source, dest, options)
         
     | 
| 
      
 168 
     | 
    
         
            +
                merge_debug = options[:merge_debug] || false
         
     | 
| 
      
 169 
     | 
    
         
            +
                overwrite_unmergeable = !options[:preserve_unmergeables]
         
     | 
| 
      
 170 
     | 
    
         
            +
                knockout_prefix = options[:knockout_prefix] || false
         
     | 
| 
      
 171 
     | 
    
         
            +
                di = options[:debug_indent] || ''
         
     | 
| 
      
 172 
     | 
    
         
            +
                if knockout_prefix && overwrite_unmergeable
         
     | 
| 
      
 173 
     | 
    
         
            +
                  if source.kind_of?(String) # remove knockout string from source before overwriting dest
         
     | 
| 
      
 174 
     | 
    
         
            +
                    src_tmp = source.gsub(%r{^#{knockout_prefix}},"")
         
     | 
| 
      
 175 
     | 
    
         
            +
                  elsif source.kind_of?(Array) # remove all knockout elements before overwriting dest
         
     | 
| 
      
 176 
     | 
    
         
            +
                    src_tmp = source.delete_if {|ko_item| ko_item.kind_of?(String) && ko_item.match(%r{^#{knockout_prefix}}) }
         
     | 
| 
      
 177 
     | 
    
         
            +
                  else
         
     | 
| 
      
 178 
     | 
    
         
            +
                    src_tmp = source
         
     | 
| 
      
 179 
     | 
    
         
            +
                  end
         
     | 
| 
      
 180 
     | 
    
         
            +
                  if src_tmp == source # if we didn't find a knockout_prefix then we just overwrite dest
         
     | 
| 
      
 181 
     | 
    
         
            +
                    puts "#{di}#{src_tmp.inspect} -over-> #{dest.inspect}" if merge_debug
         
     | 
| 
      
 182 
     | 
    
         
            +
                    dest = src_tmp
         
     | 
| 
      
 183 
     | 
    
         
            +
                  else # if we do find a knockout_prefix, then we just delete dest
         
     | 
| 
      
 184 
     | 
    
         
            +
                    puts "#{di}\"\" -over-> #{dest.inspect}" if merge_debug
         
     | 
| 
      
 185 
     | 
    
         
            +
                    dest = ""
         
     | 
| 
      
 186 
     | 
    
         
            +
                  end
         
     | 
| 
      
 187 
     | 
    
         
            +
                elsif overwrite_unmergeable
         
     | 
| 
      
 188 
     | 
    
         
            +
                  dest = source
         
     | 
| 
      
 189 
     | 
    
         
            +
                end
         
     | 
| 
      
 190 
     | 
    
         
            +
                dest
         
     | 
| 
      
 191 
     | 
    
         
            +
              end
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
              def DeepMerge::clear_or_nil(obj)
         
     | 
| 
      
 194 
     | 
    
         
            +
                if obj.respond_to?(:clear)
         
     | 
| 
      
 195 
     | 
    
         
            +
                  obj.clear
         
     | 
| 
      
 196 
     | 
    
         
            +
                else
         
     | 
| 
      
 197 
     | 
    
         
            +
                  obj = nil
         
     | 
| 
      
 198 
     | 
    
         
            +
                end
         
     | 
| 
      
 199 
     | 
    
         
            +
                obj
         
     | 
| 
      
 200 
     | 
    
         
            +
              end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
            end # module DeepMerge
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
            class Hash
         
     | 
| 
      
 205 
     | 
    
         
            +
              include DeepMerge::DeepMergeHash
         
     | 
| 
      
 206 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,553 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require '../lib/deep_merge.rb'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class TestDeepMerge < Test::Unit::TestCase
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              # show that Hash object has deep merge capabilities in form of three methods:
         
     | 
| 
      
 10 
     | 
    
         
            +
              #   ko_deep_merge! # uses '--' knockout and overwrites unmergeable
         
     | 
| 
      
 11 
     | 
    
         
            +
              #   deep_merge! # overwrites unmergeable
         
     | 
| 
      
 12 
     | 
    
         
            +
              #   deep_merge # skips unmergeable
         
     | 
| 
      
 13 
     | 
    
         
            +
              def test_hash_deep_merge
         
     | 
| 
      
 14 
     | 
    
         
            +
                x = {}
         
     | 
| 
      
 15 
     | 
    
         
            +
                assert x.respond_to?('deep_merge!'.to_sym)  
         
     | 
| 
      
 16 
     | 
    
         
            +
                hash_src  = {'id' => [3,4,5]}
         
     | 
| 
      
 17 
     | 
    
         
            +
                hash_dest = {'id' => [1,2,3]}
         
     | 
| 
      
 18 
     | 
    
         
            +
                assert hash_dest.ko_deep_merge!(hash_src)
         
     | 
| 
      
 19 
     | 
    
         
            +
                assert_equal({'id' => [1,2,3,4,5]}, hash_dest)
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                hash_src  = {'id' => [3,4,5]}
         
     | 
| 
      
 22 
     | 
    
         
            +
                hash_dest = {'id' => [1,2,3]}
         
     | 
| 
      
 23 
     | 
    
         
            +
                assert hash_dest.deep_merge!(hash_src)
         
     | 
| 
      
 24 
     | 
    
         
            +
                assert_equal({'id' => [1,2,3,4,5]}, hash_dest)
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                hash_src  = {'id' => 'xxx'}
         
     | 
| 
      
 27 
     | 
    
         
            +
                hash_dest = {'id' => [1,2,3]}
         
     | 
| 
      
 28 
     | 
    
         
            +
                assert hash_dest.deep_merge(hash_src)
         
     | 
| 
      
 29 
     | 
    
         
            +
                assert_equal({'id' => [1,2,3]}, hash_dest)
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
              FIELD_KNOCKOUT_PREFIX = DeepMerge::DEFAULT_FIELD_KNOCKOUT_PREFIX
         
     | 
| 
      
 33 
     | 
    
         
            +
              
         
     | 
| 
      
 34 
     | 
    
         
            +
              # tests DeepMerge::deep_merge! function
         
     | 
| 
      
 35 
     | 
    
         
            +
              def test_deep_merge
         
     | 
| 
      
 36 
     | 
    
         
            +
                # merge tests (moving from basic to more complex)
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                # test merging an hash w/array into blank hash
         
     | 
| 
      
 39 
     | 
    
         
            +
                hash_src = {'id' => '2'}
         
     | 
| 
      
 40 
     | 
    
         
            +
                hash_dst = {}
         
     | 
| 
      
 41 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src.dup, hash_dst, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 42 
     | 
    
         
            +
                assert_equal hash_src, hash_dst
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                # test merging an hash w/array into blank hash
         
     | 
| 
      
 45 
     | 
    
         
            +
                hash_src = {'region' => {'id' => ['227', '2']}}
         
     | 
| 
      
 46 
     | 
    
         
            +
                hash_dst = {}
         
     | 
| 
      
 47 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 48 
     | 
    
         
            +
                assert_equal hash_src, hash_dst
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                # merge from empty hash
         
     | 
| 
      
 51 
     | 
    
         
            +
                hash_src = {}
         
     | 
| 
      
 52 
     | 
    
         
            +
                hash_dst = {"property" => ["2","4"]}
         
     | 
| 
      
 53 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 54 
     | 
    
         
            +
                assert_equal({"property" => ["2","4"]}, hash_dst)
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                # merge to empty hash
         
     | 
| 
      
 57 
     | 
    
         
            +
                hash_src = {"property" => ["2","4"]}
         
     | 
| 
      
 58 
     | 
    
         
            +
                hash_dst = {}
         
     | 
| 
      
 59 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 60 
     | 
    
         
            +
                assert_equal({"property" => ["2","4"]}, hash_dst)
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                # simple string overwrite
         
     | 
| 
      
 63 
     | 
    
         
            +
                hash_src = {"name" => "value"}
         
     | 
| 
      
 64 
     | 
    
         
            +
                hash_dst = {"name" => "value1"}
         
     | 
| 
      
 65 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 66 
     | 
    
         
            +
                assert_equal({"name" => "value"}, hash_dst)
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                # simple string overwrite of empty hash
         
     | 
| 
      
 69 
     | 
    
         
            +
                hash_src = {"name" => "value"}
         
     | 
| 
      
 70 
     | 
    
         
            +
                hash_dst = {}
         
     | 
| 
      
 71 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 72 
     | 
    
         
            +
                assert_equal(hash_src, hash_dst)
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                # hashes holding array
         
     | 
| 
      
 75 
     | 
    
         
            +
                hash_src = {"property" => ["1","3"]}
         
     | 
| 
      
 76 
     | 
    
         
            +
                hash_dst = {"property" => ["2","4"]}
         
     | 
| 
      
 77 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 78 
     | 
    
         
            +
                assert_equal(["2","4","1","3"], hash_dst['property'])
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                # hashes holding array (sorted)
         
     | 
| 
      
 81 
     | 
    
         
            +
                hash_src = {"property" => ["1","3"]}
         
     | 
| 
      
 82 
     | 
    
         
            +
                hash_dst = {"property" => ["2","4"]}
         
     | 
| 
      
 83 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:sort_merged_arrays => true})
         
     | 
| 
      
 84 
     | 
    
         
            +
                assert_equal(["1","2","3","4"].sort, hash_dst['property'])
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                # hashes holding hashes holding arrays (array with duplicate elements is merged with dest then src
         
     | 
| 
      
 87 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["1", "4+"]}}
         
     | 
| 
      
 88 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => ["3", "2"], "bathroom_count" => ["2"]}}
         
     | 
| 
      
 89 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 90 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => ["3","2","1"], "bathroom_count" => ["2", "1", "4+"]}}, hash_dst)
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                # hash holding hash holding array v string (string is overwritten by array)
         
     | 
| 
      
 93 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["1", "4+"]}}
         
     | 
| 
      
 94 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => "3", "bathroom_count" => ["2"]}}
         
     | 
| 
      
 95 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 96 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2","1","4+"]}}, hash_dst)
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                # hash holding hash holding array v string (string is NOT overwritten by array)
         
     | 
| 
      
 99 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["1", "4+"]}}
         
     | 
| 
      
 100 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => "3", "bathroom_count" => ["2"]}}
         
     | 
| 
      
 101 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:preserve_unmergeables => true})
         
     | 
| 
      
 102 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => "3", "bathroom_count" => ["2","1","4+"]}}, hash_dst)
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                # hash holding hash holding string v array (array is overwritten by string)
         
     | 
| 
      
 105 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => "3", "bathroom_count" => ["1", "4+"]}}
         
     | 
| 
      
 106 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2"]}}
         
     | 
| 
      
 107 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 108 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => "3", "bathroom_count" => ["2","1","4+"]}}, hash_dst)
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                # hash holding hash holding string v array (array does NOT overwrite string)
         
     | 
| 
      
 111 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => "3", "bathroom_count" => ["1", "4+"]}}
         
     | 
| 
      
 112 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2"]}}
         
     | 
| 
      
 113 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:preserve_unmergeables => true})
         
     | 
| 
      
 114 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2","1","4+"]}}, hash_dst)
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                # hash holding hash holding hash v array (array is overwritten by hash)
         
     | 
| 
      
 117 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["1", "4+"]}}
         
     | 
| 
      
 118 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2"]}}
         
     | 
| 
      
 119 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 120 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["2","1","4+"]}}, hash_dst)
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                # hash holding hash holding hash v array (array is NOT overwritten by hash)
         
     | 
| 
      
 123 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["1", "4+"]}}
         
     | 
| 
      
 124 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2"]}}
         
     | 
| 
      
 125 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:preserve_unmergeables => true})
         
     | 
| 
      
 126 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => ["1", "2"], "bathroom_count" => ["2","1","4+"]}}, hash_dst)
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                # 3 hash layers holding integers (integers are overwritten by source)
         
     | 
| 
      
 129 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["1", "4+"]}}
         
     | 
| 
      
 130 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => 2, "queen_bed" => 4}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 131 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 132 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => 1}, "bathroom_count" => ["2","1","4+"]}}, hash_dst)
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                # 3 hash layers holding arrays of int (arrays are merged)
         
     | 
| 
      
 135 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {"king_bed" => [3], "queen_bed" => [1]}, "bathroom_count" => ["1", "4+"]}}
         
     | 
| 
      
 136 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 137 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 138 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4,1]}, "bathroom_count" => ["2","1","4+"]}}, hash_dst)
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                # 1 hash overwriting 3 hash layers holding arrays of int
         
     | 
| 
      
 141 
     | 
    
         
            +
                hash_src = {"property" => "1"}
         
     | 
| 
      
 142 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 143 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 144 
     | 
    
         
            +
                assert_equal({"property" => "1"}, hash_dst)
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                # 1 hash NOT overwriting 3 hash layers holding arrays of int
         
     | 
| 
      
 147 
     | 
    
         
            +
                hash_src = {"property" => "1"}
         
     | 
| 
      
 148 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 149 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:preserve_unmergeables => true})
         
     | 
| 
      
 150 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}, hash_dst)
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                # 3 hash layers holding arrays of int (arrays are merged) but second hash's array is overwritten
         
     | 
| 
      
 153 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {"king_bed" => [3], "queen_bed" => [1]}, "bathroom_count" => "1"}}
         
     | 
| 
      
 154 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 155 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 156 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4,1]}, "bathroom_count" => "1"}}, hash_dst)
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                # 3 hash layers holding arrays of int (arrays are merged) but second hash's array is NOT overwritten
         
     | 
| 
      
 159 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {"king_bed" => [3], "queen_bed" => [1]}, "bathroom_count" => "1"}}
         
     | 
| 
      
 160 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 161 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:preserve_unmergeables => true})
         
     | 
| 
      
 162 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4,1]}, "bathroom_count" => ["2"]}}, hash_dst)
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                # 3 hash layers holding arrays of int, but one holds int. This one overwrites, but the rest merge
         
     | 
| 
      
 165 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => [1]}, "bathroom_count" => ["1"]}}
         
     | 
| 
      
 166 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 167 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 168 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {"king_bed" => 3, "queen_bed" => [4,1]}, "bathroom_count" => ["2","1"]}}, hash_dst)
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                # 3 hash layers holding arrays of int, but source is incomplete.
         
     | 
| 
      
 171 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {"king_bed" => [3]}, "bathroom_count" => ["1"]}}
         
     | 
| 
      
 172 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 173 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 174 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {"king_bed" => [2,3], "queen_bed" => [4]}, "bathroom_count" => ["2","1"]}}, hash_dst)
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                # 3 hash layers holding arrays of int, but source is shorter and has new 2nd level ints.
         
     | 
| 
      
 177 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {2=>3, "king_bed" => [3]}, "bathroom_count" => ["1"]}}
         
     | 
| 
      
 178 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 179 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 180 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {2=>3, "king_bed" => [2,3], "queen_bed" => [4]}, "bathroom_count" => ["2","1"]}}, hash_dst)
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                # 3 hash layers holding arrays of int, but source is empty
         
     | 
| 
      
 183 
     | 
    
         
            +
                hash_src = {}
         
     | 
| 
      
 184 
     | 
    
         
            +
                hash_dst = {"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}
         
     | 
| 
      
 185 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 186 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {"king_bed" => [2], "queen_bed" => [4]}, "bathroom_count" => ["2"]}}, hash_dst)
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                # 3 hash layers holding arrays of int, but dest is empty
         
     | 
| 
      
 189 
     | 
    
         
            +
                hash_src = {"property" => {"bedroom_count" => {2=>3, "king_bed" => [3]}, "bathroom_count" => ["1"]}}
         
     | 
| 
      
 190 
     | 
    
         
            +
                hash_dst = {}
         
     | 
| 
      
 191 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 192 
     | 
    
         
            +
                assert_equal({"property" => {"bedroom_count" => {2=>3, "king_bed" => [3]}, "bathroom_count" => ["1"]}}, hash_dst)
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                # test parameter management for knockout_prefix and overwrite unmergable
         
     | 
| 
      
 195 
     | 
    
         
            +
                assert_raise(DeepMerge::InvalidParameter) {DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => ""})}
         
     | 
| 
      
 196 
     | 
    
         
            +
                assert_raise(DeepMerge::InvalidParameter) {DeepMerge::deep_merge!(hash_src, hash_dst, {:preserve_unmergeables => true, :knockout_prefix => ""})}
         
     | 
| 
      
 197 
     | 
    
         
            +
                assert_raise(DeepMerge::InvalidParameter) {DeepMerge::deep_merge!(hash_src, hash_dst, {:preserve_unmergeables => true, :knockout_prefix => "--"})}
         
     | 
| 
      
 198 
     | 
    
         
            +
                assert_nothing_raised(DeepMerge::InvalidParameter) {DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => "--"})}
         
     | 
| 
      
 199 
     | 
    
         
            +
                assert_nothing_raised(DeepMerge::InvalidParameter) {DeepMerge::deep_merge!(hash_src, hash_dst)}
         
     | 
| 
      
 200 
     | 
    
         
            +
                assert_nothing_raised(DeepMerge::InvalidParameter) {DeepMerge::deep_merge!(hash_src, hash_dst, {:preserve_unmergeables => true})}
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
                # hash holding arrays of arrays
         
     | 
| 
      
 203 
     | 
    
         
            +
                hash_src = {["1", "2", "3"] => ["1", "2"]}
         
     | 
| 
      
 204 
     | 
    
         
            +
                hash_dst = {["4", "5"] => ["3"]}
         
     | 
| 
      
 205 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 206 
     | 
    
         
            +
                assert_equal({["1","2","3"] => ["1", "2"], ["4", "5"] => ["3"]}, hash_dst)
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                # test merging of hash with blank hash, and make sure that source array split still functions
         
     | 
| 
      
 209 
     | 
    
         
            +
                hash_src = {'property' => {'bedroom_count' => ["1","2,3"]}}
         
     | 
| 
      
 210 
     | 
    
         
            +
                hash_dst = {}
         
     | 
| 
      
 211 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 212 
     | 
    
         
            +
                assert_equal({'property' => {'bedroom_count' => ["1","2","3"]}}, hash_dst)
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
                # test merging of hash with blank hash, and make sure that source array split does not function when turned off
         
     | 
| 
      
 215 
     | 
    
         
            +
                hash_src = {'property' => {'bedroom_count' => ["1","2,3"]}}
         
     | 
| 
      
 216 
     | 
    
         
            +
                hash_dst = {}
         
     | 
| 
      
 217 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX})
         
     | 
| 
      
 218 
     | 
    
         
            +
                assert_equal({'property' => {'bedroom_count' => ["1","2,3"]}}, hash_dst)
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
                # test merging into a blank hash with overwrite_unmergeables turned on
         
     | 
| 
      
 221 
     | 
    
         
            +
                hash_src = {"action"=>"browse", "controller"=>"results"}
         
     | 
| 
      
 222 
     | 
    
         
            +
                hash_dst = {}
         
     | 
| 
      
 223 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:overwrite_unmergeables => true, :knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 224 
     | 
    
         
            +
                assert_equal hash_src, hash_dst
         
     | 
| 
      
 225 
     | 
    
         
            +
             
     | 
| 
      
 226 
     | 
    
         
            +
                # KNOCKOUT_PREFIX testing
         
     | 
| 
      
 227 
     | 
    
         
            +
                # the next few tests are looking for correct behavior from specific real-world params/session merges
         
     | 
| 
      
 228 
     | 
    
         
            +
                # using the custom modifiers built for param/session merges
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                [nil, ","].each do |ko_split|
         
     | 
| 
      
 231 
     | 
    
         
            +
                  # typical params/session style hash with knockout_merge elements
         
     | 
| 
      
 232 
     | 
    
         
            +
                  hash_params = {"property"=>{"bedroom_count"=>[FIELD_KNOCKOUT_PREFIX+"1", "2", "3"]}}
         
     | 
| 
      
 233 
     | 
    
         
            +
                  hash_session = {"property"=>{"bedroom_count"=>["1", "2", "3"]}}
         
     | 
| 
      
 234 
     | 
    
         
            +
                  DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ko_split})
         
     | 
| 
      
 235 
     | 
    
         
            +
                  assert_equal({"property"=>{"bedroom_count"=>["2", "3"]}}, hash_session)
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                  # typical params/session style hash with knockout_merge elements
         
     | 
| 
      
 238 
     | 
    
         
            +
                  hash_params = {"property"=>{"bedroom_count"=>[FIELD_KNOCKOUT_PREFIX+"1", "2", "3"]}}
         
     | 
| 
      
 239 
     | 
    
         
            +
                  hash_session = {"property"=>{"bedroom_count"=>["3"]}}
         
     | 
| 
      
 240 
     | 
    
         
            +
                  DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ko_split})
         
     | 
| 
      
 241 
     | 
    
         
            +
                  assert_equal({"property"=>{"bedroom_count"=>["3","2"]}}, hash_session)
         
     | 
| 
      
 242 
     | 
    
         
            +
             
     | 
| 
      
 243 
     | 
    
         
            +
                  # typical params/session style hash with knockout_merge elements
         
     | 
| 
      
 244 
     | 
    
         
            +
                  hash_params = {"property"=>{"bedroom_count"=>[FIELD_KNOCKOUT_PREFIX+"1", "2", "3"]}}
         
     | 
| 
      
 245 
     | 
    
         
            +
                  hash_session = {"property"=>{"bedroom_count"=>["4"]}}
         
     | 
| 
      
 246 
     | 
    
         
            +
                  DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ko_split})
         
     | 
| 
      
 247 
     | 
    
         
            +
                  assert_equal({"property"=>{"bedroom_count"=>["4","2","3"]}}, hash_session)
         
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
                  # typical params/session style hash with knockout_merge elements
         
     | 
| 
      
 250 
     | 
    
         
            +
                  hash_params = {"property"=>{"bedroom_count"=>[FIELD_KNOCKOUT_PREFIX+"1", "2", "3"]}}
         
     | 
| 
      
 251 
     | 
    
         
            +
                  hash_session = {"property"=>{"bedroom_count"=>[FIELD_KNOCKOUT_PREFIX+"1", "4"]}}
         
     | 
| 
      
 252 
     | 
    
         
            +
                  DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ko_split})
         
     | 
| 
      
 253 
     | 
    
         
            +
                  assert_equal({"property"=>{"bedroom_count"=>["4","2","3"]}}, hash_session)
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
      
 255 
     | 
    
         
            +
                  # typical params/session style hash with knockout_merge elements
         
     | 
| 
      
 256 
     | 
    
         
            +
                  hash_params = {"amenity"=>{"id"=>[FIELD_KNOCKOUT_PREFIX+"1", FIELD_KNOCKOUT_PREFIX+"2", "3", "4"]}}
         
     | 
| 
      
 257 
     | 
    
         
            +
                  hash_session = {"amenity"=>{"id"=>["1", "2"]}}
         
     | 
| 
      
 258 
     | 
    
         
            +
                  DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ko_split})
         
     | 
| 
      
 259 
     | 
    
         
            +
                  assert_equal({"amenity"=>{"id"=>["3","4"]}}, hash_session)
         
     | 
| 
      
 260 
     | 
    
         
            +
                end
         
     | 
| 
      
 261 
     | 
    
         
            +
             
     | 
| 
      
 262 
     | 
    
         
            +
                # special params/session style hash with knockout_merge elements in form src: ["1","2"] dest:["--1,--2", "3,4"]
         
     | 
| 
      
 263 
     | 
    
         
            +
                hash_params = {"amenity"=>{"id"=>[FIELD_KNOCKOUT_PREFIX+"1,"+FIELD_KNOCKOUT_PREFIX+"2", "3,4"]}}
         
     | 
| 
      
 264 
     | 
    
         
            +
                hash_session = {"amenity"=>{"id"=>["1", "2"]}}
         
     | 
| 
      
 265 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 266 
     | 
    
         
            +
                assert_equal({"amenity"=>{"id"=>["3","4"]}}, hash_session)
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
      
 268 
     | 
    
         
            +
                # same as previous but without ko_split value, this merge should fail
         
     | 
| 
      
 269 
     | 
    
         
            +
                hash_params = {"amenity"=>{"id"=>[FIELD_KNOCKOUT_PREFIX+"1,"+FIELD_KNOCKOUT_PREFIX+"2", "3,4"]}}
         
     | 
| 
      
 270 
     | 
    
         
            +
                hash_session = {"amenity"=>{"id"=>["1", "2"]}}
         
     | 
| 
      
 271 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX})
         
     | 
| 
      
 272 
     | 
    
         
            +
                assert_equal({"amenity"=>{"id"=>["1","2","3,4"]}}, hash_session)
         
     | 
| 
      
 273 
     | 
    
         
            +
             
     | 
| 
      
 274 
     | 
    
         
            +
                # special params/session style hash with knockout_merge elements in form src: ["1","2"] dest:["--1,--2", "3,4"]
         
     | 
| 
      
 275 
     | 
    
         
            +
                hash_params = {"amenity"=>{"id"=>[FIELD_KNOCKOUT_PREFIX+"1,2", "3,4", "--5", "6"]}}
         
     | 
| 
      
 276 
     | 
    
         
            +
                hash_session = {"amenity"=>{"id"=>["1", "2"]}}
         
     | 
| 
      
 277 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 278 
     | 
    
         
            +
                assert_equal({"amenity"=>{"id"=>["2","3","4","6"]}}, hash_session)
         
     | 
| 
      
 279 
     | 
    
         
            +
             
     | 
| 
      
 280 
     | 
    
         
            +
                # special params/session style hash with knockout_merge elements in form src: ["--1,--2", "3,4", "--5", "6"] dest:["1,2", "3,4"]
         
     | 
| 
      
 281 
     | 
    
         
            +
                hash_params = {"amenity"=>{"id"=>["#{FIELD_KNOCKOUT_PREFIX}1,#{FIELD_KNOCKOUT_PREFIX}2", "3,4", "#{FIELD_KNOCKOUT_PREFIX}5", "6"]}}
         
     | 
| 
      
 282 
     | 
    
         
            +
                hash_session = {"amenity"=>{"id"=>["1", "2", "3", "4"]}}
         
     | 
| 
      
 283 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 284 
     | 
    
         
            +
                assert_equal({"amenity"=>{"id"=>["3","4","6"]}}, hash_session)
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
      
 286 
     | 
    
         
            +
             
     | 
| 
      
 287 
     | 
    
         
            +
                hash_src = {"url_regions"=>[], "region"=>{"ids"=>["227,233"]}, "action"=>"browse", "task"=>"browse", "controller"=>"results"}
         
     | 
| 
      
 288 
     | 
    
         
            +
                hash_dst = {"region"=>{"ids"=>["227"]}}
         
     | 
| 
      
 289 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src.dup, hash_dst, {:overwrite_unmergeables => true, :knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 290 
     | 
    
         
            +
                assert_equal({"url_regions"=>[], "region"=>{"ids"=>["227","233"]}, "action"=>"browse", "task"=>"browse", "controller"=>"results"}, hash_dst)
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
                hash_src = {"region"=>{"ids"=>["--","227"], "id"=>"230"}}
         
     | 
| 
      
 293 
     | 
    
         
            +
                hash_dst = {"region"=>{"ids"=>["227", "233", "324", "230", "230"], "id"=>"230"}}
         
     | 
| 
      
 294 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:overwrite_unmergeables => true, :knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 295 
     | 
    
         
            +
                assert_equal({"region"=>{"ids"=>["227"], "id"=>"230"}}, hash_dst)
         
     | 
| 
      
 296 
     | 
    
         
            +
             
     | 
| 
      
 297 
     | 
    
         
            +
                hash_src = {"region"=>{"ids"=>["--","227", "232", "233"], "id"=>"232"}}
         
     | 
| 
      
 298 
     | 
    
         
            +
                hash_dst = {"region"=>{"ids"=>["227", "233", "324", "230", "230"], "id"=>"230"}}
         
     | 
| 
      
 299 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:overwrite_unmergeables => true, :knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 300 
     | 
    
         
            +
                assert_equal({"region"=>{"ids"=>["227", "232", "233"], "id"=>"232"}}, hash_dst)
         
     | 
| 
      
 301 
     | 
    
         
            +
             
     | 
| 
      
 302 
     | 
    
         
            +
                hash_src = {"region"=>{"ids"=>["--,227,232,233"], "id"=>"232"}}
         
     | 
| 
      
 303 
     | 
    
         
            +
                hash_dst = {"region"=>{"ids"=>["227", "233", "324", "230", "230"], "id"=>"230"}}
         
     | 
| 
      
 304 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:overwrite_unmergeables => true, :knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 305 
     | 
    
         
            +
                assert_equal({"region"=>{"ids"=>["227", "232", "233"], "id"=>"232"}}, hash_dst)
         
     | 
| 
      
 306 
     | 
    
         
            +
             
     | 
| 
      
 307 
     | 
    
         
            +
                hash_src = {"region"=>{"ids"=>["--,227,232","233"], "id"=>"232"}}
         
     | 
| 
      
 308 
     | 
    
         
            +
                hash_dst = {"region"=>{"ids"=>["227", "233", "324", "230", "230"], "id"=>"230"}}
         
     | 
| 
      
 309 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:overwrite_unmergeables => true, :knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 310 
     | 
    
         
            +
                assert_equal({"region"=>{"ids"=>["227", "232", "233"], "id"=>"232"}}, hash_dst)
         
     | 
| 
      
 311 
     | 
    
         
            +
             
     | 
| 
      
 312 
     | 
    
         
            +
                hash_src = {"region"=>{"ids"=>["--,227"], "id"=>"230"}}
         
     | 
| 
      
 313 
     | 
    
         
            +
                hash_dst = {"region"=>{"ids"=>["227", "233", "324", "230", "230"], "id"=>"230"}}
         
     | 
| 
      
 314 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:overwrite_unmergeables => true, :knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 315 
     | 
    
         
            +
                assert_equal({"region"=>{"ids"=>["227"], "id"=>"230"}}, hash_dst)
         
     | 
| 
      
 316 
     | 
    
         
            +
             
     | 
| 
      
 317 
     | 
    
         
            +
                hash_src = {"region"=>{"ids"=>["--,227"], "id"=>"230"}}
         
     | 
| 
      
 318 
     | 
    
         
            +
                hash_dst = {"region"=>{"ids"=>["227", "233", "324", "230", "230"], "id"=>"230"}, "action"=>"browse", "task"=>"browse", "controller"=>"results", "property_order_by"=>"property_type.descr"}
         
     | 
| 
      
 319 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:overwrite_unmergeables => true, :knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 320 
     | 
    
         
            +
                assert_equal({"region"=>{"ids"=>["227"], "id"=>"230"}, "action"=>"browse", "task"=>"browse",
         
     | 
| 
      
 321 
     | 
    
         
            +
                  "controller"=>"results", "property_order_by"=>"property_type.descr"}, hash_dst)
         
     | 
| 
      
 322 
     | 
    
         
            +
             
     | 
| 
      
 323 
     | 
    
         
            +
                hash_src = {"query_uuid"=>"6386333d-389b-ab5c-8943-6f3a2aa914d7", "region"=>{"ids"=>["--,227"], "id"=>"230"}}
         
     | 
| 
      
 324 
     | 
    
         
            +
                hash_dst = {"query_uuid"=>"6386333d-389b-ab5c-8943-6f3a2aa914d7", "url_regions"=>[], "region"=>{"ids"=>["227", "233", "324", "230", "230"], "id"=>"230"}, "action"=>"browse", "task"=>"browse", "controller"=>"results", "property_order_by"=>"property_type.descr"}
         
     | 
| 
      
 325 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:overwrite_unmergeables => true, :knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 326 
     | 
    
         
            +
                assert_equal({"query_uuid" => "6386333d-389b-ab5c-8943-6f3a2aa914d7", "url_regions"=>[],
         
     | 
| 
      
 327 
     | 
    
         
            +
                  "region"=>{"ids"=>["227"], "id"=>"230"}, "action"=>"browse", "task"=>"browse",
         
     | 
| 
      
 328 
     | 
    
         
            +
                  "controller"=>"results", "property_order_by"=>"property_type.descr"}, hash_dst)
         
     | 
| 
      
 329 
     | 
    
         
            +
             
     | 
| 
      
 330 
     | 
    
         
            +
                # knock out entire dest hash if "--" is passed for source
         
     | 
| 
      
 331 
     | 
    
         
            +
                hash_params = {'amenity' => "--"}
         
     | 
| 
      
 332 
     | 
    
         
            +
                hash_session = {"amenity" => "1"}
         
     | 
| 
      
 333 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => "--", :unpack_arrays => ","})
         
     | 
| 
      
 334 
     | 
    
         
            +
                assert_equal({'amenity' => ""}, hash_session)
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
                # knock out entire dest hash if "--" is passed for source
         
     | 
| 
      
 337 
     | 
    
         
            +
                hash_params = {'amenity' => ["--"]}
         
     | 
| 
      
 338 
     | 
    
         
            +
                hash_session = {"amenity" => "1"}
         
     | 
| 
      
 339 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => "--", :unpack_arrays => ","})
         
     | 
| 
      
 340 
     | 
    
         
            +
                assert_equal({'amenity' => []}, hash_session)
         
     | 
| 
      
 341 
     | 
    
         
            +
             
     | 
| 
      
 342 
     | 
    
         
            +
                # knock out entire dest hash if "--" is passed for source
         
     | 
| 
      
 343 
     | 
    
         
            +
                hash_params = {'amenity' => "--"}
         
     | 
| 
      
 344 
     | 
    
         
            +
                hash_session = {"amenity" => ["1"]}
         
     | 
| 
      
 345 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => "--", :unpack_arrays => ","})
         
     | 
| 
      
 346 
     | 
    
         
            +
                assert_equal({'amenity' => ""}, hash_session)
         
     | 
| 
      
 347 
     | 
    
         
            +
             
     | 
| 
      
 348 
     | 
    
         
            +
                # knock out entire dest hash if "--" is passed for source
         
     | 
| 
      
 349 
     | 
    
         
            +
                hash_params = {'amenity' => ["--"]}
         
     | 
| 
      
 350 
     | 
    
         
            +
                hash_session = {"amenity" => ["1"]}
         
     | 
| 
      
 351 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => "--", :unpack_arrays => ","})
         
     | 
| 
      
 352 
     | 
    
         
            +
                assert_equal({'amenity' => []}, hash_session)
         
     | 
| 
      
 353 
     | 
    
         
            +
             
     | 
| 
      
 354 
     | 
    
         
            +
                # knock out entire dest hash if "--" is passed for source
         
     | 
| 
      
 355 
     | 
    
         
            +
                hash_params = {'amenity' => ["--"]}
         
     | 
| 
      
 356 
     | 
    
         
            +
                hash_session = {"amenity" => "1"}
         
     | 
| 
      
 357 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => "--", :unpack_arrays => ","})
         
     | 
| 
      
 358 
     | 
    
         
            +
                assert_equal({'amenity' => []}, hash_session)
         
     | 
| 
      
 359 
     | 
    
         
            +
             
     | 
| 
      
 360 
     | 
    
         
            +
                # knock out entire dest hash if "--" is passed for source
         
     | 
| 
      
 361 
     | 
    
         
            +
                hash_params = {'amenity' => ["--", "2"]}
         
     | 
| 
      
 362 
     | 
    
         
            +
                hash_session = {'amenity' => ["1", "3", "7+"]}
         
     | 
| 
      
 363 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => "--", :unpack_arrays => ","})
         
     | 
| 
      
 364 
     | 
    
         
            +
                assert_equal({'amenity' => ["2"]}, hash_session)
         
     | 
| 
      
 365 
     | 
    
         
            +
             
     | 
| 
      
 366 
     | 
    
         
            +
                # knock out entire dest hash if "--" is passed for source
         
     | 
| 
      
 367 
     | 
    
         
            +
                hash_params = {'amenity' => ["--", "2"]}
         
     | 
| 
      
 368 
     | 
    
         
            +
                hash_session = {'amenity' => "5"}
         
     | 
| 
      
 369 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => "--", :unpack_arrays => ","})
         
     | 
| 
      
 370 
     | 
    
         
            +
                assert_equal({'amenity' => ['2']}, hash_session)
         
     | 
| 
      
 371 
     | 
    
         
            +
             
     | 
| 
      
 372 
     | 
    
         
            +
                # knock out entire dest hash if "--" is passed for source
         
     | 
| 
      
 373 
     | 
    
         
            +
                hash_params = {'amenity' => "--"}
         
     | 
| 
      
 374 
     | 
    
         
            +
                hash_session = {"amenity"=>{"id"=>["1", "2", "3", "4"]}}
         
     | 
| 
      
 375 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => "--", :unpack_arrays => ","})
         
     | 
| 
      
 376 
     | 
    
         
            +
                assert_equal({'amenity' => ""}, hash_session)
         
     | 
| 
      
 377 
     | 
    
         
            +
             
     | 
| 
      
 378 
     | 
    
         
            +
                # knock out entire dest hash if "--" is passed for source
         
     | 
| 
      
 379 
     | 
    
         
            +
                hash_params = {'amenity' => ["--"]}
         
     | 
| 
      
 380 
     | 
    
         
            +
                hash_session = {"amenity"=>{"id"=>["1", "2", "3", "4"]}}
         
     | 
| 
      
 381 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => "--", :unpack_arrays => ","})
         
     | 
| 
      
 382 
     | 
    
         
            +
                assert_equal({'amenity' => []}, hash_session)
         
     | 
| 
      
 383 
     | 
    
         
            +
             
     | 
| 
      
 384 
     | 
    
         
            +
                # knock out dest array if "--" is passed for source
         
     | 
| 
      
 385 
     | 
    
         
            +
                hash_params = {"region" => {'ids' => FIELD_KNOCKOUT_PREFIX}}
         
     | 
| 
      
 386 
     | 
    
         
            +
                hash_session = {"region"=>{"ids"=>["1", "2", "3", "4"]}}
         
     | 
| 
      
 387 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 388 
     | 
    
         
            +
                assert_equal({'region' => {'ids' => ""}}, hash_session)
         
     | 
| 
      
 389 
     | 
    
         
            +
             
     | 
| 
      
 390 
     | 
    
         
            +
                # knock out dest array but leave other elements of hash intact
         
     | 
| 
      
 391 
     | 
    
         
            +
                hash_params = {"region" => {'ids' => FIELD_KNOCKOUT_PREFIX}}
         
     | 
| 
      
 392 
     | 
    
         
            +
                hash_session = {"region"=>{"ids"=>["1", "2", "3", "4"], 'id'=>'11'}}
         
     | 
| 
      
 393 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 394 
     | 
    
         
            +
                assert_equal({'region' => {'ids' => "", 'id'=>'11'}}, hash_session)
         
     | 
| 
      
 395 
     | 
    
         
            +
             
     | 
| 
      
 396 
     | 
    
         
            +
                # knock out entire tree of dest hash
         
     | 
| 
      
 397 
     | 
    
         
            +
                hash_params = {"region" => FIELD_KNOCKOUT_PREFIX}
         
     | 
| 
      
 398 
     | 
    
         
            +
                hash_session = {"region"=>{"ids"=>["1", "2", "3", "4"], 'id'=>'11'}}
         
     | 
| 
      
 399 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 400 
     | 
    
         
            +
                assert_equal({'region' => ""}, hash_session)
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
      
 402 
     | 
    
         
            +
                # knock out entire tree of dest hash - retaining array format
         
     | 
| 
      
 403 
     | 
    
         
            +
                hash_params = {"region" => {'ids' => [FIELD_KNOCKOUT_PREFIX]}}
         
     | 
| 
      
 404 
     | 
    
         
            +
                hash_session = {"region"=>{"ids"=>["1", "2", "3", "4"], 'id'=>'11'}}
         
     | 
| 
      
 405 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 406 
     | 
    
         
            +
                assert_equal({'region' => {'ids' => [], 'id'=>'11'}}, hash_session)
         
     | 
| 
      
 407 
     | 
    
         
            +
             
     | 
| 
      
 408 
     | 
    
         
            +
                # knock out entire tree of dest hash & replace with new content
         
     | 
| 
      
 409 
     | 
    
         
            +
                hash_params = {"region" => {'ids' => ["2", FIELD_KNOCKOUT_PREFIX, "6"]}}
         
     | 
| 
      
 410 
     | 
    
         
            +
                hash_session = {"region"=>{"ids"=>["1", "2", "3", "4"], 'id'=>'11'}}
         
     | 
| 
      
 411 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 412 
     | 
    
         
            +
                assert_equal({'region' => {'ids' => ["2", "6"], 'id'=>'11'}}, hash_session)
         
     | 
| 
      
 413 
     | 
    
         
            +
             
     | 
| 
      
 414 
     | 
    
         
            +
                # knock out entire tree of dest hash & replace with new content
         
     | 
| 
      
 415 
     | 
    
         
            +
                hash_params = {"region" => {'ids' => ["7", FIELD_KNOCKOUT_PREFIX, "6"]}}
         
     | 
| 
      
 416 
     | 
    
         
            +
                hash_session = {"region"=>{"ids"=>["1", "2", "3", "4"], 'id'=>'11'}}
         
     | 
| 
      
 417 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 418 
     | 
    
         
            +
                assert_equal({'region' => {'ids' => ["7", "6"], 'id'=>'11'}}, hash_session)
         
     | 
| 
      
 419 
     | 
    
         
            +
             
     | 
| 
      
 420 
     | 
    
         
            +
                # edge test: make sure that when we turn off knockout_prefix that all values are processed correctly
         
     | 
| 
      
 421 
     | 
    
         
            +
                hash_params = {"region" => {'ids' => ["7", "--", "2", "6,8"]}}
         
     | 
| 
      
 422 
     | 
    
         
            +
                hash_session = {"region"=>{"ids"=>["1", "2", "3", "4"], 'id'=>'11'}}
         
     | 
| 
      
 423 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:unpack_arrays => ","})
         
     | 
| 
      
 424 
     | 
    
         
            +
                assert_equal({'region' => {'ids' => ["1", "2", "3", "4", "7", "--", "6", "8"], 'id'=>'11'}}, hash_session)
         
     | 
| 
      
 425 
     | 
    
         
            +
             
     | 
| 
      
 426 
     | 
    
         
            +
                # edge test 2: make sure that when we turn off source array split that all values are processed correctly
         
     | 
| 
      
 427 
     | 
    
         
            +
                hash_params = {"region" => {'ids' => ["7", "3", "--", "6,8"]}}
         
     | 
| 
      
 428 
     | 
    
         
            +
                hash_session = {"region"=>{"ids"=>["1", "2", "3", "4"], 'id'=>'11'}}
         
     | 
| 
      
 429 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session)
         
     | 
| 
      
 430 
     | 
    
         
            +
                assert_equal({'region' => {'ids' => ["1", "2", "3", "4", "7", "--", "6,8"], 'id'=>'11'}}, hash_session)
         
     | 
| 
      
 431 
     | 
    
         
            +
             
     | 
| 
      
 432 
     | 
    
         
            +
                # Example: src = {'key' => "--1"}, dst = {'key' => "1"} -> merges to {'key' => ""}
         
     | 
| 
      
 433 
     | 
    
         
            +
                hash_params = {"amenity"=>"--1"}
         
     | 
| 
      
 434 
     | 
    
         
            +
                hash_session = {"amenity"=>"1"}
         
     | 
| 
      
 435 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX})
         
     | 
| 
      
 436 
     | 
    
         
            +
                assert_equal({"amenity"=>""}, hash_session)
         
     | 
| 
      
 437 
     | 
    
         
            +
             
     | 
| 
      
 438 
     | 
    
         
            +
                # Example: src = {'key' => "--1"}, dst = {'key' => "2"} -> merges to {'key' => ""}
         
     | 
| 
      
 439 
     | 
    
         
            +
                hash_params = {"amenity"=>"--1"}
         
     | 
| 
      
 440 
     | 
    
         
            +
                hash_session = {"amenity"=>"2"}
         
     | 
| 
      
 441 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX})
         
     | 
| 
      
 442 
     | 
    
         
            +
                assert_equal({"amenity"=>""}, hash_session)
         
     | 
| 
      
 443 
     | 
    
         
            +
             
     | 
| 
      
 444 
     | 
    
         
            +
                # Example: src = {'key' => "--1"}, dst = {'key' => "1"} -> merges to {'key' => ""}
         
     | 
| 
      
 445 
     | 
    
         
            +
                hash_params = {"amenity"=>["--1"]}
         
     | 
| 
      
 446 
     | 
    
         
            +
                hash_session = {"amenity"=>"1"}
         
     | 
| 
      
 447 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX})
         
     | 
| 
      
 448 
     | 
    
         
            +
                assert_equal({"amenity"=>[]}, hash_session)
         
     | 
| 
      
 449 
     | 
    
         
            +
             
     | 
| 
      
 450 
     | 
    
         
            +
                # Example: src = {'key' => "--1"}, dst = {'key' => "1"} -> merges to {'key' => ""}
         
     | 
| 
      
 451 
     | 
    
         
            +
                hash_params = {"amenity"=>["--1"]}
         
     | 
| 
      
 452 
     | 
    
         
            +
                hash_session = {"amenity"=>["1"]}
         
     | 
| 
      
 453 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX})
         
     | 
| 
      
 454 
     | 
    
         
            +
                assert_equal({"amenity"=>[]}, hash_session)
         
     | 
| 
      
 455 
     | 
    
         
            +
             
     | 
| 
      
 456 
     | 
    
         
            +
                # Example: src = {'key' => "--1"}, dst = {'key' => "1"} -> merges to {'key' => ""}
         
     | 
| 
      
 457 
     | 
    
         
            +
                hash_params = {"amenity"=>"--1"}
         
     | 
| 
      
 458 
     | 
    
         
            +
                hash_session = {}
         
     | 
| 
      
 459 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX})
         
     | 
| 
      
 460 
     | 
    
         
            +
                assert_equal({"amenity"=>""}, hash_session)
         
     | 
| 
      
 461 
     | 
    
         
            +
             
     | 
| 
      
 462 
     | 
    
         
            +
             
     | 
| 
      
 463 
     | 
    
         
            +
                # Example: src = {'key' => "--1"}, dst = {'key' => "1"} -> merges to {'key' => ""}
         
     | 
| 
      
 464 
     | 
    
         
            +
                hash_params = {"amenity"=>"--1"}
         
     | 
| 
      
 465 
     | 
    
         
            +
                hash_session = {"amenity"=>["1"]}
         
     | 
| 
      
 466 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX})
         
     | 
| 
      
 467 
     | 
    
         
            +
                assert_equal({"amenity"=>""}, hash_session)
         
     | 
| 
      
 468 
     | 
    
         
            +
             
     | 
| 
      
 469 
     | 
    
         
            +
                #are unmerged hashes passed unmodified w/out :unpack_arrays?
         
     | 
| 
      
 470 
     | 
    
         
            +
                hash_params = {"amenity"=>{"id"=>["26,27"]}}
         
     | 
| 
      
 471 
     | 
    
         
            +
                hash_session = {}
         
     | 
| 
      
 472 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX})
         
     | 
| 
      
 473 
     | 
    
         
            +
                assert_equal({"amenity"=>{"id"=>["26,27"]}}, hash_session)
         
     | 
| 
      
 474 
     | 
    
         
            +
             
     | 
| 
      
 475 
     | 
    
         
            +
                #hash should be merged
         
     | 
| 
      
 476 
     | 
    
         
            +
                hash_params = {"amenity"=>{"id"=>["26,27"]}}
         
     | 
| 
      
 477 
     | 
    
         
            +
                hash_session = {}
         
     | 
| 
      
 478 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 479 
     | 
    
         
            +
                assert_equal({"amenity"=>{"id"=>["26","27"]}}, hash_session)
         
     | 
| 
      
 480 
     | 
    
         
            +
             
     | 
| 
      
 481 
     | 
    
         
            +
                # second merge of same values should result in no change in output
         
     | 
| 
      
 482 
     | 
    
         
            +
                hash_params = {"amenity"=>{"id"=>["26,27"]}}
         
     | 
| 
      
 483 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 484 
     | 
    
         
            +
                assert_equal({"amenity"=>{"id"=>["26","27"]}}, hash_session)
         
     | 
| 
      
 485 
     | 
    
         
            +
             
     | 
| 
      
 486 
     | 
    
         
            +
                #hashes with knockout values are suppressed
         
     | 
| 
      
 487 
     | 
    
         
            +
                hash_params = {"amenity"=>{"id"=>["#{FIELD_KNOCKOUT_PREFIX}26,#{FIELD_KNOCKOUT_PREFIX}27,28"]}}
         
     | 
| 
      
 488 
     | 
    
         
            +
                hash_session = {}
         
     | 
| 
      
 489 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_params, hash_session, {:knockout_prefix => FIELD_KNOCKOUT_PREFIX, :unpack_arrays => ","})
         
     | 
| 
      
 490 
     | 
    
         
            +
                assert_equal({"amenity"=>{"id"=>["28"]}}, hash_session)
         
     | 
| 
      
 491 
     | 
    
         
            +
             
     | 
| 
      
 492 
     | 
    
         
            +
                hash_src= {'region' =>{'ids'=>['--']}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 493 
     | 
    
         
            +
                hash_dst= {'region' =>{'ids'=>['227','2','3','3']}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 494 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 495 
     | 
    
         
            +
                assert_equal({'region' =>{'ids'=>[]}, 'query_uuid' => 'zzz'}, hash_dst)
         
     | 
| 
      
 496 
     | 
    
         
            +
             
     | 
| 
      
 497 
     | 
    
         
            +
                hash_src= {'region' =>{'ids'=>['--']}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 498 
     | 
    
         
            +
                hash_dst= {'region' =>{'ids'=>['227','2','3','3'], 'id' => '3'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 499 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 500 
     | 
    
         
            +
                assert_equal({'region' =>{'ids'=>[], 'id'=>'3'}, 'query_uuid' => 'zzz'}, hash_dst)
         
     | 
| 
      
 501 
     | 
    
         
            +
             
     | 
| 
      
 502 
     | 
    
         
            +
                hash_src= {'region' =>{'ids'=>['--']}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 503 
     | 
    
         
            +
                hash_dst= {'region' =>{'muni_city_id' => '2244', 'ids'=>['227','2','3','3'], 'id'=>'3'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 504 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 505 
     | 
    
         
            +
                assert_equal({'region' =>{'muni_city_id' => '2244', 'ids'=>[], 'id'=>'3'}, 'query_uuid' => 'zzz'}, hash_dst)
         
     | 
| 
      
 506 
     | 
    
         
            +
             
     | 
| 
      
 507 
     | 
    
         
            +
                hash_src= {'region' =>{'ids'=>['--'], 'id' => '5'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 508 
     | 
    
         
            +
                hash_dst= {'region' =>{'muni_city_id' => '2244', 'ids'=>['227','2','3','3'], 'id'=>'3'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 509 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 510 
     | 
    
         
            +
                assert_equal({'region' =>{'muni_city_id' => '2244', 'ids'=>[], 'id'=>'5'}, 'query_uuid' => 'zzz'}, hash_dst)
         
     | 
| 
      
 511 
     | 
    
         
            +
             
     | 
| 
      
 512 
     | 
    
         
            +
                hash_src= {'region' =>{'ids'=>['--', '227'], 'id' => '5'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 513 
     | 
    
         
            +
                hash_dst= {'region' =>{'muni_city_id' => '2244', 'ids'=>['227','2','3','3'], 'id'=>'3'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 514 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 515 
     | 
    
         
            +
                assert_equal({'region' =>{'muni_city_id' => '2244', 'ids'=>['227'], 'id'=>'5'}, 'query_uuid' => 'zzz'}, hash_dst)
         
     | 
| 
      
 516 
     | 
    
         
            +
             
     | 
| 
      
 517 
     | 
    
         
            +
                hash_src= {'region' =>{'muni_city_id' => '--', 'ids'=>'--', 'id'=>'5'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 518 
     | 
    
         
            +
                hash_dst= {'region' =>{'muni_city_id' => '2244', 'ids'=>['227','2','3','3'], 'id'=>'3'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 519 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 520 
     | 
    
         
            +
                assert_equal({'region' =>{'muni_city_id' => '', 'ids'=>'', 'id'=>'5'}, 'query_uuid' => 'zzz'}, hash_dst)
         
     | 
| 
      
 521 
     | 
    
         
            +
             
     | 
| 
      
 522 
     | 
    
         
            +
                hash_src= {'region' =>{'muni_city_id' => '--', 'ids'=>['--'], 'id'=>'5'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 523 
     | 
    
         
            +
                hash_dst= {'region' =>{'muni_city_id' => '2244', 'ids'=>['227','2','3','3'], 'id'=>'3'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 524 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 525 
     | 
    
         
            +
                assert_equal({'region' =>{'muni_city_id' => '', 'ids'=>[], 'id'=>'5'}, 'query_uuid' => 'zzz'}, hash_dst)
         
     | 
| 
      
 526 
     | 
    
         
            +
             
     | 
| 
      
 527 
     | 
    
         
            +
                hash_src= {'region' =>{'muni_city_id' => '--', 'ids'=>['--','227'], 'id'=>'5'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 528 
     | 
    
         
            +
                hash_dst= {'region' =>{'muni_city_id' => '2244', 'ids'=>['227','2','3','3'], 'id'=>'3'}, 'query_uuid' => 'zzz'}
         
     | 
| 
      
 529 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 530 
     | 
    
         
            +
                assert_equal({'region' =>{'muni_city_id' => '', 'ids'=>['227'], 'id'=>'5'}, 'query_uuid' => 'zzz'}, hash_dst)
         
     | 
| 
      
 531 
     | 
    
         
            +
             
     | 
| 
      
 532 
     | 
    
         
            +
                hash_src = {"muni_city_id"=>"--", "id"=>""}
         
     | 
| 
      
 533 
     | 
    
         
            +
                hash_dst = {"muni_city_id"=>"", "id"=>""}
         
     | 
| 
      
 534 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 535 
     | 
    
         
            +
                assert_equal({"muni_city_id"=>"", "id"=>""}, hash_dst)
         
     | 
| 
      
 536 
     | 
    
         
            +
             
     | 
| 
      
 537 
     | 
    
         
            +
                hash_src = {"region"=>{"muni_city_id"=>"--", "id"=>""}}
         
     | 
| 
      
 538 
     | 
    
         
            +
                hash_dst = {"region"=>{"muni_city_id"=>"", "id"=>""}}
         
     | 
| 
      
 539 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 540 
     | 
    
         
            +
                assert_equal({"region"=>{"muni_city_id"=>"", "id"=>""}}, hash_dst)
         
     | 
| 
      
 541 
     | 
    
         
            +
             
     | 
| 
      
 542 
     | 
    
         
            +
                hash_src = {"query_uuid"=>"a0dc3c84-ec7f-6756-bdb0-fff9157438ab", "url_regions"=>[], "region"=>{"muni_city_id"=>"--", "id"=>""}, "property"=>{"property_type_id"=>"", "search_rate_min"=>"", "search_rate_max"=>""}, "task"=>"search", "run_query"=>"Search"}
         
     | 
| 
      
 543 
     | 
    
         
            +
                hash_dst = {"query_uuid"=>"a0dc3c84-ec7f-6756-bdb0-fff9157438ab", "url_regions"=>[], "region"=>{"muni_city_id"=>"", "id"=>""}, "property"=>{"property_type_id"=>"", "search_rate_min"=>"", "search_rate_max"=>""}, "task"=>"search", "run_query"=>"Search"}
         
     | 
| 
      
 544 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst, {:knockout_prefix => '--', :unpack_arrays => ","})
         
     | 
| 
      
 545 
     | 
    
         
            +
                assert_equal({"query_uuid"=>"a0dc3c84-ec7f-6756-bdb0-fff9157438ab", "url_regions"=>[], "region"=>{"muni_city_id"=>"", "id"=>""}, "property"=>{"property_type_id"=>"", "search_rate_min"=>"", "search_rate_max"=>""}, "task"=>"search", "run_query"=>"Search"}, hash_dst)
         
     | 
| 
      
 546 
     | 
    
         
            +
             
     | 
| 
      
 547 
     | 
    
         
            +
                # hash of array of hashes
         
     | 
| 
      
 548 
     | 
    
         
            +
                hash_src = {"item" => [{"1" => "3"}, {"2" => "4"}]}
         
     | 
| 
      
 549 
     | 
    
         
            +
                hash_dst = {"item" => [{"3" => "5"}]}
         
     | 
| 
      
 550 
     | 
    
         
            +
                DeepMerge::deep_merge!(hash_src, hash_dst)
         
     | 
| 
      
 551 
     | 
    
         
            +
                assert_equal({"item" => [{"3" => "5"}, {"1" => "3"}, {"2" => "4"}]}, hash_dst)
         
     | 
| 
      
 552 
     | 
    
         
            +
              end # test_deep_merge
         
     | 
| 
      
 553 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: deep_merge
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Steve Midgley
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: deep_merge
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2008-05-18 00:00:00 -07:00
         
     | 
| 
      
 13 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 14 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            description: 
         
     | 
| 
      
 17 
     | 
    
         
            +
            email: public@misuse.org
         
     | 
| 
      
 18 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            extra_rdoc_files: 
         
     | 
| 
      
 23 
     | 
    
         
            +
            - README
         
     | 
| 
      
 24 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 25 
     | 
    
         
            +
            - lib/deep_merge.rb
         
     | 
| 
      
 26 
     | 
    
         
            +
            - test/test_deep_merge.rb
         
     | 
| 
      
 27 
     | 
    
         
            +
            - README
         
     | 
| 
      
 28 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 29 
     | 
    
         
            +
            homepage: 
         
     | 
| 
      
 30 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 31 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 34 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 35 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 36 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 37 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 38 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 39 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 40 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 41 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 42 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 43 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 44 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 45 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 46 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 47 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 50 
     | 
    
         
            +
            rubygems_version: 0.9.5
         
     | 
| 
      
 51 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 52 
     | 
    
         
            +
            specification_version: 2
         
     | 
| 
      
 53 
     | 
    
         
            +
            summary: Permits recursive/deep merges of arrays and hashes.
         
     | 
| 
      
 54 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     |