pancake 0.1.10 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/Rakefile +5 -1
  2. data/lib/pancake/bootloaders.rb +27 -27
  3. data/lib/pancake/defaults/configuration.rb +2 -1
  4. data/lib/pancake/errors.rb +8 -7
  5. data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%.rb.tt +1 -0
  6. data/lib/pancake/generators/templates/short/%stack_name%/spec/%stack_name%_spec.rb.tt +4 -0
  7. data/lib/pancake/generators/templates/short/%stack_name%/spec/spec_helper.rb.tt +5 -1
  8. data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%.rb.tt +1 -0
  9. data/lib/pancake/generators/templates/stack/%stack_name%/spec/%stack_name%_spec.rb.tt +4 -0
  10. data/lib/pancake/generators/templates/stack/%stack_name%/spec/spec_helper.rb.tt +5 -1
  11. data/lib/pancake/mixins/render/render.rb +10 -4
  12. data/lib/pancake/mixins/render.rb +37 -7
  13. data/lib/pancake/mixins/request_helper.rb +25 -0
  14. data/lib/pancake/mixins/response_helper.rb +6 -0
  15. data/lib/pancake/router.rb +81 -7
  16. data/lib/pancake/stack/bootloader.rb +40 -10
  17. data/lib/pancake/stack/router.rb +10 -2
  18. data/lib/pancake/stack/stack.rb +34 -1
  19. data/lib/pancake/stacks/short/bootloaders.rb +2 -2
  20. data/lib/pancake/stacks/short/controller.rb +17 -4
  21. data/lib/pancake/test/matchers.rb +39 -0
  22. data/lib/pancake.rb +5 -0
  23. data/spec/pancake/bootloaders_spec.rb +29 -28
  24. data/spec/pancake/defaults/configuration_spec.rb +1 -1
  25. data/spec/pancake/fixtures/render_templates/view_context/_basic.haml +3 -0
  26. data/spec/pancake/fixtures/render_templates/view_context/_basic.html.haml +4 -0
  27. data/spec/pancake/fixtures/render_templates/view_context/_foo_as_name.haml +1 -0
  28. data/spec/pancake/fixtures/render_templates/view_context/_local_as_name.haml +1 -0
  29. data/spec/pancake/fixtures/render_templates/view_context/_with_locals.haml +2 -0
  30. data/spec/pancake/fixtures/render_templates/view_context/collection_with_partial_name.haml +1 -0
  31. data/spec/pancake/fixtures/render_templates/view_context/contains_partial.haml +5 -0
  32. data/spec/pancake/middleware_spec.rb +5 -5
  33. data/spec/pancake/mixins/render/view_context_spec.rb +60 -0
  34. data/spec/pancake/stack/router_spec.rb +52 -13
  35. data/spec/pancake/stacks/short/controller_spec.rb +35 -0
  36. data/spec/pancake/stacks/short/router_spec.rb +4 -2
  37. data/spec/pancake/stacks/short/stack_spec.rb +4 -3
  38. metadata +51 -3
@@ -2,11 +2,19 @@ module Pancake
2
2
  class Stack
3
3
  class Router < Pancake::Router; end
4
4
  inheritable_inner_classes :Router
5
-
6
- class_inheritable_accessor :_router
5
+ cattr_writer :_router
7
6
 
8
7
  @_router = self::Router.new
9
8
 
9
+ def self._router
10
+ @_router ||= begin
11
+ r = self::Router.new
12
+ unless self == Pancake::Stack
13
+ r.router = superclass._router.router.dup
14
+ end
15
+ r
16
+ end
17
+ end
10
18
  # Resets the router to use the stacks namespaced router.
11
19
  # This allows a router to mixin a module, and have that module
12
20
  # mixed in to child stacks/routers. Effectively, this will reset the scope of inheritance so that a stack type can have particular route helpers
@@ -43,7 +43,7 @@ module Pancake
43
43
  Pancake.configuration.stacks[@app_name] = self
44
44
 
45
45
  # setup the configuration for this stack
46
- Pancake.configuration.configs[@app_name] = opts[:config] if opts [:config]
46
+ Pancake.configuration.configs[@app_name] = opts[:config] if opts[:config]
47
47
  self.configuration(@app_name)
48
48
  yield self.configuration(@app_name) if block_given?
