mini-train 0.1.0
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.
- 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: []
|