webmachine 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/CHANGELOG.md +4 -0
  4. data/Gemfile +13 -11
  5. data/README.md +85 -89
  6. data/Rakefile +0 -1
  7. data/documentation/adapters.md +39 -0
  8. data/documentation/authentication-and-authorization.md +37 -0
  9. data/documentation/configurator.md +19 -0
  10. data/documentation/error-handling.md +86 -0
  11. data/documentation/examples.md +215 -0
  12. data/documentation/how-it-works.md +76 -0
  13. data/documentation/routes.md +97 -0
  14. data/documentation/validation.md +159 -0
  15. data/documentation/versioning-apis.md +74 -0
  16. data/documentation/visual-debugger.md +38 -0
  17. data/examples/application.rb +2 -2
  18. data/examples/debugger.rb +1 -1
  19. data/lib/webmachine.rb +3 -1
  20. data/lib/webmachine/adapter.rb +7 -13
  21. data/lib/webmachine/adapters.rb +1 -2
  22. data/lib/webmachine/adapters/httpkit.rb +74 -0
  23. data/lib/webmachine/adapters/lazy_request_body.rb +1 -2
  24. data/lib/webmachine/adapters/rack.rb +37 -21
  25. data/lib/webmachine/adapters/reel.rb +21 -23
  26. data/lib/webmachine/adapters/webrick.rb +16 -16
  27. data/lib/webmachine/application.rb +2 -2
  28. data/lib/webmachine/chunked_body.rb +3 -4
  29. data/lib/webmachine/constants.rb +75 -0
  30. data/lib/webmachine/decision/conneg.rb +12 -10
  31. data/lib/webmachine/decision/flow.rb +31 -21
  32. data/lib/webmachine/decision/fsm.rb +10 -18
  33. data/lib/webmachine/decision/helpers.rb +9 -37
  34. data/lib/webmachine/dispatcher.rb +13 -10
  35. data/lib/webmachine/dispatcher/route.rb +18 -8
  36. data/lib/webmachine/errors.rb +7 -1
  37. data/lib/webmachine/header_negotiation.rb +25 -0
  38. data/lib/webmachine/headers.rb +7 -2
  39. data/lib/webmachine/locale/en.yml +7 -5
  40. data/lib/webmachine/media_type.rb +10 -8
  41. data/lib/webmachine/request.rb +44 -15
  42. data/lib/webmachine/resource.rb +1 -1
  43. data/lib/webmachine/resource/callbacks.rb +6 -4
  44. data/lib/webmachine/spec/IO_response.body +1 -0
  45. data/lib/webmachine/spec/adapter_lint.rb +70 -36
  46. data/lib/webmachine/spec/test_resource.rb +10 -4
  47. data/lib/webmachine/streaming/fiber_encoder.rb +1 -5
  48. data/lib/webmachine/streaming/io_encoder.rb +6 -0
  49. data/lib/webmachine/trace.rb +1 -0
  50. data/lib/webmachine/trace/fsm.rb +20 -10
  51. data/lib/webmachine/trace/resource_proxy.rb +2 -0
  52. data/lib/webmachine/translation.rb +2 -1
  53. data/lib/webmachine/version.rb +3 -3
  54. data/memory_test.rb +37 -0
  55. data/spec/spec_helper.rb +9 -9
  56. data/spec/webmachine/adapter_spec.rb +14 -15
  57. data/spec/webmachine/adapters/httpkit_spec.rb +10 -0
  58. data/spec/webmachine/adapters/rack_spec.rb +6 -6
  59. data/spec/webmachine/adapters/reel_spec.rb +15 -11
  60. data/spec/webmachine/adapters/webrick_spec.rb +2 -2
  61. data/spec/webmachine/application_spec.rb +18 -17
  62. data/spec/webmachine/chunked_body_spec.rb +3 -3
  63. data/spec/webmachine/configuration_spec.rb +5 -5
  64. data/spec/webmachine/cookie_spec.rb +13 -13
  65. data/spec/webmachine/decision/conneg_spec.rb +48 -42
  66. data/spec/webmachine/decision/falsey_spec.rb +4 -4
  67. data/spec/webmachine/decision/flow_spec.rb +194 -144
  68. data/spec/webmachine/decision/fsm_spec.rb +17 -17
  69. data/spec/webmachine/decision/helpers_spec.rb +20 -20
  70. data/spec/webmachine/dispatcher/route_spec.rb +73 -27
  71. data/spec/webmachine/dispatcher_spec.rb +34 -24
  72. data/spec/webmachine/errors_spec.rb +1 -1
  73. data/spec/webmachine/etags_spec.rb +19 -19
  74. data/spec/webmachine/events_spec.rb +6 -6
  75. data/spec/webmachine/headers_spec.rb +14 -14
  76. data/spec/webmachine/media_type_spec.rb +36 -36
  77. data/spec/webmachine/request_spec.rb +33 -33
  78. data/spec/webmachine/resource/authentication_spec.rb +6 -6
  79. data/spec/webmachine/response_spec.rb +12 -12
  80. data/spec/webmachine/trace/fsm_spec.rb +8 -8
  81. data/spec/webmachine/trace/resource_proxy_spec.rb +9 -9
  82. data/spec/webmachine/trace/trace_store_spec.rb +5 -5
  83. data/spec/webmachine/trace_spec.rb +3 -3
  84. data/webmachine.gemspec +2 -6
  85. metadata +48 -206
  86. data/lib/webmachine/adapters/hatetepe.rb +0 -108
  87. data/lib/webmachine/adapters/mongrel.rb +0 -127
  88. data/lib/webmachine/dispatcher/not_found_resource.rb +0 -5
  89. data/lib/webmachine/fiber18.rb +0 -88
  90. data/spec/webmachine/adapters/hatetepe_spec.rb +0 -60
  91. data/spec/webmachine/adapters/mongrel_spec.rb +0 -16
