class WebMock::BodyPattern

Constants

BODY_FORMATS

Attributes

pattern[R]

Public Class Methods

new(pattern) click to toggle source
# File lib/webmock/request_pattern.rb, line 268
def initialize(pattern)
  @pattern = if pattern.is_a?(Hash)
    normalize_hash(pattern)
  elsif rSpecHashIncludingMatcher?(pattern)
    WebMock::Matchers::HashIncludingMatcher.from_rspec_matcher(pattern)
  else
    pattern
  end
end

Public Instance Methods

matches?(body, content_type = "") click to toggle source
# File lib/webmock/request_pattern.rb, line 278
def matches?(body, content_type = "")
  assert_non_multipart_body(content_type)

  if (@pattern).is_a?(Hash)
    return true if @pattern.empty?
    matching_body_hashes?(body_as_hash(body, content_type), @pattern, content_type)
  elsif (@pattern).is_a?(Array)
    matching_body_array?(body_as_hash(body, content_type), @pattern, content_type)
  elsif (@pattern).is_a?(WebMock::Matchers::HashIncludingMatcher)
    @pattern == body_as_hash(body, content_type)
  else
    empty_string?(@pattern) && empty_string?(body) ||
      @pattern == body ||
      @pattern === body
  end
end
to_s() click to toggle source
# File lib/webmock/request_pattern.rb, line 295
def to_s
  @pattern.inspect
end

Private Instance Methods

assert_non_multipart_body(content_type) click to toggle source
# File lib/webmock/request_pattern.rb, line 317
def assert_non_multipart_body(content_type)
  if content_type =~ %r{^multipart/form-data}
    raise ArgumentError.new("WebMock does not support matching body for multipart/form-data requests yet :(")
  end
end
body_as_hash(body, content_type) click to toggle source
# File lib/webmock/request_pattern.rb, line 301
def body_as_hash(body, content_type)
  case body_format(content_type)
  when :json then
    WebMock::Util::JSON.parse(body)
  when :xml then
    Crack::XML.parse(body)
  else
    WebMock::Util::QueryMapper.query_to_values(body, notation: Config.instance.query_values_notation)
  end
end
body_format(content_type) click to toggle source
# File lib/webmock/request_pattern.rb, line 312
def body_format(content_type)
  normalized_content_type = content_type.sub(/\A(application\/)[a-zA-Z0-9.-]+\+(json|xml)\Z/,'\1\2')
  BODY_FORMATS[normalized_content_type]
end
empty_string?(string) click to toggle source
# File lib/webmock/request_pattern.rb, line 376
def empty_string?(string)
  string.nil? || string == ""
end
matching_body_array?(query_parameters, pattern, content_type) click to toggle source
# File lib/webmock/request_pattern.rb, line 356
def matching_body_array?(query_parameters, pattern, content_type)
  return false unless query_parameters.is_a?(Array)
  return false unless query_parameters.length == pattern.length

  query_parameters.each_with_index do |actual, index|
    expected = pattern[index]
    return false unless matching_values(actual, expected, content_type)
  end

  true
end
matching_body_hashes?(query_parameters, pattern, content_type) click to toggle source

Compare two hashes for equality

For two hashes to match they must have the same length and all values must match when compared using `#===`.

The following hashes are examples of matches:

{a: /\d+/} and {a: '123'}

{a: '123'} and {a: '123'}

{a: {b: /\d+/}} and {a: {b: '123'}}

{a: {b: 'wow'}} and {a: {b: 'wow'}}

@param [Hash] query_parameters typically the result of parsing

JSON, XML or URL encoded parameters.

@param [Hash] pattern which contains keys with a string, hash or

regular expression value to use for comparison.

@return [Boolean] true if the paramaters match the comparison

hash, false if not.
# File lib/webmock/request_pattern.rb, line 346
def matching_body_hashes?(query_parameters, pattern, content_type)
  return false unless query_parameters.is_a?(Hash)
  return false unless query_parameters.keys.sort == pattern.keys.sort

  query_parameters.all? do |key, actual|
    expected = pattern[key]
    matching_values(actual, expected, content_type)
  end
end
matching_values(actual, expected, content_type) click to toggle source
# File lib/webmock/request_pattern.rb, line 368
def matching_values(actual, expected, content_type)
  return matching_body_hashes?(actual, expected, content_type) if actual.is_a?(Hash) && expected.is_a?(Hash)
  return matching_body_array?(actual, expected, content_type) if actual.is_a?(Array) && expected.is_a?(Array)

  expected = WebMock::Util::ValuesStringifier.stringify_values(expected) if url_encoded_body?(content_type)
  expected === actual
end
normalize_hash(hash) click to toggle source
# File lib/webmock/request_pattern.rb, line 380
def normalize_hash(hash)
  Hash[WebMock::Util::HashKeysStringifier.stringify_keys!(hash, deep: true).sort]
end
url_encoded_body?(content_type) click to toggle source
# File lib/webmock/request_pattern.rb, line 384
def url_encoded_body?(content_type)
  content_type =~ %r{^application/x-www-form-urlencoded}
end