syro 2.2.0 → 3.0.0

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.
Files changed (7) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +6 -0
  3. data/README.md +55 -2
  4. data/lib/syro.rb +36 -19
  5. data/syro.gemspec +2 -2
  6. data/test/all.rb +50 -14
  7. metadata +6 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0861a7a3ac07757e8fb462b0a61b5dc734cade04
4
- data.tar.gz: 3cba990483608d42a41c7b1f80e50dec57ef2945
3
+ metadata.gz: 26150785e6dd591e63f5e670b6dcc2a27dd01c08
4
+ data.tar.gz: ea5d9a93323838ee03e3ca140946cee52a8cf339
5
5
  SHA512:
6
- metadata.gz: 7f13c5c536db61588a19a5b45d49dcf9f48509e9b8a8deda5ccf95761b417523456f81f6d070518d0935ba2348cf5507d429f9437510f43d789ce2c07165c20a
7
- data.tar.gz: 9c0ef31436e67e67fa0def5e8b770bc838fb545cce5d636a1882216b4e6124a0206a707d5a9847f628861df9926dfcd3b4947be33bbdb4e0dd545c29d2107b53
6
+ metadata.gz: e07343b0890bf4820471ebe54a7947713956e506465b0b5eff37c42fbeb50b0bf0957f57693d34118b0dcbe40ccd669689d11d4f3263330f712bdb2a0eaf2739
7
+ data.tar.gz: 50a533a7933292c1b29fbcfd0bd8f8347128e7b6110ba97ce063939086cd86ffd52b2e4023e8800efee0aed43fa8f24a1a713a99317064140abbbdfc231acce6
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 3.0.0
2
+
3
+ * Change how status codes are set.
4
+ * Change how the Content-Type is set.
5
+ * Add Content-Type helpers to Syro::Response.
6
+
1
7
  2.2.0
2
8
 
3
9
  * Change gemspec to allow Rack 2.
data/README.md CHANGED
@@ -239,6 +239,61 @@ the command `run(Users)`, an inbox can be provided as the second
239
239
  argument: `run(Users, inbox)`. That allows apps to share previous
240
240
  captures.
241
241
 
242
+ Status code
243
+ -----------
244
+
245
+ By default the status code is set to `404`. If both path and request
246
+ method are matched, the status is automatically changed to `200`.
247
+ You can change the status code by assigning a number to `res.status`,
248
+ for example:
249
+
250
+ ```ruby
251
+ post do
252
+ ...
253
+ res.status = 201
254
+ end
255
+ ```
256
+
257
+ Content type
258
+ ------------
259
+
260
+ There's no default value for the content type header, but there's
261
+ a handy way of setting the desired value.
262
+
263
+ In order to write the body of the response, the `res.write` method
264
+ is used:
265
+
266
+ ```ruby
267
+ res.write "hello world"
268
+ ```
269
+
270
+ It has the drawback of leaving the `Content-Type` header empty.
271
+ Three alternative methods are provided, and more can be added by
272
+ using custom Decks.
273
+
274
+ Setting the Content-Type as `"text/plain"`:
275
+
276
+ ```ruby
277
+ res.text "hello world"
278
+ ```
279
+
280
+ Setting the Content-Type as `"text/html"`:
281
+
282
+ ```ruby
283
+ res.html "hello world"
284
+ ```
285
+
286
+ Setting the Content-Type as `"application/json"`:
287
+
288
+ ```ruby
289
+ res.json "hello world"
290
+ ```
291
+
292
+ Note that aside from writing the response body and setting the value
293
+ for the Content-Type header, no encoding or serialization takes
294
+ place. If you want to return a JSON encoded response, make sure to
295
+ encode the objects yourself (i.e., `res.json JSON.dump(...)`).
296
+
242
297
  Security
243
298
  --------
244
299
 
@@ -260,7 +315,6 @@ just use `Rack::Builder`:
260
315
 
261
316
  ```ruby
262
317
  App = Rack::Builder.new do
263
-
264
318
  use Rack::Session::Cookie, secret: "..."
265
319
 
266
320
  run Syro.new do
@@ -268,7 +322,6 @@ App = Rack::Builder.new do
268
322
  res.write("Hello, world")
269
323
  end
270
324
  end
271
-
272
325
  end
273
326
  ```
274
327
 
@@ -28,7 +28,12 @@ class Syro
28
28
 
29
29
  class Response
30
30
  LOCATION = "Location".freeze # :nodoc:
