mini-train 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +108 -0
- data/lib/minitrain.rb +111 -0
- data/mini-train.gemspec +14 -0
- data/sample/app.rb +104 -0
- data/sample/config.ru +6 -0
- data/sample/views/index.erb +8 -0
- data/sample/views/index.haml +9 -0
- data/sample/views/index.slim +11 -0
- data/test/minitrain-test.rb +185 -0
- metadata +65 -0
data/README.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
>There's a lady who sures
|
2
|
+
>all that glitters is gold
|
3
|
+
>and she's buying a stairway to heaven -- Led Zeppelin
|
4
|
+
|
5
|
+
mini-train
|
6
|
+
=====
|
7
|
+
|
8
|
+
mini-train is an attempt to fork from a rack project(rack-golem) into
|
9
|
+
a very simple web mini-framework (thats the name mini-train)
|
10
|
+
|
11
|
+
Install with: (there are no gems yet, so don't try to install right now)
|
12
|
+
|
13
|
+
sudo gem install mini-train
|
14
|
+
|
15
|
+
You can use config.ru as a start up file as for any rack app based
|
16
|
+
|
17
|
+
require 'models' # Loads your models and all ORM stuff
|
18
|
+
require 'app' # This is the main file
|
19
|
+
require 'json' # Some help from other gems
|
20
|
+
use Rack::ContentLength
|
21
|
+
use Rack::Session::Cookies
|
22
|
+
run App
|
23
|
+
|
24
|
+
Now save this into app.rb
|
25
|
+
|
26
|
+
require 'minitrain'
|
27
|
+
|
28
|
+
class App
|
29
|
+
include Minitrain # Still no classes to inherit but don't worry just await!
|
30
|
+
|
31
|
+
before do
|
32
|
+
# Here you can do many things
|
33
|
+
# In order to help you here are some variables you can read and override:
|
34
|
+
# @r => the Rack::Request object
|
35
|
+
# @res => the Rack::Response object
|
36
|
+
# @action => Name of the public method that will handle the request
|
37
|
+
# @action_arguments => Arguments for the action (really?)
|
38
|
+
end
|
39
|
+
|
40
|
+
helpers do
|
41
|
+
#altough you can write many things in before block
|
42
|
+
#you always need helpers for your main app
|
43
|
+
def help(with)
|
44
|
+
"Helping the World!"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def index(*args)
|
49
|
+
# When no public method is found
|
50
|
+
# Of course you don't have to declare one and it is gonna use Controller#not_found instead
|
51
|
+
# Still can have arguments
|
52
|
+
@articles = Post.all
|
53
|
+
erb :index
|
54
|
+
end
|
55
|
+
|
56
|
+
def post(id=nil)
|
57
|
+
@post = Post[id]
|
58
|
+
if @post.nil?
|
59
|
+
not_found
|
60
|
+
else
|
61
|
+
erb :post
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def best_restaurants_json
|
66
|
+
# mini-train replaces dots and dashes with underscores
|
67
|
+
# So you can trigger this handler by visiting /best-restaurant.json
|
68
|
+
json_response({
|
69
|
+
'title' => 'Best restaurants in town',
|
70
|
+
'list' => Restaurant.full_list
|
71
|
+
})
|
72
|
+
|
73
|
+
def say(listener='me', *words)
|
74
|
+
"Hey #{listener} I don't need ERB to tell you that #{words.join(' ')}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def not_found(*args)
|
78
|
+
# This one is defined by mini-train but here we decided to override it
|
79
|
+
# Like :index this method receives the arguments in order to make something with it
|
80
|
+
Email.alert('Too many people are looking for porn here') if args.includes?("porn")
|
81
|
+
super(args)
|
82
|
+
end
|
83
|
+
|
84
|
+
def error(err, *args)
|
85
|
+
# Again this one is defined by mini-train and only shows up when RACK_ENV is not `nil` or `dev` or `development`
|
86
|
+
# Default only prints "ERROR"
|
87
|
+
# Here we're going to send the error message
|
88
|
+
# One would rarely show that to the end user but this is just a demo
|
89
|
+
err.message
|
90
|
+
end
|
91
|
+
|
92
|
+
after do
|
93
|
+
Spy.analyse.send_info_to([:government, :facebook, :google, :james_bond])
|
94
|
+
#this was a joke
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
You need to provide the class Post in your models.
|
100
|
+
Class Spy doesn't exist so you need to create it (he he, just kidding).
|
101
|
+
|
102
|
+
WHAT mini-train DOES NOT
|
103
|
+
===================
|
104
|
+
|
105
|
+
- Support templates other than ERB (Slim, Haml and other tilt based templates has been added)
|
106
|
+
- Session/Cookies administration (Like for many things, use a middleware instead ex: Rack::Session::Cookies)
|
107
|
+
- Prepare the coffee (Emacs does but i had never used it, just geany)
|
108
|
+
- So many things, but what is a fork for...
|
data/lib/minitrain.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'rack'
|
2
|
+
require 'tilt'
|
3
|
+
|
4
|
+
module Minitrain
|
5
|
+
|
6
|
+
def self.included(klass)
|
7
|
+
klass.class_eval do
|
8
|
+
extend ClassMethods
|
9
|
+
include InstanceMethods
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
attr_reader :before_block, :helpers_block, :after_block
|
15
|
+
def before(&block); @before_block = block; end
|
16
|
+
def helpers(&block); @helpers_block = block; end
|
17
|
+
def after(&block); @after_block = block; end
|
18
|
+
def dispatcher(&block); @dispatcher_block = block; end
|
19
|
+
def dispatcher_block
|
20
|
+
@dispatcher_block || proc{
|
21
|
+
@path_atoms = @r.path_info.split('/').find_all{|s| s!=''}
|
22
|
+
@action, *@action_arguments = @path_atoms
|
23
|
+
@action = @action.gsub(/[-.]/, '_') unless @action.nil?
|
24
|
+
unless public_methods.include?(@action)||(@action&&public_methods.include?(@action.to_sym))
|
25
|
+
if public_methods.include?('index')||public_methods.include?(:index) # For different RUBY_VERSION(s)
|
26
|
+
@action, @action_arguments = 'index', @path_atoms
|
27
|
+
else
|
28
|
+
@action, @action_arguments = 'not_found', @path_atoms
|
29
|
+
end
|
30
|
+
end
|
31
|
+
instance_eval(&self.class.before_block) unless self.class.before_block.nil?
|
32
|
+
instance_eval(&self.class.helpers_block) unless self.class.helpers_block.nil?
|
33
|
+
begin
|
34
|
+
@res.write(self.__send__(@action,*@action_arguments))
|
35
|
+
rescue ArgumentError => e
|
36
|
+
failed_method = e.backtrace[0][/`.*'$/][1..-2]
|
37
|
+
raise unless failed_method==@action
|
38
|
+
@res.write(self.__send__('not_found', @path_atoms))
|
39
|
+
end
|
40
|
+
instance_eval(&self.class.after_block) unless self.class.after_block.nil?
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module InstanceMethods
|
46
|
+
|
47
|
+
DEV_ENV = [nil,'development','dev']
|
48
|
+
|
49
|
+
def initialize(app=nil); @app = app; end
|
50
|
+
def call(env); dup.call!(env); end
|
51
|
+
|
52
|
+
def call!(env)
|
53
|
+
catch(:response) {
|
54
|
+
@r = ::Rack::Request.new(env)
|
55
|
+
@res = ::Rack::Response.new
|
56
|
+
@session = env['rack.session'] || {}
|
57
|
+
begin
|
58
|
+
instance_eval(&self.class.dispatcher_block)
|
59
|
+
rescue => e
|
60
|
+
raise if DEV_ENV.include?(ENV['RACK_ENV'])
|
61
|
+
@res.write(self.__send__('error', e, @path_atoms))
|
62
|
+
end
|
63
|
+
@res.status==404&&!@app.nil? ? @app.call(env) : @res.finish
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def not_found(*args)
|
68
|
+
@res.status = 404
|
69
|
+
@res.headers['X-Cascade']='pass'
|
70
|
+
"NOT FOUND: #{@r.path_info}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def error(e, *args)
|
74
|
+
puts "\n", e.class, e.message, e.backtrace # Log the error anyway
|
75
|
+
@res.status = 500
|
76
|
+
"ERROR 500"
|
77
|
+
end
|
78
|
+
|
79
|
+
def tpl(template, extention)
|
80
|
+
key = (template.to_s + extention.gsub(/[.]/,"_")).to_sym
|
81
|
+
@@tilt_cache ||= {}
|
82
|
+
if @@tilt_cache.has_key?(key)
|
83
|
+
template_obj = @@tilt_cache[key]
|
84
|
+
else
|
85
|
+
views_location = @r.env['views'] || ::Dir.pwd+'/views/'
|
86
|
+
views_location << '/' unless views_location[-1]==?/
|
87
|
+
template_obj = Tilt.new("#{views_location}#{template}#{extention}")
|
88
|
+
@@tilt_cache.store(key,template_obj) if ENV['RACK_ENV']=='production'
|
89
|
+
end
|
90
|
+
@res['Content-Type'] = "text/html;charset=utf-8"
|
91
|
+
template_obj.render(self)
|
92
|
+
end
|
93
|
+
|
94
|
+
def erb(template)
|
95
|
+
tpl(template,'.erb')
|
96
|
+
end
|
97
|
+
|
98
|
+
def slim(template)
|
99
|
+
tpl(template,'.slim')
|
100
|
+
end
|
101
|
+
|
102
|
+
def haml(template)
|
103
|
+
tpl(template,'.haml')
|
104
|
+
end
|
105
|
+
|
106
|
+
def scss(template)
|
107
|
+
tpl(template,'.scss')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
data/mini-train.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'mini-train'
|
3
|
+
s.version = "0.1.0"
|
4
|
+
s.platform = Gem::Platform::RUBY
|
5
|
+
s.summary = "An attempt to create a web mini-framework forked from an rack app (rack-golem)"
|
6
|
+
s.description = "This is a simplistic web framework"
|
7
|
+
s.files = `git ls-files`.split("\n").sort
|
8
|
+
s.require_path = './lib'
|
9
|
+
s.author = "Carlos Esquer"
|
10
|
+
s.email = "carlitos.esquer@gmail.com"
|
11
|
+
s.homepage = "http://rubymx.blogspot.com"
|
12
|
+
s.add_dependency(%q<tilt>, [">= 1.2.2"])
|
13
|
+
#s.add_development_dependency(%q<bacon>, "~> 1.1.0")
|
14
|
+
end
|
data/sample/app.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'minitrain'
|
2
|
+
require 'slim'
|
3
|
+
require 'yaml'
|
4
|
+
require 'json'
|
5
|
+
class App
|
6
|
+
include Minitrain # Still no classes to inherit but don't worry just await!
|
7
|
+
|
8
|
+
before do
|
9
|
+
# Here you can do many things
|
10
|
+
# In order to help you here are some variables you can read and override:
|
11
|
+
# @r => the Rack::Request object
|
12
|
+
# @res => the Rack::Response object
|
13
|
+
# @action => Name of the public method that will handle the request
|
14
|
+
# @action_arguments => Arguments for the action (really?)
|
15
|
+
end
|
16
|
+
|
17
|
+
helpers do
|
18
|
+
#altough you can write many things in before block
|
19
|
+
#we recommend you to write helpers here to give your app some structure
|
20
|
+
def simple
|
21
|
+
"<b>Siempre genera BOLD</b>"
|
22
|
+
end
|
23
|
+
|
24
|
+
def json_response(data=nil)
|
25
|
+
@res['Content-Type'] = "text/plain;charset=utf-8"
|
26
|
+
data.nil? ? "{}" : JSON.generate(data)
|
27
|
+
end
|
28
|
+
|
29
|
+
def yaml_response(data=nil)
|
30
|
+
@res['Content-Type'] = "text/plain;charset=utf-8"
|
31
|
+
data.to_yaml
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def index(*args)
|
37
|
+
# When no public method is found
|
38
|
+
# Of course you don't have to declare one and it is gonna use Controller#not_found instead
|
39
|
+
# Still can have arguments
|
40
|
+
@articles = [{titulo: "hola mundo",contenido: "Este mundo material"},
|
41
|
+
{titulo: "bienvenidos", contenido: "Nunca habra paz..."},
|
42
|
+
{titulo: "el final", contenido: "como en los viejos tiempos"}
|
43
|
+
]
|
44
|
+
simple + (slim :index)
|
45
|
+
#"<h1>Bienvenido</h1><br><h3>Hola mundo...</h3>"
|
46
|
+
end
|
47
|
+
|
48
|
+
def post(id=nil)
|
49
|
+
@post = Post[id]
|
50
|
+
if @post.nil?
|
51
|
+
not_found
|
52
|
+
else
|
53
|
+
erb :post
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def best_restaurants_json
|
58
|
+
# mini-train replaces dots and dashes with underscores
|
59
|
+
# So you can trigger this handler by visiting /best-restaurants.json
|
60
|
+
json_response({
|
61
|
+
'title' => 'Best restaurants in town',
|
62
|
+
'list' => "{ nuevo: 'artículo', antiguo: 'años'}"
|
63
|
+
})
|
64
|
+
end
|
65
|
+
|
66
|
+
def best_restaurants_yaml
|
67
|
+
#you can generate YAML responses (next time we will use XML)
|
68
|
+
yaml_response({
|
69
|
+
'title' => 'Best restaurants in town',
|
70
|
+
'list' => "{ nuevo: 'artículo', antiguo: 'años'}"
|
71
|
+
})
|
72
|
+
end
|
73
|
+
|
74
|
+
def envy(*args)
|
75
|
+
@res['Content-Type'] = "text/html;charset=utf-8"
|
76
|
+
my_res = ""
|
77
|
+
my_res += "<p> Método: #{@r.request_method}</p>"
|
78
|
+
my_res += "<p> Metodo: #{@r.query_string}</p>"
|
79
|
+
end
|
80
|
+
|
81
|
+
def say(listener='me', *words)
|
82
|
+
"Hey #{listener} I don't need ERB to tell you that #{words.join(' ')}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def not_found(*args)
|
86
|
+
# This one is defined by mini-train but here we decided to override it
|
87
|
+
# Like :index this method receives the arguments in order to make something with it
|
88
|
+
#Email.alert('Too many people are looking for porn here') if args.includes?("porn")
|
89
|
+
super(args)
|
90
|
+
end
|
91
|
+
|
92
|
+
def error(err, *args)
|
93
|
+
# Again this one is defined by mini-train and only shows up when RACK_ENV is not `nil` or `dev` or `development`
|
94
|
+
# Default only prints "ERROR"
|
95
|
+
# Here we're going to send the error message
|
96
|
+
# One would rarely show that to the end user but this is just a demo
|
97
|
+
err.message
|
98
|
+
end
|
99
|
+
|
100
|
+
after do
|
101
|
+
#Spy.analyse.send_info_to([:government, :facebook, :google, :james_bond])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
data/sample/config.ru
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
<head>
|
2
|
+
<link rel='stylesheet' type='text/css' href='http://fonts.googleapis.com/css?family=Play:400,700'/>
|
3
|
+
<link rel="stylesheet" type="text/css" href="/css/layout.css"/>
|
4
|
+
</head>
|
5
|
+
<h1>Algunos artículos (.erb)...<h1>
|
6
|
+
<% @articles.each do |art| %>
|
7
|
+
<h2> <%= art[:titulo] %> </h2>
|
8
|
+
<% end %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
%head
|
2
|
+
%link{:rel=>'stylesheet', :type=>'text/css', :href=>'http://fonts.googleapis.com/css?family=Play:400,700'}
|
3
|
+
%link{:rel=>"stylesheet", :type=>"text/css", :href=>"/css/layout.css"}
|
4
|
+
%body
|
5
|
+
%h1 Algunos artículos (.haml)...
|
6
|
+
%br
|
7
|
+
- @articles.each do |art|
|
8
|
+
%h2= art[:titulo]
|
9
|
+
%br
|
@@ -0,0 +1,11 @@
|
|
1
|
+
head
|
2
|
+
link rel='stylesheet' type='text/css' href='http://fonts.googleapis.com/css?family=Play:400,700'
|
3
|
+
link rel="stylesheet" type="text/css" href="/css/layout.css"
|
4
|
+
body
|
5
|
+
h1 Algunos artículos (.slim)...
|
6
|
+
br
|
7
|
+
- @articles.each do |art|
|
8
|
+
h2= art[:titulo]
|
9
|
+
br
|
10
|
+
.content=art[:contenido]
|
11
|
+
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'rack/lobster'
|
3
|
+
require 'minitrain'
|
4
|
+
|
5
|
+
# =========
|
6
|
+
# = Basic =
|
7
|
+
# =========
|
8
|
+
|
9
|
+
class Basic
|
10
|
+
include Minitrain
|
11
|
+
def no_arg; 'nothing'; end
|
12
|
+
def with_args(a,b); '%s+%s' % [a,b]; end
|
13
|
+
def splat_arg(*a); a.join('+'); end
|
14
|
+
def test_throw
|
15
|
+
throw :response, [200,{'Content-Type'=>'text/html'},['Growl']]
|
16
|
+
'Grrr'
|
17
|
+
end
|
18
|
+
def best_restaurants_rss; '<xml>test</xml>'; end
|
19
|
+
private
|
20
|
+
def no_way; 'This is private'; end
|
21
|
+
end
|
22
|
+
BasicR = ::Rack::MockRequest.new(::Rack::Lint.new(Basic.new))
|
23
|
+
BasicLobsterR = ::Rack::MockRequest.new(::Rack::Lint.new(Basic.new(::Rack::Lobster.new)))
|
24
|
+
|
25
|
+
# ==========
|
26
|
+
# = Filter =
|
27
|
+
# ==========
|
28
|
+
|
29
|
+
class Filter
|
30
|
+
include Minitrain
|
31
|
+
before{@res.write @action=='not_found' ? @action_arguments.join('+') : 'before+'}
|
32
|
+
after{@res.write '+after'}
|
33
|
+
def wrapped; 'wrapped'; end
|
34
|
+
end
|
35
|
+
FilterR = ::Rack::MockRequest.new(::Rack::Lint.new(Filter.new))
|
36
|
+
|
37
|
+
# ===========
|
38
|
+
# = Indexed =
|
39
|
+
# ===========
|
40
|
+
|
41
|
+
class Indexed
|
42
|
+
include Minitrain
|
43
|
+
before{ @res.write("action=#{@action} args=#{@action_arguments.join(',')} ") if @r['switch']=='true' }
|
44
|
+
def index(*a); a.join('+'); end
|
45
|
+
def exist(*a); a.join('+'); end
|
46
|
+
end
|
47
|
+
IndexedR = ::Rack::MockRequest.new(::Rack::Lint.new(Indexed.new))
|
48
|
+
|
49
|
+
# ==================
|
50
|
+
# = Simply indexed =
|
51
|
+
# ==================
|
52
|
+
|
53
|
+
class SimplyIndexed
|
54
|
+
include Minitrain
|
55
|
+
def index; 'index'; end
|
56
|
+
def will_fail; please_fail; end
|
57
|
+
private
|
58
|
+
def please_fail(num); 'ArgumentError baby'; end
|
59
|
+
end
|
60
|
+
SimplyIndexedR = ::Rack::MockRequest.new(::Rack::Lint.new(SimplyIndexed.new))
|
61
|
+
SimplyIndexedUsedR = ::Rack::MockRequest.new(::Rack::Lint.new(SimplyIndexed.new(lambda{|env| [200,{},"#{3+nil}"]})))
|
62
|
+
|
63
|
+
# =============
|
64
|
+
# = Sessioned =
|
65
|
+
# =============
|
66
|
+
|
67
|
+
class Sessioned
|
68
|
+
include Minitrain
|
69
|
+
def set_val(val); @session[:val] = val; end
|
70
|
+
def get_val; @session[:val]; end
|
71
|
+
end
|
72
|
+
SessionedR = ::Rack::MockRequest.new(::Rack::Session::Cookie.new(::Rack::Lint.new(Sessioned.new)))
|
73
|
+
|
74
|
+
# =============
|
75
|
+
# = Helpers =
|
76
|
+
# =============
|
77
|
+
|
78
|
+
class UsingHelpers
|
79
|
+
include Minitrain
|
80
|
+
helpers { def hola(w); "Hola " + w; end }
|
81
|
+
def index; hola("mundo"); end
|
82
|
+
end
|
83
|
+
UsinghelpersR = ::Rack::MockRequest.new(::Rack::Lint.new(UsingHelpers.new))
|
84
|
+
|
85
|
+
# =========
|
86
|
+
# = Specs =
|
87
|
+
# =========
|
88
|
+
|
89
|
+
describe "Minitrain" do
|
90
|
+
|
91
|
+
it "Should dispatch on a method with no arguments" do
|
92
|
+
assert_equal "nothing",BasicR.get('/no_arg').body
|
93
|
+
end
|
94
|
+
|
95
|
+
it "Should dispatch on a method with arguments" do
|
96
|
+
assert_equal "a+b",BasicR.get('/with_args/a/b').body
|
97
|
+
end
|
98
|
+
|
99
|
+
it "Should dispatch on a method with splat argument" do
|
100
|
+
assert_equal "a+b+c+d",BasicR.get('/splat_arg/a/b/c/d').body
|
101
|
+
end
|
102
|
+
|
103
|
+
it "Should not dispatch if the method is private or does not exist" do
|
104
|
+
r = BasicR.get('/no_way')
|
105
|
+
assert_equal 404,r.status
|
106
|
+
assert_equal "NOT FOUND: /no_way",r.body
|
107
|
+
r = BasicR.get('/no')
|
108
|
+
assert_equal 404,r.status
|
109
|
+
assert_equal "NOT FOUND: /no",r.body
|
110
|
+
end
|
111
|
+
|
112
|
+
it "Should dispatch to appropriate underscored action when name contains '-' or '.'" do
|
113
|
+
assert_equal "<xml>test</xml>",BasicR.get('/best-restaurants.rss').body
|
114
|
+
end
|
115
|
+
|
116
|
+
it "Should only apply '-' and '.' substitution on action names" do
|
117
|
+
assert_equal 'best-restaurants.rss',IndexedR.get('/best-restaurants.rss').body
|
118
|
+
end
|
119
|
+
|
120
|
+
it "Should follow the rack stack if response is 404 and there are middlewares below" do
|
121
|
+
r = BasicLobsterR.get("/no_way")
|
122
|
+
assert_equal 200,r.status
|
123
|
+
end
|
124
|
+
|
125
|
+
it "Should provide filters" do
|
126
|
+
assert_equal "before+wrapped+after",FilterR.get('/wrapped').body
|
127
|
+
end
|
128
|
+
|
129
|
+
it "Should provide arguments in filter when page is not_found" do
|
130
|
+
assert_equal "a+b+c+dNOT FOUND: /a/b/c/d+after",FilterR.get('/a/b/c/d').body
|
131
|
+
end
|
132
|
+
|
133
|
+
it "Should send everything to :index if it exists and there is no matching method for first arg" do
|
134
|
+
assert_equal 'a+b+c+d',IndexedR.get('/exist/a/b/c/d').body
|
135
|
+
assert_equal 'a+b+c+d',IndexedR.get('/a/b/c/d').body
|
136
|
+
assert_equal '',IndexedR.get('/').body
|
137
|
+
end
|
138
|
+
|
139
|
+
it "Should send not_found if there is an argument error on handlers" do
|
140
|
+
assert_equal 200,SimplyIndexedR.get('/').status
|
141
|
+
assert_equal 404,SimplyIndexedR.get('/unknown').status
|
142
|
+
assert_equal 404,SimplyIndexedR.get('/will_fail/useless').status
|
143
|
+
assert_raises(ArgumentError) { SimplyIndexedR.get('/will_fail') }
|
144
|
+
end
|
145
|
+
|
146
|
+
it "Should handle errors without raising an exception unless in dev mode" do
|
147
|
+
assert_raises(ArgumentError) { SimplyIndexedR.get('/will_fail') }
|
148
|
+
ENV['RACK_ENV'] = 'development'
|
149
|
+
assert_raises(ArgumentError) { SimplyIndexedR.get('/will_fail') }
|
150
|
+
ENV['RACK_ENV'] = 'production'
|
151
|
+
@old_stdout = $stdout
|
152
|
+
$stdout = StringIO.new
|
153
|
+
res = SimplyIndexedR.get('/will_fail')
|
154
|
+
logged = $stdout.dup
|
155
|
+
$stdout = @old_stdout
|
156
|
+
assert_equal res.status,500
|
157
|
+
assert_match logged.string, /ArgumentError/
|
158
|
+
ENV['RACK_ENV'] = nil
|
159
|
+
end
|
160
|
+
|
161
|
+
it "Should not use the error handler if the error occurs further down the rack stack" do
|
162
|
+
ENV['RACK_ENV'] = 'production'
|
163
|
+
assert_raises(TypeError) { SimplyIndexedUsedR.get('/not_found') }
|
164
|
+
ENV['RACK_ENV'] = nil
|
165
|
+
end
|
166
|
+
|
167
|
+
it "Should set dispatch-specific variables correctly when defaulting to :index" do
|
168
|
+
assert_equal "action=index args=a,b,c,d a+b+c+d",IndexedR.get('/a/b/c/d?switch=true').body
|
169
|
+
end
|
170
|
+
|
171
|
+
it "Should have a shortcut for session hash" do
|
172
|
+
res = SessionedR.get('/set_val/ichigo')
|
173
|
+
res_2 = SessionedR.get('/get_val', 'HTTP_COOKIE'=>res["Set-Cookie"])
|
174
|
+
assert_equal 'ichigo',res_2.body
|
175
|
+
end
|
176
|
+
|
177
|
+
it "Should catch :response if needed" do
|
178
|
+
assert_equal BasicR.get('/test_throw').body,'Growl'
|
179
|
+
end
|
180
|
+
|
181
|
+
it "Should response with the helpers content" do
|
182
|
+
assert_equal UsinghelpersR.get('/').body,'Hola mundo'
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mini-train
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Carlos Esquer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: tilt
|
16
|
+
requirement: &71720560 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.2.2
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *71720560
|
25
|
+
description: This is a simplistic web framework
|
26
|
+
email: carlitos.esquer@gmail.com
|
27
|
+
executables: []
|
28
|
+
extensions: []
|
29
|
+
extra_rdoc_files: []
|
30
|
+
files:
|
31
|
+
- README.md
|
32
|
+
- lib/minitrain.rb
|
33
|
+
- mini-train-0.1.0.gem
|
34
|
+
- mini-train.gemspec
|
35
|
+
- sample/app.rb
|
36
|
+
- sample/config.ru
|
37
|
+
- sample/views/index.erb
|
38
|
+
- sample/views/index.haml
|
39
|
+
- sample/views/index.slim
|
40
|
+
- test/minitrain-test.rb
|
41
|
+
homepage: http://rubymx.blogspot.com
|
42
|
+
licenses: []
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- ./lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.8.11
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: An attempt to create a web mini-framework forked from an rack app (rack-golem)
|
65
|
+
test_files: []
|