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.
- data/LICENSE +20 -0
- data/README.textile +95 -0
- data/Rakefile +56 -0
- data/TODO +18 -0
- data/bin/jeweler +19 -0
- data/bin/pancake-gen +17 -0
- data/bin/rubyforge +19 -0
- data/lib/pancake.rb +48 -0
- data/lib/pancake/bootloaders.rb +180 -0
- data/lib/pancake/configuration.rb +140 -0
- data/lib/pancake/core_ext/class.rb +44 -0
- data/lib/pancake/core_ext/object.rb +22 -0
- data/lib/pancake/core_ext/symbol.rb +15 -0
- data/lib/pancake/errors.rb +61 -0
- data/lib/pancake/generators.rb +8 -0
- data/lib/pancake/generators/base.rb +12 -0
- data/lib/pancake/generators/flat_generator.rb +17 -0
- data/lib/pancake/generators/short_generator.rb +17 -0
- data/lib/pancake/generators/stack_generator.rb +17 -0
- data/lib/pancake/generators/templates/common/dotgitignore +22 -0
- data/lib/pancake/generators/templates/common/dothtaccess +17 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/%stack_name%.rb.tt +8 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/.gitignore +21 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/config.ru.tt +12 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/pancake.init.tt +1 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/.gitignore +21 -0
- data/lib/pancake/generators/templates/short/%stack_name%/LICENSE.tt +20 -0
- data/lib/pancake/generators/templates/short/%stack_name%/README.tt +7 -0
- data/lib/pancake/generators/templates/short/%stack_name%/Rakefile.tt +48 -0
- data/lib/pancake/generators/templates/short/%stack_name%/VERSION.tt +1 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%.rb.tt +5 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/%stack_name%.rb.tt +6 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/pancake.init.tt +1 -0
- data/lib/pancake/generators/templates/short/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
- data/lib/pancake/generators/templates/short/%stack_name%/spec/spec_helper.rb.tt +9 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/.gitignore +21 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/LICENSE.tt +20 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/README.tt +7 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/Rakefile.tt +48 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/VERSION.tt +1 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%.rb.tt +3 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/development.rb.tt +18 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/production.rb.tt +18 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/router.rb.tt +6 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/pancake.init.tt +1 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/spec/spec_helper.rb.tt +9 -0
- data/lib/pancake/hooks/inheritable_inner_classes.rb +60 -0
- data/lib/pancake/hooks/on_inherit.rb +34 -0
- data/lib/pancake/master.rb +87 -0
- data/lib/pancake/middleware.rb +354 -0
- data/lib/pancake/mime_types.rb +265 -0
- data/lib/pancake/mixins/publish.rb +125 -0
- data/lib/pancake/mixins/publish/action_options.rb +104 -0
- data/lib/pancake/mixins/render.rb +61 -0
- data/lib/pancake/mixins/request_helper.rb +92 -0
- data/lib/pancake/mixins/stack_helper.rb +44 -0
- data/lib/pancake/mixins/url.rb +10 -0
- data/lib/pancake/more/controller.rb +4 -0
- data/lib/pancake/more/controller/base.rb +34 -0
- data/lib/pancake/paths.rb +218 -0
- data/lib/pancake/router.rb +99 -0
- data/lib/pancake/stack/app.rb +10 -0
- data/lib/pancake/stack/bootloader.rb +79 -0
- data/lib/pancake/stack/configuration.rb +44 -0
- data/lib/pancake/stack/middleware.rb +0 -0
- data/lib/pancake/stack/router.rb +18 -0
- data/lib/pancake/stack/stack.rb +57 -0
- data/lib/pancake/stacks/short.rb +2 -0
- data/lib/pancake/stacks/short/controller.rb +105 -0
- data/lib/pancake/stacks/short/stack.rb +194 -0
- data/spec/helpers/helpers.rb +20 -0
- data/spec/helpers/matchers.rb +25 -0
- data/spec/pancake/bootloaders_spec.rb +109 -0
- data/spec/pancake/configuration_spec.rb +177 -0
- data/spec/pancake/fixtures/foo_stack/pancake.init +0 -0
- data/spec/pancake/fixtures/paths/controllers/controller1.rb +0 -0
- data/spec/pancake/fixtures/paths/controllers/controller2.rb +0 -0
- data/spec/pancake/fixtures/paths/controllers/controller3.rb +0 -0
- data/spec/pancake/fixtures/paths/models/model1.rb +0 -0
- data/spec/pancake/fixtures/paths/models/model2.rb +0 -0
- data/spec/pancake/fixtures/paths/models/model3.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/controllers/controller1.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/models/model3.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view1.erb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view1.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view2.erb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view2.haml +0 -0
- data/spec/pancake/fixtures/render_templates/context_template.html.erb +1 -0
- data/spec/pancake/fixtures/render_templates/erb_template.html.erb +1 -0
- data/spec/pancake/fixtures/render_templates/erb_template.json.erb +1 -0
- data/spec/pancake/fixtures/render_templates/haml_template.html.haml +1 -0
- data/spec/pancake/fixtures/render_templates/haml_template.xml.haml +1 -0
- data/spec/pancake/hooks/on_inherit_spec.rb +65 -0
- data/spec/pancake/inheritance_spec.rb +100 -0
- data/spec/pancake/middleware_spec.rb +401 -0
- data/spec/pancake/mime_types_spec.rb +234 -0
- data/spec/pancake/mixins/publish_spec.rb +94 -0
- data/spec/pancake/mixins/render_spec.rb +55 -0
- data/spec/pancake/mixins/stack_helper_spec.rb +46 -0
- data/spec/pancake/pancake_spec.rb +31 -0
- data/spec/pancake/paths_spec.rb +210 -0
- data/spec/pancake/stack/app_spec.rb +28 -0
- data/spec/pancake/stack/bootloader_spec.rb +41 -0
- data/spec/pancake/stack/middleware_spec.rb +0 -0
- data/spec/pancake/stack/router_spec.rb +266 -0
- data/spec/pancake/stack/stack_configuration_spec.rb +101 -0
- data/spec/pancake/stack/stack_spec.rb +55 -0
- data/spec/pancake/stacks/short/controller_spec.rb +287 -0
- data/spec/pancake/stacks/short/router_spec.rb +132 -0
- data/spec/pancake/stacks/short/stack_spec.rb +40 -0
- data/spec/spec_helper.rb +21 -0
- 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
|