31
- DEFAULT = "text/html".freeze # :nodoc:
31
+
32
+ module ContentType
33
+ HTML = "text/html".freeze # :nodoc:
34
+ TEXT = "text/plain".freeze # :nodoc:
35
+ JSON = "application/json".freeze # :nodoc:
36
+ end
32
37
 
33
38
  # The status of the response.
34
39
  #
@@ -58,7 +63,7 @@ class Syro
58
63
  attr_reader :headers
59
64
 
60
65
  def initialize(headers = {})
61
- @status = nil
66
+ @status = 404
62
67
  @headers = headers
63
68
  @body = []
64
69
  @length = 0
@@ -103,6 +108,24 @@ class Syro
103
108
  @body << s
104
109
  end
105
110
 
111
+ # Write response body as text/plain
112
+ def text(str)
113
+ @headers[Rack::CONTENT_TYPE] = ContentType::TEXT
114
+ write(str)
115
+ end
116
+
117
+ # Write response body as text/html
118
+ def html(str)
119
+ @headers[Rack::CONTENT_TYPE] = ContentType::HTML
120
+ write(str)
121
+ end
122
+
123
+ # Write response body as application/json
124
+ def json(str)
125
+ @headers[Rack::CONTENT_TYPE] = ContentType::JSON
126
+ write(str)
127
+ end
128
+
106
129
  # Sets the `Location` header to `path` and updates the status to
107
130
  # `status`. By default, `status` is `302`.
108
131
  #
@@ -121,10 +144,10 @@ class Syro
121
144
  @status = status
122
145
  end
123
146
 
124
- # Returns an array with three elements: the status, headers and body.
125
- # If the status is not set, the status is set to 404 if empty body,
126
- # otherwise the status is set to 200 and updates the `Content-Type`
127
- # header to `text/html`.
147
+ # Returns an array with three elements: the status, headers and
148
+ # body. If the status is not set, the status is set to 404. If
149
+ # a match is found for both path and request method, the status
150
+ # is changed to 200.
128
151
  #
129
152
  # res.status = 200
130
153
  # res.finish
@@ -140,12 +163,6 @@ class Syro
140
163
  # # => [200, { "Content-Type" => "text/html" }, ["syro"]]
141
164
  #
142
165
  def finish
143
- @status ||= (@body.empty?) ? 404 : 200
144
-
145
- if @body.any?
146
- @headers[Rack::CONTENT_TYPE] ||= DEFAULT
147
- end
148
-
149
166
  [@status, @headers, @body]
150
167
  end
151
168
 
@@ -314,31 +331,31 @@ class Syro
314
331
  end
315
332
 
316
333
  def get
317
- root { yield } if req.get?
334
+ root { res.status = 200; yield } if req.get?
318
335
  end
319
336
 
320
337
  def put
321
- root { yield } if req.put?
338
+ root { res.status = 200; yield } if req.put?
322
339
  end
323
340
 
324
341
  def head
325
- root { yield } if req.head?
342
+ root { res.status = 200; yield } if req.head?
326
343
  end
327
344
 
328
345
  def post
329
- root { yield } if req.post?
346
+ root { res.status = 200; yield } if req.post?
330
347
  end
331
348
 
332
349
  def patch
333
- root { yield } if req.patch?
350
+ root { res.status = 200; yield } if req.patch?
334
351
  end
335
352
 
336
353
  def delete
337
- root { yield } if req.delete?
354
+ root { res.status = 200; yield } if req.delete?
338
355
  end
339
356
 
340
357
  def options
341
- root { yield } if req.options?
358
+ root { res.status = 200; yield } if req.options?
342
359
  end
343
360
  end
344
361
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "syro"
3
- s.version = "2.2.0"
3
+ s.version = "3.0.0"
4
4
  s.summary = "Simple router"
5
5
  s.description = "Simple router for web applications"
6
6
  s.authors = ["Michel Martens"]
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.files = `git ls-files`.split("\n")
12
12
 
13
13
  s.add_dependency "seg"
14
- s.add_dependency "rack", ">= 1.6.0"
14
+ s.add_dependency "rack", "~> 2"
15
15
  s.add_development_dependency "cutest"
16
16
  s.add_development_dependency "rack-test"
17
17
  end
@@ -6,9 +6,9 @@ class RackApp
6
6
  end
7
7
  end
8
8
 
9
- class TextualDeck < Syro::Deck
10
- def text(str)
11
- res[Rack::CONTENT_TYPE] = "text/plain"
9
+ class MarkdownDeck < Syro::Deck
10
+ def markdown(str)
11
+ res[Rack::CONTENT_TYPE] = "text/markdown"
12
12
  res.write(str)
