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.
@@ -1,50 +0,0 @@
1
- class Tynn
2
- # Public: Adds method for HTTP's +HEAD+ and +OPTIONS+.
3
- #
4
- # Examples
5
- #
6
- # require "tynn"
7
- # require "tynn/all_methods"
8
- #
9
- # Tynn.plugin(Tynn::AllMethods)
10
- #
11
- module AllMethods
12
- module InstanceMethods
13
- # Public: Executes the given block if the request method is +HEAD+.
14
- #
15
- # Examples
16
- #
17
- # Tynn.define do
18
- # head do
19
- # res.status = 201
20
- # end
21
- # end
22
- #
23
- def head
24
- if root? && req.head?
25
- yield
26
-
27
- halt(res.finish)
28
- end
29
- end
30
-
31
- # Public: Executes the given block if the request method is +OPTIONS+.
32
- #
33
- # Examples
34
- #
35
- # Tynn.define do
36
- # options do
37
- # res.status = 405
38
- # end
39
- # end
40
- #
41
- def options
42
- if root? && req.options?
43
- yield
44
-
45
- halt(res.finish)
46
- end
47
- end
48
- end
49
- end
50
- end
@@ -1,34 +0,0 @@
1
- require "hmote"
2
-
3
- class Tynn
4
- module HMote
5
- def self.setup(app, options = {}) # :nodoc:
6
- app.set(:layout, options.fetch(:layout, "layout"))
7
- app.set(:views, options.fetch(:views, File.expand_path("views", Dir.pwd)))
8
- end
9
-
10
- module InstanceMethods
11
- include ::HMote::Helpers
12
-
13
- def render(template, locals = {}, layout = self.class.settings[:layout])
14
- res.headers[Rack::CONTENT_TYPE] ||= Syro::Response::DEFAULT
15
-
16
- res.write(view(template, locals, layout))
17
- end
18
-
19
- def view(template, locals = {}, layout = self.class.settings[:layout])
20
- return partial(layout, locals.merge(content: partial(template, locals)))
21
- end
22
-
23
- def partial(template, locals = {})
24
- return hmote(template_path(template), locals.merge(app: self), TOPLEVEL_BINDING)
25
- end
26
-
27
- private
28
-
29
- def template_path(template)
30
- return File.join(self.class.settings[:views], "#{ template }.mote")
31
- end
32
- end
33
- end
34
- end
@@ -1,20 +0,0 @@
1
- class Tynn
2
- module NotFound
3
- module InstanceMethods
4
- def call(*) # :nodoc:
5
- result = super
6
-
7
- if result[0] == 404 && result[2].empty?
8
- not_found
9
-
10
- return res.finish
11
- else
12
- return result
13
- end
14
- end
15
-
16
- def not_found # :nodoc:
17
- end
18
- end
19
- end
20
- end
@@ -1,45 +0,0 @@
1
- require_relative "secure_headers"
2
-
3
- class Tynn
4
- # Public: Adds security measures against common attacks.
5
- #
6
- # Examples
7
- #
8
- # require "tynn"
9
- # require "tynn/protection"
10
- #
11
- # Tynn.plugin(Tynn::Protection)
12
- #
13
- # If you are using SSL/TLS (HTTPS), it's recommended to set
14
- # the +:ssl+ option:
15
- #
16
- # Examples
17
- #
18
- # require "tynn"
19
- # require "tynn/protection"
20
- #
21
- # Tynn.plugin(Tynn::Protection, ssl: true)
22
- #
23
- # By default, it includes the following security plugins:
24
- #
25
- # - Tynn::SecureHeaders
26
- #
27
- # If the +:ssl+ option is +true+, includes:
28
- #
29
- # - Tynn::SSL
30
- #
31
- module Protection
32
- # Internal: Configures security related plugins.
33
- def self.setup(app, ssl: false, hsts: {})
34
- app.plugin(Tynn::SecureHeaders)
35
-
36
- if ssl
37
- app.settings[:ssl] = true
38
-
39
- require_relative "ssl"
40
-
41
- app.plugin(Tynn::SSL, hsts: hsts)
42
- end
43
- end
44
- end
45
- end
@@ -1,16 +0,0 @@
1
- require_relative "../lib/tynn/all_methods"
2
-
3
- Tynn.plugin(Tynn::AllMethods)
4
-
5
- test "methods" do
6
- [:head, :options].each do |method|
7
- Tynn.define do
8
- send(method) { res.write "" }
9
- end
10
-
11
- app = Tynn::Test.new
12
- app.send(method, "/")
13
-
14
- assert_equal 200, app.res.status
15
- end
16
- end
@@ -1,65 +0,0 @@
1
- test "hello" do
2
- Tynn.define do
3
- get do
4
- res.write("hello")
5
- end
6
- end
7
-
8
- app = Tynn::Test.new
9
- app.get("/")
10
-
11
- assert_equal 200, app.res.status
12
- assert_equal "hello", app.res.body
13
- end
14
-
15
- test "methods" do
16
- [:get, :post, :put, :patch, :delete].each do |method|
17
- Tynn.define do
18
- send(method) { res.write "" }
19
- end
20
-
21
- app = Tynn::Test.new
22
- app.send(method, "/")
23
-
24
- assert_equal 200, app.res.status
25
- end
26
- end
27
-
28
- test "captures" do
29
- Tynn.define do
30
- on :foo do |foo|
31
- on :bar do |bar|
32
- res.write(sprintf("%s:%s", foo, bar))
33
- end
34
- end
35
- end
36
-
37
- app = Tynn::Test.new
38
- app.get("/foo/bar")
39
-
40
- assert_equal 200, app.res.status
41
- assert_equal "foo:bar", app.res.body
42
- end
43
-
44
- test "composition" do
45
- class Foo < Tynn
46
- end
47
-
48
- Foo.define do
49
- get do
50
- res.write(inbox[:foo])
51
- end
52
- end
53
-
54
- Tynn.define do
55
- on "foo" do
56
- run(Foo, foo: 42)
57
- end
58
- end
59
-
60
- app = Tynn::Test.new
61
- app.get("/foo")
62
-
63
- assert_equal 200, app.res.status
64
- assert_equal "42", app.res.body
65
- end
@@ -1,78 +0,0 @@
1
- require_relative "../lib/tynn/hmote"
2
-
3
- setup do
4
- Tynn.plugin(Tynn::HMote, views: File.expand_path("./test/views"))
5
-
6
- Tynn::Test.new
7
- end
8
-
9
- test "partial" do |app|
10
- Tynn.define do
11
- on "partial" do
12
- res.write(partial("partial", name: "mote"))
13
- end
14
- end
15
-
16
- app.get("/partial")
17
-
18
- assert_equal "mote", app.res.body.strip
19
- end
20
-
21
- test "view" do |app|
22
- Tynn.define do
23
- on "view" do
24
- res.write(view("view", title: "tynn", name: "mote"))
25
- end
26
- end
27
-
28
- app.get("/view")
29
-
30
- assert_equal "tynn / mote", app.res.body.strip
31
- end
32
-
33
- test "render" do |app|
34
- Tynn.define do
35
- on "render" do
36
- render("view", title: "tynn", name: "mote")
37
- end
38
- end
39
-
40
- app.get("/render")
41
-
42
- assert_equal 200, app.res.status
43
- assert_equal "text/html", app.res.headers["Content-Type"]
44
- assert_equal "tynn / mote", app.res.body.strip
45
- end
46
-
47
- test "404" do |app|
48
- Tynn.define do
49
- on "404" do
50
- res.status = 404
51
-
52
- render("view", title: "tynn", name: "mote")
53
- end
54
- end
55
-
56
- app.get("/404")
57
-
58
- assert_equal 404, app.res.status
59
- assert_equal "text/html", app.res.headers["Content-Type"]
60
- assert_equal "tynn / mote", app.res.body.strip
61
- end
62
-
63
- test "custom layout" do
64
- class App < Tynn
65
- set(:layout, "custom_layout")
66
- end
67
-
68
- App.define do
69
- root do
70
- render("view", title: "tynn", name: "mote")
71
- end
72
- end
73
-
74
- app = Tynn::Test.new(App)
75
- app.get("/")
76
-
77
- assert_equal "custom / tynn / mote", app.res.body.strip
78
- end
@@ -1,19 +0,0 @@
1
- require_relative "../lib/tynn/not_found"
2
-
3
- test "not found" do
4
- Tynn.plugin(Tynn::NotFound)
5
-
6
- class Tynn
7
- def not_found
8
- res.write("not found")
9
- end
10
- end
11
-
12
- Tynn.define do
13
- end
14
-
15
- app = Tynn::Test.new
16
- app.get("/notfound")
17
-
18
- assert_equal "not found", app.res.body
19
- end
@@ -1,36 +0,0 @@
1
- require_relative "../lib/tynn/protection"
2
- require_relative "../lib/tynn/session"
3
-
4
- test "supports hsts options" do
5
- hsts = { expires: 100, subdomains: false, preload: true }
6
-
7
- Tynn.plugin(Tynn::Protection, ssl: true, hsts: hsts)
8
-
9
- Tynn.define do
10
- end
11
-
12
- app = Tynn::Test.new
13
- app.get("/", {}, "HTTPS" => "on")
14
-
15
- hsts = app.res.headers["Strict-Transport-Security"]
16
-
17
- assert_equal "max-age=100; preload", hsts
18
- end
19
-
20
- test "adds secure flag to session cookie" do
21
- Tynn.plugin(Tynn::Protection, ssl: true)
22
- Tynn.plugin(Tynn::Session, secret: "_this_must_be_random_")
23
-
24
- Tynn.define do
25
- root do
26
- session[:foo] = "foo"
27
- end
28
- end
29
-
30
- app = Tynn::Test.new
31
- app.get("/", {}, "HTTPS" => "on")
32
-
33
- session, _ = app.res.headers["Set-Cookie"].split("\n")
34
-
35
- assert(/;\s*secure\s*(;|$)/i === session)
36
- end