strelka 0.0.1pre4 → 0.0.1.pre129

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/History.rdoc +1 -1
  2. data/IDEAS.rdoc +62 -0
  3. data/Manifest.txt +38 -7
  4. data/README.rdoc +124 -5
  5. data/Rakefile +22 -6
  6. data/bin/leash +102 -157
  7. data/contrib/hoetemplate/.autotest.erb +23 -0
  8. data/contrib/hoetemplate/History.rdoc.erb +4 -0
  9. data/contrib/hoetemplate/Manifest.txt.erb +8 -0
  10. data/contrib/hoetemplate/README.rdoc.erb +17 -0
  11. data/contrib/hoetemplate/Rakefile.erb +24 -0
  12. data/contrib/hoetemplate/data/file_name/apps/file_name_app +36 -0
  13. data/contrib/hoetemplate/data/file_name/templates/layout.tmpl.erb +13 -0
  14. data/contrib/hoetemplate/data/file_name/templates/top.tmpl.erb +8 -0
  15. data/contrib/hoetemplate/lib/file_name.rb.erb +18 -0
  16. data/contrib/hoetemplate/spec/file_name_spec.rb.erb +21 -0
  17. data/data/strelka/apps/hello-world +30 -0
  18. data/lib/strelka/app/defaultrouter.rb +49 -30
  19. data/lib/strelka/app/errors.rb +121 -0
  20. data/lib/strelka/app/exclusiverouter.rb +40 -0
  21. data/lib/strelka/app/filters.rb +18 -7
  22. data/lib/strelka/app/negotiation.rb +122 -0
  23. data/lib/strelka/app/parameters.rb +171 -14
  24. data/lib/strelka/app/paramvalidator.rb +751 -0
  25. data/lib/strelka/app/plugins.rb +66 -46
  26. data/lib/strelka/app/restresources.rb +499 -0
  27. data/lib/strelka/app/router.rb +73 -0
  28. data/lib/strelka/app/routing.rb +140 -18
  29. data/lib/strelka/app/templating.rb +12 -3
  30. data/lib/strelka/app.rb +174 -24
  31. data/lib/strelka/constants.rb +0 -20
  32. data/lib/strelka/exceptions.rb +29 -0
  33. data/lib/strelka/httprequest/acceptparams.rb +377 -0
  34. data/lib/strelka/httprequest/negotiation.rb +257 -0
  35. data/lib/strelka/httprequest.rb +155 -7
  36. data/lib/strelka/httpresponse/negotiation.rb +579 -0
  37. data/lib/strelka/httpresponse.rb +140 -0
  38. data/lib/strelka/logging.rb +4 -1
  39. data/lib/strelka/mixins.rb +53 -0
  40. data/lib/strelka.rb +22 -1
  41. data/spec/data/error.tmpl +1 -0
  42. data/spec/lib/constants.rb +0 -1
  43. data/spec/lib/helpers.rb +21 -0
  44. data/spec/strelka/app/defaultrouter_spec.rb +41 -35
  45. data/spec/strelka/app/errors_spec.rb +212 -0
  46. data/spec/strelka/app/exclusiverouter_spec.rb +220 -0
  47. data/spec/strelka/app/filters_spec.rb +196 -0
  48. data/spec/strelka/app/negotiation_spec.rb +73 -0
  49. data/spec/strelka/app/parameters_spec.rb +149 -0
  50. data/spec/strelka/app/paramvalidator_spec.rb +1059 -0
  51. data/spec/strelka/app/plugins_spec.rb +26 -19
  52. data/spec/strelka/app/restresources_spec.rb +393 -0
  53. data/spec/strelka/app/router_spec.rb +63 -0
  54. data/spec/strelka/app/routing_spec.rb +183 -9
  55. data/spec/strelka/app/templating_spec.rb +1 -2
  56. data/spec/strelka/app_spec.rb +265 -32
  57. data/spec/strelka/exceptions_spec.rb +53 -0
  58. data/spec/strelka/httprequest/acceptparams_spec.rb +282 -0
  59. data/spec/strelka/httprequest/negotiation_spec.rb +246 -0
  60. data/spec/strelka/httprequest_spec.rb +204 -14
  61. data/spec/strelka/httpresponse/negotiation_spec.rb +464 -0
  62. data/spec/strelka/httpresponse_spec.rb +114 -0
  63. data/spec/strelka/mixins_spec.rb +99 -0
  64. data.tar.gz.sig +1 -0
  65. metadata +175 -79
  66. metadata.gz.sig +2 -0
  67. data/IDEAS.textile +0 -174
  68. data/data/strelka/apps/strelka-admin +0 -65
  69. data/data/strelka/apps/strelka-setup +0 -26
  70. data/data/strelka/bootstrap-config.rb +0 -34
  71. data/data/strelka/templates/admin/console.tmpl +0 -21
  72. data/data/strelka/templates/layout.tmpl +0 -30
  73. data/lib/strelka/process.rb +0 -19
