pancake 0.1.10 → 0.1.12

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 (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"