hassox-pancake 0.1.6

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 (125) hide show
  1. data/LICENSE +20 -0
  2. data/README.textile +95 -0
  3. data/Rakefile +56 -0
  4. data/TODO +18 -0
  5. data/bin/jeweler +19 -0
  6. data/bin/pancake-gen +17 -0
  7. data/bin/rubyforge +19 -0
  8. data/lib/pancake.rb +48 -0
  9. data/lib/pancake/bootloaders.rb +180 -0
  10. data/lib/pancake/configuration.rb +140 -0
  11. data/lib/pancake/core_ext/class.rb +44 -0
  12. data/lib/pancake/core_ext/object.rb +22 -0
  13. data/lib/pancake/core_ext/symbol.rb +15 -0
  14. data/lib/pancake/errors.rb +61 -0
  15. data/lib/pancake/generators.rb +8 -0
  16. data/lib/pancake/generators/base.rb +12 -0
  17. data/lib/pancake/generators/flat_generator.rb +17 -0
  18. data/lib/pancake/generators/short_generator.rb +17 -0
  19. data/lib/pancake/generators/stack_generator.rb +17 -0
  20. data/lib/pancake/generators/templates/common/dotgitignore +22 -0
  21. data/lib/pancake/generators/templates/common/dothtaccess +17 -0
  22. data/lib/pancake/generators/templates/flat/%stack_name%/%stack_name%.rb.tt +8 -0
  23. data/lib/pancake/generators/templates/flat/%stack_name%/.gitignore +21 -0
  24. data/lib/pancake/generators/templates/flat/%stack_name%/config.ru.tt +12 -0
  25. data/lib/pancake/generators/templates/flat/%stack_name%/pancake.init.tt +1 -0
  26. data/lib/pancake/generators/templates/flat/%stack_name%/public/.empty_directory +0 -0
  27. data/lib/pancake/generators/templates/flat/%stack_name%/tmp/.empty_directory +0 -0
  28. data/lib/pancake/generators/templates/short/%stack_name%/.gitignore +21 -0
  29. data/lib/pancake/generators/templates/short/%stack_name%/LICENSE.tt +20 -0
  30. data/lib/pancake/generators/templates/short/%stack_name%/README.tt +7 -0
  31. data/lib/pancake/generators/templates/short/%stack_name%/Rakefile.tt +48 -0
  32. data/lib/pancake/generators/templates/short/%stack_name%/VERSION.tt +1 -0
  33. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%.rb.tt +5 -0
  34. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/%stack_name%.rb.tt +6 -0
  35. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
  36. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
  37. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
  38. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
  39. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
  40. data/lib/pancake/generators/templates/short/%stack_name%/pancake.init.tt +1 -0
  41. data/lib/pancake/generators/templates/short/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
  42. data/lib/pancake/generators/templates/short/%stack_name%/spec/spec_helper.rb.tt +9 -0
  43. data/lib/pancake/generators/templates/stack/%stack_name%/.gitignore +21 -0
  44. data/lib/pancake/generators/templates/stack/%stack_name%/LICENSE.tt +20 -0
  45. data/lib/pancake/generators/templates/stack/%stack_name%/README.tt +7 -0
  46. data/lib/pancake/generators/templates/stack/%stack_name%/Rakefile.tt +48 -0
  47. data/lib/pancake/generators/templates/stack/%stack_name%/VERSION.tt +1 -0
  48. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%.rb.tt +3 -0
  49. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
  50. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/development.rb.tt +18 -0
  51. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/production.rb.tt +18 -0
  52. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/router.rb.tt +6 -0
  53. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
  54. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
  55. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
  56. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
  57. data/lib/pancake/generators/templates/stack/%stack_name%/pancake.init.tt +1 -0
  58. data/lib/pancake/generators/templates/stack/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
  59. data/lib/pancake/generators/templates/stack/%stack_name%/spec/spec_helper.rb.tt +9 -0
  60. data/lib/pancake/hooks/inheritable_inner_classes.rb +60 -0
  61. data/lib/pancake/hooks/on_inherit.rb +34 -0
  62. data/lib/pancake/master.rb +87 -0
  63. data/lib/pancake/middleware.rb +354 -0
  64. data/lib/pancake/mime_types.rb +265 -0
  65. data/lib/pancake/mixins/publish.rb +125 -0
  66. data/lib/pancake/mixins/publish/action_options.rb +104 -0
  67. data/lib/pancake/mixins/render.rb +61 -0
  68. data/lib/pancake/mixins/request_helper.rb +92 -0
  69. data/lib/pancake/mixins/stack_helper.rb +44 -0
  70. data/lib/pancake/mixins/url.rb +10 -0
  71. data/lib/pancake/more/controller.rb +4 -0
  72. data/lib/pancake/more/controller/base.rb +34 -0
  73. data/lib/pancake/paths.rb +218 -0
  74. data/lib/pancake/router.rb +99 -0
  75. data/lib/pancake/stack/app.rb +10 -0
  76. data/lib/pancake/stack/bootloader.rb +79 -0
  77. data/lib/pancake/stack/configuration.rb +44 -0
  78. data/lib/pancake/stack/middleware.rb +0 -0
  79. data/lib/pancake/stack/router.rb +18 -0
  80. data/lib/pancake/stack/stack.rb +57 -0
  81. data/lib/pancake/stacks/short.rb +2 -0
  82. data/lib/pancake/stacks/short/controller.rb +105 -0
  83. data/lib/pancake/stacks/short/stack.rb +194 -0
  84. data/spec/helpers/helpers.rb +20 -0
  85. data/spec/helpers/matchers.rb +25 -0
  86. data/spec/pancake/bootloaders_spec.rb +109 -0
  87. data/spec/pancake/configuration_spec.rb +177 -0
  88. data/spec/pancake/fixtures/foo_stack/pancake.init +0 -0
  89. data/spec/pancake/fixtures/paths/controllers/controller1.rb +0 -0
  90. data/spec/pancake/fixtures/paths/controllers/controller2.rb +0 -0
  91. data/spec/pancake/fixtures/paths/controllers/controller3.rb +0 -0
  92. data/spec/pancake/fixtures/paths/models/model1.rb +0 -0
  93. data/spec/pancake/fixtures/paths/models/model2.rb +0 -0
  94. data/spec/pancake/fixtures/paths/models/model3.rb +0 -0
  95. data/spec/pancake/fixtures/paths/stack/controllers/controller1.rb +0 -0
  96. data/spec/pancake/fixtures/paths/stack/models/model3.rb +0 -0
  97. data/spec/pancake/fixtures/paths/stack/views/view1.erb +0 -0
  98. data/spec/pancake/fixtures/paths/stack/views/view1.rb +0 -0
  99. data/spec/pancake/fixtures/paths/stack/views/view2.erb +0 -0
  100. data/spec/pancake/fixtures/paths/stack/views/view2.haml +0 -0
  101. data/spec/pancake/fixtures/render_templates/context_template.html.erb +1 -0
  102. data/spec/pancake/fixtures/render_templates/erb_template.html.erb +1 -0
  103. data/spec/pancake/fixtures/render_templates/erb_template.json.erb +1 -0
  104. data/spec/pancake/fixtures/render_templates/haml_template.html.haml +1 -0
  105. data/spec/pancake/fixtures/render_templates/haml_template.xml.haml +1 -0
  106. data/spec/pancake/hooks/on_inherit_spec.rb +65 -0
  107. data/spec/pancake/inheritance_spec.rb +100 -0
  108. data/spec/pancake/middleware_spec.rb +401 -0
  109. data/spec/pancake/mime_types_spec.rb +234 -0
  110. data/spec/pancake/mixins/publish_spec.rb +94 -0
  111. data/spec/pancake/mixins/render_spec.rb +55 -0
  112. data/spec/pancake/mixins/stack_helper_spec.rb +46 -0
  113. data/spec/pancake/pancake_spec.rb +31 -0
  114. data/spec/pancake/paths_spec.rb +210 -0
  115. data/spec/pancake/stack/app_spec.rb +28 -0
  116. data/spec/pancake/stack/bootloader_spec.rb +41 -0
  117. data/spec/pancake/stack/middleware_spec.rb +0 -0
  118. data/spec/pancake/stack/router_spec.rb +266 -0
  119. data/spec/pancake/stack/stack_configuration_spec.rb +101 -0
  120. data/spec/pancake/stack/stack_spec.rb +55 -0
  121. data/spec/pancake/stacks/short/controller_spec.rb +287 -0
  122. data/spec/pancake/stacks/short/router_spec.rb +132 -0
  123. data/spec/pancake/stacks/short/stack_spec.rb +40 -0
  124. data/spec/spec_helper.rb +21 -0
  125. metadata +238 -0