@@ -40,7 +40,10 @@ module Strelka::Logging
40
40
  end
41
41
 
42
42
  mod.default_logger = mod.logger = Logger.new( $stderr )
43
- mod.default_logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
43
+ mod.default_logger.level = case
44
+ when $DEBUG then Logger::DEBUG
45
+ when $VERBOSE then Logger::INFO
46
+ else Logger::WARN end
44
47
  mod.default_log_formatter = Strelka::Logging::Formatter.new( mod.default_logger )
45
48
  end
46
49
 
@@ -137,6 +137,59 @@ module Strelka
137
137
 
138
138
  end # module ANSIColorUtilities
139
139
 
140
+
141
+ # Hides your class's ::new method and adds a +pure_virtual+ method generator for
142
+ # defining API methods. If subclasses of your class don't provide implementations of
143
+ # "pure_virtual" methods, NotImplementedErrors will be raised if they are called.
144
+ #
145
+ # # AbstractClass
146
+ # class MyBaseClass
147
+ # include Strelka::AbstractClass
148
+ #
149
+ # # Define a method that will raise a NotImplementedError if called
150
+ # pure_virtual :api_method
151
+ # end
152
+ #
153
+ module AbstractClass
154
+
155
+ ### Methods to be added to including classes
156
+ module ClassMethods
157
+
158
+ ### Define one or more "virtual" methods which will raise
159
+ ### NotImplementedErrors when called via a concrete subclass.
160
+ def pure_virtual( *syms )
161
+ syms.each do |sym|
162
+ define_method( sym ) do |*args|
163
+ raise ::NotImplementedError,
164
+ "%p does not provide an implementation of #%s" % [ self.class, sym ],
165
+ caller(1)
166
+ end
167
+ end
168
+ end
169
+
170
+
171
+ ### Turn subclasses' new methods back to public.
172
+ def inherited( subclass )
173
+ subclass.module_eval { public_class_method :new }
174
+ super
175
+ end
176
+
177
+ end # module ClassMethods
178
+
179
+
180
+ ### Inclusion callback
181
+ def self::included( mod )
182
+ super
183
+ if mod.respond_to?( :new )
184
+ mod.extend( ClassMethods )
185
+ mod.module_eval { private_class_method :new }
186
+ end
187
+ end
188
+
189
+
190
+ end # module AbstractClass
191
+
192
+
140
193
  end # module Strelka
141
194
 
142
195
  # vim: set nosta noet ts=4 sw=4:
data/lib/strelka.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'mongrel2'
4
4
  require 'configurability'
5
+ require 'configurability/config'
5
6
 
6
7
  # An application framework for Ruby-mongrel2
7
8
  #
@@ -15,15 +16,21 @@ module Strelka
15
16
  VERSION = '0.0.1'
16
17
 
17
18
  # Version-control revision constant
18
- REVISION = %q$Revision: 1e34f33f76af $
19
+ REVISION = %q$Revision: dd54849bf817 $
19
20
 
20
21
 