@@ -1,8 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Webmachine::Decision::Falsey do
4
- specify { (described_class.=== false).should be_true }
5
- specify { (described_class.=== nil).should be_true }
6
- specify { (described_class.=== true).should be_false }
7
- specify { (described_class.=== []).should be_false }
4
+ specify { expect(described_class.=== false).to be(true) }
5
+ specify { expect(described_class.=== nil).to be(true) }
6
+ specify { expect(described_class.=== true).to be(false) }
7
+ specify { expect(described_class.=== []).to be(false) }
8
8
  end
@@ -16,7 +16,7 @@ describe Webmachine::Decision::Flow do
16
16
  # ... [except 1xx or 5xx]
17
17
  after(:each) do
18
18
  unless response.code < 200 || response.code >= 500
19
- response.headers.should have_key('Date')
19
+ expect(response.headers).to have_key('Date')
20
20
  end
21
21
  end
22
22
 
@@ -46,7 +46,7 @@ describe Webmachine::Decision::Flow do
46
46
  it "should respond with 503 when the service is unavailable" do
47
47
  resource.available = false
48
48
  subject.run
49
- response.code.should == 503
49
+ expect(response.code).to eq 503
50
50
  end
51
51
  end
52
52
 
@@ -59,7 +59,7 @@ describe Webmachine::Decision::Flow do
59
59
 
60
60
  it "should respond with 501 when the method is unknown" do
61
61
  subject.run
62
- response.code.should == 501
62
+ expect(response.code).to eq 501
63
63
  end
64
64
  end
65
65
 
@@ -72,7 +72,7 @@ describe Webmachine::Decision::Flow do
72
72
 
73
73
  it "should respond with 414 when the URI is too long" do
74
74
  subject.run
75
- response.code.should == 414
75
+ expect(response.code).to eq 414
76
76
  end
77
77
  end
78
78
 
@@ -85,8 +85,8 @@ describe Webmachine::Decision::Flow do
85
85
 
86
86
  it "should respond with 405 when the method is not allowed" do
87
87
  subject.run
88
- response.code.should == 405
89
- response.headers['Allow'].should == "POST"
88
+ expect(response.code).to eq 405
89
+ expect(response.headers['Allow']).to eq "POST"
90
90
  end
91
91
  end
92
92
 
@@ -95,7 +95,7 @@ describe Webmachine::Decision::Flow do
95
95
 
96
96
  it "should respond with 400 when the request is malformed" do
97
97
  subject.run
98
- response.code.should == 400
98
+ expect(response.code).to eq 400
99
99
  end
100
100
 
101
101
  context "when the Content-MD5 header is present" do
@@ -112,31 +112,61 @@ describe Webmachine::Decision::Flow do
112
112
  let(:body) { "This is the body." }
113
113
  let(:headers) { Webmachine::Headers["Content-Type" => "text/plain"] }
114
114
 
115
+ it "should respond with 204 when the request body does match the header" do
116
+ headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest(body)
117
+ subject.run
118
+ expect(response.code).to eq 204
119
+ end
120
+
121
+ it "should bypass validation when the header has a nil value" do
122
+ headers['Content-MD5'] = nil
123
+ subject.run
124
+ expect(response.code).to eq 204
125
+ end
126
+
127
+ it "should respond with 400 when the header has a empty string value" do
128
+ headers['Content-MD5'] = ""
129
+ subject.run
130
+ expect(response.code).to eq 400
131
+ end
132
+
133
+ it "should respond with 400 when the header has a non-hashed, non-encoded value" do
134
+ headers["Content-MD5"] = body
135
+ subject.run
136
+ expect(response.code).to eq 400
137
+ end
138
+
139
+ it "should respond with 400 when the header is not encoded as Base64 but digest matches the body" do
140
+ headers['Content-MD5'] = Digest::MD5.hexdigest(body)
141
+ subject.run
142
+ expect(response.code).to eq 400
143
+ end
144
+
115
145
  it "should respond with 400 when the request body does not match the header" do
116
- headers['Content-MD5'] = "thiswillnotmatchthehash"
146
+ headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest("thiswillnotmatchthehash")
117
147
  subject.run
118
- response.code.should == 400
148
+ expect(response.code).to eq 400
119
149
  end
120
150
 
121
151
  it "should respond with 400 when the resource invalidates the checksum" do
122
152
  resource.validation = false
123
- headers['Content-MD5'] = "thiswillnotmatchthehash"
153
+ headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest("thiswillnotmatchthehash")
124
154
  subject.run
125
- response.code.should == 400
155
+ expect(response.code).to eq 400
126
156
  end
127
157
 
128
158
  it "should not respond with 400 when the resource validates the checksum" do
129
159
  resource.validation = true
130
- headers['Content-MD5'] = "thiswillnotmatchthehash"
160
+ headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest("thiswillnotmatchthehash")
131
161
  subject.run
132
- response.code.should_not == 400
162
+ expect(response.code).to_not eq 400
133
163
  end
