newark 0.0.4 → 0.0.5

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: 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: