lego-core 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,188 @@
1
+ require File.join('spec', '/spec_helper')
2
+
3
+ describe Lego::Controller::RouteHandler do
4
+
5
+ context '.match_all_routes with matching route' do
6
+ before do
7
+ @route_handler = empty_route_handler
8
+ @env = {}
9
+ @env["REQUEST_METHOD"] = 'GET'
10
+ @valid_route = {:path => '/myadmin'}
11
+ @other_route = {:path => '/foo'}
12
+ @fake_routes = {:get => [@other_route, @other_route, @valid_route], :post => [{}]}
13
+ end
14
+
15
+ it 'should return matching route if found' do
16
+ @route_handler.should_receive(:routes).and_return(@fake_routes)
17
+ @route_handler.should_receive(:run_matchers).with(@other_route, @env).exactly(2).times.and_return(false)
18
+ @route_handler.should_receive(:run_matchers).with(@valid_route, @env).and_return(true)
19
+ @route_handler.match_all_routes(@env).should eql(@valid_route)
20
+ end
21
+
22
+ it 'should return false when no matching route is found' do
23
+ @route_handler.should_receive(:routes).and_return({:get=> [{}]})
24
+ @route_handler.should_receive(:run_matchers).and_return(false)
25
+ @route_handler.match_all_routes(@env).should eql(nil)
26
+ end
27
+ end
28
+
29
+ context '.run_matchers' do
30
+ before do
31
+ @route_handler = empty_route_handler
32
+ @env = {}
33
+ @route = { :path => '/mypath' }
34
+ module Match1; end
35
+ module Match2; end
36
+ @matchers = [Match1, Match2]
37
+ end
38
+
39
+ it 'should return true when matching route found' do
40
+ Match1.should_receive(:match_route).with(@route, @env).and_return(false)
41
+ Match2.should_receive(:match_route).with(@route, @env).and_return(true)
42
+ @route_handler.should_receive(:matchers).and_return(@matchers)
43
+ @route_handler.run_matchers(@route, @env).should eql(true)
44
+ end
45
+
46
+ it 'should return false when no matching route found' do
47
+ Match1.should_receive(:match_route).with(@route, @env).and_return(false)
48
+ Match2.should_receive(:match_route).with(@route, @env).and_return(false)
49
+ @route_handler.should_receive(:matchers).and_return(@matchers)
50
+ @route_handler.run_matchers(@route, @env).should eql(false)
51
+ end
52
+ end
53
+
54
+ context '.routes' do
55
+ before do
56
+ @route_handler = empty_route_handler
57
+ end
58
+
59
+ it 'should return empty routes when new' do
60
+ @route_handler.routes.should eql({
61
+ :get => [],
62
+ :post => [],
63
+ :put => [],
64
+ :head => [],
65
+ :delete => [],
66
+ :not_found => nil
67
+ })
68
+ end
69
+ end
70
+
71
+ context '.add_route' do
72
+ before do
73
+ @route_handler = empty_route_handler
74
+ end
75
+
76
+ it 'should appen routes with their options' do
77
+ route_options1 = { :path => '/a_path1' }
78
+ route_options2 = { :path => '/a_path2' }
79
+ @route_handler.add_route(:get, route_options1)
80
+ @route_handler.add_route(:get, route_options2)
81
+ @route_handler.routes[:get].should eql([route_options1, route_options2])
82
+ end
83
+
84
+ it 'should set not_found route if method is :not_found' do
85
+ route_options = { :action_block => '{block}' }
86
+ @route_handler.add_route(:not_found, route_options)
87
+ @route_handler.routes[:not_found].should eql(route_options)
88
+ end
89
+ end
90
+
91
+ context '.matchers' do
92
+ before do
93
+ @route_handler = empty_route_handler
94
+ end
95
+
96
+ it 'should return an empty Array when new' do
97
+ @route_handler.matchers.should eql([])
98
+ end
99
+
100
+ end
101
+
102
+ context '.add_matcher' do
103
+ before do
104
+ @route_handler = empty_route_handler
105
+ module ValidMatcher; def self.match_route(route, env); end; end
106
+ module BrokenMatcher; end
107
+ end
108
+
109
+ it 'should store route matchers if valid' do
110
+ @route_handler.add_matcher(ValidMatcher)
111
+ @route_handler.matchers.should eql([ValidMatcher])
112
+ end
113
+
114
+ it 'should raise InvalidMatcher error if invalid' do
115
+ @route_handler.should_receive(:validate_matcher).and_return(false)
116
+ lambda { @route_handler.add_matcher(BrokenMatcher) }.should raise_error(Lego::Controller::RouteHandler::InvalidMatcher)
117
+ @route_handler.matchers.should == []
118
+ end
119
+ end
120
+
121
+ context '.validate_matcher' do
122
+ before do
123
+ @route_handler = empty_route_handler
124
+ module MyBrokenMatcher; end
125
+ module MyValidMatcher; def self.match_route(); end; end
126
+ end
127
+
128
+ it 'should return true if a valid Matcher module' do
129
+ @route_handler.validate_matcher(MyValidMatcher).should be_true
130
+ end
131
+
132
+ it 'should return false if not a valid Matcher module' do
133
+ @route_handler.validate_matcher(MyBrokenMatcher).should be_false
134
+ end
135
+ end
136
+
137
+ context 'when extended' do
138
+ before do
139
+ reset_lego_base
140
+ end
141
+ it 'plugins should be copied from base class' do
142
+
143
+ module GlobalPlug
144
+ def self.register(lego)
145
+ lego.add_plugin :router, self
146
+ end
147
+
148
+ def another_routehandler
149
+ add_route(:get, {})
150
+ end
151
+
152
+ def self.match_route(route, env); end
153
+ end
154
+
155
+ # Create two fake plugins
156
+ Object.const_set(:App1Plug, GlobalPlug.clone)
157
+ Object.const_set(:App2Plug, GlobalPlug.clone)
158
+
159
+ Lego.plugin GlobalPlug
160
+
161
+ create_new_app("MyApp1", Lego::Controller)
162
+ create_new_app("MyApp2", Lego::Controller)
163
+
164
+ MyApp1.plugin App1Plug
165
+ MyApp2.plugin App2Plug
166
+
167
+ Lego::Controller::RouteHandler.matchers.should eql([GlobalPlug])
168
+ MyApp1::RouteHandler.matchers.should eql([GlobalPlug, App1Plug])
169
+ MyApp2::RouteHandler.matchers.should eql([GlobalPlug, App2Plug])
170
+ end
171
+
172
+ after do
173
+ rm_const "GlobalPlug", "App1Plug", "App2Plug", "MyApp1", "MyApp2"
174
+ end
175
+ end
176
+
177
+ end
178
+
179
+ def empty_route_handler
180
+ route_handler = Lego::Controller::RouteHandler.clone
181
+ route_handler.class_eval "remove_instance_variable :@route_cache if @route_cache"
182
+ route_handler.class_eval "remove_instance_variable :@matcher_cache if @matcher_cache"
183
+ route_handler
184
+ end
185
+
186
+
187
+
188
+
@@ -0,0 +1,297 @@
1
+ require File.join('spec', '/spec_helper')
2
+
3
+ describe Lego::Controller do
4
+
5
+ it 'should contain an ActionContext Class' do
6
+ Lego::Controller::ActionContext.should be_kind_of(Class)
7
+ end
8
+
9
+ it 'should contain an RouteHandler Module' do
10
+ Lego::Controller::RouteHandler.should be_kind_of(Module)
11
+ end
12
+
13
+ it 'should load Lego::Plugin::Controller::NotFound by default' do
14
+ Lego::Controller.methods.should include('not_found')
15
+ end
16
+
17
+ context 'when inherited' do
18
+ before do
19
+ create_new_app("MyController", Lego::Controller)
20
+ end
21
+
22
+ it 'should create a new ActionContext for the inheriting class' do
23
+ MyController::ActionContext.object_id.should_not == Lego::Controller::ActionContext.object_id
24
+ end
25
+
26
+ it 'should setup a constant on ActionContext holding a reference to the application class' do
27
+ MyController::ActionContext::ApplicationClass.should eql(MyController)
28
+ end
29
+
30
+ it 'should create a new RouteHandler for the inheriting class' do
31
+ MyController::RouteHandler.object_id.should_not == Lego::Controller::RouteHandler.object_id
32
+ end
33
+
34
+ it 'should create a new Config for the inheriting class' do
35
+ MyController::Config.object_id.should_not == Lego::Controller::Config.object_id
36
+ end
37
+
38
+ it 'should create a new Config for every inheriting class' do
39
+ create_new_app "MyOtherController", Lego::Controller
40
+ MyController::Config.object_id.should_not == MyOtherController::Config.object_id
41
+ end
42
+ end
43
+
44
+ context '.plugin <plugin_module>' do
45
+ before do
46
+ create_new_app("MyApp", Lego::Controller)
47
+ module MyPlugin
48
+ def self.register(lego)
49
+ lego.register self
50
+ end
51
+ end
52
+ end
53
+
54
+ after do
55
+ rm_const "MyPlugin", "MyApp"
56
+ end
57
+
58
+ it 'should have a class method named plugin' do
59
+ MyApp.should respond_to(:plugin)
60
+ end
61
+
62
+ it 'should call self.register on <plugin_module>' do
63
+ MyPlugin.should_receive(:register).with(MyApp)
64
+ MyApp.plugin MyPlugin
65
+ end
66
+ end
67
+
68
+ context '.add_plugin :view, <plugin_module>' do
69
+ before do
70
+ create_new_app("MyApp", Lego::Controller)
71
+ module MyViewPlugin
72
+ def self.register(lego)
73
+ lego.add_plugin :view, self
74
+ end
75
+ def makebold(content)
76
+ "<b>#{content}</b>"
77
+ end
78
+ end
79
+ end
80
+
81
+ it 'should make plugin methods availibe to ActionContext' do
82
+ MyApp::ActionContext.instance_methods.should_not include('makebold')
83
+ MyApp.plugin MyViewPlugin
84
+ MyApp::ActionContext.instance_methods.should include('makebold')
85
+ end
86
+
87
+ after do
88
+ rm_const "MyViewPlugin", "MyApp"
89
+ end
90
+ end
91
+
92
+ context '.add_plugin :controller, <plugin_module>' do
93
+ before do
94
+ create_new_app("MyApp", Lego::Controller)
95
+ module MyPlugin2
96
+ def self.register(lego)
97
+ lego.add_plugin :controller, PluginMethods
98
+ end
99
+ module PluginMethods
100
+ def get_this;end
101
+ end
102
+ end
103
+ end
104
+
105
+ after do
106
+ rm_const "MyPlugin2", "MyApp"
107
+ end
108
+
109
+ it 'should extend controller with <plugin_module>' do
110
+ MyApp.should_not respond_to(:get_this)
111
+ MyApp.plugin MyPlugin2
112
+ MyApp.should respond_to(:get_this)
113
+ end
114
+ end
115
+
116
+ context '.add_route <method> <route>' do
117
+ before do
118
+ create_new_app("MyApp", Lego::Controller)
119
+ end
120
+
121
+ it 'should be defined' do
122
+ MyApp.should respond_to(:add_route)
123
+ end
124
+
125
+ it 'should add a route to RouteHandler' do
126
+ route = {:path => '/somewhere'}
127
+ method = :get
128
+ MyApp::RouteHandler.should_receive(:add_route).with(method, route)
129
+ MyApp.add_route(method, route)
130
+ end
131
+ after { rm_const 'MyApp' }
132
+ end
133
+
134
+ context '.add_plugin :router, <plugin_module>' do
135
+ before do
136
+ create_new_app("MyApp", Lego::Controller)
137
+ module MyRouter
138
+ def self.register(lego)
139
+ lego.add_plugin :router, RouterMethods
140
+ end
141
+ module RouterMethods
142
+ extend self
143
+ def match_route
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ after do
150
+ rm_const "MyRouter", "MyApp"
151
+ end
152
+
153
+ it 'should not extend controller with <plugin_module>' do
154
+ MyApp.plugin MyRouter
155
+ MyApp.should_not respond_to(:match_route)
156
+ end
157
+
158
+ it 'should call add_matcher on RouteHandler with <plugin_module>' do
159
+ MyApp::RouteHandler.should_receive(:add_matcher).with(MyRouter::RouterMethods)
160
+ MyApp.plugin MyRouter
161
+ end
162
+ end
163
+
164
+ context '.call <env>' do
165
+ context 'with a route that matches' do
166
+ before do
167
+ @env = ["Environment"]
168
+ create_new_app("MyApp", Lego::Controller)
169
+ MyApp::RouteHandler.should_receive(:match_all_routes).with(@env).and_return("route")
170
+ end
171
+
172
+ it 'should create a new instance of ActionContext' do
173
+ mock = mock("ActionContext instance")
174
+ mock.should_receive(:run).with("route", @env)
175
+ MyApp::ActionContext.should_receive(:new).and_return(mock)
176
+ end
177
+
178
+ after do
179
+ MyApp.call(@env)
180
+ rm_const "MyApp"
181
+ end
182
+ end
183
+
184
+ context 'with a route that don\'t matches' do
185
+ before do
186
+ @env = ["Environment"]
187
+ create_new_app("MyApp", Lego::Controller)
188
+ MyApp::RouteHandler.should_receive(:match_all_routes).with(@env).and_return(nil)
189
+ end
190
+
191
+ it 'should create a new instance of ActionContext' do
192
+ MyApp::ActionContext.should_not_receive(:new)
193
+ end
194
+
195
+ after do
196
+ MyApp.call(@env).should eql(
197
+ [404, {'Content-Type' => 'text/html'}, '404 - Not found']
198
+ )
199
+ rm_const "MyApp"
200
+ end
201
+ end
202
+
203
+ context 'without matching route and a :not_found route defined' do
204
+ before do
205
+ @env = ["Rack Env"]
206
+ @routes = { :not_found => {}}
207
+ create_new_app("MyApp", Lego::Controller)
208
+ MyApp::RouteHandler.should_receive(:match_all_routes).with(@env).and_return(nil)
209
+ MyApp::RouteHandler.should_receive(:routes).and_return( @routes )
210
+ end
211
+
212
+ it 'should create a new ActionContext with the :not_found route' do
213
+ action_context = mock("ActionContext instance")
214
+ MyApp::ActionContext.should_receive(:new).and_return(action_context)
215
+ action_context.should_receive(:run).with(@routes[:not_found], @env)
216
+ end
217
+
218
+ after do
219
+ MyApp.call(@env)
220
+ rm_const "MyApp"
221
+ end
222
+ end
223
+ end
224
+
225
+ context ".set" do
226
+ context 'on Lego::Controller' do
227
+
228
+ it "should proxy the method call to its own Config" do
229
+ Lego::Controller::Config.should_receive(:set).and_return(nil)
230
+ Lego::Controller.set :foo => "bar"
231
+ end
232
+ end
233
+
234
+ context "on subclasses" do
235
+
236
+ before do
237
+ create_new_app "MyApp", Lego::Controller
238
+ end
239
+
240
+ it "should proxy the method call to its own Confg" do
241
+ MyApp::Config.should_receive(:set).and_return(nil)
242
+ MyApp.set :foo => "bar"
243
+ end
244
+
245
+ after do
246
+ rm_const "MyApp"
247
+ end
248
+ end
249
+ end
250
+
251
+ context ".environment <env>" do
252
+
253
+ context 'on Lego::Controller' do
254
+
255
+ before do
256
+ @config_block = lambda {}
257
+ end
258
+
259
+ it 'should proxy the method call to its own config' do
260
+ Lego::Controller::Config.should_receive(:environment).with(nil, &@config_block).and_return(nil)
261
+ Lego::Controller.environment(&@config_block)
262
+ end
263
+
264
+ it 'take an optional <env> argument' do
265
+ Lego::Controller::Config.should_receive(:environment).
266
+ with('development', &@config_block).
267
+ and_return(nil)
268
+
269
+ Lego::Controller.environment('development', &@config_block)
270
+ end
271
+
272
+ it 'should raise an ArgumentError if no block is provided' do
273
+ lambda {
274
+ Lego::Controller.environment(:development)
275
+ }.should raise_error(ArgumentError, "No block provided")
276
+ end
277
+ end
278
+
279
+ context 'on subclasses' do
280
+
281
+ before do
282
+ create_new_app "MyApp", Lego::Controller
283
+ @config_block = lambda {}
284
+ end
285
+
286
+ it 'should proxy the method call to its own config' do
287
+ MyApp::Config.should_receive(:environment).with(nil, &@config_block).and_return(nil)
288
+ MyApp.environment(&@config_block)
289
+ end
290
+
291
+ after do
292
+ rm_const "MyApp"
293
+ end
294
+ end
295
+ end
296
+ end
297
+