Sha256: e3c1052b18b2a0870e6974835ecb8311b6187ecbd7bcba83b995c00456d25b14

Contents?: true

Size: 1.95 KB

Versions: 2

Compression:

Stored size: 1.95 KB

Contents

require 'json'

# ~*~ encoding: utf-8 ~*~
module Aladdin

  module Support

    # Provides a rich comparison with weak-typing.
    # @see #same?
    module WeakComparator

      # Compares +submitted+ against +saved+ and returns a simple diff. Assumes
      # that:
      # - +saved+ is a ruby-marshalled value that carries rich type information
      # - +submitted+ is a user-submitted value that is either a string or an
      #   hash
      #
      # === Booleans
      # If +saved+ is +true+, then it will accept any +submitted+ value that
      # begins with 'T' or 't'. Similarly, if +saved+ is +false+, then it will
      # accept any +submitted+ value that begins with 'F' or 'f'.
      #
      # === Numerics
      # If +saved+ is a numeric, then it will accept any +submitted+ value that
      # is numerically equivalent to +saved+. For example, if +saved+ is 0,
      # then both +'0.0'+ and +'0'+ will be accepted.
      #
      # @param [String, Hash] submitted
      # @param [String, Numeric, Boolean, Hash] saved
      # @return [Boolean, Hash] diff
      def same?(submitted, saved)
        case saved
        when Hash
          Hash === submitted and same_hash? submitted, saved
        when String then saved == submitted
        when Numeric then saved == JSON.parse(%|[#{submitted}]|).first
        when TrueClass, FalseClass then saved.to_s[0] == submitted.downcase[0]
        else false end
      rescue
        false
      end

      private

      # Compares two hashes and returns a simple diff. It checks that both
      # +submitted+ and +saved+ have the same number of keys, and then
      # compares all key-value pairs in order.
      #
      # @param [Hash] submitted
      # @param [Hash] saved
      # @return [Boolean, Hash] diff
      # @see #same?
      def same_hash?(submitted, saved)
        saved.count == submitted.count and
          Hash[saved.map { |key, value| [key, same?(submitted[key], value)] }]
      end

      extend self

    end

  end

end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
aladdin-0.1.0.pre.1 lib/aladdin/support/weak_comparator.rb
aladdin-0.1.0.pre lib/aladdin/support/weak_comparator.rb