49
49
 
@@ -62,5 +62,38 @@ module Pancake
62
62
  app = new(nil, opts, &block)
63
63
  Pancake.configuration.configs[app.app_name].router
64
64
  end # stackup
65
+
66
+ # Creates a bootloader hook(s) of the given name. That are inheritable
67
+ # This will create hooks for use in a bootloader (but will not create the bootloader itself!)
68
+ #
69
+ # @example
70
+ # MyStack.create_bootloader_hook(:before_stuff, :after_stuff)
71
+ #
72
+ # MyStack.before_stuff do
73
+ # # stuff to do before stuff
74
+ # end
75
+ #
76
+ # MyStack.after_stuff do
77
+ # # stuff to do after stuff
78
+ # enc
79
+ #
80
+ # MyStack.before_stuff.each{|blk| blk.call}
81
+ #
82
+ # @api public
83
+ def self.create_bootloader_hook(*hooks)
84
+ hooks.each do |hook|
85
+ class_inheritable_reader "_#{hook}"
86
+ instance_variable_set("@_#{hook}", [])
87
+
88
+ class_eval <<-RUBY
89
+ def self.#{hook}(&blk)
90
+ _#{hook} << blk if blk
91
+ _#{hook}
92
+ end
93
+ RUBY
94
+ end
95
+ end
96
+
97
+ create_bootloader_hook :before_build_stack, :before_mount_applications, :after_initialize_application, :after_build_stack
65
98
  end # Stack
66
99
  end # Pancake
@@ -1,4 +1,4 @@
1
- Pancake::Stacks::Short::BootLoader.add(:paths) do
1
+ Pancake::Stacks::Short::BootLoader.add(:paths, :before => :load_mounted_inits ) do
2
2
  def run!
3
3
  stack_class.push_paths :public, "public"
4
4
 
@@ -6,7 +6,7 @@ Pancake::Stacks::Short::BootLoader.add(:paths) do
6
6
  end
7
7
  end
8
8
 
9
- Pancake::Stacks::Short::BootLoader.add(:default_middlewares, :before => :build_stack) do
9
+ Pancake::Stacks::Short::BootLoader.add(:default_middlewares, :before => :load_mounted_inits) do
10
10
  def run!
11
11
  stack_class.stack(:static_files).use(Pancake::Middlewares::Static, stack_class)
12
12
  end
@@ -63,7 +63,16 @@ module Pancake
63
63
 
64
64
  # set the response header
65
65
  headers["Content-Type"] = ct
66
- Rack::Response.new(self.send(params["action"]), status, headers).finish
66
+
67
+ result = self.send(params['action'])
68
+ case result
69
+ when Array
70
+ result
71
+ when Rack::Response
72
+ result.finish
73
+ else
74
+ Rack::Response.new(self.send(params["action"]), status, headers).finish
75
+ end
67
76
 
68
77
  rescue Errors::HttpError => e
69
78
  if logger
@@ -72,8 +81,12 @@ module Pancake
72
81
  end
73
82
  handle_request_exception(e)
74
83
  rescue Exception => e
75
- server_error = Errors::Server.new
76
- server_error.exceptions << e
84
+ if Pancake.handle_errors?
85
+ server_error = Errors::Server.new
86
+ server_error.exceptions << e
87
+ else
88
+ server_error = e
89
+ end
77
90
  handle_request_exception(server_error)
78
91
  end
79
92
 
@@ -90,7 +103,7 @@ module Pancake
90
103
  end
91
104
 
92
105
  def handle_request_exception(error)
93
- raise error unless Pancake.handle_errors?
106
+ raise(error.class, error.message, error.backtrace) unless Pancake.handle_errors?
94
107
  self.status = error.code
95
108
  result = instance_exec error, &self.class.handle_exception
96
109
  Rack::Response.new(result, status, headers).finish