134
164
 
135
165
  it "should respond with the given code when the resource returns a code while validating" do
136
166
  resource.validation = 500
137
- headers['Content-MD5'] = "thiswillnotmatchthehash"
167
+ headers['Content-MD5'] = Base64.encode64 Digest::MD5.hexdigest("thiswillnotmatchthehash")
138
168
  subject.run
139
- response.code.should == 500
169
+ expect(response.code).to eq 500
140
170
  end
141
171
  end
142
172
  end
@@ -147,26 +177,26 @@ describe Webmachine::Decision::Flow do
147
177
  it "should reply with 401 when the client is unauthorized" do
148
178
  resource.auth = false
149
179
  subject.run
150
- response.code.should == 401
180
+ expect(response.code).to eq 401
151
181
  end
152
182
 
153
183
  it "should reply with 401 when the resource gives a challenge" do
154
184
  resource.auth = "Basic realm=Webmachine"
155
185
  subject.run
156
- response.code.should == 401
157
- response.headers['WWW-Authenticate'].should == "Basic realm=Webmachine"
186
+ expect(response.code).to eq 401
187
+ expect(response.headers['WWW-Authenticate']).to eq "Basic realm=Webmachine"
158
188
  end
159
189
 
160
190
  it "should halt with the given code when the resource returns a status code" do
161
191
  resource.auth = 400
162
192
  subject.run
163
- response.code.should == 400
193
+ expect(response.code).to eq 400
164
194
  end
165
195
 
166
196
  it "should not reply with 401 when the client is authorized" do
167
197
  resource.auth = true
168
198
  subject.run
169
- response.code.should_not == 401
199
+ expect(response.code).to_not eq 401
170
200
  end
171
201
  end
172
202
 
@@ -176,19 +206,19 @@ describe Webmachine::Decision::Flow do
176
206
  it "should reply with 403 when the request is forbidden" do
177
207
  resource.forbid = true
178
208
  subject.run
179
- response.code.should == 403
209
+ expect(response.code).to eq 403
180
210
  end
181
211
 
182
212
  it "should not reply with 403 when the request is permitted" do
183
213
  resource.forbid = false
184
214
  subject.run
185
- response.code.should_not == 403
215
+ expect(response.code).to_not eq 403
186
216
  end
187
217
 
188
218
  it "should halt with the given code when the resource returns a status code" do
189
219
  resource.forbid = 400
190
220
  subject.run
191
- response.code.should == 400
221
+ expect(response.code).to eq 400
192
222
  end
193
223
  end
194
224
 
@@ -204,12 +234,12 @@ describe Webmachine::Decision::Flow do
204
234
  it "should reply with 501 when an invalid Content-* header is present" do
205
235
  headers['Content-Fail'] = "yup"
206
236
  subject.run
207
- response.code.should == 501
237
+ expect(response.code).to eq 501
208
238
  end
209
239
 
210
240
  it "should not reply with 501 when all Content-* headers are valid" do
211
241
  subject.run
212
- response.code.should_not == 501
242
+ expect(response.code).to_not eq 501
213
243
  end
214
244
  end
215
245
 
@@ -229,13 +259,13 @@ describe Webmachine::Decision::Flow do
229
259
  it "should reply with 415 when the Content-Type is unknown" do
230
260
  headers['Content-Type'] = "application/x-unknown-type"
231
261
  subject.run
232
- response.code.should == 415
262
+ expect(response.code).to eq 415
233
263
  end
234
264
 
235
265
  it "should not reply with 415 when the Content-Type is known" do
236
266
  headers['Content-Type'] = "text/plain"
237
267
  subject.run
238
- response.code.should_not == 415
268
+ expect(response.code).to_not eq 415
239
269
  end
240
270
  end
241
271
 
@@ -254,7 +284,7 @@ describe Webmachine::Decision::Flow do
254
284
  let(:body) { "Big" * 100 }
255
285
  it "should reply with 413" do
256
286
  subject.run
257
- response.code.should == 413
287
+ expect(response.code).to eq 413
258
288
  end
259
289
  end
260
290
 
@@ -263,7 +293,7 @@ describe Webmachine::Decision::Flow do
263
293
 
264
294
  it "should not reply with 413" do
265
295
  subject.run
266
- response.code.should_not == 413
296
+ expect(response.code).to_not eq 413
267
297
  end
268
298
  end
269
299
  end
@@ -273,7 +303,7 @@ describe Webmachine::Decision::Flow do
273
303
  let(:resource){ resource_with { def allowed_methods; %w[GET HEAD OPTIONS]; end } }
274
304
  it "should reply with 200 when the request method is OPTIONS" do
275
305
  subject.run
276
- response.code.should == 200
306
+ expect(response.code).to eq 200
277
307
  end
278
308
  end
279
309
 
@@ -283,23 +313,23 @@ describe Webmachine::Decision::Flow do
283
313
  it "should reply with 406 when the type is unacceptable" do
284
314
  headers['Accept'] = "text/plain"
285
315
  subject.run
286
- response.code.should == 406
316
+ expect(response.code).to eq 406
287
317
  end
288
318
 
289
319
  it "should not reply with 406 when the type is acceptable" do
290
320
  headers['Accept'] = "text/*"
291
321
  subject.run
292
- response.code.should_not == 406
293
- response.headers['Content-Type'].should == "text/html"
322
+ expect(response.code).to_not eq 406
323
+ expect(response.headers['Content-Type']).to eq "text/html"
294
324
  end
