cuba 3.1.0 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b881a2c6bb3396ac4515bea4b2a9745933f071b2
4
+ data.tar.gz: dad770ec883f93c34cd0f0bb55a0fb5f8a782096
5
+ SHA512:
6
+ metadata.gz: 16ff53505523c87084f283005ad9819e06d87676d08663ebe430c15924beb7265a55c88328a7b71dd04fb3c13af5035b590e620319c3752b8da7515aa054d9d4
7
+ data.tar.gz: 5e1ef15fa6595a48050e3fbdf1fbd71cba9615a509631a5724445bb20bd37e6f5b1b9eb40d8295c0474c8e533a22f3bf14387a7443e4440133fbe97a917beaf1
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ 3.1.1
2
+
3
+ * Add support for custom default layouts.
4
+
1
5
  3.1.0
2
6
 
3
7
  * Do a deep clone of the settings object during inheritance.
data/README.md CHANGED
@@ -8,13 +8,17 @@ _n_. a microframework for web development.
8
8
  Community
9
9
  ---------
10
10
 
11
- Meet us on IRC: [#cuba.rb](irc://chat.freenode.net/#cuba.rb) on [freenode.net](http://freenode.net/)
11
+ Meet us on IRC: [#cuba.rb][irc] on [freenode.net][freenode].
12
+
13
+ [irc]: irc://chat.freenode.net/#cuba.rb
14
+ [freenode]: http://freenode.net/
12
15
 
13
16
  Description
14
17
  -----------
15
18
 
16
- Cuba is a microframework for web development originally inspired by [Rum][rum],
17
- a tiny but powerful mapper for [Rack][rack] applications.
19
+ Cuba is a microframework for web development originally inspired
20
+ by [Rum][rum], a tiny but powerful mapper for [Rack][rack]
21
+ applications.
18
22
 
19
23
  It integrates many templates via [Tilt][tilt], and testing via
20
24
  [Cutest][cutest] and [Capybara][capybara].
@@ -24,6 +28,14 @@ It integrates many templates via [Tilt][tilt], and testing via
24
28
  [tilt]: http://github.com/rtomayko/tilt
25
29
  [cutest]: http://github.com/djanowski/cutest
26
30
  [capybara]: http://github.com/jnicklas/capybara
31
+ [rack-test]: https://github.com/brynary/rack-test
32
+
33
+ Installation
34
+ ------------
35
+
36
+ ``` console
37
+ $ gem install cuba
38
+ ```
27
39
 
28
40
  Usage
29
41
  -----
@@ -33,8 +45,10 @@ Here's a simple application:
33
45
  ``` ruby
34
46
  # cat hello_world.rb
35
47
  require "cuba"
48
+ require "rack/protection"
36
49
 
37
- Cuba.use Rack::Session::Cookie
50
+ Cuba.use Rack::Session::Cookie, :secret => "__a_very_long_string__"
51
+ Cuba.use Rack::Protection
38
52
 
39
53
  Cuba.define do
40
54
  on get do
@@ -47,14 +61,22 @@ Cuba.define do
47
61
  end
48
62
  end
49
63
  end
64
+ ```
65
+
66
+ And the test file:
50
67
 
68
+ ``` ruby
51
69
  # cat hello_world_test.rb
52
70
  require "cuba/test"
71
+ require "./hello_world"
53
72
 
54
73
  scope do
55
74
  test "Homepage" do
56
- visit "/"
57
- assert has_content?("Hello world!")
75
+ get "/"
76
+
77
+ follow_redirect!
78
+
79
+ assert_equal "Hello world!", last_response.body
58
80
  end
59
81
  end
60
82
  ```
@@ -77,8 +99,10 @@ Here's an example showcasing how different matchers work:
77
99
 
78
100
  ``` ruby
79
101
  require "cuba"
102
+ require "rack/protection"
80
103
 
81
- Cuba.use Rack::Session::Cookie
104
+ Cuba.use Rack::Session::Cookie, :secret => "__a_very_long_string__"
105
+ Cuba.use Rack::Protection
82
106
 
83
107
  Cuba.define do
84
108
 
@@ -148,23 +172,194 @@ Cuba.define do
148
172
  end
149
173
  ```
150
174
 
175
+ Status codes
176
+ ------------
177
+
178
+ As soon as an `on` block is executed, the status code for the
179
+ response is changed to 200. The default status code is 404, and it
180
+ is returned if no `on` block succeeds inside a Cuba app.
181
+
182
+ As this behavior can be tricky, let's look at some examples:
183
+
184
+ ``` ruby
185
+ Cuba.define do
186
+ on get do
187
+ on "hello" do
188
+ res.write "hello world"
189
+ end
190
+ end
191
+ end
192
+
193
+ # Requests:
194
+ #
195
+ # GET / # 200, ""
196
+ # GET /hello # 200, "hello world"
197
+ # GET /hello/world # 200, "hello world"
198
+ ```
199
+
200
+ As you can see, as soon as `on get` matched, the status code was
201
+ changed to 200. If you expected some of those requests to return a
202
+ 404 status code, you may be surprised by this behavior.
203
+
204
+ In the following example, as both arguments to `on` must match,
205
+ the requests to `/` return 404.
206
+
207
+ ``` ruby
208
+ Cuba.define do
209
+ on get, "hello" do
210
+ res.write "hello world"
211
+ end
212
+ end
213
+
214
+ # Requests:
215
+ #
216
+ # GET / # 404, ""
217
+ # GET /hello # 200, "hello world"
218
+ # GET /hello/world # 200, "hello world"
219
+ ```
220
+
221
+ Another way is to add a default block:
222
+
223
+ ``` ruby
224
+ Cuba.define do
225
+ on get do
226
+ on "hello" do
227
+ res.write "hello world"
228
+ end
229
+
230
+ on default do
231
+ res.status = 404
232
+ end
233
+ end
234
+ end
235
+
236
+ # Requests:
237
+ #
238
+ # GET / # 404, ""
239
+ # GET /hello # 200, "hello world"
240
+ # GET /hello/world # 200, "hello world"
241
+ ```
242
+
243
+ Yet another way is to mount an application with routes that don't
244
+ match the request:
245
+
246
+ ``` ruby
247
+ SomeApp = Cuba.new do
248
+ on "bye" do
249
+ res.write "bye!"
250
+ end
251
+ end
252
+
253
+ Cuba.define do
254
+ on get do
255
+ run SomeApp
256
+ end
257
+ end
258
+
259
+ # Requests:
260
+ #
261
+ # GET / # 404, ""
262
+ # GET /hello # 404, ""
263
+ # GET /hello/world # 404, ""
264
+ ```
265
+
266
+ As Cuba encourages the composition of applications, this last
267
+ example is a very common pattern.
268
+
269
+ You can also change the status code at any point inside the define
270
+ block. That way you can change the default status, as shown in the
271
+ following example:
272
+
273
+ ``` ruby
274
+ Cuba.define do
275
+ res.status = 404
276
+
277
+ on get do
278
+ on "hello" do
279
+ res.status = 200
280
+ res.write "hello world"
281
+ end
282
+ end
283
+ end
284
+
285
+ # Requests:
286
+ #
287
+ # GET / # 404, ""
288
+ # GET /hello # 200, "hello world"
289
+ # GET /hello/world # 200, "hello world"
290
+ ```
291
+
292
+ If you really want to return 404 for everything under "hello", you
293
+ can match the end of line:
294
+
295
+ ``` ruby
296
+ Cuba.define do
297
+ res.status = 404
298
+
299
+ on get do
300
+ on /hello\/?\z/ do
301
+ res.status = 200
302
+ res.write "hello world"
303
+ end
304
+ end
305
+ end
306
+
307
+ # Requests:
308
+ #
309
+ # GET / # 404, ""
310
+ # GET /hello # 200, "hello world"
311
+ # GET /hello/world # 404, ""
312
+ ```
313
+
314
+ This last example is not a common usage pattern. It's here only to
315
+ illustrate how Cuba can be adapted for different use cases.
316
+
317
+ If you need this behavior, you can create a helper:
318
+
319
+ ``` ruby
320
+ module TerminalMatcher
321
+ def terminal(path)
322
+ /#{path}\/?\z/
323
+ end
324
+ end
325
+
326
+ Cuba.plugin TerminalMatcher
327
+
328
+ Cuba.define do
329
+ res.status = 404
330
+
331
+ on get do
332
+ on terminal("hello") do
333
+ res.status = 200
334
+ res.write "hello world"
335
+ end
336
+ end
337
+ end
338
+ ```
339
+
151
340
  Security
152
341
  --------
153
342
 
154
343
  The favorite security layer for Cuba is
155
- [Rack::Protection](https://github.com/rkh/rack-protection). It is not
156
- included by default because there are legitimate uses for plain Cuba
157
- (for instance, when designing an API).
344
+ [Rack::Protection][rack-protection]. It is not included by default
345
+ because there are legitimate uses for plain Cuba (for instance,
346
+ when designing an API).
158
347
 
159
- If you are building a web application, by all means make sure to
160
- include a security layer. As it is the convention for unsafe
348
+ If you are building a web application, by all means make sure
349
+ to include a security layer. As it is the convention for unsafe
161
350
  operations, only POST, PUT and DELETE requests are monitored.
162
351
 
352
+ You should also always set a session secret to some undisclosed
353
+ value. Keep in mind that the content in the session cookie is
354
+ *not* encrypted.
355
+
356
+ [rack-protection]: https://github.com/rkh/rack-protection
357
+
163
358
  ``` ruby
164
359
  require "cuba"
165
360
  require "rack/protection"
166
361
 
167
- Cuba.use Rack::Session::Cookie
362
+ Cuba.use Rack::Session::Cookie, :secret => "__a_very_long_string__"
168
363
  Cuba.use Rack::Protection
169
364
  Cuba.use Rack::Protection::RemoteReferrer
170
365
 
@@ -210,7 +405,7 @@ instances of [Rack::Request][request] and `Cuba::Response` respectively, and
210
405
  [response]: http://rack.rubyforge.org/doc/classes/Rack/Response.html
211
406
 
212
407
  Those objects are helpers for accessing the request and for building
213
- the response. Most of the time, you will just use `req.write`.
408
+ the response. Most of the time, you will just use `res.write`.
214
409
 
215
410
  If you want to use custom `Request` or `Response` objects, you can
216
411
  set the new values as follows:
@@ -276,15 +471,32 @@ end
276
471
  Testing
277
472
  -------
278
473
 
279
- Given that Cuba is essentially Rack, it is very easy to test with `Webrat` or
280
- `Capybara`. Cuba's own tests are written with a combination of [Cutest][cutest]
281
- and [Capybara][capybara], and if you want to use the same for your tests it is
282
- as easy as requiring `cuba/test`:
474
+ Given that Cuba is essentially Rack, it is very easy to test with
475
+ `Rack::Test`, `Webrat` or `Capybara`. Cuba's own tests are written
476
+ with a combination of [Cutest][cutest] and [Rack::Test][rack-test],
477
+ and if you want to use the same for your tests it is as easy as
478
+ requiring `cuba/test`:
283
479
 
284
480
  ``` ruby
285
481
  require "cuba/test"
286
482
  require "your/app"
287
483
 
484
+ scope do
485
+ test "Homepage" do
486
+ get "/"
487
+
488
+ assert_equal "Hello world!", last_response.body
489
+ end
490
+ end
491
+ ```
492
+
493
+ If you prefer to use [Capybara][capybara], instead of requiring
494
+ `cuba/test` you can require `cuba/capybara`:
495
+
496
+ ``` ruby
497
+ require "cuba/capybara"
498
+ require "your/app"
499
+
288
500
  scope do
289
501
  test "Homepage" do
290
502
  visit "/"
@@ -294,8 +506,8 @@ scope do
294
506
  end
295
507
  ```
296
508
 
297
- To read more about testing, check the documentation for [Cutest][cutest] and
298
- [Capybara][capybara].
509
+ To read more about testing, check the documentation for
510
+ [Cutest][cutest], [Rack::Test][rack-test] and [Capybara][capybara].
299
511
 
300
512
  Settings
301
513
  --------
@@ -341,6 +553,26 @@ end
341
553
  Note that in order to use this plugin you need to have [Tilt][tilt] installed, along
342
554
  with the templating engines you want to use.
343
555
 
556
+ You can also configure the template engine in the app's settings,
557
+ and that will allow you to skip the file extension when rendering a
558
+ file:
559
+
560
+ ``` ruby
561
+ require "cuba/render"
562
+
563
+ Cuba.plugin Cuba::Render
564
+ Cuba.settings[:render][:template_engine] = "slim"
565
+
566
+ Cuba.define do
567
+ on default do
568
+
569
+ # Now we can use the `view` helper, which guesses the file
570
+ # extension based on the configured template_engine.
571
+ res.write view("home", content: "hello, world")
572
+ end
573
+ end
574
+ ```
575
+
344
576
  Plugins
345
577
  -------
346
578
 
@@ -364,7 +596,7 @@ That's the simplest kind of plugin you'll write. In fact, that's exactly how
364
596
  the `markdown` helper is written in `Cuba::TextHelpers`.
365
597
 
366
598
  A more complicated plugin can make use of `Cuba.settings` to provide default
367
- values. In the following example, note that if the module has a `setup` method it will
599
+ values. In the following example, note that if the module has a `setup` method, it will
368
600
  be called as soon as it is included:
369
601
 
370
602
  ``` ruby
@@ -406,10 +638,3 @@ Cuba.set(:foo, "bar")
406
638
  assert_equal "bar", Cuba.get(:foo)
407
639
  assert_equal "bar", Cuba.settings[:foo]
408
640
  ```
409
-
410
- Installation
411
- ------------
412
-
413
- ``` ruby
414
- $ gem install cuba
415
- ```
data/cuba.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cuba"
3
- s.version = "3.1.0"
3
+ s.version = "3.1.1"
4
4
  s.summary = "Microframework for web applications."
5
5
  s.description = "Cuba is a microframework for web applications."
6
6
  s.authors = ["Michel Martens"]
data/lib/cuba.rb CHANGED
@@ -147,7 +147,7 @@ class Cuba
147
147
  # end
148
148
  #
149
149
  # on get, "signup" do
150
- # res.write "Signup
150
+ # res.write "Signup"
151
151
  # end
152
152
  #
153
153
  # on "user/:id" do |uid|
@@ -197,7 +197,7 @@ class Cuba
197
197
  private :try
198
198
 
199
199
  def consume(pattern)
200
- matchdata = env["PATH_INFO"].match(/\A\/(#{pattern})((?:\/|\z))/)
200
+ matchdata = env["PATH_INFO"].match(/\A\/(#{pattern})(\/|\z)/)
201
201
 
202
202
  return false unless matchdata
203
203
 
data/lib/cuba/render.rb CHANGED
@@ -5,13 +5,14 @@ class Cuba
5
5
  def self.setup(app)
6
6
  app.settings[:render] ||= {}
7
7
  app.settings[:render][:template_engine] ||= "erb"
8
+ app.settings[:render][:layout] ||= "layout"
8
9
  app.settings[:render][:views] ||= File.expand_path("views", Dir.pwd)
9
10
  app.settings[:render][:options] ||= {
10
11
  default_encoding: Encoding.default_external
11
12
  }
12
13
  end
13
14
 
14
- def view(template, locals = {}, layout = "layout")
15
+ def view(template, locals = {}, layout = settings[:render][:layout])
15
16
  partial(layout, { content: partial(template, locals) }.merge(locals))
16
17
  end
17
18
 
data/test/cookie.rb CHANGED
@@ -29,6 +29,6 @@ test "delete cookie" do
29
29
 
30
30
  _, headers, body = Cuba.call(env)
31
31
 
32
- assert_equal "foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT",
32
+ assert_equal "foo=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000",
33
33
  headers["Set-Cookie"]
34
34
  end
data/test/render.rb CHANGED
@@ -58,6 +58,14 @@ scope do
58
58
 
59
59
  assert_response body, ["<title>Cuba: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>\n\n"]
60
60
  end
61
+
62
+ test "custom default layout support" do
63
+ Cuba.settings[:render][:layout] = "layout-alternative"
64
+
65
+ _, _, body = Cuba.call({ "PATH_INFO" => "/home", "SCRIPT_NAME" => "/" })
66
+
67
+ assert_response body, ["<title>Alternative Layout: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>\n"]
68
+ end
61
69
  end
62
70
 
63
71
  test "caching behavior" do
@@ -94,3 +102,18 @@ test "simple layout support" do
94
102
 
95
103
  assert_response resp, ["Header\nThis is the actual content.\nFooter\n"]
96
104
  end
105
+
106
+ test "overrides layout" do
107
+ Cuba.plugin Cuba::Render
108
+ Cuba.settings[:render][:views] = "./test/views"
109
+
110
+ Cuba.define do
111
+ on true do
112
+ res.write view("home", { name: "Agent Smith", title: "Home" }, "layout-alternative")
113
+ end
114
+ end
115
+
116
+ _, _, body = Cuba.call({})
117
+
118
+ assert_response body, ["<title>Alternative Layout: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>\n"]
119
+ end
metadata CHANGED
@@ -1,60 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuba
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
5
- prerelease:
4
+ version: 3.1.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Michel Martens
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-07-24 00:00:00.000000000 Z
11
+ date: 2014-03-09 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rack
16
- requirement: &2152188260 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *2152188260
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: cutest
27
- requirement: &2152187440 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - '>='
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *2152187440
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: rack-test
38
- requirement: &2152186360 !ruby/object:Gem::Requirement
39
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
- - - ! '>='
45
+ - - '>='
42
46
  - !ruby/object:Gem::Version
43
47
  version: '0'
44
48
  type: :development
45
49
  prerelease: false
46
- version_requirements: *2152186360
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
47
55
  - !ruby/object:Gem::Dependency
48
56
  name: tilt
49
- requirement: &2152185380 !ruby/object:Gem::Requirement
50
- none: false
57
+ requirement: !ruby/object:Gem::Requirement
51
58
  requirements:
52
- - - ! '>='
59
+ - - '>='
53
60
  - !ruby/object:Gem::Version
54
61
  version: '0'
55
62
  type: :development
56
63
  prerelease: false
57
- version_requirements: *2152185380
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
58
69
  description: Cuba is a microframework for web applications.
59
70
  email:
60
71
  - michel@soveran.com
@@ -96,26 +107,25 @@ files:
96
107
  - test/settings.rb
97
108
  homepage: http://github.com/soveran/cuba
98
109
  licenses: []
110
+ metadata: {}
99
111
  post_install_message:
100
112
  rdoc_options: []
101
113
  require_paths:
102
114
  - lib
103
115
  required_ruby_version: !ruby/object:Gem::Requirement
104
- none: false
105
116
  requirements:
106
- - - ! '>='
117
+ - - '>='
107
118
  - !ruby/object:Gem::Version
108
119
  version: '0'
109
120
  required_rubygems_version: !ruby/object:Gem::Requirement
110
- none: false
111
121
  requirements:
112
- - - ! '>='
122
+ - - '>='
113
123
  - !ruby/object:Gem::Version
114
124
  version: '0'
115
125
  requirements: []
116
126
  rubyforge_project:
117
- rubygems_version: 1.8.11
127
+ rubygems_version: 2.0.3
118
128
  signing_key:
119
- specification_version: 3
129
+ specification_version: 4
120
130
  summary: Microframework for web applications.
121
131
  test_files: []