tynn 2.0.0.alpha → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,7 +4,7 @@ require_relative "helper"
4
4
 
5
5
  class PluginTest < Minitest::Test
6
6
  def setup
7
- @app = Class.new(Tynn)
7
+ @app = new_app
8
8
  end
9
9
 
10
10
  def test_class_methods
@@ -2,20 +2,17 @@
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
- VIEWS_PATH = File.expand_path("views", __dir__)
9
-
10
7
  def setup
11
- @app = Class.new(Tynn)
8
+ @app = new_app
12
9
 
13
- @app.plugin(Tynn::Render, views: VIEWS_PATH)
10
+ @app.plugin(Tynn::Render, root: __dir__)
14
11
  end
15
12
 
16
13
  def test_partial
17
14
  @app.define do
18
- on("partial") do
15
+ on "partial" do
19
16
  res.write(partial("partial", name: "alice"))
20
17
  end
21
18
  end
@@ -23,12 +20,12 @@ class RenderTest < Minitest::Test
23
20
  ts = Tynn::Test.new(@app)
24
21
  ts.get("/partial")
25
22
 
26
- assert_equal "alice", ts.res.body.strip
23
+ assert_equal "alice", ts.res.body.join.strip
27
24
  end
28
25
 
29
26
  def test_view
30
27
  @app.define do
31
- on("view") do
28
+ on "view" do
32
29
  res.write(view("view", title: "welcome", name: "alice"))
33
30
  end
34
31
  end
@@ -36,12 +33,25 @@ class RenderTest < Minitest::Test
36
33
  ts = Tynn::Test.new(@app)
37
34
  ts.get("/view")
38
35
 
39
- assert_equal "welcome / alice", ts.res.body.strip
36
+ assert_equal "welcome / alice", ts.res.body.join.strip
40
37
  end
41
38
 
42
39
  def test_render
43
40
  @app.define do
44
- on("render") do
41
+ on "render" do
42
+ render("view", title: "welcome", name: "alice")
43
+ end
44
+ end
45
+
46
+ ts = Tynn::Test.new(@app)
47
+ ts.get("/render")
48
+
49
+ assert_equal "welcome / alice", ts.res.body.join.strip
50
+ end
51
+
52
+ def test_render_content_type
53
+ @app.define do
54
+ on "render" do
45
55
  render("view", title: "welcome", name: "alice")
46
56
  end
47
57
  end
@@ -50,12 +60,11 @@ class RenderTest < Minitest::Test
50
60
  ts.get("/render")
51
61
 
52
62
  assert_equal "text/html", ts.res.content_type
53
- assert_equal "welcome / alice", ts.res.body.strip
54
63
  end
55
64
 
56
65
  def test_escaping
57
66
  @app.define do
58
- on("escape") do
67
+ on "escape" do
59
68
  res.write(partial("partial", name: "<a></a>"))
60
69
  end
61
70
  end
@@ -63,14 +72,14 @@ class RenderTest < Minitest::Test
63
72
  ts = Tynn::Test.new(@app)
64
73
  ts.get("/escape")
65
74
 
66
- assert_equal "&lt;a&gt;&lt;/a&gt;", ts.res.body.strip
75
+ assert_equal "&lt;a&gt;&lt;&#x2F;a&gt;", ts.res.body.join.strip
67
76
  end
68
77
 
69
78
  def test_custom_layout
70
79
  @app.set(:render, layout: "custom_layout")
71
80
 
72
81
  @app.define do
73
- get do
82
+ on get do
74
83
  render("view", title: "welcome", name: "alice")
75
84
  end
76
85
  end
@@ -78,6 +87,6 @@ class RenderTest < Minitest::Test
78
87
  ts = Tynn::Test.new(@app)
79
88
  ts.get("/")
80
89
 
81
- assert_equal "custom / welcome / alice", ts.res.body.strip
90
+ assert_equal "custom / welcome / alice", ts.res.body.join.strip
82
91
  end
83
92
  end
@@ -4,14 +4,18 @@ require_relative "helper"
4
4
 
5
5
  class RequestHeadersTest < Minitest::Test
6
6
  def setup
7
- env = { "HTTP_HOST" => "127.0.0.1", "CONTENT_TYPE" => "text/plain" }
8
- request = Tynn::Request.new(env)
9
-
10
- @headers = Tynn::Request::Headers.new(request)
7
+ @headers = Tynn::Request::Headers.new(
8
+ "HTTP_HOST" => "127.0.0.1",
9
+ "CONTENT_TYPE" => "text/plain"
10
+ )
11
11
  end
12
12
 
13
13
  def test_get_header
14
14
  assert_equal "127.0.0.1", @headers["Host"]
