public
Last active

  • Download Gist
api_signature.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
require File.expand_path('../exceptions', __FILE__)
 
# Supports the following matchers:
#
# describe '/api/account.json' do
# subject { json_response }
# before { get '/api/account.json' }
# it { should have_json(:email).of_type(String) }
# it { should have_json(:posts).of_type(Array).inside_of('account') }
# it { should have_json(:review).of_type(Hash).inside_of('account/profile') }
# end
#
RSpec::Matchers.define :have_json do |name|
diffable
 
match do |json|
begin
@obj = value_at_json_path(json, @path)["#{name}"]
@obj != nil && (@type_class.present? ? @obj.kind_of?(@type_class) : true)
rescue Response::Matchers::MissingPathError
false
end
end
 
chain :of_type do |type_class|
@type_class = type_class
end
 
chain :inside_of do |path|
@path = path
end
 
failure_message_for_should do |json|
message = "expected JSON signature to include attribute '#{name}'"
message << %( of type #{@type_class}) if @type_class
message << %( at path "#{@path}") if @path
message << %(, but it was #{@obj.inspect})
message
end
 
failure_message_for_should_not do |json|
message = "expected JSON signature to exclude attribute '#{name}'"
message << %( of type #{@type_class}) if @type_class
message << %( at path "#{@path}") if @path
message << %(, but it was #{@obj.inspect})
message
end
 
description do
message = "contain the JSON signature for '#{name.to_s}'"
message << %( of type #{@type_class}) if @type_class.present?
message << %( at path "#{@path}") if @path.present?
message
end
 
# Begin internal helpers
 
def value_at_json_path(json, path)
return json unless path
 
json_path_to_keys(path).inject(json) do |value, key|
case value
when Hash, Array then value.fetch(key){ missing_json_path!(path) }
else missing_json_path!(path)
end
end
end
 
def json_path_to_keys(path)
path.split("/").map{|k| k =~ /^\d+$/ ? k.to_i : k }
end
 
def missing_json_path!(path)
raise Response::Matchers::MissingPathError.new(path)
end
end

Output looks like

:public is no longer used to avoid overloading Module#public, use :public_folder instead
        from /Users/justinsmestad/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/gems/resque-1.19.0/lib/resque/server.rb:12:in `<class:Server>'
Run filtered including {:locations=>{"./spec/api/account/profiles_api_spec.rb"=>[28]}}

/v1/account.json
  profile updates
    the return payload
      should contain the JSON signature for 'biography' of type String

Finished in 17.28 seconds
1 example, 0 failures

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.