295
325
  end
296
326
 
297
327
  context "when the Accept header does not exist" do
298
328
  it "should not negotiate a media type" do
299
- headers['Accept'].should be_nil
300
- subject.should_not_receive(:c4)
329
+ expect(headers['Accept']).to be_nil
330
+ expect(subject).to_not receive(:c4)
301
331
  subject.run
302
- response.headers['Content-Type'].should == 'text/html'
332
+ expect(response.headers['Content-Type']).to eq 'text/html'
303
333
  end
304
334
  end
305
335
  end
@@ -310,25 +340,25 @@ describe Webmachine::Decision::Flow do
310
340
  it "should reply with 406 when the language is unacceptable" do
311
341
  headers['Accept-Language'] = "es, de"
312
342
  subject.run
313
- response.code.should == 406
343
+ expect(response.code).to eq 406
314
344
  end
315
345
 
316
346
  it "should not reply with 406 when the language is acceptable" do
317
347
  headers['Accept-Language'] = "en-GB, en;q=0.7"
318
348
  subject.run
319
- response.code.should_not == 406
320
- response.headers['Content-Language'].should == "en-US"
321
- resource.instance_variable_get(:@language).should == 'en-US'
349
+ expect(response.code).to_not eq 406
350
+ expect(response.headers['Content-Language']).to eq "en-US"
351
+ expect(resource.instance_variable_get(:@language)).to eq 'en-US'
322
352
  end
323
353
  end
324
354
 
325
355
  context "when the Accept-Language header is absent" do
326
356
  it "should not negotiate the language" do
327
- headers['Accept-Language'].should be_nil
328
- subject.should_not_receive(:d5)
357
+ expect(headers['Accept-Language']).to be_nil
358
+ expect(subject).to_not receive(:d5)
329
359
  subject.run
330
- response.headers['Content-Language'].should == 'en-US'
331
- resource.instance_variable_get(:@language).should == 'en-US'
360
+ expect(response.headers['Content-Language']).to eq 'en-US'
361
+ expect(resource.instance_variable_get(:@language)).to eq 'en-US'
332
362
  end
333
363
  end
334
364
  end
@@ -348,23 +378,23 @@ describe Webmachine::Decision::Flow do
348
378
  it "should reply with 406 when the charset is unacceptable" do
349
379
  headers['Accept-Charset'] = "utf-16"
350
380
  subject.run
351
- response.code.should == 406
381
+ expect(response.code).to eq 406
352
382
  end
353
383
 
354
384
  it "should not reply with 406 when the charset is acceptable" do
355
385
  headers['Accept-Charset'] = "iso8859-1"
356
386
  subject.run
357
- response.code.should_not == 406
358
- response.headers['Content-Type'].should == "text/html;charset=iso8859-1"
387
+ expect(response.code).to_not eq 406
388
+ expect(response.headers['Content-Type']).to eq "text/html;charset=iso8859-1"
359
389
  end
360
390
  end
361
391
 
362
392
  context "when the Accept-Charset header is absent" do
363
393
  it "should not negotiate the language" do
364
- headers['Accept-Charset'].should be_nil
365
- subject.should_not_receive(:e6)
394
+ expect(headers['Accept-Charset']).to be_nil
395
+ expect(subject).to_not receive(:e6)
366
396
  subject.run
367
- response.headers['Content-Type'].should == 'text/html;charset=iso8859-1'
397
+ expect(response.headers['Content-Type']).to eq 'text/html;charset=iso8859-1'
368
398
  end
369
399
  end
370
400
  end
@@ -382,27 +412,27 @@ describe Webmachine::Decision::Flow do
382
412
  it "should reply with 406 if the encoding is unacceptable" do
383
413
  headers['Accept-Encoding'] = 'deflate, identity;q=0.0'
384
414
  subject.run
385
- response.code.should == 406
415
+ expect(response.code).to eq 406
386
416
  end
387
417
 
388
418
  it "should not reply with 406 if the encoding is acceptable" do
389
419
  headers['Accept-Encoding'] = 'gzip, deflate'
390
420
  subject.run
391
- response.code.should_not == 406
392
- response.headers['Content-Encoding'].should == 'gzip'
421
+ expect(response.code).to_not eq 406
422
+ expect(response.headers['Content-Encoding']).to eq 'gzip'
393
423
  # It should be compressed
394
- response.body.should_not == 'test resource'
424
+ expect(response.body).to_not eq 'test resource'
395
425
  end
396
426
  end
397
427
 
398
428
  context "when the Accept-Encoding header is not present" do
399
429
  it "should not negotiate an encoding" do
400
- headers['Accept-Encoding'].should be_nil
401
- subject.should_not_receive(:f7)
430
+ expect(headers['Accept-Encoding']).to be_nil
431
+ expect(subject).to_not receive(:f7)
402
432
  subject.run
403
- response.code.should_not == 406
433
+ expect(response.code).to_not eq 406
404
434
  # It should not be compressed
405
- response.body.should == 'test resource'
435
+ expect(response.body).to eq 'test resource'
406
436
  end
407
437
  end
408
438
  end
@@ -412,28 +442,28 @@ describe Webmachine::Decision::Flow do
412
442
 
413
443
  it "should not enter conditional requests if missing (and eventually reply with 404)" do
414
444
  resource.exist = false
