lego-core 0.0.2 → 0.0.3

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.
@@ -52,7 +52,7 @@ It's all about the bits an pieces!
52
52
 
53
53
  module Matcher
54
54
  def self.match_route(route, env)
55
- (route[:path] == env['PATH_INFO']) ? true : false
55
+ (route[:path] == env['PATH_INFO']) ? [env, {}] : false
56
56
  end
57
57
  end
58
58
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -14,7 +14,7 @@ module BasicRoutes
14
14
 
15
15
  module RouteMatcher
16
16
  def self.match_route(route, env)
17
- (route[:path] == env['PATH_INFO']) ? true : false
17
+ (route[:path] == env['PATH_INFO']) ? [env, {}] : false
18
18
  end
19
19
  end
20
20
  end
@@ -26,8 +26,9 @@ module RegexpMatcher
26
26
 
27
27
  def self.match_route(route, env)
28
28
  if route[:path].is_a?(Regexp) && match = route[:path].match(env['PATH_INFO'])
29
- route[:instance_vars] = { :caps => match.captures }
30
- true
29
+ match_data = {}
30
+ match_data[:instance_vars] = { :caps => match.captures }
31
+ [env, match_data]
31
32
  else
32
33
  false
33
34
  end
@@ -45,11 +46,12 @@ module SymbolExtractor
45
46
  if matches.size > 0
46
47
  exp = Regexp.escape( route[:path] ).gsub(/:([\w]+)/, "([\\w]+)")
47
48
  if match = Regexp.new("^#{exp}$").match(env["PATH_INFO"])
48
- route[:instance_vars] = {} if route[:instance_vars].nil?
49
+ match_data = {}
50
+ match_data[:instance_vars] = {}
49
51
  1.upto(matches.size) do |i|
50
- route[:instance_vars][matches[i-1]] = match.captures[i-1]
52
+ match_data[:instance_vars][matches[i-1]] = match.captures[i-1]
51
53
  end
52
- return true
54
+ return [env, match_data]
53
55
  end
54
56
  end
