doze 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- data/README +6 -0
- data/lib/doze/application.rb +92 -0
- data/lib/doze/collection/object.rb +14 -0
- data/lib/doze/entity.rb +62 -0
- data/lib/doze/error.rb +75 -0
- data/lib/doze/media_type.rb +135 -0
- data/lib/doze/negotiator.rb +107 -0
- data/lib/doze/request.rb +119 -0
- data/lib/doze/resource/error.rb +21 -0
- data/lib/doze/resource/proxy.rb +81 -0
- data/lib/doze/resource.rb +193 -0
- data/lib/doze/responder/error.rb +34 -0
- data/lib/doze/responder/main.rb +41 -0
- data/lib/doze/responder/resource.rb +262 -0
- data/lib/doze/responder.rb +58 -0
- data/lib/doze/response.rb +78 -0
- data/lib/doze/router/anchored_route_set.rb +68 -0
- data/lib/doze/router/route.rb +88 -0
- data/lib/doze/router/route_set.rb +34 -0
- data/lib/doze/router.rb +100 -0
- data/lib/doze/serialization/entity.rb +34 -0
- data/lib/doze/serialization/form_data_helpers.rb +40 -0
- data/lib/doze/serialization/html.rb +116 -0
- data/lib/doze/serialization/json.rb +29 -0
- data/lib/doze/serialization/multipart_form_data.rb +162 -0
- data/lib/doze/serialization/resource.rb +30 -0
- data/lib/doze/serialization/resource_proxy.rb +14 -0
- data/lib/doze/serialization/www_form_encoded.rb +42 -0
- data/lib/doze/serialization/yaml.rb +25 -0
- data/lib/doze/uri_template.rb +220 -0
- data/lib/doze/utils.rb +53 -0
- data/lib/doze/version.rb +3 -0
- data/lib/doze.rb +5 -0
- data/test/functional/auth_test.rb +69 -0
- data/test/functional/base.rb +159 -0
- data/test/functional/cache_header_test.rb +76 -0
- data/test/functional/direct_response_test.rb +16 -0
- data/test/functional/error_handling_test.rb +131 -0
- data/test/functional/get_and_conneg_test.rb +182 -0
- data/test/functional/media_type_extensions_test.rb +102 -0
- data/test/functional/media_type_test.rb +40 -0
- data/test/functional/method_support_test.rb +49 -0
- data/test/functional/non_get_method_test.rb +173 -0
- data/test/functional/precondition_test.rb +84 -0
- data/test/functional/raw_path_info_test.rb +69 -0
- data/test/functional/resource_representation_test.rb +14 -0
- data/test/functional/router_test.rb +196 -0
- data/test/functional/serialization_test.rb +142 -0
- data/test/functional/uri_template_test.rb +51 -0
- metadata +221 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'functional/base'
|
2
|
+
require 'doze/serialization/resource'
|
3
|
+
|
4
|
+
class SerializationTest < Test::Unit::TestCase
|
5
|
+
include Doze::Utils
|
6
|
+
include Doze::TestCase
|
7
|
+
include Doze::MediaTypeTestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
root.extend(Doze::Serialization::Resource)
|
11
|
+
@ruby_data = ['some', 123, 'ruby data']
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_parse_error
|
16
|
+
root.stubs(:supports_put?).returns(true)
|
17
|
+
root.stubs(:accepts_put_with_media_type?).returns(true)
|
18
|
+
def root.put(entity)
|
19
|
+
# actually try to parse the entity
|
20
|
+
entity.object_data
|
21
|
+
end
|
22
|
+
|
23
|
+
put('CONTENT_TYPE' => 'application/json', :input => '{"foo":')
|
24
|
+
assert_equal STATUS_BAD_REQUEST, last_response.status
|
25
|
+
assert_match /parse/i, last_response.body
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_semantic_client_error
|
29
|
+
root.stubs(:supports_put?).returns(true)
|
30
|
+
root.stubs(:accepts_put_with_media_type?).returns(true)
|
31
|
+
|
32
|
+
root.expects(:put).raises(Doze::ClientResourceError, "semantic problem with submitted data").once
|
33
|
+
put('CONTENT_TYPE' => 'application/json', :input => '{"foo":"bar"}')
|
34
|
+
assert_equal STATUS_UNPROCESSABLE_ENTITY, last_response.status
|
35
|
+
assert_match /semantic/i, last_response.body
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_json_serialization
|
39
|
+
media_type = Doze::Serialization::JSON
|
40
|
+
entity = media_type.entity_class.new(media_type, :object_data => {'foo' => 'bar'})
|
41
|
+
assert_equal '{"foo":"bar"}', entity.binary_data
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_form_encoding_serialization
|
45
|
+
media_type = Doze::Serialization::WWW_FORM_ENCODED
|
46
|
+
entity = media_type.entity_class.new(media_type, :object_data => {'foo' => {'bar' => '='}, 'baz' => '3'})
|
47
|
+
assert ['foo[bar]=%3D&baz=3', 'baz=3&foo[bar]=%3D'].include?(entity.binary_data)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_get_serialized
|
51
|
+
root.expects(:get_data).returns(@ruby_data).twice
|
52
|
+
|
53
|
+
get('HTTP_ACCEPT' => 'application/json')
|
54
|
+
assert_equal STATUS_OK, last_response.status
|
55
|
+
assert_equal @ruby_data.to_json, last_response.body
|
56
|
+
assert_equal 'application/json', last_response.media_type
|
57
|
+
|
58
|
+
get('HTTP_ACCEPT' => 'text/html')
|
59
|
+
assert_equal STATUS_OK, last_response.status
|
60
|
+
assert_equal 'text/html', last_response.media_type
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_put_serialized
|
64
|
+
root.expects(:supports_put?).returns(true).twice
|
65
|
+
root.expects(:put).with {|entity| entity.object_data == @ruby_data}.once
|
66
|
+
|
67
|
+
put('CONTENT_TYPE' => 'application/json', :input => @ruby_data.to_json)
|
68
|
+
assert_equal STATUS_NO_CONTENT, last_response.status
|
69
|
+
|
70
|
+
put('CONTENT_TYPE' => 'application/yaml', :input => @ruby_data.to_yaml)
|
71
|
+
assert_equal STATUS_UNSUPPORTED_MEDIA_TYPE, last_response.status
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_post_serialized
|
75
|
+
root.expects(:supports_post?).returns(true).twice
|
76
|
+
root.expects(:post).with {|entity| entity.object_data == @ruby_data}.once
|
77
|
+
|
78
|
+
post('CONTENT_TYPE' => 'application/json', :input => @ruby_data.to_json)
|
79
|
+
assert_equal STATUS_NO_CONTENT, last_response.status
|
80
|
+
|
81
|
+
# YAML is disabled by default
|
82
|
+
post('CONTENT_TYPE' => 'application/yaml', :input => @ruby_data.to_yaml)
|
83
|
+
assert_equal STATUS_UNSUPPORTED_MEDIA_TYPE, last_response.status
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_form_post
|
87
|
+
root.expects(:supports_post?).returns(true).once
|
88
|
+
root.expects(:post).with {|entity| entity.object_data == {'abc' => {'def' => 'ghi'}, 'e' => '='}}.once
|
89
|
+
post('CONTENT_TYPE' => 'application/x-www-form-urlencoded', :input => "abc%5Bdef%5D=ghi&e=%3D")
|
90
|
+
assert_equal STATUS_NO_CONTENT, last_response.status
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_derived_type
|
94
|
+
json_subtype = Doze::Serialization::JSON.register_derived_type('application/vnd.foo.bar')
|
95
|
+
|
96
|
+
assert_equal "application/vnd.foo.bar+json", json_subtype.name
|
97
|
+
assert json_subtype.matches_names.include?("application/json")
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_get_derived_type_via_generic_accept
|
101
|
+
derived_media_types = [Doze::Serialization::JSON].map {|x| x.register_derived_type('application/vnd.foo.bar')}
|
102
|
+
|
103
|
+
root.expects(:get_data).returns(@ruby_data).once
|
104
|
+
root.expects(:serialization_media_types).returns(derived_media_types).once
|
105
|
+
|
106
|
+
get('HTTP_ACCEPT' => 'application/json')
|
107
|
+
assert_equal STATUS_OK, last_response.status
|
108
|
+
assert_equal @ruby_data.to_json, last_response.body
|
109
|
+
assert_equal 'application/vnd.foo.bar+json', last_response.media_type
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_put_multipart
|
113
|
+
root.expects(:supports_put?).returns(true)
|
114
|
+
root.expects(:put).with do |entity|
|
115
|
+
entity.object_data["z"] == {"y" => "x"} and
|
116
|
+
file = entity.object_data["x"] and
|
117
|
+
file.is_a?(Hash) and
|
118
|
+
file["filename"] == "test.html" and
|
119
|
+
file["media_type"] == "text/html" and
|
120
|
+
file["tempfile"].read == "<html>test</html>" and
|
121
|
+
File.read(file["temp_path"]) == "<html>test</html>"
|
122
|
+
end
|
123
|
+
|
124
|
+
boundary = "----------------------------0ef440f6b22e"
|
125
|
+
body = <<END
|
126
|
+
------------------------------0ef440f6b22e
|
127
|
+
Content-Disposition: form-data; name="z[y]"
|
128
|
+
|
129
|
+
x
|
130
|
+
------------------------------0ef440f6b22e
|
131
|
+
Content-Disposition: form-data; name="x"; filename="test.html"
|
132
|
+
Content-Type: text/html
|
133
|
+
|
134
|
+
<html>test</html>
|
135
|
+
------------------------------0ef440f6b22e--
|
136
|
+
END
|
137
|
+
body = body.gsub(/\r?\n/, "\r\n")
|
138
|
+
|
139
|
+
put('CONTENT_TYPE' => "multipart/form-data; boundary=#{boundary}", :input => body)
|
140
|
+
assert_equal STATUS_NO_CONTENT, last_response.status
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'functional/base'
|
2
|
+
|
3
|
+
class URITemplateTest < Test::Unit::TestCase
|
4
|
+
include Doze::Utils
|
5
|
+
include Doze::TestCase
|
6
|
+
|
7
|
+
def test_match
|
8
|
+
a = Doze::URITemplate.compile("/abc/{x}/def")
|
9
|
+
assert_equal({:x => '123'}, a.match("/abc/123/def"))
|
10
|
+
assert_equal({:x => ' /'}, a.match("/abc/%20%2F/def"))
|
11
|
+
assert_equal([{:x => '123'}, '/abc/123/def', '/ghi'], a.match_with_trailing("/abc/123/def/ghi"))
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_match_with_trailing_with_path_separator
|
15
|
+
a = Doze::URITemplate.compile("/abc/{x}")
|
16
|
+
assert_equal([{:x => '123'}, '/abc/123', '/def'], a.match_with_trailing("/abc/123/def"))
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_addition
|
20
|
+
a = Doze::URITemplate.compile("/abc/{x}") + Doze::URITemplate.compile("/def/{y}")
|
21
|
+
assert_equal({:x => '1', :y => '2'}, a.match("/abc/1/def/2"))
|
22
|
+
assert_equal([:x, :y], a.variables.map {|v| v.name})
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_expand
|
26
|
+
a = Doze::URITemplate.compile("/abc/{x}/def/{y}")
|
27
|
+
assert_equal("/abc/123/def/", a.expand(:x => 123))
|
28
|
+
assert_equal("/abc/123/def/456", a.expand(:x => 123, :y => 456))
|
29
|
+
assert_equal("/abc/123/def/%20%2F", a.expand(:x => 123, :y => ' /'))
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_partial_expand
|
33
|
+
a = Doze::URITemplate.compile("/abc/{x}") + Doze::URITemplate.compile("/def/{y}")
|
34
|
+
assert_equal("/abc/123/def/{y}", a.partially_expand(:x => 123).to_s)
|
35
|
+
assert_equal([:y], a.partially_expand(:x => 123).variables.map {|v| v.name})
|
36
|
+
assert_equal({:y => '456'}, a.partially_expand(:x => 123).match('/abc/123/def/456'))
|
37
|
+
assert_equal("/abc/{x}/def/456", a.partially_expand(:y => 456).to_s)
|
38
|
+
assert_equal("/abc/123/def/456", a.partially_expand(:x => 123).expand(:y => 456))
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_quadhexbytes
|
42
|
+
a = Doze::URITemplate.compile("/abc{/x.quadhexbytes*}")
|
43
|
+
assert_equal([{:x => 1234}, '/abc/00/00/04/d2', '/def'], a.match_with_trailing("/abc/00/00/04/d2/def"))
|
44
|
+
assert_equal({:x => 1234}, a.match("/abc/00/00/04/d2"))
|
45
|
+
assert_equal("/abc/00/00/04/d2", a.expand(:x => 1234))
|
46
|
+
b = a + Doze::URITemplate.compile('/def/{y}')
|
47
|
+
assert_equal({:x => 1234, :y => 'sss'}, b.match("/abc/00/00/04/d2/def/sss"))
|
48
|
+
assert_equal("/abc/00/00/04/d2/def/sss", b.expand(:x => 1234, :y => 'sss'))
|
49
|
+
assert_equal("/abc/00/00/04/d2/def/sss", b.partially_expand(:y => 'sss').expand(:x => 1234))
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,221 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: doze
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 11
|
10
|
+
version: 0.0.11
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Matthew Willson
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-02-13 00:00:00 +00:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rake
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rack-test
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: mocha
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :development
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rdoc
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :development
|
76
|
+
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: rack
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 15
|
86
|
+
segments:
|
87
|
+
- 1
|
88
|
+
- 0
|
89
|
+
version: "1.0"
|
90
|
+
type: :runtime
|
91
|
+
version_requirements: *id005
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: json
|
94
|
+
prerelease: false
|
95
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ~>
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 9
|
101
|
+
segments:
|
102
|
+
- 1
|
103
|
+
- 5
|
104
|
+
- 5
|
105
|
+
version: 1.5.5
|
106
|
+
type: :runtime
|
107
|
+
version_requirements: *id006
|
108
|
+
description: Library for building restful APIs, with hierarchical routing, content type handling and other RESTful stuff
|
109
|
+
email:
|
110
|
+
- matthew@playlouder.com
|
111
|
+
executables: []
|
112
|
+
|
113
|
+
extensions: []
|
114
|
+
|
115
|
+
extra_rdoc_files:
|
116
|
+
- README
|
117
|
+
files:
|
118
|
+
- lib/doze.rb
|
119
|
+
- lib/doze/error.rb
|
120
|
+
- lib/doze/uri_template.rb
|
121
|
+
- lib/doze/responder.rb
|
122
|
+
- lib/doze/version.rb
|
123
|
+
- lib/doze/response.rb
|
124
|
+
- lib/doze/media_type.rb
|
125
|
+
- lib/doze/negotiator.rb
|
126
|
+
- lib/doze/collection/object.rb
|
127
|
+
- lib/doze/utils.rb
|
128
|
+
- lib/doze/request.rb
|
129
|
+
- lib/doze/resource/error.rb
|
130
|
+
- lib/doze/resource/proxy.rb
|
131
|
+
- lib/doze/router/route_set.rb
|
132
|
+
- lib/doze/router/anchored_route_set.rb
|
133
|
+
- lib/doze/router/route.rb
|
134
|
+
- lib/doze/serialization/json.rb
|
135
|
+
- lib/doze/serialization/html.rb
|
136
|
+
- lib/doze/serialization/multipart_form_data.rb
|
137
|
+
- lib/doze/serialization/yaml.rb
|
138
|
+
- lib/doze/serialization/www_form_encoded.rb
|
139
|
+
- lib/doze/serialization/form_data_helpers.rb
|
140
|
+
- lib/doze/serialization/resource_proxy.rb
|
141
|
+
- lib/doze/serialization/entity.rb
|
142
|
+
- lib/doze/serialization/resource.rb
|
143
|
+
- lib/doze/entity.rb
|
144
|
+
- lib/doze/responder/error.rb
|
145
|
+
- lib/doze/responder/main.rb
|
146
|
+
- lib/doze/responder/resource.rb
|
147
|
+
- lib/doze/resource.rb
|
148
|
+
- lib/doze/application.rb
|
149
|
+
- lib/doze/router.rb
|
150
|
+
- README
|
151
|
+
- test/functional/resource_representation_test.rb
|
152
|
+
- test/functional/method_support_test.rb
|
153
|
+
- test/functional/router_test.rb
|
154
|
+
- test/functional/direct_response_test.rb
|
155
|
+
- test/functional/error_handling_test.rb
|
156
|
+
- test/functional/precondition_test.rb
|
157
|
+
- test/functional/auth_test.rb
|
158
|
+
- test/functional/raw_path_info_test.rb
|
159
|
+
- test/functional/base.rb
|
160
|
+
- test/functional/cache_header_test.rb
|
161
|
+
- test/functional/uri_template_test.rb
|
162
|
+
- test/functional/media_type_extensions_test.rb
|
163
|
+
- test/functional/non_get_method_test.rb
|
164
|
+
- test/functional/get_and_conneg_test.rb
|
165
|
+
- test/functional/serialization_test.rb
|
166
|
+
- test/functional/media_type_test.rb
|
167
|
+
has_rdoc: true
|
168
|
+
homepage: https://github.com/mjwillson/doze
|
169
|
+
licenses: []
|
170
|
+
|
171
|
+
post_install_message:
|
172
|
+
rdoc_options:
|
173
|
+
- --title
|
174
|
+
- Doze
|
175
|
+
- --main
|
176
|
+
- README
|
177
|
+
- --line-numbers
|
178
|
+
require_paths:
|
179
|
+
- lib
|
180
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
181
|
+
none: false
|
182
|
+
requirements:
|
183
|
+
- - ">="
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
hash: 3
|
186
|
+
segments:
|
187
|
+
- 0
|
188
|
+
version: "0"
|
189
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
|
+
none: false
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
hash: 3
|
195
|
+
segments:
|
196
|
+
- 0
|
197
|
+
version: "0"
|
198
|
+
requirements: []
|
199
|
+
|
200
|
+
rubyforge_project:
|
201
|
+
rubygems_version: 1.6.2
|
202
|
+
signing_key:
|
203
|
+
specification_version: 3
|
204
|
+
summary: RESTful resource-oriented API framework
|
205
|
+
test_files:
|
206
|
+
- test/functional/resource_representation_test.rb
|
207
|
+
- test/functional/method_support_test.rb
|
208
|
+
- test/functional/router_test.rb
|
209
|
+
- test/functional/direct_response_test.rb
|
210
|
+
- test/functional/error_handling_test.rb
|
211
|
+
- test/functional/precondition_test.rb
|
212
|
+
- test/functional/auth_test.rb
|
213
|
+
- test/functional/raw_path_info_test.rb
|
214
|
+
- test/functional/base.rb
|
215
|
+
- test/functional/cache_header_test.rb
|
216
|
+
- test/functional/uri_template_test.rb
|
217
|
+
- test/functional/media_type_extensions_test.rb
|
218
|
+
- test/functional/non_get_method_test.rb
|
219
|
+
- test/functional/get_and_conneg_test.rb
|
220
|
+
- test/functional/serialization_test.rb
|
221
|
+
- test/functional/media_type_test.rb
|