rack-parser 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +17 -38
- data/Rakefile +3 -3
- data/lib/rack/parser.rb +31 -59
- data/rack-parser.gemspec +2 -5
- data/spec/parser_spec.rb +71 -0
- data/spec/spec_helper.rb +38 -0
- metadata +26 -61
- checksums.yaml +0 -7
- data/test/parser_test.rb +0 -100
- data/test/teststrap.rb +0 -42
data/README.md
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
# Rack::Parser #
|
2
2
|
|
3
|
-
Rack::Parser is a
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
What this allows your rack application to do is decode/parse incoming post data
|
8
|
-
into param hashes for your applications to use.
|
3
|
+
Rack::Parser is a rack middleware that allows your application to do decode/parse incoming post data
|
4
|
+
into param hashes for your applications to use. You can provide a custom
|
5
|
+
Parser for things like JSON, XML, MSGPACK using your library of choice.
|
9
6
|
|
10
7
|
## Installation ##
|
11
8
|
|
@@ -23,45 +20,29 @@ or put it in your Gemfile:
|
|
23
20
|
gem 'rack-parser', :require => 'rack/parser'
|
24
21
|
```
|
25
22
|
|
26
|
-
|
27
23
|
## Usage ##
|
28
24
|
|
29
|
-
|
30
25
|
In a Sinatra or [Padrino](http://padrinorb.com) application, it would probably be something like:
|
31
26
|
|
32
27
|
```ruby
|
33
28
|
# app.rb
|
34
29
|
|
35
|
-
use Rack::Parser
|
30
|
+
use Rack::Parser :parsers => { 'application/json' => proc { |data| JSON.parse data },
|
31
|
+
'application/xml' => proc { |data| XML.parse data },
|
32
|
+
%r{msgpack} => proc { |data| Msgpack.parse data }
|
33
|
+
}
|
36
34
|
```
|
37
35
|
|
38
|
-
|
39
36
|
### Content Type Parsing ###
|
40
37
|
|
41
|
-
By default, Rack::Parser uses
|
42
|
-
|
43
|
-
them. However, through using them you can just as easily leverage the
|
44
|
-
engine of your choice by setting the engine like so:
|
45
|
-
|
46
|
-
|
47
|
-
```ruby
|
48
|
-
# app.rb
|
49
|
-
|
50
|
-
MultiJson.engine = :yajl # Yajl-ruby for json decoding
|
51
|
-
MultiXml.parser = :libxml # libxml for XML parsing
|
52
|
-
|
53
|
-
use Rack::Parser
|
54
|
-
```
|
55
|
-
|
56
|
-
To set your own custom engine that perhaps neither MultiJson or MultiXml
|
57
|
-
support, just make it a Proc:
|
58
|
-
|
38
|
+
By default, Rack::Parser uses `JSON` decode/parse your JSON Data. This can be overwritten if you choose not to use
|
39
|
+
them. You can do it like so:
|
59
40
|
|
60
41
|
```ruby
|
61
|
-
use Rack::Parser, :
|
62
|
-
'application/json' =>
|
63
|
-
'application/xml' =>
|
64
|
-
'application/roll' =>
|
42
|
+
use Rack::Parser, :parsers => {
|
43
|
+
'application/json' => proc { |body| MyCustomJsonEngine.do_it body },
|
44
|
+
'application/xml' => proc { |body| MyCustomXmlEngine.decode body },
|
45
|
+
'application/roll' => proc { |body| 'never gonna give you up' }
|
65
46
|
}
|
66
47
|
```
|
67
48
|
|
@@ -75,18 +56,16 @@ You can additionally customize the error handling response as well to
|
|
75
56
|
whatever it is you like:
|
76
57
|
|
77
58
|
```ruby
|
78
|
-
use Rack::Parser, :
|
79
|
-
'
|
80
|
-
|
81
|
-
}
|
59
|
+
use Rack::Parser, :handlers => {
|
60
|
+
'application/json' => proc { |e, type| [400, { 'Content-Type' => type }, ["broke"]] }
|
61
|
+
}
|
82
62
|
```
|
83
63
|
|
84
64
|
The error handler expects to pass both the `error` and `content_type` so
|
85
65
|
that you can use them within your responses. In addition, you can
|
86
66
|
override the default response as well.
|
87
67
|
|
88
|
-
If no content_type error handling response is present, it will
|
89
|
-
`default`.
|
68
|
+
If no content_type error handling response is present, it will return `400`
|
90
69
|
|
91
70
|
## Inspirations ##
|
92
71
|
|
data/Rakefile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
|
3
3
|
require 'rake/testtask'
|
4
|
-
Rake::TestTask.new(:
|
5
|
-
test.libs << 'lib' << '
|
6
|
-
test.pattern = '
|
4
|
+
Rake::TestTask.new(:spec) do |test|
|
5
|
+
test.libs << 'lib' << 'spec'
|
6
|
+
test.pattern = 'spec/**/*_spec.rb'
|
7
7
|
test.warning = true
|
8
8
|
test.verbose = true
|
9
9
|
end
|
data/lib/rack/parser.rb
CHANGED
@@ -1,60 +1,20 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
require 'multi_xml'
|
3
|
-
|
4
1
|
module Rack
|
5
|
-
|
6
|
-
# Rack::Parser allows you to set custom parsers for incoming post body data. As a default,
|
7
|
-
# Rack::Parser uses MultiJson and MultiXml to do the decoding/parsing for you. This allows you to
|
8
|
-
# designate any engine you wish that is compatible with the MultiJson/MultiXml libraries.
|
9
|
-
# You can also conveniently use another library by as well by wrapping it as a Proc or add additional
|
10
|
-
# content types which are not default in this middleware.
|
11
|
-
# In addition, you can set custom error handling for each content_type. If no error response is defined for
|
12
|
-
# a particular content_type, it will use the default error response, which can also be overrided.
|
13
|
-
#
|
14
2
|
class Parser
|
15
3
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
FORM_HASH = 'rack.request.form_hash'.freeze
|
4
|
+
POST_BODY = 'rack.input'.freeze
|
5
|
+
FORM_INPUT = 'rack.request.form_input'.freeze
|
6
|
+
FORM_HASH = 'rack.request.form_hash'.freeze
|
20
7
|
|
21
|
-
|
22
|
-
|
23
|
-
'application/xml' => Proc.new { |body| MultiXml.parse(body) },
|
24
|
-
'application/json' => Proc.new { |body| MultiJson.decode(body) }
|
25
|
-
}
|
26
|
-
|
27
|
-
DEFAULT_ERROR_RESPONSE = {
|
28
|
-
'default' =>
|
29
|
-
Proc.new do |e, content_type|
|
30
|
-
format = content_type.split('/').last
|
31
|
-
meth = "to_#{format}"
|
32
|
-
meth = "inspect" unless ::Hash.respond_to? meth
|
33
|
-
[400, {'Content-Type' => content_type }, [ { 'errors' => e.to_s }.method(meth).call ] ]
|
34
|
-
end
|
35
|
-
}
|
8
|
+
JSON_PARSER = proc { |data| JSON.parse data }
|
9
|
+
ERROR_HANDLER = proc { |err, type| [400, {}, ''] }
|
36
10
|
|
37
|
-
attr_reader :
|
11
|
+
attr_reader :parsers, :handlers, :logger
|
38
12
|
|
39
|
-
# Usage:
|
40
|
-
# use Rack::Parser, :content_types => {
|
41
|
-
# 'application/xml' => Proc.new { |body| XmlParser.parse body } # if you don't want the default
|
42
|
-
# 'application/json' => Proc.new { |body| JsonParser.decode body } # if you don't want the default
|
43
|
-
# 'application/foo' => Proc.new { |body| FooParser.parse body } # Add custom content_types to parse.
|
44
|
-
# }
|
45
|
-
#
|
46
|
-
# # use Rack::Parser,
|
47
|
-
# :content_types => {
|
48
|
-
# 'application/xml' => Proc.new { |body| XmlParser.parse body } # if you don't want the default
|
49
|
-
# },
|
50
|
-
# :error_responses => {
|
51
|
-
# 'default' => Proc.new { |e, content_type| [500, {}, ["boo hoo"] ] }, # Override the default error response..
|
52
|
-
# 'application/json' => Proc.new { |e, content_type| [400, {'Content-Type'=>content_type}, ["broke"]] } # Customize error responses based on content type.
|
53
|
-
# }
|
54
13
|
def initialize(app, options = {})
|
55
|
-
@app
|
56
|
-
@
|
57
|
-
@
|
14
|
+
@app = app
|
15
|
+
@parsers = options.delete(:parsers) || { %r{json} => JSON_PARSER }
|
16
|
+
@handlers = options.delete(:handlers) || {}
|
17
|
+
@logger = options.delete(:logger)
|
58
18
|
end
|
59
19
|
|
60
20
|
def call(env)
|
@@ -62,20 +22,32 @@ module Rack
|
|
62
22
|
end
|
63
23
|
|
64
24
|
def _call(env)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
25
|
+
type = Rack::Request.new(env).media_type
|
26
|
+
parser = parsers.detect { |content_type, _| type.match(content_type) } if type
|
27
|
+
return @app.call(env) unless parser
|
28
|
+
body = env[POST_BODY].read ; env[POST_BODY].rewind
|
29
|
+
return @app.call(env) unless body && !body.empty?
|
69
30
|
begin
|
70
|
-
|
71
|
-
env.update FORM_HASH =>
|
31
|
+
parsed = parser.last.call body
|
32
|
+
env.update FORM_HASH => parsed, FORM_INPUT => env[POST_BODY]
|
72
33
|
rescue Exception => e
|
73
|
-
|
74
|
-
|
75
|
-
|
34
|
+
warn! e, type
|
35
|
+
handler = handlers.detect { |content_type, _| type.match(content_type) }
|
36
|
+
handler ||= ['default', ERROR_HANDLER]
|
37
|
+
return handler.last.call(e, type)
|
76
38
|
end
|
77
39
|
@app.call env
|
78
40
|
end
|
79
41
|
|
42
|
+
# Private: send a warning out to the logger
|
43
|
+
#
|
44
|
+
# error - Exception object
|
45
|
+
# type - String of the Content-Type
|
46
|
+
#
|
47
|
+
def warn!(error, type)
|
48
|
+
return unless logger
|
49
|
+
message = "[Rack::Parser] Error on %s : %s" % [type, error.to_s]
|
50
|
+
logger.warn message
|
51
|
+
end
|
80
52
|
end
|
81
53
|
end
|
data/rack-parser.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "rack-parser"
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.4.0"
|
7
7
|
s.authors = ["Arthur Chiu"]
|
8
8
|
s.email = ["mr.arthur.chiu@gmail.com"]
|
9
9
|
s.homepage = "https://www.github.com/achiu/rack-parser"
|
@@ -18,9 +18,6 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
20
|
s.add_dependency 'rack'
|
21
|
-
s.
|
22
|
-
s.add_dependency 'multi_xml', '>= 0.5.2'
|
23
|
-
s.add_development_dependency 'riot'
|
21
|
+
s.add_development_dependency 'minitest'
|
24
22
|
s.add_development_dependency 'rack-test'
|
25
|
-
s.add_development_dependency 'json'
|
26
23
|
end
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Rack::Parser do
|
4
|
+
|
5
|
+
it "allows you to setup parsers for content types" do
|
6
|
+
middleware = Rack::Parser.new ParserApp, :parsers => { 'foo' => 'bar' }
|
7
|
+
assert_equal 'bar', middleware.parsers['foo']
|
8
|
+
end
|
9
|
+
|
10
|
+
it "allows you to setup error handlers" do
|
11
|
+
stack = Rack::Parser.new ParserApp, :handlers => { 'foo' => 'bar' }
|
12
|
+
assert_equal 'bar', stack.handlers['foo']
|
13
|
+
end
|
14
|
+
|
15
|
+
it "parses a Content-Type" do
|
16
|
+
payload = JSON.dump(:a => 1)
|
17
|
+
parser = proc { |data| JSON.parse data }
|
18
|
+
stack Rack::Parser, :parsers => { 'application/json' => parser }
|
19
|
+
post '/post', payload, { 'CONTENT_TYPE' => 'application/json' }
|
20
|
+
|
21
|
+
assert last_response.ok?
|
22
|
+
assert_equal "{\"a\"=>1}", last_response.body
|
23
|
+
end
|
24
|
+
|
25
|
+
it "does nothing if unmatched Content-Type" do
|
26
|
+
payload = JSON.dump(:a => 1)
|
27
|
+
parser = proc { |data| JSON.parse data }
|
28
|
+
stack Rack::Parser, :parsers => { 'application/json' => parser }
|
29
|
+
post '/post', payload, { 'CONTENT_TYPE' => 'application/xml' }
|
30
|
+
|
31
|
+
assert last_response.ok?
|
32
|
+
assert_equal "{}", last_response.body # request.params won't pick up this content type
|
33
|
+
end
|
34
|
+
|
35
|
+
it "matches Content-Type by regex" do
|
36
|
+
payload = JSON.dump(:a => 2)
|
37
|
+
parser = proc { |data| JSON.parse data }
|
38
|
+
stack Rack::Parser, :parsers => { %r{json} => parser }
|
39
|
+
post '/post', payload, { 'CONTENT_TYPE' => 'application/vnd.foo+json' }
|
40
|
+
|
41
|
+
assert last_response.ok?
|
42
|
+
assert_equal "{\"a\"=>2}", last_response.body
|
43
|
+
end
|
44
|
+
|
45
|
+
it "handles upstream errors" do
|
46
|
+
assert_raises Exception, 'error!' do
|
47
|
+
parser = proc { |data| JSON.parse data }
|
48
|
+
stack Rack::Parser, :parsers => { %r{json} => parser }
|
49
|
+
post '/error', '{}', { 'CONTENT_TYPE' => 'application/json' }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns a default error" do
|
54
|
+
parser = proc { |data| raise Exception, 'wah wah' }
|
55
|
+
stack Rack::Parser, :parsers => { %r{json} => parser }
|
56
|
+
post '/post', '{}', { 'CONTENT_TYPE' => 'application/vnd.foo+json' }
|
57
|
+
|
58
|
+
assert_equal 400, last_response.status
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns a custom error message" do
|
62
|
+
parser = proc { |data| raise Exception, "wah wah" }
|
63
|
+
handler = proc { |err, type| [500, {}, "%s : %s" % [type, err]] }
|
64
|
+
stack Rack::Parser, :parsers => { %r{json} => parser },
|
65
|
+
:handlers => { %r{json} => handler }
|
66
|
+
post '/post', '{}', { 'CONTENT_TYPE' => 'application/vnd.foo+json' }
|
67
|
+
|
68
|
+
assert_equal 500, last_response.status
|
69
|
+
assert_equal 'application/vnd.foo+json : wah wah', last_response.body
|
70
|
+
end
|
71
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
gem 'minitest'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'rack'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'rack/builder'
|
6
|
+
require 'json'
|
7
|
+
require File.expand_path('../../lib/rack/parser', __FILE__)
|
8
|
+
|
9
|
+
class ParserApp
|
10
|
+
def call(env)
|
11
|
+
request = Rack::Request.new(env)
|
12
|
+
type = { 'Content-Type' => 'text/plain' }
|
13
|
+
code, body =
|
14
|
+
case request.path
|
15
|
+
when '/' then [200, 'Hello World']
|
16
|
+
when '/post' then [200, request.params.inspect]
|
17
|
+
when '/error' then raise(Exception, 'error!')
|
18
|
+
else
|
19
|
+
[404, 'Nothing']
|
20
|
+
end
|
21
|
+
[code, type, body]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Minitest::Spec
|
26
|
+
include Rack::Test::Methods
|
27
|
+
|
28
|
+
def app(*middleware)
|
29
|
+
@builder = Rack::Builder.new
|
30
|
+
@builder.use(*@stack)
|
31
|
+
@builder.run ParserApp.new
|
32
|
+
@builder.to_app
|
33
|
+
end
|
34
|
+
|
35
|
+
def stack(*middleware)
|
36
|
+
@stack = middleware
|
37
|
+
end
|
38
|
+
end
|
metadata
CHANGED
@@ -1,97 +1,62 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Arthur Chiu
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
+
date: 2013-08-16 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rack
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- - '>='
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '0'
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- - '>='
|
27
|
+
- - ! '>='
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '0'
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
31
|
+
name: minitest
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
|
-
- - '>='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - '>='
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: multi_xml
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - '>='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.5.2
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 0.5.2
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: riot
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - '>='
|
35
|
+
- - ! '>='
|
60
36
|
- !ruby/object:Gem::Version
|
61
37
|
version: '0'
|
62
38
|
type: :development
|
63
39
|
prerelease: false
|
64
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
65
42
|
requirements:
|
66
|
-
- - '>='
|
43
|
+
- - ! '>='
|
67
44
|
- !ruby/object:Gem::Version
|
68
45
|
version: '0'
|
69
46
|
- !ruby/object:Gem::Dependency
|
70
47
|
name: rack-test
|
71
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
72
50
|
requirements:
|
73
|
-
- - '>='
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - '>='
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: json
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - '>='
|
51
|
+
- - ! '>='
|
88
52
|
- !ruby/object:Gem::Version
|
89
53
|
version: '0'
|
90
54
|
type: :development
|
91
55
|
prerelease: false
|
92
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
93
58
|
requirements:
|
94
|
-
- - '>='
|
59
|
+
- - ! '>='
|
95
60
|
- !ruby/object:Gem::Version
|
96
61
|
version: '0'
|
97
62
|
description: Rack Middleware for parsing post body data for json, xml and various
|
@@ -109,32 +74,32 @@ files:
|
|
109
74
|
- Rakefile
|
110
75
|
- lib/rack/parser.rb
|
111
76
|
- rack-parser.gemspec
|
112
|
-
-
|
113
|
-
-
|
77
|
+
- spec/parser_spec.rb
|
78
|
+
- spec/spec_helper.rb
|
114
79
|
homepage: https://www.github.com/achiu/rack-parser
|
115
80
|
licenses: []
|
116
|
-
metadata: {}
|
117
81
|
post_install_message:
|
118
82
|
rdoc_options: []
|
119
83
|
require_paths:
|
120
84
|
- lib
|
121
85
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
122
87
|
requirements:
|
123
|
-
- - '>='
|
88
|
+
- - ! '>='
|
124
89
|
- !ruby/object:Gem::Version
|
125
90
|
version: '0'
|
126
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
127
93
|
requirements:
|
128
|
-
- - '>='
|
94
|
+
- - ! '>='
|
129
95
|
- !ruby/object:Gem::Version
|
130
96
|
version: '0'
|
131
97
|
requirements: []
|
132
98
|
rubyforge_project: rack-parser
|
133
|
-
rubygems_version:
|
99
|
+
rubygems_version: 1.8.23
|
134
100
|
signing_key:
|
135
|
-
specification_version:
|
101
|
+
specification_version: 3
|
136
102
|
summary: Rack Middleware for parsing post body data
|
137
103
|
test_files:
|
138
|
-
-
|
139
|
-
-
|
140
|
-
has_rdoc:
|
104
|
+
- spec/parser_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 669beb8cc96fc852dc771cd9c9a95639668c4e13
|
4
|
-
data.tar.gz: dc190ec4551249620a769cb0ee42a1157903f5c1
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 7c957776b51e2325400b40bc52ac23fe7c0f7b175ec6ca20aa89329b8a93a12c362414e885b8ee5a5c14bcbb49796f93b11441bb7ff75d7dd811e199eba88bc6
|
7
|
-
data.tar.gz: d46f6696f9e4b74a84cb0157c8a2bc4130682592a6774a97d1fb4cf696687a7175f9697c4ae4d7bae915ab0e208c3f99bb3bf3b28db673f8cdcdeab0ab6d4886
|
data/test/parser_test.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
require File.expand_path('../teststrap', __FILE__)
|
2
|
-
|
3
|
-
class FooApp
|
4
|
-
def call(env); env; end
|
5
|
-
end
|
6
|
-
|
7
|
-
context "Rack::Parser" do
|
8
|
-
|
9
|
-
context "default configuration" do
|
10
|
-
setup do
|
11
|
-
Rack::Parser.new(FooApp.new).content_types
|
12
|
-
end
|
13
|
-
|
14
|
-
asserts(:[],'application/xml').kind_of Proc
|
15
|
-
asserts(:[],'application/json').kind_of Proc
|
16
|
-
end
|
17
|
-
|
18
|
-
context "with custom configuration" do
|
19
|
-
setup do
|
20
|
-
Rack::Parser.new(FooApp.new, :content_types => {
|
21
|
-
'application/xml' => :meh,
|
22
|
-
'application/foo' => :bar
|
23
|
-
}).content_types
|
24
|
-
end
|
25
|
-
|
26
|
-
asserts(:[], 'application/xml').equals :meh
|
27
|
-
asserts(:[], 'application/foo').equals :bar
|
28
|
-
end
|
29
|
-
|
30
|
-
context "with json" do
|
31
|
-
setup do
|
32
|
-
post '/post', "{\"test\":1,\"foo\":2,\"bar\":\"3\"}", { 'CONTENT_TYPE' => 'application/json' }
|
33
|
-
end
|
34
|
-
|
35
|
-
asserts(:status).equals 200
|
36
|
-
asserts(:body).equals "{\"test\"=>1, \"foo\"=>2, \"bar\"=>\"3\"}"
|
37
|
-
end
|
38
|
-
|
39
|
-
context "with xml" do
|
40
|
-
setup do
|
41
|
-
put '/post', "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<hash>\n <a type=\"integer\">1</a>\n</hash>\n", { 'CONTENT_TYPE' => 'application/xml'}
|
42
|
-
end
|
43
|
-
|
44
|
-
asserts(:status).equals 200
|
45
|
-
asserts(:body).equals "{\"hash\"=>{\"a\"=>1}}"
|
46
|
-
end
|
47
|
-
|
48
|
-
context "with custom 'foo'" do
|
49
|
-
setup do
|
50
|
-
post '/post', 'something that does not matter', { 'CONTENT_TYPE' => 'application/foo' }
|
51
|
-
end
|
52
|
-
|
53
|
-
asserts(:status).equals 200
|
54
|
-
asserts(:body).equals({'foo' => 'bar'}.inspect)
|
55
|
-
end
|
56
|
-
|
57
|
-
context "for errors" do
|
58
|
-
|
59
|
-
context "with default error message" do
|
60
|
-
setup do
|
61
|
-
post '/post', "fuuuuuuuuuu", { 'CONTENT_TYPE' => 'application/json' }
|
62
|
-
end
|
63
|
-
|
64
|
-
asserts(:status).equals 400
|
65
|
-
asserts(:body).matches %r!{"errors":"\d+: unexpected token at 'fuuuuuuuuuu'"}!
|
66
|
-
end
|
67
|
-
|
68
|
-
context "with custom default error message" do
|
69
|
-
setup do
|
70
|
-
post '/post', "fuuuuuuuuuu", { 'CONTENT_TYPE' => 'application/wahh' }
|
71
|
-
end
|
72
|
-
|
73
|
-
asserts(:status).equals 500
|
74
|
-
asserts(:body).equals "wahh"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context "for get with no content_type" do
|
79
|
-
setup { get '/' }
|
80
|
-
|
81
|
-
asserts(:status).equals 200
|
82
|
-
asserts(:body).matches %r{Hello world}
|
83
|
-
end
|
84
|
-
|
85
|
-
context "for get with unconcerned content_type" do
|
86
|
-
setup do
|
87
|
-
post '/post', 'foo=bar', { 'CONTENT_TYPE' => 'application/x-www-form-urlencoded' }
|
88
|
-
end
|
89
|
-
|
90
|
-
asserts(:status).equals 200
|
91
|
-
asserts(:body).equals({'foo' => 'bar'}.inspect)
|
92
|
-
end
|
93
|
-
|
94
|
-
context "for upstream errors" do
|
95
|
-
asserts('/error') do
|
96
|
-
post '/error', '{}', { 'CONTENT_TYPE' => 'application/json' }
|
97
|
-
end.raises(Exception, 'OOOPS!!')
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
data/test/teststrap.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
require 'rack'
|
2
|
-
require 'riot'
|
3
|
-
require 'rack/test'
|
4
|
-
require 'rack/builder'
|
5
|
-
require 'json'
|
6
|
-
|
7
|
-
require File.expand_path('../../lib/rack/parser', __FILE__)
|
8
|
-
|
9
|
-
class Riot::Situation
|
10
|
-
include Rack::Test::Methods
|
11
|
-
|
12
|
-
def app
|
13
|
-
main_app = lambda { |env|
|
14
|
-
request = Rack::Request.new(env)
|
15
|
-
return_code, body_text =
|
16
|
-
case request.path
|
17
|
-
when '/' then [200,'Hello world']
|
18
|
-
when '/post'
|
19
|
-
[200, Rack::Request.new(env).params]
|
20
|
-
when '/error'
|
21
|
-
raise Exception, 'OOOPS!!'
|
22
|
-
else
|
23
|
-
[404,'Nothing here']
|
24
|
-
end
|
25
|
-
[return_code,{'Content-type' => 'text/plain'}, [body_text]]
|
26
|
-
}
|
27
|
-
|
28
|
-
builder = Rack::Builder.new
|
29
|
-
builder.use Rack::Parser,
|
30
|
-
:content_types => {
|
31
|
-
'application/foo' => Proc.new { |b| {'foo' => 'bar'} }
|
32
|
-
},
|
33
|
-
:error_responses => {
|
34
|
-
'application/wahh' => Proc.new { |e, content_type| [500,{'Content-Type' => content_type},['wahh']]}
|
35
|
-
}
|
36
|
-
builder.run main_app
|
37
|
-
builder.to_app
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
class Riot::Context
|
42
|
-
end
|