415
- subject.should_not_receive(:g8)
445
+ expect(subject).to_not receive(:g8)
416
446
  subject.run
417
- response.code.should == 404
447
+ expect(response.code).to eq 404
418
448
  end
419
449
 
420
450
  it "should not reply with 404 if it does exist" do
421
451
  resource.exist = true
422
- subject.should_not_receive(:h7)
452
+ expect(subject).to_not receive(:h7)
423
453
  subject.run
424
- response.code.should_not == 404
454
+ expect(response.code).to_not eq 404
425
455
  end
426
456
 
427
457
  it "should not reply with 404 for truthy non-booleans" do
428
458
  resource.exist = []
429
459
  subject.run
430
- response.code.should_not == 404
460
+ expect(response.code).to_not eq 404
431
461
  end
432
462
 
433
463
  it "should reply with 404 for nil" do
434
464
  resource.exist = nil
435
465
  subject.run
436
- response.code.should == 404
466
+ expect(response.code).to eq 404
437
467
  end
438
468
  end
439
469
 
@@ -441,26 +471,26 @@ describe Webmachine::Decision::Flow do
441
471
  describe "#g8, #g9, #g10 (ETag match)" do
442
472
  let(:resource) { resource_with { def generate_etag; "etag"; end } }
443
473
  it "should skip ETag matching when If-Match is missing" do
444
- headers['If-Match'].should be_nil
445
- subject.should_not_receive(:g9)
446
- subject.should_not_receive(:g11)
474
+ expect(headers['If-Match']).to be_nil
475
+ expect(subject).to_not receive(:g9)
476
+ expect(subject).to_not receive(:g11)
447
477
  subject.run
448
- response.code.should_not == 412
478
+ expect(response.code).to_not eq 412
449
479
  end
450
480
  it "should not reply with 304 when If-Match is *" do
451
481
  headers['If-Match'] = "*"
452
482
  subject.run
453
- response.code.should_not == 412
483
+ expect(response.code).to_not eq 412
454
484
  end
455
485
  it "should reply with 412 if the ETag is not in If-Match" do
456
486
  headers['If-Match'] = '"notetag"'
457
487
  subject.run
458
- response.code.should == 412
488
+ expect(response.code).to eq 412
459
489
  end
460
490
  it "should not reply with 412 if the ETag is in If-Match" do
461
491
  headers['If-Match'] = '"etag"'
462
492
  subject.run
463
- response.code.should_not == 412
493
+ expect(response.code).to_not eq 412
464
494
  end
465
495
  end
466
496
 
@@ -469,30 +499,30 @@ describe Webmachine::Decision::Flow do
469
499
  before { @now = resource.now = Time.now }
470
500
 
471
501
  it "should skip LM matching if IUMS is missing" do
472
- headers['If-Unmodified-Since'].should be_nil
473
- subject.should_not_receive(:h11)
474
- subject.should_not_receive(:h12)
502
+ expect(headers['If-Unmodified-Since']).to be_nil
503
+ expect(subject).to_not receive(:h11)
504
+ expect(subject).to_not receive(:h12)
475
505
  subject.run
476
- response.code.should_not == 412
506
+ expect(response.code).to_not eq 412
477
507
  end
478
508
 
479
509
  it "should skip LM matching if IUMS is an invalid date" do
480
510
  headers['If-Unmodified-Since'] = "garbage"
481
- subject.should_not_receive(:h12)
511
+ expect(subject).to_not receive(:h12)
482
512
  subject.run
483
- response.code.should_not == 412
513
+ expect(response.code).to_not eq 412
484
514
  end
485
515
 
486
516
  it "should not reply with 412 if LM is <= IUMS" do
487
517
  headers['If-Unmodified-Since'] = (@now + 100).httpdate
488
518
  subject.run
489
- response.code.should_not == 412
519
+ expect(response.code).to_not eq 412
490
520
  end
491
521
 
492
522
  it "should reply with 412 if LM is > IUMS" do
493
523
  headers['If-Unmodified-Since'] = (@now - 100).httpdate
494
524
  subject.run
495
- response.code.should == 412
525
+ expect(response.code).to eq 412
496
526
  end
497
527
  end
498
528
 
@@ -506,18 +536,18 @@ describe Webmachine::Decision::Flow do
506
536
  end
507
537
 
508
538
  it "should skip ETag matching if If-None-Match is missing" do
509
- headers['If-None-Match'].should be_nil
539
+ expect(headers['If-None-Match']).to be_nil
510
540
  %w{i13 k13 j18}.each do |m|
511
- subject.should_not_receive(m.to_sym)
541
+ expect(subject).to_not receive(m.to_sym)
512
542
  end
513
543
  subject.run
514
- [304, 412].should_not include(response.code)
544
+ expect([304, 412]).to_not include(response.code)
515
545
  end
516
546
 
517
547
  it "should not reply with 412 or 304 if the ETag is not in If-None-Match" do
518
548
  headers['If-None-Match'] = '"notetag"'
519
549
  subject.run
520
- [304, 412].should_not include(response.code)
550
+ expect([304, 412]).to_not include(response.code)
521
551
  end
522
552
 
523
553
  context "when the method is GET or HEAD" do
@@ -528,7 +558,7 @@ describe Webmachine::Decision::Flow do
528
558
  it "should reply with 304 when the ETag is in If-None-Match" do
529
559
  headers['If-None-Match'] = '"etag", "foobar"'
530
560
  end
