strelka 0.0.1pre4 → 0.0.1.pre129

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 (73) hide show
  1. data/History.rdoc +1 -1
  2. data/IDEAS.rdoc +62 -0
  3. data/Manifest.txt +38 -7
  4. data/README.rdoc +124 -5
  5. data/Rakefile +22 -6
  6. data/bin/leash +102 -157
  7. data/contrib/hoetemplate/.autotest.erb +23 -0
  8. data/contrib/hoetemplate/History.rdoc.erb +4 -0
  9. data/contrib/hoetemplate/Manifest.txt.erb +8 -0
  10. data/contrib/hoetemplate/README.rdoc.erb +17 -0
  11. data/contrib/hoetemplate/Rakefile.erb +24 -0
  12. data/contrib/hoetemplate/data/file_name/apps/file_name_app +36 -0
  13. data/contrib/hoetemplate/data/file_name/templates/layout.tmpl.erb +13 -0
  14. data/contrib/hoetemplate/data/file_name/templates/top.tmpl.erb +8 -0
  15. data/contrib/hoetemplate/lib/file_name.rb.erb +18 -0
  16. data/contrib/hoetemplate/spec/file_name_spec.rb.erb +21 -0
  17. data/data/strelka/apps/hello-world +30 -0
  18. data/lib/strelka/app/defaultrouter.rb +49 -30
  19. data/lib/strelka/app/errors.rb +121 -0
  20. data/lib/strelka/app/exclusiverouter.rb +40 -0
  21. data/lib/strelka/app/filters.rb +18 -7
  22. data/lib/strelka/app/negotiation.rb +122 -0
  23. data/lib/strelka/app/parameters.rb +171 -14
  24. data/lib/strelka/app/paramvalidator.rb +751 -0
  25. data/lib/strelka/app/plugins.rb +66 -46
  26. data/lib/strelka/app/restresources.rb +499 -0
  27. data/lib/strelka/app/router.rb +73 -0
  28. data/lib/strelka/app/routing.rb +140 -18
  29. data/lib/strelka/app/templating.rb +12 -3
  30. data/lib/strelka/app.rb +174 -24
  31. data/lib/strelka/constants.rb +0 -20
  32. data/lib/strelka/exceptions.rb +29 -0
  33. data/lib/strelka/httprequest/acceptparams.rb +377 -0
  34. data/lib/strelka/httprequest/negotiation.rb +257 -0
  35. data/lib/strelka/httprequest.rb +155 -7
  36. data/lib/strelka/httpresponse/negotiation.rb +579 -0
  37. data/lib/strelka/httpresponse.rb +140 -0
  38. data/lib/strelka/logging.rb +4 -1
  39. data/lib/strelka/mixins.rb +53 -0
  40. data/lib/strelka.rb +22 -1
  41. data/spec/data/error.tmpl +1 -0
  42. data/spec/lib/constants.rb +0 -1
  43. data/spec/lib/helpers.rb +21 -0
  44. data/spec/strelka/app/defaultrouter_spec.rb +41 -35
  45. data/spec/strelka/app/errors_spec.rb +212 -0
  46. data/spec/strelka/app/exclusiverouter_spec.rb +220 -0
  47. data/spec/strelka/app/filters_spec.rb +196 -0
  48. data/spec/strelka/app/negotiation_spec.rb +73 -0
  49. data/spec/strelka/app/parameters_spec.rb +149 -0
  50. data/spec/strelka/app/paramvalidator_spec.rb +1059 -0
  51. data/spec/strelka/app/plugins_spec.rb +26 -19
  52. data/spec/strelka/app/restresources_spec.rb +393 -0
  53. data/spec/strelka/app/router_spec.rb +63 -0
  54. data/spec/strelka/app/routing_spec.rb +183 -9
  55. data/spec/strelka/app/templating_spec.rb +1 -2
  56. data/spec/strelka/app_spec.rb +265 -32
  57. data/spec/strelka/exceptions_spec.rb +53 -0
  58. data/spec/strelka/httprequest/acceptparams_spec.rb +282 -0
  59. data/spec/strelka/httprequest/negotiation_spec.rb +246 -0
  60. data/spec/strelka/httprequest_spec.rb +204 -14
  61. data/spec/strelka/httpresponse/negotiation_spec.rb +464 -0
  62. data/spec/strelka/httpresponse_spec.rb +114 -0
  63. data/spec/strelka/mixins_spec.rb +99 -0
  64. data.tar.gz.sig +1 -0
  65. metadata +175 -79
  66. metadata.gz.sig +2 -0
  67. data/IDEAS.textile +0 -174
  68. data/data/strelka/apps/strelka-admin +0 -65
  69. data/data/strelka/apps/strelka-setup +0 -26
  70. data/data/strelka/bootstrap-config.rb +0 -34
  71. data/data/strelka/templates/admin/console.tmpl +0 -21
  72. data/data/strelka/templates/layout.tmpl +0 -30
  73. data/lib/strelka/process.rb +0 -19
