strelka 0.6.0 → 0.7.0

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 (80) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/ChangeLog +156 -9
  4. data/History.rdoc +15 -0
  5. data/IDEAS.rdoc +17 -1
  6. data/MILESTONES.rdoc +1 -1
  7. data/Manifest.txt +10 -2
  8. data/Plugins.rdoc +4 -4
  9. data/README.rdoc +3 -3
  10. data/Rakefile +5 -4
  11. data/bin/strelka +19 -10
  12. data/contrib/hoetemplate/data/project/apps/file_name_app +1 -0
  13. data/contrib/hoetemplate/lib/file_name.rb.erb +3 -2
  14. data/examples/apps/hello-world +1 -0
  15. data/examples/apps/ws-chat +69 -0
  16. data/examples/apps/ws-echo +61 -0
  17. data/examples/gen-config.rb +6 -5
  18. data/lib/strelka/app/auth.rb +2 -2
  19. data/lib/strelka/app/errors.rb +1 -1
  20. data/lib/strelka/app/filters.rb +3 -2
  21. data/lib/strelka/app/negotiation.rb +2 -2
  22. data/lib/strelka/app/parameters.rb +1 -2
  23. data/lib/strelka/app/restresources.rb +3 -2
  24. data/lib/strelka/app/routing.rb +1 -1
  25. data/lib/strelka/app/sessions.rb +2 -2
  26. data/lib/strelka/app/templating.rb +7 -3
  27. data/lib/strelka/app.rb +5 -145
  28. data/lib/strelka/behavior/plugin.rb +4 -4
  29. data/lib/strelka/discovery.rb +211 -0
  30. data/lib/strelka/httprequest.rb +1 -0
  31. data/lib/strelka/httpresponse/negotiation.rb +7 -1
  32. data/lib/strelka/mixins.rb +4 -1
  33. data/lib/strelka/paramvalidator.rb +1 -1
  34. data/lib/strelka/plugins.rb +8 -6
  35. data/lib/strelka/websocketserver/routing.rb +116 -0
  36. data/lib/strelka/websocketserver.rb +147 -0
  37. data/lib/strelka.rb +5 -4
  38. data/spec/{lib/constants.rb → constants.rb} +3 -2
  39. data/spec/{lib/helpers.rb → helpers.rb} +15 -14
  40. data/spec/strelka/app/auth_spec.rb +145 -142
  41. data/spec/strelka/app/errors_spec.rb +20 -26
  42. data/spec/strelka/app/filters_spec.rb +67 -54
  43. data/spec/strelka/app/negotiation_spec.rb +8 -14
  44. data/spec/strelka/app/parameters_spec.rb +23 -29
  45. data/spec/strelka/app/restresources_spec.rb +98 -100
  46. data/spec/strelka/app/routing_spec.rb +57 -57
  47. data/spec/strelka/app/sessions_spec.rb +11 -17
  48. data/spec/strelka/app/templating_spec.rb +36 -40
  49. data/spec/strelka/app_spec.rb +48 -147
  50. data/spec/strelka/authprovider/basic_spec.rb +5 -11
  51. data/spec/strelka/authprovider/hostaccess_spec.rb +9 -15
  52. data/spec/strelka/authprovider_spec.rb +3 -9
  53. data/spec/strelka/cookie_spec.rb +32 -38
  54. data/spec/strelka/cookieset_spec.rb +31 -37
  55. data/spec/strelka/discovery_spec.rb +144 -0
  56. data/spec/strelka/exceptions_spec.rb +2 -8
  57. data/spec/strelka/httprequest/acceptparams_spec.rb +74 -83
  58. data/spec/strelka/httprequest/auth_spec.rb +5 -15
  59. data/spec/strelka/httprequest/negotiation_spec.rb +93 -103
  60. data/spec/strelka/httprequest/session_spec.rb +12 -22
  61. data/spec/strelka/httprequest_spec.rb +1 -7
  62. data/spec/strelka/httpresponse/negotiation_spec.rb +84 -76
  63. data/spec/strelka/httpresponse/session_spec.rb +25 -35
  64. data/spec/strelka/httpresponse_spec.rb +20 -26
  65. data/spec/strelka/mixins_spec.rb +66 -61
  66. data/spec/strelka/multipartparser_spec.rb +31 -37
  67. data/spec/strelka/paramvalidator_spec.rb +389 -373
  68. data/spec/strelka/plugins_spec.rb +17 -23
  69. data/spec/strelka/router/default_spec.rb +32 -38
  70. data/spec/strelka/router/exclusive_spec.rb +28 -34
  71. data/spec/strelka/router_spec.rb +2 -8
  72. data/spec/strelka/session/db_spec.rb +17 -15
  73. data/spec/strelka/session/default_spec.rb +22 -28
  74. data/spec/strelka/session_spec.rb +3 -9
  75. data/spec/strelka/websocketserver/routing_spec.rb +119 -0
  76. data/spec/strelka/websocketserver_spec.rb +149 -0
  77. data/spec/strelka_spec.rb +11 -13
  78. data.tar.gz.sig +3 -3
  79. metadata +22 -14
  80. metadata.gz.sig +0 -0