55
57
  false
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'lego-modules'
3
+ require 'lego-core'
4
+ require 'erb'
5
+
6
+ # Global options
7
+ Lego.config do
8
+ plugin SimpleRouter
9
+ set :views => "./"
10
+ end
11
+
12
+ class MyApp < Lego::Controller
13
+
14
+ # Load our Erb plugin for this controller.
15
+ plugin ViewHelpers
16
+
17
+ get '/' do
18
+ redirect_to '/hello'
19
+ end
20
+
21
+ get '/hello' do
22
+ # Setup a instance var for our template to use...
23
+ @title = "Hello, right now it's:"
24
+ # Render our ERB template hello.erb found in the templates folder.
25
+ @userinput = "<b>hello bold</b>"
26
+ erb :hello
27
+ end
28
+
29
+ end
30
+
31
+ # Makes Rack run our app
32
+ run MyApp
@@ -0,0 +1,5 @@
1
+ <%= h1 @title %>
2
+
3
+ <p><%= Time.new %></p>
4
+
5
+ <p>...and here is some user input: <%=h @userinput %></p>
@@ -0,0 +1,47 @@
1
+ module SimpleRouter
2
+ def self.register(lego)
3
+ lego.add_plugin :router, RouteMatcher
4
+ lego.add_plugin :controller, RouteHandler
5
+ end
6
+
7
+ module RouteHandler
8
+ def get(path, &block)
9
+ add_route(:get, {:path => path, :action_block => block})
10
+ end
11
+ end
12
+
13
+ module RouteMatcher
14
+ def self.match_route(route, env)
15
+ (route[:path] == env['PATH_INFO']) ? [env, {}] : false
16
+ end
17
+ end
18
+ end
19
+
20
+ module ViewHelpers
21
+ def self.register(lego)
22
+ lego.add_plugin :view, View
23
+ end
24
+
25
+ module View
26
+ def redirect_to(path)
27
+ @response[:code] = 301
28
+ @response[:headers].merge!({'Location', path})
29
+ ""
30
+ end
31
+
32
+ def h1(content)
33
+ "<h1>#{content}</h1>"
34
+ end
35
+
36
+ def h(s)
37
+ html_escape = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;' }
38
+ s.to_s.gsub(/[&"><]/) { |special| html_escape[special] }
39
+ end
40
+
41
+ def erb(template, bind = binding)
42
+ path = options(:views) || "#{File.dirname(__file__)/views}"
43
+ template = File.read("#{path}/#{template}.erb") if template.is_a? Symbol
44
+ ERB.new(template).result(bind)
45
+ end
46
+ end
47
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{lego-core}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Mathias Stjernstr\303\266m", "Patrik Hedman"]
12
- s.date = %q{2010-01-12}
12
+ s.date = %q{2010-01-13}
13
13
  s.description = %q{It's all about the bits and peices}
14
14
  s.email = %q{mathias@globalinn.com}
15
15
  s.extra_rdoc_files = [
@@ -21,6 +21,9 @@ Gem::Specification.new do |s|
21
21
  "Rakefile",
22
22
  "VERSION",
23
23
  "examples/config.ru",
24
+ "examples/sample_with_plugins/config.ru",
25
+ "examples/sample_with_plugins/hello.erb",
26
+ "examples/sample_with_plugins/lego-modules.rb",
24
27
  "lego-core.gemspec",
25
28
  "lib/lego-core.rb",
26
29
  "lib/lego/controller.rb",
@@ -54,7 +57,8 @@ Gem::Specification.new do |s|
54
57
  "spec/lego/plugin/controller/not_found_spec.rb",
55
58
  "spec/lego/plugin_spec.rb",
56
59
  "spec/lego_spec.rb",
57
- "spec/spec_helper.rb"
60
+ "spec/spec_helper.rb",
61
+ "examples/sample_with_plugins/lego-modules.rb"
58
62
  ]
59
63
 
60
64
  if s.respond_to? :specification_version then
@@ -140,11 +140,11 @@ class Lego::Controller
140
140
  #
141
141
 
142
142
  def call(env)
143
- if route = self::RouteHandler.match_all_routes(env)
144
- self::ActionContext.new.run(route, env)
143
+ if match_data = self::RouteHandler.match_all_routes(env)
144
+ self::ActionContext.new.run(match_data)
145
145
  else
146
146
  if route = self::RouteHandler.routes[:not_found]
147
- self::ActionContext.new.run(route, env)
147
+ self::ActionContext.new.run([route, env, { :set_response_code => 404 }])
148
148
  else
149
149
  [404, {'Content-Type' => 'text/html'}, '404 - Not found']
150
150
  end
@@ -3,7 +3,7 @@
3
3
 
4
4
  class Lego::Controller::ActionContext
5
5
 
6
- attr_accessor :response, :env, :route
6
+ attr_accessor :response, :env, :route, :match_data
7
7
 
8
8
  def initialize
9
9
  setup_defaults
@@ -13,9 +13,8 @@ class Lego::Controller::ActionContext
13
13
  "#{self.class::ApplicationClass.current_config.options(key)}"
14
14
  end
15
15
 
16
- def run(route, env)
17
- @route = route
18
- @env = env
16
+ def run(match_data)
17
+ @route, @env, @match_data = match_data
19
18
  setup_instance_vars_from_route
20
19
  evaluate_action
21
20
  [@response[:code], @response[:headers], @response[:body]]
@@ -29,10 +28,10 @@ private
29
28
  #
30
29
 
31
30
  def setup_instance_vars_from_route
32
- @route[:instance_vars].each_key do |var|
33
- instance_variable_set("@#{var}", @route[:instance_vars][var])
34
- end if @route[:instance_vars]
35
- @response[:code] = @route[:set_response_code] if @route[:set_response_code]
31
+ @match_data[:instance_vars].each_key do |var|
32
+ instance_variable_set("@#{var}", @match_data[:instance_vars][var])
33
+ end if @match_data[:instance_vars]
34
+ @response[:code] = @match_data[:set_response_code] if @match_data[:set_response_code]
36
35
  end
37
36
 
38
37
  #
@@ -16,7 +16,6 @@ module Lego::Controller::RouteHandler
16
16
 
17
17
  def extended(base)
18
18
  base.matchers.concat(matchers)
19
- base.routes.merge!(routes)
20
19
  end
21
20
 
22
21
  def add_route(method, options)
@@ -50,7 +49,8 @@ module Lego::Controller::RouteHandler
50
49
 
51
50
  def run_matchers(route, env)
52
51
  matchers.each do |matcher|
53
- return true if matcher.match_route(route, env) == true
52
+ match = matcher.match_route(route, env)
53
+ return match if match.kind_of?(Array)
54
54
  end
55
55
  false
56
56
  end
@@ -58,7 +58,9 @@ module Lego::Controller::RouteHandler
58
58
  def match_all_routes(env)
59
59
  method = extract_method_from_env(env)
60
60
  routes[method].each do |route|
61
- return route if run_matchers(route, env)
61
+ if match_data = run_matchers(route, env)
62
+ return [route] | match_data
63
+ end
62
64
  end
63
65
  nil
64
66
  end
@@ -48,7 +48,8 @@ describe 'Full stack request' do
48
48
  end
49
49
  module Matcher
50
50
  def self.match_route(route, env)
51
- (route[:path] == env['PATH_INFO']) ? true : false
51
+ match_data = { :instance_vars => { :foo => "bar" }}
52
+ (route[:path] == env['PATH_INFO']) ? [env, match_data] : false
52
53
  end
53
54
  end
54
55
  end
@@ -57,7 +58,7 @@ describe 'Full stack request' do
57
58
 
58
59
  class App1 < Lego::Controller
59
60
  get '/hello' do
60
- h1 'Hello world'
61
+ h1 "Hello world, #{@foo}"
61
62
  end
62
63
  end
63
64
 
@@ -71,7 +72,7 @@ describe 'Full stack request' do
71
72
  it 'should respond with with valid data' do
72
73
  @result[0].should eql(200)
73
74
  @result[1].should eql({"Content-Type"=>"text/html"})
74
- @result[2].should eql('<h1>Hello world</h1>')
75
+ @result[2].should eql('<h1>Hello world, bar</h1>')
75
76
  end
76
77
 
77
78
  after do
@@ -9,17 +9,17 @@ describe Lego::Controller::ActionContext do
9
9
 
10
10
  it 'should set the current message body' do
11
11
  @instance.response[:body] = "Hello again"
12
- @instance.run({},nil).should eql([ 200, {"Content-Type"=>"text/html"}, 'Hello again' ])
12
+ @instance.run([{},nil, {}]).should eql([ 200, {"Content-Type"=>"text/html"}, 'Hello again' ])
13
13
  end
14
14
 
15
15
  it 'should set response headers' do
16
16
  @instance.response[:headers] = {'Content-Type' => 'cust/head'}
17
- @instance.run({},nil).should eql([ 200, {"Content-Type"=>"cust/head"}, '' ])
17
+ @instance.run([{},nil, {}]).should eql([ 200, {"Content-Type"=>"cust/head"}, '' ])
18
18
  end
19
19
 
20
20
  it 'should set response code' do
21
21
  @instance.response[:code] = 666
22
- @instance.run({},nil).should eql([ 666, {"Content-Type"=>"text/html"}, '' ])
22
+ @instance.run([{},nil,{}]).should eql([ 666, {"Content-Type"=>"text/html"}, '' ])
23
23
  end
24
24
  end
25
25
 
@@ -30,23 +30,25 @@ describe Lego::Controller::ActionContext do
30
30
  end
31
31
 
32
32
  it 'should have a default Rack response' do
33
- @instance.run("", @env).should eql([200, {'Content-Type' => 'text/html'} , ''])
33
+ @instance.run(["", @env, {}]).should eql([200, {'Content-Type' => 'text/html'} , ''])
34
34
  end
35
35
 
36
36
  it 'should evaluate :action_block in instance if exists in route' do
37
37
  route = { :action_block => Proc.new{ "Hello my world!" }}
38
- @instance.run(route, @env).should eql([200, {'Content-Type' => 'text/html'} , "Hello my world!" ])
38
+ @instance.run([route, @env, {}]).should eql([200, {'Content-Type' => 'text/html'} , "Hello my world!" ])
39
39
  end
40
40
 
41
41
  it 'should convert route[:instance_vars] to instance variables' do
42
- route = { :instance_vars => { :myvar => "This is my var" } }
43
- @instance.run(route, @env).should eql([200, {'Content-Type' => 'text/html'} , '' ])
42
+ route = {}
43
+ match_data = { :instance_vars => { :myvar => "This is my var" } }
44
+ @instance.run([route, @env, match_data]).should eql([200, {'Content-Type' => 'text/html'} , '' ])
44
45
  @instance.instance_variable_get(:@myvar).should eql("This is my var")
45
46
  end
46
47
 
47
48
  it 'should set response[:code] if set_response_route is set in route' do
48
- route = { :set_response_code => 666 }
49
- @instance.run(route, @env).should eql([666, {'Content-Type' => 'text/html'} , '' ])
49
+ route = {}
50
+ route_match = { :set_response_code => 666 }
51
+ @instance.run([route, @env, route_match]).should eql([666, {'Content-Type' => 'text/html'} , '' ])
50
52
  end
51
53
  end
52
54
 
@@ -61,7 +63,7 @@ describe Lego::Controller::ActionContext do
61
63
  it 'should evaluate :action_block in instance if exists in route' do
62
64
  Lego::Controller.set :foo => "bar"
63
65
  route = { :action_block => Proc.new{ options(:foo) }}
64
- @instance.run(route, @env).should eql([200, {'Content-Type' => 'text/html'} , "bar" ])
66
+ @instance.run([route, @env, {}]).should eql([200, {'Content-Type' => 'text/html'} , "bar" ])
65
67
  end
66
68
 
67
69
  after do
@@ -12,11 +12,11 @@ describe Lego::Controller::RouteHandler do
12
12
  @fake_routes = {:get => [@other_route, @other_route, @valid_route], :post => [{}]}
13
13
  end
14
14
 
15
- it 'should return matching route if found' do
15
+ it 'should return Array matching route found' do
16
16
  @route_handler.should_receive(:routes).and_return(@fake_routes)
17
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)
18
+ @route_handler.should_receive(:run_matchers).with(@valid_route, @env).and_return([@env, [:var => "some var"]])
19
+ @route_handler.match_all_routes(@env).should eql( [@valid_route, @env, [:var => "some var"]] )
20
20
  end
21
21
 
22
22
  it 'should return false when no matching route is found' do
@@ -36,11 +36,11 @@ describe Lego::Controller::RouteHandler do
36
36
  @matchers = [Match1, Match2]
37
37
  end
38
38
 
39
- it 'should return true when matching route found' do
39
+ it 'should return Array when matching route found' do
40
40
  Match1.should_receive(:match_route).with(@route, @env).and_return(false)
41
- Match2.should_receive(:match_route).with(@route, @env).and_return(true)
41
+ Match2.should_receive(:match_route).with(@route, @env).and_return([@env, { :var => "a var"}])
42
42
  @route_handler.should_receive(:matchers).and_return(@matchers)
43
- @route_handler.run_matchers(@route, @env).should eql(true)
43
+ @route_handler.run_matchers(@route, @env).should eql([@env, { :var => "a var"}])
44
44
  end
45
45
 
46
46
  it 'should return false when no matching route found' do
@@ -88,6 +88,38 @@ describe Lego::Controller::RouteHandler do
88
88
  end
89
89
  end
90
90
 
91
+ context '.add_route with global plugins' do
92
+ before do
93
+ module RouterPlugin
94
+ reset_lego_base
95
+ def self.register(lego)
96
+ lego.add_plugin(:controller, self)
97
+ end
98
+ def get(path)
99
+ add_route(:get, {:path => path})
100
+ end
101
+ end
102
+ Lego.plugin RouterPlugin
103
+
104
+ class App1 < Lego::Controller
105
+ get('/app1')
106
+ end
107
+
108
+ class App2 < Lego::Controller
109
+ get('/app2')
110
+ end
111
+ end
112
+
113
+ it 'should not share routes between apps' do
114
+ App1::RouteHandler.routes[:get].should eql([:path => "/app1"])
115
+ App2::RouteHandler.routes[:get].should eql([:path => "/app2"])
116
+ end
117
+
118
+ after do
119
+ rm_const 'App1', 'App2'
120
+ end
121
+ end
122
+
91
123
  context '.matchers' do
92
124
  before do
93
125
  @route_handler = empty_route_handler
@@ -165,13 +165,15 @@ describe Lego::Controller do
165
165
  context 'with a route that matches' do
166
166
  before do
167
167
  @env = ["Environment"]
168
+ @match_data = [:foo => "bar"]
169
+ @match_route = [:route => "route"]
168
170
  create_new_app("MyApp", Lego::Controller)
169
- MyApp::RouteHandler.should_receive(:match_all_routes).with(@env).and_return("route")
171
+ MyApp::RouteHandler.should_receive(:match_all_routes).with(@env).and_return([@match_route, @env, @match_data])
170
172
  end
171
173
 
172
174
  it 'should create a new instance of ActionContext' do
173
175
  mock = mock("ActionContext instance")
174
- mock.should_receive(:run).with("route", @env)
176
+ mock.should_receive(:run).with([@match_route, @env, @match_data])
175
177
  MyApp::ActionContext.should_receive(:new).and_return(mock)
176
178
  end
177
179
 
@@ -181,45 +183,45 @@ describe Lego::Controller do
181
183
  end
182
184
  end
183
185
 
184
- context 'with a route that don\'t matches' do
186
+ context 'without a route match and a not_found route defined' do
185
187
  before do
186
- @env = ["Environment"]
188
+ @env = []
189
+ @block = lambda { "404, gone." }
187
190
  create_new_app("MyApp", Lego::Controller)
188
191
  MyApp::RouteHandler.should_receive(:match_all_routes).with(@env).and_return(nil)
192
+ MyApp::RouteHandler.should_receive('routes').and_return({:not_found => { :action_block => @block }})
189
193
  end
190
194
 
191
- it 'should create a new instance of ActionContext' do
192
- MyApp::ActionContext.should_not_receive(:new)
195
+ it 'should get a valid 404 response with the block data' do
196
+ MyApp.call(@env).should eql(
197
+ [404, {'Content-Type' => 'text/html'}, '404, gone.']
198
+ )
193
199
  end
194
200
 
195
201
  after do
196
- MyApp.call(@env).should eql(
197
- [404, {'Content-Type' => 'text/html'}, '404 - Not found']
198
- )
199
202
  rm_const "MyApp"
200
203
  end
201
204
  end
202
205
 
203
- context 'without matching route and a :not_found route defined' do
206
+ context 'with a route that don\'t matches' do
204
207
  before do
205
- @env = ["Rack Env"]
206
- @routes = { :not_found => {}}
208
+ @env = ["Environment"]
207
209
  create_new_app("MyApp", Lego::Controller)
208
210
  MyApp::RouteHandler.should_receive(:match_all_routes).with(@env).and_return(nil)
209
- MyApp::RouteHandler.should_receive(:routes).and_return( @routes )
210
211
  end
211
212
 
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)
213
+ it 'should create a new instance of ActionContext' do
214
+ MyApp::ActionContext.should_not_receive(:new)
216
215
  end
217
216
 
218
217
  after do
219
- MyApp.call(@env)
218
+ MyApp.call(@env).should eql(
219
+ [404, {'Content-Type' => 'text/html'}, '404 - Not found']
220
+ )
220
221
  rm_const "MyApp"
221
222
  end
222
223
  end
224
+
223
225
  end
224
226
 
225
227
  context ".set" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lego-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Mathias Stjernstr\xC3\xB6m"
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2010-01-12 00:00:00 +01:00
13
+ date: 2010-01-13 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -28,6 +28,9 @@ files:
28
28
  - Rakefile
29
29
  - VERSION
30
30
  - examples/config.ru
31
+ - examples/sample_with_plugins/config.ru
32
+ - examples/sample_with_plugins/hello.erb
33
+ - examples/sample_with_plugins/lego-modules.rb
31
34
  - lego-core.gemspec
32
35
  - lib/lego-core.rb
33
36
  - lib/lego/controller.rb
@@ -84,3 +87,4 @@ test_files:
84
87
  - spec/lego/plugin_spec.rb
85
88
  - spec/lego_spec.rb
86
89
  - spec/spec_helper.rb
90
+ - examples/sample_with_plugins/lego-modules.rb