nyny 1.0.0.pre1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 46c8a11a01cebb1bd9a45524d3c05a66a3af2262
4
- data.tar.gz: 67dd8bb1b90e4e11a273c0debe370fb40a00fd11
3
+ metadata.gz: 7d06702b70c5c8ae2b5b41dec0c6cdddd867e2cc
4
+ data.tar.gz: 771e4872192c8727b722181153822df8dd379985
5
5
  SHA512:
6
- metadata.gz: 5542318ca155709ff482ebe99c3f1ab1896f5fa3183bcee856edd9e38ca581ad8e4b944ae1cb87876110bba084421c461f52aa9042da3e8e6e79c9f9fe48f85d
7
- data.tar.gz: 55919c677098f054c192b508db71a92d60475590424815e74f8d33f3c6050181a74064b605707607e457f14683882250a9108f55ca1121470eb0c03c1780e653
6
+ metadata.gz: 20c1401e48e5dd9a690c084ac040bdf705db169f765ea4203ed7bcc9cc63149f2153d4a1f8a96bb6b0d12d4c3007ed39c36f4e353fcb5da7318814580347e163
7
+ data.tar.gz: 9bdd755fcd18570974ce27564a605618f8dd3ea944111d74c55268b86879a85e320c9672be7738d1d99a9edcfeb390ee398adcb0a9fcffd1afdcbb40d77c8f7c
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ *.sqlite3
6
7
  Gemfile.lock
7
8
  InstalledFiles
8
9
  _yardoc
@@ -0,0 +1,12 @@
1
+ ---
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - rbx-19mode
7
+ - jruby-19mode
8
+ - jruby-20mode
9
+
10
+ branches:
11
+ only:
12
+ - master
data/Gemfile CHANGED
@@ -3,3 +3,8 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem 'rack'
6
+
7
+ group :test do
8
+ gem 'coveralls', :require => false
9
+ gem 'rack-protection'
10
+ end
@@ -1,13 +1,15 @@
1
- # Frankie vs Sinatra performance test
1
+ # NYNY vs Sinatra performance test
2
2
 
3
3
  Note: all the tests below were made using Thin as a webserver. Httperf was
4
4
  choosen as the tool to do that. Bench settings: `--num-conns 10000`
5
5
 
6
6
  Hardware: Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz, 6 GB DDR3
7
7
 