@@ -2,16 +2,10 @@
2
2
  # vim: set nosta noet ts=4 sw=4:
3
3
  # encoding: utf-8
4
4
 
5
- BEGIN {
6
- require 'pathname'
7
- basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
8
- $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
- }
5
+ require_relative '../../helpers'
10
6
 
11
7
  require 'rspec'
12
8
 
13
- require 'spec/lib/helpers'
14
-
15
9
  require 'strelka'
16
10
  require 'strelka/plugins'
17
11
  require 'strelka/app/restresources'
@@ -48,7 +42,7 @@ describe Strelka::App::RestResources do
48
42
  end
49
43
 
50
44
 
51
- it_should_behave_like( "A Strelka::App Plugin" )
45
+ it_should_behave_like( "A Strelka Plugin" )
52
46
 
53
47
 
54
48
  describe "included in an App" do
@@ -64,8 +58,8 @@ describe Strelka::App::RestResources do
64
58
 
65
59
 
66
60
  it "keeps track of what resources are mounted where" do
67
- @app.resource_verbs.should be_a( Hash )
68
- @app.resource_verbs.should be_empty()
61
+ expect( @app.resource_verbs ).to be_a( Hash )
62
+ expect( @app.resource_verbs ).to be_empty()
69
63
  end
70
64
 
71
65
 
@@ -80,8 +74,8 @@ describe Strelka::App::RestResources do
80
74
  end
81
75
 
82
76
  it "keeps track of what resources are mounted where" do
83
- @app.resource_verbs.should have( 1 ).member
84
- @app.resource_verbs.should include( 'servers' )
77
+ expect( @app.resource_verbs ).to have( 1 ).member
78
+ expect( @app.resource_verbs ).to include( 'servers' )
85
79
  @app.resource_verbs[ 'servers' ].
86
80
  should include( :OPTIONS, :GET, :HEAD, :POST, :PUT, :DELETE )
87
81
  end
@@ -117,8 +111,8 @@ describe Strelka::App::RestResources do
117
111
  end
118
112
 
119
113
  it "keeps track of what resources are mounted where" do
120
- @app.resource_verbs.should have( 1 ).member
121
- @app.resource_verbs.should include( 'servers' )
114
+ expect( @app.resource_verbs ).to have( 1 ).member
115
+ expect( @app.resource_verbs ).to include( 'servers' )
122
116
  @app.resource_verbs[ 'servers' ].
123
117
  should include( :OPTIONS, :GET, :HEAD )
124
118
  @app.resource_verbs[ 'servers' ].
@@ -182,8 +176,8 @@ describe Strelka::App::RestResources do
182
176
  req = @request_factory.options( '/api/v1/servers' )
183
177
  res = @app.new.handle( req )
184
178
 
185
- res.status.should == HTTP::OK
186
- res.headers.allowed.split( /\s*,\s*/ ).should include(*%w[GET HEAD POST PUT DELETE])
179
+ expect( res.status ).to eq( HTTP::OK )
180
+ expect( res.headers.allowed.split( /\s*,\s*/ ) ).to include(*%w[GET HEAD POST PUT DELETE])
187
181
  end