@@ -0,0 +1,101 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "pancake stack configuration" do
4
+
5
+ before(:each) do
6
+ Pancake.configuration.stacks.clear
7
+ Pancake.configuration.configs.clear
8
+ class ::FooStack < Pancake::Stack
9
+ end
10
+ FooStack.roots << Pancake.get_root(__FILE__)
11
+ end
12
+
13
+ after(:each) do
14
+ clear_constants(:FooStack)
15
+ end
16
+
17
+ it "should provide access to the stack configuration" do
18
+ FooStack.configuration.class.should inherit_from(Pancake::Configuration::Base)
19
+ end
20
+
21
+ it "should allow me to set defaults on a stack" do
22
+ FooStack.configuration do
23
+ default :foo, :bar
24
+ default :bar, "Foo Bar Man"
25
+ end
26
+ FooStack.configuration.foo.should == :bar
27
+ FooStack.configuration.bar.should == "Foo Bar Man"
28
+ end
29
+
30
+ it "should allow me to extend the configuration" do
31
+ class Pancake::Stack::Configuration
32
+ default :foo, :bar, "I am a foo default"
33
+ default :bar do
34
+ foobar
35
+ end
36
+
37
+ def foobar
38
+ :foobar
39
+ end
40
+ end
41
+ class FooBarStack < Pancake::Stack; end
42
+
43
+ FooBarStack.configuration.foo.should == :bar
44
+ FooBarStack.configuration.bar.should == :foobar
45
+ end
46
+
47
+ describe "configurations" do
48
+
49
+ it "should provide a configuration object for the stack" do
50
+ app = FooStack.stackup
51
+ app.configuration.should be_an_instance_of(FooStack::Configuration)
52
+ end
53
+
54
+ it "should put a copy of the application at the stack identified by the class" do
55
+ router = FooStack.stackup
56
+ Pancake.configuration.stacks[FooStack].should be_an_instance_of(FooStack)
57
+ end
58
+
59
+ it "should allow me to set a configuration object manually" do
60
+ config = FooStack::Configuration.new
61
+ app = FooStack.stackup(:config => config)
62
+ app.configuration.should equal(config)
63
+ end
64
+
65
+ it "should allow me to have access to the configuration object when creating the stack through a block" do
66
+ app = FooStack.stackup do |config|
67
+ config.foo = :foo
68
+ config.bar = :bar
69
+ end
70
+ app.configuration.foo.should == :foo
71
+ app.configuration.bar.should == :bar
72
+ end
73
+
74
+ it "should setup access to the configuration object through Pancakes configuration" do
75
+ router = FooStack.stackup
76
+ Pancake.configuration.stacks(FooStack).should be_an_instance_of(FooStack)
77
+ Pancake.configuration.configs(FooStack).should equal router.configuration
78
+ end
79
+
80
+ it "should allow me to create a configuration with a label" do
81
+ FooStack.configuration(:my_config).should be_an_instance_of(FooStack::Configuration)
82
+ FooStack.configuration(:my_config).should_not equal(FooStack.configuration)
83
+ end
84
+
85
+ it "should create a stack with an app_name" do
86
+ FooStack.stackup(:app_name => "my.app.name")
87
+ Pancake.configuration.stacks(FooStack).should be_nil
88
+ Pancake.configuration.stacks("my.app.name").should be_an_instance_of(FooStack)
89
+ Pancake.configuration.configs("my.app.name").should be_an_instance_of(FooStack::Configuration)
90
+ end
91
+
92
+ it "should provide access to the configuration in a block" do
93
+ Pancake.configuration.configs(FooStack) do |config|
94
+ config.foo = :foo
95
+ end
96
+ @app = FooStack.stackup
97
+ @app.configuration.foo.should == :foo
98
+ end
99
+ end
100
+
101
+ end
@@ -0,0 +1,55 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "Pancake::Stack" do
4
+ before(:each) do
5
+ class ::StackSpecStack < Pancake::Stack
6
+ end
7
+ end
8
+
9
+ after(:each) do
10
+ clear_constants(:StackSpecStack)
11
+ end
12
+
13
+ describe "roots" do
14
+
15
+ it "should provide access to setting the roots" do
16
+ StackSpecStack.roots.should be_empty
17
+ StackSpecStack.roots << File.expand_path(File.dirname(__FILE__))
18
+ StackSpecStack.roots.should include(File.expand_path(File.dirname(__FILE__)))
19
+ end
20
+
21
+ it "should provide access to adding a root" do
22
+ StackSpecStack.roots.should be_empty
23
+ StackSpecStack.roots << Pancake.get_root(__FILE__)
24
+ StackSpecStack.roots.should include(File.expand_path(File.dirname(__FILE__)))
25
+ end
26
+
27
+ it "should allow me to get multiple roots in the order they're added" do
28
+ StackSpecStack.roots.should be_empty
29
+ StackSpecStack.roots << Pancake.get_root(__FILE__)
30
+ StackSpecStack.roots << "/tmp"
31
+ StackSpecStack.roots.should == [Pancake.get_root(__FILE__), "/tmp"]
32
+ end
33
+
34
+ it "should iterate over the roots in the direction they're added" do
35
+ StackSpecStack.roots.should be_empty
36
+ StackSpecStack.roots << Pancake.get_root(__FILE__)
37
+ StackSpecStack.roots << "/foo"
38
+ StackSpecStack.roots.map{|f| f}.should == [Pancake.get_root(__FILE__), "/foo"]
39
+ end
40
+ end # roots
41
+
42
+ # describe "initialize stack" do
43
+
44
+ it "should mark a stack as initialized once it has called the initialize_stack method" do
45
+ StackSpecStack::BootLoader
46
+ StackSpecStack.roots << ::Pancake.get_root(__FILE__)
47
+ StackSpecStack.initialize_stack
48
+ StackSpecStack.should be_initialized
49
+ end
50
+
51
+ it "should not be initialized when it has not called initialize_stack" do
52
+ StackSpecStack.should_not be_initialized
53
+ end
54
+ # end
55
+ end
@@ -0,0 +1,287 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)),'..', '..', '..', 'spec_helper')
2
+
3
+ describe Pancake::Stacks::Short::Controller do
4
+
5
+ before do
6
+ class ::ShortFoo < Pancake::Stacks::Short
7
+ class Controller
8
+ def do_dispatch!
9
+ dispatch!
10
+ end
11
+
12
+ publish
13
+ def show; "show"; end
14
+
15
+ publish
16
+ def index; "index"; end
17
+
18
+ protected
19
+ def a_protected_method; "protected"; end
20
+
21
+ private
22
+ def a_private_method; "private"; end
23
+ end
24
+ end
25
+ ShortFoo.roots << Pancake.get_root(__FILE__)
26
+ end
27
+
28
+ after do
29
+ clear_constants "ShortFoo", :ShortBar
30
+ end
31
+
32
+ def app
33
+ ShortFoo.stackup
34
+ end
35
+
36
+ it "should have a Controller" do
37
+ Pancake::Stacks::Short.constants.map(&:to_s).should include("Controller")
38
+ end
39
+
40
+ it "should inherit the subclass controller from the parent controller" do
41
+ ShortFoo::Controller.should inherit_from(Pancake::Stacks::Short::Controller)
42
+ end
43
+
44
+ describe "dispatching an action" do
45
+ before do
46
+ @controller = ShortFoo::Controller.new(env_for)
47
+ end
48
+
49
+ it "should call the 'show' action" do
50
+ @controller.params["action"] = "show"
51
+ result = @controller.do_dispatch!
52
+ result[0].should == 200
53
+ result[2].body.join.should == "show"
54
+ end
55
+
56
+ it "should raise a Pancake::Response::NotFound exception when an action is now found" do
57
+ @controller.params["action"] = :does_not_exist
58
+ result = @controller.do_dispatch!
59
+ result[0].should == 404
60
+ end
61
+
62
+ it "should not dispatch to a protected method" do
63
+ @controller.params["action"] = "a_protected_method"
64
+ result = @controller.do_dispatch!
65
+ result[0].should == 404
66
+ end
67
+
68
+ it "should not dispatch to a private method" do
69
+ @controller.params["action"] = "a_private_method"
70
+ result = @controller.do_dispatch!
71
+ result[0].should == 404
72
+ end
73
+
74
+ describe "helper in methods" do
75
+ before do
76
+ module PancakeTestHelper
77
+ def some_helper_method
78
+ "foo"
79
+ end
80
+ end
81
+
82
+ class ShortFoo
83
+ class Controller
84
+ include PancakeTestHelper
85
+ end
86
+ end
87
+ end
88
+ after do
89
+ clear_constants "PancakeTestHelper"
90
+ end
91
+
92
+ it "should not call a helper method" do
93
+ @controller.params["action"] = "some_helper_method"
94
+ result = @controller.do_dispatch!
95
+ result[0].should == 404
96
+ end
97
+
98
+ end
99
+ end
100
+
101
+ describe "accept type negotiations" do
102
+ before do
103
+ class ::ShortBar < Pancake::Stacks::Short
104
+ roots << Pancake.get_root(__FILE__)
105
+ # makes the dispatch method public
106
+ def do_dispatch!
107
+ dispatch!
108
+ end
109
+
110
+ provides :json, :xml, :text
111
+
112
+ get "/foo/bar(.:format)" do
113
+ "format #{content_type.inspect}"
114
+ end
115
+ end # ShortBar
116
+ end # before
117
+
118
+ def app
119
+ ShortBar.stackup
120
+ end
121
+
122
+ it "should get json by default" do
123
+ result = get "/foo/bar", {}, "HTTP_ACCEPT" => "application/json"
124
+ result.status.should == 200
125
+ result.headers["Content-Type"].should == "application/json"
126
+ result.body.to_s.should == "format :json"
127
+ end
128
+
129
+ it "should get xml when specified" do
130
+ result = get "/foo/bar.xml"
131
+ result.status.should == 200
132
+ result.headers["Content-Type"].should == "application/xml"
133
+ result.body.to_s.should == "format :xml"
134
+ end
135
+
136
+ it "should get json when specified with */*" do
137
+ result = get "/foo/bar", {}, "HTTP_ACCEPT" => "*/*"
138
+ result.status.should == 200
139
+ result.body.to_s.should == "format :json"
140
+ result.headers["Content-Type"].should == "application/json"
141
+ end
142
+
143
+ it "should get the default when specified with */*" do
144
+ result = get "/foo/bar", {}, "HTTP_ACCEPT" => "application/xml,*/*"
145
+ result.status.should == 200
146
+ result.body.to_s.should == "format :json"
147
+ result.headers["Content-Type"].should == "application/json"
148
+ end
149
+
150
+ it "should use the format in preference to the content type" do
151
+ result = get "/foo/bar.xml", {}, "HTTP_ACCEPT" => "*/*"
152
+ result.status.should == 200
153
+ result.body.to_s.should == "format :xml"
154
+ result.headers["Content-Type"].should == "application/xml"
155
+ end
156
+
157
+ it "should get json by default" do
158
+ result = get "/foo/bar"
159
+ result.status.should == 200
160
+ result.body.to_s.should == "format :json"
161
+ result.headers["Content-Type"].should == "application/json"
162
+ end
163
+
164
+ it "should correctly negotiate different scenarios" do
165
+ r = get "/foo/bar", {}, {}
166
+ r.body.should == "format :json"
167
+ r = get "/foo/bar.xml", {}, {}
168
+ r.body.should == "format :xml"
169
+ r = get "/foo/bar", {}, {}
170
+ r.body.should == "format :json"
171
+ r = get "/foo/bar", {}, "HTTP_ACCEPT" => "application/xml"
172
+ r.body.should == "format :xml"
173
+ r = get "/foo/bar.json"
174
+ r.body.should == "format :json"
175
+ end
176
+
177
+ it "should negotiate based on extension" do
178
+ r = get "/foo/bar"
179
+ r.body.should == "format :json"
180
+ r = get "/foo/bar.text"
181
+ r.body.should == "format :text"
182
+ r = get "/foo/bar.xml"
183
+ r.body.should == "format :xml"
184
+ r = get "/foo/bar.txt"
185
+ r.body.should == "format :text"
186
+ end
187
+
188
+ it "should not provide a response to a format that is not provided" do
189
+ r = get "/foo/bar.svg"
190
+ r.status.should == 406
191
+ end
192
+ end # Accept type negotiations
193
+
194
+ describe "error handling" do
195
+ before do
196
+ class ::ShortFoo
197
+ provides :html, :xml
198
+
199
+ get "/foo(.:format)" do
200
+ "HERE"
201
+ end
202
+
203
+ get "/bad" do
204
+ raise "This is bad"
205
+ end
206
+
207
+ end
208
+ end
209
+
210
+ describe "default error handling" do
211
+ def app
212
+ ShortFoo.stackup
213
+ end
214
+
215
+ it "should handle a NotFound by default" do
216
+ result = get "/does_not_exist"
217
+ result.status.should == 404
218
+ result.body.should include(Pancake::Errors::NotFound.description)
219
+ end
220
+
221
+ it "should return a 500 status for a Random Error by wrapping it in a Pancake::Errors::Server" do
222
+ result = get "/bad"
223
+ result.status.should == 500
224
+ result.body.should include(Pancake::Errors::Server.description)
225
+ end
226
+
227
+ it "should handle a NotAcceptable error" do
228
+ result = get "/foo.no_format_i_know_of"
229
+ result.status.should == 406
230
+ result.body.should include(Pancake::Errors::NotAcceptable.description)
231
+ end
232
+
233
+ it "should return 406 for a format that is in pancake but not in the group" do
234
+ r = get "/foo.svg"
235
+ r.status.should == 406
236
+ end
237
+
238
+
239
+ end
240
+
241
+ describe "custom error handling" do
242
+ before do
243
+ ShortFoo.handle_exception do |error|
244
+ out = ""
245
+ out << "CUSTOM "
246
+ out << error.name
247
+ out << ": "
248
+ out << error.description
249
+ end
250
+
251
+ ShortFoo.get "/bad" do
252
+ raise "Really Bad"
253
+ end
254
+ end
255
+
256
+ after do
257
+ ShortFoo.handle_exception(&Pancake::Stacks::Short::Controller::DEFAULT_EXCEPTION_HANDLER)
258
+ end
259
+
260
+ it "should handle Pancake::Errors::NotFound errors" do
261
+ r = get "/not_a_thing"
262
+ r.status.should == 404
263
+ r.body.should include("CUSTOM")
264
+ r.body.should include(Pancake::Errors::NotFound.description)
265
+ end
266
+
267
+ it "should handle an unknown server error" do
268
+ r = get "/bad"
269
+ r.status.should == 500
270
+ r.body.should include("CUSTOM")
271
+ r.body.should include(Pancake::Errors::Server.description)
272
+ end
273
+
274
+ it "should let me do stuff on an instance level inside the handle exception" do
275
+ ShortFoo.handle_exception do |error|
276
+ self.status = 123
277
+ "BOOO!"
278
+ end
279
+
280
+ r = get "/bad"
281
+ r.status.should == 123
282
+ r.body.should == "BOOO!"
283
+ end
284
+
285
+ end
286
+ end
287
+ end
@@ -0,0 +1,132 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)),'..', '..', '..', 'spec_helper')
2
+
3
+ describe Pancake::Stacks::Short, "routes" do
4
+ before do
5
+ class ::RoutedShortStack < Pancake::Stacks::Short
6
+ roots << Pancake.get_root(__FILE__)
7
+
8
+ get "/foo", :_name => :foo do
9
+ "get - foo"
10
+ end
11
+
12
+ get "/bar", :_name => :bar do
13
+ "get - bar"
14
+ end
15
+
16
+ post "/foo" do
17
+ "post - foo"
18
+ end
19
+
20
+ post "/bar" do
21
+ "post - bar"
22
+ end
23
+
24
+ put "/foo" do
25
+ "put - foo"
26
+ end
27
+
28
+ put "/bar" do
29
+ "put - bar"
30
+ end
31
+
32
+ delete "/foo" do
33
+ "delete - foo"
34
+ end
35
+
36
+ delete "/bar" do
37
+ "delete - bar"
38
+ end
39
+
40
+ get "/baz/:var(/:date)" do
41
+ "done: var == #{params[:var]} : date == #{params[:date]}"
42
+ end.name(:baz)
43
+ end
44
+ @app = RoutedShortStack.stackup
45
+ end
46
+ after do
47
+ clear_constants "RoutedShortStack", "FooApp", "BarApp"
48
+ end
49
+
50
+ def app
51
+ @app
52
+ end
53
+
54
+ %w(foo bar).each do |item|
55
+ %w(get post put delete).each do |method|
56
+ it "should #{method} /#{item}" do
57
+ result = self.send(method, "/#{item}")
58
+ result.status.should == 200
59
+ result.body.should == "#{method} - #{item}"
60
+ end
61
+ end # get post put delete
62
+ end # foo bar
63
+
64
+ it "should return a not found if we try to get an action that has not been defined" do
65
+ result = get "/blah"
66
+ result.status.should == 404
67
+ end
68
+
69
+
70
+ it "should handle tricky routes" do
71
+ result = get "/baz/hassox"
72
+ result.status.should == 200
73
+ result.body.should == "done: var == hassox : date == "
74
+ end
75
+
76
+ it "should handle tricky routes with optional parameters" do
77
+ result = get "/baz/hassox/2009-08-21"
78
+ result.status.should == 200
79
+ result.body.should == "done: var == hassox : date == 2009-08-21"
80
+ end
81
+
82
+ describe "url generation" do
83
+ it "should generate a simple named url" do
84
+ Pancake.url(RoutedShortStack, :foo).should == "/foo"
85
+ end
86
+
87
+ it "should generate a complex named url" do
88
+ Pancake.url(RoutedShortStack, :baz, :var => "bar").should == "/baz/bar"
89
+ Pancake.url(RoutedShortStack, :baz, :var => "bar", :date => "today").should == "/baz/bar/today"
90
+ end
91
+
92
+ it "should generate it's url when it's nested" do
93
+ class ::FooApp < Pancake::Stack; end
94
+ FooApp.router.mount(RoutedShortStack.stackup, "/short/stack")
95
+ Pancake.url(RoutedShortStack, :foo).should == "/short/stack/foo"
96
+ Pancake.url(RoutedShortStack, :baz, :var => "var", :date => "today").should == "/short/stack/baz/var/today"
97
+ end
98
+ end
99
+
100
+ describe "inherited route generation" do
101
+ before do
102
+ class ::FooApp < RoutedShortStack; end
103
+ @app = FooApp.stackup
104
+ end
105
+
106
+ it "should generate an inherited simple url" do
107
+ Pancake.url(FooApp, :foo).should == "/foo"
108
+ end
109
+
110
+ it "should generate a complex url" do
111
+ Pancake.url(FooApp, :baz, :var => "the_var", :date => "today").should == "/baz/the_var/today"
112
+ end
113
+
114
+ %w(foo bar).each do |item|
115
+ %w(get post put delete).each do |method|
116
+ it "should #{method} /#{item}" do
117
+ result = self.send(method, "/#{item}")
118
+ result.status.should == 200
119
+ result.body.should == "#{method} - #{item}"
120
+ end
121
+ end # get post put delete
122
+ end # foo bar
123
+
124
+ it "should match the nested route without affecting the parent" do
125
+ class ::BarApp < Pancake::Stack; end
126
+ BarApp.router.mount(FooApp.stackup, "/mount/point")
127
+
128
+ Pancake.url(FooApp, :foo).should == "/mount/point/foo"
129
+ Pancake.url(RoutedShortStack, :foo).should == "/foo"
130
+ end
131
+ end
132
+ end