File tree 16 files changed +132
-35
lines changed
16 files changed +132
-35
lines changed Original file line number Diff line number Diff line change 1
1
Next Release
2
2
============
3
+ * [ #309 ] ( https://github.com/intridea/grape/pull/309 ) : An XML format API will return an error instead of returning a string representation of the response if the latter cannot be converted to XML - [ @dblock ] ( http://github.com/dblock ) .
4
+ * [ #309 ] ( https://github.com/intridea/grape/pull/309 ) : Added XML support to entities - [ @johnnyiller ] ( https://github.com/johnnyiller ) , [ @dblock ] ( http://github.com/dblock ) .
5
+ * A formatter that raises an exception will cause the API to return a 500 error - [ @dblock ] ( http://github.com/dblock ) .
3
6
* Your contribution here.
4
7
5
8
0.2.6 (01/11/2013)
Original file line number Diff line number Diff line change
1
+ require 'logger'
1
2
require 'rack'
3
+ require 'rack/mount'
2
4
require 'rack/builder'
5
+ require 'rack/accept'
6
+ require 'rack/auth/basic'
7
+ require 'rack/auth/digest/md5'
8
+ require 'hashie'
9
+ require 'active_support/all'
10
+ require 'grape/util/deep_merge'
11
+ require 'grape/util/content_types'
12
+ require 'multi_json'
13
+ require 'multi_xml'
14
+ require 'virtus'
15
+ require 'i18n'
16
+
17
+ I18n . load_path << File . expand_path ( '../grape/locale/en.yml' , __FILE__ )
3
18
4
19
module Grape
5
20
autoload :API , 'grape/api'
Original file line number Diff line number Diff line change 1
- require 'rack/mount'
2
- require 'rack/auth/basic'
3
- require 'rack/auth/digest/md5'
4
- require 'logger'
5
- require 'grape/util/deep_merge'
6
- require 'grape/util/content_types'
7
-
8
1
module Grape
9
2
# The API class is the primary entry point for
10
3
# creating Grape APIs.Users should subclass this
Original file line number Diff line number Diff line change 1
- require 'rack'
2
- require 'grape'
3
- require 'hashie'
4
-
5
1
module Grape
6
2
# An Endpoint is the proxy scope in which all routing
7
3
# blocks are executed. In other words, any methods
Original file line number Diff line number Diff line change 1
- require 'hashie'
2
-
3
1
module Grape
4
2
# An Entity is a lightweight structure that allows you to easily
5
3
# represent data from your application in a consistent and abstracted
@@ -335,6 +333,11 @@ def to_json(options = {})
335
333
MultiJson . dump ( serializable_hash ( options ) )
336
334
end
337
335
336
+ def to_xml ( options = { } )
337
+ options = options . to_h if options && options . respond_to? ( :to_h )
338
+ serializable_hash ( options ) . to_xml ( options )
339
+ end
340
+
338
341
protected
339
342
340
343
def key_for ( attribute )
Original file line number Diff line number Diff line change @@ -4,7 +4,8 @@ module Xml
4
4
class << self
5
5
6
6
def call ( object , env )
7
- object . respond_to? ( :to_xml ) ? object . to_xml : object . to_s
7
+ return object . to_xml if object . respond_to? ( :to_xml )
8
+ raise "cannot convert #{ object . class } to xml"
8
9
end
9
10
10
11
end
Original file line number Diff line number Diff line change 1
- require 'active_support/core_ext/hash/indifferent_access'
2
- require 'grape/util/content_types'
3
- require 'multi_json'
4
- require 'multi_xml'
5
-
6
1
module Grape
7
2
module Middleware
8
3
class Base
Original file line number Diff line number Diff line change 1
1
require 'grape/middleware/base'
2
- require 'multi_json'
3
2
4
3
module Grape
5
4
module Middleware
Original file line number Diff line number Diff line change @@ -24,8 +24,12 @@ def before
24
24
def after
25
25
status , headers , bodies = *@app_response
26
26
formatter = Grape ::Formatter ::Base . formatter_for env [ 'api.format' ] , options
27
- bodymap = bodies . collect do |body |
28
- formatter . call body , env
27
+ begin
28
+ bodymap = bodies . collect do |body |
29
+ formatter . call body , env
30
+ end
31
+ rescue Exception => e
32
+ throw :error , :status => 500 , :message => e . message
29
33
end
30
34
headers [ 'Content-Type' ] = content_type_for ( env [ 'api.format' ] ) unless headers [ 'Content-Type' ]
31
35
Rack ::Response . new ( bodymap , status , headers ) . to_a
Original file line number Diff line number Diff line change 1
1
require 'grape/middleware/base'
2
- require 'rack/accept'
3
2
4
3
module Grape
5
4
module Middleware
Original file line number Diff line number Diff line change 1
- require 'active_support/ordered_hash'
2
-
3
1
module Grape
4
2
module ContentTypes
5
3
# Content types are listed in order of preference.
Original file line number Diff line number Diff line change 1
- require 'virtus'
2
- require 'i18n'
3
-
4
- I18n . load_path << File . expand_path ( '../locale/en.yml' , __FILE__ )
5
1
module Grape
6
2
7
3
module Validations
Original file line number Diff line number Diff line change @@ -1690,6 +1690,52 @@ def serializable_hash
1690
1690
last_response . body . should == '[{"abc":"def"},{"abc":"def"}]'
1691
1691
end
1692
1692
end
1693
+ context ":xml" do
1694
+ before ( :each ) do
1695
+ subject . format :xml
1696
+ end
1697
+ it 'string' do
1698
+ subject . get "/example" do
1699
+ "example"
1700
+ end
1701
+ get '/example'
1702
+ last_response . status . should == 500
1703
+ last_response . body . should == <<-XML
1704
+ <?xml version="1.0" encoding="UTF-8"?>
1705
+ <error>
1706
+ <message>cannot convert String to xml</message>
1707
+ </error>
1708
+ XML
1709
+ end
1710
+ it 'hash' do
1711
+ subject . get "/example" do
1712
+ { :example1 => "example1" , :example2 => "example2" }
1713
+ end
1714
+ get '/example'
1715
+ last_response . status . should == 200
1716
+ last_response . body . should == <<-XML
1717
+ <?xml version="1.0" encoding="UTF-8"?>
1718
+ <hash>
1719
+ <example1>example1</example1>
1720
+ <example2>example2</example2>
1721
+ </hash>
1722
+ XML
1723
+ end
1724
+ it 'array' do
1725
+ subject . get "/example" do
1726
+ [ "example1" , "example2" ]
1727
+ end
1728
+ get '/example'
1729
+ last_response . status . should == 200
1730
+ last_response . body . should == <<-XML
1731
+ <?xml version="1.0" encoding="UTF-8"?>
1732
+ <strings type="array">
1733
+ <string>example1</string>
1734
+ <string>example2</string>
1735
+ </strings>
1736
+ XML
1737
+ end
1738
+ end
1693
1739
end
1694
1740
1695
1741
context "catch-all" do
Original file line number Diff line number Diff line change @@ -552,6 +552,57 @@ def initialize(id)
552
552
end
553
553
554
554
end
555
+
556
+ it 'presents with xml' do
557
+ entity = Class . new ( Grape ::Entity )
558
+ entity . root "examples" , "example"
559
+ entity . expose :name
560
+
561
+ subject . format :xml
562
+
563
+ subject . get '/example' do
564
+ c = Class . new do
565
+ attr_reader :name
566
+ def initialize ( args )
567
+ @name = args [ :name ] || "no name set"
568
+ end
569
+ end
570
+ present c . new ( { :name => "johnnyiller" } ) , :with => entity
571
+ end
572
+ get '/example'
573
+ last_response . status . should == 200
574
+ last_response . headers [ 'Content-type' ] . should == "application/xml"
575
+ last_response . body . should == <<-XML
576
+ <?xml version="1.0" encoding="UTF-8"?>
577
+ <hash>
578
+ <example>
579
+ <name>johnnyiller</name>
580
+ </example>
581
+ </hash>
582
+ XML
583
+ end
584
+
585
+ it 'presents with json' do
586
+ entity = Class . new ( Grape ::Entity )
587
+ entity . root "examples" , "example"
588
+ entity . expose :name
589
+
590
+ subject . format :json
591
+
592
+ subject . get '/example' do
593
+ c = Class . new do
594
+ attr_reader :name
595
+ def initialize ( args )
596
+ @name = args [ :name ] || "no name set"
597
+ end
598
+ end
599
+ present c . new ( { :name => "johnnyiller" } ) , :with => entity
600
+ end
601
+ get '/example'
602
+ last_response . status . should == 200
603
+ last_response . headers [ 'Content-type' ] . should == "application/json"
604
+ last_response . body . should == '{"example":{"name":"johnnyiller"}}'
605
+ end
555
606
end
556
607
557
608
context 'filters' do
Original file line number Diff line number Diff line change 4
4
subject { Grape ::Middleware ::Formatter . new ( app ) }
5
5
before { subject . stub! ( :dup ) . and_return ( subject ) }
6
6
7
- let ( :app ) { lambda { |env | [ 200 , { } , [ @body ] ] } }
7
+ let ( :app ) { lambda { |env | [ 200 , { } , [ @body || { "foo" => "bar" } ] ] } }
8
8
9
9
context 'serialization' do
10
10
it 'looks at the bodies for possibly serializable data' do
@@ -37,6 +37,7 @@ def to_xml
37
37
end
38
38
39
39
context 'detection' do
40
+
40
41
it 'uses the extension if one is provided' do
41
42
subject . call ( { 'PATH_INFO' => '/info.xml' } )
42
43
subject . env [ 'api.format' ] . should == :xml
@@ -45,9 +46,9 @@ def to_xml
45
46
end
46
47
47
48
it 'uses the format parameter if one is provided' do
48
- subject . call ( { 'PATH_INFO' => '/somewhere ' , 'QUERY_STRING' => 'format=json' } )
49
+ subject . call ( { 'PATH_INFO' => '/info ' , 'QUERY_STRING' => 'format=json' } )
49
50
subject . env [ 'api.format' ] . should == :json
50
- subject . call ( { 'PATH_INFO' => '/somewhere ' , 'QUERY_STRING' => 'format=xml' } )
51
+ subject . call ( { 'PATH_INFO' => '/info ' , 'QUERY_STRING' => 'format=xml' } )
51
52
subject . env [ 'api.format' ] . should == :xml
52
53
end
53
54
Original file line number Diff line number Diff line change 12
12
13
13
require 'rack/test'
14
14
require 'pry'
15
-
16
15
require 'base64'
17
16
18
- require 'hashie/hash'
19
-
20
17
Dir [ "#{ File . dirname ( __FILE__ ) } /support/*.rb" ] . each do |file |
21
18
require file
22
19
end
You can’t perform that action at this time.
0 commit comments