188
182
 
189
183
  end # OPTIONS routes
@@ -194,11 +188,11 @@ describe Strelka::App::RestResources do
194
188
  req = @request_factory.get( '/api/v1/servers', 'Accept' => 'application/json' )
195
189
  res = @app.new.handle( req )
196
190
 
197
- res.content_type.should == 'application/json'
191
+ expect( res.content_type ).to eq( 'application/json' )
198
192
  body = Yajl.load( res.body )
199
193
 
200
- body.should have( 2 ).members
201
- body.map {|record| record['uuid'] }.should include( 'test-server', 'step-server' )
194
+ expect( body ).to have( 2 ).members
195
+ expect( body.map {|record| record['uuid'] } ).to include( 'test-server', 'step-server' )
202
196
  end
203
197
 
204
198
  it "supports limiting the result set when fetching the resource collection" do
@@ -206,12 +200,12 @@ describe Strelka::App::RestResources do
206
200
  'Accept' => 'application/json' )
207
201
  res = @app.new.handle( req )
208
202
 
209
- res.status.should == HTTP::OK
210
- res.content_type.should == 'application/json'
203
+ expect( res.status ).to eq( HTTP::OK )
204
+ expect( res.content_type ).to eq( 'application/json' )
211
205
  body = Yajl.load( res.body )
212
206
 
213
- body.should have( 1 ).member
214
- body[0]['uuid'].should == 'test-server'
207
+ expect( body ).to have( 1 ).member
208
+ expect( body[0]['uuid'] ).to eq( 'test-server' )
215
209
  end
216
210
 
217
211
  it "supports paging the result set when fetching the resource collection" do
@@ -219,12 +213,12 @@ describe Strelka::App::RestResources do
219
213
  'Accept' => 'application/json' )
220
214
  res = @app.new.handle( req )
221
215
 
222
- res.status.should == HTTP::OK
223
- res.content_type.should == 'application/json'
216
+ expect( res.status ).to eq( HTTP::OK )
217
+ expect( res.content_type ).to eq( 'application/json' )
224
218
  body = Yajl.load( res.body )
225
219
 
226
- body.should have( 1 ).member
227
- body[0]['uuid'].should == 'step-server'
220
+ expect( body ).to have( 1 ).member
221
+ expect( body[0]['uuid'] ).to eq( 'step-server' )
228
222
  end
229
223
 
230
224
  it "supports ordering the result by a single column" do
@@ -232,12 +226,12 @@ describe Strelka::App::RestResources do
232
226
  'Accept' => 'application/json' )
233
227
  res = @app.new.handle( req )
234
228
 
235
- res.status.should == HTTP::OK
236
- res.content_type.should == 'application/json'
229
+ expect( res.status ).to eq( HTTP::OK )
230
+ expect( res.content_type ).to eq( 'application/json' )
237
231
  body = Yajl.load( res.body )
238
232
 
239
- body.should have( 2 ).members
240
- body[0]['name'].should == 'Step'
233
+ expect( body ).to have( 2 ).members
234
+ expect( body[0]['name'] ).to eq( 'Step' )
241
235
  end
242
236
 
243
237
  it "supports ordering the result by multiple columns" do
@@ -245,41 +239,41 @@ describe Strelka::App::RestResources do
245
239
  'Accept' => 'application/json' )
246
240
  res = @app.new.handle( req )
247
241
 
248
- res.status.should == HTTP::OK
249
- res.content_type.should == 'application/json'
242
+ expect( res.status ).to eq( HTTP::OK )
243
+ expect( res.content_type ).to eq( 'application/json' )
250
244
  body = Yajl.load( res.body )
251
245
 
252
- body.should have( 2 ).members
253
- body[0]['name'].should == 'Test'
246
+ expect( body ).to have( 2 ).members
247
+ expect( body[0]['name'] ).to eq( 'Test' )
254
248
  end
255
249
 
256
250
  it "has a GET route to fetch a single resource by its ID" do
257
251
  req = @request_factory.get( '/api/v1/servers/1', 'Accept' => 'application/json' )