@@ -0,0 +1,39 @@
1
+ module Pancake
2
+ module Test
3
+ module Matchers
4
+ class MountMatcher
5
+ def initialize(expected_app, path)
6
+ @expected_app, @path = expected_app, path
7
+ end
8
+
9
+ def matches?(target)
10
+ @target = target
11
+ @ma = @target::Router.mounted_applications.detect{|m| m.mounted_app == @expected_app}
12
+ if @ma
13
+ @ma.mounted_app == @expected_app && @ma.mount_path == @path
14
+ else
15
+ false
16
+ end
17
+ end
18
+
19
+ def failure_message_for_should
20
+ if @ma
21
+ "Expected #{@target} to mount #{@expected_app} at #{@path.inspect} but was mounted at #{@ma.mount_path.inspect}"
22
+ else
23
+ "Expected #{@target} to mount #{@expected_app} but it was not mounted"
24
+ end
25
+ end
26
+
27
+ def failure_message_for_should_not
28
+ if @ma
29
+ "Expected #{@target} to not implement #{@expected_app} at #{@path} but it was mounted there"
30
+ end
31
+ end
32
+ end # MountMatcher
33
+
34
+ def mount(expected, path)
35
+ MountMatcher.new(expected, path)
36
+ end
37
+ end # Matchers
38
+ end # Test
39
+ end # Pancake
data/lib/pancake.rb CHANGED
@@ -35,6 +35,11 @@ module Pancake
35
35
  autoload :Static, "pancake/middlewares/static"
36
36
  autoload :Logger, "pancake/middlewares/logger"
37
37
  end
38
+
39
+ module Test
40
+ autoload :Matchers, "pancake/test/matchers"
41
+ end
42
+
38
43
  end
39
44
 
40
45
  require 'pancake/paths'
@@ -1,42 +1,42 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe "Pancake::Stack::BootLoader" do
4
-
4
+
5
5
  before(:each) do
6
6
  $captures = []
7
-
7
+
8
8
  class ::FooStack < Pancake::Stack
9
9
  roots << File.join(Pancake.get_root(__FILE__), "..", "fixtures", "foo_stack")
10
10
  end
11
11
  end
12
-
12
+
13
13
  after(:each) do
14
14
  clear_constants(:FooStack)
15
15
  end
16
-
16
+
17
17
  it "should not add the bootloader without it having a run! method" do
18
18
  lambda do
19
19
  FooStack::BootLoader.add(:foo){|s,c| :here }
20
20
  end.should raise_error
21
21
  end
22
-
22
+
23
23
  it "should allow me to add an application specific BootLoader" do
24
- FooStack::BootLoader.add(:my_initializer){ def run!; :foo; end}
24
+ FooStack::BootLoader.add(:my_initializer){ def run!; :foo; end}
25
25
  FooStack::BootLoader[:my_initializer].call({}).should == :foo
26
26
  end
27
-
27
+
28
28
  it "should provide a bootloader instance" do
29
29
  FooStack::BootLoader.add(:my_initializer){ def run!; :foo; end}
30
30
  FooStack::BootLoader[:my_initializer].should inherit_from(Pancake::BootLoaderMixin::Base)
31
31
  end
32
-
32
+
33
33
  it "should allow me to add multiple boot loaders" do
34
34
  FooStack::BootLoader.add(:foo){ def run!; :foo; end}
35
35
  FooStack::BootLoader.add(:bar){ def run!; :bar; end}
36
36
  FooStack::BootLoader[:foo].call({}).should == :foo
37
37
  FooStack::BootLoader[:bar].call({}).should == :bar
38
38
  end
39
-
39
+
40
40
  it "should allow me to add a bootloader before another" do
41
41
  $captures.should be_empty
42
42
  FooStack::BootLoader.add(:foo){ def run!; $captures << :foo; end}
@@ -45,7 +45,7 @@ describe "Pancake::Stack::BootLoader" do
45
45
  FooStack.new
46
46
  $captures.should == [:foo, :baz, :bar]
47
47
  end
48
-
48
+
49
49
  it "should allow me to add a bootloader after another" do
50
50
  $captures.should be_empty
51
51
  FooStack::BootLoader.add(:foo){ def run!; $captures << :foo; end}
@@ -54,7 +54,7 @@ describe "Pancake::Stack::BootLoader" do
54
54
  FooStack.new
55
55
  $captures.should == [:foo, :baz, :bar]
56
56
  end
57
-
57
+
58
58
  it "should provide an arbitrarily complex setup" do
59
59
  $captures.should be_empty
60
60
  FooStack::BootLoader.add(:foo ){ def run!; $captures << :foo; end}