15
+ assert_equal "127.0.0.1", @headers["host"]
16
+ assert_equal "text/plain", @headers["Content-Type"]
17
+ assert_equal "text/plain", @headers["content-type"]
18
+ assert_equal "text/plain", @headers["CONTENT_TYPE"]
15
19
  end
16
20
 
17
21
  def test_check_if_key_exists
@@ -0,0 +1,9 @@
1
+ require_relative "helper"
2
+
3
+ class RequestTest < Minitest::Test
4
+ def test_content_length_as_int
5
+ req = Tynn::Request.new("CONTENT_LENGTH" => "20")
6
+
7
+ assert_kind_of Integer, req.content_length
8
+ end
9
+ end
@@ -0,0 +1,217 @@
1
+ require_relative "helper"
2
+
3
+ class ResponseTest < Minitest::Test
4
+ def test_new
5
+ res = Tynn::Response.new
6
+
7
+ assert_nil res.status
8
+ assert_empty res.headers
9
+ assert_empty res.body
10
+ end
11
+
12
+ def test_new_with_headers
13
+ res = Tynn::Response.new("Content-Type" => "text/plain")
14
+
15
+ assert_equal "text/plain", res.headers["Content-Type"]
16
+ end
17
+
18
+ def test_status
19
+ res = Tynn::Response.new
20
+
21
+ res.status = 200
22
+
23
+ assert_equal 200, res.status
24
+ end
25
+
26
+ def test_headers
27
+ res = Tynn::Response.new
28
+
29
+ res.headers["Content-Type"] = "text/plain"
30
+
31
+ assert_equal "text/plain", res.headers["Content-Type"]
32
+ end
33
+
34
+ def test_content_length
35
+ res = Tynn::Response.new
36
+
37
+ res.headers["Content-Length"] = "42"
38
+
39
+ assert_equal 42, res.content_length
40
+ end
41
+
42
+ def test_content_type
43
+ res = Tynn::Response.new
44
+
45
+ res.content_type = "text/html"
46
+
47
+ assert_equal "text/html", res.headers["Content-Type"]
48
+ assert_equal "text/html", res.content_type
49
+ end
50
+
51
+ def test_location
52
+ res = Tynn::Response.new
53
+
54
+ res.location = "/users"
55
+
56
+ assert_equal "/users", res.headers["Location"]
57
+ assert_equal "/users", res.location
58
+ end
59
+
60
+ def test_write_body
61
+ res = Tynn::Response.new
62
+
63
+ res.write("foo")
64
+ res.write("bar")
65
+
66
+ assert_equal ["foo", "bar"], res.body
67
+ end
68
+
69
+ def test_write_content_length
70
+ res = Tynn::Response.new
71
+
72
+ res.write("foo")
73
+ res.write("bar")
74
+
75
+ assert_equal "6", res.headers["Content-Length"]
76
+ end
77
+
78
+ def test_finish_without_status_and_body
79
+ res = Tynn::Response.new
80
+
81
+ status, _, body = res.finish
82
+
83
+ assert_equal 404, status
84
+ assert_empty body
85
+ end
86
+
87
+ def test_finish_without_status_but_body
88
+ res = Tynn::Response.new
89
+
90
+ res.write("hei!")
91
+
92
+ status, _, body = res.finish
93
+
94
+ assert_equal 200, status
95
+ assert_equal ["hei!"], body
96
+ end
97
+
98
+ def test_redirect_with_path
99
+ res = Tynn::Response.new
100
+
101
+ res.redirect("/path")
102
+
103
+ assert_equal 302, res.status
104
+ assert_equal "/path", res.location
105
+ end
106
+
107
+ def test_redirect_with_url
108
+ res = Tynn::Response.new
109
+
110
+ res.redirect("https://google.com")
111
+
112
+ assert_equal 302, res.status
113
+ assert_equal "https://google.com", res.location
114
+ end
115
+
116
+ def test_redirect_with_status
117
+ res = Tynn::Response.new
118
+
119
+ res.redirect("/path", 303)
120
+
121
+ assert_equal 303, res.status
122
+ end
123
+
124
+ def test_set_cookie
125
+ res = Tynn::Response.new
126
+
127
+ res.set_cookie("foo", "bar")
128
+
129
+ assert_equal "foo=bar", res.headers["Set-Cookie"]
130
+ end
131
+
132
+ def test_set_multiple_cookies
133
+ res = Tynn::Response.new
134
+
135
+ res.set_cookie("foo1", "bar1")
136
+ res.set_cookie("foo2", "bar2")
137
+
138
+ assert_equal "foo1=bar1\nfoo2=bar2", res.headers["Set-Cookie"]
139
+ end
140
+
141
+ def test_set_cookie_with_options
142
+ res = Tynn::Response.new
143
+
144
+ time = Time.new(2016)
145
+
146
+ res.set_cookie("foo", "bar", {
147
+ domain: "example.org",
148
+ path: "/path",
149
+ max_age: 100, # seconds
150
+ expires: time,
151
+ httponly: true,
152
+ secure: true,
153
+ same_site: :Lax
154
+ })
155
+
156
+ expected = %W(
157
+ foo=bar
158
+ domain=example.org
159
+ path=/path
160
+ max-age=100
161
+ expires=#{ time.gmtime.rfc2822 }
162
+ secure
163
+ HttpOnly
164
+ SameSite=Lax
165
+ ).join("; ")
166
+
167
+ assert_equal expected, res.headers["Set-Cookie"]
168
+ end
169
+
170
+ def test_delete_cookie
171
+ res = Tynn::Response.new
172
+
173
+ res.set_cookie("foo1", "bar1")
174
+ res.set_cookie("foo2", "bar2")
175
+
176
+ res.delete_cookie("foo1")
177
+
178
+ expected = [
179
+ "foo2=bar2",
180
+ "foo1=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
181
+ ].join("\n")
182
+
183
+ assert_equal expected, res.headers["Set-Cookie"]
184
+ end
185
+
186
+ def test_delete_cookie_with_multiple_domains
187
+ res = Tynn::Response.new
188
+
189
+ res.set_cookie("foo1", "bar1", domain: "foo1.example.org")
190
+ res.set_cookie("foo2", "bar2", domain: "foo2.example.org")
191
+
192
+ res.delete_cookie("foo1", domain: "foo1.example.org")
193
+
194
+ expected = [
195
+ "foo2=bar2; domain=foo2.example.org",
196
+ "foo1=; domain=foo1.example.org; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
197
+ ].join("\n")
198
+
199
+ assert_equal expected, res.headers["Set-Cookie"]
200
+ end
201
+
202
+ def test_delete_cookie_with_same_domain_and_multiple_paths
203
+ res = Tynn::Response.new
204
+
205
+ res.set_cookie("foo1", "bar1", domain: "example.org", path: "/foo1")
206
+ res.set_cookie("foo2", "bar2", domain: "example.org", path: "/foo2")
207
+
208
+ res.delete_cookie("foo1", domain: "example.org", path: "/foo1")
209
+
210
+ expected = [
211
+ "foo2=bar2; domain=example.org; path=/foo2",
212
+ "foo1=; domain=example.org; path=/foo1; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
213
+ ].join("\n")
214
+
215
+ assert_equal expected, res.headers["Set-Cookie"]
216
+ end
217
+ end
@@ -4,17 +4,31 @@ require_relative "helper"
4
4
 