258
252
  res = @app.new.handle( req )
259
253
 
260
- res.content_type.should == 'application/json'
254
+ expect( res.content_type ).to eq( 'application/json' )
261
255
  body = Yajl.load( res.body )
262
256
 
263
- body.should be_a( Hash )
264
- body['uuid'].should == 'test-server'
257
+ expect( body ).to be_a( Hash )
258
+ expect( body['uuid'] ).to eq( 'test-server' )
265
259
  end
266
260
 
267
261
  it "returns a NOT FOUND response when fetching a non-existant resource" do
268
262
  req = @request_factory.get( '/api/v1/servers/411', 'Accept' => 'application/json' )
269
263
  res = @app.new.handle( req )
270
264
 
271
- res.status.should == HTTP::NOT_FOUND
265
+ expect( res.status ).to eq( HTTP::NOT_FOUND )
272
266
  res.body.rewind
273
- res.body.read.should =~ /no such server/i
267
+ expect( res.body.read ).to match( /no such server/i )
274
268
  end
275
269
 
276
270
  it "returns a NOT FOUND response when fetching a resource with an invalid ID" do
277
271
  req = @request_factory.get( '/api/v1/servers/ape-tastic' )
278
272
  res = @app.new.handle( req )
279
273
 
280
- res.status.should == HTTP::NOT_FOUND
274
+ expect( res.status ).to eq( HTTP::NOT_FOUND )
281
275
  res.body.rewind
282
- res.body.read.should =~ /requested resource was not found/i
276
+ expect( res.body.read ).to match( /requested resource was not found/i )
283
277
  end
284
278
 
285
279
  it "has a GET route for fetching the resource via one of its dataset methods" do
@@ -287,13 +281,13 @@ describe Strelka::App::RestResources do
287
281
  :accept => 'application/json' )
288
282
  res = @app.new.handle( req )
289
283
 
290
- res.status.should == HTTP::OK
284
+ expect( res.status ).to eq( HTTP::OK )
291
285
  body = Yajl.load( res.body )
292
286
 
293
- body.should be_an( Array )
294
- body.should have( 1 ).member
295
- body.first.should be_a( Hash )
296
- body.first['uuid'].should == 'test-server'
287
+ expect( body ).to be_an( Array )
288
+ expect( body ).to have( 1 ).member
289
+ expect( body.first ).to be_a( Hash )
290
+ expect( body.first['uuid'] ).to eq( 'test-server' )
297
291
  end
298
292
 
299
293
  it "has a GET route for fetching the resource via a subset" do
@@ -301,13 +295,13 @@ describe Strelka::App::RestResources do
301
295
  :accept => 'application/json' )
302
296
  res = @app.new.handle( req )
303
297
 
304
- res.status.should == HTTP::OK
298
+ expect( res.status ).to eq( HTTP::OK )
305
299
  body = Yajl.load( res.body )
306
300
 
307
- body.should be_an( Array )
308
- body.should have( 1 ).member
309
- body.first.should be_a( Hash )
310
- body.first['port'].should > 1024
301
+ expect( body ).to be_an( Array )
302
+ expect( body ).to have( 1 ).member
303
+ expect( body.first ).to be_a( Hash )
304
+ expect( body.first['port'] ).to be > 1024
311
305
  end
312
306
 
313
307
  it "has a GET route for methods declared in a named dataset module" do
@@ -315,13 +309,13 @@ describe Strelka::App::RestResources do
315
309
  :accept => 'application/json' )
316
310
  res = @app.new.handle( req )
317
311
 
318
- res.status.should == HTTP::OK
312
+ expect( res.status ).to eq( HTTP::OK )
319
313
  body = Yajl.load( res.body )
320
314
 
321
- body.should be_an( Array )
322
- body.should have( 1 ).member
323
- body.first.should be_a( Hash )
324
- body.first['name'].should == 'Step'
315
+ expect( body ).to be_an( Array )
316
+ expect( body ).to have( 1 ).member
317
+ expect( body.first ).to be_a( Hash )
318
+ expect( body.first['name'] ).to eq( 'Step' )
325
319
  end
