strelka 0.0.1pre4 → 0.0.1.pre129

Sign up to get free protection for your applications and to get access to all the features.
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