531
- after { subject.run; response.code.should == 304 }
561
+ after { subject.run; expect(response.code).to eq 304 }
532
562
  end
533
563
 
534
564
  context "when the method is not GET or HEAD" do
@@ -543,7 +573,27 @@ describe Webmachine::Decision::Flow do
543
573
  it "should reply with 412 when the ETag is in If-None-Match" do
544
574
  headers['If-None-Match'] = '"etag"'
545
575
  end
546
- after { subject.run; response.code.should == 412 }
576
+ after { subject.run; expect(response.code).to eq 412 }
577
+ end
578
+
579
+ context "when the resource does not define an ETag" do
580
+ let(:resource) do
581
+ resource_with do
582
+ def generate_etag; nil; end
583
+ end
584
+ end
585
+
586
+ it "should reply with 200 when If-None-Match is missing" do
587
+ headers.delete 'If-None-Match'
588
+ subject.run
589
+ expect(response.code).to eq 200
590
+ end
591
+
592
+ it "should reply with 200 when If-None-Match is present" do
593
+ headers['If-None-Match'] = '"etag"'
594
+ subject.run
595
+ expect(response.code).to eq 200
596
+ end
547
597
  end
548
598
  end
549
599
 
@@ -551,41 +601,41 @@ describe Webmachine::Decision::Flow do
551
601
  let(:resource) { resource_with { attr_accessor :now; def last_modified; @now; end } }
552
602
  before { @now = resource.now = Time.now }
553
603
  it "should skip LM matching if IMS is missing" do
554
- headers['If-Modified-Since'].should be_nil
604
+ expect(headers['If-Modified-Since']).to be_nil
555
605
  %w{l14 l15 l17}.each do |m|
556
- subject.should_not_receive(m.to_sym)
606
+ expect(subject).to_not receive(m.to_sym)
557
607
  end
558
608
  subject.run
559
- response.code.should_not == 304
609
+ expect(response.code).to_not eq 304
560
610
  end
561
611
 
562
612
  it "should skip LM matching if IMS is an invalid date" do
563
613
  headers['If-Modified-Since'] = "garbage"
564
614
  %w{l15 l17}.each do |m|
565
- subject.should_not_receive(m.to_sym)
615
+ expect(subject).to_not receive(m.to_sym)
566
616
  end
567
617
  subject.run
568
- response.code.should_not == 304
618
+ expect(response.code).to_not eq 304
569
619
  end
570
620
 
571
621
  it "should skip LM matching if IMS is later than current time" do
572
622
  headers['If-Modified-Since'] = (@now + 1000).httpdate
573
- subject.should_not_receive(:l17)
623
+ expect(subject).to_not receive(:l17)
574
624
  subject.run
575
- response.code.should_not == 304
625
+ expect(response.code).to_not eq 304
576
626
  end
577
627
 
578
628
  it "should reply with 304 if LM is <= IMS" do
579
629
  headers['If-Modified-Since'] = (@now - 1).httpdate
580
630
  resource.now = @now - 1000
581
631
  subject.run
582
- response.code.should == 304
632
+ expect(response.code).to eq 304
583
633
  end
584
634
 
585
635
  it "should not reply with 304 if LM is > IMS" do
586
636
  headers['If-Modified-Since'] = (@now - 1000).httpdate
587
637
  subject.run
588
- response.code.should_not == 304
638
+ expect(response.code).to_not eq 304
589
639
  end
590
640
  end
591
641
 
@@ -595,13 +645,13 @@ describe Webmachine::Decision::Flow do
595
645
  it "should reply with 412 when the If-Match header is *" do
596
646
  headers['If-Match'] = '"*"'
597
647
  subject.run
598
- response.code.should == 412
648
+ expect(response.code).to eq 412
599
649
  end
600
650
 
601
651
  it "should not reply with 412 when the If-Match header is missing or not *" do
602
652
  headers['If-Match'] = ['"etag"', nil][rand(1)]
603
653
  subject.run
604
- response.code.should_not == 412
654
+ expect(response.code).to_not eq 412
605
655
  end
606
656
  end
607
657
 
@@ -619,22 +669,22 @@ describe Webmachine::Decision::Flow do
619
669
  let(:method){ "PUT" }
620
670
 
621
671
  it "should not reach state k7" do
622
- subject.should_not_receive(:k7)
672
+ expect(subject).to_not receive(:k7)
623
673
  subject.run
624
674
  end
625
675
 
626
- after { [404, 410, 303].should_not include(response.code) }
676
+ after { expect([404, 410, 303]).to_not include(response.code) }
627
677
  end
628
678
 
629
679
  context "when the method is not PUT" do
630
680
  let(:method){ %W{GET HEAD POST DELETE}[rand(4)] }
631
681
 
632
682
  it "should not reach state i4" do
633
- subject.should_not_receive(:i4)
683
+ expect(subject).to_not receive(:i4)
634
684
  subject.run
635
685
  end
636
686
 
637
- after { response.code.should_not == 409 }
687
+ after { expect(response.code).to_not eq 409 }
638
688
  end
639
689
  end
640
690
 
@@ -653,14 +703,14 @@ describe Webmachine::Decision::Flow do
653
703
  it "should reply with 301 when the resource has moved" do
654
704
  resource.location = URI.parse("http://localhost:8098/newuri")
655
705
  subject.run
