Skip to content

Commit 9e0ed8b

Browse files
author
Michael Bleigh
committed
Merge pull request ruby-grape#99 from sauliusg/represent_array
Frontier: Entity array representation
2 parents fd8b850 + 62665d7 commit 9e0ed8b

File tree

2 files changed

+39
-25
lines changed

2 files changed

+39
-25
lines changed

lib/grape/middleware/base.rb

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,32 @@ def initialize(app, options = {})
1212
@app = app
1313
@options = default_options.merge(options)
1414
end
15-
15+
1616
def default_options; {} end
17-
17+
1818
def call(env)
1919
dup.call!(env)
2020
end
21-
21+
2222
def call!(env)
2323
@env = env
2424
before
2525
@app_response = @app.call(@env)
2626
after || @app_response
2727
end
28-
28+
2929
# @abstract
3030
# Called before the application is called in the middleware lifecycle.
3131
def before; end
3232
# @abstract
3333
# Called after the application is called in the middleware lifecycle.
3434
# @return [Response, nil] a Rack SPEC response or nil to call the application afterwards.
3535
def after; end
36-
36+
3737
def request
3838
Rack::Request.new(self.env)
3939
end
40-
40+
4141
def response
4242
Rack::Response.new(@app_response)
4343
end
@@ -115,6 +115,8 @@ def encode_json(object)
115115

116116
if object.respond_to? :serializable_hash
117117
MultiJson.encode(object.serializable_hash)
118+
elsif object.kind_of?(Array) && !object.map {|o| o.respond_to? :serializable_hash }.include?(false)
119+
MultiJson.encode(object.map {|o| o.serializable_hash })
118120
elsif object.respond_to? :to_json
119121
object.to_json
120122
else
@@ -125,11 +127,11 @@ def encode_json(object)
125127
def encode_txt(object)
126128
object.respond_to?(:to_txt) ? object.to_txt : object.to_s
127129
end
128-
130+
129131
def decode_xml(object)
130132
MultiXml.parse(object)
131133
end
132-
134+
133135
def encode_xml(object)
134136
object.respond_to?(:to_xml) ? object.to_xml : object.to_s
135137
end

spec/grape/middleware/formatter_spec.rb

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,93 +3,105 @@
33
describe Grape::Middleware::Formatter do
44
subject{ Grape::Middleware::Formatter.new(app, :default_format => :json)}
55
before{ subject.stub!(:dup).and_return(subject) }
6-
6+
77
let(:app){ lambda{|env| [200, {}, [@body]]} }
8-
8+
99
context 'serialization' do
1010
it 'should look at the bodies for possibly serializable data' do
1111
@body = {"abc" => "def"}
1212
status, headers, bodies = *subject.call({'PATH_INFO' => '/somewhere'})
1313
bodies.each{|b| b.should == MultiJson.encode(@body) }
1414
end
15-
15+
1616
it 'should call #to_json first if it is available' do
1717
@body = ['foo']
1818
@body.instance_eval do
1919
def to_json
2020
"\"bar\""
2121
end
2222
end
23-
23+
2424
subject.call({'PATH_INFO' => '/somewhere'}).last.each{|b| b.should == '"bar"'}
2525
end
26-
26+
2727
it 'should serialize the #serializable_hash if that is available' do
2828
class SimpleExample
2929
def serializable_hash
3030
{:abc => 'def'}
3131
end
3232
end
33-
33+
34+
@body = [SimpleExample.new, SimpleExample.new]
35+
36+
subject.call({'PATH_INFO' => '/somewhere'}).last.each{|b| b.should == '[{"abc":"def"},{"abc":"def"}]'}
37+
end
38+
39+
it 'should serialize multiple objects that respond to #serializable_hash' do
40+
class SimpleExample
41+
def serializable_hash
42+
{:abc => 'def'}
43+
end
44+
end
45+
3446
@body = SimpleExample.new
35-
47+
3648
subject.call({'PATH_INFO' => '/somewhere'}).last.each{|b| b.should == '{"abc":"def"}'}
3749
end
38-
50+
3951
it 'should call #to_xml if the content type is xml' do
4052
@body = "string"
4153
@body.instance_eval do
4254
def to_xml
4355
"<bar/>"
4456
end
4557
end
46-
58+
4759
subject.call({'PATH_INFO' => '/somewhere.xml'}).last.each{|b| b.should == '<bar/>'}
4860
end
4961
end
50-
62+
5163
context 'detection' do
5264
it 'should use the extension if one is provided' do
5365
subject.call({'PATH_INFO' => '/info.xml'})
5466
subject.env['api.format'].should == :xml
5567
subject.call({'PATH_INFO' => '/info.json'})
5668
subject.env['api.format'].should == :json
5769
end
58-
70+
5971
it 'should use the default format if none is provided' do
6072
subject.call({'PATH_INFO' => '/info'})
6173
subject.env['api.format'].should == :json
6274
end
63-
75+
6476
it 'should throw an error on an unrecognized format' do
6577
err = catch(:error){ subject.call({'PATH_INFO' => '/info.barklar'}) }
6678
err.should == {:status => 406, :message => "The requested format is not supported."}
6779
end
6880
end
69-
81+
7082
context 'Accept header detection' do
7183
it 'should detect from the Accept header' do
7284
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/xml'})
7385
subject.env['api.format'].should == :xml
7486
end
75-
87+
7688
it 'should look for case-indifferent headers' do
7789
subject.call({'PATH_INFO' => '/info', 'accept' => 'application/xml'})
7890
subject.env['api.format'].should == :xml
7991
end
80-
92+
8193
it 'should use quality rankings to determine formats' do
8294
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/json; q=0.3,application/xml; q=1.0'})
8395
subject.env['api.format'].should == :xml
8496
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/json; q=1.0,application/xml; q=0.3'})
8597
subject.env['api.format'].should == :json
8698
end
87-
99+
88100
it 'should handle quality rankings mixed with nothing' do
89101
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/json,application/xml; q=1.0'})
90102
subject.env['api.format'].should == :xml
91103
end
92-
104+
93105
it 'should properly parse headers with other attributes' do
94106
subject.call({'PATH_INFO' => '/info', 'Accept' => 'application/json; abc=2.3; q=1.0,application/xml; q=0.7'})
95107
subject.env['api.format'].should == :json

0 commit comments

Comments
 (0)