21
22
  require 'strelka/logging'
22
23
  extend Strelka::Logging
23
24
 
25
+ # Combine Strelka, Mongrel2, and Configurability logging
26
+ Mongrel2.logger = Strelka.logger
27
+ Configurability.logger = Strelka.logger
28
+
24
29
  require 'strelka/constants'
25
30
  include Strelka::Constants
26
31
 
32
+ require 'strelka/exceptions'
33
+
27
34
 
28
35
  ### Get the library version. If +include_buildnum+ is true, the version string will
29
36
  ### include the VCS rev ID.
@@ -36,5 +43,19 @@ module Strelka
36
43
  require 'strelka/app'
37
44
  require 'strelka/httprequest'
38
45
 
46
+
47
+ # The installed Configurability::Config object
48
+ @config = nil
49
+ class << self; attr_accessor :config; end
50
+
51
+
52
+ ### Convenience method -- Load the Configurability::Config from +configfile+
53
+ ### and install it.
54
+ def self::load_config( configfile, defaults={} )
55
+ Strelka.log.info "Loading universal config from %p" % [ configfile ]
56
+ self.config = Configurability::Config.load( configfile, defaults )
57
+ self.config.install
58
+ end
59
+
39
60
  end # module Strelka
40
61
 
@@ -0,0 +1 @@
1
+ This is an error-handler template. The request is: <?pp request ?>.
@@ -20,7 +20,6 @@ module Strelka::TestConstants # :nodoc:all
20
20
  TEST_RECV_SPEC = 'tcp://127.0.0.1:9997'
21
21
 
22
22
 
23
-
24
23
  # Freeze all testing constants
25
24
  constants.each do |cname|
26
25
  const_get(cname).freeze
data/spec/lib/helpers.rb CHANGED
@@ -112,6 +112,27 @@ module Strelka::SpecHelpers
112
112
  end
113
113
  end
114
114
 
115
+ ### Set up a Mongrel2 configuration database according to the specified +dbspec+.
116
+ def setup_config_db( dbspec=':memory:' )
117
+ Mongrel2::Config.configure( :configdb => dbspec ) unless
118
+ Mongrel2::Config.db.uri[ %r{sqlite:/(.*)}, 1 ] == dbspec
119
+ Mongrel2::Config.init_database
120
+ Mongrel2::Config.db.tables.collect {|t| Mongrel2::Config.db[t] }.each( &:truncate )
121
+ end
122
+
123
+
124
+ # Helper method
125
+ def route( name )
126
+ return {:action => name.to_sym}
127
+ end
128
+
129
+ # Route matcher
130
+ RSpec::Matchers.define( :match_route ) do |routename|
131
+ match do |route|
132
+ route[:action] == routename
133
+ end
134
+ end
135
+
115
136
  end
116
137
 
117
138
 
@@ -26,33 +26,34 @@ describe Strelka::App::DefaultRouter do
26
26
  end
27
27
 
28
28
  before( :each ) do
29
- @router = Strelka::App::DefaultRouter.new
29
+ @router = Strelka::App::Router.create( 'default' )
30
30
  end
31
31
 
32
32
  after( :all ) do
33
33
  reset_logging()
34
34
  end
35
35
 
36
+
36
37
  context "a router with routes for 'foo', 'foo/bar'" do
37
38
 
38
39
  before( :each ) do
39
- @router.add_route( :GET, ['foo'], :the_foo_action )
40
- @router.add_route( :GET, ['foo','bar'], :the_foo_bar_action )
40
+ @router.add_route( :GET, ['foo'], route(:foo) )
41
+ @router.add_route( :GET, ['foo','bar'], route(:foo_bar) )
41
42
  end
42
43
 
43
44
  it "routes /user/foo/bar/baz to the foo/bar action" do
44
45
  req = @request_factory.get( '/user/foo/bar/baz' )
45
- @router.route_request( req ).should == :the_foo_bar_action
46
+ @router.route_request( req ).should match_route( :foo_bar )
46
47
  end