@@ -63,47 +63,48 @@ describe "Pancake::Stack::BootLoader" do
63
63
  FooStack::BootLoader.add(:paz, :before => :baz ){ def run!; $captures << :paz; end}
64
64
  FooStack::BootLoader.add(:fred, :before => :bar ){ def run!; $captures << :fred; end}
65
65
  FooStack::BootLoader.add(:barney, :after => :fred ){ def run!; $captures << :barney; end}
66
-
66
+
67
67
  FooStack.new
68
68
  $captures.should == [:foo, :paz, :baz, :fred, :barney, :bar]
69
69
  end
70
-
70
+
71
71
  describe "types" do
72
-
72
+
73
73
  it "should run bootloaders marked as :init" do
74
74
  FooStack::BootLoader.add(:bar, :level => :init ){ def run!; $captures << [:bar, :init ]; end}
75
75
  FooStack::BootLoader.add(:baz, :level => :init ){ def run!; $captures << [:baz, :init ]; end}
76
76
  FooStack::BootLoader.add(:paz, :level => :init, :before => :baz){ def run!; $captures << [:paz, :init]; end}
77
-
77
+
78
78
  FooStack::BootLoader.run!(:only => {:level => :init})
79
79
  $captures.should == [[:bar, :init], [:paz, :init], [:baz, :init]]
80
80
  end
81
-
81
+
82
82
  it "should run init or then default level bootloaders individually" do
83
83
  FooStack::BootLoader.add(:foo ){ def run!; $captures << [:foo, :default]; end}
84
- FooStack::BootLoader.add(:grh ){ def run!; $captures << [:grh, :default]; end}
84
+ FooStack::BootLoader.add(:grh ){ def run!; $captures << [:grh, :default]; end}
85
85
  FooStack::BootLoader.add(:bar, :level => :init ){ def run!; $captures << [:bar, :init ]; end}
86
- FooStack::BootLoader.add(:ptf, :before => :grh ){ def run!; $captures << [:ptf, :default]; end}
86
+ FooStack::BootLoader.add(:ptf, :before => :grh ){ def run!; $captures << [:ptf, :default]; end}
87
87
  FooStack::BootLoader.add(:baz, :level => :init ){ def run!; $captures << [:baz, :init ]; end}
88
88
  FooStack::BootLoader.add(:paz, :level => :init, :before => :baz){ def run!; $captures << [:paz, :init]; end}
89
-
89
+
90
90
  FooStack.new
91
91
  $captures.should == [[:bar, :init], [:paz, :init], [:baz, :init], [:foo, :default], [:ptf, :default], [:grh, :default]]
92
92
  end
93
-
94
- it "should inherit from the default boot loaders" do
95
- ::Pancake::Stack::BootLoader.add(:default_boot_loader_test){def run!; end}
96
- class ::Bario < Pancake::Stack; end
97
- Bario::BootLoader.map{|n,bl| n}.should include(:default_boot_loader_test)
98
- end
99
-
93
+
94
+ # it "should inherit from the default boot loaders" do
95
+ # ::Pancake::Stack::BootLoader.add(:default_boot_loader_test){def run!; end}
96
+ # class ::Bario < Pancake::Stack; end
97
+ # Bario::BootLoader.map{|n,bl| n}.should include(:default_boot_loader_test)
98
+ # ::Pancake::Stack::BootLoader.
99
+ # end
100
+
100
101
  it "should let me pass options to the bootloaders and pass them on" do
101
102
  FooStack::BootLoader.add(:foo){ def run!; config[:result] << :foo; end}
102
103
  FooStack::BootLoader.add(:bar){ def run!; config[:result] << :bar; end}
103
-
104
+
104
105
  opts = { :result => [] }
105
106
  FooStack.new(nil, opts)
106
107
  opts[:result].should == [:foo, :bar]
107
108
  end
108
109
  end
109
- end
110
+ end
@@ -43,7 +43,7 @@ describe "Pancake configuration defaults" do
43
43
 
44
44
  it "should set the log stream to a file path when told to log to file" do
45
45
  Pancake.configuration.log_to_file = true