8
+ If you have a clue how to make proper benchmarks (because, frankly, I don't), I am open to suggestions.
9
+
8
10
  ## Results
9
11
 
10
- | Benchmark | Frankie (req/s) | Sinatra (req/s) |
12
+ | Benchmark | NYNY (req/s) | Sinatra (req/s) |
11
13
  |-----------|:---------------:|:---------------:|
12
14
  | Simple |__5012__ |2534 |
13
15
  | UrlPattern|__4564__ |2338 |
@@ -19,21 +21,21 @@ See below the code for each benchmark
19
21
  ## Code
20
22
  ### Simple
21
23
 
22
- class App < Frankie::App #(or Sinatra::Base)
24
+ class App < NYNY::App #(or Sinatra::Base)
23
25
  get '/' do
24
26
  'Hello World!'
25
27
  end
26
28
  end
27
29
 
28
30
  ### UrlPattern
29
- class App < Frankie::App #(or Sinatra::Base)
31
+ class App < NYNY::App #(or Sinatra::Base)
30
32
  get '/hello/:name' do
31
33
  "Hello #{params[:name]}!"
32
34
  end
33
35
  end
34
36
 
35
37
  ### Filters
36
- class App < Frankie::App #(or Sinatra::Base)
38
+ class App < NYNY::App #(or Sinatra::Base)
37
39
  before do
38
40
  request
39
41
  end
@@ -54,7 +56,7 @@ See below the code for each benchmark
54
56
  end
55
57
  end
56
58
 
57
- class App < Frankie::App #(or Sinatra::Base)
59
+ class App < NYNY::App #(or Sinatra::Base)
58
60
  helpers Dude
59
61
 
60
62
  get '/' do
data/README.md CHANGED
@@ -1,10 +1,35 @@
1
1
  # New York, New York.
2
- Sinatra's little brother.
2
+ (very) small Sinatra clone.
3
3
 
4
- - [TOP](#frankie)
4
+ ![alt text](https://api.travis-ci.org/alisnic/nyny.png "build status")
5
+ [![Coverage Status](https://coveralls.io/repos/alisnic/nyny/badge.png)](https://coveralls.io/r/alisnic/nyny)
6
+ [![Code Climate](https://codeclimate.com/repos/521b7ee513d637348712864a/badges/60e3637788bbac94f1cb/gpa.png)](https://codeclimate.com/repos/521b7ee513d637348712864a/feed)
7
+
8
+ # myapp.rb
9
+
10
+ require 'nyny'
11
+ class App < NYNY::App
12
+ get '/' do
13
+ 'Hello world!'
14
+ end
15
+ end
16
+
17
+ App.run!
18
+
19
+ Install the gem:
20
+
21
+ gem install nyny --pre
22
+
23
+ Run the file
24
+
25
+ ruby myapp.rb
26
+
27
+ Open the browser at [http://localhost:9292]()
28
+
29
+ - [TOP](#new-york-new-york)
5
30
  - [Motivation](#motivation)
6
31
  - [Philosophy](#philosophy)
7
- - [Why use NYNY instead of Sinatra](#why-use-frankie-instead-of-sinatra)
32
+ - [Why use NYNY instead of Sinatra](#why-use-nyny-instead-of-sinatra)
8
33
  - [Usage](#usage)
9
34
  - [Running](#running)
10
35
  - [Defining routes](#defining-routes)
@@ -16,22 +41,27 @@ Sinatra's little brother.
16
41
  - [Contributing](#contributing)
17
42
 
18
43
  # Motivation
19
- My efforts to write __NYNY__ started when I wanted to understand how __Sinatra__ works, and stumbled upon the [base.rb][0]. The majority of the classes that are used by sinatra are in one single file, which makes it nearly impossible for a new person to grasp.
20
-
21
- [I've tried to change the situation][1], but unfortunately, my initiative was premature for the sinatra project (considering their plans).
44
+ My efforts to write __NYNY__ started when I wanted to understand how __Sinatra__
45
+ works, and stumbled upon the [base.rb][0]. The majority of the classes that
46
+ are used by sinatra are in one single file, which makes it nearly impossible
47
+ for a new person to grasp.
22
48
 
23
- I wanted to understand how sinatra works, but the code was pretty challenging. So I decided I should re-implement the basic things sinatra has. Thus, __NYNY__ was born.
49
+ I wanted to understand how sinatra works, but the code was pretty challenging.
50
+ So I decided I should re-implement the basic things Sinatra has.
51
+ Thus, __NYNY__ was born.
24
52
 
25
53
  # Philosophy
26
54
  NYNY should have only the bare minimum to write basic web servers comfortably,
27
- everything else should be in a extension (see frankie extensions). It is also
28
- trivial to use frankie to build large and complex app, by writing multiple sub
55
+ everything else should be in a extension. It is also
56
+ trivial to use NYNY to build large and complex apps, by writing multiple sub
29
57
  apps and using Rack to mount them, or by using those sub apps in the "main" app
30
58
  as middleware.
31
59
 
32
60
  # Why use NYNY instead of Sinatra
33
- - It's very small (~250 LOC), which is just a little overhead on top of Rack.
34
- - Sinatra is a drop-in replacement for NYNY. Anytime you feel that you need more, you can just change your app to inherit from `Sinatra::Base`, your code will still work, and you will be able to use any of the Sinatra features.
61
+ - It's very small (<300 LOC), which is just a little overhead on top of Rack.
62
+ - Sinatra is a drop-in replacement for NYNY. Anytime you feel that you need more,
63
+ you can just change your app to inherit from `Sinatra::Base`, your code will
64
+ still work, and you will be able to use any of the Sinatra features.
35
65
  - It's __~2 times faster__ than Sinatra (see [Performance][performance] for details)
36
66
  - You want to dig into the source code and change to your needs (NYNY's source code is more welcoming)
37
67
  - Each NYNY app is a Rack middleware, so it can be used inside of Sinatra, Rails, or any other Rack-based app.
@@ -49,91 +79,120 @@ A NYNY app must _always_ be in a class which inherits from `NYNY::App`.
49
79
  ## Running
50
80
  There are two ways to run a NYNY app __directly__ [[?]](#middleware):
51
81
 
52
- - be requiring it in a `config.ru` file, and then passing it as argument to the
82
+ - by requiring it in a `config.ru` file, and then passing it as argument to the
53
83
  Rack's `run` function:
54
84
 
55
85
  #config.ru
56
86
  require 'app'
57
87
  run App.new
58
-
88
+
59
89
  - by using the `run!` method directly on the app class:
60
90
 
61
91
  #app.rb
62
92
  #...App class definition...
63
-
93
+
64
94
  App.run!
65
-
66
- `run!` takes the port number as optional argument (the default port is 9292). Also the `run!` method will include 2 default middlewares to make the development easier: Rack::CommonLogger and Rack::ShowExceptions. This will show all requests in the log, and will provide useful details in the case a error occurs during a request.
95
+
96
+ `run!` takes the port number as optional argument (the default port is 9292).
97
+ Also the `run!` method will include 2 default middlewares to make the
98
+ development easier: Rack::CommonLogger and Rack::ShowExceptions.
99
+ This will show all requests in the log, and will provide useful details
100
+ in the case a error occurs during a request.
67
101
 
68
102
 
69
103
  ## Defining routes
70
104
 
71
- NYNY supports the following verbs for defining a route: delete, get, head, options, patch, post, put and trace.
105
+ NYNY supports the following verbs for defining a route: delete, get, head,
106
+ options, patch, post, put and trace.
72
107
 
73
108
  class App < NYNY::App
74
- post '/' do
75
- 'You Posted, dude!'
76
- end
109
+ post '/' do
110
+ 'You Posted, dude!'
111
+ end
77
112
  end
78
113
 
79
114
  NYNY also suports basic URL patterns:
80
115
 
81
116
  class App < NYNY::App
82
- get '/greet/:first_name/:last_name' do
83
- # The last expression in the block is _always_ considered the response body.
84
- "Hello #{params[:first_name]} #{params[:last_name]}!"
85
- end
117
+ get '/greet/:first_name/:last_name' do
118
+ # The last expression in the block is _always_ considered the response body.
119
+ "Hello #{params[:first_name]} #{params[:last_name]}!"
120
+ end
86
121
  end
87
122
 
88
- Each block that is passed to a route definition is evaluated in the context of a request scope. See below what methods are available there.
123
+ you can also tell NYNY to match a regex for a path:
124
+
125
+ class App < NYNY::App
126
+ get /html/ do
127
+ 'Your URL contains html!'
128
+ end
129
+ end
130
+
131
+ Each block that is passed to a route definition is evaluated in the context of
132
+ a request scope. See below what methods are available there.
89
133
 
90
134
  ## Request scope
91
- As was said above, when you pass a block to a route definition, that block is evaluated in the context of a [RequestScope][2]. This means that several methods/objects available inside that block:
135
+ As was said above, when you pass a block to a route definition,
136
+ that block is evaluated in the context of a [RequestScope][2].
137
+ This means that several methods/objects available inside that block:
92
138
 
93
- - `request` - A `Rack::Request` object which encapsulates the request to that route. (see [Rack::Request documentation][3] for more info)
139
+ - `request` - A `Rack::Request` object which encapsulates the request
140
+ to that route. (see [Rack::Request documentation][3] for more info)
94
141
  - `params` - a hash which contains both POST body params and GET querystring params.
95
- - `headers` - allows you to read/add headers to the response (ex: `headers 'Content-Type' => 'text/html'`)
142
+ - `headers` - allows you to read/add headers to the response
143
+ (ex: `headers 'Content-Type' => 'text/html'`)
96
144
  - `status` - allows you to set the status of the response (ex: `status 403`)
97
- - `redirect_to` - sets the response to redirect (ex: `redirect_to 'http://google.com'`)
98
- - `cookies` - a hash which allows you to access/modify/remove cookies (ex: `cookies[:foo] = 'bar'`)
99
- - `session` - a hash which allows you to access/modify/remove session variables (ex: `session[:foo] = 'bar'`)
145
+ - `redirect_to` - sets the response to redirect
146
+ (ex: `redirect_to 'http://google.com'`)
147
+ - `cookies` - a hash which allows you to access/modify/remove cookies
148
+ (ex: `cookies[:foo] = 'bar'`)
149
+ - `session` - a hash which allows you to access/modify/remove session variables
150
+ (ex: `session[:foo] = 'bar'`)
100
151
 
101
152
  ## Filters
102
153
 
103
- Unlike Sinatra, NYNY supports only "generic" before and after filters. This means that you can't execute a filter depending on a URL pattern.
154
+ Unlike Sinatra, NYNY supports only "generic" before and after filters.
155
+ This means that you can't declare a filter to execute depending on a URL pattern.
156
+ However, you can obtain the same effect by calling next in a before block
157
+ if the request.path matches a pattern.
104
158
 
105
159
  class App < NYNY::App
106
- before do
107
- headers 'Content-Type' => 'text/html'
108
- end
109
-
110
- after do
111
- puts response.inspect
112
- end
113
-
114
- get '/' do
115
- 'hello'
116
- end
160
+ before do
161
+ next unless /html/ =~ request.path
162
+ headers 'Content-Type' => 'text/html'
163
+ end
164
+
165
+ after do
166
+ puts response.inspect
167
+ end
168
+
169
+ get '/' do
170
+ 'hello'
171
+ end
117
172
  end
118
173
 
119
- Before and after filters are also evaluated in a RequestScope context. A little exception are the after filters, which can access the __response__ object ([Rack::Response][4]).
174
+ Before and after filters are also evaluated in a RequestScope context.
175
+ A little exception are the after filters, which can access
176
+ the __response__ object ([Rack::Response][4]).
120
177
 
121
178
  ## Middleware
122
179
 
123
- A Fankie app is a Rack middleware, which means that it can be used inside of Sinatra, Rails, or any other Rack-based app:
180
+ A NYNY app is a Rack middleware, which means that it can be used inside
181
+ Sinatra, Rails, or any other Rack-based app:
124
182
 
125
183
  class MyApp < Sinatra::Base
126
- use MyNYNYApp
184
+ use MyNYNYApp
127
185
  end
128
186
 
129
- NYNY also supports middleware itself, and that means you can use Rack middleware (or a Sinatra app) inside a NYNY app:
187
+ NYNY also supports middleware itself, and that means you can use Rack middleware
188
+ (or a Sinatra app) inside a NYNY app:
130
189
 
131
190
  class App < NYNY::App
132
- #this will serve all the files in the "public" folder
133
- use Rack::Static :url => ['public']
134
- use SinatraApp
191
+ #this will serve all the files in the "public" folder
192
+ use Rack::Static :url => ['public']
193
+ use SinatraApp
135
194
  end
136
-
195
+
137
196
  I recommend looking at [the list of Rack middlewares][rack-middleware]
138
197
 
139
198
  ## Helpers
@@ -141,10 +200,12 @@ I recommend looking at [the list of Rack middlewares][rack-middleware]
141
200
  NYNY supports helpers as Sinatra does:
142
201
 
143
202
  class App < NYNY::App
144
- helpers MyHelperModule
203
+ helpers MyHelperModule
145
204
  end
146
205
 
147
- Using a helper implies that the helper module is included in the [RequestScope][2], and that all the methods in that module will be available inside a route definition block.
206
+ Using a helper implies that the helper module is included in the [RequestScope][2],
207
+ and that all the methods in that module will be available inside a route
208
+ definition block.
148
209
 
149
210
  # F. A. Q.
150
211
  TBD.
@@ -160,8 +221,8 @@ TBD.
160
221
 
161
222
  [0]: https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb
162
223
  [1]: https://github.com/sinatra/sinatra/pull/716
163
- [2]: https://github.com/alisnic/frankie/blob/master/lib/frankie/request_scope.rb
224
+ [2]: https://github.com/alisnic/nyny/blob/master/lib/nyny/request_scope.rb
164
225
  [3]: http://rack.rubyforge.org/doc/classes/Rack/Request.html
165
226
  [4]: http://rack.rubyforge.org/doc/classes/Rack/Response.html
166
- [performance]: https://github.com/alisnic/frankie/blob/master/Performance.md
227
+ [performance]: https://github.com/alisnic/nyny/blob/master/Performance.md
167
228
  [rack-middleware]: https://github.com/rack/rack/wiki/List-of-Middleware
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc "run all specs"
5
+ RSpec::Core::RakeTask.new(:default)
6
+
@@ -1,7 +1,7 @@
1
1
  #!ruby -I ../../lib -I lib
2
- require 'frankie'
2
+ require 'nyny'
3
3
 
4
- class App < Frankie::App
4
+ class App < NYNY::App
5
5
  before do
6
6
  request
7
7
  end
@@ -1,5 +1,5 @@
1
1
  #!ruby -I ../../lib -I lib
2
- require 'frankie'
2
+ require 'nyny'
3
3
 
4
4
  module Dude
5
5
  def da_request_man
@@ -7,7 +7,7 @@ module Dude
7
7
  end
8
8
  end
9
9
 
10
- class App < Frankie::App
10
+ class App < NYNY::App
11
11
  helpers Dude
12
12
 
13
13
  get '/' do
@@ -1,7 +1,7 @@
1
1
  #!ruby -I ../../lib -I lib
2
- require 'frankie'
2
+ require 'nyny'
3
3
 
4
- class App < Frankie::App
4
+ class App < NYNY::App
5
5
  get '/' do
6
6
  'Hello World!'
7
7
  end
@@ -1,7 +1,7 @@
1
1
  #!ruby -I ../../lib -I lib
2
- require 'frankie'
2
+ require 'nyny'
3
3
 
4
- class App < Frankie::App
4
+ class App < NYNY::App
5
5
  get '/hello/:name' do
6
6
  "Hello #{params[:name]}!"
7
7
  end
@@ -6,14 +6,14 @@ require 'rubygems'
6
6
  require 'bundler'
7
7
  Bundler.setup(:default, ENV['RACK_ENV'].to_sym)
8
8
 
9
- require 'frankie'
9
+ require 'nyny'
10
10
  require_relative 'database'
11
11
 
12
12
  #Require all models
13
13
  Dir[File.dirname(__FILE__) + "/models/*.rb"].each {|file| require file }
14
14
  TEMPLATE = DATA.read.freeze
15
15
 
16
- class App < Frankie::App
16
+ class App < NYNY::App
17
17
  get '/' do
18
18
  shouts = Shout.all.reverse
19
19
  ERB.new(TEMPLATE).result(binding)
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+ gem 'sqlite3'
3
+ gem 'rack'
4
+ gem 'thin'
5
+
6
+ gem 'data_mapper', '~> 1.2.0'
7
+ gem 'dm-sqlite-adapter', '~> 1.2.0'
@@ -0,0 +1,7 @@
1
+ require 'data_mapper'
2
+
3
+ DataMapper.setup(:default, "sqlite:///#{Dir.pwd}/db/database.sqlite3")
4
+ Dir[File.dirname(__FILE__) + "/models/*.rb"].each {|f| require f }
5
+
6
+ DataMapper.finalize
7
+ DataMapper.auto_upgrade!
@@ -0,0 +1,7 @@
1
+ class Shout
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :body, String
6
+ end
7
+