47
48
 
48
49
  it "routes /user/foo/bar to the foo/bar action" do
49
50
  req = @request_factory.get( '/user/foo/bar' )
50
- @router.route_request( req ).should == :the_foo_bar_action
51
+ @router.route_request( req ).should match_route( :foo_bar )
51
52
  end
52
53
 
53
54
  it "routes /user/foo to the foo action" do
54
55
  req = @request_factory.get( '/user/foo' )
55
- @router.route_request( req ).should == :the_foo_action
56
+ @router.route_request( req ).should match_route( :foo )
56
57
  end
57
58
 
58
59
  it "doesn't route /user" do
@@ -60,6 +61,11 @@ describe Strelka::App::DefaultRouter do
60
61
  @router.route_request( req ).should be_nil()
61
62
  end
62
63
 
64
+ it "doesn't route /user/something/foo/bar" do
65
+ req = @request_factory.get( '/user/something/foo/bar' )
66
+ @router.route_request( req ).should be_nil()
67
+ end
68
+
63
69
  it "doesn't route /user/other" do
64
70
  req = @request_factory.get( '/user/other' )
65
71
  @router.route_request( req ).should be_nil()
@@ -70,34 +76,34 @@ describe Strelka::App::DefaultRouter do
70
76
  context "a router with routes for 'foo', 'foo/bar', and a fallback action" do
71
77
 
72
78
  before( :each ) do
73
- @router.add_route( :GET, [], :the_fallback_action )
74
- @router.add_route( :GET, ['foo'], :the_foo_action )
75
- @router.add_route( :GET, ['foo','bar'], :the_foo_bar_action )
79
+ @router.add_route( :GET, [], route(:fallback) )
80
+ @router.add_route( :GET, ['foo'], route(:foo) )
81
+ @router.add_route( :GET, ['foo','bar'], route(:foo_bar) )
76
82
  end
77
83
 
78
84
  it "routes /user/foo/bar/baz to the foo/bar action" do
79
85
  req = @request_factory.get( '/user/foo/bar/baz' )
80
- @router.route_request( req ).should == :the_foo_bar_action
86
+ @router.route_request( req ).should match_route( :foo_bar )
81
87
  end
82
88
 
83
89
  it "routes /user/foo/bar to the foo/bar action" do
84
90
  req = @request_factory.get( '/user/foo/bar' )
85
- @router.route_request( req ).should == :the_foo_bar_action
91
+ @router.route_request( req ).should match_route( :foo_bar )
86
92
  end
87
93
 
88
94
  it "routes /user/foo to the foo action" do
89
95
  req = @request_factory.get( '/user/foo' )
90
- @router.route_request( req ).should == :the_foo_action
96
+ @router.route_request( req ).should match_route( :foo )
91
97
  end
92
98
 
93
99
  it "routes /user to the fallback action" do
94
100
  req = @request_factory.get( '/user' )
95
- @router.route_request( req ).should == :the_fallback_action
101
+ @router.route_request( req ).should match_route( :fallback )
96
102
  end
97
103
 
98
104
  it "routes /user/other to the fallback action" do
99
105
  req = @request_factory.get( '/user/other' )
100
- @router.route_request( req ).should == :the_fallback_action
106
+ @router.route_request( req ).should match_route( :fallback )
101
107
  end
102
108
 
103
109
  end
@@ -105,34 +111,34 @@ describe Strelka::App::DefaultRouter do
105
111
  context "a router with routes for 'foo', 'foo/\w{3}', and 'foo/\w{6}'" do
106
112
 
107
113
  before( :each ) do
108
- @router.add_route( :GET, ['foo'], :the_foo_action )
109
- @router.add_route( :GET, ['foo',/\w{3}/], :the_foo_threeaction )
110
- @router.add_route( :GET, ['foo',/\w{6}/], :the_foo_sixaction )
114
+ @router.add_route( :GET, ['foo'], route(:foo) )
115
+ @router.add_route( :GET, ['foo',/\w{3}/], route(:foo_three) )
116
+ @router.add_route( :GET, ['foo',/\w{6}/], route(:foo_six) )
111
117
  end
