cuba 2.0.0 → 2.0.1
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.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
|
-
|