326
320
 
327
321
 
@@ -329,28 +323,28 @@ describe Strelka::App::RestResources do
329
323
  req = @request_factory.get( '/api/v1/servers/1/hosts' )
330
324
  res = @app.new.handle( req )
331
325
 
332
- res.status.should == HTTP::OK
326
+ expect( res.status ).to eq( HTTP::OK )
333
327
  body = Yajl.load( res.body )
334
328
 
335
- body.should be_an( Array )
336
- body.should have( 4 ).members
337
- body.first.should be_a( Hash )
338
- body.first['server_id'].should == 1
339
- body.first['id'].should == 1
329
+ expect( body ).to be_an( Array )
330
+ expect( body ).to have( 4 ).members
331
+ expect( body.first ).to be_a( Hash )
332
+ expect( body.first['server_id'] ).to eq( 1 )
333
+ expect( body.first['id'] ).to eq( 1 )
340
334
  end
341
335
 
342
336
  it "supports offset and limits for composite GET routes" do
343
337
  req = @request_factory.get( '/api/v1/servers/1/hosts?offset=2;limit=2' )
344
338
  res = @app.new.handle( req )
345
339
 
346
- res.status.should == HTTP::OK
340
+ expect( res.status ).to eq( HTTP::OK )
347
341
  body = Yajl.load( res.body )
348
342
 
349
- body.should be_an( Array )
350
- body.should have( 2 ).members
351
- body.first.should be_a( Hash )
352
- body.first['server_id'].should == 1
353
- body.first['id'].should == 3
343
+ expect( body ).to be_an( Array )
344
+ expect( body ).to have( 2 ).members
345
+ expect( body.first ).to be_a( Hash )
346
+ expect( body.first['server_id'] ).to eq( 1 )
347
+ expect( body.first['id'] ).to eq( 3 )
354
348
  end
355
349
 
356
350
  end # GET routes
@@ -384,23 +378,25 @@ describe Strelka::App::RestResources do
384
378
 
385
379
  res = @app.new.handle( req )
386
380
 
387
- res.status.should == HTTP::CREATED
388
- res.headers.location.should == 'http://localhost:8080/api/v1/servers/3'
381
+ expect( res.status ).to eq( HTTP::CREATED )
382
+ expect( res.headers.location ).to eq( 'http://localhost:8080/api/v1/servers/3' )
389
383
 
390
384
  new_server = Mongrel2::Config::Server[ 3 ]
391
385
 
392
- new_server.uuid.should == "test-server"
393
- new_server.access_log.should == "/logs/admin-access.log"
394
- new_server.error_log.should == "/logs/admin-error.log"
395
- new_server.chroot.should == "/var/www"
396
- new_server.pid_file.should == "/var/run/test.pid"
397
- new_server.default_host.should == "localhost"
398
- new_server.name.should == "Testing Server"
399
- new_server.bind_addr.should == "127.0.0.1"
400
- new_server.port.should == 7337
401
- new_server.use_ssl.should == 0
386
+ expect( new_server.uuid ).to eq( "test-server" )
387
+ expect( new_server.access_log ).to eq( "/logs/admin-access.log" )
388
+ expect( new_server.error_log ).to eq( "/logs/admin-error.log" )
389
+ expect( new_server.chroot ).to eq( "/var/www" )
390
+ expect( new_server.pid_file ).to eq( "/var/run/test.pid" )
391
+ expect( new_server.default_host ).to eq( "localhost" )
392
+ expect( new_server.name ).to eq( "Testing Server" )
393
+ expect( new_server.bind_addr ).to eq( "127.0.0.1" )
394
+ expect( new_server.port ).to eq( 7337 )
395
+ expect( new_server.use_ssl ).to eq( 0 )
402
396
  end
403
397
 
398
+ it "has a POST route to update instances"
399
+
404
400
  end # POST routes
405
401
 
406
402
 
@@ -413,7 +409,7 @@ describe Strelka::App::RestResources do
413
409
  }
414
410
  end
415
411
 
416
- it "has a PUT route to update instances in the resource collection" do
412
+ it "has a PUT route to replace instances in the resource collection" do
417
413
  req = @request_factory.put( '/api/v1/servers/1' )