@@ -0,0 +1,282 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
6
+
7
+ libdir = basedir + "lib"
8
+
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
10
+ $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
11
+ }
12
+
13
+ require 'rspec'
14
+
15
+ require 'spec/lib/helpers'
16
+
17
+ require 'strelka'
18
+ require 'strelka/httprequest/acceptparams'
19
+
20
+
21
+ #####################################################################
22
+ ### C O N T E X T S
23
+ #####################################################################
24
+
25
+ describe Strelka::HTTPRequest, "accept params" do
26
+ before( :all ) do
27
+ setup_logging( :fatal )
28
+ end
29
+
30
+ after( :all ) do
31
+ reset_logging()
32
+ end
33
+
34
+
35
+ describe Strelka::HTTPRequest::MediaType do
36
+
37
+ VALID_HEADERS = {
38
+ '*/*' =>
39
+ {:type => nil, :subtype => nil, :qval => 1.0},
40
+ '*/*; q=0.1' =>
41
+ {:type => nil, :subtype => nil, :qval => 0.1},
42
+ '*/*;q=0.1' =>
43
+ {:type => nil, :subtype => nil, :qval => 0.1},
44
+ 'image/*' =>
45
+ {:type => 'image', :subtype => nil, :qval => 1.0},
46
+ 'image/*; q=0.18' =>
47
+ {:type => 'image', :subtype => nil, :qval => 0.18},
48
+ 'image/*;q=0.4' =>
49
+ {:type => 'image', :subtype => nil, :qval => 0.4},
50
+ 'image/*;q=0.9; porn=0; anseladams=1' =>
51
+ {:type => 'image', :subtype => nil, :qval => 0.9,
52
+ :extensions => %w[anseladams=1 porn=0]},
53
+ 'image/png' =>
54
+ {:type => 'image', :subtype => 'png', :qval => 1.0},
55
+ 'IMAGE/pNg' =>
56
+ {:type => 'image', :subtype => 'png', :qval => 1.0},
57
+ 'application/x-porno' =>
58
+ {:type => 'application', :subtype => 'x-porno', :qval => 1.0},
59
+ 'image/png; q=0.2' =>
60
+ {:type => 'image', :subtype => 'png', :qval => 0.2},
61
+ 'image/x-giraffes;q=0.2' =>
62
+ {:type => 'image', :subtype => 'x-giraffes', :qval => 0.2},
63
+ 'example/pork; headcheese=0;withfennel=1' =>
64
+ {:type => 'example', :subtype => 'pork', :qval => 1.0,
65
+ :extensions => %w[headcheese=0 withfennel=1]},
66
+ 'model/vnd.moml+xml' =>
67
+ {:type => 'model', :subtype => 'vnd.moml+xml', :qval => 1.0},
68
+ 'model/parasolid.transmit.binary; q=0.2' =>
69
+ {:type => 'model', :subtype => 'parasolid.transmit.binary',
70
+ :qval => 0.2},
71
+ 'image/png; q=0.2; compression=1' =>
72
+ {:type => 'image', :subtype => 'png', :qval => 0.2,
73
+ :extensions => %w[compression=1]},
74
+ }
75
+
76
+
77
+ it "parses valid Accept header values" do
78
+ VALID_HEADERS.each do |hdr, expectations|
79
+ rval = Strelka::HTTPRequest::MediaType.parse( hdr )
80
+
81
+ rval.should be_an_instance_of( Strelka::HTTPRequest::MediaType )
82
+ rval.type.should == expectations[:type]
83
+ rval.subtype.should == expectations[:subtype]
84
+ rval.qvalue.should == expectations[:qval]
85
+
86
+ if expectations[:extensions]
87
+ expectations[:extensions].each do |ext|
88
+ rval.extensions.should include( ext )
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+
95
+ it "is lenient (but warns) about invalid qvalues" do
96
+ rval = Strelka::HTTPRequest::MediaType.parse( '*/*; q=18' )
97
+ rval.should be_an_instance_of( Strelka::HTTPRequest::MediaType )
98
+ rval.qvalue.should == 1.0
99
+ end
100
+
101
+
102
+ it "rejects invalid Accept header values" do
103
+ lambda {
104
+ Strelka::HTTPRequest::MediaType.parse( 'porksausage' )
105
+ }.should raise_error()
106
+ end
107
+
108
+
109
+ it "can represent itself in a human-readable object format" do
110
+ header = "text/html; q=0.9; level=2"
111
+ acceptparam = Strelka::HTTPRequest::MediaType.parse( header )
112
+ acceptparam.inspect.should =~ %r{MediaType.*text/html.*q=0.9}
113
+ end
114
+
115
+
116
+ it "can represent itself as an Accept header" do
117
+ header = "text/html;q=0.9;level=2"
118
+ acceptparam = Strelka::HTTPRequest::MediaType.parse( header )
119
+ acceptparam.to_s.should == header
120
+ end
121
+
122
+
123
+ it "can compare and sort on specificity" do
124
+ header = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9," +
125
+ "text/html;q=0.9;level=1,text/plain;q=0.8,image/png,*/*;q=0.5"
126
+ params = header.
127
+ split( /\s*,\s*/ ).
128
+ collect {|par| Strelka::HTTPRequest::MediaType.parse( par ) }.
129
+ sort
130
+
131
+ params[0].to_s.should == 'application/xhtml+xml;q=1.0'
132
+ params[1].to_s.should == 'application/xml;q=1.0'
133
+ params[2].to_s.should == 'image/png;q=1.0'
134
+ params[3].to_s.should == 'text/xml;q=1.0'
135
+ params[4].to_s.should == 'text/html;q=0.9'
136
+ params[5].to_s.should == 'text/html;q=0.9;level=1'
137
+ params[6].to_s.should == 'text/plain;q=0.8'
138
+ params[7].to_s.should == '*/*;q=0.5'
139
+ end
140
+
141
+
142
+ it "can be compared against strings" do
143
+ specific_param = Strelka::HTTPRequest::MediaType.parse( 'text/html' )
144
+ subtype_wildcard_param = Strelka::HTTPRequest::MediaType.parse( 'image/*' )
145
+
146
+ ( specific_param =~ 'text/html' ).should be_true()
147
+ ( specific_param =~ 'image/png' ).should be_false()
148
+
149
+ ( subtype_wildcard_param =~ 'image/png' ).should be_true()
150
+ ( subtype_wildcard_param =~ 'image/jpeg' ).should be_true()
151
+ ( subtype_wildcard_param =~ 'text/plain' ).should be_false()
152
+ end
153
+ end
154
+
155
+
156
+ describe Strelka::HTTPRequest::Language do
157
+
158
+ it "can parse a simple language code" do
159
+ hdr = 'en'
160
+ param = Strelka::HTTPRequest::Language.parse( hdr )
161
+
162
+ param.should be_an_instance_of( Strelka::HTTPRequest::Language )
163
+ param.primary_tag.should == 'en'
164
+ param.subtag.should be_nil()
165
+ param.qvalue.should == 1.0
166
+ param.extensions.should be_empty()
167
+ end
168
+
169
+ it "can parse a language range with a dialect" do
170
+ hdr = 'en-gb'
171
+ param = Strelka::HTTPRequest::Language.parse( hdr )
172
+
173
+ param.should be_an_instance_of( Strelka::HTTPRequest::Language )
174
+ param.primary_tag.should == 'en'
175
+ param.subtag.should == 'gb'
176
+ param.qvalue.should == 1.0
177
+ param.extensions.should be_empty()
178
+ end
179
+
180
+ it "can parse a language tag with a q-value" do
181
+ hdr = 'en-US; q=0.8'
182
+ param = Strelka::HTTPRequest::Language.parse( hdr )
183
+
184
+ param.should be_an_instance_of( Strelka::HTTPRequest::Language )
185
+ param.primary_tag.should == 'en'
186
+ param.subtag.should == 'us'
187
+ param.qvalue.should == 0.8
188
+ param.extensions.should be_empty()
189
+ end
190
+
191
+ end
192
+
193
+
194
+ describe Strelka::HTTPRequest::Charset do
195
+
196
+ it "can parse a simple charset" do
197
+ hdr = 'iso-8859-1'
198
+ param = Strelka::HTTPRequest::Charset.parse( hdr )
199
+
200
+ param.should be_an_instance_of( Strelka::HTTPRequest::Charset )
201
+ param.name.should == 'iso-8859-1'
202
+ param.subtype.should be_nil()
203
+ param.qvalue.should == 1.0
204
+ param.extensions.should be_empty()
205
+ end
206
+
207
+ it "can parse a charset with a q-value" do
208
+ hdr = 'iso-8859-15; q=0.5'
209
+ param = Strelka::HTTPRequest::Charset.parse( hdr )
210
+
211
+ param.should be_an_instance_of( Strelka::HTTPRequest::Charset )
212
+ param.name.should == 'iso-8859-15'
213
+ param.subtype.should be_nil()
214
+ param.qvalue.should == 0.5
215
+ param.extensions.should be_empty()
216
+ end
217
+
218
+ it "can return the Ruby Encoding object associated with its character set" do
219
+ param = Strelka::HTTPRequest::Charset.parse( 'koi8-r' )
220
+ param.name.should == 'koi8-r'
221
+ param.encoding_object.should == Encoding::KOI8_R
222
+ end
223
+
224
+ it "can be compared against strings" do
225
+ specific_param = Strelka::HTTPRequest::Charset.parse( 'us-ascii' )
226
+
227
+ ( specific_param =~ 'us-ascii' ).should be_true()
228
+ ( specific_param =~ 'ansi_x3.4-1968' ).should be_true()
229
+ ( specific_param =~ 'utf-8' ).should be_false()
230
+ end
231
+
232
+ it "can be compared against Encoding objects" do
233
+ specific_param = Strelka::HTTPRequest::Charset.parse( 'utf-8' )
234
+
235
+ ( specific_param =~ Encoding::UTF_8 ).should be_true()
236
+ ( specific_param =~ Encoding::CP65001 ).should be_true()
237
+ ( specific_param =~ Encoding::MacThai ).should be_false()
238
+ end
239
+ end
240
+
241
+
242
+ describe Strelka::HTTPRequest::Encoding do
243
+
244
+ it "can parse a simple encoding" do
245
+ hdr = 'identity'
246
+ param = Strelka::HTTPRequest::Encoding.parse( hdr )
247
+
248
+ param.should be_an_instance_of( Strelka::HTTPRequest::Encoding )
249
+ param.content_coding.should == 'identity'
250
+ param.subtype.should be_nil()
251
+ param.qvalue.should == 1.0
252
+ param.extensions.should be_empty()
253
+ end
254
+
255
+ it "can parse an encoding with a q-value" do
256
+ hdr = 'gzip; q=0.55'
257
+ param = Strelka::HTTPRequest::Encoding.parse( hdr )
258
+
259
+ param.should be_an_instance_of( Strelka::HTTPRequest::Encoding )
260
+ param.content_coding.should == 'gzip'
261
+ param.subtype.should be_nil()
262
+ param.qvalue.should == 0.55
263
+ param.extensions.should be_empty()
264
+ end
265
+
266
+ it "can be compared against strings" do
267
+ specific_param = Strelka::HTTPRequest::MediaType.parse( 'text/html' )
268
+ subtype_wildcard_param = Strelka::HTTPRequest::MediaType.parse( 'image/*' )
269
+
270
+ ( specific_param =~ 'text/html' ).should be_true()
271
+ ( specific_param =~ 'image/png' ).should be_false()
272
+
273
+ ( subtype_wildcard_param =~ 'image/png' ).should be_true()
274
+ ( subtype_wildcard_param =~ 'image/jpeg' ).should be_true()
275
+ ( subtype_wildcard_param =~ 'text/plain' ).should be_false()
276
+ end
277
+ end
278
+
279
+
280
+ end
281
+
282
+ # vim: set nosta noet ts=4 sw=4:
@@ -0,0 +1,246 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
6
+
7
+ libdir = basedir + "lib"
8
+
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
10
+ $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
11
+ }
12
+
13
+ require 'rspec'
14
+
15
+ require 'spec/lib/helpers'
16
+
17
+ require 'strelka'
18
+ require 'strelka/httprequest/negotiation'
19
+ require 'strelka/httpresponse/negotiation'
20
+
21
+
22
+ #####################################################################
23
+ ### C O N T E X T S
24
+ #####################################################################
25
+
26
+ describe Strelka::HTTPRequest::Negotiation do
27
+
28
+ before( :all ) do
29
+ setup_logging( :fatal )
30
+ @request_factory = Mongrel2::RequestFactory.new( route: '/service/user' )
31
+ end
32
+
33
+ after( :all ) do
34
+ reset_logging()
35
+ end
36
+
37
+
38
+ before( :each ) do
39
+ @req = @request_factory.get( '/service/user/estark' )
40
+ @req.extend( described_class )
41
+ end
42
+
43
+
44
+ describe "mediatype negotiation" do
45
+
46
+ it "know what content-types are accepted by the client" do
47
+ @req.headers.accept = 'application/x-yaml, application/json; q=0.2, text/xml; q=0.75'
48
+
49
+ @req.accepted_types.should have(3).members
50
+ @req.accepted_types[0].mediatype.should == 'application/x-yaml'
51
+ @req.accepted_types[0].qvalue.should == 1.0
52
+ @req.accepted_types[1].mediatype.should == 'application/json'
53
+ @req.accepted_types[1].qvalue.should == 0.2
54
+ @req.accepted_types[2].mediatype.should == 'text/xml'
55
+ @req.accepted_types[2].qvalue.should == 0.75
56
+ end
57
+
58
+ it "knows what mimetypes are acceptable responses" do
59
+ @req.headers.accept = 'text/html, text/plain; q=0.5, image/*;q=0.1'
60
+
61
+ @req.accepts?( 'text/html' ).should be_true()
62
+ @req.accepts?( 'text/plain' ).should be_true()
63
+ @req.accepts?( 'text/ascii' ).should be_false()
64
+ @req.accepts?( 'image/png' ).should be_true()
65
+ @req.accepts?( 'application/x-yaml' ).should be_false()
66
+ end
67
+
68
+ it "knows what mimetypes are explicitly acceptable responses" do
69
+ @req.headers.accept = 'text/html, text/plain; q=0.5, image/*;q=0.1, */*'
70
+
71
+ @req.explicitly_accepts?( 'text/html' ).should be_true()
72
+ @req.explicitly_accepts?( 'text/plain' ).should be_true()
73
+ @req.explicitly_accepts?( 'text/ascii' ).should be_false()
74
+ @req.explicitly_accepts?( 'image/png' ).should be_false()
75
+ @req.explicitly_accepts?( 'application/x-yaml' ).should be_false()
76
+ end
77
+
78
+ it "accepts anything if the client doesn't provide an Accept header" do
79
+ @req.headers.delete( :accept )
80
+
81
+ @req.accepts?( 'text/html' ).should be_true()
82
+ @req.accepts?( 'text/plain' ).should be_true()
83
+ @req.accepts?( 'text/ascii' ).should be_true()
84
+ @req.accepts?( 'image/png' ).should be_true()
85
+ @req.accepts?( 'application/x-yaml' ).should be_true()
86
+ end
87
+
88
+ it "doesn't explicitly accept anything if the client doesn't provide an Accept header" do
89
+ @req.headers.delete( :accept )
90
+
91
+ @req.explicitly_accepts?( 'text/html' ).should be_false()
92
+ @req.explicitly_accepts?( 'text/plain' ).should be_false()
93
+ @req.explicitly_accepts?( 'text/ascii' ).should be_false()
94
+ @req.explicitly_accepts?( 'image/png' ).should be_false()
95
+ @req.explicitly_accepts?( 'application/x-yaml' ).should be_false()
96
+ end
97
+
98
+ end
99
+
100
+
101
+ describe "character-set negotiation" do
102
+
103
+ it "knows what character sets are accepted by the client" do
104
+ @req.headers.accept_charset = 'iso-8859-5, utf-8;q=0.8'
105
+
106
+ @req.accepted_charsets.should have(2).members
107
+ @req.accepted_charsets[0].name.should == 'iso-8859-5'
108
+ @req.accepted_charsets[0].qvalue.should == 1.0
109
+ @req.accepted_charsets[1].name.should == 'utf-8'
110
+ @req.accepted_charsets[1].qvalue.should == 0.8
111
+ end
112
+
113
+ it "knows what charsets are acceptable responses" do
114
+ @req.headers.accept_charset = 'iso-8859-5, utf-8;q=0.8'
115
+
116
+ @req.accepts_charset?( 'iso8859-5' ).should be_true()
117
+ @req.accepts_charset?( 'iso-8859-5' ).should be_true()
118
+ @req.accepts_charset?( 'utf-8' ).should be_true()
119
+ @req.accepts_charset?( Encoding::CP65001 ).should be_true()
120
+ @req.accepts_charset?( 'mac' ).should be_false()
121
+ @req.accepts_charset?( Encoding::SJIS ).should be_false()
122
+ end
123
+
124
+ it "accepts any charset if the client doesn't provide an Accept-Charset header" do
125
+ @req.headers.delete( :accept_charset )
126
+
127
+ @req.accepts_charset?( 'iso8859-5' ).should be_true()
128
+ @req.accepts_charset?( 'iso-8859-5' ).should be_true()
129
+ @req.accepts_charset?( 'utf-8' ).should be_true()
130
+ @req.accepts_charset?( Encoding::CP65001 ).should be_true()
131
+ @req.accepts_charset?( 'mac' ).should be_true()
132
+ @req.accepts_charset?( Encoding::SJIS ).should be_true()
133
+ end
134
+
135
+ end
136
+
137
+
138
+ describe "content encoding negotiation" do
139
+
140
+ it "knows what encodings are accepted by the client" do
141
+ @req.headers.accept_encoding = 'gzip;q=1.0, identity; q=0.5, *;q=0'
142
+
143
+ @req.accepted_encodings.should have(3).members
144
+ @req.accepted_encodings[0].content_coding.should == 'gzip'
145
+ @req.accepted_encodings[0].qvalue.should == 1.0
146
+ @req.accepted_encodings[1].content_coding.should == 'identity'
147
+ @req.accepted_encodings[1].qvalue.should == 0.5
148
+ @req.accepted_encodings[2].content_coding.should be_nil()
149
+ @req.accepted_encodings[2].qvalue.should == 0.0
150
+ end
151
+
152
+ it "knows what encodings are acceptable" do
153
+ @req.headers.accept_encoding = 'gzip;q=1.0, identity; q=0.5, *;q=0'
154
+
155
+ @req.accepts_encoding?( 'gzip' ).should be_true()
156
+ @req.accepts_encoding?( 'identity' ).should be_true()
157
+ @req.accepts_encoding?( 'compress' ).should be_false()
158
+ end
159
+
160
+ it "knows that the identity encoding is acceptable if it isn't disabled" do
161
+ @req.headers.accept_encoding = 'gzip;q=1.0, compress; q=0.5'
162
+
163
+ @req.accepts_encoding?( 'gzip' ).should be_true()
164
+ @req.accepts_encoding?( 'identity' ).should be_true()
165
+ @req.accepts_encoding?( 'compress' ).should be_true()
166
+ @req.accepts_encoding?( 'clowns' ).should be_false()
167
+ end
168
+
169
+ it "accepts only the 'identity' encoding if the Accept-Encoding field is empty" do
170
+ @req.headers.accept_encoding = ''
171
+
172
+ @req.accepts_encoding?( 'identity' ).should be_true()
173
+ @req.accepts_encoding?( 'gzip' ).should be_false()
174
+ @req.accepts_encoding?( 'compress' ).should be_false()
175
+ end
176
+
177
+ it "doesn't accept the 'identity' encoding if the Accept-Encoding field explicitly disables it" do
178
+ @req.headers.accept_encoding = 'gzip;q=0.5, identity;q=0'
179
+
180
+ @req.accepts_encoding?( 'identity' ).should be_false()
181
+ @req.accepts_encoding?( 'gzip' ).should be_true()
182
+ @req.accepts_encoding?( 'compress' ).should be_false()
183
+ end
184
+
185
+ it "doesn't accept the 'identity' encoding if the Accept-Encoding field has a wildcard " +
186
+ "with q-value of 0 and doesn't explicitly include 'identity'" do
187
+ @req.headers.accept_encoding = 'gzip;q=0.5, *;q=0'
188
+
189
+ @req.accepts_encoding?( 'identity' ).should be_false()
190
+ @req.accepts_encoding?( 'gzip' ).should be_true()
191
+ @req.accepts_encoding?( 'compress' ).should be_false()
192
+ end
193
+
194
+ it "accepts every encoding if the request doesn't have an Accept-Encoding header" do
195
+ @req.headers.delete( :accept_encoding )
196
+
197
+ @req.accepts_encoding?( 'identity' ).should be_true()
198
+ @req.accepts_encoding?( 'gzip' ).should be_true()
199
+ @req.accepts_encoding?( 'compress' ).should be_true()
200
+ end
201
+
202
+ end
203
+
204
+
205
+ describe "natural language negotiation" do
206
+
207
+ it "knows what languages are accepted by the client" do
208
+ @req.headers.accept_language = 'da, en-gb;q=0.8, en;q=0.7'
209
+
210
+ @req.accepted_languages.should have(3).members
211
+ @req.accepted_languages[0].primary_tag.should == 'da'
212
+ @req.accepted_languages[0].subtag.should == nil
213
+ @req.accepted_languages[0].qvalue.should == 1.0
214
+ @req.accepted_languages[1].primary_tag.should == 'en'
215
+ @req.accepted_languages[1].subtag.should == 'gb'
216
+ @req.accepted_languages[1].qvalue.should == 0.8
217
+ @req.accepted_languages[2].primary_tag.should == 'en'
218
+ @req.accepted_languages[2].subtag.should == nil
219
+ @req.accepted_languages[2].qvalue.should == 0.7
220
+ end
221
+
222
+ it "knows what languages may be used in acceptable responses" do
223
+ @req.headers.accept_language = 'da, en-gb;q=0.8, en;q=0.7'
224
+
225
+ @req.accepts_language?( 'da' ).should be_true()
226
+ @req.accepts_language?( 'en' ).should be_true()
227
+ @req.accepts_language?( 'en-gb' ).should be_true()
228
+ @req.accepts_language?( 'en-cockney' ).should be_true()
229
+ @req.accepts_language?( 'de' ).should be_false()
230
+ @req.accepts_language?( 'tlh' ).should be_false()
231
+ end
232
+
233
+ it "accepts any language if the client doesn't provide an Accept-Language header" do
234
+ @req.headers.delete( :accept_language )
235
+
236
+ @req.accepts_language?( 'da' ).should be_true()
237
+ @req.accepts_language?( 'en' ).should be_true()
238
+ @req.accepts_language?( 'en-gb' ).should be_true()
239
+ @req.accepts_language?( 'en-cockney' ).should be_true()
240
+ @req.accepts_language?( 'de' ).should be_true()
241
+ @req.accepts_language?( 'tlh' ).should be_true()
242
+ end
243
+
244
+ end
245
+
246
+ end