module RSpec::ComposableJSONMatchers

Mix-in module for the `be_json` matcher.

@example Make `be_json` matcher available everywhere

# spec/spec_helper.rb
require 'rspec/composable_json_matchers'
RSpec.configure do |config|
  include RSpec::ComposableJSONMatchers
end

@example Make `be_json` matcher available only in specific example groups

require 'rspec/composable_json_matchers'
describe 'something' do
  include RSpec::ComposableJSONMatchers
end

Public Class Methods

configuration() click to toggle source

@api public

Returns the current configuration.

@return [RSpec::ComposableJSONMatchers::Configuration] the current configuration

@see .configure

# File lib/rspec/composable_json_matchers.rb, line 29
def configuration
  @configuration ||= Configuration.new
end
configure() { |configuration| ... } click to toggle source

@api public

Provides a block for configuring RSpec::ComposableJSONMatchers.

@yieldparam config [RSpec::ComposableJSONMatchers::Configuration] the current configuration

@return [void]

@example

# spec/spec_helper.rb
RSpec::ComposableJSONMatchers.configure do |config|
  config.parser_options = { symbolize_names: false }
end

@see .configuration

# File lib/rspec/composable_json_matchers.rb, line 48
def configure
  yield configuration
end
json_value?(object) click to toggle source

@api private

# File lib/rspec/composable_json_matchers.rb, line 69
def json_value?(object)
  # value = false / null / true / object / array / number / string
  # https://www.rfc-editor.org/rfc/rfc8259.txt
  case object
  when Hash, Array, Numeric, String, TrueClass, FalseClass, NilClass
    true
  else
    false
  end
end
matcher?(object) click to toggle source

@api private

# File lib/rspec/composable_json_matchers.rb, line 58
def matcher?(object)
  begin
    return false if object.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher)
  rescue NoMethodError
    return false
  end

  object.respond_to?(:matches?)
end
reset!() click to toggle source

@api private

# File lib/rspec/composable_json_matchers.rb, line 53
def reset!
  @configuration = nil
end

Public Instance Methods

be_json(matcher_or_json_value) click to toggle source

@api public

Passes if actual string can be decoded as JSON and the decoded value passes the given matcher. When a JSON value is given, it's handled as `be_json matching(value)` (`matching` is an alias of the [`match`](www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/match-matcher) matcher).

@param

matcher_or_json_value
[#matches?, Hash, Array, Numeric, String, TrueClass, FalseClass, NilClass]
a matcher object or a JSON value

@example

expect('{ "foo": 1, "bar": 2 }').to be_json(foo: 1, bar: 2)
expect('{ "foo": 1, "bar": 2 }').to be_json(foo: 1, bar: a_kind_of(Integer))
expect('{ "foo": 1, "bar": 2 }').to be_json matching(foo: 1, bar: 2)
expect('{ "foo": 1, "bar": 2 }').to be_json including(foo: 1)
expect('{ "foo": 1, "bar": 2 }').to be_json a_kind_of(Hash)
# File lib/rspec/composable_json_matchers.rb, line 99
def be_json(matcher_or_json_value)
  if ComposableJSONMatchers.matcher?(matcher_or_json_value)
    BeJSON.new(matcher_or_json_value, ComposableJSONMatchers.configuration)
  elsif ComposableJSONMatchers.json_value?(matcher_or_json_value)
    matcher = matching(matcher_or_json_value)
    BeJSON.new(matcher, ComposableJSONMatchers.configuration)
  else
    raise ArgumentError, 'You must pass a matcher or a JSON value ' \
                         '(hash, array, numeric, string, true, false, or nil) ' \
                         'to `be_json` matcher.'
  end
end