418
414
  req.content_type = 'application/json'
419
415
  req.headers.accept = 'application/json'
@@ -421,22 +417,24 @@ describe Strelka::App::RestResources do
421
417
 
422
418
  res = @app.new.handle( req )
423
419
 
424
- res.status.should == HTTP::NO_CONTENT
420
+ expect( res.status ).to eq( HTTP::NO_CONTENT )
425
421
 
426
- Mongrel2::Config::Server[ 1 ].name.should == 'Not A Testing Server'
427
- Mongrel2::Config::Server[ 1 ].bind_addr.should == '0.0.0.0'
422
+ expect( Mongrel2::Config::Server[ 1 ].name ).to eq( 'Not A Testing Server' )
423
+ expect( Mongrel2::Config::Server[ 1 ].bind_addr ).to eq( '0.0.0.0' )
428
424
  end
429
425
 
430
- it "has a PUT route to mass-update all resources in a collection" do
431
- req = @request_factory.put( '/api/v1/servers' )
432
- req.content_type = 'application/json'
433
- req.body = Yajl.dump({ 'bind_addr' => '0.0.0.0' })
426
+ it "has a PUT route to replace all resources in a collection" do
427
+ pending "fix the semantics of PUT and POST" do
428
+ req = @request_factory.put( '/api/v1/servers' )
429
+ req.content_type = 'application/json'
430
+ req.body = Yajl.dump({ 'bind_addr' => '0.0.0.0' })
434
431
 
435
- res = @app.new.handle( req )
432
+ res = @app.new.handle( req )
436
433
 
437
- res.status.should == HTTP::NO_CONTENT
434
+ expect( res.status ).to eq( HTTP::NO_CONTENT )
438
435
 
439
- Mongrel2::Config::Server.map( :bind_addr ).uniq.should == ['0.0.0.0']
436
+ expect( Mongrel2::Config::Server.map( :bind_addr ) ).to eq( ['0.0.0.0'] )
437
+ end
440
438
  end
441
439
 
442
440
  end # PUT routes
@@ -449,9 +447,9 @@ describe Strelka::App::RestResources do
449
447
 
450
448
  res = @app.new.handle( req )
451
449
 
452
- res.status.should == HTTP::NO_CONTENT
450
+ expect( res.status ).to eq( HTTP::NO_CONTENT )
453
451
 
454
- Mongrel2::Config::Server.count.should == 1
452
+ expect( Mongrel2::Config::Server.count ).to eq( 1 )
455
453
  end
456
454
 
457
455
  it "has a DELETE route to mass-delete all resources in a collection" do
@@ -459,9 +457,9 @@ describe Strelka::App::RestResources do
459
457
 
460
458
  res = @app.new.handle( req )
461
459
 
462
- res.status.should == HTTP::NO_CONTENT
460
+ expect( res.status ).to eq( HTTP::NO_CONTENT )
463
461
 
464
- Mongrel2::Config::Server.count.should == 0
462
+ expect( Mongrel2::Config::Server.count ).to eq( 0 )
465
463
  end
466
464
 
467
465
  end # DELETE routes
@@ -478,13 +476,13 @@ describe Strelka::App::RestResources do
478
476
 
479
477
 
480
478
  it "has its config inherited by subclass" do
481
- subject.service_options.should == @app.service_options
482
- subject.service_options.should_not be( @app.service_options )
479
+ expect( subject.service_options ).to eq( @app.service_options )
480
+ expect( subject.service_options ).to_not be( @app.service_options )
483
481
  end
484
482
 
485
483
  it "has its metadata inherited by subclasses" do
486
- subject.resource_verbs.should have( 1 ).member
487
- subject.resource_verbs.should include( 'servers' )
484
+ expect( subject.resource_verbs ).to have( 1 ).member
485
+ expect( subject.resource_verbs ).to include( 'servers' )
488
486
  subject.resource_verbs[ 'servers' ].
489
487
  should include( :OPTIONS, :GET, :HEAD, :POST, :PUT, :DELETE )
490
488
  end