orange 0.0.2
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/README.markdown +154 -0
- data/lib/orange.rb +7 -0
- data/lib/orange/application.rb +125 -0
- data/lib/orange/carton.rb +114 -0
- data/lib/orange/cartons/site_carton.rb +9 -0
- data/lib/orange/core.rb +197 -0
- data/lib/orange/magick.rb +91 -0
- data/lib/orange/middleware/access_control.rb +100 -0
- data/lib/orange/middleware/base.rb +41 -0
- data/lib/orange/middleware/database.rb +22 -0
- data/lib/orange/middleware/globals.rb +18 -0
- data/lib/orange/middleware/recapture.rb +19 -0
- data/lib/orange/middleware/rerouter.rb +13 -0
- data/lib/orange/middleware/restful_router.rb +59 -0
- data/lib/orange/middleware/route_context.rb +39 -0
- data/lib/orange/middleware/route_site.rb +51 -0
- data/lib/orange/middleware/show_exceptions.rb +78 -0
- data/lib/orange/middleware/site_load.rb +33 -0
- data/lib/orange/middleware/static.rb +81 -0
- data/lib/orange/middleware/static_file.rb +32 -0
- data/lib/orange/middleware/template.rb +61 -0
- data/lib/orange/model_resource.rb +170 -0
- data/lib/orange/packet.rb +88 -0
- data/lib/orange/resource.rb +37 -0
- data/lib/orange/resources/flex_router.rb +13 -0
- data/lib/orange/resources/mapper.rb +55 -0
- data/lib/orange/resources/page_parts.rb +54 -0
- data/lib/orange/resources/parser.rb +60 -0
- data/lib/orange/routable_resource.rb +16 -0
- data/lib/orange/stack.rb +201 -0
- data/spec/application_spec.rb +146 -0
- data/spec/carton_spec.rb +5 -0
- data/spec/core_spec.rb +231 -0
- data/spec/magick_spec.rb +89 -0
- data/spec/mock/mock_app.rb +17 -0
- data/spec/mock/mock_core.rb +2 -0
- data/spec/mock/mock_middleware.rb +13 -0
- data/spec/mock/mock_mixins.rb +19 -0
- data/spec/mock/mock_pulp.rb +24 -0
- data/spec/mock/mock_resource.rb +5 -0
- data/spec/mock/mock_router.rb +10 -0
- data/spec/model_resource_spec.rb +5 -0
- data/spec/orange_spec.rb +19 -0
- data/spec/packet_spec.rb +134 -0
- data/spec/resource_spec.rb +5 -0
- data/spec/resources/flex_router_spec.rb +5 -0
- data/spec/resources/mapper_spec.rb +5 -0
- data/spec/resources/parser_spec.rb +5 -0
- data/spec/routable_resource_spec.rb +5 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/stack_spec.rb +202 -0
- data/spec/stats.rb +182 -0
- metadata +194 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'orange'
|
3
|
+
require 'rack/abstract_format'
|
4
|
+
|
5
|
+
class MockApplication < Orange::Application
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
class MockApplication2 < Orange::Application
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
class MockExitware
|
14
|
+
def call(env)
|
15
|
+
raise 'Mock Exitware'
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class MockOrangeBasedMiddleware < Orange::Middleware::Base
|
2
|
+
def packet_call(packet)
|
3
|
+
raise "It's over 9000 #{@core.class.to_s}s!"
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class MockMiddleware
|
8
|
+
def initialize(app)
|
9
|
+
end
|
10
|
+
def call(env)
|
11
|
+
raise "I'm in ur #{env[:test]}"
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module MockMixinOrange1
|
2
|
+
def mixin_orange_one
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
module MockMixinOrange2
|
7
|
+
def mixin_orange_two
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module MockMixinCore1
|
12
|
+
def mixin_core_one
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module MockMixinCore2
|
17
|
+
def mixin_core_two
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MockPulpOrange1
|
2
|
+
def pulp_orange_one
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
module MockPulpOrange2
|
7
|
+
def pulp_orange_two
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module MockPulpCore1
|
12
|
+
def pulp_core_one
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module MockPulpCore2
|
17
|
+
def pulp_core_two
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module MockPulp
|
22
|
+
def my_new_mock_method
|
23
|
+
end
|
24
|
+
end
|
data/spec/orange_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
describe Orange do
|
2
|
+
it "should allow core mixin via mixin method" do
|
3
|
+
c= Orange::Core.new
|
4
|
+
c.should_not respond_to(:mixin_orange_one)
|
5
|
+
Orange.mixin MockMixinOrange1
|
6
|
+
c2= Orange::Core.new
|
7
|
+
c.should respond_to(:mixin_orange_one)
|
8
|
+
c2.should respond_to(:mixin_orange_one)
|
9
|
+
end
|
10
|
+
it "should allow pulp mixin via pulp method" do
|
11
|
+
c= Orange::Core.new
|
12
|
+
p= Orange::Packet.new(c, {})
|
13
|
+
p.should_not respond_to(:pulp_orange_one)
|
14
|
+
Orange.add_pulp MockPulpOrange1
|
15
|
+
p2= Orange::Packet.new(c, {})
|
16
|
+
p.should respond_to(:pulp_orange_one)
|
17
|
+
p2.should respond_to(:pulp_orange_one)
|
18
|
+
end
|
19
|
+
end
|
data/spec/packet_spec.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Orange::Packet do
|
4
|
+
it "should return a default header content type of html" do
|
5
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
6
|
+
p.finish[1].should have_key("Content-Type")
|
7
|
+
p.finish[1]["Content-Type"].should eql("text/html")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should not create a new object for env if one already exists" do
|
11
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
12
|
+
env = p.env
|
13
|
+
p2= Orange::Packet.new(Orange::Core.new, env)
|
14
|
+
p.should equal p2 # Exact equality - same instances
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should save core passed to it on initialization" do
|
18
|
+
c= Orange::Core.new
|
19
|
+
p= Orange::Packet.new(c, {})
|
20
|
+
p.orange.should equal c
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should save the env passed to it on init" do
|
24
|
+
p= Orange::Packet.new(Orange::Core.new, {:test => :foo})
|
25
|
+
p.env.should have_key(:test)
|
26
|
+
p.env[:test].should == :foo
|
27
|
+
p.env.should_not be_empty
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should add orange.packet and orange.env to env on init" do
|
31
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
32
|
+
p.env.should have_key('orange.packet')
|
33
|
+
p.env['orange.packet'].should equal p
|
34
|
+
p.env.should have_key('orange.env')
|
35
|
+
p.env['orange.env'].should have_key(:request)
|
36
|
+
p.env['orange.env'][:request].should be_an_instance_of(Rack::Request)
|
37
|
+
p.env['orange.env'].should have_key(:headers)
|
38
|
+
p.env['orange.env'][:headers].should be_an_instance_of(Hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have access to the orange.env through []" do
|
42
|
+
p= Orange::Packet.new(Orange::Core.new, {'orange.env' => {'foo' => :true}})
|
43
|
+
p['foo'].should == :true
|
44
|
+
p['foo'] = 'banana'
|
45
|
+
p.env['orange.env']['foo'].should == 'banana'
|
46
|
+
p['foo'].should == 'banana'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should allow defaults through [] calls" do
|
50
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
51
|
+
p['nonexistent'].should be_false
|
52
|
+
p['nonexistent', true].should be_true
|
53
|
+
p['nonexistent', true].should_not be_an_instance_of Hash
|
54
|
+
p['nonexistent', {}].should be_an_instance_of Hash
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should give access to the rack.session env" do
|
58
|
+
p= Orange::Packet.new(Orange::Core.new, {'rack.session' => 'banana'})
|
59
|
+
p.session.should == 'banana'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should give headers by combining :headers with defaults" do
|
63
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
64
|
+
p.headers.should == p[:headers, {}].with_defaults(Orange::Packet::DEFAULT_HEADERS)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should allow setting headers via header(key, val)" do
|
68
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
69
|
+
p.header('Content-Type', 'text/plain')
|
70
|
+
p.headers['Content-Type'].should == 'text/plain'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should allow adding headers with add_header" do
|
74
|
+
p1= Orange::Packet.new(Orange::Core.new, {})
|
75
|
+
p2= Orange::Packet.new(Orange::Core.new, {})
|
76
|
+
p1.add_header('Content-Type', 'text/plain')
|
77
|
+
p2.header('Content-Type', 'text/plain')
|
78
|
+
p1.headers['Content-Type'].should == p2.headers['Content-Type']
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should give access to the core object via orange" do
|
82
|
+
c= Orange::Core.new
|
83
|
+
p= Orange::Packet.new(c, {})
|
84
|
+
p.orange.should equal c
|
85
|
+
p.orange.should be_an_instance_of(Orange::Core)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should create a triple according to rack standards on #finish" do
|
89
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
90
|
+
fin = p.finish
|
91
|
+
fin[0].should be_a_kind_of Integer
|
92
|
+
fin[1].should be_a_kind_of Hash
|
93
|
+
fin[2].should be_a_kind_of Array
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should give self when using packet" do
|
97
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
98
|
+
p.packet.should equal p
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should mixin when calling mixin" do
|
102
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
103
|
+
p.should_not respond_to(:pulp_orange_two)
|
104
|
+
Orange::Packet.mixin MockPulpOrange2
|
105
|
+
p.should respond_to(:pulp_orange_two)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should raise an error if no router set" do
|
109
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
110
|
+
lambda{
|
111
|
+
p.route
|
112
|
+
}.should raise_error(RuntimeError, 'Router not found')
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should pass self to assigned router's route method" do
|
116
|
+
class MockDeathRouter
|
117
|
+
def route(p); raise "die, die, death, #{p[:lame]}"; end
|
118
|
+
end
|
119
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
120
|
+
p['route.router'] = MockDeathRouter.new
|
121
|
+
p[:lame] = 'death'
|
122
|
+
lambda{
|
123
|
+
p.route
|
124
|
+
}.should_not raise_error(RuntimeError, 'Router not found')
|
125
|
+
lambda{
|
126
|
+
p.route
|
127
|
+
}.should raise_error(RuntimeError, 'die, die, death, death')
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should give a request object" do
|
131
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
132
|
+
p.request.should be_an_instance_of Rack::Request
|
133
|
+
end
|
134
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec/mock/mock_app'
|
2
|
+
require 'spec/mock/mock_pulp'
|
3
|
+
require 'spec/mock/mock_core'
|
4
|
+
require 'spec/mock/mock_mixins'
|
5
|
+
require 'spec/mock/mock_router'
|
6
|
+
require 'spec/mock/mock_resource'
|
7
|
+
require 'spec/mock/mock_middleware'
|
8
|
+
require 'rack/test'
|
9
|
+
|
10
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
11
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
12
|
+
|
13
|
+
require 'orange'
|
14
|
+
Spec::Runner.configure do |config|
|
15
|
+
config.include(Rack::Test::Methods)
|
16
|
+
end
|
data/spec/stack_spec.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Orange::Stack do
|
4
|
+
before(:all) do
|
5
|
+
# allow deep introspection into rack builder
|
6
|
+
class Rack::Builder
|
7
|
+
attr_accessor :ins
|
8
|
+
# introspection into the Builder object's list of items
|
9
|
+
# builder uses Proc magic to chain the middleware together,
|
10
|
+
# so we undo it.
|
11
|
+
def ins_no_procs
|
12
|
+
@ins.map{|x| x.instance_of?(Proc)? x.call(nil) : x }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
class Orange::Stack
|
16
|
+
attr_accessor :build
|
17
|
+
def middlewarez
|
18
|
+
build.ins_no_procs
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def app
|
24
|
+
MockApplication.app
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should create a default stack when called by Application" do
|
28
|
+
MockApplication2.app.should be_an_instance_of(Orange::Stack)
|
29
|
+
MockApplication2.app.main_app.should be_a_kind_of(Orange::Application)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have access to core" do
|
33
|
+
MockApplication.app.orange.should be_an_instance_of(Orange::Core)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have access to the main application instance" do
|
37
|
+
MockApplication2.app.main_app.should be_an_instance_of(MockApplication2)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should have the run function" do
|
41
|
+
x= Orange::Stack.new do
|
42
|
+
run MockExitware.new
|
43
|
+
end
|
44
|
+
lambda {
|
45
|
+
x.call({:test => 'middlewarez'})
|
46
|
+
}.should raise_error(RuntimeError, "Mock Exitware")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have the use function" do
|
50
|
+
x= Orange::Stack.new do
|
51
|
+
use MockMiddleware
|
52
|
+
run MockExitware.new
|
53
|
+
end
|
54
|
+
lambda {
|
55
|
+
x.call({:test => 'middlewarez'})
|
56
|
+
}.should raise_error(RuntimeError, "I'm in ur middlewarez")
|
57
|
+
lambda {
|
58
|
+
x.call({:test => 'middlewarez'})
|
59
|
+
}.should_not raise_error(RuntimeError, "It's over 9000")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have the stack function" do
|
63
|
+
x= Orange::Stack.new do
|
64
|
+
stack MockOrangeBasedMiddleware
|
65
|
+
run MockExitware.new
|
66
|
+
end
|
67
|
+
lambda {
|
68
|
+
x.call({:test => 'middlewarez'})
|
69
|
+
}.should raise_error(RuntimeError, "It's over 9000 Orange::Cores!")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should respect order of stack/use cases" do
|
73
|
+
x= Orange::Stack.new do
|
74
|
+
use MockMiddleware
|
75
|
+
stack MockOrangeBasedMiddleware
|
76
|
+
run MockExitware.new
|
77
|
+
end
|
78
|
+
y= Orange::Stack.new do
|
79
|
+
stack MockOrangeBasedMiddleware
|
80
|
+
use MockMiddleware
|
81
|
+
run MockExitware.new
|
82
|
+
end
|
83
|
+
lambda {
|
84
|
+
x.call({:test => 'middlewarez'})
|
85
|
+
}.should raise_error(RuntimeError, "I'm in ur middlewarez")
|
86
|
+
lambda {
|
87
|
+
y.call({:test => 'middlewarez'})
|
88
|
+
}.should raise_error(RuntimeError, "It's over 9000 Orange::Cores!")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should load a resource when using load" do
|
92
|
+
x= Orange::Stack.new
|
93
|
+
x.load(MockResource.new, :test)
|
94
|
+
x.orange[:test].mock_method.should == 'MockResource#mock_method'
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should not rebuild stack if auto_reload not set" do
|
98
|
+
x= Orange::Stack.new do
|
99
|
+
run MockExitware.new
|
100
|
+
end
|
101
|
+
x.app.should eql(x.app)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should rebuild stack if auto_reload! set" do
|
105
|
+
x= Orange::Stack.new do
|
106
|
+
auto_reload!
|
107
|
+
run MockExitware.new
|
108
|
+
end
|
109
|
+
x.app.should_not eql(x.app)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should include ShowExceptions in stack if use_exceptions called" do
|
113
|
+
x= Orange::Stack.new do
|
114
|
+
use_exceptions
|
115
|
+
run MockExitware.new
|
116
|
+
end
|
117
|
+
mapped = x.middlewarez
|
118
|
+
mapped.should_not eql([])
|
119
|
+
mapped.select{|x| x.instance_of?(Orange::Middleware::ShowExceptions)}.should_not be_empty
|
120
|
+
mapped.select{|x| x.instance_of?(Orange::Middleware::ShowExceptions)}.should have(1).items
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should add middleware when calling prerouting" do
|
124
|
+
x= Orange::Stack.new do
|
125
|
+
no_recapture
|
126
|
+
run MockExitware.new
|
127
|
+
end
|
128
|
+
x.middlewarez.should have(1).middlewares
|
129
|
+
x.prerouting
|
130
|
+
x.middlewarez.should have(6).middlewares
|
131
|
+
x.middlewarez.select{|y| y.instance_of?(Rack::AbstractFormat)}.should_not be_empty
|
132
|
+
x.middlewarez.select{|y| y.instance_of?(Orange::Middleware::RouteSite)}.should_not be_empty
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should add one less middleware when calling prerouting with opt :no_abstract_format" do
|
136
|
+
x= Orange::Stack.new do
|
137
|
+
no_recapture
|
138
|
+
run MockExitware.new
|
139
|
+
end
|
140
|
+
x.middlewarez.should have(1).middlewares
|
141
|
+
x.prerouting(:no_abstract_format => true)
|
142
|
+
x.middlewarez.should have(5).middlewares
|
143
|
+
x.middlewarez.select{|y| y.instance_of?(Rack::AbstractFormat)}.should be_empty
|
144
|
+
x.middlewarez.select{|y| y.instance_of?(Orange::Middleware::RouteSite)}.should_not be_empty
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should add middleware when calling restful_routing" do
|
148
|
+
x= Orange::Stack.new do
|
149
|
+
no_recapture
|
150
|
+
run MockExitware.new
|
151
|
+
end
|
152
|
+
x.middlewarez.should have(1).middlewares
|
153
|
+
x.restful_routing
|
154
|
+
x.middlewarez.should have(2).middlewares
|
155
|
+
restfuls = x.middlewarez.select{|y| y.instance_of?(Orange::Middleware::RestfulRouter)}
|
156
|
+
restfuls.should_not be_empty
|
157
|
+
restfuls.should have(1).items
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should have not have recapture middleware for a default stack" do
|
161
|
+
x= Orange::Stack.new MockApplication
|
162
|
+
x.middlewarez.should have(1).middlewares
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should have recapture middleware by default if stack created with block" do
|
166
|
+
x= Orange::Stack.new do
|
167
|
+
run MockExitware.new
|
168
|
+
end
|
169
|
+
x.middlewarez.should have(2).middlewares
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should not include Rack::OpenID unless openid_access_control enabled" do
|
173
|
+
defined?(Rack::OpenID).should be_nil
|
174
|
+
x= Orange::Stack.new do
|
175
|
+
openid_access_control
|
176
|
+
run MockExitware.new
|
177
|
+
end
|
178
|
+
defined?(Rack::OpenID).should == "constant"
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should add middleware when calling openid_access_control" do
|
182
|
+
x= Orange::Stack.new do
|
183
|
+
no_recapture
|
184
|
+
run MockExitware.new
|
185
|
+
end
|
186
|
+
x.middlewarez.should have(1).middlewares
|
187
|
+
x.openid_access_control
|
188
|
+
x.middlewarez.should have(3).middlewares
|
189
|
+
x.middlewarez.select{|y| y.instance_of?(Rack::OpenID)}.should_not be_empty
|
190
|
+
x.middlewarez.select{|y| y.instance_of?(Orange::Middleware::AccessControl)}.should_not be_empty
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should include a module into Orange::Packet on add_pulp" do
|
194
|
+
x= Orange::Stack.new
|
195
|
+
p= Orange::Packet.new(Orange::Core.new, {})
|
196
|
+
p.should_not respond_to(:my_new_mock_method)
|
197
|
+
x.add_pulp(MockPulp)
|
198
|
+
p.should respond_to(:my_new_mock_method)
|
199
|
+
p.should be_a_kind_of(MockPulp)
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|