tynn 2.0.0.beta3 → 2.0.0.beta4
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 +83 -660
- data/lib/tynn.rb +186 -50
- data/lib/tynn/environment.rb +1 -84
- data/lib/tynn/json.rb +24 -25
- data/lib/tynn/render.rb +72 -33
- data/lib/tynn/request.rb +2 -82
- data/lib/tynn/response.rb +4 -118
- data/lib/tynn/secure_headers.rb +2 -24
- data/lib/tynn/session.rb +4 -87
- data/lib/tynn/ssl.rb +12 -71
- data/lib/tynn/static.rb +1 -19
- data/lib/tynn/test.rb +2 -125
- data/lib/tynn/utils.rb +51 -8
- data/lib/tynn/version.rb +1 -1
- data/lib/tynn/x/versioning.rb +29 -0
- data/test/json_test.rb +197 -7
- data/test/render_test.rb +56 -8
- data/test/request_test.rb +2 -0
- data/test/response_test.rb +7 -3
- data/test/routing_test.rb +56 -4
- data/test/settings_test.rb +31 -0
- data/test/versioning_test.rb +201 -0
- metadata +10 -35
- data/lib/tynn/base.rb +0 -434
data/test/render_test.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require_relative "helper"
|
4
4
|
require_relative "../lib/tynn/render"
|
5
|
-
require "tilt/erubis"
|
6
5
|
|
7
6
|
class RenderTest < Minitest::Test
|
8
7
|
def setup
|
@@ -14,7 +13,7 @@ class RenderTest < Minitest::Test
|
|
14
13
|
def test_partial
|
15
14
|
@app.define do
|
16
15
|
on "partial" do
|
17
|
-
res.write(partial("partial", name: "alice"))
|
16
|
+
res.write(partial("partial", locals: { name: "alice" }))
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
@@ -27,7 +26,7 @@ class RenderTest < Minitest::Test
|
|
27
26
|
def test_view
|
28
27
|
@app.define do
|
29
28
|
on "view" do
|
30
|
-
res.write(view("view", title: "welcome", name: "alice"))
|
29
|
+
res.write(view("view", locals: { title: "welcome", name: "alice" }))
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
@@ -40,7 +39,7 @@ class RenderTest < Minitest::Test
|
|
40
39
|
def test_render
|
41
40
|
@app.define do
|
42
41
|
on "render" do
|
43
|
-
render("view", title: "welcome", name: "alice")
|
42
|
+
render("view", locals: { title: "welcome", name: "alice" })
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
@@ -53,7 +52,7 @@ class RenderTest < Minitest::Test
|
|
53
52
|
def test_render_content_type
|
54
53
|
@app.define do
|
55
54
|
on "render" do
|
56
|
-
render("view", title: "welcome", name: "alice")
|
55
|
+
render("view", locals: { title: "welcome", name: "alice" })
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
@@ -63,10 +62,42 @@ class RenderTest < Minitest::Test
|
|
63
62
|
assert_equal "text/html", ts.res.content_type
|
64
63
|
end
|
65
64
|
|
65
|
+
def test_render_content_type_custom
|
66
|
+
@app.define do
|
67
|
+
on "render" do
|
68
|
+
render(
|
69
|
+
"view",
|
70
|
+
content_type: "text/plain",
|
71
|
+
locals: { title: "welcome", name: "alice" }
|
72
|
+
)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
ts = Tynn::Test.new(@app)
|
77
|
+
ts.get("/render")
|
78
|
+
|
79
|
+
assert_equal "text/plain", ts.res.content_type
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_render_content_type_global
|
83
|
+
@app.set(:render, content_type: "text/plain")
|
84
|
+
|
85
|
+
@app.define do
|
86
|
+
on "render" do
|
87
|
+
render("view", locals: { title: "welcome", name: "alice" })
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
ts = Tynn::Test.new(@app)
|
92
|
+
ts.get("/render")
|
93
|
+
|
94
|
+
assert_equal "text/plain", ts.res.content_type
|
95
|
+
end
|
96
|
+
|
66
97
|
def test_escaping
|
67
98
|
@app.define do
|
68
99
|
on "escape" do
|
69
|
-
res.write(partial("partial", name: "<a></a>"))
|
100
|
+
res.write(partial("partial", locals: { name: "<a></a>" }))
|
70
101
|
end
|
71
102
|
end
|
72
103
|
|
@@ -76,12 +107,29 @@ class RenderTest < Minitest::Test
|
|
76
107
|
assert_equal "<a></a>", ts.res.body.join.strip
|
77
108
|
end
|
78
109
|
|
79
|
-
def
|
110
|
+
def test_custom_global_layout
|
80
111
|
@app.set(:render, layout: "custom_layout")
|
81
112
|
|
82
113
|
@app.define do
|
83
114
|
on get do
|
84
|
-
render("view", title: "welcome", name: "alice")
|
115
|
+
render("view", locals: { title: "welcome", name: "alice" })
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
ts = Tynn::Test.new(@app)
|
120
|
+
ts.get("/")
|
121
|
+
|
122
|
+
assert_equal "custom / welcome / alice", ts.res.body.join.strip
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_custom_layout
|
126
|
+
@app.define do
|
127
|
+
on get do
|
128
|
+
render(
|
129
|
+
"view",
|
130
|
+
layout: "custom_layout",
|
131
|
+
locals: { title: "welcome", name: "alice" }
|
132
|
+
)
|
85
133
|
end
|
86
134
|
end
|
87
135
|
|
data/test/request_test.rb
CHANGED
data/test/response_test.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "helper"
|
2
4
|
|
3
5
|
class ResponseTest < Minitest::Test
|
4
|
-
def
|
6
|
+
def test_new_with_defaults
|
5
7
|
res = Tynn::Response.new
|
6
8
|
|
7
9
|
assert_nil res.status
|
@@ -9,10 +11,12 @@ class ResponseTest < Minitest::Test
|
|
9
11
|
assert_empty res.body
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
res = Tynn::Response.new("Content-Type" => "text/plain")
|
14
|
+
def test_new
|
15
|
+
res = Tynn::Response.new(200, { "Content-Type" => "text/plain" }, ["hei!"])
|
14
16
|
|
17
|
+
assert_equal 200, res.status
|
15
18
|
assert_equal "text/plain", res.headers["Content-Type"]
|
19
|
+
assert_equal "hei!", res.body.join
|
16
20
|
end
|
17
21
|
|
18
22
|
def test_status
|
data/test/routing_test.rb
CHANGED
@@ -11,6 +11,14 @@ class RoutingTest < Minitest::Test
|
|
11
11
|
assert_raises(RuntimeError) { @app.call({}) }
|
12
12
|
end
|
13
13
|
|
14
|
+
def test_freeze_when_define
|
15
|
+
@app.define {}
|
16
|
+
|
17
|
+
assert @app.app.frozen?
|
18
|
+
assert @app.middleware.frozen?
|
19
|
+
assert @app.settings.frozen?
|
20
|
+
end
|
21
|
+
|
14
22
|
def test_path_matching
|
15
23
|
@app.define do
|
16
24
|
on "path" do
|
@@ -108,6 +116,50 @@ class RoutingTest < Minitest::Test
|
|
108
116
|
assert_empty ts.res.body
|
109
117
|
end
|
110
118
|
|
119
|
+
def test_match_true
|
120
|
+
@app.define do
|
121
|
+
on true do
|
122
|
+
on get do
|
123
|
+
res.write("true")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
ts = Tynn::Test.new(@app)
|
129
|
+
ts.get("/")
|
130
|
+
|
131
|
+
assert_equal 200, ts.res.status
|
132
|
+
assert_equal "true", ts.res.body.join
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_dont_match_false
|
136
|
+
@app.define do
|
137
|
+
on false do
|
138
|
+
res.write("nothing to see here")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
ts = Tynn::Test.new(@app)
|
143
|
+
ts.get("/")
|
144
|
+
|
145
|
+
assert_equal 404, ts.res.status
|
146
|
+
assert_empty ts.res.body
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_dont_match_falsy
|
150
|
+
@app.define do
|
151
|
+
on nil do
|
152
|
+
res.write("nothing to see here")
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
ts = Tynn::Test.new(@app)
|
157
|
+
ts.get("/")
|
158
|
+
|
159
|
+
assert_equal 404, ts.res.status
|
160
|
+
assert_empty ts.res.body
|
161
|
+
end
|
162
|
+
|
111
163
|
def test_composition
|
112
164
|
admin = new_app
|
113
165
|
|
@@ -130,7 +182,7 @@ class RoutingTest < Minitest::Test
|
|
130
182
|
assert_equal "/admin", ts.res.body.join
|
131
183
|
end
|
132
184
|
|
133
|
-
def
|
185
|
+
def test_composition_with_vars
|
134
186
|
foo = new_app
|
135
187
|
bar = new_app
|
136
188
|
baz = new_app
|
@@ -143,19 +195,19 @@ class RoutingTest < Minitest::Test
|
|
143
195
|
|
144
196
|
foo.define do
|
145
197
|
on "bar" do
|
146
|
-
run(bar,
|
198
|
+
run(bar, vars.merge(bar: "bar"))
|
147
199
|
end
|
148
200
|
end
|
149
201
|
|
150
202
|
bar.define do
|
151
203
|
on "baz" do
|
152
|
-
run(baz,
|
204
|
+
run(baz, vars.merge(baz: "baz"))
|
153
205
|
end
|
154
206
|
end
|
155
207
|
|
156
208
|
baz.define do
|
157
209
|
on get do
|
158
|
-
res.write(sprintf("%{foo}/%{bar}/%{baz}",
|
210
|
+
res.write(sprintf("%{foo}/%{bar}/%{baz}", vars))
|
159
211
|
end
|
160
212
|
end
|
161
213
|
|
data/test/settings_test.rb
CHANGED
@@ -50,4 +50,35 @@ class SettingsTest < Minitest::Test
|
|
50
50
|
assert_equal "foo", @child1.settings[:foo]
|
51
51
|
assert_equal "bar", @child2.settings[:foo]
|
52
52
|
end
|
53
|
+
|
54
|
+
def test_inheritance_deep_dup
|
55
|
+
@app.set(:foo, bar: ["bar"], baz: { foo: "baz" })
|
56
|
+
|
57
|
+
@child1 = new_app(parent: @app)
|
58
|
+
@child1.set(:foo, foo: "foo")
|
59
|
+
@child1.settings[:foo][:bar].push("foo")
|
60
|
+
@child1.settings[:foo][:baz][:foo] = "foo"
|
61
|
+
|
62
|
+
assert_equal ["bar"], @app.settings[:foo][:bar]
|
63
|
+
assert_equal "baz", @app.settings[:foo][:baz][:foo]
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_freeze
|
67
|
+
@app.set(:foo, foo: "foo", bar: { foo: "foo" })
|
68
|
+
|
69
|
+
@app.define do
|
70
|
+
on get do
|
71
|
+
self.class.settings[:foo][:foo] = "bar"
|
72
|
+
end
|
73
|
+
|
74
|
+
on post do
|
75
|
+
self.class.settings[:foo][:bar][:foo] = "bar"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
ts = Tynn::Test.new(@app)
|
80
|
+
|
81
|
+
assert_raises { ts.get("/") }
|
82
|
+
assert_raises { ts.post("/") }
|
83
|
+
end
|
53
84
|
end
|
@@ -0,0 +1,201 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "helper"
|
4
|
+
require_relative "../lib/tynn/x/versioning"
|
5
|
+
|
6
|
+
class VersioningTest < Minitest::Test
|
7
|
+
def setup
|
8
|
+
@app = new_app
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_default_vendor
|
12
|
+
@app.plugin(Tynn::Versioning)
|
13
|
+
|
14
|
+
@app.define do
|
15
|
+
on version do |v|
|
16
|
+
res.write(v)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
ts = Tynn::Test.new(@app)
|
21
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/vnd.api+json; version = 1")
|
22
|
+
|
23
|
+
assert_equal 200, ts.res.status
|
24
|
+
assert_equal "1", ts.res.body.join
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_custom_vendor
|
28
|
+
@app.plugin(Tynn::Versioning)
|
29
|
+
|
30
|
+
@app.define do
|
31
|
+
on version(vendor: "tynn") do |v|
|
32
|
+
res.write(v)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
ts = Tynn::Test.new(@app)
|
37
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/vnd.tynn+json; version=1")
|
38
|
+
|
39
|
+
assert_equal 200, ts.res.status
|
40
|
+
assert_equal "1", ts.res.body.join
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_version_and_format
|
44
|
+
@app.plugin(Tynn::Versioning)
|
45
|
+
|
46
|
+
@app.define do
|
47
|
+
on version do |version, format|
|
48
|
+
res.write(version)
|
49
|
+
res.write(format)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
ts = Tynn::Test.new(@app)
|
54
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/vnd.api+json; version=1")
|
55
|
+
|
56
|
+
assert_equal 200, ts.res.status
|
57
|
+
assert_equal "1", ts.res.body[0]
|
58
|
+
assert_equal "json", ts.res.body[1]
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_custom_format
|
62
|
+
@app.plugin(Tynn::Versioning)
|
63
|
+
|
64
|
+
@app.define do
|
65
|
+
on version do |_, format|
|
66
|
+
res.write(format)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
ts = Tynn::Test.new(@app)
|
71
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/vnd.api+raw; version=1")
|
72
|
+
|
73
|
+
assert_equal 200, ts.res.status
|
74
|
+
assert_equal "raw", ts.res.body.join
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_version_without_spaces
|
78
|
+
@app.plugin(Tynn::Versioning)
|
79
|
+
|
80
|
+
@app.define do
|
81
|
+
on version do |v|
|
82
|
+
res.write(v)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
ts = Tynn::Test.new(@app)
|
87
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/vnd.api+json;version=1")
|
88
|
+
|
89
|
+
assert_equal 200, ts.res.status
|
90
|
+
assert_equal "1", ts.res.body.join
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_multiple_accepts
|
94
|
+
@app.plugin(Tynn::Versioning)
|
95
|
+
|
96
|
+
@app.define do
|
97
|
+
on version do |v|
|
98
|
+
res.write(v)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
ts = Tynn::Test.new(@app)
|
103
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/json, application/vnd.api+json; version = 1")
|
104
|
+
|
105
|
+
assert_equal 200, ts.res.status
|
106
|
+
assert_equal "1", ts.res.body.join
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_no_accept_header
|
110
|
+
@app.plugin(Tynn::Versioning)
|
111
|
+
|
112
|
+
@app.define do
|
113
|
+
on version do |v|
|
114
|
+
res.write(v)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
ts = Tynn::Test.new(@app)
|
119
|
+
ts.get("/")
|
120
|
+
|
121
|
+
assert_equal 404, ts.res.status
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_invalid_vendor
|
125
|
+
@app.plugin(Tynn::Versioning)
|
126
|
+
|
127
|
+
@app.define do
|
128
|
+
on version do |v|
|
129
|
+
res.write(v)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
ts = Tynn::Test.new(@app)
|
134
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/vnd.invalid+json; version=1")
|
135
|
+
|
136
|
+
assert_equal 404, ts.res.status
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_no_version
|
140
|
+
@app.plugin(Tynn::Versioning)
|
141
|
+
|
142
|
+
@app.define do
|
143
|
+
on version do |v|
|
144
|
+
res.write(v)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
ts = Tynn::Test.new(@app)
|
149
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/vnd.invalid+json; version=")
|
150
|
+
|
151
|
+
assert_equal 404, ts.res.status
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_default_version_without_accept
|
155
|
+
@app.plugin(Tynn::Versioning)
|
156
|
+
|
157
|
+
@app.define do
|
158
|
+
on version(default: 10) do |v|
|
159
|
+
res.write(v)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
ts = Tynn::Test.new(@app)
|
164
|
+
ts.get("/")
|
165
|
+
|
166
|
+
assert_equal 200, ts.res.status
|
167
|
+
assert_equal "10", ts.res.body.join
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_default_version_without_version_tag
|
171
|
+
@app.plugin(Tynn::Versioning)
|
172
|
+
|
173
|
+
@app.define do
|
174
|
+
on version(default: 10) do |v|
|
175
|
+
res.write(v)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
ts = Tynn::Test.new(@app)
|
180
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/vnd.api+json")
|
181
|
+
|
182
|
+
assert_equal 200, ts.res.status
|
183
|
+
assert_equal "10", ts.res.body.join
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_default_version_without_version_value
|
187
|
+
@app.plugin(Tynn::Versioning)
|
188
|
+
|
189
|
+
@app.define do
|
190
|
+
on version(default: 10) do |v|
|
191
|
+
res.write(v)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
ts = Tynn::Test.new(@app)
|
196
|
+
ts.get("/", nil, "HTTP_ACCEPT" => "application/vnd.tynn+json; version=")
|
197
|
+
|
198
|
+
assert_equal 200, ts.res.status
|
199
|
+
assert_equal "10", ts.res.body.join
|
200
|
+
end
|
201
|
+
end
|