rack-app 7.3.2 → 7.7.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
- SHA1:
3
- metadata.gz: 29ab9521da605cc10dd970e9f8736ee48804c212
4
- data.tar.gz: bd0a104987412fd77c16f7517ffc38a1ebc19504
2
+ SHA256:
3
+ metadata.gz: bf6acb7c4c89bd038387d214bd7379ade393a3f0b48088f4b7542b6a0c6f05ca
4
+ data.tar.gz: e084eaa3c611498a98bbdb7cb1a8ccbcdc81cc893e1c08848a515db4b9e536f1
5
5
  SHA512:
6
- metadata.gz: 0cbbcc149f4d751691b86db4183687e1a787768dab8fafbd172d83988dc91f27d0c6b631a83afbfb995b573d7e5d05d8db4314ee45d1afd7a131b928451b626a
7
- data.tar.gz: 4213b29c6b75f3e3f812252ffa0a6a5522d2a1383a0c7b98b68e9385087ef71ca18cd5211b254bcde881131395403167fd8f92217ddb405d1abd5eec43755bab
6
+ metadata.gz: '09f143bdb3a084226e0f51f9f8c471dff28b06ab99f4f52c0895abd3541673152ef3949f34711a5eb67fc53ce1544c0bfd0acf6d000b30cf803c5b28f96ce1c1'
7
+ data.tar.gz: 6667a98608f80d53984ec9147373e370edecec9b5b525b74c3ff0c354f0843ea685deb2b96b57cae354039f56b1d1ab8104ae20bb1cf884bfba98c36b741c537
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: bug
6
+ assignees: adamluzsi
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **ruby interpreter**
24
+ ruby interpreter implementation like Mruby, Jruby, ...
25
+
26
+ **ruby version**
27
+
28
+ **rack-app version**
29
+
30
+ **Additional context**
31
+ Add any other context about the problem here.
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.4.0
1
+ 2.6.3
data/.travis.yml CHANGED
@@ -6,16 +6,14 @@ install:
6
6
  - bundle install
7
7
 
8
8
  rvm:
9
- - 1.9
10
- - 2.0.0
11
- - 2.1.1
12
- - 2.1.2
13
- - 2.2.2
14
- - 2.3.1
15
- - jruby-19mode
16
-
17
9
  - ruby-head
18
10
  - jruby-head
11
+ - jruby-19mode
12
+ - 1.9
13
+ - 2.3.8
14
+ - 2.4.6
15
+ - 2.5.5
16
+ - 2.6.3
19
17
 
20
18
  matrix:
21
19
  allow_failures:
data/README.md CHANGED
@@ -4,7 +4,9 @@
4
4
  [travis-link]: https://travis-ci.org/rack-app/rack-app
5
5
  [travis-home]: http://travis-ci.org/
6
6
 
7
- Your next favourite rack based micro framework that is totally addition free!
7
+ ![rack-app-logo](/assets/rack-app-logo.png)
8
+
9
+ Your next favorite rack-based micro-framework that is totally addition free!
8
10
  Have a cup of awesomeness with your sadistically minimalist framework!
9
11
 
10
12
  The idea behind is simple.
@@ -14,24 +16,41 @@ that will do nothing more than what you defined.
14
16
 
15
17
  The Routing can handle any amount of endpoints that can fit in the memory,
16
18
  so if you that crazy to use more than 10k endpoint,
17
- you still dont have to worry about response speed.
19
+ you still don't have to worry about response speed.
18
20
 
19
21
  It was inspirited by sinatra, grape, and the pure use form of rack.
20
22
  It's in production, powering Back Ends on Heroku
21
23
 
24
+ ## Development Status
25
+
26
+ The framework considered stable.
27
+ I don't have the plan to feature creep the framework without real-life use-cases,
28
+ since most of the custom edge cases can be resolved with composition.
29
+
30
+ The next time it will receive further updates,
31
+ when rack provides a finalized support for http2.
32
+
33
+ If you have an issue, I weekly check the issues tab,
34
+ answer and reply, or implement a fix for it.
35
+
36
+ Since the framework's only dependency is the `rack` gem,
37
+ I don't have to update the code base to often.
38
+
39
+ Cheers and Happy Coding!
40
+
22
41
  ## Concerns
23
42
 
24
- If you want see fancy magic, you are in a bad place buddy!
43
+ If you want to see fancy magic, you are in a bad place buddy!
25
44
 