656
- response.code.should == 301
657
- response.headers['Location'].should == resource.location.to_s
706
+ expect(response.code).to eq 301
707
+ expect(response.headers['Location']).to eq resource.location.to_s
658
708
  end
659
709
 
660
710
  it "should not reply with 301 when resource has not moved" do
661
711
  resource.location = false
662
712
  subject.run
663
- response.code.should_not == 301
713
+ expect(response.code).to_not eq 301
664
714
  end
665
715
  end
666
716
 
@@ -682,13 +732,13 @@ describe Webmachine::Decision::Flow do
682
732
  it "should reply with 301 when the resource has moved permanently" do
683
733
  uri = resource.moved_perm = URI.parse("http://www.google.com/")
684
734
  subject.run
685
- response.code.should == 301
686
- response.headers['Location'].should == uri.to_s
735
+ expect(response.code).to eq 301
736
+ expect(response.headers['Location']).to eq uri.to_s
687
737
  end
688
738
  it "should not reply with 301 when the resource has not moved permanently" do
689
739
  resource.moved_perm = false
690
740
  subject.run
691
- response.code.should_not == 301
741
+ expect(response.code).to_not eq 301
692
742
  end
693
743
  end
694
744
 
@@ -697,34 +747,34 @@ describe Webmachine::Decision::Flow do
697
747
  it "should reply with 307 when the resource has moved temporarily" do
698
748
  uri = resource.moved_temp = URI.parse("http://www.basho.com/")
699
749
  subject.run
700
- response.code.should == 307
701
- response.headers['Location'].should == uri.to_s
750
+ expect(response.code).to eq 307
751
+ expect(response.headers['Location']).to eq uri.to_s
702
752
  end
703
753
  it "should not reply with 307 when the resource has not moved temporarily" do
704
754
  resource.moved_temp = false
705
755
  subject.run
706
- response.code.should_not == 307
756
+ expect(response.code).to_not eq 307
707
757
  end
708
758
  end
709
759
 
710
760
  describe "#m5 (POST?), #n5 (POST to missing resource?)" do
711
761
  before { resource.moved_perm = resource.moved_temp = false }
712
762
  it "should reply with 410 when the method is not POST" do
713
- method.should_not == "POST"
763
+ expect(method).to_not eq "POST"
714
764
  subject.run
715
- response.code.should == 410
765
+ expect(response.code).to eq 410
716
766
  end
717
767
  it "should reply with 410 when the resource disallows missing POSTs" do
718
768
  @method = "POST"
719
769
  resource.allow_missing = false
720
770
  subject.run
721
- response.code.should == 410
771
+ expect(response.code).to eq 410
722
772
  end
723
773
  it "should not reply with 410 when the resource allows missing POSTs" do
724
774
  @method = "POST"
725
775
  resource.allow_missing = true
726
776
  subject.run
727
- response.code.should == 410
777
+ expect(response.code).to eq 410
728
778
  end
729
779
  end
730
780
  end
@@ -741,21 +791,21 @@ describe Webmachine::Decision::Flow do
741
791
  end
742
792
  let(:method){ @method || "GET" }
743
793
  it "should reply with 404 when the method is not POST" do
744
- method.should_not == "POST"
794
+ expect(method).to_not eq "POST"
745
795
  subject.run
746
- response.code.should == 404
796
+ expect(response.code).to eq 404
747
797
  end
748
798
  it "should reply with 404 when the resource disallows missing POSTs" do
749
799
  @method = "POST"
750
800
  resource.allow_missing = false
751
801
  subject.run
752
- response.code.should == 404
802
+ expect(response.code).to eq 404
753
803
  end
754
804
  it "should not reply with 404 when the resource allows missing POSTs" do
755
805
  @method = "POST"
756
806
  resource.allow_missing = true
757
807
  subject.run
758
- response.code.should_not == 404
808
+ expect(response.code).to_not eq 404
759
809
  end
760
810
  end
761
811
 
@@ -771,12 +821,12 @@ describe Webmachine::Decision::Flow do
771
821
  it "should reply with 409 if the resource is in conflict" do
772
822
  resource.conflict = true
773
823
  subject.run
774
- response.code.should == 409
824
+ expect(response.code).to eq 409
775
825
  end
776
826
  it "should not reply with 409 if the resource is in conflict" do
777
827
  resource.conflict = false
778
828
  subject.run
779
- response.code.should_not == 409
829
+ expect(response.code).to_not eq 409
780
830
  end
781
831
  end
782
832
 
@@ -801,14 +851,14 @@ describe Webmachine::Decision::Flow do
801
851
  it "should reply with 303 if the resource redirected" do
802
852
  resource.new_loc = URI.parse("/foo/bar")
803
853
  subject.run
804
- response.code.should == 303
805
- response.headers['Location'].should == "/foo/bar"
854
+ expect(response.code).to eq 303
855
+ expect(response.headers['Location']).to eq "/foo/bar"
806
856
  end
807
857
 
808
858
  it "should not reply with 303 if the resource did not redirect" do
809
859
  resource.new_loc = nil
810
860
  subject.run
811
- response.code.should_not == 303
861
+ expect(response.code).to_not eq 303
812
862
  end
813
863
  end
814
864
  end
@@ -845,13 +895,13 @@ describe Webmachine::Decision::Flow do
845
895
  resource.exist = e
846
896
  resource.new_loc = "http://ruby-doc.org/"
847
897
  subject.run
848
- response.code.should == 201
898
+ expect(response.code).to eq 201
849
899
  end