46
- result = Pancake.configuration.log_stream
46
+ result = Pancake.configuration.log_path
47
47
  result.should match(/\log\/pancake_#{Pancake.env}\.log$/)
48
48
  end
49
49
 
@@ -0,0 +1,3 @@
1
+ .item
2
+ In Partial Basic
3
+ - $captures << self
@@ -0,0 +1,4 @@
1
+ .item
2
+ In Partial Basic
3
+
4
+ - $captures << self
@@ -0,0 +1 @@
1
+ = "local_as_name == #{local_as_name}"
@@ -0,0 +1,2 @@
1
+ = "foo == #{foo}"
2
+ = "bar == #{bar}"
@@ -0,0 +1 @@
1
+ = partial :local_as_name, :with => collection
@@ -0,0 +1,5 @@
1
+ - $captures << self
2
+
3
+ %p
4
+ In Contains Partial
5
+ = partial :basic
@@ -85,15 +85,15 @@ describe "Pancake::Middleware" do
85
85
  BazApp.use FooMiddle
86
86
  Pancake.use GeneralMiddleware
87
87
 
88
- FooApp.with_router do |r|
89
- r.mount(BarApp.stackup, "/bar")
90
- r.mount(BazApp.stackup, "/baz")
88
+ FooApp.router do |r|
89
+ r.mount(BarApp, "/bar")
90
+ r.mount(BazApp, "/baz")
91
91
  end
92
92
 
93
93
  @app = Pancake.start(:root => @root){ FooApp.stackup }
94
- get "/baz"
94
+ result = get "/baz"
95
95
  $current_env["p.s.c"].should == [GeneralMiddleware, FooMiddle]
96
- get "/bar"
96
+ reult = get "/bar"
97
97
  $current_env["p.s.c"].should == [GeneralMiddleware, BarMiddle]
98
98
  end
99
99
  end
@@ -249,6 +249,66 @@ describe Pancake::Mixins::Render::ViewContext do
249
249
  result.should include("nested new bar content")
250
250
  end
251
251
  end
252
+
253
+ describe "partials" do
254
+ before do
255
+ @foo = FooBar.new({})
256
+ @collection = %w(one two three four)
257
+ $captures = []
258
+ end
259
+
260
+ it "should use the _partial_template_name_for method to find a partial" do
261
+ @foo.should_receive(:_partial_template_name_for).with(:basic, {}).and_return("_basic")
262
+ result = @foo.partial(:basic)
263
+ end
264
+
265
+ it "should render a partial with the partial call" do
266
+ result = @foo.partial(:basic)
267
+ result.should include("In Partial Basic")
268
+ end
269
+
270
+ it "should render from within a template" do
271
+ result = @foo.render(:contains_partial)
272
+ result.should include("In Partial Basic")
273
+ end
274
+
275
+ it "should use a different view context instance for the partial" do
276
+ result = @foo.render(:contains_partial)
277
+ $captures.should have(2).items
278
+ $captures.first.should_not == $captures.last
279
+ end
280
+
281
+ it "should allow me to specify locals for use in the partial" do
282
+ result = @foo.partial(:with_locals, :foo => "this is foo", :bar => "and this is bar")
283
+ result.should include("foo == this is foo")
284
+ result.should include("bar == and this is bar")
285
+ end
286
+
287
+ it "should render a partial with an object as the local name" do
288
+ result = @foo.partial(:local_as_name, :with => "value of local as name")
289
+ result.should include("local_as_name == value of local as name")
290
+ end
291
+
292
+ it "should render a partial with many objects with the obj as a local with the partial name" do
293
+ result = @foo.partial(:local_as_name, :with => @collection)
294
+ @collection.each do |val|
295
+ result.should include("local_as_name == #{val}")
296
+ end
297
+ end
298
+
299
+ it "should render a partial with an object with a specified name" do
300
+ result = @foo.partial(:foo_as_name, :with => "jimmy", :as => :foo)
301
+ result.should include("foo == jimmy")
302
+ end
303
+
304
+ it "should render a partial with many objects as a local with a specified name" do
305
+ result = @foo.partial(:foo_as_name, :with => @collection, :as => :foo)
306
+ @collection.each do |val|
307
+ result.should include("foo == #{val}")
308
+ end
309
+ end
310
+
311
+ end
252
312
  end
253
313
 
254
314
 
@@ -65,13 +65,6 @@ describe "stack router" do
65
65
  last_response.status.should == 404
66
66
  end
67
67
 
68
- it "should make sure that the application is a rack application" do
69
- lambda do
70
- FooApp.router.mount(:not_an_app, "/foo")
71
- end.should raise_error(Pancake::Router::RackApplicationExpected)
72
- end
73
-
74
-
75
68
  it "should not match a single segment route when only / is defined" do
76
69
  FooApp.router.add("/", :_defaults => {:root => :var}) do |e|
77
70
  Rack::Response.new("In the Root").finish
@@ -80,6 +73,36 @@ describe "stack router" do
80
73
  result = get "/not_a_route"
81
74
  result.status.should == 404
82
75
  end
76
+
77
+ describe "mounting stacks" do
78
+ before do
79
+ @stack_app = lambda{|e| Rack::Response.new("stacked up").finish}
80
+ end
81
+
82
+ it "should not imediately stackup the passed in resource" do
83
+ stack = mock("stack")
84
+ stack.should_not_receive(:stackup)
85
+ FooApp.router.mount(stack, "/stackup")
86
+ end
87
+
88
+ it "should stackup a class if it responds to stackup" do
89
+ stack = mock("stack")
90
+ stack.should_receive(:stackup).and_return(@stack_app)
91
+ FooApp.router.mount(stack, "/stackup")
92
+
93
+ @app = FooApp.stackup
94
+ result = get "/stackup"
95
+ result.body.should include("stacked up")
96
+ end
97
+
98
+ it "should activate the class with the activate option" do
99
+
100
+ end
101
+
102
+ it "should pass the given args to the class to create it" do
103
+
104
+ end
105
+ end
83
106
  end
84
107
 
85
108
  describe "generating routes" do
@@ -116,6 +139,9 @@ describe "stack router" do
116
139
  Pancake.url(FooApp, :unique_var => "unique_var").should == "/some/unique_var"
117
140
  end
118
141
 
142
+ it "should generate a base url of '/' for the top level router" do
143
+ FooApp.router.base_url.should == "/"
144
+ end
119
145
 
120
146
  describe "mounted route generation" do
121
147
  before do
@@ -125,7 +151,9 @@ describe "stack router" do
125
151
  r.add("/simple").name(:simple)
126
152
  r.add("/some/:var", :_defaults => {:var => "foo"}).name(:foo)
127
153
  end
128
- FooApp.router.mount(BarApp.stackup, "/bar")
154
+ FooApp.router.mount(BarApp, "/bar")
155
+ FooApp.router.mount_applications!
156
+ FooApp.stackup
129
157
  end
130
158
 
131
159
  it "should allow me to generate a simple nested named route" do
@@ -133,10 +161,19 @@ describe "stack router" do
133
161
  end
134
162
 
135
163
  it "should allow me to generate a simple nested named route for a named app" do
136
- FooApp.router.mount(BarApp.stackup(:app_name => :bar_app), "/different")
164
+ FooApp.router.mount(BarApp, "/different", :_args => [{:app_name => :bar_app}])
165
+ FooApp.router.mount_applications!
137
166
  Pancake.url(:bar_app, :simple).should == "/different/simple"
138
167
  Pancake.url(BarApp, :simple).should == "/bar/simple"
139
168
  end
169
+
170
+ it "should generate the base url for a mounted application" do
171
+ BarApp.configuration.router.base_url.should == "/bar"
172
+ end
173
+
174
+ it "should generate a base url for a named application" do
175
+ Pancake.base_url_for(BarApp)
176
+ end
140
177
  end
141
178
 
142
179
  end
@@ -149,6 +186,7 @@ describe "stack router" do
149
186
  INNER_APP
150
187
  end
151
188
  end
189
+ FooApp.router.mount(INNER_APP, "/some_mount")
152
190
 
153
191
  @app = FooApp.stackup
154
192
  get "/bar"
@@ -195,6 +233,7 @@ describe "stack router" do
195
233
  end
196
234
 
197
235
  class ::BarApp < FooApp; end
236
+ FooApp.router.mount_applications!
198
237
 
199
238
  Pancake.url(BarApp, :simple).should == "/simple"
200
239
  Pancake.url(BarApp, :stuff => "this_stuff").should == "/foo/this_stuff"
@@ -215,10 +254,10 @@ describe "stack router" do
215
254
  BarApp::Router.should inherit_from(FooApp::Router)
216
255
  end
217
256
 
218
- it "should grab a new copy of the router rather than instantiate an inherited one" do
257
+ it "should inherit the router class as an inner class" do
219
258
  class ::BarApp < FooApp; end
220
- FooApp.router.class.should == Pancake::Stack::Router
221
- BarApp.router.class.should == Pancake::Stack::Router
259
+ FooApp.router.class.should == FooApp::Router
260
+ BarApp.router.class.should == BarApp::Router
222
261
  end
223
262
 
224
263
  it "should reset the router to the namespaced router" do
@@ -259,7 +298,7 @@ describe "stack router" do
259
298
  end
260
299
 
261
300
  FooApp.router do |r|
262
- r.mount(BarApp.stackup, "/bar")
301
+ r.mount(BarApp, "/bar")
263
302
  r.add( "/foo" ).name(:foo)
264
303
  r.add( "/simple").name(:simple)
265
304
  end
@@ -17,6 +17,18 @@ describe Pancake::Stacks::Short::Controller do
17
17
  publish
18
18
  def index; "index"; end
19
19
 
20
+ publish
21
+ def a_rack_response
22
+ r = Rack::Response.new
23
+ r.redirect("/foo")
24
+ r
25
+ end
26
+
27
+ publish
28
+ def an_array_response
29
+ [200, {"Content-Type" => "text/plain"}, ["Custom Array Response"]]
30
+ end
31
+
20
32
  protected
21
33
  def a_protected_method; "protected"; end
22
34
 
@@ -80,6 +92,19 @@ describe Pancake::Stacks::Short::Controller do
80
92
  end.should raise_error
81
93
  end
82
94
 
95
+ it "should let me return an array as a rack response" do
96
+ @controller.params["action"] = "an_array_response"
97
+ result = @controller.do_dispatch!
98
+ result.should == [200, {"Content-Type" => "text/plain"}, ["Custom Array Response"]]
99
+ end
100
+
101
+ it "should allow me to return a Rack::Response" do
102
+ @controller.params["action"] = "a_rack_response"
103
+ result = @controller.do_dispatch!
104
+ result[0].should == 302
105
+ result[1]["Location"].should == "/foo"
106
+ end
107
+
83
108
  describe "helper in methods" do
84
109
  before do
85
110
  module PancakeTestHelper
@@ -123,6 +148,10 @@ describe Pancake::Stacks::Short::Controller do
123
148
  v[:my_data] = "some data"
124
149
  render :vault
125
150
  end
151
+
152
+ get "/redirect" do
153
+ redirect "/some_other_place"
154
+ end
126
155
  end
127
156
  end
128
157
 
@@ -156,6 +185,12 @@ describe Pancake::Stacks::Short::Controller do
156
185
  result.body.should include("some data")
157
186
  result.body.should include("In Vault")
158
187
  end
188
+
189
+ it "should redirect" do
190
+ result = get "/redirect"
191
+ result.status.should == 302
192
+ result.headers["Location"].should == "/some_other_place"
193
+ end
159
194
  end
160
195
 
161
196
  describe "accept type negotiations" do
@@ -95,7 +95,8 @@ describe Pancake::Stacks::Short, "routes" do
95
95
 
96
96
  it "should generate it's url when it's nested" do
97
97
  class ::FooApp < Pancake::Stack; end
98
- FooApp.router.mount(RoutedShortStack.stackup, "/short/stack")
98
+ FooApp.router.mount(RoutedShortStack, "/short/stack")
99
+ FooApp.router.mount_applications!
99
100
  Pancake.url(RoutedShortStack, :foo).should == "/short/stack/foo"
100
101
  Pancake.url(RoutedShortStack, :baz, :var => "var", :date => "today").should == "/short/stack/baz/var/today"
101
102
  end
@@ -127,7 +128,8 @@ describe Pancake::Stacks::Short, "routes" do
127
128
 
128
129
  it "should match the nested route without affecting the parent" do
129
130
  class ::BarApp < Pancake::Stack; end
130
- BarApp.router.mount(FooApp.stackup, "/mount/point")
131
+ BarApp.router.mount(FooApp, "/mount/point")
132
+ BarApp.router.mount_applications!
131
133
 
132
134
  Pancake.url(FooApp, :foo).should == "/mount/point/foo"
133
135
  Pancake.url(RoutedShortStack, :foo).should == "/foo"