tynn 0.0.1 → 0.0.2

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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gems +8 -5
  3. data/README.md +8 -0
  4. data/examples/composition.ru +42 -0
  5. data/examples/hello.ru +9 -0
  6. data/examples/render.ru +13 -0
  7. data/examples/views/home.erb +1 -0
  8. data/examples/views/layout.erb +5 -0
  9. data/lib/tynn/default_matcher.rb +7 -0
  10. data/lib/tynn/environment.rb +23 -0
  11. data/lib/tynn/erubis.rb +15 -0
  12. data/lib/tynn/hmote.rb +40 -0
  13. data/lib/tynn/hsts.rb +23 -0
  14. data/lib/tynn/json.rb +11 -0
  15. data/lib/tynn/json_parser.rb +34 -0
  16. data/lib/tynn/render.rb +56 -0
  17. data/lib/tynn/secure_headers.rb +15 -0
  18. data/lib/tynn/send_file.rb +12 -0
  19. data/lib/tynn/session.rb +11 -0
  20. data/lib/tynn/static.rb +10 -0
  21. data/lib/tynn/test.rb +16 -0
  22. data/lib/tynn/version.rb +1 -1
  23. data/lib/tynn.rb +31 -22
  24. data/makefile +9 -2
  25. data/test/core.rb +232 -0
  26. data/test/default_matcher.rb +17 -0
  27. data/test/environment.rb +31 -0
  28. data/test/erubis.rb +20 -0
  29. data/test/helper.rb +4 -11
  30. data/test/hmote.rb +78 -0
  31. data/test/hsts.rb +29 -0
  32. data/test/json.rb +19 -0
  33. data/test/json_parser.rb +22 -0
  34. data/test/render.rb +79 -0
  35. data/test/secure_headers.rb +20 -0
  36. data/test/send_file.rb +31 -0
  37. data/test/session.rb +22 -0
  38. data/test/static.rb +13 -0
  39. data/test/views/custom_layout.erb +1 -0
  40. data/test/views/custom_layout.mote +1 -0
  41. data/test/views/layout.erb +1 -0
  42. data/test/views/layout.mote +1 -0
  43. data/test/views/partial.erb +1 -0
  44. data/test/views/partial.mote +1 -0
  45. data/test/views/view.erb +1 -0
  46. data/test/views/view.mote +1 -0
  47. data/tynn.gemspec +5 -2
  48. metadata +82 -21
  49. data/test/captures.rb +0 -20
  50. data/test/composition.rb +0 -27
  51. data/test/hello.rb +0 -15
  52. data/test/helpers.rb +0 -54
  53. data/test/middleware.rb +0 -86
  54. data/test/settings.rb +0 -29
data/test/core.rb ADDED
@@ -0,0 +1,232 @@
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 "captures" do
16
+ Tynn.define do
17
+ on :foo do
18
+ on :bar do
19
+ res.write(sprintf("%s:%s", inbox[:foo], inbox[:bar]))
20
+ end
21
+ end
22
+ end
23
+
24
+ app = Tynn::Test.new
25
+ app.get("/foo/bar")
26
+
27
+ assert_equal 200, app.res.status
28
+ assert_equal "foo:bar", app.res.body
29
+ end
30
+
31
+ test "composition" do
32
+ class Foo < Tynn
33
+ end
34
+
35
+ Foo.define do
36
+ get do
37
+ res.write(inbox[:foo])
38
+ end
39
+ end
40
+
41
+ Tynn.define do
42
+ on "foo" do
43
+ run(Foo, foo: 42)
44
+ end
45
+ end
46
+
47
+ app = Tynn::Test.new
48
+ app.get("/foo")
49
+
50
+ assert_equal 200, app.res.status
51
+ assert_equal "42", app.res.body
52
+ end
53
+
54
+ test "settings" do
55
+ Tynn.settings[:message] = "hello"
56
+
57
+ Tynn.define do
58
+ get do
59
+ res.write(settings[:message])
60
+ end
61
+ end
62
+
63
+ app = Tynn::Test.new
64
+ app.get("/")
65
+
66
+ assert_equal "hello", app.res.body
67
+ end
68
+
69
+ test "raise unless application handler is set" do
70
+ app = Tynn::Test.new
71
+
72
+ assert_raise(RuntimeError) do
73
+ app.get("/")
74
+ end
75
+ end
76
+
77
+ scope "middleware" do
78
+ class Shrimp
79
+ def initialize(app)
80
+ @app = app
81
+ end
82
+
83
+ def call(env)
84
+ s, h, resp = @app.call(env)
85
+
86
+ return [s, h, resp.reverse]
87
+ end
88
+ end
89
+
90
+ setup do
91
+ Tynn.reset!
92
+ end
93
+
94
+ test "middleware in main application" do
95
+ Tynn.use(Shrimp)
96
+
97
+ Tynn.define do
98
+ get do
99
+ res.write("1")
100
+ res.write("2")
101
+ end
102
+ end
103
+
104
+ app = Tynn::Test.new
105
+ app.get("/")
106
+
107
+ assert_equal 200, app.res.status
108
+ assert_equal "21", app.res.body
109
+ end
110
+
111
+ test "middleware with composition" do
112
+ Tynn.use(Shrimp)
113
+
114
+ Tynn.define do
115
+ on "api" do
116
+ run(API)
117
+ end
118
+ end
119
+
120
+ class API < Tynn
121
+ end
122
+
123
+ API.define do
124
+ get do
125
+ res.write("1")
126
+ res.write("2")
127
+ end
128
+ end
129
+
130
+ app = Tynn::Test.new
131
+ app.get("/api")
132
+
133
+ assert_equal 200, app.res.status
134
+ assert_equal "21", app.res.body
135
+ end
136
+
137
+ test "middleware only in child application" do
138
+ Tynn.define do
139
+ on "api" do
140
+ run(API)
141
+ end
142
+ end
143
+
144
+ class API < Tynn
145
+ use(Shrimp)
146
+ end
147
+
148
+ API.define do
149
+ get do
150
+ res.write("1")
151
+ res.write("2")
152
+ end
153
+ end
154
+
155
+ app = Tynn::Test.new
156
+ app.get("/api")
157
+
158
+ assert_equal 200, app.res.status
159
+ assert_equal "21", app.res.body
160
+ end
161
+ end
162
+
163
+ scope "helpers" do
164
+ module Helper
165
+ def clean(str)
166
+ return str.strip
167
+ end
168
+
169
+ module Number
170
+ def self.setup(app, number)
171
+ app.settings[:number] = number
172
+ end
173
+
174
+ def number
175
+ return settings[:number]
176
+ end
177
+ end
178
+
179
+ def self.setup(app, number = 1)
180
+ app.helpers(Number, number)
181
+ end
182
+
183
+ module ClassMethods
184
+ def foo
185
+ "foo"
186
+ end
187
+ end
188
+ end
189
+
190
+ setup do
191
+ Tynn::Test.new
192
+ end
193
+
194
+ test "helpers" do |app|
195
+ Tynn.helpers(Helper)
196
+
197
+ Tynn.define do
198
+ get do
199
+ res.write(clean(" foo "))
200
+ end
201
+ end
202
+
203
+ app.get("/")
204
+
205
+ assert_equal "foo", app.res.body
206
+ assert_equal "foo", Tynn.foo
207
+ end
208
+
209
+ test "setup" do |app|
210
+ Tynn.helpers(Helper)
211
+
212
+ Tynn.define do
213
+ res.write(number)
214
+ end
215
+
216
+ app.get("/")
217
+
218
+ assert_equal "1", app.res.body
219
+ end
220
+
221
+ test "setup with arguments" do |app|
222
+ Tynn.helpers(Helper, 2)
223
+
224
+ Tynn.define do
225
+ res.write(number)
226
+ end
227
+
228
+ app.get("/")
229
+
230
+ assert_equal "2", app.res.body
231
+ end
232
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "../lib/tynn/default_matcher"
2
+
3
+ test "default" do
4
+ Tynn.helpers(Tynn::DefaultMatcher)
5
+
6
+ Tynn.define do
7
+ default do
8
+ res.write("foo")
9
+ end
10
+ end
11
+
12
+ app = Tynn::Test.new
13
+ app.get("/")
14
+
15
+ assert_equal 200, app.res.status
16
+ assert_equal "foo", app.res.body
17
+ end
@@ -0,0 +1,31 @@
1
+ require_relative "../lib/tynn/environment"
2
+
3
+ test "default" do
4
+ Tynn.helpers(Tynn::Environment)
5
+
6
+ assert_equal(:development, Tynn.environment)
7
+ end
8
+
9
+ test "helpers" do
10
+ Tynn.helpers(Tynn::Environment)
11
+
12
+ assert Tynn.development?
13
+ assert !Tynn.test?
14
+ assert !Tynn.production?
15
+ end
16
+
17
+ test "use RACK_ENV by default" do
18
+ ENV["RACK_ENV"] = "production"
19
+
20
+ Tynn.helpers(Tynn::Environment)
21
+
22
+ assert_equal(:production, Tynn.environment)
23
+
24
+ ENV.delete("RACK_ENV")
25
+ end
26
+
27
+ test "use custom value" do
28
+ Tynn.helpers(Tynn::Environment, env: "development")
29
+
30
+ assert_equal(:development, Tynn.environment)
31
+ end
data/test/erubis.rb ADDED
@@ -0,0 +1,20 @@
1
+ require_relative "../lib/tynn/erubis"
2
+
3
+ setup do
4
+ Tynn.helpers(Tynn::Erubis, views: File.expand_path("./test/views"))
5
+
6
+ Tynn::Test.new
7
+ end
8
+
9
+ test "escapes" do |app|
10
+ Tynn.define do
11
+ root do
12
+ res.write(partial("partial", name: "<a></a>"))
13
+ end
14
+ end
15
+
16
+ app = Tynn::Test.new
17
+ app.get("/")
18
+
19
+ assert_equal "&lt;a&gt;&lt;/a&gt;", app.res.body.strip
20
+ end
data/test/helper.rb CHANGED
@@ -1,17 +1,10 @@
1
- $VERBOSE = ENV["VERBOSE"]
1
+ $VERBOSE = true
2
2
 
3
3
  require "cutest"
4
4
  require "rack/test"
5
5
  require_relative "../lib/tynn"
6
+ require_relative "../lib/tynn/test"
6
7
 
7
- class Driver
8
- include Rack::Test::Methods
9
-
10
- attr_reader :app
11
-
12
- def initialize(app)
13
- @app = app
14
- end
15
-
16
- alias_method :res, :last_response
8
+ prepare do
9
+ Tynn.reset!
17
10
  end
data/test/hmote.rb ADDED
@@ -0,0 +1,78 @@
1
+ require_relative "../lib/tynn/hmote"
2
+
3
+ setup do
4
+ Tynn.helpers(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
+ 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
data/test/hsts.rb ADDED
@@ -0,0 +1,29 @@
1
+ require_relative "../lib/tynn/hsts"
2
+
3
+ test "hsts" do
4
+ Tynn.helpers(Tynn::HSTS)
5
+
6
+ Tynn.define do
7
+ end
8
+
9
+ app = Tynn::Test.new
10
+ app.get("/")
11
+
12
+ header = app.res.headers["Strict-Transport-Security"]
13
+
14
+ assert_equal "max-age=15552000; includeSubdomains", header
15
+ end
16
+
17
+ test "hsts with options" do
18
+ Tynn.helpers(Tynn::HSTS, max_age: 1, preload: true)
19
+
20
+ Tynn.define do
21
+ end
22
+
23
+ app = Tynn::Test.new
24
+ app.get("/")
25
+
26
+ header = app.res.headers["Strict-Transport-Security"]
27
+
28
+ assert_equal "max-age=1; includeSubdomains; preload", header
29
+ end
data/test/json.rb ADDED
@@ -0,0 +1,19 @@
1
+ require_relative "../lib/tynn/json"
2
+
3
+ test "json" do
4
+ Tynn.helpers(Tynn::JSON)
5
+
6
+ Tynn.define do
7
+ root do
8
+ json(name: "tynn")
9
+ end
10
+ end
11
+
12
+ app = Tynn::Test.new
13
+ app.get("/")
14
+
15
+ json = JSON.parse(app.res.body)
16
+
17
+ assert_equal "tynn", json["name"]
18
+ assert_equal "application/json", app.res.headers["Content-Type"]
19
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "../lib/tynn/json_parser"
2
+
3
+ headers = {
4
+ "CONTENT_TYPE" => "application/json"
5
+ }
6
+
7
+ test "json body parse" do
8
+ Tynn.helpers(Tynn::JSONParser)
9
+
10
+ params = { "foo" => "foo" }
11
+
12
+ Tynn.define do
13
+ root do
14
+ res.write(JSON.generate(req.params))
15
+ end
16
+ end
17
+
18
+ app = Tynn::Test.new(Tynn)
19
+ app.post("/", JSON.generate(params), headers)
20
+
21
+ assert_equal params, JSON.parse(app.res.body)
22
+ end
data/test/render.rb ADDED
@@ -0,0 +1,79 @@
1
+ require "erb"
2
+ require_relative "../lib/tynn/render"
3
+
4
+ setup do
5
+ Tynn.helpers(Tynn::Render, views: File.expand_path("./test/views"))
6
+
7
+ Tynn::Test.new
8
+ end
9
+
10
+ test "partial" do |app|
11
+ Tynn.define do
12
+ on "partial" do
13
+ res.write(partial("partial", name: "erb"))
14
+ end
15
+ end
16
+
17
+ app.get("/partial")
18
+
19
+ assert_equal "erb", app.res.body.strip
20
+ end
21
+
22
+ test "view" do |app|
23
+ Tynn.define do
24
+ on "view" do
25
+ res.write(view("view", title: "tynn", name: "erb"))
26
+ end
27
+ end
28
+
29
+ app.get("/view")
30
+
31
+ assert_equal "tynn / erb", app.res.body.strip
32
+ end
33
+
34
+ test "render" do |app|
35
+ Tynn.define do
36
+ on "render" do
37
+ render("view", title: "tynn", name: "erb")
38
+ end
39
+ end
40
+
41
+ app.get("/render")
42
+
43
+ assert_equal 200, app.res.status
44
+ assert_equal "text/html", app.res.headers["Content-Type"]
45
+ assert_equal "tynn / erb", app.res.body.strip
46
+ end
47
+
48
+ test "404" do |app|
49
+ Tynn.define do
50
+ on "404" do
51
+ res.status = 404
52
+
53
+ render("view", title: "tynn", name: "erb")
54
+ end
55
+ end
56
+
57
+ app.get("/404")
58
+
59
+ assert_equal 404, app.res.status
60
+ assert_equal "text/html", app.res.headers["Content-Type"]
61
+ assert_equal "tynn / erb", app.res.body.strip
62
+ end
63
+
64
+ test "custom layout" do
65
+ class App < Tynn
66
+ layout("custom_layout")
67
+ end
68
+
69
+ App.define do
70
+ root do
71
+ render("view", title: "tynn", name: "erb")
72
+ end
73
+ end
74
+
75
+ app = Tynn::Test.new(App)
76
+ app.get("/")
77
+
78
+ assert_equal "custom / tynn / erb", app.res.body.strip
79
+ end
@@ -0,0 +1,20 @@
1
+ require_relative "../lib/tynn/secure_headers"
2
+
3
+ test "secure headers" do
4
+ Tynn.helpers(Tynn::SecureHeaders)
5
+
6
+ Tynn.define do
7
+ root do
8
+ res.write("safe")
9
+ end
10
+ end
11
+
12
+ app = Tynn::Test.new
13
+ app.get("/")
14
+
15
+ headers = app.res.headers
16
+
17
+ Tynn::SecureHeaders::HEADERS.each do |header, value|
18
+ assert_equal(value, headers[header])
19
+ end
20
+ end
data/test/send_file.rb ADDED
@@ -0,0 +1,31 @@
1
+ require_relative "../lib/tynn/send_file"
2
+
3
+ test "file send" do
4
+ Tynn.helpers(Tynn::SendFile)
5
+
6
+ Tynn.define do
7
+ root do
8
+ send_file(__FILE__)
9
+ end
10
+ end
11
+
12
+ app = Tynn::Test.new
13
+ app.get("/")
14
+
15
+ assert_equal File.read(__FILE__), app.res.body
16
+ end
17
+
18
+ test "file not exists" do
19
+ Tynn.helpers(Tynn::SendFile)
20
+
21
+ Tynn.define do
22
+ root do
23
+ send_file("notexists")
24
+ end
25
+ end
26
+
27
+ app = Tynn::Test.new
28
+ app.get("/")
29
+
30
+ assert_equal 404, app.res.status
31
+ end
data/test/session.rb ADDED
@@ -0,0 +1,22 @@
1
+ require "securerandom"
2
+ require_relative "../lib/tynn/session"
3
+
4
+ test "session" do
5
+ Tynn.helpers(Tynn::Session, secret: SecureRandom.hex(64))
6
+
7
+ Tynn.define do
8
+ root do
9
+ session[:foo] = "foo"
10
+
11
+ res.write(session[:foo])
12
+ end
13
+ end
14
+
15
+ app = Tynn::Test.new
16
+ app.get("/")
17
+
18
+ env = app.last_request.env
19
+
20
+ assert_equal "foo", app.res.body
21
+ assert_equal "foo", env["rack.session"]["foo"]
22
+ end
data/test/static.rb ADDED
@@ -0,0 +1,13 @@
1
+ require_relative "../lib/tynn/static"
2
+
3
+ test "static" do
4
+ Tynn.helpers(Tynn::Static, %w(/test), root: Dir.pwd)
5
+
6
+ Tynn.define do
7
+ end
8
+
9
+ app = Tynn::Test.new
10
+ app.get("/test/static.rb")
11
+
12
+ assert_equal File.read(__FILE__), app.res.body
13
+ end
@@ -0,0 +1 @@
1
+ custom / <%= content %>
@@ -0,0 +1 @@
1
+ custom / {{! content }}
@@ -0,0 +1 @@
1
+ <%= content %>
@@ -0,0 +1 @@
1
+ {{! content }}
@@ -0,0 +1 @@
1
+ <%= name %>
@@ -0,0 +1 @@
1
+ {{ name }}
@@ -0,0 +1 @@
1
+ <%= title %> / <%= partial("partial", name: name) %>
@@ -0,0 +1 @@
1
+ {{ title }} / {{! app.partial("partial", name: name) }}
data/tynn.gemspec CHANGED
@@ -12,9 +12,12 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.files = `git ls-files`.split("\n")
14
14
 
15
- s.add_dependency "syro", "~> 0.0.7"
16
- s.add_dependency "rack", "~> 1.6.4"
15
+ s.add_dependency "rack", "~> 1.6"
17
16
  s.add_dependency "seteable", "1.0.0"
17
+ s.add_dependency "syro", "~> 0.0.8"
18
+
18
19
  s.add_development_dependency "cutest", "1.2.2"
20
+ s.add_development_dependency "hmote", "1.4.0"
19
21
  s.add_development_dependency "rack-test", "0.6.3"
22
+ s.add_development_dependency "tilt", "~> 2.0"
20
23
  end