tynn 1.4.0 → 2.0.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +540 -25
- data/lib/tynn.rb +50 -103
- data/lib/tynn/base.rb +97 -0
- data/lib/tynn/default_headers.rb +50 -0
- data/lib/tynn/environment.rb +54 -28
- data/lib/tynn/json.rb +7 -18
- data/lib/tynn/render.rb +16 -12
- data/lib/tynn/request.rb +54 -38
- data/lib/tynn/response.rb +33 -173
- data/lib/tynn/secure_headers.rb +28 -31
- data/lib/tynn/session.rb +68 -34
- data/lib/tynn/settings.rb +56 -27
- data/lib/tynn/ssl.rb +78 -70
- data/lib/tynn/static.rb +12 -21
- data/lib/tynn/test.rb +51 -78
- data/lib/tynn/version.rb +4 -7
- data/test/default_headers_test.rb +21 -9
- data/test/environment_test.rb +57 -16
- data/test/helper.rb +4 -6
- data/test/json_test.rb +48 -10
- data/test/middleware_test.rb +63 -54
- data/test/plugin_test.rb +121 -0
- data/test/render_test.rb +56 -65
- data/test/request_headers_test.rb +33 -0
- data/test/routing_test.rb +111 -0
- data/test/secure_headers_test.rb +29 -17
- data/test/session_test.rb +44 -11
- data/test/settings_test.rb +53 -0
- data/test/ssl_test.rb +107 -35
- data/test/static_test.rb +25 -6
- metadata +33 -38
- data/lib/tynn/all_methods.rb +0 -50
- data/lib/tynn/hmote.rb +0 -34
- data/lib/tynn/not_found.rb +0 -20
- data/lib/tynn/protection.rb +0 -45
- data/test/all_methods_test.rb +0 -16
- data/test/core_test.rb +0 -65
- data/test/hmote_test.rb +0 -78
- data/test/not_found_test.rb +0 -19
- data/test/protection_test.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3428a8bf437b03bf9e9dc2d2568143010f5a8be7
|
4
|
+
data.tar.gz: 9a36c6091a73ced16b4b5a5e9f8cec60fa6fd39e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25196be28e4b69d4d0ea609bcdfa7fa08276716c6e94753347ac17c8dfad6d6c9f9b390559b79ca9c9f67fbec78dec2379a481c21497460768502649bc95c63e
|
7
|
+
data.tar.gz: a5bdf9e80a0d95d9d172264a00612dc0c86666a1c25c761598363e100279f6c32d09d20235d3d1a0216a0ed29f2890a80da263e431c9e30f125aaa3081a418fc
|
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2015 Francesco Rodríguez and contributors
|
3
|
+
Copyright (c) 2015-2016 Francesco Rodríguez and contributors
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,50 +1,565 @@
|
|
1
|
-
Tynn
|
2
|
-
====
|
1
|
+
# Tynn
|
3
2
|
|
4
|
-
|
3
|
+
[![Build Status](https://travis-ci.org/frodsan/tynn.svg?branch=master)](https://travis-ci.org/frodsan/tynn)
|
4
|
+
[![Dependency Status](https://gemnasium.com/badges/github.com/frodsan/tynn.svg)](https://gemnasium.com/github.com/frodsan/tynn)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/frodsan/tynn/badges/gpa.svg)](https://codeclimate.com/github/frodsan/tynn)
|
6
|
+
[![Join the chat at https://gitter.im/frodsan/tynn](https://badges.gitter.im/frodsan/tynn.svg)](https://gitter.im/frodsan/tynn?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
5
7
|
|
6
|
-
|
7
|
-
-----------
|
8
|
+
A thin library for web development in Ruby.
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
* [Getting Started](#getting-started)
|
11
|
+
* [Assumptions](#assumptions)
|
12
|
+
* [Installation](#installation)
|
13
|
+
* [Hello World!](#hello-world)
|
14
|
+
* [Under the Hood](#under-the-hood)
|
15
|
+
* [Tynn on Rack](#tynn-on-rack)
|
16
|
+
* [Routing Basics](#routing-basics)
|
17
|
+
* [Managing Request and Response](#managing-request-and-response)
|
18
|
+
* [Redirecting a Request](#redirecting-a-request)
|
19
|
+
* [Halting a Request](#halting-a-request)
|
20
|
+
* [Extending Tynn](#extending-tynn)
|
21
|
+
* [Middleware](#middleware)
|
22
|
+
* [Plugins](#plugins)
|
23
|
+
* [Settings](#settings)
|
24
|
+
* [Default Plugins](#default-plugins)
|
25
|
+
* [Environments](#environments)
|
26
|
+
* [Method Override](#method-override)
|
27
|
+
* [Static Files](#static-files)
|
28
|
+
* [Security](#security)
|
29
|
+
* [Testing](#testing)
|
30
|
+
* [API Reference](http://api.tynn.xyz/2.0.0)
|
31
|
+
* [Changelog](#changelog)
|
32
|
+
* [Development](#development)
|
33
|
+
* [Contributing](#contributing)
|
34
|
+
* [Build History](#build-history)
|
35
|
+
* [License](#license)
|
11
36
|
|
12
|
-
|
13
|
-
-----
|
37
|
+
**NOTE. There is an online version of this README at http://tynn.xyz/.**
|
14
38
|
|
15
|
-
|
39
|
+
## Getting Started
|
40
|
+
|
41
|
+
Tynn is a minimal and flexible library for building JSON web services and web applications in Ruby. It's designed with two main goals: simplicity and extensibility.
|
42
|
+
|
43
|
+
Tynn offers the essentials to handle HTTP requests and also includes mechanisms to easily extend its functionality through [plugins](#plugins) and [middleware][middleware]. Tynn ships with a set of [default plugins](#default-plugins) that you can combine to meet your needs.
|
44
|
+
|
45
|
+
Tynn is not a framework. There is no built-in support for connecting to databases or a common application architecture. This gives you the freedom to choose the appropiate tools for the job at hand.
|
46
|
+
|
47
|
+
Like most web libraries in Ruby, Tynn is built on top of [Rack], a Ruby webserver interface. Because of this, it has the benefits of using existing libraries and a variety of web servers for free.
|
48
|
+
|
49
|
+
Tynn takes design cues from other web libraries like [Rails], [Sinatra], and [Cuba]. Under the hood, it uses [Syro], a fast router for web applications.
|
50
|
+
|
51
|
+
### Assumptions
|
52
|
+
|
53
|
+
This section serves as a high-level introduction to the core features of Tynn. It also covers installation and walks through the creation of a simple application. To get the most out of it, it's recommended to have a basic knowledge about Ruby and HTTP.
|
54
|
+
|
55
|
+
### Installation
|
56
|
+
|
57
|
+
Installing Tynn is pretty straightforward. From the command line, use the `gem` command:
|
58
|
+
|
59
|
+
```
|
60
|
+
$ gem install tynn
|
61
|
+
```
|
62
|
+
|
63
|
+
If you prefer to use [Bundler] instead, set up the environment with:
|
64
|
+
|
65
|
+
```
|
66
|
+
$ bundle init
|
67
|
+
```
|
68
|
+
|
69
|
+
Then, update the contents of the generated Gemfile to:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
source "https://rubygems.org"
|
73
|
+
|
74
|
+
gem "tynn", "~> 2.0"
|
75
|
+
```
|
76
|
+
|
77
|
+
Finally, install the dependencies with:
|
78
|
+
|
79
|
+
```
|
80
|
+
$ bundle install
|
81
|
+
```
|
82
|
+
|
83
|
+
Now you can create your first Tynn app!
|
84
|
+
|
85
|
+
### Hello World!
|
86
|
+
|
87
|
+
Let's start with a minimal application. Open your preferred text editor and enter the following code:
|
16
88
|
|
17
89
|
```ruby
|
18
|
-
# config.ru
|
19
90
|
require "tynn"
|
20
91
|
|
21
92
|
Tynn.define do
|
22
|
-
root do
|
93
|
+
on root? do
|
94
|
+
get do
|
95
|
+
res.write("Hello World!")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
Save this file as `app.rb`. Once you've done so, create another file called `config.ru` with the contents shown below:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
require File.expand_path("app", __dir__)
|
105
|
+
|
106
|
+
run(Tynn)
|
107
|
+
```
|
108
|
+
|
109
|
+
You already have a functional application! The syntax is very readable, but we'll discuss the details in a moment. To see it in action, you need to start a web server. You can do this by typing `rackup` in the command line.
|
110
|
+
|
111
|
+
![Starting a Web Server](https://raw.githubusercontent.com/frodsan/tynn/master/docs/images/rackup.png)
|
112
|
+
|
113
|
+
> **NOTE:** To stop the web server, hit `Ctrl+C` in the terminal window where it's running. To verify that the server has stopped you should see your command prompt cursor again.
|
114
|
+
|
115
|
+
Now open a browser window and navigate to http://localhost:9292 to see the greeting message.
|
116
|
+
|
117
|
+
![Hello World!](https://raw.githubusercontent.com/frodsan/tynn/master/docs/images/hello-world.png)
|
118
|
+
|
119
|
+
### Under the hood
|
120
|
+
|
121
|
+
Tynn is all about routing. Routing determines how an application should respond to a client request to a URI (or path) and a specific HTTP request method. In our previous example, that would be the root path (`/`) and the HTTP GET method.
|
122
|
+
|
123
|
+
To get a look on what's happening under the hood, let's see line 4:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
on root? do
|
127
|
+
# ...
|
128
|
+
end
|
129
|
+
```
|
130
|
+
|
131
|
+
That's a little taste of what we call routing matchers in Tynn. The purpose of the `on` matcher is to execute the given block only if the given argument returns `true`. In our case, `root?` returns `true` because we are accessing the root path (`/`) from our browser.
|
132
|
+
|
133
|
+
One line below there is another type of matcher:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
get do
|
137
|
+
res.write("Hello World!")
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
Tynn also includes methods for matching all the HTTP verbs (GET, POST, etc.). By default, if there are no other matchers before a verb matcher, it automatically checks that the current request is for the root path. The above example can be written as:
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
Tynn.define do
|
145
|
+
get do
|
23
146
|
res.write("Hello World!")
|
24
147
|
end
|
25
148
|
end
|
149
|
+
```
|
150
|
+
|
151
|
+
> **Note.** If you're not familiar with the HTTP methods, check out this [Wikipedia page](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods).
|
152
|
+
|
153
|
+
### Tynn on Rack
|
154
|
+
|
155
|
+
The last part of the puzzle is the `config.ru` file. As we mentioned earlier, Tynn is built on top of Rack ... but what is Rack?
|
156
|
+
|
157
|
+
Rack deals with HTTP requests. It provides a minimal interface between web servers supporting Ruby and Ruby web frameworks. Without Rack, Tynn would have to implement its own handler for each Ruby web server.
|
26
158
|
|
159
|
+
To run the hello world application you used `rackup`, one of the tools that comes with Rack. To use `rackup`, you need to supply a `config.ru` file. This file connects the Rack interface with our Tynn application through the `run` method.
|
160
|
+
|
161
|
+
```ruby
|
27
162
|
run(Tynn)
|
28
163
|
```
|
29
164
|
|
30
|
-
|
165
|
+
Rack also figures out which server you have available in your system. When we used `rackup`, it fired up WEBrick, a web server built into Ruby by default.
|
166
|
+
|
167
|
+
```
|
168
|
+
$ rackup
|
169
|
+
[2016-05-14 00:25:11] INFO WEBrick 1.3.1
|
170
|
+
```
|
171
|
+
|
172
|
+
Most popular web servers, like [Puma], [Unicorn] or [Thin], have built-in support for Rack, and thus support Tynn too. You can read more about Rack visiting their home page: http://rack.github.io/.
|
173
|
+
|
174
|
+
## Routing basics
|
175
|
+
|
176
|
+
This section covers the routing features of Tynn, such as route definitions, composing applications, and so on.
|
177
|
+
|
178
|
+
## Managing Request and Response
|
179
|
+
|
180
|
+
This section covers the many features Tynn provides to handle requests and responses.
|
181
|
+
|
182
|
+
### Redirecting a Request
|
183
|
+
|
184
|
+
To redirect a request to a different location, use `res.redirect`.
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
res.redirect("/pricing")
|
188
|
+
```
|
189
|
+
|
190
|
+
To redirect to a different site, use a fully-qualified URL.
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
res.redirect("https://google.com")
|
194
|
+
```
|
195
|
+
|
196
|
+
By default, the status code is set to `302` (Found). To set a different status code, pass an integer as a second parameter.
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
res.redirect("/projects/1", 301)
|
200
|
+
```
|
201
|
+
|
202
|
+
### Halting a Request
|
203
|
+
|
204
|
+
To immediately stop a request within a route, you can use the `halt` method.
|
205
|
+
|
206
|
+
```ruby
|
207
|
+
halt([status, headers, body])
|
208
|
+
```
|
209
|
+
|
210
|
+
Use `res.finish` to return a response as per Rack's specification.
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
if current_user.nil?
|
214
|
+
res.redirect("/login")
|
215
|
+
|
216
|
+
halt(res.finish)
|
217
|
+
end
|
218
|
+
|
219
|
+
# This won't be reached if current_user is nil
|
220
|
+
```
|
221
|
+
|
222
|
+
## Extending Tynn
|
223
|
+
|
224
|
+
### Middleware
|
225
|
+
|
226
|
+
Tynn runs on [Rack](https://github.com/rack/rack). Therefore it is possible
|
227
|
+
to use Rack middleware in Tynn. This is how you add a middleware (for example
|
228
|
+
`YourMiddleware`) to your app:
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
Tynn.use(YourMiddleware)
|
232
|
+
```
|
233
|
+
|
234
|
+
You can use any Rack middleware to your app, it is not specific to Tynn. You
|
235
|
+
can find a list of Rack middleware [here][middleware].
|
236
|
+
|
237
|
+
[middleware]: https://github.com/rack/rack/wiki/list-of-middleware
|
238
|
+
|
239
|
+
### Plugins
|
240
|
+
|
241
|
+
A way to extend Tynn is to use the plugin API. A plugin is just a module which can contain any of the following rules:
|
242
|
+
|
243
|
+
- If a `ClassMethods` module is defined, it extends the application class.
|
244
|
+
|
245
|
+
- If a `InstanceMethods` module is defined, it's included in the application.
|
246
|
+
|
247
|
+
- If a `setup` method is defined, it will be called last. This method can be used to configure the plugin.
|
248
|
+
|
249
|
+
The following is a complete example of the plugin API.
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
require "valuta"
|
253
|
+
|
254
|
+
module CurrencyHelper
|
255
|
+
def self.setup(app, currency: "$")
|
256
|
+
self.currency = currency
|
257
|
+
end
|
258
|
+
|
259
|
+
module ClassMethods
|
260
|
+
def currency
|
261
|
+
@currency
|
262
|
+
end
|
263
|
+
|
264
|
+
def currency=(currency)
|
265
|
+
@currency = currency
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
module InstanceMethods
|
270
|
+
def to_currency(value)
|
271
|
+
Valuta.convert(value, prefix: self.class.currency)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
```
|
276
|
+
|
277
|
+
To load the plugin into the application, use the `plugin` method.
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
App.plugin(CurrencyHelper, currency: "$")
|
281
|
+
```
|
282
|
+
|
283
|
+
Here is the plugin in action:
|
284
|
+
|
285
|
+
```ruby
|
286
|
+
App.currency # => "$"
|
287
|
+
|
288
|
+
App.define do
|
289
|
+
get do
|
290
|
+
res.write(to_currency(4567))
|
291
|
+
end
|
292
|
+
end
|
293
|
+
# GET / => 200 $4,567
|
294
|
+
```
|
295
|
+
|
296
|
+
### Settings
|
297
|
+
|
298
|
+
Each application has a `settings` hash where configuration can be stored. By default, settings are inherited.
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
Tynn.set(:layout, "layout")
|
302
|
+
|
303
|
+
class Guests < Tynn; end
|
304
|
+
class Users < Tynn; end
|
305
|
+
class Adminds < Tynn; end
|
306
|
+
|
307
|
+
Users.set(:layout, "users/layout")
|
308
|
+
Admins.set(:layout, "admins/layout")
|
309
|
+
|
310
|
+
Guests.settings[:layout] # => "layout"
|
311
|
+
Users.settings[:layout] # => "users/layout"
|
312
|
+
Admins.settings[:layout] # => "admins/layout"
|
313
|
+
```
|
314
|
+
|
315
|
+
This features comes in handy when authoring plugins.
|
316
|
+
|
317
|
+
```ruby
|
318
|
+
module CurrencyHelper
|
319
|
+
module ClassMethods
|
320
|
+
def currency=(currency)
|
321
|
+
set(:currency, currency)
|
322
|
+
end
|
323
|
+
|
324
|
+
def currency
|
325
|
+
settings.fetch(:currency, "$")
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
331
|
+
## Default Plugins
|
332
|
+
|
333
|
+
Tynn ships with a set of default plugins:
|
334
|
+
|
335
|
+
| Name | Description
|
336
|
+
| --------------------- | -----------------------------------------------------------------
|
337
|
+
| [Tynn::Environment] | Adds helper methods to get and check the current environment.
|
338
|
+
| [Tynn::JSON] | Adds helper methods for json generation.
|
339
|
+
| [Tynn::Render] | Adds support for rendering templates through different engines.
|
340
|
+
| [Tynn::Session] | Adds simple cookie based session management.
|
341
|
+
| [Tynn::Static] | Adds support for static files (javascript files, images, etc.).
|
342
|
+
|
343
|
+
The following sections cover the default plugins and extensions shipped with Tynn.
|
344
|
+
|
345
|
+
### Environments
|
346
|
+
|
347
|
+
Tynn ships with [Tynn::Environment] to set and check the current environment for the application.
|
348
|
+
|
349
|
+
```ruby
|
350
|
+
require "tynn"
|
351
|
+
require "tynn/environment"
|
352
|
+
|
353
|
+
Tynn.plugin(Tynn::Environment)
|
354
|
+
```
|
355
|
+
|
356
|
+
The default environment is based on the `RACK_ENV` environment variable.
|
357
|
+
|
358
|
+
```ruby
|
359
|
+
ENV["RACK_ENV"]
|
360
|
+
# => "test"
|
361
|
+
|
362
|
+
Tynn.environment
|
363
|
+
# => :test
|
364
|
+
```
|
365
|
+
|
366
|
+
If `ENV["RACK_ENV"]` is `nil`, the default value is `:development`.
|
367
|
+
|
368
|
+
```ruby
|
369
|
+
Tynn.environment
|
370
|
+
# => :development
|
371
|
+
```
|
372
|
+
|
373
|
+
To change the current environment, use the `environment=` method.
|
374
|
+
|
375
|
+
```ruby
|
376
|
+
Tynn.environment = :development
|
377
|
+
|
378
|
+
Tynn.environment
|
379
|
+
# => :development
|
380
|
+
```
|
381
|
+
|
382
|
+
To check the current environment, use: `development?`, `test?`,
|
383
|
+
`production?` or `staging?`.
|
384
|
+
|
385
|
+
```ruby
|
386
|
+
Tynn.plugin(Tynn::SSL) if Tynn.production?
|
387
|
+
```
|
388
|
+
|
389
|
+
Perform operations on specific environments with the `configure` method.
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
Tynn.configure(:development) do |app|
|
393
|
+
app.use(Tynn::Static, %w(/js /css /images))
|
394
|
+
end
|
395
|
+
|
396
|
+
Tynn.configure(:production) do |app|
|
397
|
+
app.use(Tynn::SSL)
|
398
|
+
end
|
399
|
+
```
|
400
|
+
|
401
|
+
### Method Override
|
402
|
+
|
403
|
+
HTML Forms only support GET and POST requests. To perform other actions such as PUT, PATCH or DELETE, use the [Rack::MethodOverride] middleware. Note that there is no need to add any new dependencies to the application as it's included in Rack already.
|
404
|
+
|
405
|
+
```ruby
|
406
|
+
Tynn.use(Rack::MethodOverride)
|
407
|
+
```
|
408
|
+
|
409
|
+
This uses a POST form to simulate a request with a non-supported method. In order to succeed, a hidden input field, with the name `_method` and the method name as the value, needs to be included. The following example simulates a PUT
|
410
|
+
request.
|
411
|
+
|
412
|
+
```html
|
413
|
+
<form method="POST" action="/posts/1">
|
414
|
+
<input type="hidden" name="_method" value="PUT">
|
415
|
+
<!-- ... -->
|
416
|
+
</form>
|
417
|
+
```
|
418
|
+
|
419
|
+
Now, this will trigger the `put` matcher in the application.
|
420
|
+
|
421
|
+
```ruby
|
422
|
+
Posts.define do
|
423
|
+
put do
|
424
|
+
post.update(req.params["post"])
|
425
|
+
end
|
426
|
+
end
|
427
|
+
```
|
428
|
+
|
429
|
+
### Static Files
|
430
|
+
|
431
|
+
Tynn ships with [Tynn::Static] to serve static files such as images, CSS, JavaScript and others.
|
432
|
+
|
433
|
+
```ruby
|
434
|
+
require "tynn"
|
435
|
+
require "tynn/static"
|
436
|
+
|
437
|
+
Tynn.plugin(Tynn::Static, %w(/js /css /images))
|
438
|
+
```
|
439
|
+
|
440
|
+
By default, static files are served from the folder `public` in the current directory. You can specify a different location by passing the `:root` option:
|
441
|
+
|
442
|
+
```ruby
|
443
|
+
Tynn.plugin(Tynn::Static, %w(/js /css /images), root: "assets")
|
444
|
+
```
|
445
|
+
|
446
|
+
As you can see in the table below, the name of static directory is not included in the URL because the files are looked up relative to that directory.
|
447
|
+
|
448
|
+
|
449
|
+
| File | URL |
|
450
|
+
| ---------------------------- | -------------------------------------- |
|
451
|
+
| ./public/js/application.js | http://example.org/js/application.js |
|
452
|
+
| ./public/css/application.css | http://example.org/css/application.css |
|
453
|
+
| ./public/images/logo.png | http://example.org/images/logo.png |
|
454
|
+
|
455
|
+
It's important to mention that the path of the static directory path is relative to the directory where you run the application. If you run the application from another directory, it's safer to use an absolute path:
|
456
|
+
|
457
|
+
```ruby
|
458
|
+
Tynn.plugin(
|
459
|
+
Tynn::Static,
|
460
|
+
%w(/js /css /images),
|
461
|
+
root: File.expand_path("public", __dir__)
|
462
|
+
)
|
463
|
+
```
|
464
|
+
|
465
|
+
## Security
|
466
|
+
|
467
|
+
## Testing
|
468
|
+
|
469
|
+
Tynn ships with [Tynn::Test], a simple helper class to simulate requests to your application.
|
470
|
+
|
471
|
+
```ruby
|
472
|
+
require "tynn"
|
473
|
+
require "tynn/test"
|
474
|
+
|
475
|
+
Tynn.define do
|
476
|
+
root do
|
477
|
+
res.write("hei")
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
app = Tynn::Test.new
|
482
|
+
app.get("/")
|
483
|
+
|
484
|
+
200 == app.res.status # => true
|
485
|
+
"hei" == app.res.body # => true
|
486
|
+
```
|
487
|
+
|
488
|
+
[Tynn::Test] is test-framework agnostic. The following example uses [Minitest]:
|
489
|
+
|
490
|
+
```ruby
|
491
|
+
require "minitest/autorun"
|
492
|
+
require "tynn/test"
|
493
|
+
|
494
|
+
class GuestsRouteTest < Minitest::Test
|
495
|
+
def setup
|
496
|
+
@app = Tynn::Test.new
|
497
|
+
end
|
498
|
+
|
499
|
+
def test_home
|
500
|
+
@app.get("/")
|
501
|
+
|
502
|
+
assert_equal 200, @app.res.status
|
503
|
+
assert_equal "Hello World!", @app.res.body
|
504
|
+
assert_equal "text/html", @app.res["Content-Type"]
|
505
|
+
end
|
506
|
+
end
|
507
|
+
```
|
508
|
+
|
509
|
+
If this is not of your flavor, you can use any Rack-based testing library or framework, like: [Rack::Test] or [Capybara].
|
510
|
+
|
511
|
+
## Changelog
|
512
|
+
|
513
|
+
To learn about new features, bug fixes, and changes, please refer to the [CHANGELOG](https://github.com/frodsan/tynn/blob/master/CHANGELOG.md).
|
514
|
+
|
515
|
+
## Development
|
516
|
+
|
517
|
+
Fork the project with:
|
518
|
+
|
519
|
+
```
|
520
|
+
$ git clone git@github.com:frodsan/tynn.git
|
521
|
+
```
|
522
|
+
|
523
|
+
To install dependencies, use:
|
524
|
+
|
525
|
+
```
|
526
|
+
$ bundle install
|
527
|
+
```
|
528
|
+
|
529
|
+
To run the test suite, do:
|
530
|
+
|
531
|
+
```
|
532
|
+
$ rake test
|
533
|
+
```
|
31
534
|
|
32
|
-
|
33
|
-
-------------
|
535
|
+
## Contributing
|
34
536
|
|
35
|
-
|
537
|
+
Use [GitHub Issues](https://github.com/frodsan/tynn/issues) for reporting bugs, discussing features and general feedback. If you've found a problem in Tynn, be sure to check the [past issues](https://github.com/frodsan/tynn/issues?state=closed) before open a new one.
|
36
538
|
|
37
|
-
|
38
|
-
------------
|
539
|
+
## Build History
|
39
540
|
|
40
|
-
|
541
|
+
[![Build History](https://buildstats.info/travisci/chart/frodsan/tynn?branch=master)](https://travis-ci.org/frodsan/tynn/builds)
|
41
542
|
|
42
|
-
License
|
43
|
-
-------
|
543
|
+
## License
|
44
544
|
|
45
|
-
Tynn is released under the [MIT License]
|
545
|
+
Tynn is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
46
546
|
|
47
|
-
[
|
48
|
-
[
|
49
|
-
[
|
547
|
+
[bundler]: http://bundler.io/
|
548
|
+
[capybara]: https://github.com/jnicklas/capybara
|
549
|
+
[cuba]: http://cuba.is/
|
550
|
+
[minitest]: https://github.com/seattlerb/minitest
|
551
|
+
[puma]: http://puma.io/
|
552
|
+
[rack]: http://rack.github.io/
|
553
|
+
[rack::test]: https://github.com/brynary/rack-test
|
554
|
+
[rack::methodoverride]: http://www.rubydoc.info/github/rack/rack/Rack/MethodOverride
|
555
|
+
[rails]: http://rubyonrails.org/
|
556
|
+
[sinatra]: http://www.sinatrarb.com/
|
50
557
|
[syro]: http://soveran.github.io/syro/
|
558
|
+
[thin]: http://code.macournoyer.com/thin/
|
559
|
+
[tynn::environment]: http://api.tynn.xyz/2.0.0/Tynn/Environment.html
|
560
|
+
[tynn::json]: http://api.tynn.xyz/2.0.0/Tynn/JSON.html
|
561
|
+
[tynn::render]: http://api.tynn.xyz/2.0.0/Tynn/Render.html
|
562
|
+
[tynn::session]: http://api.tynn.xyz/2.0.0/Tynn/Session.html
|
563
|
+
[tynn::static]: http://api.tynn.xyz/2.0.0/Tynn/Static.html
|
564
|
+
[tynn::test]: http://api.tynn.xyz/2.0.0/Tynn/Test.html
|
565
|
+
[unicorn]: https://unicorn.bogomips.org/
|