doze 0.0.11

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.
Files changed (50) hide show
  1. data/README +6 -0
  2. data/lib/doze/application.rb +92 -0
  3. data/lib/doze/collection/object.rb +14 -0
  4. data/lib/doze/entity.rb +62 -0
  5. data/lib/doze/error.rb +75 -0
  6. data/lib/doze/media_type.rb +135 -0
  7. data/lib/doze/negotiator.rb +107 -0
  8. data/lib/doze/request.rb +119 -0
  9. data/lib/doze/resource/error.rb +21 -0
  10. data/lib/doze/resource/proxy.rb +81 -0
  11. data/lib/doze/resource.rb +193 -0
  12. data/lib/doze/responder/error.rb +34 -0
  13. data/lib/doze/responder/main.rb +41 -0
  14. data/lib/doze/responder/resource.rb +262 -0
  15. data/lib/doze/responder.rb +58 -0
  16. data/lib/doze/response.rb +78 -0
  17. data/lib/doze/router/anchored_route_set.rb +68 -0
  18. data/lib/doze/router/route.rb +88 -0
  19. data/lib/doze/router/route_set.rb +34 -0
  20. data/lib/doze/router.rb +100 -0
  21. data/lib/doze/serialization/entity.rb +34 -0
  22. data/lib/doze/serialization/form_data_helpers.rb +40 -0
  23. data/lib/doze/serialization/html.rb +116 -0
  24. data/lib/doze/serialization/json.rb +29 -0
  25. data/lib/doze/serialization/multipart_form_data.rb +162 -0
  26. data/lib/doze/serialization/resource.rb +30 -0
  27. data/lib/doze/serialization/resource_proxy.rb +14 -0
  28. data/lib/doze/serialization/www_form_encoded.rb +42 -0
  29. data/lib/doze/serialization/yaml.rb +25 -0
  30. data/lib/doze/uri_template.rb +220 -0
  31. data/lib/doze/utils.rb +53 -0
  32. data/lib/doze/version.rb +3 -0
  33. data/lib/doze.rb +5 -0
  34. data/test/functional/auth_test.rb +69 -0
  35. data/test/functional/base.rb +159 -0
  36. data/test/functional/cache_header_test.rb +76 -0
  37. data/test/functional/direct_response_test.rb +16 -0
  38. data/test/functional/error_handling_test.rb +131 -0
  39. data/test/functional/get_and_conneg_test.rb +182 -0
  40. data/test/functional/media_type_extensions_test.rb +102 -0
  41. data/test/functional/media_type_test.rb +40 -0
  42. data/test/functional/method_support_test.rb +49 -0
  43. data/test/functional/non_get_method_test.rb +173 -0
  44. data/test/functional/precondition_test.rb +84 -0
  45. data/test/functional/raw_path_info_test.rb +69 -0
  46. data/test/functional/resource_representation_test.rb +14 -0
  47. data/test/functional/router_test.rb +196 -0
  48. data/test/functional/serialization_test.rb +142 -0
  49. data/test/functional/uri_template_test.rb +51 -0
  50. 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