cuba 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +110 -34
- data/cuba.gemspec +17 -6
- data/lib/cuba/ron.rb +8 -5
- data/lib/cuba/test.rb +5 -1
- data/lib/cuba/version.rb +1 -1
- data/test/helper.rb +0 -1
- data/test/layout.rb +15 -0
- data/test/root.rb +40 -0
- metadata +54 -60
data/README.markdown
CHANGED
@@ -58,13 +58,18 @@ Here's a simple application:
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
To run it, you can create a `config.ru
|
61
|
+
To run it, you can create a `config.ru` file:
|
62
62
|
|
63
63
|
# cat config.ru
|
64
64
|
require "hello_world"
|
65
65
|
|
66
66
|
run Cuba
|
67
67
|
|
68
|
+
You can now run `rackup` and enjoy what you have just created.
|
69
|
+
|
70
|
+
Matchers
|
71
|
+
--------
|
72
|
+
|
68
73
|
Here's an example showcasing how different matchers work:
|
69
74
|
|
70
75
|
require "cuba"
|
@@ -73,50 +78,55 @@ Here's an example showcasing how different matchers work:
|
|
73
78
|
|
74
79
|
Cuba.define do
|
75
80
|
|
76
|
-
#
|
77
|
-
on
|
78
|
-
res.write "Home"
|
79
|
-
end
|
81
|
+
# only GET requests
|
82
|
+
on get do
|
80
83
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
84
|
+
# /
|
85
|
+
on "" do
|
86
|
+
res.write "Home"
|
87
|
+
end
|
85
88
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
89
|
+
# /about
|
90
|
+
on "about" do
|
91
|
+
res.write "About"
|
92
|
+
end
|
90
93
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
94
|
+
# /styles/basic.css
|
95
|
+
on "styles", extension("css") do |file|
|
96
|
+
res.write "Filename: #{file}" #=> "Filename: basic"
|
97
|
+
end
|
98
|
+
|
99
|
+
# /post/2011/02/16/hello
|
100
|
+
on "post/:y/:m/:d/:slug" do |y, m, d, slug|
|
101
|
+
res.write "#{y}-#{m}-#{d} #{slug}" #=> "2011-02-16 hello"
|
102
|
+
end
|
95
103
|
|
96
|
-
|
97
|
-
|
104
|
+
# /username/foobar
|
105
|
+
on "username/:username" do |username|
|
98
106
|
|
99
|
-
|
107
|
+
user = User.find_by_username(username) # username == "foobar"
|
100
108
|
|
101
|
-
|
102
|
-
|
109
|
+
# /username/foobar/posts
|
110
|
+
on "posts" do
|
103
111
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
112
|
+
# You can access `user` here, because the `on` blocks
|
113
|
+
# are closures.
|
114
|
+
res.write "Total Posts: #{user.posts.size}" #=> "Total Posts: 6"
|
115
|
+
end
|
108
116
|
|
109
|
-
|
110
|
-
|
111
|
-
|
117
|
+
# /username/foobar/following
|
118
|
+
on "following" do
|
119
|
+
res.write user.following.size #=> "1301"
|
120
|
+
end
|
112
121
|
end
|
113
|
-
end
|
114
122
|
|
115
|
-
|
116
|
-
|
117
|
-
|
123
|
+
# /search?q=barbaz
|
124
|
+
on "search", param("q") do |query|
|
125
|
+
res.write "Searched for #{query}" #=> "Searched for barbaz"
|
126
|
+
end
|
118
127
|
end
|
119
128
|
|
129
|
+
# only POST requests
|
120
130
|
on post do
|
121
131
|
on "login"
|
122
132
|
|
@@ -134,7 +144,73 @@ Here's an example showcasing how different matchers work:
|
|
134
144
|
end
|
135
145
|
end
|
136
146
|
|
137
|
-
|
147
|
+
HTTP Verbs
|
148
|
+
----------
|
149
|
+
|
150
|
+
There are four matchers defined for HTTP Verbs: `get`, `post`, `put` and
|
151
|
+
`delete`. But the world doesn't end there, does it? As you have the whole
|
152
|
+
request available via the `req` object, you can query it with helper methods
|
153
|
+
like `req.options?` or `req.head?`, or you can even go to a lower level
|
154
|
+
and inspect the environment via the `env` object, and check for example if
|
155
|
+
`env["REQUEST_METHOD"]` equals the obscure verb `PATCH`.
|
156
|
+
|
157
|
+
What follows is an example of different ways of saying the same thing:
|
158
|
+
|
159
|
+
on env["REQUEST_METHOD"] == "GET", "api" do ... end
|
160
|
+
|
161
|
+
on req.get?, "api" do ... end
|
162
|
+
|
163
|
+
on get, "api" do ... end
|
164
|
+
|
165
|
+
Actually, `get` is syntax sugar for `req.get?`, which in turn is syntax sugar
|
166
|
+
for `env["REQUEST_METHOD"] == "GET"`.
|
167
|
+
|
168
|
+
Captures
|
169
|
+
--------
|
170
|
+
|
171
|
+
You may have noticed that some matchers yield a value to the block. The rules
|
172
|
+
for determining if a matcher will yield a value are simple:
|
173
|
+
|
174
|
+
1. Regex captures: `"posts/(\d+)-(.*)"` will yield two values, corresponding to each capture.
|
175
|
+
2. Placeholders: `"users/:id"` will yield the value in the position of :id.
|
176
|
+
3. Symbols: `:foobar` will yield if a segment is available.
|
177
|
+
4. File extensions: `extension("css")` will yield the basename of the matched file.
|
178
|
+
5. Parameters: `param("user")` will yield the value of the parameter user, if present.
|
179
|
+
|
180
|
+
The first case is important because it shows the underlying effect of regex
|
181
|
+
captures.
|
182
|
+
|
183
|
+
In the second case, the substring `:id` gets replaced by `([^\\/]+)` and the
|
184
|
+
string becomes `"users/([^\\/]+)"` before performing the match, thus it reverts
|
185
|
+
to the first form we saw.
|
186
|
+
|
187
|
+
In the third case, the symbol ––no matter what it says––gets replaced
|
188
|
+
by `"([^\\/]+)"`, and again we are in presence of case 1.
|
189
|
+
|
190
|
+
The fourth case, again, reverts to the basic matcher: it generates the string
|
191
|
+
`"([^\\/]+?)\.#{ext}\\z"` before performing the match.
|
192
|
+
|
193
|
+
The fifth case is different: it checks if the the parameter supplied is present
|
194
|
+
in the request (via POST or QUERY_STRING) and it pushes the value as a capture.
|
195
|
+
|
196
|
+
Testing
|
197
|
+
-------
|
198
|
+
|
199
|
+
Given that Cuba is essentially Rack, it is very easy to test with `Webrat` or
|
200
|
+
`Capybara`. Cuba's own tests are written with a combination of [Cutest][cutest]
|
201
|
+
and [Capybara][capybara], and if you want to use the same for your tests it is
|
202
|
+
as easy as requiring `cuba/test`:
|
203
|
+
|
204
|
+
require "cuba/test"
|
205
|
+
require "your/app"
|
206
|
+
|
207
|
+
scope do
|
208
|
+
test "Homepage" do
|
209
|
+
visit "/"
|
210
|
+
|
211
|
+
assert has_content?("Hello world!")
|
212
|
+
end
|
213
|
+
end
|
138
214
|
|
139
215
|
To read more about testing, check the documentation for [Cutest][cutest] and
|
140
216
|
[Capybara][capybara].
|
data/cuba.gemspec
CHANGED
@@ -1,14 +1,25 @@
|
|
1
|
+
require "./lib/cuba/version"
|
2
|
+
|
1
3
|
Gem::Specification.new do |s|
|
2
4
|
s.name = "cuba"
|
3
|
-
s.version =
|
5
|
+
s.version = Cuba::VERSION
|
4
6
|
s.summary = "Microframework for web applications."
|
5
7
|
s.description = "Cuba is a microframework for web applications."
|
6
8
|
s.authors = ["Michel Martens"]
|
7
9
|
s.email = ["michel@soveran.com"]
|
8
10
|
s.homepage = "http://github.com/soveran/cuba"
|
9
|
-
|
10
|
-
s.
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
|
12
|
+
s.files = Dir[
|
13
|
+
"LICENSE",
|
14
|
+
"README.markdown",
|
15
|
+
"Rakefile",
|
16
|
+
"lib/**/*.rb",
|
17
|
+
"*.gemspec",
|
18
|
+
"test/*.*"
|
19
|
+
]
|
20
|
+
|
21
|
+
s.add_dependency "rack"
|
22
|
+
s.add_dependency "tilt"
|
23
|
+
s.add_development_dependency "cutest"
|
24
|
+
s.add_development_dependency "capybara"
|
14
25
|
end
|
data/lib/cuba/ron.rb
CHANGED
@@ -63,10 +63,13 @@ module Cuba
|
|
63
63
|
# # Renders with HAML options
|
64
64
|
# render("home.haml", {}, ugly: true, format: :html5)
|
65
65
|
#
|
66
|
-
|
66
|
+
# # Renders in layout
|
67
|
+
# render("layout.haml") { render("home.haml") }
|
68
|
+
#
|
69
|
+
def render(template, locals = {}, options = {}, &block)
|
67
70
|
_cache.fetch(template, locals) {
|
68
71
|
Tilt.new(template, 1, options)
|
69
|
-
}.render(self, locals)
|
72
|
+
}.render(self, locals, &block)
|
70
73
|
end
|
71
74
|
|
72
75
|
# The heart of the path / verb / any condition matching.
|
@@ -140,12 +143,12 @@ module Cuba
|
|
140
143
|
private :try
|
141
144
|
|
142
145
|
def consume(pattern)
|
143
|
-
return unless match = env["PATH_INFO"].match(/\A\/(#{pattern})(?:\/|\z)/)
|
146
|
+
return unless match = env["PATH_INFO"].match(/\A\/(#{pattern})((?:\/|\z))/)
|
144
147
|
|
145
148
|
path, *vars = match.captures
|
146
149
|
|
147
150
|
env["SCRIPT_NAME"] += "/#{path}"
|
148
|
-
env["PATH_INFO"] = "
|
151
|
+
env["PATH_INFO"] = "#{vars.pop}#{match.post_match}"
|
149
152
|
|
150
153
|
captures.push(*vars)
|
151
154
|
end
|
@@ -254,4 +257,4 @@ module Cuba
|
|
254
257
|
throw :ron_run_next_app, app
|
255
258
|
end
|
256
259
|
end
|
257
|
-
end
|
260
|
+
end
|
data/lib/cuba/test.rb
CHANGED
data/lib/cuba/version.rb
CHANGED
data/test/helper.rb
CHANGED
data/test/layout.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path("helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
test "simple layout support" do
|
4
|
+
Cuba.define do
|
5
|
+
on true do
|
6
|
+
res.write render("test/fixtures/layout.erb") {
|
7
|
+
render("test/fixtures/content.erb")
|
8
|
+
}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
_, _, resp = Cuba.call({})
|
13
|
+
|
14
|
+
assert_equal ["alfa beta\n\n"], resp.body
|
15
|
+
end
|
data/test/root.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path("helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
test "matching an empty segment" do
|
4
|
+
Cuba.define do
|
5
|
+
on "" do
|
6
|
+
res.write req.path
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
env = {
|
11
|
+
"SCRIPT_NAME" => "",
|
12
|
+
"PATH_INFO" => "/"
|
13
|
+
}
|
14
|
+
|
15
|
+
_, _, resp = Cuba.call(env)
|
16
|
+
|
17
|
+
assert_equal ["/"], resp.body
|
18
|
+
end
|
19
|
+
|
20
|
+
test "nested empty segments" do
|
21
|
+
Cuba.define do
|
22
|
+
on "" do
|
23
|
+
on "" do
|
24
|
+
on "1" do
|
25
|
+
res.write "IT WORKS!"
|
26
|
+
res.write req.path
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
env = {
|
33
|
+
"SCRIPT_NAME" => "",
|
34
|
+
"PATH_INFO" => "///1"
|
35
|
+
}
|
36
|
+
|
37
|
+
_, _, resp = Cuba.call(env)
|
38
|
+
|
39
|
+
assert_equal ["IT WORKS!", "///1"], resp.body
|
40
|
+
end
|
metadata
CHANGED
@@ -1,72 +1,68 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: cuba
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.1
|
4
5
|
prerelease:
|
5
|
-
version: 2.0.0
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Michel Martens
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
date: 2011-03-18 00:00:00 -03:00
|
12
|
+
date: 2011-07-19 00:00:00.000000000 -03:00
|
14
13
|
default_executable:
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
17
16
|
name: rack
|
18
|
-
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: &2157267480 !ruby/object:Gem::Requirement
|
20
18
|
none: false
|
21
|
-
requirements:
|
22
|
-
- -
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version:
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
25
23
|
type: :runtime
|
26
|
-
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: tilt
|
29
24
|
prerelease: false
|
30
|
-
|
25
|
+
version_requirements: *2157267480
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: tilt
|
28
|
+
requirement: &2157267060 !ruby/object:Gem::Requirement
|
31
29
|
none: false
|
32
|
-
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version:
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
36
34
|
type: :runtime
|
37
|
-
version_requirements: *id002
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: cutest
|
40
35
|
prerelease: false
|
41
|
-
|
36
|
+
version_requirements: *2157267060
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: cutest
|
39
|
+
requirement: &2157266640 !ruby/object:Gem::Requirement
|
42
40
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version:
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
47
45
|
type: :development
|
48
|
-
version_requirements: *id003
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: capybara
|
51
46
|
prerelease: false
|
52
|
-
|
47
|
+
version_requirements: *2157266640
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: capybara
|
50
|
+
requirement: &2157266220 !ruby/object:Gem::Requirement
|
53
51
|
none: false
|
54
|
-
requirements:
|
55
|
-
- -
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version:
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
58
56
|
type: :development
|
59
|
-
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *2157266220
|
60
59
|
description: Cuba is a microframework for web applications.
|
61
|
-
email:
|
60
|
+
email:
|
62
61
|
- michel@soveran.com
|
63
62
|
executables: []
|
64
|
-
|
65
63
|
extensions: []
|
66
|
-
|
67
64
|
extra_rdoc_files: []
|
68
|
-
|
69
|
-
files:
|
65
|
+
files:
|
70
66
|
- LICENSE
|
71
67
|
- README.markdown
|
72
68
|
- Rakefile
|
@@ -82,40 +78,38 @@ files:
|
|
82
78
|
- test/helper.rb
|
83
79
|
- test/host.rb
|
84
80
|
- test/integration.rb
|
81
|
+
- test/layout.rb
|
85
82
|
- test/match.rb
|
86
83
|
- test/number.rb
|
87
84
|
- test/on.rb
|
88
85
|
- test/param.rb
|
89
86
|
- test/path.rb
|
87
|
+
- test/root.rb
|
90
88
|
- test/run.rb
|
91
89
|
- test/segment.rb
|
92
90
|
has_rdoc: true
|
93
91
|
homepage: http://github.com/soveran/cuba
|
94
92
|
licenses: []
|
95
|
-
|
96
93
|
post_install_message:
|
97
94
|
rdoc_options: []
|
98
|
-
|
99
|
-
require_paths:
|
95
|
+
require_paths:
|
100
96
|
- lib
|
101
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
98
|
none: false
|
103
|
-
requirements:
|
104
|
-
- -
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
version:
|
107
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
104
|
none: false
|
109
|
-
requirements:
|
110
|
-
- -
|
111
|
-
- !ruby/object:Gem::Version
|
112
|
-
version:
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
113
109
|
requirements: []
|
114
|
-
|
115
110
|
rubyforge_project:
|
116
|
-
rubygems_version: 1.6.
|
111
|
+
rubygems_version: 1.6.2
|
117
112
|
signing_key:
|
118
113
|
specification_version: 3
|
119
114
|
summary: Microframework for web applications.
|
120
115
|
test_files: []
|
121
|
-
|