13
13
  end
14
14
  end
@@ -41,9 +41,9 @@ class CustomRequestAndResponse < Syro::Deck
41
41
  end
42
42
  end
43
43
 
44
- textual = Syro.new(TextualDeck) do
44
+ markdown = Syro.new(MarkdownDeck) do
45
45
  get do
46
- text("GET /textual")
46
+ markdown("GET /markdown")
47
47
  end
48
48
  end
49
49
 
@@ -182,15 +182,15 @@ app = Syro.new do
182
182
  end
183
183
  end
184
184
 
185
- on "textual" do
186
- run(textual)
185
+ on "markdown" do
186
+ run(markdown)
187
187
  end
188
188
 
189
189
  on "headers" do
190
190
  run(default_headers)
191
191
  end
192
192
 
193
- on "json" do
193
+ on "custom" do
194
194
  run(json)
195
195
  end
196
196
 
@@ -198,6 +198,22 @@ app = Syro.new do
198
198
  res.status = 401
199
199
  res.write("Unauthorized")
200
200
  end
201
+
202
+ on "write" do
203
+ res.write "nil!"
204
+ end
205
+
206
+ on "text" do
207
+ res.text "plain!"
208
+ end
209
+
210
+ on "html" do
211
+ res.html "html!"
212
+ end
213
+
214
+ on "json" do
215
+ res.json "json!"
216
+ end
201
217
  end
202
218
 
203
219
  setup do
@@ -209,6 +225,10 @@ test "path + verb" do |f|
209
225
  assert_equal 200, f.last_response.status
210
226
  assert_equal "GET /foo/bar", f.last_response.body
211
227
 
228
+ f.get("/bar/baz")
229
+ assert_equal 404, f.last_response.status
230
+ assert_equal "", f.last_response.body
231
+
212
232
  f.put("/foo/bar")
213
233
  assert_equal 200, f.last_response.status
214
234
  assert_equal "PUT /foo/bar", f.last_response.body
@@ -267,7 +287,9 @@ end
267
287
  test "captures" do |f|
268
288
  f.get("/users/42")
269
289
  assert_equal "GET /users/42", f.last_response.body
270
- assert_equal 200, f.last_response.status
290
+
291
+ # As the verb was not mached, the status is 404.
292
+ assert_equal 404, f.last_response.status
271
293
  end
272
294
 
273
295
  test "post values" do |f|
@@ -306,9 +328,9 @@ test "redirect" do |f|
306
328
  end
307
329
 
308
330
  test "custom deck" do |f|
309
- f.get("/textual")
310
- assert_equal "GET /textual", f.last_response.body
311
- assert_equal "text/plain", f.last_response.headers["Content-Type"]
331
+ f.get("/markdown")
332
+ assert_equal "GET /markdown", f.last_response.body
333
+ assert_equal "text/markdown", f.last_response.headers["Content-Type"]
312
334
  assert_equal 200, f.last_response.status
313
335
  end
314
336
 
@@ -321,15 +343,29 @@ end
321
343
  test "custom request and response class" do |f|
322
344
  params = JSON.generate(foo: "foo")
323
345
 
324
- f.post("/json", params)
346
+ f.post("/custom", params)
325
347
 
326
348
  assert_equal params, f.last_response.body
327
349
  end
328
350
 
329
- test "set content type if body is set" do |f|
351
+ test "don't set content type by default" do |f|
330
352
  f.get("/private")
331
353
 
332
354
  assert_equal 401, f.last_response.status
333
355
  assert_equal "Unauthorized", f.last_response.body
356
+ assert_equal nil, f.last_response.headers["Content-Type"]
357
+ end
358
+
359
+ test "content type" do |f|
360
+ f.get("/write")
361
+ assert_equal nil, f.last_response.headers["Content-Type"]
362
+
363
+ f.get("/text")
364
+ assert_equal "text/plain", f.last_response.headers["Content-Type"]
365
+
366
+ f.get("/html")
334
367
  assert_equal "text/html", f.last_response.headers["Content-Type"]
368
+
369
+ f.get("/json")
370
+ assert_equal "application/json", f.last_response.headers["Content-Type"]
335
371
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syro
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michel Martens
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-01 00:00:00.000000000 Z
11
+ date: 2017-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: seg
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.6.0
33
+ version: '2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.6.0
40
+ version: '2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: cutest
43
43
  requirement: !ruby/object:Gem::Requirement