GithubHelp home page GithubHelp logo

waterlink / rspec-json_expectations Goto Github PK

View Code? Open in Web Editor NEW
140.0 6.0 23.0 63 KB

Set of matchers and helpers to allow you test your APIs responses like a pro.

Home Page: https://www.relishapp.com/waterlink/rspec-json-expectations/docs

License: MIT License

Ruby 28.37% Shell 0.31% Gherkin 71.32%

rspec-json_expectations's Introduction

RSpec::JsonExpectations

Build Status

Set of matchers and helpers for RSpec 3 to allow you test your JSON API responses like a pro.

Installation

Add this line to your application's Gemfile:

gem 'rspec-json_expectations'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rspec-json_expectations

Setup

Simply add this line at the top of your spec helper:

require "rspec/json_expectations"

Usage

Simple example:

require "spec_helper"

RSpec.describe "User API" do
  subject { api_get :user }

  it "has basic info about user" do
    expect(subject).to include_json(
      id: 25,
      email: "[email protected]",
      name: "John"
    )
  end

  it "has some additional info about user" do
    expect(subject).to include_json(
      premium: "gold",
      gamification_score: 79
    )
  end
end

And the output when I run it is:

FF

Failures:

  1) User API has basic info about user
     Failure/Error: expect(subject).to include_json(

                 json atom at path "id" is not equal to expected value:

                   expected: 25
                        got: 37

                 json atom at path "name" is not equal to expected value:

                   expected: "John"
                        got: "Smith J."

     # ./spec/user_api_spec.rb:18:in `block (2 levels) in <top (required)>'

  2) User API has some additional info about user
     Failure/Error: expect(subject).to include_json(

                 json atom at path "premium" is not equal to expected value:

                   expected: "gold"
                        got: "silver"

     # ./spec/user_api_spec.rb:26:in `block (2 levels) in <top (required)>'

Finished in 0.00102 seconds (files took 0.0853 seconds to load)
2 examples, 2 failures

Failed examples:

rspec ./spec/user_api_spec.rb:17 # User API has basic info about user
rspec ./spec/user_api_spec.rb:25 # User API has some additional info about user

For other features look into documentation: https://www.relishapp.com/waterlink/rspec-json-expectations/docs/json-expectations

Development

  • bundle install to install all dependencies.
  • bin/build to run the test suite

Contributing

  1. Fork it ( https://github.com/waterlink/rspec-json_expectations/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

rspec-json_expectations's People

Contributors

ecbrodie avatar esjee avatar graaff avatar graemeboyd avatar janstevens avatar jeroenj avatar mothonmars avatar shamil614 avatar waterlink avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

rspec-json_expectations's Issues

Support array size ?

An idea will be to count the number of json object in array accessible.

Something like

it 'return 3 objects' do
  expect(subjet).to include_json_with_exact_size(
    users: [
        {
          groups: [
            {
             id: group_everybody.id,
              name: 'everybody'
            },
            {
              id: group.id,
              name: group.name
            },
            {
              id: group2.id,
              name: group2.name
            }
          ]
        )
end
Failure/Error: expect(subjet).to include_json_with_exact_size(

                 json atom size  "groups" is not equal to expected value:

                         expected: 3
                              got: 4

Support for matching unordered arrays in nested jsons

We have a quite complex JSON structure in which we have a mix of hashes and arrays. The root node is a Hash causing include_unordered_json to not be supported.

An example of our json (simplified):

{
  "foo" => "bar",
  "baz" => ["one", "three", "two"]
}

In that case we need to know the exact order of the baz array.

A workaround we use now is by explicitly wrapping the array in our expected json in RSpec::JsonExpectations::Matchers::UnorderedArrayMatcher classes:

{
  "foo" => "bar",
  "baz" => RSpec::JsonExpectations::Matchers::UnorderedArrayMatcher.new(["one", "two", "three"])
}

I'd say that include_unordered_json could accept a Hash too and uses the unordered array matcher for arrays it has in its structure.

Support all aliased RSpec expectations

RSpec expectation is supported, but not all their aliases:

require 'rspec/json_expectations'

describe 'sample' do
  it 'passes with original matcher' do
    json = '{"foo":"bar"}'
    expect(json).to include_json(
      foo: be_a_kind_of(String)
    )
  end

  it 'should have succeeded' do
    expect('bar').to a_kind_of(String)
  end

  it 'fails' do
    json = '{"foo":"bar"}'
    expect(json).to include_json(
      foo: a_kind_of(String)
    )
  end
end

Here a_kind_of is an alias of be_a_kind_of. I find the noun-phrase aliases fit better here. Notably be_kind_of, another alias of be_a_kind_of, is supported. Any reason to reject the noun-phrase?

Cannot deal with nil in values

Following fails:

expect(phone: nil).to include_json(phone: nil)

NotImplementedError: expectation is not supported
from /Users/sheerun/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-json_expectations-1.1.0/lib/rspec/json_expectations/json_traverser.rb:80:in `handle_unsupported'

Forwardable is extended without requiring it

When using this gem. You get the following error if no one required forwardable first.

Failure/Error: require 'rspec/json_expectations'

NameError:
  uninitialized constant RSpec::JsonExpectations::Matchers::UnorderedArrayMatcher::Forwardable
# ./spec/utils/add_office_spec.rb:4:in '<top (required)>'
# ------------------
# --- Caused by: ---
# LoadError:
#   cannot load such file -- rspec/json_expectations
#   ./spec/utils/add_office_spec.rb:4:in '<top (required)>'

DateTime is not considered a supported value

Hey! I recently ran into the "issue" where doing an expectation like this:

# record = ...
# ^ some active record object 
expected_response = {
  updated_at: record.updated_at
}
expect(response.body).to include_json expected_response

which raises

     NotImplementedError:
       2017-11-13 13:37:00 UTC expectation is not supported

the fix here is to use .as_json, like so:

# record = ...
# ^ some active record object 
expected_response = {
  updated_at: record.updated_at.as_json
}
expect(response.body).to include_json expected_response

For what it's worth, it seems that datetimes are serialized to datetime strings in the Zulu timezone.

I was wondering if you (or others!) would find it useful to automagically detect datetimes like this in the provided expected json, and run as_json on any datetime objects encountered.

RSpec crashes when using `match` or `kind_of`

Probably messed something up in #19. My specs crash when I use match or kind_of in the value of the json, example:

expect(response.body).to include_json({
  resource: {
    version_number: (match(/1.1.[\d]+.event/)),
    checksum: a_kind_of(String)
  }
})
/lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:151:in `block in failure_lines': undefined method `empty?' for nil:NilClass (NoMethodError)
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:147:in `tap'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:147:in `failure_lines'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:32:in `colorized_message_lines'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:238:in `formatted_message_and_backtrace'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:84:in `fully_formatted_lines'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:348:in `block (2 levels) in sub_failure_list_formatter'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/flat_map.rb:7:in `each'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/flat_map.rb:7:in `each_with_index'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/flat_map.rb:7:in `each'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/flat_map.rb:7:in `flat_map'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/flat_map.rb:7:in `flat_map'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:337:in `block in sub_failure_list_formatter'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:85:in `fully_formatted_lines'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/formatters/exception_presenter.rb:76:in `fully_formatted'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/notifications.rb:199:in `fully_formatted'
        from /lib/ruby/gems/2.3.0/gems/fuubar-2.2.0/lib/fuubar.rb:71:in `example_failed'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/reporter.rb:201:in `block in notify'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/reporter.rb:200:in `each'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/reporter.rb:200:in `notify'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/reporter.rb:140:in `example_failed'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example.rb:469:in `finish'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example.rb:428:in `fail_with_exception'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example_group.rb:596:in `block in run'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example_group.rb:637:in `each'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example_group.rb:637:in `for_filtered_examples'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example_group.rb:641:in `block in for_filtered_examples'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example_group.rb:639:in `each'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example_group.rb:639:in `for_filtered_examples'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example_group.rb:596:in `rescue in run'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/example_group.rb:602:in `run'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:113:in `block (3 levels) in run_specs'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:113:in `map'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:113:in `block (2 levels) in run_specs'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/configuration.rb:1835:in `with_suite_hooks'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:112:in `block in run_specs'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/reporter.rb:77:in `report'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:111:in `run_specs'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:87:in `run'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:71:in `run'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:45:in `invoke'
        from /lib/ruby/gems/2.3.0/gems/rspec-core-3.5.4/exe/rspec:4:in `<top (required)>'
        from /lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:268:in `load'
        from /lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:268:in `block in load'
        from /lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:240:in `load_dependency'
        from /lib/ruby/gems/2.3.0/gems/activesupport-4.2.7.1/lib/active_support/dependencies.rb:268:in `load'
        from /lib/ruby/gems/2.3.0/gems/spring-commands-rspec-1.0.4/lib/spring/commands/rspec.rb:18:in `call'
        from /lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from /lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from -e:1:in `<main>'

getting error when running rspec

Hi,
I've added gem 'rspec-json_expectations' to Gemfile.
Then, when I run bundle exec rspec, I get the following error:
/Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-json_expectations-1.2.1/lib/rspec/json_expectations.rb:1:in require': cannot load such file -- rspec (LoadError)
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-json_expectations-1.2.1/lib/rspec/json_expectations.rb:1:in <top (required)>' from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:91:in require'
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:91:in rescue in block in require' from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:68:in block in require'
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:61:in each' from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler/runtime.rb:61:in require'
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.11.2/lib/bundler.rb:99:in require' from /Users/eyalgo/dev/datalift-management-ruby/config/application.rb:17:in <top (required)>'
from /Users/eyalgo/dev/datalift-management-ruby/config/environment.rb:2:in require' from /Users/eyalgo/dev/datalift-management-ruby/config/environment.rb:2:in <top (required)>'
from /Users/eyalgo/dev/datalift-management-ruby/spec/spec_helper.rb:19:in require' from /Users/eyalgo/dev/datalift-management-ruby/spec/spec_helper.rb:19:in <top (required)>'
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/configuration.rb:1072:in require' from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/configuration.rb:1072:in block in requires='
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/configuration.rb:1072:in each' from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/configuration.rb:1072:in requires='
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/configuration_options.rb:103:in block in process_options_into' from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/configuration_options.rb:102:in each'
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/configuration_options.rb:102:in process_options_into' from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/configuration_options.rb:22:in configure'
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/runner.rb:95:in setup' from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/runner.rb:84:in run'
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/runner.rb:69:in run' from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/lib/rspec/core/runner.rb:37:in invoke'
from /Users/eyalgo/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.1.7/exe/rspec:4:in <top (required)>' from /Users/eyalgo/.rbenv/versions/2.3.0/bin/rspec:23:in load'
from /Users/eyalgo/.rbenv/versions/2.3.0/bin/rspec:23:in <main>'

from Gemfile.lock: rspec-core (3.1.7)

It's even before I even touched spec_helper.rb (that's the only file we use)

Any idea?

Is this project dead?

If this ticket remains unanswered, and you are coming across this project later, we can assume it is, in fact, dead.

"warning: assigned but unused variable - items" and "warning: method redefined; discarding old traverse" warnings

Whenever I run my tests, I see warnings like this in the RSpec output:

/code/.bundle-cache/gems/rspec-json_expectations-2.1.0/lib/rspec/json_expectations/failure_presenter.rb:63: warning: assigned but unused variable - items

Randomized with seed 44329
.../code/.bundle-cache/gems/rspec-json_expectations-2.1.0/lib/rspec/json_expectations/matchers.rb:2: warning: method redefined; discarding old traverse
/code/.bundle-cache/gems/rspec-json_expectations-2.1.0/lib/rspec/json_expectations/matchers.rb:2: warning: previous definition of traverse was here
../code/.bundle-cache/gems/rspec-json_expectations-2.1.0/lib/rspec/json_expectations/matchers.rb:2: warning: method redefined; discarding old traverse
/code/.bundle-cache/gems/rspec-json_expectations-2.1.0/lib/rspec/json_expectations/matchers.rb:2: warning: previous definition of traverse was here
../code/.bundle-cache/gems/rspec-json_expectations-2.1.0/lib/rspec/json_expectations/matchers.rb:2: warning: method redefined; discarding old traverse
/code/.bundle-cache/gems/rspec-json_expectations-2.1.0/lib/rspec/json_expectations/matchers.rb:2: warning: previous definition of traverse was here
.......

Finished in 0.23034 seconds (files took 2.81 seconds to load)
14 examples, 0 failures

Am I doing something wrong, or is this expected output?

Ruby version: ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]
rspec-json_expectations version: 2.1.0

feature: regex matching of string values

example:

  expect(response_body).to include_json(
    entity_code: "somecode",
    entity_url: %r{api/v1/entitites/somecode}
  )

Given that response_body["entity_url"] has full url (with schema, domain, you know), it will match this string only partially, as a regex.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.