racket-mvc 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 297c59402186821841ac8b3d9ec1585ebd19a9d4
4
- data.tar.gz: acd9b707fa7aa9d7e249e818454fb2045367b5ef
3
+ metadata.gz: aa507274155a8638944da1b19957b0423499a3aa
4
+ data.tar.gz: 54631b41e9a2ec392b7bb41fd23a87c93ea1df02
5
5
  SHA512:
6
- metadata.gz: a0a346641c4c8f09872051634660c1270edaa0c6ca34ee4f9fd13e69736d24c58bb976b45df94cbc4208443204ad0198ab0ef7d1cfbb57b47d9c27995ac81a01
7
- data.tar.gz: 0cfa26fb63e2750dd4b3ab3bb1472fefbbc589f24d29fcacfbeb13ea55b787cd46f0b249b57b5f0fa5706786dc6b72cfd67da64e2feff86a40eb11ba18e1728c
6
+ metadata.gz: e1e402abcbadc38764b851c7b014e39493692b71247f0db412d75d063b5c844c9048c2faa2dc695f37cb53ee9809d8386a2cae994d0b76afa10952f0889af03e
7
+ data.tar.gz: 65c154fb5ecdb60e364500614f7f7eb1346d3054a1923ec092a0cf52c874a16b150cd383d2aca07cd0ad9dd8455a4500bdde53a24e26b87601f80f946d8bfe29
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Racket - The noisy Rack MVC framework
2
2
 
