racket-mvc 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +49 -49
- data/Rakefile +8 -7
- data/lib/racket/controller.rb +7 -14
- data/lib/racket/current.rb +16 -8
- data/lib/racket/helpers/file.rb +20 -12
- data/lib/racket/router.rb +24 -21
- data/lib/racket/utils.rb +44 -1
- data/lib/racket/version.rb +1 -1
- data/lib/racket/view_manager.rb +22 -25
- data/rake/utils.rb +36 -0
- data/spec/_custom.rb +3 -3
- data/spec/_default.rb +38 -45
- data/spec/_invalid.rb +1 -2
- data/spec/_request.rb +0 -2
- data/spec/racket.rb +7 -6
- data/spec/test_custom_app/controllers/sub1/custom_sub_controller_1.rb +1 -2
- data/spec/test_custom_app/controllers/sub2/custom_sub_controller_2.rb +1 -2
- data/spec/test_custom_app/controllers/sub3/custom_sub_controller_3.rb +1 -2
- data/spec/test_custom_app/controllers/sub3/inherited/custom_inherited_controller.rb +1 -2
- data/spec/test_custom_app/controllers/sub4/custom_sub_controller_4.rb +25 -0
- data/spec/test_default_app/controllers/default_root_controller.rb +1 -2
- data/spec/test_default_app/controllers/sub1/default_sub_controller_1.rb +1 -2
- data/spec/test_default_app/controllers/sub2/default_sub_controller_2.rb +3 -4
- data/spec/test_default_app/controllers/sub3/default_sub_controller_3.rb +12 -1
- data/spec/test_default_app/controllers/sub3/inherited/default_inherited_controller.rb +1 -2
- metadata +4 -3
- data/spec/test_custom_app/controllers/sub4/default_sub_controller_4.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 105b08877782c44a513558312f3e9b6af7daef75
|
4
|
+
data.tar.gz: 4ccd48feacc8788667f1ea5ab580a3cdb17cbdb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7275ee4175f164a783c9f827ddaee45f68b949ac4977c3637f6ff80e6f7662d03f0985926872d8fa68b68d4f1fa91a34c8aca3d2e3c8383cdbbdb9f3f4d45bac
|
7
|
+
data.tar.gz: 6795e2bfcca8c5671df6e65012fc60ec6ab374458d074c69f91451f9d5fde72de257530c9c32cf0e9336b16f18bc20417a2f6339edeefd09dbba91f62c5a3ab8
|
data/README.md
CHANGED
@@ -1,49 +1,49 @@
|
|
1
|
-
# Racket - The noisy Rack MVC framework
|
2
|
-
|
3
|
-
[](https://travis-ci.org/lasso/racket) [](https://codecov.io/github/lasso/racket?branch=master) [](http://badge.fury.io/rb/racket-mvc)
|
4
|
-
|
5
|
-
## Say what?
|
6
|
-
Yes. It is yet another framework built on rack. Using MVC. Doing silly stuff while you look the other way.
|
7
|
-
|
8
|
-
## Why? I though there were a gazillion frameworks that did the same thing already...
|
9
|
-
You are correct. There are _lots_ of Rack frameworks out there. This one does not pretend to do anything special
|
10
|
-
that you could not get from any of them.
|
11
|
-
|
12
|
-
## So, I have to ask again. Why did you create this monstrosity?
|
13
|
-
Well, when my web host suddenly started insisting on using Phusion Passenger on all of their servers
|
14
|
-
I needed to replace my old [Ramaze](http://ramaze.net/) setup without to much hassle. I tried several
|
15
|
-
other Rack framework, but none of them seemed capable of replacing my apps without some major rewrites.
|
16
|
-
|
17
|
-
## So you just though writing a whole new framework would be easier than using Rails?
|
18
|
-
Yes. Writing Rack frameworks is easy! And since I am able to decide exactly what features I want I don't
|
19
|
-
need to adopt to a large ecosystem of concepts I do not like.
|
20
|
-
|
21
|
-
## So, is it any good?
|
22
|
-
Let us just say it is good _enough_ for my needs at the moment. I plan to add more features/make stuff faster
|
23
|
-
whenever I am finished porting most of my old apps from Ramaze.
|
24
|
-
|
25
|
-
## Where are the tests?
|
26
|
-
Have a look in the `spec` directory. The code base have tests covering 100 per cent of the code and I am planning on keeping it that way. At the moment the code is tested on the following platforms (using [Travis CI](https://travis-ci.org/)):
|
27
|
-
|
28
|
-
-
|
29
|
-
-
|
30
|
-
-
|
31
|
-
-
|
32
|
-
- jruby
|
33
|
-
- jruby
|
34
|
-
- rbx-2
|
35
|
-
|
36
|
-
I am using [bacon](https://github.com/chneukirchen/bacon) and [rack-test](https://github.com/brynary/rack-test) for testing. Run the tests by typing `rake test`in the root directory. Code coverage reports are provided by [simplecov](https://rubygems.org/gems/simplecov). After the tests have run the an HTML report can be found in the `coverage` directory.
|
37
|
-
|
38
|
-
If you are not interested in running the tests yourself you could have a look at the test status at [Travis CI](https://travis-ci.org/lasso/racket) and the code coverage at [Codecov](https://codecov.io/github/lasso/racket). Their stats get updated on every commit.
|
39
|
-
|
40
|
-
## Alright, I want to try using this stuff. Where are the docs?
|
41
|
-
At the moment there is not much documentation available, but I have started working on the [wiki](https://github.com/lasso/racket/wiki).
|
42
|
-
|
43
|
-
The code itself is documented using [Yard](http://yardoc.org/). The docs are not generated automatically, you need to run `rake doc` in the root directory to generate them. After running the rake task the documentation will be available in the `doc` directory.
|
44
|
-
|
45
|
-
## Why is the code licenced under the GNU Affero General Public License? I want a more liberal licence!
|
46
|
-
Because I think it is a Good Thing™ to share code. The
|
47
|
-
[GNU Affero General Public License licence](https://www.gnu.org/licenses/agpl.html) is very liberal unless you plan
|
48
|
-
on beeing egotistical. I you feel you cannot work with that, please choose
|
49
|
-
[something else](https://en.wikipedia.org/wiki/Comparison_of_web_application_frameworks#Ruby).
|
1
|
+
# Racket - The noisy Rack MVC framework
|
2
|
+
|
3
|
+
[](https://travis-ci.org/lasso/racket) [](https://codeclimate.com/github/lasso/racket) [](https://codecov.io/github/lasso/racket?branch=master) [](http://badge.fury.io/rb/racket-mvc)
|
4
|
+
|
5
|
+
## Say what?
|
6
|
+
Yes. It is yet another framework built on rack. Using MVC. Doing silly stuff while you look the other way.
|
7
|
+
|
8
|
+
## Why? I though there were a gazillion frameworks that did the same thing already...
|
9
|
+
You are correct. There are _lots_ of Rack frameworks out there. This one does not pretend to do anything special
|
10
|
+
that you could not get from any of them.
|
11
|
+
|
12
|
+
## So, I have to ask again. Why did you create this monstrosity?
|
13
|
+
Well, when my web host suddenly started insisting on using Phusion Passenger on all of their servers
|
14
|
+
I needed to replace my old [Ramaze](http://ramaze.net/) setup without to much hassle. I tried several
|
15
|
+
other Rack framework, but none of them seemed capable of replacing my apps without some major rewrites.
|
16
|
+
|
17
|
+
## So you just though writing a whole new framework would be easier than using Rails?
|
18
|
+
Yes. Writing Rack frameworks is easy! And since I am able to decide exactly what features I want I don't
|
19
|
+
need to adopt to a large ecosystem of concepts I do not like.
|
20
|
+
|
21
|
+
## So, is it any good?
|
22
|
+
Let us just say it is good _enough_ for my needs at the moment. I plan to add more features/make stuff faster
|
23
|
+
whenever I am finished porting most of my old apps from Ramaze.
|
24
|
+
|
25
|
+
## Where are the tests?
|
26
|
+
Have a look in the `spec` directory. The code base have tests covering 100 per cent of the code and I am planning on keeping it that way. At the moment the code is tested on the following platforms (using [Travis CI](https://travis-ci.org/)):
|
27
|
+
|
28
|
+
- 1.9.3
|
29
|
+
- 2.0.0
|
30
|
+
- 2.1.7
|
31
|
+
- 2.2.3
|
32
|
+
- jruby-19mode
|
33
|
+
- jruby-head
|
34
|
+
- rbx-2
|
35
|
+
|
36
|
+
I am using [bacon](https://github.com/chneukirchen/bacon) and [rack-test](https://github.com/brynary/rack-test) for testing. Run the tests by typing `rake test`in the root directory. Code coverage reports are provided by [simplecov](https://rubygems.org/gems/simplecov). After the tests have run the an HTML report can be found in the `coverage` directory.
|
37
|
+
|
38
|
+
If you are not interested in running the tests yourself you could have a look at the test status at [Travis CI](https://travis-ci.org/lasso/racket) and the code coverage at [Codecov](https://codecov.io/github/lasso/racket). Their stats get updated on every commit.
|
39
|
+
|
40
|
+
## Alright, I want to try using this stuff. Where are the docs?
|
41
|
+
At the moment there is not much documentation available, but I have started working on the [wiki](https://github.com/lasso/racket/wiki).
|
42
|
+
|
43
|
+
The code itself is documented using [Yard](http://yardoc.org/). The docs are not generated automatically, you need to run `rake doc` in the root directory to generate them. After running the rake task the documentation will be available in the `doc` directory.
|
44
|
+
|
45
|
+
## Why is the code licenced under the GNU Affero General Public License? I want a more liberal licence!
|
46
|
+
Because I think it is a Good Thing™ to share code. The
|
47
|
+
[GNU Affero General Public License licence](https://www.gnu.org/licenses/agpl.html) is very liberal unless you plan
|
48
|
+
on beeing egotistical. I you feel you cannot work with that, please choose
|
49
|
+
[something else](https://en.wikipedia.org/wiki/Comparison_of_web_application_frameworks#Ruby).
|
data/Rakefile
CHANGED
@@ -1,30 +1,31 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler/setup'
|
3
|
+
require './rake/utils.rb'
|
3
4
|
|
4
|
-
desc
|
5
|
+
desc 'Run bacon tests'
|
5
6
|
task default: [:test]
|
6
7
|
|
7
|
-
desc
|
8
|
+
desc 'Build racket-mvc gem'
|
8
9
|
task :build_gem do
|
9
10
|
exec 'gem build racket.gemspec'
|
10
11
|
end
|
11
12
|
|
12
|
-
desc
|
13
|
+
desc 'Build yard docs'
|
13
14
|
task :doc do
|
14
15
|
exec 'yard'
|
15
16
|
end
|
16
17
|
|
17
|
-
desc
|
18
|
+
desc 'Show list of undocumented modules/classes/methods'
|
18
19
|
task :nodoc do
|
19
20
|
exec 'yard stats --list-undoc'
|
20
21
|
end
|
21
22
|
|
22
|
-
desc
|
23
|
+
desc 'Publish racket-mvc gem'
|
23
24
|
task publish_gem: [:build_gem] do
|
24
|
-
exec
|
25
|
+
exec "gem push racket-mvc#{racket_version}.gem"
|
25
26
|
end
|
26
27
|
|
27
|
-
desc
|
28
|
+
desc 'Run bacon tests'
|
28
29
|
task :test do
|
29
30
|
exec 'bacon spec/racket.rb'
|
30
31
|
end
|
data/lib/racket/controller.rb
CHANGED
@@ -24,24 +24,17 @@ module Racket
|
|
24
24
|
helper_modules = {}
|
25
25
|
helpers.each do |helper|
|
26
26
|
helper_module = helper.to_s.split('_').collect(&:capitalize).join.to_sym
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
begin
|
33
|
-
require Utils.build_path(helper_dir, helper)
|
34
|
-
rescue LoadError
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
27
|
+
Utils.run_block(NameError) do
|
28
|
+
Utils.run_block(LoadError) { require "racket/helpers/#{helper}" } ||
|
29
|
+
(helper_dir &&
|
30
|
+
Utils.run_block(LoadError) { require Utils.build_path(helper_dir, helper) }
|
31
|
+
)
|
38
32
|
helper_modules[helper] = Racket::Helpers.const_get(helper_module)
|
39
33
|
Application.inform_dev("Added helper module #{helper.inspect} to class #{self}.")
|
40
|
-
|
34
|
+
end ||
|
41
35
|
Application.inform_dev(
|
42
36
|
"Failed to add helper module #{helper.inspect} to class #{self}.", :warn
|
43
37
|
)
|
44
|
-
end
|
45
38
|
end
|
46
39
|
helper_modules
|
47
40
|
end
|
@@ -102,7 +95,7 @@ module Racket
|
|
102
95
|
helper_modules.merge!(__load_helpers(existing_helpers))
|
103
96
|
end
|
104
97
|
# Load new helpers
|
105
|
-
helpers.map!
|
98
|
+
helpers.map!(&:to_sym)
|
106
99
|
helpers.reject! { |helper| helper_modules.key?(helper) }
|
107
100
|
helper_modules.merge!(__load_helpers(helpers))
|
108
101
|
set_option(:helpers, helper_modules)
|
data/lib/racket/current.rb
CHANGED
@@ -35,17 +35,25 @@ module Racket
|
|
35
35
|
# @return [Module] A module encapsulating all state relating to the current request
|
36
36
|
def self.init(env, klass, action, params)
|
37
37
|
klass.helper if klass.get_option(:helpers).nil? # Makes sure default helpers are loaded.
|
38
|
-
|
39
|
-
request = Request.new(env)
|
40
|
-
response = Response.new
|
41
|
-
session = Session.new(env['rack.session']) if env.key?('rack.session')
|
38
|
+
properties = init_properties(action, params, env)
|
42
39
|
Module.new do
|
43
40
|
klass.get_option(:helpers).each_value { |helper| include helper }
|
44
|
-
define_method(
|
45
|
-
define_method(:request) { request }
|
46
|
-
define_method(:response) { response }
|
47
|
-
define_method(:session) { session } if env.key?('rack.session')
|
41
|
+
properties.each_pair { |key, value| define_method(key) { value } }
|
48
42
|
end
|
49
43
|
end
|
44
|
+
|
45
|
+
def self.init_properties(action, params, env)
|
46
|
+
properties =
|
47
|
+
{
|
48
|
+
racket: State.new(action, nil, params),
|
49
|
+
request: Request.new(env),
|
50
|
+
response: Response.new
|
51
|
+
}
|
52
|
+
session = env.fetch('rack.session', nil)
|
53
|
+
properties[:session] = Session.new(session) if session
|
54
|
+
properties
|
55
|
+
end
|
56
|
+
|
57
|
+
private_class_method :init_properties
|
50
58
|
end
|
51
59
|
end
|
data/lib/racket/helpers/file.rb
CHANGED
@@ -28,12 +28,7 @@ module Racket
|
|
28
28
|
# @return [Array]
|
29
29
|
def send_file(file, options = {})
|
30
30
|
file = Utils.build_path(file)
|
31
|
-
|
32
|
-
respond!(
|
33
|
-
404,
|
34
|
-
{ 'Content-Type' => 'text/plain' },
|
35
|
-
Rack::Utils::HTTP_STATUS_CODES[404]
|
36
|
-
) unless Utils.file_readable? (file)
|
31
|
+
_send_file_check_file_readable(file)
|
37
32
|
headers = {}
|
38
33
|
mime_type = options.fetch(:mime_type, nil)
|
39
34
|
# Calculate MIME type if it was not already specified.
|
@@ -41,15 +36,28 @@ module Racket
|
|
41
36
|
headers['Content-Type'] = mime_type
|
42
37
|
# Set Content-Disposition (and a file name) if the file should be downloaded
|
43
38
|
# instead of displayed inline.
|
44
|
-
|
45
|
-
filename = options.fetch(:filename, nil).to_s
|
46
|
-
headers['Content-Disposition'] = 'attachment'
|
47
|
-
headers['Content-Disposition'] << sprintf('; filename="%s"', filename) unless
|
48
|
-
filename.empty?
|
49
|
-
end
|
39
|
+
_send_file_set_content_disposition(options, headers)
|
50
40
|
# Send response
|
51
41
|
respond!(200, headers, ::File.read(file))
|
52
42
|
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def _send_file_check_file_readable(file)
|
47
|
+
# Respond with a 404 Not Found if the file cannot be read.
|
48
|
+
respond!(
|
49
|
+
404,
|
50
|
+
{ 'Content-Type' => 'text/plain' },
|
51
|
+
Rack::Utils::HTTP_STATUS_CODES[404]
|
52
|
+
) unless Utils.file_readable?(file)
|
53
|
+
end
|
54
|
+
|
55
|
+
def _send_file_set_content_disposition(options, headers)
|
56
|
+
return unless options.fetch(:download, false)
|
57
|
+
filename = options.fetch(:filename, nil).to_s
|
58
|
+
headers['Content-Disposition'] = 'attachment'
|
59
|
+
headers['Content-Disposition'] << format('; filename="%s"', filename) unless filename.empty?
|
60
|
+
end
|
53
61
|
end
|
54
62
|
end
|
55
63
|
end
|
data/lib/racket/router.rb
CHANGED
@@ -23,38 +23,41 @@ require 'http_router'
|
|
23
23
|
module Racket
|
24
24
|
# Handles routing in Racket applications.
|
25
25
|
class Router
|
26
|
+
attr_reader :action_cache
|
27
|
+
attr_reader :routes
|
28
|
+
|
26
29
|
def initialize
|
27
30
|
@router = HttpRouter.new
|
28
|
-
@
|
29
|
-
@
|
31
|
+
@routes = {}
|
32
|
+
@action_cache = {}
|
30
33
|
end
|
31
34
|
|
32
35
|
# Caches available actions for each controller class. This also works for controller classes
|
33
36
|
# that inherit from other controller classes.
|
34
37
|
#
|
35
|
-
# @param [Class]
|
38
|
+
# @param [Class] controller_class
|
36
39
|
# @return [nil]
|
37
|
-
def cache_actions(
|
40
|
+
def cache_actions(controller_class)
|
38
41
|
actions = SortedSet.new
|
39
|
-
|
40
|
-
while
|
41
|
-
actions.merge(
|
42
|
-
|
42
|
+
current_class = controller_class
|
43
|
+
while current_class < Controller
|
44
|
+
actions.merge(current_class.public_instance_methods(false))
|
45
|
+
current_class = current_class.superclass
|
43
46
|
end
|
44
|
-
(@
|
47
|
+
(@action_cache[controller_class] = actions.to_a) && nil
|
45
48
|
end
|
46
49
|
|
47
50
|
# Returns a route to the specified controller/action/parameter combination.
|
48
51
|
#
|
49
|
-
# @param [Class]
|
52
|
+
# @param [Class] controller_class
|
50
53
|
# @param [Symbol] action
|
51
54
|
# @param [Array] params
|
52
55
|
# @return [String]
|
53
|
-
def get_route(
|
54
|
-
fail "Cannot find controller #{
|
56
|
+
def get_route(controller_class, action, params)
|
57
|
+
fail "Cannot find controller #{controller_class}" unless @routes.key?(controller_class)
|
55
58
|
params.flatten!
|
56
59
|
route = ''
|
57
|
-
route << @
|
60
|
+
route << @routes[controller_class]
|
58
61
|
route << "/#{action}" unless action.nil?
|
59
62
|
route << "/#{params.join('/')}" unless params.empty?
|
60
63
|
route = route[1..-1] if route.start_with?('//') # Special case for root path
|
@@ -64,14 +67,14 @@ module Racket
|
|
64
67
|
# Maps a controller to the specified path.
|
65
68
|
#
|
66
69
|
# @param [String] path
|
67
|
-
# @param [Class]
|
70
|
+
# @param [Class] controller_class
|
68
71
|
# @return [nil]
|
69
|
-
def map(path,
|
70
|
-
|
71
|
-
Application.inform_dev("Mapping #{
|
72
|
-
@router.add("#{path}(/*params)").to(
|
73
|
-
@
|
74
|
-
cache_actions(
|
72
|
+
def map(path, controller_class)
|
73
|
+
controller_class_base_path = path.empty? ? '/' : path
|
74
|
+
Application.inform_dev("Mapping #{controller_class} to #{controller_class_base_path}.")
|
75
|
+
@router.add("#{path}(/*params)").to(controller_class)
|
76
|
+
@routes[controller_class] = controller_class_base_path
|
77
|
+
cache_actions(controller_class) && nil
|
75
78
|
end
|
76
79
|
|
77
80
|
# @todo: Allow the user to set custom handlers for different errors
|
@@ -105,7 +108,7 @@ module Racket
|
|
105
108
|
action = params.empty? ? target_klass.get_option(:default_action) : params.shift.to_sym
|
106
109
|
|
107
110
|
# Check if action is available on target
|
108
|
-
return render_error(404) unless @
|
111
|
+
return render_error(404) unless @action_cache[target_klass].include?(action)
|
109
112
|
|
110
113
|
# Rewrite PATH_INFO to reflect that we split out the parameters
|
111
114
|
env['PATH_INFO'] = env['PATH_INFO']
|
data/lib/racket/utils.rb
CHANGED
@@ -19,6 +19,38 @@
|
|
19
19
|
module Racket
|
20
20
|
# Collects utilities needed by different objects in Racket.
|
21
21
|
class Utils
|
22
|
+
# Handles exceptions dynamically
|
23
|
+
class ExceptionHandler
|
24
|
+
# Runs a block.
|
25
|
+
# If no exceptions are raised, this method returns true.
|
26
|
+
# If any of the provided error types are raised, this method returns false.
|
27
|
+
# If any other exception is raised, this method will just forward the exception.
|
28
|
+
#
|
29
|
+
# @param [Array] errors
|
30
|
+
# @return [true|flase]
|
31
|
+
def self.run_block(errors)
|
32
|
+
fail 'Need a block' unless block_given?
|
33
|
+
begin
|
34
|
+
true.tap { yield }
|
35
|
+
rescue boolean_module(errors)
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns an anonymous module that can be used to rescue exceptions dynamically.
|
41
|
+
def self.boolean_module(errors)
|
42
|
+
Module.new do
|
43
|
+
(class << self; self; end).instance_eval do
|
44
|
+
define_method(:===) do |error|
|
45
|
+
errors.any? { |e| error.class <= e }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private_class_method :boolean_module
|
52
|
+
end
|
53
|
+
|
22
54
|
# Builds and returns a path in the file system from the provided arguments. The first element
|
23
55
|
# in the argument list can be either absolute or relative, all other arguments must be relative,
|
24
56
|
# otherwise they will be removed from the final path.
|
@@ -29,7 +61,7 @@ module Racket
|
|
29
61
|
if args.empty?
|
30
62
|
path = Pathname.pwd
|
31
63
|
else
|
32
|
-
args.map!
|
64
|
+
args.map!(&:to_s)
|
33
65
|
path = Pathname.new(args.shift)
|
34
66
|
path = Pathname.new(Application.options[:root_dir]).join(path) if path.relative?
|
35
67
|
args.each do |arg|
|
@@ -50,5 +82,16 @@ module Racket
|
|
50
82
|
pathname = Pathname.new(path)
|
51
83
|
pathname.exist? && pathname.file? && pathname.readable?
|
52
84
|
end
|
85
|
+
|
86
|
+
# Runs a block.
|
87
|
+
# If no exceptions are raised, this method returns true.
|
88
|
+
# If any of the provided error types are raised, this method returns false.
|
89
|
+
# If any other exception is raised, this method will just forward the exception.
|
90
|
+
#
|
91
|
+
# @param [Array] errors
|
92
|
+
# @return [true|flase]
|
93
|
+
def self.run_block(*errors, &block)
|
94
|
+
ExceptionHandler.run_block(errors, &block)
|
95
|
+
end
|
53
96
|
end
|
54
97
|
end
|
data/lib/racket/version.rb
CHANGED
data/lib/racket/view_manager.rb
CHANGED
@@ -21,7 +21,6 @@ require 'tilt'
|
|
21
21
|
module Racket
|
22
22
|
# Handles rendering in Racket applications.
|
23
23
|
class ViewManager
|
24
|
-
|
25
24
|
attr_reader :layout_cache
|
26
25
|
attr_reader :view_cache
|
27
26
|
|
@@ -77,6 +76,26 @@ module Racket
|
|
77
76
|
proc.call(*proc_args).to_s
|
78
77
|
end
|
79
78
|
|
79
|
+
# Returns a cached template. If the template has not been cached yet, this method will run a
|
80
|
+
# lookup against the provided parameters.
|
81
|
+
#
|
82
|
+
# @param [String] path
|
83
|
+
# @param [Racket::Controller] controller
|
84
|
+
# @param [Symbol] type
|
85
|
+
def ensure_in_cache(path, controller, type)
|
86
|
+
store = instance_variable_get("@#{type}_cache".to_sym)
|
87
|
+
return store[path] if store.key?(path)
|
88
|
+
base_dir = instance_variable_get("@#{type}_base_dir".to_sym)
|
89
|
+
default_template = controller.controller_option("default_#{type}".to_sym)
|
90
|
+
template = lookup_template(base_dir, path)
|
91
|
+
template =
|
92
|
+
lookup_default_template(base_dir, File.dirname(path), default_template) unless template
|
93
|
+
Application.inform_dev(
|
94
|
+
"Using #{type} #{template.inspect} for #{controller.class}.#{controller.racket.action}."
|
95
|
+
)
|
96
|
+
store[path] = template
|
97
|
+
end
|
98
|
+
|
80
99
|
# Tries to locate a layout matching +path+ in the file system and returns the path if a
|
81
100
|
# matching file is found. If no matching file is found, +nil+ is returned. The result is cached,
|
82
101
|
# meaning that the filesystem lookup for a specific path will only happen once.
|
@@ -85,18 +104,7 @@ module Racket
|
|
85
104
|
# @param [Racket::Controller] controller
|
86
105
|
# @return [String|nil]
|
87
106
|
def get_layout(path, controller)
|
88
|
-
|
89
|
-
layout = lookup_template(@layout_base_dir, path)
|
90
|
-
layout =
|
91
|
-
lookup_default_template(
|
92
|
-
@layout_base_dir, File.dirname(path), controller.controller_option(:default_layout)
|
93
|
-
) unless layout
|
94
|
-
Application.inform_dev(
|
95
|
-
"Using layout #{layout.inspect} for #{controller.class}.#{controller.racket.action}."
|
96
|
-
)
|
97
|
-
@layout_cache[path] = layout
|
98
|
-
end
|
99
|
-
layout = @layout_cache[path]
|
107
|
+
layout = ensure_in_cache(path, controller, :layout)
|
100
108
|
if layout.is_a?(Proc)
|
101
109
|
layout =
|
102
110
|
lookup_template(
|
@@ -115,18 +123,7 @@ module Racket
|
|
115
123
|
# @param [Racket::Controller] controller
|
116
124
|
# @return [String|nil]
|
117
125
|
def get_view(path, controller)
|
118
|
-
|
119
|
-
view = lookup_template(@view_base_dir, path)
|
120
|
-
view =
|
121
|
-
lookup_default_template(
|
122
|
-
@view_base_dir, File.dirname(path), controller.controller_option(:default_view)
|
123
|
-
) unless view
|
124
|
-
Application.inform_dev(
|
125
|
-
"Using view #{view.inspect} for #{controller.class}.#{controller.racket.action}."
|
126
|
-
)
|
127
|
-
@view_cache[path] = view
|
128
|
-
end
|
129
|
-
view = @view_cache[path]
|
126
|
+
view = ensure_in_cache(path, controller, :view)
|
130
127
|
if view.is_a?(Proc)
|
131
128
|
view =
|
132
129
|
lookup_template(
|
data/rake/utils.rb
ADDED
@@ -0,0 +1,36 @@
|
|
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
|
+
def racket_version
|
20
|
+
mod = Module.new
|
21
|
+
mod.module_eval(
|
22
|
+
File.read(
|
23
|
+
File.join(File.dirname(File.dirname(__FILE__)), 'lib', 'racket', 'version.rb')
|
24
|
+
)
|
25
|
+
)
|
26
|
+
mod::Racket::Version.current
|
27
|
+
end
|
28
|
+
|
29
|
+
def racket_files
|
30
|
+
Dir.chdir(File.dirname(File.dirname(__FILE__))) do
|
31
|
+
files = FileList['lib/**/*.rb'].to_a
|
32
|
+
files.concat(FileList['rake/**/*'].to_a)
|
33
|
+
files.concat(FileList['spec/**/*'].to_a)
|
34
|
+
files.concat(FileList['COPYING.AGPL', 'Rakefile', 'README.md'].to_a)
|
35
|
+
end
|
36
|
+
end
|
data/spec/_custom.rb
CHANGED
@@ -50,14 +50,14 @@ describe 'A custom Racket test Application' do
|
|
50
50
|
last_response.headers.key?('X-Hook-Action').should.equal(true)
|
51
51
|
last_response.headers['X-Hook-Action'].should.equal('run')
|
52
52
|
response = JSON.parse(last_response.body)
|
53
|
-
response.should.equal([
|
53
|
+
response.should.equal(['Data added in before block', 'Data added in action'])
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'should let Rack::ShowExceptions handle the error' do
|
57
57
|
get '/sub1/epic_fail'
|
58
58
|
last_response.status.should.equal(500)
|
59
59
|
last_response.headers['Content-Type'].should.equal('text/plain')
|
60
|
-
last_response.body.should.match(
|
60
|
+
last_response.body.should.match(/^RuntimeError: Epic fail!/)
|
61
61
|
end
|
62
62
|
|
63
63
|
it 'should be able to render custom files' do
|
@@ -104,7 +104,7 @@ describe 'A custom Racket test Application' do
|
|
104
104
|
last_response.status.should.equal(404)
|
105
105
|
last_response.headers['Content-Type'].should.equal('text/plain')
|
106
106
|
last_response.headers.key?('Content-Disposition').should.equal(false)
|
107
|
-
last_response.body.should.equal(
|
107
|
+
last_response.body.should.equal('Not Found')
|
108
108
|
end
|
109
109
|
|
110
110
|
it 'should be able to handle dynamic layouts and views' do
|
data/spec/_default.rb
CHANGED
@@ -10,33 +10,27 @@ describe 'A default Racket test Application' do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'has mapped controllers correctly' do
|
13
|
-
|
14
|
-
app.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
actions_by_controller[DefaultSubController2].length.should.equal(5)
|
35
|
-
actions_by_controller[DefaultSubController2].include?(:index).should.equal(true)
|
36
|
-
actions_by_controller[DefaultSubController2].include?(:current_action).should.equal(true)
|
37
|
-
actions_by_controller[DefaultSubController2].include?(:current_params).should.equal(true)
|
38
|
-
actions_by_controller[DefaultSubController3].should.equal([:index])
|
39
|
-
actions_by_controller[DefaultInheritedController].should.equal([:index])
|
13
|
+
app.router.routes.length.should.equal(5)
|
14
|
+
app.router.routes[DefaultRootController].should.equal('/')
|
15
|
+
app.router.routes[DefaultSubController1].should.equal('/sub1')
|
16
|
+
app.router.routes[DefaultSubController2].should.equal('/sub2')
|
17
|
+
app.router.routes[DefaultSubController3].should.equal('/sub3')
|
18
|
+
app.router.routes[DefaultInheritedController].should.equal('/sub3/inherited')
|
19
|
+
|
20
|
+
app.router.action_cache[DefaultRootController].length.should.equal(5)
|
21
|
+
app.router.action_cache[DefaultRootController].include?(:index).should.equal(true)
|
22
|
+
app.router.action_cache[DefaultRootController].include?(:my_first_route).should.equal(true)
|
23
|
+
app.router.action_cache[DefaultRootController].include?(:my_second_route).should.equal(true)
|
24
|
+
app.router.action_cache[DefaultSubController1].length.should.equal(4)
|
25
|
+
app.router.action_cache[DefaultSubController1].include?(:route_to_root).should.equal(true)
|
26
|
+
app.router.action_cache[DefaultSubController1].include?(:route_to_nonexisting)
|
27
|
+
.should.equal(true)
|
28
|
+
app.router.action_cache[DefaultSubController2].length.should.equal(5)
|
29
|
+
app.router.action_cache[DefaultSubController2].include?(:index).should.equal(true)
|
30
|
+
app.router.action_cache[DefaultSubController2].include?(:current_action).should.equal(true)
|
31
|
+
app.router.action_cache[DefaultSubController2].include?(:current_params).should.equal(true)
|
32
|
+
app.router.action_cache[DefaultSubController3].should.equal([:index])
|
33
|
+
app.router.action_cache[DefaultInheritedController].should.equal([:index])
|
40
34
|
end
|
41
35
|
|
42
36
|
it 'should set rack variables correctly' do
|
@@ -46,7 +40,7 @@ describe 'A default Racket test Application' do
|
|
46
40
|
|
47
41
|
get '/sub2/current_params/foo/bar/baz'
|
48
42
|
last_response.status.should.equal(200)
|
49
|
-
JSON.parse(last_response.body).should.equal(
|
43
|
+
JSON.parse(last_response.body).should.equal(%w(foo bar baz))
|
50
44
|
end
|
51
45
|
|
52
46
|
it 'returns the correct respnse when calling index action' do
|
@@ -107,27 +101,27 @@ describe 'A default Racket test Application' do
|
|
107
101
|
end
|
108
102
|
|
109
103
|
it 'should be able to log messages to everybody' do
|
110
|
-
|
104
|
+
original_logger = app.options[:logger]
|
111
105
|
sio = StringIO.new
|
112
106
|
app.options[:logger] = Logger.new(sio)
|
113
|
-
app.inform_all('Informational message')
|
107
|
+
app.inform_all('Informational message')
|
114
108
|
sio.string.should.match(/Informational message/)
|
115
|
-
app.options[:logger] =
|
109
|
+
app.options[:logger] = original_logger
|
116
110
|
end
|
117
111
|
|
118
112
|
it 'should be able to log messages to developer' do
|
119
|
-
|
120
|
-
|
113
|
+
original_logger = app.options[:logger]
|
114
|
+
original_mode = app.options[:mode]
|
121
115
|
sio = StringIO.new
|
122
116
|
app.options[:logger] = Logger.new(sio)
|
123
117
|
app.options[:mode] = :live
|
124
|
-
app.inform_dev('Development message')
|
118
|
+
app.inform_dev('Development message')
|
125
119
|
sio.string.should.be.empty
|
126
120
|
app.options[:mode] = :dev
|
127
|
-
app.inform_dev('Hey, listen up!')
|
128
|
-
sio.string.should.match(
|
129
|
-
app.options[:mode] =
|
130
|
-
app.options[:logger] =
|
121
|
+
app.inform_dev('Hey, listen up!')
|
122
|
+
sio.string.should.match(/Hey, listen up!/)
|
123
|
+
app.options[:mode] = original_mode
|
124
|
+
app.options[:logger] = original_logger
|
131
125
|
end
|
132
126
|
|
133
127
|
it 'should be able to set and clear session variables' do
|
@@ -138,7 +132,7 @@ describe 'A default Racket test Application' do
|
|
138
132
|
response.keys.should.be.empty
|
139
133
|
get '/session_as_json?foo=bar'
|
140
134
|
last_response.headers.keys.should.include('Set-Cookie')
|
141
|
-
last_response.headers['Set-Cookie'].should.match(
|
135
|
+
last_response.headers['Set-Cookie'].should.match(/racket.session=/)
|
142
136
|
response = JSON.parse(last_response.body)
|
143
137
|
response.class.should.equal(Hash)
|
144
138
|
response.keys.length.should.equal(2)
|
@@ -146,7 +140,7 @@ describe 'A default Racket test Application' do
|
|
146
140
|
response.keys.should.include('session_id')
|
147
141
|
get '/session_as_json?baz=quux'
|
148
142
|
last_response.headers.keys.should.include('Set-Cookie')
|
149
|
-
last_response.headers['Set-Cookie'].should.match(
|
143
|
+
last_response.headers['Set-Cookie'].should.match(/racket.session=/)
|
150
144
|
response = JSON.parse(last_response.body)
|
151
145
|
response.class.should.equal(Hash)
|
152
146
|
response.keys.length.should.equal(3)
|
@@ -155,14 +149,14 @@ describe 'A default Racket test Application' do
|
|
155
149
|
response.keys.should.include('session_id')
|
156
150
|
get '/session_as_json?drop_session'
|
157
151
|
last_response.headers.keys.should.include('Set-Cookie')
|
158
|
-
last_response.headers['Set-Cookie'].should.match(
|
152
|
+
last_response.headers['Set-Cookie'].should.match(/racket.session=/)
|
159
153
|
response = JSON.parse(last_response.body)
|
160
154
|
response.class.should.equal(Hash)
|
161
155
|
response.keys.should.be.empty
|
162
156
|
get '/session_strings'
|
163
157
|
response = JSON.parse(last_response.body)
|
164
158
|
response.length.should.equal(3)
|
165
|
-
response.each { |elem| elem.should.match(
|
159
|
+
response.each { |elem| elem.should.match(/Racket::Session/) }
|
166
160
|
end
|
167
161
|
|
168
162
|
it 'should be able to build paths correctly' do
|
@@ -173,7 +167,7 @@ describe 'A default Racket test Application' do
|
|
173
167
|
end
|
174
168
|
|
175
169
|
it 'should handle GET parameters correctly' do
|
176
|
-
get '/sub2/
|
170
|
+
get '/sub2/some_get_data/?data1=foo&data3=bar'
|
177
171
|
last_response.status.should.equal(200)
|
178
172
|
response = JSON.parse(last_response.body, symbolize_names: true)
|
179
173
|
response.class.should.equal(Hash)
|
@@ -184,7 +178,7 @@ describe 'A default Racket test Application' do
|
|
184
178
|
end
|
185
179
|
|
186
180
|
it 'should handle POST parameters correctly' do
|
187
|
-
post '/sub2/
|
181
|
+
post '/sub2/some_post_data', data1: 'foo', data3: 'bar'
|
188
182
|
last_response.status.should.equal(200)
|
189
183
|
response = JSON.parse(last_response.body, symbolize_names: true)
|
190
184
|
response.class.should.equal(Hash)
|
@@ -207,5 +201,4 @@ describe 'A default Racket test Application' do
|
|
207
201
|
last_response.headers['Content-Type'].should.equal('text/plain')
|
208
202
|
last_response.body.should.equal('500 Internal Server Error')
|
209
203
|
end
|
210
|
-
|
211
204
|
end
|
data/spec/_invalid.rb
CHANGED
data/spec/_request.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
describe 'Racket::Request should override Rack::Request correctly' do
|
2
|
-
|
3
2
|
r = Racket::Request.new({}).freeze
|
4
3
|
|
5
4
|
describe 'Racket::Request should inherit some methods from Rack::Request' do
|
@@ -45,5 +44,4 @@ describe 'Racket::Request should override Rack::Request correctly' do
|
|
45
44
|
end
|
46
45
|
end
|
47
46
|
end
|
48
|
-
|
49
47
|
end
|
data/spec/racket.rb
CHANGED
@@ -11,8 +11,9 @@ if ENV['CI'] == 'true'
|
|
11
11
|
SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
TEST_DIR = File.absolute_path(File.dirname(__FILE__))
|
15
|
+
TEST_DEFAULT_APP_DIR = File.join(TEST_DIR, 'test_default_app')
|
16
|
+
TEST_CUSTOM_APP_DIR = File.join(TEST_DIR, 'test_custom_app')
|
16
17
|
|
17
18
|
require 'racket'
|
18
19
|
|
@@ -22,9 +23,9 @@ require 'racket/helpers/file.rb'
|
|
22
23
|
require 'rack/test'
|
23
24
|
require 'bacon'
|
24
25
|
|
25
|
-
|
26
|
+
require File.join(TEST_DIR, '_request.rb')
|
26
27
|
|
27
|
-
Dir.chdir(TEST_DEFAULT_APP_DIR) {
|
28
|
-
Dir.chdir(TEST_CUSTOM_APP_DIR) {
|
28
|
+
Dir.chdir(TEST_DEFAULT_APP_DIR) { require File.join(TEST_DIR, '_default.rb') }
|
29
|
+
Dir.chdir(TEST_CUSTOM_APP_DIR) { require File.join(TEST_DIR, '_custom.rb') }
|
29
30
|
|
30
|
-
|
31
|
+
require File.join(TEST_DIR, '_invalid.rb')
|
@@ -1,5 +1,5 @@
|
|
1
|
+
# Custom sub controller 1
|
1
2
|
class CustomSubController1 < Racket::Controller
|
2
|
-
|
3
3
|
helper :file
|
4
4
|
|
5
5
|
def index
|
@@ -37,5 +37,4 @@ class CustomSubController1 < Racket::Controller
|
|
37
37
|
def send_nonexisting_file
|
38
38
|
send_file('files/no_such_thing.jpg')
|
39
39
|
end
|
40
|
-
|
41
40
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
+
# Custom sub controller 3
|
1
2
|
class CustomSubController3 < Racket::Controller
|
2
|
-
|
3
3
|
set_option(:top_secret, 42)
|
4
4
|
|
5
5
|
def index
|
@@ -23,5 +23,4 @@ class CustomSubController3 < Racket::Controller
|
|
23
23
|
obj.instance_eval { @secret = 42 }
|
24
24
|
render_template('files/secret.erb', obj)
|
25
25
|
end
|
26
|
-
|
27
26
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Custom sub controller 4
|
2
|
+
class CustomSubController4 < Racket::Controller
|
3
|
+
set_option :default_layout, -> { 'layout.erb' }
|
4
|
+
|
5
|
+
set_option :default_view,
|
6
|
+
lambda { |action|
|
7
|
+
case action
|
8
|
+
when :foo then 'myfoo.erb'
|
9
|
+
when :bar then 'mybar.erb'
|
10
|
+
else 'default.erb'
|
11
|
+
end
|
12
|
+
}
|
13
|
+
|
14
|
+
def foo
|
15
|
+
@data = 'FOO'
|
16
|
+
end
|
17
|
+
|
18
|
+
def bar
|
19
|
+
@data = 'BAR'
|
20
|
+
end
|
21
|
+
|
22
|
+
def baz
|
23
|
+
@data = 'BAZ'
|
24
|
+
end
|
25
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
|
+
# Default root controller
|
3
4
|
class DefaultRootController < Racket::Controller
|
4
|
-
|
5
5
|
def index
|
6
6
|
"#{self.class}::#{__method__}"
|
7
7
|
end
|
@@ -28,5 +28,4 @@ class DefaultRootController < Racket::Controller
|
|
28
28
|
def session_strings
|
29
29
|
[session.inspect, session.to_s, session.to_str].to_json
|
30
30
|
end
|
31
|
-
|
32
31
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
+
# Default sub controller 2
|
1
2
|
class DefaultSubController2 < Racket::Controller
|
2
|
-
|
3
3
|
def index
|
4
4
|
"#{self.class}::#{__method__}"
|
5
5
|
end
|
@@ -12,7 +12,7 @@ class DefaultSubController2 < Racket::Controller
|
|
12
12
|
racket.params.to_json
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
15
|
+
def some_get_data
|
16
16
|
data = {}
|
17
17
|
[:data1, :data2, :data3].each do |d|
|
18
18
|
data[d] = request.get(d)
|
@@ -20,12 +20,11 @@ class DefaultSubController2 < Racket::Controller
|
|
20
20
|
data.to_json
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def some_post_data
|
24
24
|
data = {}
|
25
25
|
[:data1, :data2, :data3].each do |d|
|
26
26
|
data[d] = request.post(d)
|
27
27
|
end
|
28
28
|
data.to_json
|
29
29
|
end
|
30
|
-
|
31
30
|
end
|
@@ -1,7 +1,18 @@
|
|
1
|
+
# Default sub controller 3
|
1
2
|
class DefaultSubController3 < Racket::Controller
|
2
|
-
|
3
3
|
def index
|
4
4
|
"#{self.class}::#{__method__}"
|
5
5
|
end
|
6
6
|
|
7
|
+
protected
|
8
|
+
|
9
|
+
def protected_method
|
10
|
+
"I'm protected"
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def private_method
|
16
|
+
"I'm private"
|
17
|
+
end
|
7
18
|
end
|
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.2.
|
4
|
+
version: 0.2.2
|
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-
|
11
|
+
date: 2015-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http_router
|
@@ -159,6 +159,7 @@ files:
|
|
159
159
|
- lib/racket/utils.rb
|
160
160
|
- lib/racket/version.rb
|
161
161
|
- lib/racket/view_manager.rb
|
162
|
+
- rake/utils.rb
|
162
163
|
- spec/_custom.rb
|
163
164
|
- spec/_default.rb
|
164
165
|
- spec/_invalid.rb
|
@@ -168,7 +169,7 @@ files:
|
|
168
169
|
- spec/test_custom_app/controllers/sub2/custom_sub_controller_2.rb
|
169
170
|
- spec/test_custom_app/controllers/sub3/custom_sub_controller_3.rb
|
170
171
|
- spec/test_custom_app/controllers/sub3/inherited/custom_inherited_controller.rb
|
171
|
-
- spec/test_custom_app/controllers/sub4/
|
172
|
+
- spec/test_custom_app/controllers/sub4/custom_sub_controller_4.rb
|
172
173
|
- spec/test_custom_app/extra/blob.rb
|
173
174
|
- spec/test_custom_app/extra/blob/inner_blob.rb
|
174
175
|
- spec/test_custom_app/files/plain_text.txt
|
@@ -1,26 +0,0 @@
|
|
1
|
-
class CustomSubController4 < Racket::Controller
|
2
|
-
|
3
|
-
set_option :default_layout, lambda { 'layout.erb' }
|
4
|
-
|
5
|
-
set_option :default_view,
|
6
|
-
lambda { |action|
|
7
|
-
case action
|
8
|
-
when :foo then 'myfoo.erb'
|
9
|
-
when :bar then 'mybar.erb'
|
10
|
-
else 'default.erb'
|
11
|
-
end
|
12
|
-
}
|
13
|
-
|
14
|
-
def foo
|
15
|
-
@data = 'FOO'
|
16
|
-
end
|
17
|
-
|
18
|
-
def bar
|
19
|
-
@data = 'BAR'
|
20
|
-
end
|
21
|
-
|
22
|
-
def baz
|
23
|
-
@data = 'BAZ'
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|