nyny 3.0.0 → 3.0.1
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 -11
- data/CHANGELOG +45 -40
- data/Gemfile +7 -8
- data/LICENSE.txt +22 -22
- data/Performance.md +41 -46
- data/README.md +423 -423
- data/Rakefile +6 -6
- data/benchmark.rb +116 -125
- data/lib/nyny.rb +33 -33
- data/lib/nyny/app.rb +79 -79
- data/lib/nyny/core-ext/runner.rb +19 -19
- data/lib/nyny/core-ext/templates.rb +20 -20
- data/lib/nyny/primitives.rb +25 -25
- data/lib/nyny/request_scope.rb +43 -43
- data/lib/nyny/route.rb +40 -40
- data/lib/nyny/router.rb +46 -44
- data/lib/nyny/version.rb +3 -3
- data/nyny.gemspec +29 -27
- data/spec/app_spec.rb +248 -248
- data/spec/inheritance_spec.rb +76 -75
- data/spec/nyny_spec.rb +11 -11
- data/spec/primitives_spec.rb +33 -33
- data/spec/request_scope_spec.rb +103 -103
- data/spec/router_spec.rb +29 -21
- data/spec/runner_spec.rb +23 -23
- data/spec/spec_helper.rb +61 -61
- data/spec/templates_spec.rb +52 -52
- data/spec/views/layout.erb +6 -6
- metadata +3 -3
data/spec/app_spec.rb
CHANGED
@@ -1,248 +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
|
-
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
|
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
|