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.
- data/History.rdoc +1 -1
- data/IDEAS.rdoc +62 -0
- data/Manifest.txt +38 -7
- data/README.rdoc +124 -5
- data/Rakefile +22 -6
- data/bin/leash +102 -157
- data/contrib/hoetemplate/.autotest.erb +23 -0
- data/contrib/hoetemplate/History.rdoc.erb +4 -0
- data/contrib/hoetemplate/Manifest.txt.erb +8 -0
- data/contrib/hoetemplate/README.rdoc.erb +17 -0
- data/contrib/hoetemplate/Rakefile.erb +24 -0
- data/contrib/hoetemplate/data/file_name/apps/file_name_app +36 -0
- data/contrib/hoetemplate/data/file_name/templates/layout.tmpl.erb +13 -0
- data/contrib/hoetemplate/data/file_name/templates/top.tmpl.erb +8 -0
- data/contrib/hoetemplate/lib/file_name.rb.erb +18 -0
- data/contrib/hoetemplate/spec/file_name_spec.rb.erb +21 -0
- data/data/strelka/apps/hello-world +30 -0
- data/lib/strelka/app/defaultrouter.rb +49 -30
- data/lib/strelka/app/errors.rb +121 -0
- data/lib/strelka/app/exclusiverouter.rb +40 -0
- data/lib/strelka/app/filters.rb +18 -7
- data/lib/strelka/app/negotiation.rb +122 -0
- data/lib/strelka/app/parameters.rb +171 -14
- data/lib/strelka/app/paramvalidator.rb +751 -0
- data/lib/strelka/app/plugins.rb +66 -46
- data/lib/strelka/app/restresources.rb +499 -0
- data/lib/strelka/app/router.rb +73 -0
- data/lib/strelka/app/routing.rb +140 -18
- data/lib/strelka/app/templating.rb +12 -3
- data/lib/strelka/app.rb +174 -24
- data/lib/strelka/constants.rb +0 -20
- data/lib/strelka/exceptions.rb +29 -0
- data/lib/strelka/httprequest/acceptparams.rb +377 -0
- data/lib/strelka/httprequest/negotiation.rb +257 -0
- data/lib/strelka/httprequest.rb +155 -7
- data/lib/strelka/httpresponse/negotiation.rb +579 -0
- data/lib/strelka/httpresponse.rb +140 -0
- data/lib/strelka/logging.rb +4 -1
- data/lib/strelka/mixins.rb +53 -0
- data/lib/strelka.rb +22 -1
- data/spec/data/error.tmpl +1 -0
- data/spec/lib/constants.rb +0 -1
- data/spec/lib/helpers.rb +21 -0
- data/spec/strelka/app/defaultrouter_spec.rb +41 -35
- data/spec/strelka/app/errors_spec.rb +212 -0
- data/spec/strelka/app/exclusiverouter_spec.rb +220 -0
- data/spec/strelka/app/filters_spec.rb +196 -0
- data/spec/strelka/app/negotiation_spec.rb +73 -0
- data/spec/strelka/app/parameters_spec.rb +149 -0
- data/spec/strelka/app/paramvalidator_spec.rb +1059 -0
- data/spec/strelka/app/plugins_spec.rb +26 -19
- data/spec/strelka/app/restresources_spec.rb +393 -0
- data/spec/strelka/app/router_spec.rb +63 -0
- data/spec/strelka/app/routing_spec.rb +183 -9
- data/spec/strelka/app/templating_spec.rb +1 -2
- data/spec/strelka/app_spec.rb +265 -32
- data/spec/strelka/exceptions_spec.rb +53 -0
- data/spec/strelka/httprequest/acceptparams_spec.rb +282 -0
- data/spec/strelka/httprequest/negotiation_spec.rb +246 -0
- data/spec/strelka/httprequest_spec.rb +204 -14
- data/spec/strelka/httpresponse/negotiation_spec.rb +464 -0
- data/spec/strelka/httpresponse_spec.rb +114 -0
- data/spec/strelka/mixins_spec.rb +99 -0
- data.tar.gz.sig +1 -0
- metadata +175 -79
- metadata.gz.sig +2 -0
- data/IDEAS.textile +0 -174
- data/data/strelka/apps/strelka-admin +0 -65
- data/data/strelka/apps/strelka-setup +0 -26
- data/data/strelka/bootstrap-config.rb +0 -34
- data/data/strelka/templates/admin/console.tmpl +0 -21
- data/data/strelka/templates/layout.tmpl +0 -30
- 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
|