112
118
 
113
119
  it "routes /user/foo/barbim/baz to the foo/\w{6} action" do
114
120
  req = @request_factory.get( '/user/foo/barbim/baz' )
115
- @router.route_request( req ).should == :the_foo_sixaction
121
+ @router.route_request( req ).should match_route( :foo_six )
116
122
  end
117
123
 
118
124
  it "routes /user/foo/barbat to the foo/\w{6} action" do
119
125
  req = @request_factory.get( '/user/foo/barbat' )
120
- @router.route_request( req ).should == :the_foo_sixaction
126
+ @router.route_request( req ).should match_route( :foo_six )
121
127
  end
122
128
 
123
129
  it "routes /user/foo/bar/baz to the foo/\w{3} action" do
124
130
  req = @request_factory.get( '/user/foo/bar/baz' )
125
- @router.route_request( req ).should == :the_foo_threeaction
131
+ @router.route_request( req ).should match_route( :foo_three )
126
132
  end
127
133
 
128
134
  it "routes /user/foo/bar to the foo/\w{3} action" do
129
135
  req = @request_factory.get( '/user/foo/bar' )
130
- @router.route_request( req ).should == :the_foo_threeaction
136
+ @router.route_request( req ).should match_route( :foo_three )
131
137
  end
132
138
 
133
139
  it "routes /user/foo to the foo action" do
134
140
  req = @request_factory.get( '/user/foo' )
135
- @router.route_request( req ).should == :the_foo_action
141
+ @router.route_request( req ).should match_route( :foo )
136
142
  end
137
143
 
138
144
  it "doesn't route /user" do
@@ -148,33 +154,33 @@ describe Strelka::App::DefaultRouter do
148
154
  end
149
155
 
150
156
  # get '/foo/\w{3}'
151
- # get '/foo/\d+'
157
+ # get '/foo/\d+'
152
158
 
153
159
  context "a router with routes for: 'foo/\w{3}', then 'foo/\d+'" do
154
160
 
155
161
  before( :each ) do
156
- @router.add_route( :GET, ['foo',/\w{3}/], :the_foo_threeaction )
157
- @router.add_route( :GET, ['foo',/\d+/], :the_foo_digitaction )
162
+ @router.add_route( :GET, ['foo',/\w{3}/], route(:foo_three) )
163
+ @router.add_route( :GET, ['foo',/\d+/], route(:foo_digit) )
158
164
  end
159
165
 
160
166
  it "routes /user/foo/1 to the foo/\d+ action" do
161
167
  req = @request_factory.get( '/user/foo/1' )
162
- @router.route_request( req ).should == :the_foo_digitaction
168
+ @router.route_request( req ).should match_route( :foo_digit )
163
169
  end
164
170
 
165
171
  it "routes /user/foo/12 to the foo/\d+ action" do
166
172
  req = @request_factory.get( '/user/foo/12' )
167
- @router.route_request( req ).should == :the_foo_digitaction
173
+ @router.route_request( req ).should match_route( :foo_digit )
168
174
  end
169
175
 
170
176
  it "routes /user/foo/123 to the foo/\w{3} action" do
171
177
  req = @request_factory.get( '/user/foo/123' )
172
- @router.route_request( req ).should == :the_foo_threeaction
178
+ @router.route_request( req ).should match_route( :foo_three )
173
179
  end
174
180
 
175
181
  it "routes /user/foo/1234 to the foo/\d+ action" do
176
182
  req = @request_factory.get( '/user/foo/1234' )
177
- @router.route_request( req ).should == :the_foo_digitaction
183
+ @router.route_request( req ).should match_route( :foo_digit )
178
184
  end
179
185
 
180
186
  end
@@ -185,28 +191,28 @@ describe Strelka::App::DefaultRouter do
185
191
  context "a router with routes for: 'foo/\d+', then 'foo/\w{3}'" do
