rack-app 0.4.0 → 0.5.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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +32 -7
- data/VERSION +1 -1
- data/lib/rack/app.rb +82 -7
- data/lib/rack/app/{request_helper/params.rb → params.rb} +1 -1
- data/lib/rack/app/test.rb +63 -0
- metadata +4 -6
- data/lib/rack/app/class_methods.rb +0 -69
- data/lib/rack/app/request_helpers.rb +0 -15
- data/lib/rack/app/runner.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a061f4202e995da2a1325944ec7586052d30a603
|
4
|
+
data.tar.gz: 193cb7950307a6161f8095b9f90073024241daff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5bccaeb4dcd6599eb14003434dc54dda1cb8d31f93968c7e5fccf1420e7cbdf427d3d6728f897a9557868fa9fb8681c1ebeac8189f5e6a8261d4b202d126f38f
|
7
|
+
data.tar.gz: 734d959b060a38c58ecea6f7214d33bf3396c7ba71704c4cb6d90c893086a7cdbb162e41945ea626f9c6c693cad24fff8e5126c1016515056f299c3387c90ecb
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -80,6 +80,35 @@ Rack::Response as response method.
|
|
80
80
|
|
81
81
|
By default if you dont write anything to the response 'body' the endpoint block logic return will be used
|
82
82
|
|
83
|
+
## Testing
|
84
|
+
|
85
|
+
use bundled in testing module for writing unit test for your rack application
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
|
89
|
+
require_relative '../../spec_helper'
|
90
|
+
require 'rack/app/test'
|
91
|
+
|
92
|
+
describe MyRackApp do
|
93
|
+
|
94
|
+
include Rack::App::Test
|
95
|
+
|
96
|
+
rack_app described_class
|
97
|
+
|
98
|
+
describe '#something' do
|
99
|
+
|
100
|
+
subject{ get('/hello', params: {'dog' => 'meat'}, headers: {'X-Cat' => 'fur'}) }
|
101
|
+
|
102
|
+
it { expect(subject.body).to eq ['world']}
|
103
|
+
|
104
|
+
it { expect(subject.status).to eq 201 }
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
```
|
111
|
+
|
83
112
|
## Example Apps To start with
|
84
113
|
|
85
114
|
* [Basic](https://github.com/adamluzsi/rack-app.rb-examples/tree/master/basic)
|
@@ -111,20 +140,16 @@ i feared do this for Rails that is usually slower than Grape :S
|
|
111
140
|
|
112
141
|
## Roadmap
|
113
142
|
|
114
|
-
### 0.
|
115
|
-
|
116
|
-
* add TESTING module for rspec helpers that allow easy to test controllers
|
117
|
-
|
118
|
-
### 0.4.0
|
143
|
+
### 0.6.0
|
119
144
|
|
120
145
|
* serializer block/method for class shared serialization logic
|
121
146
|
|
122
|
-
### 0.
|
147
|
+
### 0.7.0
|
123
148
|
|
124
149
|
* content_type syntax sugar on class level
|
125
150
|
* response_headers syntax sugar for request processing
|
126
151
|
|
127
|
-
### 0.
|
152
|
+
### 0.8.0
|
128
153
|
|
129
154
|
* custom error_handler block for api, where Exception class types can be defined to process
|
130
155
|
* NULL Object pattern for error_handler_fetcher
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/rack/app.rb
CHANGED
@@ -5,21 +5,96 @@ class Rack::App
|
|
5
5
|
|
6
6
|
require 'rack/app/version'
|
7
7
|
|
8
|
+
require 'rack/app/params'
|
8
9
|
require 'rack/app/utils'
|
9
10
|
require 'rack/app/router'
|
10
11
|
require 'rack/app/endpoint'
|
11
12
|
require 'rack/app/endpoint/not_found'
|
12
|
-
require 'rack/app/runner'
|
13
13
|
|
14
|
-
|
15
|
-
extend Rack::App::ClassMethods
|
14
|
+
class << self
|
16
15
|
|
17
|
-
|
16
|
+
def call(request_env)
|
17
|
+
endpoint = router.fetch_endpoint(request_env['REQUEST_METHOD'],request_env['REQUEST_PATH'])
|
18
|
+
endpoint.execute(request_env)
|
19
|
+
end
|
18
20
|
|
19
|
-
|
21
|
+
def description(*description_texts)
|
22
|
+
@last_description = description_texts.join("\n")
|
23
|
+
end
|
20
24
|
|
21
|
-
|
22
|
-
|
25
|
+
def get(path = '/', &block)
|
26
|
+
add_route('GET', path, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def post(path = '/', &block)
|
30
|
+
add_route('POST', path, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def put(path = '/', &block)
|
34
|
+
add_route('PUT', path, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def head(path = '/', &block)
|
38
|
+
add_route('HEAD', path, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete(path = '/', &block)
|
42
|
+
add_route('DELETE', path, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def options(path = '/', &block)
|
46
|
+
add_route('OPTIONS', path, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def patch(path = '/', &block)
|
50
|
+
add_route('PATCH', path, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def router
|
54
|
+
@router ||= Rack::App::Router.new
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_route(request_method, request_path, &block)
|
58
|
+
|
59
|
+
endpoint_properties = {
|
60
|
+
request_method: request_method,
|
61
|
+
request_path: request_path,
|
62
|
+
description: @last_description
|
63
|
+
}
|
64
|
+
|
65
|
+
endpoint = Rack::App::Endpoint.new(
|
66
|
+
self, endpoint_properties, &block
|
67
|
+
)
|
68
|
+
|
69
|
+
router.add_endpoint(request_method, request_path, endpoint)
|
70
|
+
|
71
|
+
@last_description = nil
|
72
|
+
return endpoint
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def mount(api_class)
|
78
|
+
|
79
|
+
unless api_class.is_a?(Class) and api_class <= Rack::App
|
80
|
+
raise(ArgumentError, 'Invalid class given for mount, must be a Rack::App')
|
81
|
+
end
|
82
|
+
|
83
|
+
router.merge!(api_class.router)
|
84
|
+
|
85
|
+
return nil
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def params
|
91
|
+
@__params__ ||= Rack::App::Params.new(request.env).to_hash
|
92
|
+
end
|
93
|
+
|
94
|
+
def status(new_status=nil)
|
95
|
+
response.status= new_status.to_i unless new_status.nil?
|
96
|
+
|
97
|
+
response.status
|
23
98
|
end
|
24
99
|
|
25
100
|
attr_writer :request, :response
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'rack/app'
|
3
|
+
module Rack::App::Test
|
4
|
+
|
5
|
+
# magic ;)
|
6
|
+
def self.included(klass)
|
7
|
+
|
8
|
+
klass.define_singleton_method :rack_app do |rack_app_class=nil, &constructor|
|
9
|
+
|
10
|
+
subject_app = rack_app_class.is_a?(Class) ? rack_app_class : Class.new(Rack::App)
|
11
|
+
subject_app.instance_eval(&constructor) unless constructor.nil?
|
12
|
+
|
13
|
+
klass.__send__ :define_method, :rack_app do
|
14
|
+
@rack_app = subject_app
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
[:get, :post, :put, :delete, :options].each do |request_method|
|
22
|
+
define_method(request_method) do |url, properties={}|
|
23
|
+
rack_app.call(request_env_by(request_method, url, properties)).last
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def format_properties(properties)
|
28
|
+
raise('use hash format such as params: {"key" => "value"} or headers with the same concept') unless properties.is_a?(Hash)
|
29
|
+
properties[:params] ||= {}
|
30
|
+
properties[:headers]||= {}
|
31
|
+
|
32
|
+
properties
|
33
|
+
end
|
34
|
+
|
35
|
+
def request_env_by(request_method, url, raw_properties)
|
36
|
+
|
37
|
+
properties = format_properties(raw_properties)
|
38
|
+
URI.encode_www_form(properties[:params].to_a)
|
39
|
+
|
40
|
+
additional_headers = properties[:headers].reduce({}) { |m,(k, v)| m.merge("HTTP_#{k.to_s.gsub('-', '_').upcase}" => v.to_s) }
|
41
|
+
|
42
|
+
{
|
43
|
+
"REMOTE_ADDR" => "192.168.56.1",
|
44
|
+
"REQUEST_METHOD" => request_method.to_s.upcase,
|
45
|
+
"REQUEST_PATH" => url,
|
46
|
+
"REQUEST_URI" => url,
|
47
|
+
"SERVER_PROTOCOL" => "HTTP/1.1",
|
48
|
+
"CONTENT_LENGTH" => "0",
|
49
|
+
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
|
50
|
+
"SERVER_NAME" => "hds-dev.ett.local",
|
51
|
+
"SERVER_PORT" => "80",
|
52
|
+
"QUERY_STRING" => URI.encode_www_form(properties[:params].to_a),
|
53
|
+
"HTTP_VERSION" => "HTTP/1.1",
|
54
|
+
"HTTP_USER_AGENT" => "spec",
|
55
|
+
"HTTP_HOST" => "spec.local",
|
56
|
+
"HTTP_ACCEPT_ENCODING" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
|
57
|
+
"HTTP_ACCEPT" => "*/*",
|
58
|
+
"HTTP_CONNECTION" => "close"
|
59
|
+
}.merge(additional_headers)
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
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: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Luzsi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -85,15 +85,13 @@ files:
|
|
85
85
|
- VERSION
|
86
86
|
- bin/setup
|
87
87
|
- lib/rack/app.rb
|
88
|
-
- lib/rack/app/class_methods.rb
|
89
88
|
- lib/rack/app/endpoint.rb
|
90
89
|
- lib/rack/app/endpoint/not_found.rb
|
91
|
-
- lib/rack/app/
|
92
|
-
- lib/rack/app/request_helpers.rb
|
90
|
+
- lib/rack/app/params.rb
|
93
91
|
- lib/rack/app/router.rb
|
94
92
|
- lib/rack/app/router/dynamic.rb
|
95
93
|
- lib/rack/app/router/static.rb
|
96
|
-
- lib/rack/app/
|
94
|
+
- lib/rack/app/test.rb
|
97
95
|
- lib/rack/app/utils.rb
|
98
96
|
- lib/rack/app/version.rb
|
99
97
|
- rack-app.gemspec
|
@@ -1,69 +0,0 @@
|
|
1
|
-
module Rack::App::ClassMethods
|
2
|
-
|
3
|
-
def description(*description_texts)
|
4
|
-
@last_description = description_texts.join("\n")
|
5
|
-
end
|
6
|
-
|
7
|
-
def get(path = '/', &block)
|
8
|
-
add_route('GET', path, &block)
|
9
|
-
end
|
10
|
-
|
11
|
-
def post(path = '/', &block)
|
12
|
-
add_route('POST', path, &block)
|
13
|
-
end
|
14
|
-
|
15
|
-
def put(path = '/', &block)
|
16
|
-
add_route('PUT', path, &block)
|
17
|
-
end
|
18
|
-
|
19
|
-
def head(path = '/', &block)
|
20
|
-
add_route('HEAD', path, &block)
|
21
|
-
end
|
22
|
-
|
23
|
-
def delete(path = '/', &block)
|
24
|
-
add_route('DELETE', path, &block)
|
25
|
-
end
|
26
|
-
|
27
|
-
def options(path = '/', &block)
|
28
|
-
add_route('OPTIONS', path, &block)
|
29
|
-
end
|
30
|
-
|
31
|
-
def patch(path = '/', &block)
|
32
|
-
add_route('PATCH', path, &block)
|
33
|
-
end
|
34
|
-
|
35
|
-
def router
|
36
|
-
@static_router ||= Rack::App::Router.new
|
37
|
-
end
|
38
|
-
|
39
|
-
def add_route(request_method, request_path, &block)
|
40
|
-
|
41
|
-
endpoint = Rack::App::Endpoint.new(
|
42
|
-
self,
|
43
|
-
{
|
44
|
-
request_method: request_method,
|
45
|
-
request_path: request_path,
|
46
|
-
description: @last_description
|
47
|
-
},
|
48
|
-
&block
|
49
|
-
)
|
50
|
-
|
51
|
-
router.add_endpoint(request_method,request_path,endpoint)
|
52
|
-
|
53
|
-
@last_description = nil
|
54
|
-
endpoint
|
55
|
-
end
|
56
|
-
|
57
|
-
|
58
|
-
def mount(api_class)
|
59
|
-
|
60
|
-
unless api_class.is_a?(Class) and api_class <= Rack::App
|
61
|
-
raise(ArgumentError, 'Invalid class given for mount, must be a Rack::App')
|
62
|
-
end
|
63
|
-
|
64
|
-
router.merge!(api_class.router)
|
65
|
-
|
66
|
-
nil
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Rack::App::RequestHelpers
|
2
|
-
|
3
|
-
require 'rack/app/request_helper/params'
|
4
|
-
|
5
|
-
def params
|
6
|
-
@__request_params__ ||= Rack::App::RequestHelpers::Params.new(request.env).to_hash
|
7
|
-
end
|
8
|
-
|
9
|
-
def status(new_status=nil)
|
10
|
-
response.status= new_status.to_i unless new_status.nil?
|
11
|
-
|
12
|
-
response.status
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|
data/lib/rack/app/runner.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
module Rack::App::Runner
|
2
|
-
extend self
|
3
|
-
|
4
|
-
def response_for(api_class, request_env)
|
5
|
-
endpoint = fetch_endpoint(api_class,request_env['REQUEST_METHOD'],request_env['REQUEST_PATH'])
|
6
|
-
endpoint.execute(request_env)
|
7
|
-
end
|
8
|
-
|
9
|
-
protected
|
10
|
-
|
11
|
-
def fetch_endpoint(api_class, request_method, request_path)
|
12
|
-
api_class.router.fetch_endpoint(request_method, request_path)
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|