850
900
  it "should not reply with 201 when the Location header has been set" do
851
901
  resource.exist = e
852
902
  subject.run
853
- response.headers['Location'].should be_nil
854
- response.code.should_not == 201
903
+ expect(response.headers['Location']).to be_nil
904
+ expect(response.code).to_not eq 201
855
905
  end
856
906
  end
857
907
  end
@@ -866,19 +916,19 @@ describe Webmachine::Decision::Flow do
866
916
  resource.new_loc = created = "/foo/bar/baz"
867
917
  resource.create = true
868
918
  subject.run
869
- response.code.should == 201
870
- response.headers['Location'].should == created
919
+ expect(response.code).to eq 201
920
+ expect(response.headers['Location']).to eq created
871
921
  end
872
922
  it "should reply with 500 when post_is_create is true and create_path returns nil" do
873
923
  resource.create = true
874
924
  subject.run
875
- response.code.should == 500
876
- response.error.should_not be_nil
925
+ expect(response.code).to eq 500
926
+ expect(response.error).to_not be_nil
877
927
  end
878
928
  it "should not reply with 201 when post_is_create is false" do
879
929
  resource.create = false
880
930
  subject.run
881
- response.code.should_not == 201
931
+ expect(response.code).to_not eq 201
882
932
  end
883
933
  end
884
934
  end
@@ -897,12 +947,12 @@ describe Webmachine::Decision::Flow do
897
947
  it "should reply with 409 if the resource is in conflict" do
898
948
  resource.conflict = true
899
949
  subject.run
900
- response.code.should == 409
950
+ expect(response.code).to eq 409
901
951
  end
902
952
  it "should not reply with 409 if the resource is in conflict" do
903
953
  resource.conflict = false
904
954
  subject.run
905
- response.code.should_not == 409
955
+ expect(response.code).to_not eq 409
906
956
  end
907
957
  end
908
958
 
@@ -919,23 +969,23 @@ describe Webmachine::Decision::Flow do
919
969
  it "should not reply with 202 if the method is not DELETE" do
920
970
  @method = "GET"
921
971
  subject.run
922
- response.code.should_not == 202
972
+ expect(response.code).to_not eq 202
923
973
  end
924
974
  it "should reply with 500 if the DELETE fails" do
925
975
  resource.deleted = false
926
976
  subject.run
927
- response.code.should == 500
977
+ expect(response.code).to eq 500
928
978
  end
929
979
  it "should reply with 202 if the DELETE succeeds but is not complete" do
930
980
  resource.deleted = true
931
981
  resource.completed = false
932
982
  subject.run
933
- response.code.should == 202
983
+ expect(response.code).to eq 202
934
984
  end
935
985
  it "should not reply with 202 if the DELETE succeeds and completes" do
936
986
  resource.completed = resource.deleted = true
937
987
  subject.run
938
- response.code.should_not == 202
988
+ expect(response.code).to_not eq 202
939
989
  end
940
990
  end
941
991
 
@@ -980,13 +1030,13 @@ describe Webmachine::Decision::Flow do
980
1030
  resource.multiple = false
981
1031
  subject.run
982
1032
  puts response.error if response.code == 500
983
- response.code.should == 200
1033
+ expect(response.code).to eq 200
984
1034
  end
985
1035
  it "should reply with 300 if there are multiple representations" do
986
1036
  resource.multiple = true
987
1037
  subject.run
988
1038
  puts response.error if response.code == 500
989
- response.code.should == 300
1039
+ expect(response.code).to eq 300
990
1040
  end
991
1041
  end
992
1042
  end
@@ -1028,7 +1078,7 @@ describe Webmachine::Decision::Flow do
1028
1078
  @method = m
1029
1079
  resource.exist = e
1030
1080
  subject.run
1031
- response.code.should_not == 204
1081
+ expect(response.code).to_not eq 204
1032
1082
  end
1033
1083
  end
1034
1084
  end
@@ -1044,7 +1094,7 @@ describe Webmachine::Decision::Flow do
1044
1094
  @method = m
1045
1095
  resource.exist = e
1046
1096
  subject.run
1047
- response.code.should == 204
1097
+ expect(response.code).to eq 204
1048
1098
  end
1049
1099
  end
1050
1100
  end
@@ -1061,13 +1111,13 @@ describe Webmachine::Decision::Flow do
1061
1111
  end
1062
1112
 
1063
1113
  it "calls handle_exception" do
1064
- resource.should_receive(:handle_exception).with instance_of(RuntimeError)
1114
+ expect(resource).to receive(:handle_exception).with instance_of(RuntimeError)
1065
1115
  subject.run
1066
1116
  end
1067
1117
 
1068
1118
  it "sets the response code to 500" do
1069
1119
  subject.run
1070
- response.code.should == 500
1120
+ expect(response.code).to eq 500
1071
1121
  end
1072
1122
  end
1073
1123
 
@@ -1086,12 +1136,12 @@ describe Webmachine::Decision::Flow do
1086
1136
 
1087
1137
  it "can define a response body" do
1088
1138
  subject.run
1089
- response.body.should == "error"
1139
+ expect(response.body).to eq "error"
1090
1140
  end
1091
1141
 
1092
1142
  it "sets the response code to 500" do
1093
1143
  subject.run
1094
- response.code.should == 500
1144
+ expect(response.code).to eq 500
1095
1145
  end
1096
1146
  end
1097
1147
  end