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 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
-