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 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 "" do
78
- res.write "Home"
79
- end
81
+ # only GET requests
82
+ on get do
80
83
 
81
- # /about
82
- on "about" do
83
- res.write "About"
84
- end
84
+ # /
85
+ on "" do
86
+ res.write "Home"
87
+ end
85
88
 
86
- # /styles/basic.css
87
- on "styles", extension("css") do |file|
88
- res.write "Filename: #{file}" #=> "Filename: basic"
89
- end
89
+ # /about
90
+ on "about" do
91
+ res.write "About"
92
+ end
90
93
 
91
- # /post/2011/02/16/hello
92
- on "post/:y/:m/:d/:slug" do |y, m, d, slug|
93
- res.write "#{y}-#{m}-#{d} #{slug}" #=> "2011-02-16 hello"
94
- end
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
- # /username/foobar
97
- on "username/:username" do |username|
104
+ # /username/foobar
105
+ on "username/:username" do |username|
98
106
 
99
- user = User.find_by_username(username) # username == "foobar"
107
+ user = User.find_by_username(username) # username == "foobar"
100
108
 
101
- # /username/foobar/posts
102
- on "posts" do
109
+ # /username/foobar/posts
110
+ on "posts" do
103
111
 
104
- # You can access `user` here, because the `on` blocks
105
- # are closures.
106
- res.write "Total Posts: #{user.posts.size}" #=> "Total Posts: 6"
107
- end
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
- # /username/foobar/following
110
- on "following" do
111
- res.write user.following.size #=> "1301"
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
- # /search?q=barbaz
116
- on "search", param("q") do |query|
117
- res.write "Searched for #{query}" #=> "Searched for barbaz"
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
- That's it, you can now run `rackup` and enjoy what you have just created.
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 = "2.0.0"
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
- s.files = ["LICENSE", "README.markdown", "Rakefile", "lib/cuba/ron.rb", "lib/cuba/test.rb", "lib/cuba/version.rb", "lib/cuba.rb", "cuba.gemspec", "test/accept.rb", "test/captures.rb", "test/composition.rb", "test/extension.rb", "test/helper.rb", "test/host.rb", "test/integration.rb", "test/match.rb", "test/number.rb", "test/on.rb", "test/param.rb", "test/path.rb", "test/run.rb", "test/segment.rb"]
10
- s.add_dependency "rack", "~> 1.2"
11
- s.add_dependency "tilt", "~> 1.2"
12
- s.add_development_dependency "cutest", "~> 1.0"
13
- s.add_development_dependency "capybara", "~> 0.4"
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
- def render(template, locals = {}, options = {})
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"] = "/#{match.post_match}"
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
@@ -3,7 +3,11 @@ require "cutest"
3
3
  require "capybara/dsl"
4
4
 
5
5
  class Cutest::Scope
6
- include Capybara
6
+ if defined? Capybara::DSL
7
+ include Capybara::DSL
8
+ else
9
+ include Capybara
10
+ end
7
11
  end
8
12
 
9
13
  Capybara.app = Cuba
data/lib/cuba/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cuba
2
- VERSION = "2.0.0"
2
+ VERSION = "2.0.1"
3
3
  end
data/test/helper.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  $:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
2
2
  require "cuba"
3
- require "cutest"
4
3
 
5
4
  prepare { Cuba.reset! }
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
- prerelease: false
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: "1.2"
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
- requirement: &id002 !ruby/object:Gem::Requirement
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: "1.2"
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
- requirement: &id003 !ruby/object:Gem::Requirement
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: "1.0"
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
- requirement: &id004 !ruby/object:Gem::Requirement
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: "0.4"
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
58
56
  type: :development
59
- version_requirements: *id004
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: "0"
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: "0"
105
+ requirements:
106
+ - - ! '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
113
109
  requirements: []
114
-
115
110
  rubyforge_project:
116
- rubygems_version: 1.6.0
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
-