nyny 1.0.2 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4590f5f6c66d42152fecc4f0749bfe4f198d6987
4
- data.tar.gz: 799af0e6c6f79f90fa6ecf627a83d7e7f40e64bc
3
+ metadata.gz: fa8bdccd5f35a66eaa05e512117950e230350185
4
+ data.tar.gz: 9932d345a2b696477bb9eef615671ce9db598de1
5
5
  SHA512:
6
- metadata.gz: 1605466f98f71349ea745155617b54bcf91d245b92f878931457ffdffe7e44c55b348d280c20eeb84f73f6efbb4e4ee64bc4cbd203172d7ed6b8803b8930c31e
7
- data.tar.gz: 28bb352a548d9eb62b759284c3cb153a624db86b640029fc318263c21ae5b1bc6f91df4c593895f32f7afb15d8588a2711c262db2a62b39a363e021ac418841d
6
+ metadata.gz: 941652c537350c79204235b9d62af1dd7a55f0e2074a4c75043fad5f793c5ec87c1f85f6d02ec28d7df3286ac56270b1f2d7aaef07f272d5480ae6f13db3ea27
7
+ data.tar.gz: a4a63feaf107bc95a0981f7b087c2a1e03d918bcf63fc1fbe23d3bf3e059a39b3124f3f8c5582fc03563deb4ca3866e3542f1803d6ca58186e03a36954aafb6f
data/CHANGELOG ADDED
@@ -0,0 +1,9 @@
1
+ 2.0.0
2
+ - Simplified and improved RouteSignature implementation
3
+ - Simplified and improved RequestScope implementation
4
+ - Made response object available in RequestScope
5
+ - removed .use_protection! (the rack-protection) middleware can be easily
6
+ used manually
7
+ - add .register, which registers an extension (works the same way as in sinatra)
8
+
9
+ 1.0.0 Initial release
data/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
  [![Build Status](https://api.travis-ci.org/alisnic/nyny.png)](https://travis-ci.org/alisnic/nyny)
5
5
  [![Coverage Status](https://coveralls.io/repos/alisnic/nyny/badge.png)](https://coveralls.io/r/alisnic/nyny)
6
6
  [![Code Climate](https://codeclimate.com/repos/521b7ee513d637348712864a/badges/60e3637788bbac94f1cb/gpa.png)](https://codeclimate.com/repos/521b7ee513d637348712864a/feed)
7
+ [![Dependency Status](https://gemnasium.com/alisnic/nyny.png)](https://gemnasium.com/alisnic/nyny)
8
+ [![Gem Version](https://badge.fury.io/rb/nyny.png)](http://badge.fury.io/rb/nyny)
7
9
 
8
10
  # myapp.rb
9
11
 
@@ -37,6 +39,7 @@ Open the browser at [http://localhost:9292](http://localhost:9292)
37
39
  - [Filters](#filters)
38
40
  - [Middleware](#middleware)
39
41
  - [Helpers](#helpers)
42
+ - [Extensions](#extensions)
40
43
  - [FAQ](#f-a-q)
41
44
  - [Contributing](#contributing)
42
45
 
@@ -138,8 +141,9 @@ As was said above, when you pass a block to a route definition,
138
141
  that block is evaluated in the context of a [RequestScope][2].
139
142
  This means that several methods/objects available inside that block:
140
143
 
141
- - `request` - A `Rack::Request` object which encapsulates the request
144
+ - `request` - A `Rack::Request` object which encapsulates the request
142
145
  to that route. (see [Rack::Request documentation][3] for more info)
146
+ - `response` - A `Rack::Response` object which encapsulates the response
143
147
  - `params` - a hash which contains both POST body params and GET querystring params.
144
148
  - `headers` - allows you to read/add headers to the response
145
149
  (ex: `headers 'Content-Type' => 'text/html'`)
@@ -175,10 +179,6 @@ if the request.path matches a pattern.
175
179
  end
176
180
  end
177
181
 
178
- Before and after filters are also evaluated in a RequestScope context.
179
- A little exception are the after filters, which can access
180
- the __response__ object ([Rack::Response][4]).
181
-
182
182
  ## Middleware
183
183
 
184
184
  A NYNY app is a Rack middleware, which means that it can be used inside
@@ -211,6 +211,60 @@ Using a helper implies that the helper module is included in the [RequestScope][
211
211
  and that all the methods in that module will be available inside a route
212
212
  definition block.
213
213
 
214
+ ## Extensions
215
+
216
+ Since version 2.0.0, NYNY added support for extensions.
217
+ This makes possible to include helpers, middlewares and custom app class
218
+ methods inside a single module:
219
+
220
+ module MyKewlExtension
221
+ class Middleware
222
+ def initialize app
223
+ @app = app
224
+ end
225
+
226
+ def call env
227
+ env['KEWL'] = true
228
+ @app.call(env) if @app
229
+ end
230
+ end
231
+
232
+ module Helpers
233
+ def the_ultimate_answer
234
+ 42
235
+ end
236
+ end
237
+
238
+ def get_or_post route, &block
239
+ get route, &block
240
+ post route, &block
241
+ end
242
+
243
+ def self.registered app
244
+ app.use Middleware
245
+ app.helpers Helpers
246
+
247
+ app.get_or_post '/' do
248
+ "After many years of hard computation, the answer is #{the_ultimate_answer}"
249
+ end
250
+ end
251
+ end
252
+
253
+ class App < NYNY::App
254
+ register MyKewlExtension
255
+ end
256
+
257
+ App.run!
258
+
259
+ By default, the App class will `extend` the provided extension module.
260
+ Optionally, an extension can add a `registered` method, which will be invoked
261
+ once the extension is registered. That method will be called with the app class
262
+ as a parameter.
263
+
264
+ Since NYNY has the same extension interface as Sinatra, some Sinatra extensions
265
+ might work with NYNY, although that is not guaranteed. However, an extension
266
+ written for NYNY will always work with Sinatra. (Forward compatible)
267
+
214
268
  # F. A. Q.
215
269
  TBD.
216
270
 
@@ -4,6 +4,7 @@ gem 'activerecord', :require => 'active_record'
4
4
  gem 'sqlite3'
5
5
  gem 'rack'
6
6
  gem 'thin'
7
+ gem 'protected_attributes'
7
8
 
8
9
  group :development do
9
10
  #
@@ -1,3 +1,4 @@
1
+ require 'protected_attributes'
1
2
  require 'active_record'
2
3
 
3
4
  ENV['RACK_ENV'] ||= 'development'
@@ -1,6 +1,6 @@
1
1
  require 'data_mapper'
2
2
 
3
- DataMapper.setup(:default, "sqlite:///#{Dir.pwd}/db/database.sqlite3")
3
+ DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/db/database.sqlite3")
4
4
  Dir[File.dirname(__FILE__) + "/models/*.rb"].each {|f| require f }
5
5
 
6
6
  DataMapper.finalize
@@ -0,0 +1 @@
1
+ *.sqlite3
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'faye-websocket'
4
+
data/lib/nyny/app.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  module NYNY
2
2
  class App
3
3
  HTTP_VERBS = [:delete, :get, :head, :options, :patch, :post, :put, :trace]
4
- extend Runner
5
4
 
6
5
  attr_reader :middleware_chain, :router
7
6
  def initialize app=nil
@@ -36,12 +35,11 @@ module NYNY
36
35
  def before_hooks; @before_hooks ||= [] end
37
36
  def after_hooks; @after_hooks ||= [] end
38
37
 
39
- def use_protection! args={}
40
- begin
41
- require 'rack/protection'
42
- middlewares.unshift [Rack::Protection, args]
43
- rescue LoadError
44
- puts "WARN: to use protection, you must install 'rack-protection' gem"
38
+ # move middleware chain and runner to core-ext
39
+ def register *extensions
40
+ extensions.each do |ext|
41
+ extend ext
42
+ ext.registered(self) if ext.respond_to?(:registered)
45
43
  end
46
44
  end
47
45
 
File without changes
@@ -7,9 +7,8 @@ module NYNY
7
7
  end
8
8
 
9
9
  def initialize request
10
- @headers = {'Content-Type' => 'text/html'}
11
- @status = 200
12
10
  @request = request
11
+ @response = Response.new '', 200, {'Content-Type' => 'text/html'}
13
12
  end
14
13
 
15
14
  def params
@@ -17,7 +16,7 @@ module NYNY
17
16
  end
18
17
 
19
18
  def headers hash={}
20
- @headers.merge! hash
19
+ response.headers.merge! hash
21
20
  end
22
21
 
23
22
  def session
@@ -29,11 +28,14 @@ module NYNY
29
28
  end
30
29
 
31
30
  def status code
32
- @status = code
31
+ response.status = code
33
32
  end
34
33
 
35
34
  def halt status, headers={}, body=''
36
- throw :halt, Response.new(body, status, @headers.merge(headers))
35
+ response.status = status
36
+ response.headers.merge! headers
37
+ response.body = body
38
+ throw :halt, response
37
39
  end
38
40
 
39
41
  def redirect_to uri, status=302
@@ -42,9 +44,9 @@ module NYNY
42
44
  alias_method :redirect, :redirect_to
43
45
 
44
46
  def apply_to &handler
45
- @response = Response.new instance_eval(&handler), @status, @headers
46
- cookies.each {|k,v| @response.set_cookie k,v }
47
- @response
47
+ response.body = instance_eval(&handler)
48
+ cookies.each {|k,v| response.set_cookie k,v }
49
+ response
48
50
  end
49
51
  end
50
52
  end
@@ -7,15 +7,14 @@ module NYNY
7
7
  @pattern = pattern_for signature
8
8
  end
9
9
 
10
- def pattern_for string
11
- return string if string.is_a? Regexp
12
- return string unless string.include? ':'
13
-
14
- signature = string.start_with?('/') ? string : "/#{string}"
15
- build_regex signature
10
+ def pattern_for signature
11
+ return signature if signature.is_a? Regexp
12
+ build_regex(signature.start_with?('/') ? signature : "/#{signature}")
16
13
  end
17
14
 
18
15
  def build_regex signature
16
+ return %r(^#{signature}$) unless signature.include?(':')
17
+
19
18
  groups = signature.split('/').map do |part|
20
19
  next part if part.empty?
21
20
  next part unless part.start_with? ':'
@@ -23,21 +22,13 @@ module NYNY
23
22
  %Q{(?<#{name}>\\S+)}
24
23
  end.select {|s| !s.empty? }.join('\/')
25
24
 
26
- %r(\/#{groups})
25
+ %r(^\/#{groups}$)
27
26
  end
28
27
 
29
28
  def match path
30
- return (pattern == path ? {} : nil) if pattern.is_a?(String)
31
29
  data = pattern.match path
32
-
33
30
  if data
34
- if pattern.respond_to? :names
35
- Hash[data.names.map {|n| [n.to_sym, URI.unescape(data[n])]}]
36
- else
37
- {}
38
- end
39
- else
40
- nil
31
+ Hash[data.names.map {|n| [n.to_sym, URI.unescape(data[n])]}]
41
32
  end
42
33
  end
43
34
  end
data/lib/nyny/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module NYNY
2
- VERSION = "1.0.2"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/nyny.rb CHANGED
@@ -5,7 +5,14 @@ require 'nyny/version'
5
5
  require 'nyny/primitives'
6
6
  require 'nyny/request_scope'
7
7
  require 'nyny/route_signature'
8
- require 'nyny/runner'
9
8
  require 'nyny/middleware_chain'
10
- require 'nyny/router'
11
9
  require 'nyny/app'
10
+ require 'nyny/router'
11
+
12
+
13
+ # Register core extensions
14
+ require 'nyny/core-ext/runner'
15
+
16
+ module NYNY
17
+ App.register NYNY::Runner
18
+ end
data/spec/app_spec.rb CHANGED
@@ -13,12 +13,29 @@ describe App do
13
13
  response.status.should == 404
14
14
  end
15
15
 
16
- it '.use_protection! should add protection middleware on top' do
17
- app_class = mock_app_class do
18
- use_protection!
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
+ it 'should call registered method on extension' do
28
+ module Foo
29
+ def self.registered app
30
+ #
31
+ end
32
+ end
33
+
34
+ class SomeApp < NYNY::App
19
35
  end
20
36
 
21
- app_class.middlewares.first.should == [Rack::Protection, {}]
37
+ Foo.should_receive(:registered).with(SomeApp)
38
+ SomeApp.register(Foo)
22
39
  end
23
40
 
24
41
  it 'should match a route for any supported verbs' do
@@ -37,6 +54,10 @@ describe App do
37
54
 
38
55
  it 'should support route patterns' do
39
56
  app = mock_app do
57
+ get '/some/:name' do
58
+ 'foo'
59
+ end
60
+
40
61
  get '/:name' do
41
62
  "hello #{params[:name]}"
42
63
  end
data/spec/runner_spec.rb CHANGED
@@ -1,23 +1,16 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Runner do
4
- describe '.run!' do
5
- before do
6
- handler = begin
7
- Rack::Handler::Thin
8
- rescue LoadError
9
- Rack::Handler::WEBrick
10
- end
11
- handler.stub :run
12
- end
4
+ let (:kls) { mock_app_class {} }
13
5
 
14
- it 'should include the default middleware on top' do
15
- kls = mock_app_class do
16
- end
6
+ before do
7
+ kls.optimal_runner.stub :run
8
+ end
17
9
 
18
- kls.run!
19
- kls.middlewares.first.should == Rack::ShowExceptions
20
- kls.middlewares[1].should == Rack::CommonLogger
21
- end
10
+ it 'should include the default middleware on top' do
11
+ kls.run!
12
+ kls.middlewares.first.should == Rack::ShowExceptions
13
+ kls.middlewares[1].should == Rack::CommonLogger
22
14
  end
15
+
23
16
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nyny
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Lisnic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-19 00:00:00.000000000 Z
11
+ date: 2013-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -77,6 +77,7 @@ files:
77
77
  - .rspec
78
78
  - .ruby-version
79
79
  - .travis.yml
80
+ - CHANGELOG
80
81
  - Gemfile
81
82
  - LICENSE.txt
82
83
  - Performance.md
@@ -100,11 +101,13 @@ files:
100
101
  - examples/active_record/server.rb
101
102
  - examples/data_mapper/Gemfile
102
103
  - examples/data_mapper/database.rb
104
+ - examples/data_mapper/db/.gitignore
103
105
  - examples/data_mapper/models/shout.rb
104
106
  - examples/data_mapper/server.rb
105
107
  - examples/json_api.rb
106
108
  - examples/templates/server.rb
107
109
  - examples/templates/views/index.haml
110
+ - examples/web_sockets/Gemfile
108
111
  - examples/web_sockets/public/FABridge.js
109
112
  - examples/web_sockets/public/WebSocketMain.swf
110
113
  - examples/web_sockets/public/index.html
@@ -113,12 +116,12 @@ files:
113
116
  - examples/web_sockets/server.rb
114
117
  - lib/nyny.rb
115
118
  - lib/nyny/app.rb
119
+ - lib/nyny/core-ext/runner.rb
116
120
  - lib/nyny/middleware_chain.rb
117
121
  - lib/nyny/primitives.rb
118
122
  - lib/nyny/request_scope.rb
119
123
  - lib/nyny/route_signature.rb
120
124
  - lib/nyny/router.rb
121
- - lib/nyny/runner.rb
122
125
  - lib/nyny/version.rb
123
126
  - nyny.gemspec
124
127
  - spec/app_spec.rb