26
45
  This also implies that the framework does not include extensions that monkey patch the whole world to give you nice features.
27
- The Clean architechture define that a webframework should only provide an external interface to the web, and nothing more.
46
+ Clean architecture defines that a web framework should only provide an external interface to the web, and nothing more.
28
47
 
29
48
  If you use rack-app, one thing is sure.
30
49
 
31
50
  You either love it or will be able to remove it from the project even after years of development because,
32
51
  it will not vendor-lock your application business entities and business use cases to this framework.
33
52
 
34
- And it's totaly fine to us. We don't want everyone to be tied to our solutions, we only want build clean and well designed softwared for the developer happiness.
53
+ And it's totally fine for us. We don't want everyone to be tied to our solutions, we only want to build clean and well-designed software for the developer happiness.
35
54
 
36
55
  ## Installation
37
56
 
@@ -52,7 +71,7 @@ Or install it yourself as:
52
71
 
53
72
  ## Is it Production ready?
54
73
 
55
- Yes, in fact it's already powering heroku hosted micro-services.
74
+ Yes, it's already powering Heroku hosted micro-services.
56
75
 
57
76
  ## Principles
58
77
 
@@ -60,18 +79,18 @@ Yes, in fact it's already powering heroku hosted micro-services.
60
79
  * No Code bloat
61
80
  * No on run time processing, or keep at the bare minimum
62
81
  * Fully BDD (Behaviour Driven Design)
63
- * build in test module to ease the development with easy to use tests
82
+ * built-in test module to ease the development with easy to use tests
64
83
  * Easy to Learn
65
84
  * rack-app use well known and easy to understand conventions, such as sinatra like DSL
66
85
  * Principle Of Least Surprise
67
86
  * Modular design
68
- * Only dependency is rack, nothing more
87
+ * the Only dependency is rack, nothing more
69
88
  * Open development
70
- * Try to create Examples for every feature so even the "sketch to learn new" types can feel in comfort
89
+ * Try to create Examples for every feature
71
90
 
72
91
  ## Features
73
92
 
74
- * easy to understand syntax
93
+ * Easy to understand syntax
75
94
  * module method level endpoint definition inspirited heavily by the Sinatra DSL
76
95
  * unified error handling
77
96
  * syntax sugar for default header definitions
@@ -80,20 +99,26 @@ Yes, in fact it's already powering heroku hosted micro-services.
80
99
  * App mounting so you can create separated controllers for different task
81
100
  * Streaming
82
101
  * O(log(n)) lookup routing
83
- * allows as many endpoint registration to you as you want, without impact on route lookup speed
84
- * only basic sets for instance method lvl for the must need tools, such as params, payload
85
- * simple to use class level response serializer
102
+ * allows as many endpoint registrations to you as you want, without impact on route lookup speed
103
+ * only basic sets for instance method level for the must need tools, such as params, payload
104
+ * Simple to use class level response serializer
86
105
  * so you can choose what type of serialization you want without any enforced convention
87
- * static file serving so you can mount even filesystem based endpoints too
88
- * built in testing module so your app can be easily written with BDD approach
106
+ * static file serving so you can mount even filesystem-based endpoints too
107
+ * built-in testing module so your app can be easily written with BDD approach
89
108
  * made with minimalism in mind so your app can't rely on the framework when you implement business logic
90
- * if you need something, you should implement it without any dependency on a webframework, rack-app only mean to be to provide you with easy to use interface to the web layer, nothing less and nothing more
109
+ * if you need something, you should implement it without any dependency on a web framework, rack-app only mean to be to provide you with easy to use interface to the web layer, nothing less and nothing more
91
110
  * per endpoint middleware definitions
92
- * you can define middleware stack before endpoints and it will only applied to them, similar like protected method workflow
93
- * File Upload and file download in a efficient and elegant way with minimal memory consuming
94
- * note that this is not only memory friendly way pure rack solution, but also 2x faster than the usually solution which includes buffering in memory
111
+ * you can define middleware stack before endpoints and it will only apply to them, similar like protected method workflow
112
+ * File Upload and file download efficiently and elegantly with minimal memory consuming
113
+ * note that this is not only memory friendly way pure rack solution, but also 2x faster than the usual solution which includes buffering in memory
95
114
  * params validation with ease
96
115
 
