newark 0.0.4 → 0.0.5

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: bb71854d252f0cb1624e26254eedacf067804078
4
- data.tar.gz: c97931ceba7ff07431537aa4b21f3aef4797f69d
3
+ metadata.gz: 1176c48b93363fe2bd3c113994b9a88fc1347212
4
+ data.tar.gz: cd767ff74a3c5e299de01841524bcfc0da42c5de
5
5
  SHA512:
6
- metadata.gz: b75f48d5ccaa1478d5f5d6c31fa3e411dc44ed77beab91bde4ba6cee393a6575012a41bee6b4a35a908b815a2c51f6b122ec0a7f2e09c5174b59ecde325581b3
7
- data.tar.gz: b9ca2a867c6b2e49db0e169c6cadb8f0d2fa9f577c0c2d42a5218db58cf98bdf88f5de17d3d96e633a5534b6d0f9356eb15324f9505b5b8af57365cd5fe0fc51
6
+ metadata.gz: 2cd14fe50f9ac849a30ad2036af27872bd2b07d722f19d69a87ef1fe29e8de8710ec66b014f9f1e26ed8c46879a8cb95b7d155ecf547f2db842883212bc9ad57
7
+ data.tar.gz: 13c9c7dd6dd9ec8977d2e2a4eb8ddefc7c22b2fc6896d3e3a07e075f4f38292193f90332175231fb1aee9f46c6860421099b0250163a16126ed51386ad6ebd43
data/Rakefile CHANGED
@@ -9,3 +9,9 @@ Rake::TestTask.new(:test) do |test|
9
9
  end
10
10
 
11
11
  task :default => :test
12
+
13
+ task :benchmark do
14
+ Dir.glob('benchmark/**/benchmark_*.rb').each do |benchmark|
15
+ require_relative benchmark
16
+ end
17
+ end
@@ -0,0 +1,71 @@
1
+ lib = File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'benchmark/ips'
5
+ require 'rack/test'
6
+ require 'newark'
7
+
8
+ class App
9
+
10
+ include Newark
11
+
12
+ get '/', params: { user: 'frank' } do
13
+ 'hello frank'
14
+ end
15
+
16
+ get '/' do
17
+ 'hello'
18
+ end
19
+
20
+ get(/\/regexp/) do
21
+ 'regexp'
22
+ end
23
+
24
+ get '/create' do
25
+ 'whoops'
26
+ end
27
+
28
+ post '/create' do
29
+ 'created'
30
+ end
31
+
32
+ get '/request_and_response' do
33
+ request && response
34
+ headers && params
35
+ 'ok'
36
+ end
37
+
38
+ get '/variables/:a/:b' do
39
+ "#{params[:a]}:#{params[:b]}"
40
+ end
41
+ end
42
+
43
+ include Rack::Test::Methods
44
+
45
+ def app
46
+ App.new
47
+ end
48
+
49
+ Benchmark.ips do |x|
50
+
51
+ x.report('match /') {
52
+ get '/'
53
+ }
54
+
55
+ x.report('match / with param') {
56
+ get '/', user: 'frank'
57
+ }
58
+
59
+ x.report('404') {
60
+ get '/not_found'
61
+ }
62
+
63
+ x.report('post') {
64
+ post '/create'
65
+ }
66
+
67
+ x.report('path params') {
68
+ get '/variables/fu/bar'
69
+ }
70
+
71
+ end
@@ -2,6 +2,11 @@
2
2
  module Newark
3
3
  module App
4
4
 
5
+ FOUR_O_FOUR = [ 404, {}, [] ].freeze
6
+
7
+ HTTP_VERBS = [ :delete, :get, :head, :options,
8
+ :patch, :post, :put, :trace ].freeze
9
+
5
10
  def self.included(klass)
6
11
  klass.instance_variable_set :@routes, []
7
12
  klass.instance_variable_set :@before_hooks, []
@@ -9,9 +14,6 @@ module Newark
9
14
  klass.extend ClassMethods
10
15
  end
11
16
 
12
- HTTP_VERBS = [ :delete, :get, :head, :options,
13
- :patch, :post, :put, :trace ].freeze
14
-
15
17
  module ClassMethods