5
5
  class RoutingTest < Minitest::Test
6
6
  def setup
7
- @app = Class.new(Tynn)
7
+ @app = new_app
8
8
  end
9
9
 
10
10
  def test_raise_if_not_handler
11
- assert_raises { @app.call({}) }
11
+ assert_raises(Tynn::Error) { @app.call({}) }
12
12
  end
13
13
 
14
14
  def test_path_matching
15
15
  @app.define do
16
- on "hello" do
17
- res.write("hello")
16
+ on "path" do
17
+ res.write("/path")
18
+ end
19
+ end
20
+
21
+ ts = Tynn::Test.new(@app)
22
+ ts.get("/path")
23
+
24
+ assert_equal 200, ts.res.status
25
+ assert_equal "/path", ts.res.body.join
26
+ end
27
+
28
+ def test_path_dont_match
29
+ @app.define do
30
+ on "private" do
31
+ res.write("nothing to see here")
18
32
  end
19
33
  end
20
34
 
@@ -22,90 +36,166 @@ class RoutingTest < Minitest::Test
22
36
  ts.get("/")
23
37
 
24
38
  assert_equal 404, ts.res.status
39
+ assert_empty ts.res.body
40
+ end
41
+
42
+ def test_capture
43
+ @app.define do
44
+ on :foo do |foo|
45
+ on :bar do |bar|
46
+ res.write(sprintf("%s:%s", foo, bar))
47
+ end
48
+ end
49
+ end
25
50
 
26
- ts.get("/hello")
51
+ ts = Tynn::Test.new(@app)
52
+ ts.get("/foo/bar")
27
53
 
28
54
  assert_equal 200, ts.res.status
29
- assert_equal "hello", ts.res.body
55
+ assert_equal "foo:bar", ts.res.body.join
30
56
  end
31
57
 
32
- def test_http_methods
33
- methods = %i(get post put patch delete head options)
58
+ def test_capture_root
59
+ @app.define do
60
+ on :foo do |foo|
61
+ res.write(foo)
62
+ end
63
+ end
64
+
65
+ ts = Tynn::Test.new(@app)
66
+ ts.get("/")
34
67
 
