Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultiJson Load errors on be_json_eql matchers #43

Open
bradherman opened this issue Jun 6, 2013 · 9 comments
Open

MultiJson Load errors on be_json_eql matchers #43

bradherman opened this issue Jun 6, 2013 · 9 comments

Comments

@bradherman
Copy link

in my tests:

this passes

it {should be_json_eql(@league.id).at_path('id')}

this throws MultiJson load error

it {should be_json_eql(@league.href).at_path('href')}

Failure/Error: it {should be_json_eql(@league.href).at_path('href')}
 MultiJson::LoadError:
   795: unexpected token at 'http://0.0.0.0/api/leagues/259?post=3000'
@laserlemon
Copy link
Contributor

What's your JSON?

@laserlemon
Copy link
Contributor

JSON strings must be quoted with double quotes, not single. That may be your issue.

@bradherman
Copy link
Author

{
  "meta": {},
  "leagues": [
    {
      "id": 1,
      "name": "NFL/Football",
      "href": "http://0.0.0.0:5000/api/leagues/1"
    }
  ]
}

@bradherman
Copy link
Author

I'm inspecting now and it's weird. Check this out:

def parse_json(json, path = nil)
  ruby = MultiJson.decode("[#{json}]").first
  puts "GOT RUBY: #{ruby}"
  v = value_at_json_path(ruby, path)
  puts "GOT VALUE: #{v}"
  v
rescue MultiJson::DecodeError => e
  puts "GOT ERROR"
  MultiJson.decode(json)
end

gives

GOT RUBY: {"meta"=>{"version"=>1, "href"=>"http://0.0.0.0:3000/api"}, "leagues"=>"http://0.0.0.0:3000/api/leagues", "teams"=>"http://0.0.0.0:3000/api/teams", "rosters"=>"http://0.0.0.0:3000/api/rosters", "players"=>"http://0.0.0.0:3000/api/players"}
GOT VALUE: http://0.0.0.0:3000/api/teams
GOT ERROR

@bradherman
Copy link
Author

It's picking up an error even though there isn't one. If I rescue the MultiJson.decode(json) with the @v (value_at_json_path return value), it works and all tests pass.

@laserlemon
Copy link
Contributor

Try running it with this:

def parse_json(json, path = nil)
  puts "GOT JSON: #{json}"
  puts "GOT PATH: #{path}"
  ruby = MultiJson.decode("[#{json}]").first
  puts "GOT RUBY: #{ruby}"
  v = value_at_json_path(ruby, path)
  puts "GOT VALUE: #{v}"
  v
rescue MultiJson::DecodeError => e
  puts "GOT ERROR"
  MultiJson.decode(json)
end

@bradherman
Copy link
Author

GOT JSON: {"meta":{},"id":313,"href":"http://0.0.0.0:3000/api/leagues/313","name":"League0","teams":[{"id":732,"full_name":" Colts","href":"http://0.0.0.0:3000/api/teams/732"}]}
GOT PATH: name
GOT RUBY: {"meta"=>{}, "id"=>313, "href"=>"http://0.0.0.0:3000/api/leagues/313", "name"=>"League0", "teams"=>[{"id"=>732, "full_name"=>" Colts", "href"=>"http://0.0.0.0:3000/api/teams/732"}]}
GOT VALUE: League0
GOT JSON: {"meta":{},"id":313,"href":"http://0.0.0.0:3000/api/leagues/313","name":"League0","teams":[{"id":732,"full_name":" Colts","href":"http://0.0.0.0:3000/api/teams/732"}]}
GOT PATH: teams
GOT RUBY: {"meta"=>{}, "id"=>313, "href"=>"http://0.0.0.0:3000/api/leagues/313", "name"=>"League0", "teams"=>[{"id"=>732, "full_name"=>" Colts", "href"=>"http://0.0.0.0:3000/api/teams/732"}]}
GOT VALUE: [{"id"=>732, "full_name"=>" Colts", "href"=>"http://0.0.0.0:3000/api/teams/732"}]
GOT JSON: {"meta":{},"id":313,"href":"http://0.0.0.0:3000/api/leagues/313","name":"League0","teams":[{"id":732,"full_name":" Colts","href":"http://0.0.0.0:3000/api/teams/732"}]}
GOT PATH: href
GOT RUBY: {"meta"=>{}, "id"=>313, "href"=>"http://0.0.0.0:3000/api/leagues/313", "name"=>"League0", "teams"=>[{"id"=>732, "full_name"=>" Colts", "href"=>"http://0.0.0.0:3000/api/teams/732"}]}
GOT VALUE: http://0.0.0.0:3000/api/leagues/313
GOT JSON: http://0.0.0.0:3000/api/leagues/313
GOT PATH:
GOT ERROR
  2) Api::LeaguesController#show valid id passed response
     Failure/Error: it {should be_json_eql(@league.href).   at_path('href')}
     MultiJson::LoadError:

@laserlemon
Copy link
Contributor

I think I figured it out (and should have a long time ago). The JSON matchers are meant to compare JSON to JSON. Above, you're comparing JSON to Ruby. So when you give an expected string to the matcher, the matcher figures you're giving it JSON. So it's trying to parse "http://0.0.0.0:3000/api/leagues/313" as if it were JSON. Of course, that won't work and bombs how you're seeing. Does that make sense?

@alexpylko
Copy link

Try this
it {should be_json_eql(@league.href.to_json).at_path('href')}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants