nyny 2.2.1 → 3.0.0
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.
- checksums.yaml +4 -4
- data/.gitignore +20 -20
- data/.rspec +2 -2
- data/.ruby-version +1 -1
- data/.travis.yml +11 -12
- data/CHANGELOG +40 -27
- data/Gemfile +8 -8
- data/LICENSE.txt +22 -22
- data/Performance.md +46 -44
- data/README.md +423 -381
- data/Rakefile +6 -6
- data/benchmark.rb +125 -125
- data/lib/nyny.rb +33 -36
- data/lib/nyny/app.rb +79 -67
- data/lib/nyny/core-ext/runner.rb +19 -19
- data/lib/nyny/core-ext/templates.rb +20 -18
- data/lib/nyny/primitives.rb +25 -25
- data/lib/nyny/request_scope.rb +43 -52
- data/lib/nyny/route.rb +40 -40
- data/lib/nyny/router.rb +44 -43
- data/lib/nyny/version.rb +3 -3
- data/nyny.gemspec +27 -26
- data/spec/app_spec.rb +248 -200
- data/spec/inheritance_spec.rb +76 -0
- data/spec/nyny_spec.rb +11 -11
- data/spec/primitives_spec.rb +33 -33
- data/spec/request_scope_spec.rb +103 -105
- data/spec/router_spec.rb +21 -21
- data/spec/runner_spec.rb +23 -22
- data/spec/spec_helper.rb +61 -58
- data/spec/templates_spec.rb +52 -52
- data/spec/views/layout.erb +6 -6
- metadata +27 -12
- data/lib/nyny/middleware_chain.rb +0 -14
data/spec/app_spec.rb
CHANGED
@@ -1,200 +1,248 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe App do
|
4
|
-
let (:app) { mock_app {} }
|
5
|
-
|
6
|
-
it 'should return a rack response on call' do
|
7
|
-
response = app.get '/'
|
8
|
-
response.should be_a(Rack::Response)
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'should return 404 for non-matched routes' do
|
12
|
-
response = app.get random_url
|
13
|
-
response.status.should == 404
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'should able to register a extension' do
|
17
|
-
module Foo
|
18
|
-
def foo
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
kls = mock_app_class {}
|
23
|
-
kls.register(Foo)
|
24
|
-
kls.should respond_to(:foo)
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
app
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
end
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
end
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
end
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe App do
|
4
|
+
let (:app) { mock_app {} }
|
5
|
+
|
6
|
+
it 'should return a rack response on call' do
|
7
|
+
response = app.get '/'
|
8
|
+
response.should be_a(Rack::Response)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should return 404 for non-matched routes' do
|
12
|
+
response = app.get random_url
|
13
|
+
response.status.should == 404
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should able to register a extension' do
|
17
|
+
module Foo
|
18
|
+
def foo
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
kls = mock_app_class {}
|
23
|
+
kls.register(Foo)
|
24
|
+
kls.should respond_to(:foo)
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'namespace' do
|
28
|
+
let (:app) do
|
29
|
+
mock_app do
|
30
|
+
namespace '/foo' do
|
31
|
+
get '/' do
|
32
|
+
'bar'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
namespace '/nested' do
|
37
|
+
namespace '/space' do
|
38
|
+
get '/' do
|
39
|
+
'caramba'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
get '/' do
|
45
|
+
'no namespace here'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'allows to specify stuff in namespaces' do
|
51
|
+
app.get('/foo').body.should == 'bar'
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'does not break the main app' do
|
55
|
+
app.get('/').body.should == 'no namespace here'
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'can be nested as well' do
|
59
|
+
app.get('/nested/space/').body.should == 'caramba'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should call registered method on extension' do
|
64
|
+
module Foo
|
65
|
+
def self.registered app
|
66
|
+
#
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class SomeApp < NYNY::App
|
71
|
+
end
|
72
|
+
|
73
|
+
Foo.should_receive(:registered).with(SomeApp)
|
74
|
+
SomeApp.register(Foo)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should match a route for any supported verbs' do
|
78
|
+
url = random_url
|
79
|
+
verb = App::HTTP_VERBS.sample
|
80
|
+
|
81
|
+
app = mock_app do
|
82
|
+
send verb, url do
|
83
|
+
'foo'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
res = app.send verb, url
|
88
|
+
res.body.should == 'foo'
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should support route patterns' do
|
92
|
+
app = mock_app do
|
93
|
+
get '/some/:name' do
|
94
|
+
'foo'
|
95
|
+
end
|
96
|
+
|
97
|
+
get '/:name' do
|
98
|
+
"hello #{params[:name]}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
res = app.get '/foo'
|
103
|
+
res.body.should == "hello foo"
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should support adding before filers' do
|
107
|
+
app = mock_app do
|
108
|
+
before do
|
109
|
+
request.should_not == nil
|
110
|
+
end
|
111
|
+
|
112
|
+
get '/' do
|
113
|
+
"hello"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
app.get('/')
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'does not maintain state between requests' do
|
121
|
+
app = mock_app do
|
122
|
+
get '/state' do
|
123
|
+
@foo ||= "new"
|
124
|
+
body = "Foo: #{@foo}"
|
125
|
+
@foo = 'discard'
|
126
|
+
body
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
2.times do
|
131
|
+
response = app.get('/state')
|
132
|
+
response.should be_ok
|
133
|
+
'Foo: new'.should == response.body
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'acts well as a middleware' do
|
138
|
+
app = lambda do |env|
|
139
|
+
[210, {}, ['Hello from downstream']]
|
140
|
+
end
|
141
|
+
|
142
|
+
app_class = mock_app_class do
|
143
|
+
get '/' do
|
144
|
+
'hello'
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
frankie = app_class.new(app)
|
149
|
+
req = Rack::MockRequest.new frankie
|
150
|
+
res = req.get '/'
|
151
|
+
res.body.should == 'hello'
|
152
|
+
|
153
|
+
res2 = req.get '/ither'
|
154
|
+
res2.body.should == 'Hello from downstream'
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'should support adding after filers' do
|
158
|
+
app = mock_app do
|
159
|
+
after do
|
160
|
+
response.should_not == nil
|
161
|
+
end
|
162
|
+
|
163
|
+
get '/' do
|
164
|
+
"hello"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
app.get '/'
|
168
|
+
end
|
169
|
+
|
170
|
+
describe 'cookies' do
|
171
|
+
let (:app) do
|
172
|
+
mock_app do
|
173
|
+
post '/cookie' do
|
174
|
+
cookies['foo'] = 'bar'
|
175
|
+
end
|
176
|
+
|
177
|
+
delete '/cookie' do
|
178
|
+
cookies.delete 'foo'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'sets a cookie' do
|
184
|
+
res = app.post '/cookie'
|
185
|
+
res.headers['Set-Cookie'].should == 'foo=bar; path=/'
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'deletes a cookie' do
|
189
|
+
app.post '/cookie'
|
190
|
+
res = app.delete '/cookie'
|
191
|
+
res.headers['Set-Cookie'].should_not include('foo=bar')
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'works with empty path' do
|
196
|
+
kls = mock_app_class do
|
197
|
+
get '/' do
|
198
|
+
'Hello'
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
env = Rack::MockRequest.env_for '/'
|
203
|
+
env['PATH_INFO'] = ''
|
204
|
+
kls.new.call(env)[2].body.first.should == 'Hello'
|
205
|
+
end
|
206
|
+
|
207
|
+
describe 'Class level api' do
|
208
|
+
let (:app_class) { Class.new(App) }
|
209
|
+
|
210
|
+
describe 'middlewares' do
|
211
|
+
|
212
|
+
it 'delegates to builder' do
|
213
|
+
kls = mock_app_class
|
214
|
+
kls.builder.should_receive(:use).with(NullMiddleware)
|
215
|
+
kls.use(NullMiddleware)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe 'helpers' do
|
220
|
+
it 'should allow to include a helper in request scope' do
|
221
|
+
app_class.helpers NullHelper
|
222
|
+
app_class.scope_class.ancestors.should include(NullHelper)
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'should allow to include multiple helpers modules' do
|
226
|
+
module NullHelper2
|
227
|
+
end
|
228
|
+
|
229
|
+
app_class.helpers NullHelper, NullHelper2
|
230
|
+
app_class.scope_class.ancestors.should include(NullHelper, NullHelper2)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'should allow to define helpers with a block' do
|
234
|
+
app_class.helpers do
|
235
|
+
def foo
|
236
|
+
'bar'
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
app_class.get '/' do
|
241
|
+
foo.should == 'bar'
|
242
|
+
end
|
243
|
+
req = Rack::MockRequest.env_for '/'
|
244
|
+
res = app_class.new.call(req)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NYNY::App do
|
4
|
+
describe 'inheritance' do
|
5
|
+
class Parent < NYNY::App
|
6
|
+
helpers do
|
7
|
+
def parent_helper; :parent; end
|
8
|
+
end
|
9
|
+
|
10
|
+
before do
|
11
|
+
headers['parent before'] = 'true'
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
headers['parent after'] = 'true'
|
16
|
+
end
|
17
|
+
|
18
|
+
get '/helpers' do
|
19
|
+
parent_helper.should == :parent
|
20
|
+
end
|
21
|
+
|
22
|
+
get '/parent' do
|
23
|
+
'parent'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Child < Parent
|
28
|
+
helpers do
|
29
|
+
def child_helper; :child; end
|
30
|
+
end
|
31
|
+
|
32
|
+
before do
|
33
|
+
headers['child before'] = 'true'
|
34
|
+
end
|
35
|
+
|
36
|
+
after do
|
37
|
+
headers['child after'] = 'true'
|
38
|
+
end
|
39
|
+
|
40
|
+
get '/helpers' do
|
41
|
+
child_helper.should == :child
|
42
|
+
end
|
43
|
+
|
44
|
+
get '/child' do
|
45
|
+
'child'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
let (:parent) { Rack::MockRequest.new Parent.new }
|
50
|
+
let (:child) { Rack::MockRequest.new Child.new }
|
51
|
+
|
52
|
+
it 'works correctly for routes' do
|
53
|
+
parent.get('/parent').body.should == 'parent'
|
54
|
+
parent.get('/child').status.should == 404
|
55
|
+
child.get('/parent').body.should == 'parent'
|
56
|
+
child.get('/child').body.should == 'child'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'works correctly for before filters' do
|
60
|
+
parent.get('/parent').headers['child before'].should be_nil
|
61
|
+
child.get('/parent').headers['child before'].should_not be_nil
|
62
|
+
child.get('/parent').headers['parent before'].should_not be_nil
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'works correctly for after filters' do
|
66
|
+
parent.get('/parent').headers['child after'].should be_nil
|
67
|
+
child.get('/parent').headers['child after'].should_not be_nil
|
68
|
+
child.get('/parent').headers['parent after'].should_not be_nil
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'works correctly for helpers' do
|
72
|
+
parent.get('/helpers')
|
73
|
+
child.get('/helpers')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|