Forum: RSpec JSON matcher

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Michael S. (Guest)
on 2009-04-07 06:14
(Received via mailing list)
Curiously, there doesn't seem to be a matcher around that matches a JSON
string against an expected ruby object. Below is what I've come up
with, including some Rails idiosyncrasies. Any suggestions for
improvements?

Michael

module Spec
  module JSONMatchers
    class BeJsonEql
      def initialize(expected)
        @raw_expected = expected
        @expected = decode(expected, 'expected')
      end

      def matches?(target)
        @raw_target = target
        @target = decode(target, 'target')
        @target == @expected
      end

      def failure_message
        "expected\n#{@raw_target}\n" +
        "to be JSON code equivalent to\n#{@raw_expected}\n" +
        "Difference:\n#{@expected.diff(@target).inspect}"
      end

      def negative_failure_message
        "expected\n#{@raw_target}\n" +
        "to be JSON code different from\n#{@raw_expected}"
      end

      private

      def decode(s, which)
        ActiveSupport::JSON.decode(s)
      rescue ActiveSupport::JSON::ParseError
        raise ArgumentError, "Invalid #{which} JSON string:
#{s.inspect}"
      end
    end

    def be_json_eql(expected)
      BeJsonEql.new(expected)
    end
  end
end

--
Michael S.
mailto:removed_email_address@domain.invalid
http://www.schuerig.de/michael/
Phlip (Guest)
on 2009-04-07 06:25
(Received via mailing list)
Michael S. wrote:

>       def failure_message
>         "expected\n#{@raw_target}\n" +
>         "to be JSON code equivalent to\n#{@raw_expected}\n" +
>         "Difference:\n#{@expected.diff(@target).inspect}"
>       end

Nice - this fixes the common problem with assertions on large bulky
variables -
they often leave you squinting, trying to see the line that's different.

But where did .diff() come from? should I know it's part of
ActiveSupport::JSON
or something?
Michael S. (Guest)
on 2009-04-07 11:48
(Received via mailing list)
On Tuesday 07 April 2009, Phlip wrote:
>
> But where did .diff() come from? should I know it's part of
> ActiveSupport::JSON or something?

Hash#diff is part of ActiveSupport and when you look at its code you'll
probably have to squint.

Michael

--
Michael S.
mailto:removed_email_address@domain.invalid
http://www.schuerig.de/michael/
Bill B. (Guest)
on 2011-05-20 00:03
JSON matcher updated (works with Rspec 1.3.1). Put this in
spec/support/matchers/json_matcher.rb:

Spec::Matchers.define :be_json_eql do | expected |
  match do | actual |
    @expected = decode(expected, 'expected')
    @actual = decode(actual, 'actual')
    @actual == @expected
  end

  failure_message_for_should do | actual |
    "expected\n#{actual}\n" +
    "to be JSON code equivalent to\n#{expected}\n" +
    "Difference:\n#{@expected.diff(@actual).inspect}"
  end

  failure_message_for_should_not do | actual |
      "expected\n#{actual}\n" +
      "to be JSON code different from\n#{expected}"
    end

  def decode(s, which)
    ActiveSupport::JSON.decode(s)
  rescue ActiveSupport::JSON::ParseError
    raise ArgumentError, "Invalid #{which} JSON string:
  #{s.inspect}"
  end
end
This topic is locked and can not be replied to.