3
- [![Build Status](https://travis-ci.org/lasso/racket.svg?branch=master)](https://travis-ci.org/lasso/racket)    [![codecov.io](https://codecov.io/github/lasso/racket/coverage.svg?branch=master)](https://codecov.io/github/lasso/racket?branch=master)
4
-
3
+ [![Build Status](https://travis-ci.org/lasso/racket.svg?branch=master)](https://travis-ci.org/lasso/racket)    [![codecov.io](https://codecov.io/github/lasso/racket/coverage.svg?branch=master)](https://codecov.io/github/lasso/racket?branch=master)    [![Gem Version](https://badge.fury.io/rb/racket-mvc.svg)](http://badge.fury.io/rb/racket-mvc)
5
4
 
6
5
  ## Say what?
7
6
  Yes. It is yet another framework built on rack. Using MVC. Doing silly stuff while you look the other way.
data/Rakefile CHANGED
@@ -1,5 +1,12 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
1
4
  task default: %w[test]
2
5
 
6
+ task :build_gem do
7
+ exec 'gem build racket.gemspec'
8
+ end
9
+
3
10
  task :doc do
4
11
  exec 'yard'
5
12
  end
data/lib/racket.rb CHANGED
@@ -1,22 +1,20 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  require 'pathname'
22
20
  require 'rack'
@@ -31,6 +29,7 @@ require_relative 'racket/session.rb'
31
29
  require_relative 'racket/view_cache.rb'
32
30
  require_relative 'racket/utils.rb'
33
31
 
32
+ # Racket main namespace
34
33
  module Racket
35
34
  # Requires a file using the current application directory as a base path.
36
35
  #
@@ -1,29 +1,26 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  require 'logger'
22
20
 
23
21
  module Racket
24
22
  # Racket main application class.
25
23
  class Application
26
-
27
24
  @options = nil
28
25
 
29
26
  # Returns the internal application object. When called for the first time this method will use
@@ -32,13 +29,16 @@ module Racket
32
29
  # @return [Rack::Builder]
33
30
  def self.application
34
31
  return @application if @application
32
+ @options[:middleware].unshift(@options[:session_handler]) if @options[:session_handler]
33
+ @options[:middleware].unshift([Rack::ContentType, @options[:default_content_type]]) if
34
+ @options[:default_content_type]
35
35
  @options[:middleware].unshift([Rack::ShowExceptions]) if dev_mode?
36
36
  instance = self
37
37
  @application = Rack::Builder.new do
38
38
  instance.options[:middleware].each do |middleware|
39
39
  klass, opts = middleware
40
- instance.inform_dev("Loading middleware #{klass} with options #{opts}.")
41
- use *middleware
40
+ instance.inform_dev("Loading middleware #{klass} with options #{opts.inspect}.")
41
+ use(*middleware)
42
42
  end
43
43
  run lambda { |env|
44
44
  static_result = instance.serve_static_file(env)
@@ -64,23 +64,25 @@ module Racket
64
64
  {
65
65
  controller_dir: Utils.build_path(root_dir, 'controllers'),
66
66
  default_action: :index,
67
+ default_content_type: 'text/html',
68
+ default_controller_helpers: [:routing, :view],
67
69
  default_layout: '_default.*',
68
70
  default_view: nil,
71
+ helper_dir: Utils.build_path(root_dir, 'helpers'),
69
72
  layout_dir: Utils.build_path(root_dir, 'layouts'),
70
73
  logger: Logger.new($stdout),
71
- middleware: [
72
- [
73
- Rack::Session::Cookie,
74
- {
75
- key: 'racket.session',
76
- old_secret: SecureRandom.hex(16),
77
- secret: SecureRandom.hex(16)
78
- }
79
- ]
80
- ],
74
+ middleware: [],
81
75
  mode: :live,
82
76
  public_dir: Utils.build_path(root_dir, 'public'),
83
77
  root_dir: root_dir,
78
+ session_handler: [
79
+ Rack::Session::Cookie,
80
+ {
81
+ key: 'racket.session',
82
+ old_secret: SecureRandom.hex(16),
83
+ secret: SecureRandom.hex(16)
84
+ }
85
+ ],
84
86
  view_dir: Utils.build_path(root_dir, 'views')
85
87
  }
86
88
  end
@@ -110,6 +112,15 @@ module Racket
110
112
  init({}, reboot)
111
113
  end
112
114
 
115
+ # Expands all paths defined in the application, but only if it is set to something usable.
116
+ #
117
+ # @return [nil]
118
+ def self.expand_paths
119
+ [:controller_dir, :helper_dir, :layout_dir, :public_dir, :view_dir].each do |dir|
120
+ @options[dir] = Utils.build_path(@options[dir]) if @options[dir]
121
+ end && nil
122
+ end
123
+
113
124
  # Writes a message to the logger if there is one present.
114
125
  #
115
126
  # @param [String] message
@@ -146,6 +157,7 @@ module Racket
146
157
  instance_variables.each { |ivar| instance_variable_set(ivar, nil) } if reboot
147
158
  fail 'Application has already been initialized!' if @options
148
159
  @options = default_options.merge(options)
160
+ expand_paths
149
161
  setup_static_server
150
162
  reload
151
163
  self
@@ -159,8 +171,7 @@ module Racket
159
171
  @options[:last_added_controller] = []
160
172
  @controller = nil
161
173
  Dir.chdir(@options[:controller_dir]) do
162
- files = Pathname.glob(File.join('**', '*.rb'))
163
- files.map! { |file| file.to_s }
174
+ files = Pathname.glob(File.join('**', '*.rb')).map!(&:to_s)
164
175
  # Sort by longest path so that the longer paths gets matched first
165
176
  # HttpRouter claims to be doing this already, but this "hack" is needed in order
166
177
  # for the router to work.
@@ -252,7 +263,7 @@ module Racket
252
263
  @view_cache ||= ViewCache.new(@options[:layout_dir], @options[:view_dir])
253
264
  end
254
265
 
255
- private_class_method :application, :default_options, :inform, :init, :load_controllers,
256
- :setup_routes, :setup_static_server
266
+ private_class_method :application, :default_options, :expand_paths, :inform, :init,
267
+ :load_controllers, :setup_routes, :setup_static_server
257
268
  end
258
269
  end
@@ -1,27 +1,52 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  module Racket
22
-
23
20
  # Base controller class. Your controllers should inherit this class.
24
21
  class Controller
22
+ def self.__load_helpers(helpers)
23
+ helper_dir = Application.options.fetch(:helper_dir, nil)
24
+ helper_modules = {}
25
+ helpers.each do |helper|
26
+ helper_module = helper.to_s.split('_').collect(&:capitalize).join.to_sym
27
+ begin
28
+ begin
29
+ require "racket/helpers/#{helper}"
30
+ rescue LoadError
31
+ if helper_dir
32
+ begin
33
+ require Utils.build_path(helper_dir, helper)
34
+ rescue LoadError
35
+ end
36
+ end
37
+ end
38
+ helper_modules[helper] = Racket::Helpers.const_get(helper_module)
39
+ Application.inform_dev("Added helper module #{helper.inspect} to class #{self}.")
40
+ rescue NameError
41
+ Application.inform_dev(
42
+ "Failed to add helper module #{helper.inspect} to class #{self}.", :warn
43
+ )
44
+ end
45
+ end
46
+ helper_modules
47
+ end
48
+
49
+ private_class_method :__load_helpers
25
50
 
26
51
  # Adds a hook to one or more actions.
27
52
  #
@@ -32,7 +57,7 @@ module Racket
32
57
  def self.__register_hook(type, methods, blk)
33
58
  key = "#{type}_hooks".to_sym
34
59
  meths = public_instance_methods(false)
35
- meths = meths & methods.map { |method| method.to_sym} unless methods.empty?
60
+ meths &= methods.map(&:to_sym) unless methods.empty?
36
61
  hooks = get_option(key) || {}
37
62
  meths.each { |meth| hooks[meth] = blk }
38
63
  set_option(key, hooks)
@@ -59,6 +84,30 @@ module Racket
59
84
  __register_hook(:before, methods, blk) if block_given?
60
85
  end
61
86
 
87
+ # Adds one or more helpers to the controller. All controllers get some default helpers
88
+ # (see Application.default_options), but if you have your own helpers you want to load this
89
+ # is the preferred method.
90
+ #
91
+ # By default Racket will look for your helpers in the helpers directory, but you can specify
92
+ # another location by setting the helper_dir option.
93
+ #
94
+ # @param [Array] helpers An array of symbols representing classes living in the Racket::Helpers
95
+ # namespace.
96
+ def self.helper(*helpers)
97
+ helper_modules = {}
98
+ existing_helpers = get_option(:helpers)
99
+ if existing_helpers.nil?
100
+ # No helpers has been loaded yet. Load the default helpers.
101
+ existing_helpers = Application.options.fetch(:default_controller_helpers, [])
102
+ helper_modules.merge!(__load_helpers(existing_helpers))
103
+ end
104
+ # Load new helpers
105
+ helpers.map! { |helper| helper.to_sym }
106
+ helpers.reject! { |helper| helper_modules.key?(helper) }
107
+ helper_modules.merge!(__load_helpers(helpers))
108
+ set_option(:helpers, helper_modules)
109
+ end
110
+
62
111
  # :nodoc:
63
112
  def self.inherited(klass)
64
113
  Application.options[:last_added_controller].push(klass)
@@ -83,7 +132,7 @@ module Racket
83
132
  # @param [Object] value
84
133
  def self.set_option(key, value)
85
134
  @options ||= {}
86
- @options[key] = value
135
+ (@options[key] = value) && nil
87
136
  end
88
137
 
89
138
  # Returns an option from the current controller class.
@@ -94,72 +143,69 @@ module Racket
94
143
  self.class.get_option(key)
95
144
  end
96
145
 
97
- # Returns a route to an action within the current controller.
146
+ # Redirects the client. After hooks are run.
98
147
  #
99
- # @param [Symbol] action
100
- # @param [Array] params
101
- # @return [String]
102
- def rs(action, *params)
103
- Application.get_route(self.class, action, params)
104
- end
105
-
106
- # Returns a route to an action within another controller.
107
- #
108
- # @param [Class] controller
109
- # @param [Symbol] action
110
- # @param [Array] params
111
- # @return [String]
112
- def r(controller, action, *params)
113
- Application.get_route(controller, action, params)
148
+ # @param [String] target URL to redirect to
149
+ # @param [Fixnum] status HTTP status to send
150
+ # @return [Object]
151
+ def redirect(target, status = 302)
152
+ response.redirect(target, status)
153
+ respond(response.status, response.headers, '')
114
154
  end
115
155
 
116
- # Redirects the client. After hooks are
156
+ # Redirects the client. After hooks are *NOT* run.
117
157
  #
118
158
  # @param [String] target URL to redirect to
119
159
  # @param [Fixnum] status HTTP status to send
120
- # @param [true|false] run_after_hook Whether after hook should be run before redirecting
121
160
  # @return [Object]
122
- def redirect(target, status = 302, run_after_hook = true)
161
+ def redirect!(target, status = 302)
123
162
  response.redirect(target, status)
124
- respond(response.status, response.headers, '', run_after_hook);
163
+ respond!(response.status, response.headers, '')
164
+ end
165
+
166
+ # Stop processing request and send a custom response. After calling this method, after hooks
167
+ # (but no rendering) will be run.
168
+ #
169
+ # @param [Fixnum] status
170
+ # @param [Hash] headers
171
+ # @param [String] body
172
+ def respond(status = 200, headers = {}, body = '')
173
+ __run_hook(:after)
174
+ respond!(status, headers, body)
125
175
  end
126
176
 
127
177
  # Stop processing request and send a custom response. After calling this method, no further
128
- # processing of the request is done unless +run_after_hook+ is set to true. If +run_after_hook+
129
- # is set to true, any after hook associated with the action (but no other code) will be run.
178
+ # processing of the request is done.
130
179
  #
131
180
  # @param [Fixnum] status
132
181
  # @param [Hash] headers
133
182
  # @param [String] body
134
- # @param [true|false] run_after_hook Whether after hook should be run
135
- def respond(status = 200, headers = {}, body = '', run_after_hook = false)
136
- __run_hook(:after, racket.action) if run_after_hook
183
+ def respond!(status = 200, headers = {}, body = '')
137
184
  throw :response, [status, headers, body]
138
185
  end
139
186
 
140
- # Renders an action.
187
+ # Calls hooks, action and renderer.
141
188
  #
142
- # @param [Symbol] action
143
189
  # @return [String]
144
- def render(action)
145
- __execute(action)
190
+ def __run
191
+ __run_hook(:before)
192
+ __run_action
193
+ __run_hook(:after)
146
194
  Application.view_cache.render(self)
147
195
  end
148
196
 
149
197
  private
150
198
 
151
- def __execute(action)
152
- __run_hook(:before, action)
153
- meth = method(action)
199
+ def __run_action
200
+ meth = method(racket.action)
154
201
  params = racket.params[0...meth.parameters.length]
155
- racket.action_result = meth.call(*params)
156
- __run_hook(:after, action)
202
+ (racket.action_result = meth.call(*params)) && nil
157
203
  end
158
204
 
159
- def __run_hook(type, action)
205
+ def __run_hook(type)
160
206
  hooks = controller_option("#{type}_hooks".to_sym) || {}
161
- self.instance_eval &hooks[action] if hooks.key?(action)
207
+ blk = hooks.fetch(racket.action, nil)
208
+ (instance_eval(&blk) if blk) && nil
162
209
  end
163
-
164
210
  end
165
211
  end
@@ -1,22 +1,20 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  module Racket
22
20
  # Represents the current state of Racket while processing a request. The state gets mixed into
@@ -30,15 +28,19 @@ module Racket
30
28
  # Called whenever a new request needs to be processed.
31
29
  #
32
30
  # @param [Hash] env Rack environment
31
+ # @param [Class] klass Target klass, needed because we are copying stuff from the class to the
32
+ # instance.
33
33
  # @param [Symbol] action Keeps track of which action was called on the controller
34
34
  # @param [Array] params Parameters sent to the action
35
35
  # @return [Module] A module encapsulating all state relating to the current request
36
- def self.init(env, action, params)
36
+ def self.init(env, klass, action, params)
37
+ klass.helper if klass.get_option(:helpers).nil? # Makes sure default helpers are loaded.
37
38
  racket = State.new(action, nil, params)
38
39
  request = Request.new(env)
39
40
  response = Response.new
40
41
  session = Session.new(env['rack.session']) if env.key?('rack.session')
41
42
  Module.new do
43
+ klass.get_option(:helpers).each_value { |helper| include helper }
42
44
  define_method(:racket) { racket }
43
45
  define_method(:request) { request }
44
46
  define_method(:response) { response }
@@ -0,0 +1,48 @@
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module Racket
20
+ # Helpers module
21
+ module Helpers
22
+ # Helper module that handles routing
23
+ module Routing
24
+ # Returns a route to an action within another controller.
25
+ #
26
+ # @param [Class] controller
27
+ # @param [Symbol] action
28
+ # @param [Array] params
29
+ # @return [String]
30
+ def route(controller, action, *params)
31
+ Application.get_route(controller, action, params)
32
+ end
33
+
34
+ alias_method(:r, :route)
35
+
36
+ # Returns a route to an action within the current controller.
37
+ #
38
+ # @param [Symbol] action
39
+ # @param [Array] params
40
+ # @return [String]
41
+ def route_self(action, *params)
42
+ Application.get_route(self.class, action, params)
43
+ end
44
+
45
+ alias_method(:rs, :route_self)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,35 @@
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ module Racket
20
+ # Helpers module
21
+ module Helpers
22
+ # Helper module that handles views
23
+ module View
24
+ # Renders a template file using the specified context.
25
+ #
26
+ # @param [String] template
27
+ # @param [Object] context
28
+ # @return [String|nil]
29
+ def render_template(template, context = self)
30
+ return nil unless Utils.file_readable?(template)
31
+ Tilt.new(template).render(context)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,22 +1,20 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  module Racket
22
20
  # Represents an incoming request. Mostly matches Rack::Request but removes some methods that
@@ -1,22 +1,20 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  module Racket
22
20
  # Represents a response from the application
data/lib/racket/router.rb CHANGED
@@ -1,22 +1,22 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
4
18
 
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
19
+ require 'set'
20
20
 
21
21
  require 'http_router'
22
22
 
@@ -35,7 +35,7 @@ module Racket
35
35
  # @param [Class] controller
36
36
  # @return [nil]
37
37
  def cache_actions(controller)
38
- actions = Set.new
38
+ actions = SortedSet.new
39
39
  current = controller
40
40
  while current < Controller
41
41
  actions.merge(current.instance_methods(false))
@@ -76,10 +76,10 @@ module Racket
76
76
  # @todo: Allow the user to set custom handlers for different errors
77
77
  def render_error(status, error = nil)
78
78
  # If running in dev mode, let Rack::ShowExceptions handle the error.
79
- raise error if error && Application.dev_mode?
79
+ fail(error) if error && Application.dev_mode?
80
80
 
81
81
  # Not running in dev mode, let us handle the error ourselves.
82
- response = Response.new([], status, { 'Content-Type' => 'text/plain' })
82
+ response = Response.new([], status, 'Content-Type' => 'text/plain')
83
83
  response.write("#{status} #{Rack::Utils::HTTP_STATUS_CODES[status]}")
84
84
  response.finish
85
85
  end
@@ -89,36 +89,35 @@ module Racket
89
89
  # @param [Hash] env Rack environment
90
90
  # @return [Array] A Rack response triplet
91
91
  def route(env)
92
- begin
93
- catch :response do # Catches early exits from Controller.respond.
94
- # Find controller in map
95
- # If controller exists, call it
96
- # Otherwise, send a 404
97
- matching_routes = @router.recognize(env)
98
- unless matching_routes.first.nil?
99
- target_klass = matching_routes.first.first.route.dest
100
- params = matching_routes.first.first.param_values.first.reject { |e| e.empty? }
101
- action = params.empty? ? target_klass.get_option(:default_action) : params.shift.to_sym
92
+ catch :response do # Catches early exits from Controller.respond.
93
+ # Find controller in map
94
+ # If controller exists, call it
95
+ # Otherwise, send a 404
96
+ matching_routes = @router.recognize(env)
97
+
98
+ # Exit early if no controller is responsible for the route
99
+ return render_error(404) if matching_routes.first.nil?
102
100
 
103
- # Check if action is available on target
104
- return render_error(404) unless @actions_by_controller[target_klass].include?(action)
101
+ # Some controller is claiming to be responsible for the route
102
+ target_klass = matching_routes.first.first.route.dest
103
+ params = matching_routes.first.first.param_values.first.reject(&:empty?)
104
+ action = params.empty? ? target_klass.get_option(:default_action) : params.shift.to_sym
105
105
 
106
- # Rewrite PATH_INFO to reflect that we split out the parameters
107
- env['PATH_INFO'] = env['PATH_INFO']
108
- .split('/')[0...-params.count]
109
- .join('/') unless params.empty?
106
+ # Check if action is available on target
107
+ return render_error(404) unless @actions_by_controller[target_klass].include?(action)
110
108
 
111
- # Initialize and render target
112
- target = target_klass.new
113
- target.extend(Current.init(env, action, params))
114
- target.render(action)
115
- else
116
- render_error(404)
117
- end
118
- end
109
+ # Rewrite PATH_INFO to reflect that we split out the parameters
110
+ env['PATH_INFO'] = env['PATH_INFO']
111
+ .split('/')[0...-params.count]
112
+ .join('/') unless params.empty?
113
+
114
+ # Initialize and render target
115
+ target = target_klass.new
116
+ target.extend(Current.init(env, target_klass, action, params))
117
+ target.__run
118
+ end
119
119
  rescue => err
120
120
  render_error(500, err)
121
- end
122
121
  end
123
122
  end
124
123
  end
@@ -1,22 +1,20 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  module Racket
22
20
  # Racket::Session is just a thin wrapper around whetever object that is implementing the session
@@ -31,7 +29,7 @@ module Racket
31
29
  def inspect
32
30
  "#<#{self.class}:#{object_id}>"
33
31
  end
34
- alias :to_s inspect
35
- alias :to_str inspect
32
+ alias_method(:to_s, :inspect)
33
+ alias_method(:to_str, :inspect)
36
34
  end
37
35
  end
data/lib/racket/utils.rb CHANGED
@@ -1,22 +1,20 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  module Racket
22
20
  # Collects utilities needed by different objects in Racket.
@@ -28,9 +26,10 @@ module Racket
28
26
  # @param [Array] args
29
27
  # @return [String]
30
28
  def self.build_path(*args)
31
- if (args.empty?)
29
+ if args.empty?
32
30
  path = Pathname.pwd
33
31
  else
32
+ args.map! { |arg| arg.to_s }
34
33
  path = Pathname.new(args.shift)
35
34
  path = Pathname.new(Application.options[:root_dir]).join(path) if path.relative?
36
35
  args.each do |arg|
@@ -46,5 +45,10 @@ module Racket
46
45
  pathname = Pathname.new(path)
47
46
  pathname.exist? && pathname.directory? && pathname.readable?
48
47
  end
48
+
49
+ def self.file_readable?(path)
50
+ pathname = Pathname.new(path)
51
+ pathname.exist? && pathname.file? && pathname.readable?
52
+ end
49
53
  end
50
54
  end
@@ -1,22 +1,20 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  module Racket
22
20
  # The only purpose of this module is to keep track of the current Racket version. It is *not*
@@ -27,7 +25,7 @@ module Racket
27
25
  # Minor version
28
26
  MINOR = 1
29
27
  # Teeny version
30
- TEENY = 0
28
+ TEENY = 1
31
29
  # Prerelease ?
32
30
  PRERELEASE = false
33
31
 
@@ -1,29 +1,26 @@
1
- =begin
2
- Racket - The noisy Rack MVC framework
3
- Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
4
-
5
- This file is part of Racket.
6
-
7
- Racket is free software: you can redistribute it and/or modify
8
- it under the terms of the GNU Affero General Public License as published by
9
- the Free Software Foundation, either version 3 of the License, or
10
- (at your option) any later version.
11
-
12
- Racket is distributed in the hope that it will be useful,
13
- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- GNU Affero General Public License for more details.
16
-
17
- You should have received a copy of the GNU Affero General Public License
18
- along with Racket. If not, see <http://www.gnu.org/licenses/>.
19
- =end
1
+ # Racket - The noisy Rack MVC framework
2
+ # Copyright (C) 2015 Lars Olsson <lasso@lassoweb.se>
3
+ #
4
+ # This file is part of Racket.
5
+ #
6
+ # Racket is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Affero General Public License as published by
8
+ # the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # Racket is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Affero General Public License
17
+ # along with Racket. If not, see <http://www.gnu.org/licenses/>.
20
18
 
21
19
  require 'tilt'
22
20
 
23
21
  module Racket
24
22
  # Handles rendering in Racket applications.
25
23
  class ViewCache
26
-
27
24
  def initialize(layout_base_dir, template_base_dir)
28
25
  @layout_base_dir = layout_base_dir
29
26
  @template_base_dir = template_base_dir
@@ -95,14 +92,14 @@ module Racket
95
92
  if default_file
96
93
  files = Pathname.glob(default_file)
97
94
  return nil if files.empty? # No default file found
98
- return File.join(file_path, files.first.to_s)
95
+ final_path = File.join(file_path, files.first.to_s)
96
+ return Utils.file_readable?(final_path) ? final_path : nil
99
97
  end
100
98
  return nil # Neither default file or specified file found
101
99
  end
102
- File.join(file_path, files.first.to_s)
100
+ final_path = File.join(file_path, files.first.to_s)
101
+ return Utils.file_readable?(final_path) ? final_path : nil
103
102
  end
104
103
  end
105
-
106
104
  end
107
-
108
105
  end
data/spec/_custom.rb CHANGED
@@ -9,7 +9,7 @@ describe 'A custom Racket test Application' do
9
9
 
10
10
  it 'should set requested options' do
11
11
  app.options[:default_layout].should.equal('zebra.*')
12
- app.options[:view_dir].should.equal('templates')
12
+ app.options[:view_dir].should.equal(Racket::Utils.build_path('templates'))
13
13
  end
14
14
 
15
15
  it 'should be able to get/set options on controller' do
@@ -17,6 +17,10 @@ describe 'A custom Racket test Application' do
17
17
  last_response.status.should.equal(302)
18
18
  last_response.headers['Location'].should.equal('/sub3/a_secret_place/42')
19
19
  last_response.body.length.should.equal(0)
20
+ get '/sub3/not_so_secret'
21
+ last_response.status.should.equal(302)
22
+ last_response.headers['Location'].should.equal('/sub3/not_so_secret/21')
23
+ last_response.body.length.should.equal(0)
20
24
  end
21
25
 
22
26
  it 'should return a 404 on a nonexisting url' do
@@ -55,4 +59,11 @@ describe 'A custom Racket test Application' do
55
59
  last_response.headers['Content-Type'].should.equal('text/plain')
56
60
  last_response.body.should.match(%r(^RuntimeError: Epic fail!))
57
61
  end
62
+
63
+ it 'should be able to render custom files' do
64
+ get '/sub3/render_a_file'
65
+ last_response.status.should.equal(200)
66
+ last_response.headers['Content-Type'].should.equal('text/html')
67
+ last_response.body.should.equal("The secret is 42!\n")
68
+ end
58
69
  end
data/spec/_default.rb CHANGED
@@ -11,7 +11,7 @@ describe 'A default Racket test Application' do
11
11
 
12
12
  it 'has mapped controllers correctly' do
13
13
  routes_by_controller = actions_by_controller = nil
14
- routes = app.instance_eval do
14
+ app.instance_eval do
15
15
  router.instance_eval do
16
16
  routes_by_controller = @routes_by_controller
17
17
  actions_by_controller = @actions_by_controller
@@ -29,4 +29,6 @@ class CustomSubController2 < Racket::Controller
29
29
  response.headers['X-Hook-Action'] = 'run'
30
30
  end
31
31
 
32
+ helper :nonexisting
33
+
32
34
  end
@@ -10,4 +10,18 @@ class CustomSubController3 < Racket::Controller
10
10
  redirect(rs(__method__, controller_option(:top_secret)))
11
11
  end
12
12
 
13
+ def not_so_secret
14
+ redirect!(rs(__method__, 21))
15
+ end
16
+
17
+ after :not_so_secret do
18
+ fail 'Should not happen!'
19
+ end
20
+
21
+ def render_a_file
22
+ obj = Object.new
23
+ obj.instance_eval { @secret = 42 }
24
+ render_template('files/secret.erb', obj)
25
+ end
26
+
13
27
  end
@@ -0,0 +1 @@
1
+ The secret is <%=@secret%>!
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: racket-mvc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lars Olsson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-15 00:00:00.000000000 Z
11
+ date: 2015-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http_router
@@ -149,6 +149,8 @@ files:
149
149
  - lib/racket/application.rb
150
150
  - lib/racket/controller.rb
151
151
  - lib/racket/current.rb
152
+ - lib/racket/helpers/routing.rb
153
+ - lib/racket/helpers/view.rb
152
154
  - lib/racket/request.rb
153
155
  - lib/racket/response.rb
154
156
  - lib/racket/router.rb
@@ -166,6 +168,7 @@ files:
166
168
  - spec/test_custom_app/controllers/sub3/inherited/custom_inherited_controller.rb
167
169
  - spec/test_custom_app/extra/blob.rb
168
170
  - spec/test_custom_app/extra/blob/inner_blob.rb
171
+ - spec/test_custom_app/files/secret.erb
169
172
  - spec/test_custom_app/layouts/sub2/zebra.erb
170
173
  - spec/test_custom_app/templates/sub2/template.erb
171
174
  - spec/test_default_app/controllers/default_root_controller.rb