116
+ ## Under the hood
117
+
118
+ rack-app's router relies on a tree structure which makes heavy use of *common prefixes*,
119
+ it is basically a *compact* [*prefix tree*](https://en.wikipedia.org/wiki/Trie) (or just [*Radix tree*](https://en.wikipedia.org/wiki/Radix_tree)).
120
+ Nodes with a common prefix also share a common parent.
121
+
97
122
  ## Contributors
98
123
 
99
124
  * **[Daniel Nagy](https://github.com/thilonel)**
@@ -112,12 +137,14 @@ Yes, in fact it's already powering heroku hosted micro-services.
112
137
 
113
138
  * [wrote an awesome article](https://www.sitepoint.com/rack-app-a-performant-and-pragmatic-web-microframework/) about the project
114
139
 
140
+ * **[TheSmartnik](https://github.com/TheSmartnik)**
141
+
142
+ * Clarify examples in the documentation
143
+
115
144
  ## [Contributing](CONTRIBUTING.md)
116
145
 
117
146
  ## Usage
118
147
 
119
- config.ru
120
-
121
148
  #### basic
122
149
 
123
150
  ```ruby
@@ -143,8 +170,6 @@ require 'rack/app'
143
170
 
144
171
  class App < Rack::App
145
172
 
146
- apply_extensions :front_end
147
-
148
173
  mount SomeAppClass
149
174
 
150
175
  headers 'Access-Control-Allow-Origin' => '*',
@@ -158,11 +183,12 @@ class App < Rack::App
158
183
  validate_params do
159
184
  required 'words', :class => Array, :of => String, :desc => 'some word', :example => ['pug']
160
185
  optional 'word', :class => String, :desc => 'one word', :example => 'pug'
186
+ optional 'boolean', :class => :boolean, :desc => 'boolean value', :example => true
161
187
  end
162
188
  get '/hello' do
163
- puts(validate_params['words'])
189
+ puts(params['words'])
164
190
 
165
- return 'Hello World!'
191
+ 'Hello World!'
166
192
  end
167
193
 
168
194
  namespace '/users' do
@@ -202,9 +228,43 @@ end
202
228
  ```
203
229
 
204
230
  you can access Rack::Request with the request method and
205
- Rack::Response as response method.
231
+ Rack::Response as a response method.
232
+
233
+ By default, if you don't write anything to the response 'body' the endpoint block logic return will be used
234
+
235
+ ### Frontend Example
236
+
237
+ if you don't mind extending your dependency list then you can use the front_end extension for creating template-based web applications.
238
+
239
+ ```ruby
240
+ require 'rack/app'
241
+ require 'rack/app/front_end' # You need to add `gem 'rack-app-front_end'` to your Gemfile
242
+
243
+ class App < Rack::App
244
+
245
+ apply_extensions :front_end
246
+
247
+ helpers do
248
+
249
+ def method_that_can_be_used_in_template
250
+ 'hello world!'
251
+ end
252
+
253
+ end
254
+
255
+ # use ./app/layout.html.erb as layout, this is optionable
256
+ layout 'layout.html.erb'
257
+
258
+ # at '/' the endpoint will serve (render)
259
+ # the ./app/index.html content as response body and wrap around with layout if the layout is given
260
+ get '/' do
261
+ render 'index.html'
262
+ end
263
+
264
+ end
265
+ ```
206
266
 
207
- By default if you dont write anything to the response 'body' the endpoint block logic return will be used
267
+ this example expects an "app" folder next to the "app.rb" file that included templates being used such as layout.html.erb and index.html.
208
268
 
209
269
  ## Testing
210
270
 
@@ -223,7 +283,7 @@ describe App do
223
283
 
224
284
  describe '/hello' do
225
285
  # example for params and headers and payload use
226
- subject{ get(url: '/hello', params: {'dog' => 'meat'}, headers: {'X-Cat' => 'fur'}, payload: 'some string') }
286
+ subject { get(url: '/hello', params: {'dog' => 'meat'}, headers: {'X-Cat' => 'fur'}, payload: 'some string') }
227
287
 
228
288
  it { expect(subject.status).to eq 200 }
229
289
 
@@ -232,7 +292,7 @@ describe App do
232
292
 
233
293
  describe '/users/:user_id' do
234
294
  # restful endpoint example
235
- subject{ get(url: '/users/1234') }
295
+ subject { get(url: '/users/1234') }
236
296
 
237
297
  it { expect(subject.body).to eq 'hello 1234!'}
238
298
 
@@ -242,7 +302,7 @@ describe App do
242
302
 
243
303
  describe '/make_error' do
244
304
  # error handled example
245
- subject{ get(url: '/make_error') }
305
+ subject { get(url: '/make_error') }
246
306
 
247
307
  it { expect(subject.body).to eq '{:error=>"error block rescued"}' }
248
308
  end
@@ -254,19 +314,19 @@ end
254
314
 
255
315
  ## Example Apps To start with
256
316
 
257
- * [Official website How To examples](http://rack-app.com/)
317
+ * [Official website How To examples](http://www.rack-app.com/)
258
318
 
259
319
  * [Rack::App Team Github repositories](https://github.com/rack-app)
260
320
 
261
321
  * [Basic](https://github.com/rack-app/rack-app-example-basic)
262
- * bare bone simple example app
322
+ * bare-bone simple example app
263
323
 
264
324
  * [Escher Authorized Api](https://github.com/rack-app/rack-app-example-escher)
265
- * complex authorization for corporal level api use
325
+ * complex authorization for corporal level API use
266
326
 
267
327
  ## [Benchmarking](https://github.com/rack-app/rack-app-benchmark)
268
328
 
269
- This is a repo that used for measure Rack::App project speed in order keep an eye on the performance in every release.
329
+ This is a repo that used for measure Rack::App project speed in order to keep an eye on the performance in every release.
270
330
 
271
331
  the benchmarking was taken on the following hardware specification:
272
332
  * Processor: 2,7 GHz Intel Core i5
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.3.2
1
+ 7.7.0
Binary file
@@ -28,6 +28,9 @@ class Rack::App::Endpoint
28
28
  end
29
29
 
30
30
  def to_app
31
+ # TODO: fix this to cache it, but to that you need to resolve the problem when middlewares added,
32
+ # old endpoints are not refreshed by the middleware configs
33
+ # router.reset must be checked
31
34
  self.class::Builder.new(@config).to_app
32
35
  end
33
36
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'rack/builder'
3
4
  class Rack::App::Endpoint::Builder
4
5
  def initialize(config)
@@ -33,17 +34,28 @@ class Rack::App::Endpoint::Builder
33
34
  end
34
35
  builder.use(Rack::App::Middlewares::Configuration, @config)
35
36
 
36
- apply_hook_middlewares(builder)
37
+ apply_catcher_on_need(builder)
38
+ @config.ancestor_apps.reverse_each do |app_class|
39
+ apply_hook_middlewares(app_class, builder)
40
+ end
37
41
  end
38
42
 
39
- def apply_hook_middlewares(builder)
40
- if @config.app_class.before.length + @config.app_class.after.length > 0
43
+ def apply_catcher_on_need(builder)
44
+ at_least_one_hook_requested = @config.ancestor_apps.any? do |app_class|
45
+ app_class.before.length + app_class.after.length > 0
46
+ end
47
+
48
+ if at_least_one_hook_requested
41
49
  builder.use(Rack::App::Endpoint::Catcher, @config)
42
50
  end
43
- @config.app_class.before.each do |before_block|
51
+ end
52
+
53
+ def apply_hook_middlewares(app_class, builder)
54
+ app_class.before.each do |before_block|
44
55
  builder.use(Rack::App::Middlewares::Hooks::Before, before_block)
45
56
  end
46
- @config.app_class.after.each do |after_block|
57
+
58
+ app_class.after.each do |after_block|
47
59
  builder.use(Rack::App::Middlewares::Hooks::After, after_block)
48
60
  end
49
61
  end
@@ -6,11 +6,14 @@ class Rack::App::Endpoint::Catcher
6
6
  end
7
7
 
8
8
  def call(env)
9
- handle_rack_response do
9
+ resp = handle_rack_response do
10
10
  handle_response_body(env) do
11
11
  @app.call(env)
12
12
  end
13
13
  end
14
+ return resp.finish if resp.is_a?(Rack::Response)
15
+
16
+ resp
14
17
  end
15
18
 
16
19
  protected
@@ -1,10 +1,24 @@
1
1
  class Rack::App::FileServer
2
+ attr_accessor :relative_file_paths
2
3
 
3
- def initialize(root_folder)
4
- require 'rack/file'
4
+ def self.serve_file(env, file_path)
5
+ dir_path = File.dirname(file_path)
6
+ basename = File.basename(file_path)
7
+ file_server = new(dir_path, map_relative_file_paths: false)
8
+ env = env.dup
9
+ env[::Rack::App::Constants::ENV::REQUEST_METHOD] = 'GET'
10
+ env[::Rack::App::Constants::ENV::PATH_INFO] = basename
11
+ file_server.call(env)
12
+ end
13
+
14
+ def initialize(root_folder, opts = {})
5
15
  @root_folder = root_folder
6
- @relative_file_paths = Dir.glob(File.join(@root_folder, '**', '*')).map { |file_path| file_path.sub(@root_folder, '') }.sort_by { |str| str.length }.reverse
16
+ @relative_file_paths = []
7
17
  @rack_file_server = ::Rack::File.new(@root_folder, {})
18
+
19
+ if map_relative_file_paths?(opts)
20
+ map_relative_paths!
21
+ end
8
22
  end
9
23
 
10
24
  def call(env)
@@ -12,7 +26,7 @@ class Rack::App::FileServer
12
26
 
13
27
  @relative_file_paths.each do |relative_file_path|
14
28
  if path_info =~ /#{Regexp.escape(relative_file_path)}$/
15
- env[::Rack::App::Constants::ENV::PATH_INFO]= relative_file_path
29
+ env[::Rack::App::Constants::ENV::PATH_INFO] = relative_file_path
16
30
  break
17
31
  end
18
32
  end
@@ -20,19 +34,31 @@ class Rack::App::FileServer
20
34
  @rack_file_server.call(env)
21
35
  end
22
36
 
23
- def self.serve_file(env, file_path)
24
- file_server = self.new(File.dirname(file_path))
25
- env = env.dup
26
- env[::Rack::App::Constants::ENV::REQUEST_METHOD]= 'GET'
27
- env[::Rack::App::Constants::ENV::PATH_INFO]= file_path
28
- file_server.call(env)
37
+ protected
38
+
39
+ def map_relative_file_paths?(opts = {})
40
+ unless opts.key?(:map_relative_file_paths)
41
+ return true
42
+ end
43
+
44
+ opts[:map_relative_file_paths]
29
45
  end
30
46
 
31
- protected
47
+ def opts_set_defaults(opts)
48
+ unless opts.key?(:map_relative_file_paths)
49
+ opts[:map_relative_file_paths] = true
50
+ end
51
+ end
52
+
53
+ def map_relative_paths!
54
+ @relative_file_paths = Dir.glob(File.join(@root_folder, '**', '*'))
55
+ .map { |file_path| file_path.sub(@root_folder, '') }
56
+ .sort_by { |str| str.length }
57
+ .reverse
58
+ end
32
59
 
33
60
  def clean_path_info(env)
34
61
  path_info = ::Rack::Utils.unescape(env[::Rack::App::Constants::ENV::PATH_INFO])
35
62
  ::Rack::Utils.clean_path_info(path_info)
36
63
  end
37
-
38
64
  end
@@ -1,10 +1,10 @@
1
1
  module Rack::App::InstanceMethods::ServeFile
2
2
 
3
3
  def serve_file(file_path)
4
- raw_rack_resp = Rack::App::FileServer.serve_file(request.env, file_path)
5
- response.status = raw_rack_resp[0]
6
- response.headers.merge!(raw_rack_resp[1])
7
- response.body = raw_rack_resp[2]
4
+ rack_resp = Rack::App::FileServer.serve_file(request.env, file_path)
5
+ response.status = rack_resp[0]
6
+ response.headers.merge!(rack_resp[1])
7
+ response.body = rack_resp[2]
8
8
  finish!
9
9
  end
10
10
 
@@ -37,22 +37,20 @@ class Rack::App::Middlewares::Params::Validator
37
37
 
38
38
  def validate_required_params(env, params)
39
39
  @descriptor[:required].each do |key, properties|
40
- validate_key(key,properties,params)
40
+ validate_key(key, properties, params)
41
41
  end
42
42
  end
43
43
 
44
44
  def validate_optional_params(env, params)
45
45
  @descriptor[:optional].each do |key, properties|
46
- next unless params.has_key?(key)
46
+ next unless params.key?(key)
47
47
 
48
- validate_key(key,properties,params)
48
+ validate_key(key, properties, params)
49
49
  end
50
50
  end
51
51
 
52
- def validate_key(key,properties,params)
53
- unless params.has_key?(key)
54
- missing_key_error(key, properties[:class])
55
- end
52
+ def validate_key(key, properties, params)
53
+ missing_key_error(key, properties[:class]) unless params.key?(key)
56
54
 
57
55
  if properties[:of]
58
56
  validate_array(properties[:class], properties[:of], key, *params[key])
@@ -69,7 +67,7 @@ class Rack::App::Middlewares::Params::Validator
69
67
  end
70
68
 
71
69
  def validate_array(type, elements_type, key, *elements)
72
- values = elements.map{ |str| parse(elements_type, str) }
70
+ values = elements.map { |str| parse(elements_type, str) }
73
71
 
74
72
  if values.include?(nil)
75
73
  invalid_type_of_error(key, type, elements_type)
@@ -92,11 +90,11 @@ class Rack::App::Middlewares::Params::Validator
92
90
  error "invalid key: #{key}"
93
91
  end
94
92
 
95
- def invalid_type_error(key,klass)
93
+ def invalid_type_error(key, klass)
96
94
  error "invalid type for #{key}: #{klass} expected"
97
95
  end
98
96
 
99
- def invalid_type_of_error(key,klass,of)
97
+ def invalid_type_of_error(key, klass, of)
100
98
  error "invalid type for #{key}: #{klass} of #{of} expected"
101
99
  end
102
100
  end
@@ -1,7 +1,7 @@
1
1
  class Rack::App::Middlewares::SetPathParams
2
2
 
3
- def initialize(app, params_lookup_hash)
4
- @params_lookup_hash = params_lookup_hash
3
+ def initialize(app, build_env)
4
+ @build_env = build_env
5
5
  @app = app
6
6
  end
7
7
 
@@ -16,19 +16,21 @@ class Rack::App::Middlewares::SetPathParams
16
16
  protected
17
17
 
18
18
  def populate_path_params(env)
19
- @params_lookup_hash.each do |index, key|
19
+ @build_env.params.each do |index, key|
20
20
  env[E::PATH_SEGMENTS_PARAMS][key] = env[E::SPLITTED_PATH_INFO][index]
21
21
  end
22
22
  end
23
23
 
24
24
  def correct_last_value_from_extensions(env)
25
+ return if @build_env.endpoint.config.serializer.extnames.empty?
25
26
  last_index = env[E::SPLITTED_PATH_INFO].length - 1
26
- return if @params_lookup_hash[last_index].nil?
27
- extless(env[E::PATH_SEGMENTS_PARAMS][@params_lookup_hash[last_index]])
27
+ return if @build_env.params[last_index].nil?
28
+ extless(env[E::PATH_SEGMENTS_PARAMS][@build_env.params[last_index]])
28
29
  end
29
30
 
30
31
  def extless(value)
31
32
  extname = File.extname(value)
33
+ return unless @build_env.endpoint.config.serializer.extnames.include?(extname)
32
34
  value.slice!(/#{Regexp.escape(extname)}$/) unless extname.empty?
33
35
  end
34
36
 
@@ -2,11 +2,11 @@ module Rack::App::Payload::Parser::Builder::Formats
2
2
  extend(self)
3
3
 
4
4
  JSON_CONTENT_TYPES = [
5
- 'application/json',
6
- 'application/x-javascript',
7
- 'text/javascript',
8
- 'text/x-javascript',
9
- 'text/x-json'
5
+ 'application/json',
6
+ 'application/x-javascript',
7
+ 'text/javascript',
8
+ 'text/x-javascript',
9
+ 'text/x-json'
10
10
  ].freeze
11
11
 
12
12
  JSON_PARSER = proc do |io|
@@ -28,9 +28,9 @@ module Rack::App::Payload::Parser::Builder::Formats
28
28
  end
29
29
 
30
30
  JSON_STREAM_CONTENT_TYPES = [
31
- 'application/jsonstream',
32
- 'application/stream+json',
33
- 'application/x-json-stream'
31
+ 'application/jsonstream',
32
+ 'application/stream+json',
33
+ 'application/x-json-stream'
34
34
  ].freeze
35
35
 
36
36
  JSON_STREAM_PARSER = proc do |io|
@@ -62,8 +62,8 @@ module Rack::App::Payload::Parser::Builder::Formats
62
62
  # end
63
63
 
64
64
  FORM_CONTENT_TYPES = [
65
- 'application/x-www-form-urlencoded',
66
- # 'multipart/form-data'
65
+ 'application/x-www-form-urlencoded',
66
+ # 'multipart/form-data'
67
67
  ].freeze
68
68
 
69
69
  FORM_SEP_CHAR = '&'.freeze
@@ -76,7 +76,7 @@ module Rack::App::Payload::Parser::Builder::Formats
76
76
  lambda do |form|
77
77
  ::Rack::Utils.parse_nested_query(form, FORM_SEP_CHAR)
78
78
  end
79
- end
79
+ end
80
80
 
81
81
  NULL_END_CHAR = /#{"\u0000"}$/
82
82
 
@@ -102,7 +102,7 @@ module Rack::App::Payload::Parser::Builder::Formats
102
102
  last_name = form_name
103
103
  unless respond_to?(form_name)
104
104
  raise(NotImplementedError, "unknown formatter: #{last_name}")
105
- end
105
+ end
106
106
  __send__ form_name, builder
107
107
  end
108
108
  end
@@ -48,5 +48,4 @@ class Rack::App::Router::Tree::Leaf < ::Hash
48
48
  self[path_part] ||= Rack::App::Router::Tree::Vein.new
49
49
  end
50
50
 
51
-
52
51
  end
@@ -21,12 +21,12 @@ class Rack::App::Router::Tree::Vein < ::Hash
21
21
 
22
22
  def create_app(env)
23
23
  app = env.endpoint.to_app
24
- env.params.empty? ? app : wrap(app, env.params)
24
+ env.params.empty? ? app : wrap(app, env)
25
25
  end
26
26
 
27
- def wrap(app, params)
27
+ def wrap(app, env)
28
28
  builder = Rack::Builder.new
29
- builder.use(Rack::App::Middlewares::SetPathParams, params)
29
+ builder.use(Rack::App::Middlewares::SetPathParams, env)
30
30
  builder.run(app)
31
31
  builder.to_app
32
32
  end
@@ -46,8 +46,8 @@ module Rack::App::SingletonMethods::Mounting
46
46
  nil
47
47
  end
48
48
 
49
- def serve_files_from(file_path, options={})
50
- file_server = Rack::App::FileServer.new(Rack::App::Utils.expand_path(file_path))
49
+ def serve_files_from(dir_path, options={})
50
+ file_server = Rack::App::FileServer.new(Rack::App::Utils.expand_path(dir_path))
51
51
  request_path = Rack::App::Utils.join(options[:to], Rack::App::Constants::PATH::MOUNT_POINT)
52
52
  add_route(::Rack::App::Constants::HTTP::METHOD::ANY, request_path, file_server)
53
53
  nil
@@ -3,8 +3,8 @@ module Rack::App::Streamer::Scheduler::Null
3
3
  extend(self)
4
4
 
5
5
  def schedule(*)
6
- yield
7
- end
6
+ yield
7
+ end
8
8
 
9
9
  def defer(*)
10
10
  yield
data/lib/rack/app/test.rb CHANGED
@@ -1,7 +1,6 @@
1
- require "uri"
2
- require "rack/mock"
1
+ require 'uri'
2
+ require 'rack/mock'
3
3
  module Rack::App::Test
4
-
5
4
  require 'rack/app/test/utils'
6
5
  require 'rack/app/test/singleton_methods'
7
6
 
@@ -16,12 +15,12 @@ module Rack::App::Test
16
15
  url = args.detect { |e| e.is_a?(String) } || properties.delete(:url)
17
16
  mock_request = Rack::MockRequest.new(rack_app)
18
17
  request_env = Rack::App::Test::Utils.env_by(url, properties)
19
- return @last_response = mock_request.request(request_method.to_s.upcase, url, request_env)
18
+ @last_response = mock_request.request(request_method.to_s.upcase, url, request_env)
20
19
  end
21
20
 
22
21
  Rack::App::Constants::HTTP::METHODS.each do |request_method_type|
23
22
  define_method(request_method_type.to_s.downcase) do |*args|
24
- self.__send_rack_app_request__(request_method_type, *args)
23
+ __send_rack_app_request__(request_method_type, *args)
25
24
  end
26
25
  end
27
26
 
@@ -38,4 +37,34 @@ module Rack::App::Test
38
37
  block.is_a?(Proc) ? @rack_app.instance_exec(&block) : @rack_app
39
38
  end
40
39
 
40
+ def mount(app_class, options)
41
+ path_prefix = options.fetch(:to)
42
+
43
+ selector = lambda do |e|
44
+ if e.config.type == :endpoint
45
+ e.config.app_class == app_class
46
+ else
47
+ e.config.callable == app_class
48
+ end
49
+ end
50
+
51
+ endpoints = rack_app.router.endpoints.select(&selector)
52
+
53
+ request_paths_that_has_prefix = lambda do |e|
54
+ e.request_path.start_with?(path_prefix)
55
+ end
56
+
57
+ matching_endpoints = endpoints.select(&request_paths_that_has_prefix)
58
+
59
+ if matching_endpoints.empty?
60
+ raise("Can't find any path that fullfill the requirement")
61
+ end
62
+
63
+ return unless app_class.is_a?(Class) && app_class <= Rack::App
64
+ app_owned_endpoints = app_class.router.endpoints.select(&selector)
65
+
66
+ if matching_endpoints.length != app_owned_endpoints.length
67
+ raise('endpoint count not matching')
68
+ end
69
+ end
41
70
  end
data/rack-app.gemspec CHANGED
@@ -1,28 +1,27 @@
1
1
  # coding: utf-8
2
2
  Gem::Specification.new do |spec|
3
3
 
4
- spec.name = "rack-app"
5
- spec.version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).strip
6
- spec.authors = ["Adam Luzsi"]
7
- spec.email = ["adamluzsi@gmail.com"]
4
+ spec.name = 'rack-app'
5
+ spec.version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).strip
6
+ spec.authors = ['Adam Luzsi']
7
+ spec.email = ['adamluzsi@gmail.com']
8
8
 
9
- spec.summary = %q{Your next favourite, performance designed micro framework!}
10
- spec.description = %q{Your next favourite rack based micro framework that is totally addition free! Have a cup of awesomeness with your to performance designed framework!}
9
+ summary = 'Minimalist rack application interface building framework.'
10
+ spec.summary = summary
11
+ spec.description = summary
11
12
 
12
- spec.homepage = 'http://www.rack-app.com/'
13
+ spec.homepage = 'http://www.rack-app.com/'
13
14
 
14
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
15
- spec.require_paths = ["lib"]
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.require_paths = ['lib']
16
17
 
17
- spec.bindir = "bin"
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.bindir = 'bin'
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
20
 
20
- spec.license = 'Apache License 2.0'
21
+ spec.license = 'Apache License 2.0'
21
22
 
22
- spec.add_development_dependency "bundler"
23
- spec.add_development_dependency "rake", '10.4.2'
24
- spec.add_development_dependency "rspec"
25
-
26
- spec.add_dependency "rack"
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'rspec'
25
+ spec.add_dependency 'rack'
27
26
 
28
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-app
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.3.2
4
+ version: 7.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Luzsi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-11 00:00:00.000000000 Z
11
+ date: 2020-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 10.4.2
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 10.4.2
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rspec
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,8 +52,7 @@ dependencies:
66
52
  - - ">="
67
53
  - !ruby/object:Gem::Version
68
54
  version: '0'
69
- description: Your next favourite rack based micro framework that is totally addition
70
- free! Have a cup of awesomeness with your to performance designed framework!
55
+ description: Minimalist rack application interface building framework.
71
56
  email:
72
57
  - adamluzsi@gmail.com
73
58
  executables:
@@ -75,6 +60,7 @@ executables:
75
60
  extensions: []
76
61
  extra_rdoc_files: []
77
62
  files:
63
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
78
64
  - ".gitignore"
79
65
  - ".rspec"
80
66
  - ".rubocop.yml"
@@ -89,6 +75,7 @@ files:
89
75
  - VERSION
90
76
  - Vagrantfile
91
77
  - _config.yml
78
+ - assets/rack-app-logo.png
92
79
  - bin/rack-app
93
80
  - dev/console
94
81
  - dev/rack-app
@@ -210,7 +197,7 @@ homepage: http://www.rack-app.com/
210
197
  licenses:
211
198
  - Apache License 2.0
212
199
  metadata: {}
213
- post_install_message:
200
+ post_install_message:
214
201
  rdoc_options: []
215
202
  require_paths:
216
203
  - lib
@@ -225,9 +212,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
212
  - !ruby/object:Gem::Version
226
213
  version: '0'
227
214
  requirements: []
228
- rubyforge_project:
229
- rubygems_version: 2.6.8
230
- signing_key:
215
+ rubygems_version: 3.0.3
216
+ signing_key:
231
217
  specification_version: 4
232
- summary: Your next favourite, performance designed micro framework!
218
+ summary: Minimalist rack application interface building framework.
233
219
  test_files: []