16
18
 
17
19
  HTTP_VERBS.each do |verb|
@@ -34,20 +36,62 @@ module Newark
34
36
  end
35
37
  end
36
38
 
39
+ attr_reader :request, :response
40
+
37
41
  def call(env)
38
- Router.new(self, env).route!
42
+ dup._call(env)
43
+ end
44
+
45
+ def _call(env)
46
+ @env = env
47
+ @request = Request.new(@env)
48
+ @response = Response.new
49
+ route
50
+ end
51
+
52
+ def headers
53
+ response.headers
54
+ end
55
+
56
+ def params
57
+ request.params
58
+ end
59
+
60
+ def route
61
+ exec_before_hooks
62
+ route = match_route
63
+ if route
64
+ request.params.merge!(route.params)
65
+ response.body = instance_exec(&route.handler)
66
+ exec_after_hooks
67
+ response.finish
68
+ else
69
+ FOUR_O_FOUR
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def match_route
76
+ Router.new(routes, request).route
39
77
  end
40
78
 
41
79
  def routes
42
- self.class.instance_variable_get :@routes
80
+ self.class.instance_variable_get(:@routes)
43
81
  end
44
82
 
45
- def before_hooks
46
- self.class.instance_variable_get :@before_hooks
83
+ def exec_before_hooks
84
+ exec_hooks self.class.instance_variable_get(:@before_hooks)
47
85
  end
48
86
 
49
- def after_hooks
50
- self.class.instance_variable_get :@after_hooks
87
+ def exec_after_hooks
88
+ exec_hooks self.class.instance_variable_get(:@after_hooks)
89
+ end
90
+
91
+ def exec_hooks(hooks)
92
+ hooks.each do |hook|
93
+ instance_exec(&hook)
94
+ end
51
95
  end
52
96
  end
53
97
  end
@@ -4,7 +4,9 @@ module Newark
4
4
  class Request < Rack::Request
5
5
 
6
6
  def uri
7
- URI(base_url + fullpath)
7
+ uri = "#{scheme}://#{host_with_port}#{path_info}"
8
+ uri << "?#{query_string}" unless query_string.empty?
9
+ URI(uri)
8
10
  end
9
11
 
10
12
  def params
@@ -1,9 +1,16 @@
1
1
  module Newark
2
2
  class Response < Rack::Response
3
3
 
4
+ JSON_MIME_TYPE = 'application/json'.freeze
5
+
4
6
  def body=(value)
5
7
  value = if value.respond_to?(:to_str)
6
8
  [ value.to_str ]
9
+ elsif value.respond_to?(:to_hash) && defined?(MultiJson)
10
+ header['Content-Type'] = JSON_MIME_TYPE
11
+ [ MultiJson.dump(value) ]
12
+ elsif value.respond_to?(:to_ary)
13
+ value
7
14
  else
8
15
  [ value ]
9
16
  end
@@ -2,6 +2,9 @@ module Newark
2
2
  class Route
3
3
 
4
4
  PARAM_MATCHER = /:(?<param>[^\/]*)/.freeze
5
+ PARAM_SUB = /:[^\/]*/.freeze
6
+ PATH_MATCHER = /\*(?<path>.*)/.freeze
7
+ PATH_SUB = /\*.*/.freeze
5
8
 
6
9
  attr_reader :handler, :params
7
10
 
@@ -9,7 +12,6 @@ module Newark
9
12
  @constraints = Constraint.load(constraints)
10
13
  @handler = handler
11
14
  @path = path_matcher(path)
12
- @params = nil
13
15
  end
14
16
 
15
17
  def match?(request)
@@ -26,7 +28,7 @@ module Newark
26
28
  end
27
29
 
28
30
  def path_match?(request)
29
- @path.match(request.path)
31
+ @path.match(request.path_info)
30
32
  end
31
33
 
32
34
  def path_matcher(path)
@@ -35,12 +37,21 @@ module Newark
35
37
  end
36
38
 
37
39
  def path_params(path)
38
- return path unless path =~ /:/
40
+ match_path(path)
41
+ match_params(path)
42
+ path
43
+ end
44
+
45
+ def match_path(path)
46
+ if match = PATH_MATCHER.match(path)
47
+ path.sub!(PATH_SUB, "(?<#{match[:path]}>.*)")
48
+ end
49
+ end
39
50
 
51
+ def match_params(path)
40
52
  while match = PARAM_MATCHER.match(path)
41
- path.sub!(/:[^\/]*/, "(?<#{match[:param]}>[^\/]*)")
53
+ path.sub!(PARAM_SUB, "(?<#{match[:param]}>[^\/]*)")
42
54
  end
43
- path
44
55
  end
45
56
 
46
57
  class Constraint
@@ -1,57 +1,12 @@
1
1
  module Newark
2
2
  class Router
3
3
 
4
- FOUR_O_FOUR = [ 404, {}, [] ].freeze
5
-
6
- attr_reader :app, :env, :request, :response
7
-
8
- def initialize(app, env)
9
- @app = app
10
- @env = env
11
- @request = Request.new(env)
12
- @response = Response.new
13
- end
14
-
15
- def route!
16
- exec_before_hooks
17
- route = matched_route(@app.routes)
18
- if route
19
- request.params.merge!(route.params)
20
- response.body = instance_exec(&route.handler)
21
- exec_after_hooks
22
- response.finish
23
- else
24
- FOUR_O_FOUR
25
- end
26
- end
27
-
28
- def matched_route(routes)
29
- routes.find { |route| route.match?(request) }
30
- end
31
-
32
- def headers
33
- response.headers
4
+ def initialize(routes, request)
5
+ @routes, @request = routes, request
34
6
  end
35
7
 
36
- def params
37
- request.params
8
+ def route
9
+ @routes.find { |route| route.match?(@request) }
38
10
  end
39
-
40
- private
41
-
42
- def exec_before_hooks
43
- exec_hooks @app.before_hooks
44
- end
45
-
46
- def exec_after_hooks
47
- exec_hooks @app.after_hooks
48
- end
49
-
50
- def exec_hooks(hooks)
51
- hooks.each do |hook|
52
- instance_exec(&hook)
53
- end
54
- end
55
-
56
11
  end
57
12
  end
@@ -1,3 +1,3 @@
1
1
  module Newark
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
@@ -25,4 +25,6 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency 'rake'
26
26
  spec.add_development_dependency 'rack-test'
27
27
  spec.add_development_dependency 'pry'
28
+ spec.add_development_dependency 'benchmark-ips'
29
+ spec.add_development_dependency 'multi_json'
28
30
  end
@@ -3,52 +3,9 @@ Coveralls.wear!
3
3
 
4
4
  require 'pry'
5
5
  require 'newark'
6
+ require 'rack/test'
6
7
  require 'minitest/autorun'
7
8
 
8
- class App
9
-
10
- include Newark
11
-
12
- before do
13
- headers['X-Newark-Version'] = Newark::VERSION
14
- end
15
-
16
- after do
17
- headers['X-Newark-Done'] = 'true'
18
- end
19
-
20
- get '/', params: { user: 'frank' } do
21
- 'hello frank'
22
- end
23
-
24
- get '/' do
25
- 'hello'
26
- end
27
-
28
- get(/\/regexp/) do
29
- 'regexp'
30
- end
31
-
32
- get '/create' do
33
- 'whoops'
34
- end
35
-
36
- post '/create' do
37
- 'created'
38
- end
39
-
40
- get '/request_and_response' do
41
- request && response
42
- headers && params
43
- 'ok'
44
- end
45
-
46
- get '/variables/:a/:b' do
47
- "#{params[:a]}:#{params[:b]}"
48
- end
49
-
50
- end
51
-
52
9
  class Minitest::Unit::TestCase
53
10
 
54
11
  end
@@ -0,0 +1,29 @@
1
+ require 'helper'
2
+
3
+ class NameApp
4
+ include Newark
5
+
6
+ def upcase(str)
7
+ str.upcase
8
+ end
9
+
10
+ get '/upcaser' do
11
+ upcase(params[:name])
12
+ end
13
+ end
14
+
15
+ class TestApp < Minitest::Unit::TestCase
16
+
17
+ include Rack::Test::Methods
18
+
19
+ def app
20
+ NameApp.new
21
+ end
22
+
23
+ def test_instance_method_access
24
+ get '/upcaser', { name: 'mike' }
25
+ assert last_response.ok?
26
+ assert_equal 'MIKE', last_response.body
27
+ end
28
+
29
+ end
@@ -1,5 +1,4 @@
1
1
  require 'helper'