35
- methods.each do |method|
36
- @app.define do
37
- send(method) { res.write(method) }
68
+ assert_equal 404, ts.res.status
69
+ assert_empty ts.res.body
70
+ end
71
+
72
+ def test_path_and_verbs
73
+ methods = %w(get post patch put delete)
74
+
75
+ @app.define do
76
+ methods.each do |method|
77
+ on method do
78
+ on send(method) do
79
+ res.write(method)
80
+ end
81
+ end
38
82
  end
83
+ end
39
84
 
40
- ts = Tynn::Test.new(@app)
41
- ts.send(method, "/")
85
+ ts = Tynn::Test.new(@app)
86
+
87
+ methods.each do |method|
88
+ ts.send(method, "/#{ method }")
42
89
 
43
90
  assert_equal 200, ts.res.status
44
- assert_equal method.to_s, ts.res.body
91
+ assert_equal method, ts.res.body.join
45
92
  end
46
93
  end
47
94
 
48
- def test_capturing_path
95
+ def test_verbs_on_root
49
96
  @app.define do
50
- on(:foo) do |foo|
51
- on(:bar) do |bar|
52
- res.write(sprintf("%s/%s", foo, bar))
97
+ on "foo" do
98
+ get do
99
+ res.write("nothing to see here")
53
100
  end
54
101
  end
55
102
  end
56
103
 
57
104
  ts = Tynn::Test.new(@app)
58
- ts.get("/john/doe")
105
+ ts.get("/foo/bar/baz")
59
106
 
60
- assert_equal 200, ts.res.status
61
- assert_equal "john/doe", ts.res.body
107
+ assert_equal 404, ts.res.status
108
+ assert_empty ts.res.body
62
109
  end
63
110
 
64
111
  def test_composition
65
- foo = Class.new(@app)
112
+ admin = new_app
113
+
114
+ admin.define do
115
+ on get do
116
+ res.write("/admin")
117
+ end
118
+ end
66
119
 
67
120
  @app.define do
68
- on("foo") do
69
- run(foo, foo: 42)
121
+ on "admin" do
122
+ run(admin)
123
+ end
124
+ end
125
+
126
+ ts = Tynn::Test.new(@app)
127
+ ts.get("/admin")
128
+
129
+ assert_equal 200, ts.res.status
130
+ assert_equal "/admin", ts.res.body.join
131
+ end
132
+
133
+ def test_composition_with_inbox
134
+ foo = new_app
135
+ bar = new_app
136
+ baz = new_app
137
+
138
+ @app.define do
139
+ on "foo" do
140
+ run(foo, foo: "foo")
70
141
  end
71
142
  end
72
143
 
73
144
  foo.define do
74
- get do
75
- res.write(inbox[:foo])
145
+ on "bar" do
146
+ run(bar, inbox.merge(bar: "bar"))
147
+ end
148
+ end
149
+
150
+ bar.define do
151
+ on "baz" do
152
+ run(baz, inbox.merge(baz: "baz"))
153
+ end
154
+ end
155
+
156
+ baz.define do
157
+ on get do
158
+ res.write(sprintf("%{foo}/%{bar}/%{baz}", inbox))
76
159
  end
77
160
  end
78
161
 
79
162
  ts = Tynn::Test.new(@app)
80
- ts.get("/foo")
163
+ ts.get("/foo/bar/baz")
81
164
 
82
165
  assert_equal 200, ts.res.status
83
- assert_equal "42", ts.res.body
166
+ assert_equal "foo/bar/baz", ts.res.body.join
84
167
  end
85
168
 
86
- def test_request_class
169
+ def test_run_rack_app
87
170
  @app.define do
88
- get do
89
- res.write(req.class.name)
90
- end
171
+ run(proc { |_|
172
+ [200, { "Content-Type" => "text/plain", "Content-Length" => "4" }, ["hei!"]]
173
+ })
91
174
  end
92
175
 
93
176
  ts = Tynn::Test.new(@app)
94
177
  ts.get("/")
95
178
 
96
- assert_equal Tynn::Request.name, ts.res.body
179
+ assert_equal 200, ts.res.status
180
+ assert_equal "hei!", ts.res.body.join
181
+ assert_equal 4, ts.res.content_length
182
+ assert_equal "text/plain", ts.res.content_type
97
183
  end
98
184
 
99
- def test_response_class
185
+ def test_halt
100
186
  @app.define do
101
- get do
102
- res.write(res.class.name)
103
- end
187
+ res.status = 401
188
+ res.write("Unauthorized")
189
+
190
+ halt(res.finish)
191
+
192
+ raise "nothing to see here"
104
193
  end
105
194
 
106
195
  ts = Tynn::Test.new(@app)
107
196
  ts.get("/")
108
197
 
109
- assert_equal Tynn::Response.name, ts.res.body
198
+ assert_equal 401, ts.res.status
199
+ assert_equal "Unauthorized", ts.res.body.join
110
200
  end
111
201
  end