186
192
 
187
193
  before( :each ) do
188
- @router.add_route( :GET, ['foo',/\d+/], :the_foo_digitaction )
189
- @router.add_route( :GET, ['foo',/\w{3}/], :the_foo_threeaction )
194
+ @router.add_route( :GET, ['foo',/\d+/], route(:foo_digit) )
195
+ @router.add_route( :GET, ['foo',/\w{3}/], route(:foo_three) )
190
196
  end
191
197
 
192
198
  it "routes /user/foo/1 to the foo/\d+ action" do
193
199
  req = @request_factory.get( '/user/foo/1' )
194
- @router.route_request( req ).should == :the_foo_digitaction
200
+ @router.route_request( req ).should match_route( :foo_digit )
195
201
  end
196
202
 
197
203
  it "routes /user/foo/12 to the foo/\d+ action" do
198
204
  req = @request_factory.get( '/user/foo/12' )
199
- @router.route_request( req ).should == :the_foo_digitaction
205
+ @router.route_request( req ).should match_route( :foo_digit )
200
206
  end
201
207
 
202
208
  it "routes /user/foo/123 to the foo/\d+ action" do
203
209
  req = @request_factory.get( '/user/foo/123' )
204
- @router.route_request( req ).should == :the_foo_digitaction
210
+ @router.route_request( req ).should match_route( :foo_digit )
205
211
  end
206
212
 
207
213
  it "routes /user/foo/1234 to the foo/\d+ action" do
208
214
  req = @request_factory.get( '/user/foo/1234' )
209
- @router.route_request( req ).should == :the_foo_digitaction
215
+ @router.route_request( req ).should match_route( :foo_digit )
210
216
  end
211
217
 
212
218
  end
@@ -0,0 +1,212 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
6
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
7
+ }
8
+
9
+ require 'rspec'
10
+ require 'inversion'
11
+
12
+ require 'spec/lib/helpers'
13
+
14
+ require 'strelka'
15
+ require 'strelka/app/plugins'
16
+ require 'strelka/app/errors'
17
+
18
+ require 'strelka/behavior/plugin'
19
+
20
+
21
+ #####################################################################
22
+ ### C O N T E X T S
23
+ #####################################################################
24
+
25
+ describe Strelka::App::Errors do
26
+
27
+ before( :all ) do
28
+ setup_logging( :fatal )
29
+ @request_factory = Mongrel2::RequestFactory.new( route: '' )
30
+ end
31
+
32
+ after( :all ) do
33
+ reset_logging()
34
+ end
35
+
36
+
37
+ it_should_behave_like( "A Strelka::App Plugin" )
38
+
39
+
40
+ describe "an including App" do
41
+
42
+ before( :each ) do
43
+ Strelka.log.debug "Creating a new Strelka::App"
44
+ @app = Class.new( Strelka::App ) do
45
+ plugin :errors, :routing
46
+ def initialize( appid='params-test', sspec=TEST_SEND_SPEC, rspec=TEST_RECV_SPEC )
47
+ super
48
+ end
49
+ end
50
+ Strelka.log.debug " new instance is: %p" % [ @app ]
51
+ end
52
+
53
+ it "doesn't alter normal responses" do
54
+ @app.class_eval do
55
+ get do |req|
56
+ res = req.response
57
+ res.puts "Oh yeah! Kool-Aid!"
58
+ res.status = HTTP::OK
59
+ return res
60
+ end
61
+ end
62
+
63
+ req = @request_factory.get( '/koolaid' )
64
+ res = @app.new.handle( req )
65
+
66
+ res.status.should == HTTP::OK
67
+ res.body.should == "Oh yeah! Kool-Aid!\n"
68
+ end
69
+
70
+ it "raises an error if a handler is declared with both a template and a block" do
71
+ expect {
72
+ @app.class_eval do
73
+ on_status 404, :a_template do |*|
74
+ # Wait, what am I DOING?!?!
75
+ end
76
+ end
77
+ }.to raise_error( ArgumentError, /don't take a block/i )
78
+ end
79
+
80
+
81
+ it "raises an error if a template handler is declared but the templating plugin isn't loaded" do
82
+ expect {
83
+ @app.class_eval do
84
+ on_status 404, :a_template
85
+ end
86
+ }.to raise_error( ScriptError, /require the :templating plugin/i )
87
+ end
88
+
89
+ it "uses the fallback status handler if an error is encountered in a custom error handler" do
90
+ @app.class_eval do
91
+ on_status 404 do |*|
92
+ raise "A problem with the custom error-handler"
93
+ end
94
+ end
95
+
96
+ req = @request_factory.get( '/foom' )
97
+ res = @app.new.handle( req )
98
+
99
+ res.body.should =~ /internal server error/i
100
+ end
101
+
102
+ context "instance with a callback-style handler for all error statuses" do
103
+
104
+ before( :each ) do
105
+ @app.class_eval do
106
+ on_status do |res, _|
107
+ res.body = 'Filthy banana'
108
+ return res
109
+ end
110
+
111
+ get do |req|
112
+ finish_with HTTP::BAD_REQUEST, "Your sandwich is missing something."
113
+ end
114
+ end
115
+ end
116
+
117
+
118
+ it "calls the appropriate callback when the response is an error status" do
119
+ req = @request_factory.get( '/foom' )
120
+ res = @app.new.handle( req )
121
+
122
+ res.status.should == HTTP::BAD_REQUEST
123
+ res.body.should == 'Filthy banana'
124
+ end
125
+
126
+ end
127
+
128
+
129
+ context "instance with a callback-style handler for NOT_FOUND" do
130
+
131
+ before( :each ) do
132
+ @app.class_eval do
133
+ on_status HTTP::NOT_FOUND do |res, _|
134
+ res.body = 'NOPE!'
135
+ return res
136
+ end
137
+ end
138
+ end
139
+
140
+
141
+ it "calls the appropriate callback when the response is of the associated status" do
142
+ req = @request_factory.get( '/foom' )
143
+ res = @app.new.handle( req )
144
+
145
+ res.body.should == 'NOPE!'
146
+ end
147
+
148
+ end
149
+
150
+
151
+ context "instance with a callback-style handler for all 400-level statuses" do
152
+
153
+ before( :each ) do
154
+ @app.class_eval do
155
+ on_status 400..499 do |res, _|
156
+ res.body = 'Error: JAMBA'
157
+ return res
158
+ end
159
+ end
160
+ end
161
+
162
+
163
+ it "calls the appropriate callback when the response is of the associated status" do
164
+ req = @request_factory.get( '/foom' )
165
+ res = @app.new.handle( req )
166
+
167
+ res.body.should == 'Error: JAMBA'
168
+ end
169
+
170
+ end
171
+
172
+
173
+ context "instance with a template-style handler for SERVER_ERROR" do
174
+
175
+
176
+ before( :all ) do
177
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
178
+ specdir = basedir + 'spec'
179
+ specdata = specdir + 'data'
180
+
181
+ tmpl_paths = [ specdata ]
182
+ Inversion::Template.configure( :template_paths => tmpl_paths )
183
+ end
184
+
185
+ before( :each ) do
186
+ @app.class_eval do
187
+ plugins :templating, :routing
188
+ templates jamba: 'error.tmpl'
189
+ on_status 500, :jamba
190
+
191
+ get do |req|
192
+ finish_with HTTP::SERVER_ERROR, "I knitted an extra arm for his hopes and dreams."
193
+ end
194
+ end
195
+ end
196
+
197
+
198
+ it "renders the response body using the templating plugin" do
199
+ req = @request_factory.get( '/foom' )
200
+ res = @app.new.handle( req )
201
+
202
+ res.body.should =~ /error-handler template/i
203
+ end
204
+ end
205
+
206
+ end
207
+
208
+
209
+ end
210
+
211
+
212
+