2
- require 'rack/test'
3
2
 
4
3
  class RequestApp
5
4
  include Newark
@@ -0,0 +1,25 @@
1
+ require 'helper'
2
+
3
+ class ResponseApp
4
+ include Newark
5
+
6
+ get '/api' do
7
+ { ok: true }
8
+ end
9
+ end
10
+
11
+ class TestResponse < Minitest::Unit::TestCase
12
+
13
+ include Rack::Test::Methods
14
+
15
+ def app
16
+ ResponseApp.new
17
+ end
18
+
19
+ def test_json_api
20
+ get '/api'
21
+ assert_equal "{\"ok\":true}", last_response.body
22
+ assert_equal 'application/json', last_response.headers['Content-Type']
23
+ end
24
+
25
+ end
@@ -1,12 +1,59 @@
1
1
  require 'helper'
2
- require 'rack/test'
2
+
3
+ class TestingApp
4
+
5
+ include Newark
6
+
7
+ before do
8
+ headers['X-Newark-Version'] = Newark::VERSION
9
+ end
10
+
11
+ after do
12
+ headers['X-Newark-Done'] = 'true'
13
+ end
14
+
15
+ get '/', params: { user: 'frank' } do
16
+ 'hello frank'
17
+ end
18
+
19
+ get '/' do
20
+ 'hello'
21
+ end
22
+
23
+ get(/\/regexp/) do
24
+ 'regexp'
25
+ end
26
+
27
+ get '/create' do
28
+ 'whoops'
29
+ end
30
+
31
+ post '/create' do
32
+ 'created'
33
+ end
34
+
35
+ get '/request_and_response' do
36
+ request && response
37
+ headers && params
38
+ 'ok'
39
+ end
40
+
41
+ get '/variables/:a/:b' do
42
+ "#{params[:a]}:#{params[:b]}"
43
+ end
44
+
45
+ get '/path_globbing/*rest_of_path' do
46
+ params[:rest_of_path]
47
+ end
48
+
49
+ end
3
50
 
4
51
  class TestRouter < Minitest::Unit::TestCase
5
52
 
6
53
  include Rack::Test::Methods
7
54
 
8
55
  def app
9
- App.new
56
+ TestingApp.new
10
57
  end
11
58
 
12
59
  def test_gets_root
@@ -60,4 +107,10 @@ class TestRouter < Minitest::Unit::TestCase
60
107
  assert last_response.ok?
61
108
  assert_equal 'fu:bar', last_response.body
62
109
  end
110
+
111
+ def test_path_globbing
112
+ get '/path_globbing/rest/of/path'
113
+ assert last_response.ok?
114
+ assert_equal 'rest/of/path', last_response.body
115
+ end
63
116
  end
metadata CHANGED
@@ -1,99 +1,127 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newark
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Evans
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-18 00:00:00.000000000 Z
11
+ date: 2014-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
15
- requirement: !ruby/object:Gem::Requirement
15
+ version_requirements: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.5.2
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
20
+ requirement: !ruby/object:Gem::Requirement
23
21
  requirements:
24
- - - ">="
22
+ - - '>='
25
23
  - !ruby/object:Gem::Version
26
24
  version: 1.5.2
25
+ prerelease: false
26
+ type: :runtime
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
- requirement: !ruby/object:Gem::Requirement
29
+ version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
34
+ requirement: !ruby/object:Gem::Requirement
37
35
  requirements:
38
- - - ">="
36
+ - - '>='
39
37
  - !ruby/object:Gem::Version
40
38
  version: '0'
39
+ prerelease: false
40
+ type: :runtime
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
- requirement: !ruby/object:Gem::Requirement
43
+ version_requirements: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.5'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
51
49
  requirements:
52
- - - "~>"
50
+ - - ~>
53
51
  - !ruby/object:Gem::Version
