racket-mvc 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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