54
52
  version: '1.5'
53
+ prerelease: false
54
+ type: :development
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
57
62
  requirement: !ruby/object:Gem::Requirement
58
63
  requirements:
59
- - - ">="
64
+ - - '>='
60
65
  - !ruby/object:Gem::Version
61
66
  version: '0'
62
- type: :development
63
67
  prerelease: false
68
+ type: :development
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-test
64
71
  version_requirements: !ruby/object:Gem::Requirement
65
72
  requirements:
66
- - - ">="
73
+ - - '>='
67
74
  - !ruby/object:Gem::Version
68
75
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rack-test
71
76
  requirement: !ruby/object:Gem::Requirement
72
77
  requirements:
73
- - - ">="
78
+ - - '>='
74
79
  - !ruby/object:Gem::Version
75
80
  version: '0'
76
- type: :development
77
81
  prerelease: false
82
+ type: :development
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
78
85
  version_requirements: !ruby/object:Gem::Requirement
79
86
  requirements:
80
- - - ">="
87
+ - - '>='
81
88
  - !ruby/object:Gem::Version
82
89
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: pry
85
90
  requirement: !ruby/object:Gem::Requirement
86
91
  requirements:
87
- - - ">="
92
+ - - '>='
88
93
  - !ruby/object:Gem::Version
89
94
  version: '0'
95
+ prerelease: false
90
96
  type: :development
97
+ - !ruby/object:Gem::Dependency
98
+ name: benchmark-ips
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
91
109
  prerelease: false
110
+ type: :development
111
+ - !ruby/object:Gem::Dependency
112
+ name: multi_json
92
113
  version_requirements: !ruby/object:Gem::Requirement
93
114
  requirements:
94
- - - ">="
115
+ - - '>='
95
116
  - !ruby/object:Gem::Version
96
117
  version: '0'
118
+ requirement: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ prerelease: false
124
+ type: :development
97
125
  description: Because everyone should write their own framework.
98
126
  email:
99
127
  - mike@urlgonomics.com
@@ -101,12 +129,13 @@ executables: []
101
129
  extensions: []
102
130
  extra_rdoc_files: []
103
131
  files:
104
- - ".gitignore"
105
- - ".travis.yml"
132
+ - .gitignore
133
+ - .travis.yml
106
134
  - Gemfile
107
135
  - LICENSE.txt
108
136
  - README.md
109
137
  - Rakefile
138
+ - benchmark/benchmark_router.rb
110
139
  - lib/newark.rb
111
140
  - lib/newark/app.rb
112
141
  - lib/newark/request.rb
@@ -116,34 +145,37 @@ files:
116
145
  - lib/newark/version.rb
117
146
  - newark.gemspec
118
147
  - test/helper.rb
148
+ - test/test_app.rb
119
149
  - test/test_request.rb
150
+ - test/test_response.rb
120
151
  - test/test_router.rb
121
152
  homepage: ''
122
153
  licenses:
123
154
  - MIT
124
155
  metadata: {}
125
- post_install_message:
156
+ post_install_message:
126
157
  rdoc_options: []
127
158
  require_paths:
128
159
  - lib
129
160
  required_ruby_version: !ruby/object:Gem::Requirement
130
161
  requirements:
131
- - - ">="
162
+ - - '>='
132
163
  - !ruby/object:Gem::Version
133
164
  version: '0'
134
165
  required_rubygems_version: !ruby/object:Gem::Requirement
135
166
  requirements:
136
- - - ">="
167
+ - - '>='
137
168
  - !ruby/object:Gem::Version
138
169
  version: '0'
139
170
  requirements: []
140
- rubyforge_project:
141
- rubygems_version: 2.2.1
142
- signing_key:
171
+ rubyforge_project:
172
+ rubygems_version: 2.2.2
173
+ signing_key:
143
174
  specification_version: 4
144
175
  summary: Pico Web Framework
145
176
  test_files:
146
177
  - test/helper.rb
178
+ - test/test_app.rb
147
179
  - test/test_request.rb
180
+ - test/test_response.rb
148
181
  - test/test_router.rb
149
- has_rdoc: