angelo 0.1.22 → 0.1.23
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/CHANGELOG.md +7 -0
- data/Gemfile.lock +3 -1
- data/lib/angelo/base.rb +37 -7
- data/lib/angelo/mustermann.rb +28 -2
- data/lib/angelo/responder/eventsource.rb +8 -10
- data/lib/angelo/responder/websocket.rb +2 -2
- data/lib/angelo/responder.rb +3 -7
- data/lib/angelo/version.rb +1 -1
- data/test/angelo/eventsource_spec.rb +69 -14
- data/test/angelo/filter_spec.rb +294 -0
- data/test/angelo/mustermann_spec.rb +88 -0
- data/test/angelo/websocket_spec.rb +2 -2
- data/test/angelo_spec.rb +8 -75
- data/test/spec_helper.rb +8 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3c4a56a27bb63eaf52526379dbc8424c6f194af
|
4
|
+
data.tar.gz: 4ab664e1d95cb17bd9d3617565d5e4005327fd37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a1f2d26c2a74f064f9c35efe1f9c923849f51d48b7a4366f7ba28cbbfd808ee984a6a703d113d5cd50673121f7956bb7ed3bb3fa44173e2b23a46d2ec5e76f8
|
7
|
+
data.tar.gz: d4a1f1487a0f56ce0cad5da17cf5322c537752d8eb2bae6d1f4bed3999fe946310eb0184f30ee1f2d0cf9d8905598d5da0f6077876891352823a7633f44c6873
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
### 0.1.23 18 sep 2014 (thanks @chewi, @samjohnduke)
|
5
|
+
|
6
|
+
* multiple before/after filters with mustermann support (#3)
|
7
|
+
* accept extra headers in eventsource route builder (#6)
|
8
|
+
* handle errors in before blocks for eventsource-built routes (#6)
|
9
|
+
* let DELETE and OPTIONS routes see query params (#8)
|
10
|
+
|
4
11
|
### 0.1.22 9 sep 2014
|
5
12
|
|
6
13
|
* handle bad/malformed requests better
|
data/Gemfile.lock
CHANGED
@@ -16,7 +16,8 @@ GEM
|
|
16
16
|
method_source (0.8.2)
|
17
17
|
mime-types (2.3)
|
18
18
|
minitest (5.4.0)
|
19
|
-
mustermann (0.
|
19
|
+
mustermann (0.3.1)
|
20
|
+
tool (~> 0.2)
|
20
21
|
nio4r (1.0.0)
|
21
22
|
nio4r (1.0.0-java)
|
22
23
|
pry (0.9.12.6)
|
@@ -42,6 +43,7 @@ GEM
|
|
42
43
|
ffi
|
43
44
|
tilt (2.0.1)
|
44
45
|
timers (1.1.0)
|
46
|
+
tool (0.2.2)
|
45
47
|
websocket-driver (0.3.4)
|
46
48
|
websocket-driver (0.3.4-java)
|
47
49
|
websocket_parser (0.1.6)
|
data/lib/angelo/base.rb
CHANGED
@@ -75,12 +75,35 @@ module Angelo
|
|
75
75
|
@routes
|
76
76
|
end
|
77
77
|
|
78
|
+
def filters
|
79
|
+
@filters ||= {before: {default: []}, after: {default: []}}
|
80
|
+
end
|
81
|
+
|
82
|
+
def filter which, opts = {}, &block
|
83
|
+
f = compile! :filter, &block
|
84
|
+
case opts
|
85
|
+
when String
|
86
|
+
filter_by which, opts, f
|
87
|
+
when Hash
|
88
|
+
if opts[:path]
|
89
|
+
filter_by which, opts[:path], f
|
90
|
+
else
|
91
|
+
filters[which][:default] << f
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def filter_by which, path, meth
|
97
|
+
filters[which][path] ||= []
|
98
|
+
filters[which][path] << meth
|
99
|
+
end
|
100
|
+
|
78
101
|
def before opts = {}, &block
|
79
|
-
|
102
|
+
filter :before, opts, &block
|
80
103
|
end
|
81
104
|
|
82
105
|
def after opts = {}, &block
|
83
|
-
|
106
|
+
filter :after, opts, &block
|
84
107
|
end
|
85
108
|
|
86
109
|
HTTPABLE.each do |m|
|
@@ -93,8 +116,8 @@ module Angelo
|
|
93
116
|
routes[:websocket][path] = Responder::Websocket.new &block
|
94
117
|
end
|
95
118
|
|
96
|
-
def eventsource path, &block
|
97
|
-
routes[:get][path] = Responder::Eventsource.new &block
|
119
|
+
def eventsource path, headers = nil, &block
|
120
|
+
routes[:get][path] = Responder::Eventsource.new headers, &block
|
98
121
|
end
|
99
122
|
|
100
123
|
def on_pong &block
|
@@ -166,9 +189,10 @@ module Angelo
|
|
166
189
|
|
167
190
|
def params
|
168
191
|
@params ||= case request.method
|
169
|
-
when GET
|
170
|
-
|
171
|
-
when PUT
|
192
|
+
when GET, DELETE, OPTIONS
|
193
|
+
parse_query_string
|
194
|
+
when POST, PUT
|
195
|
+
parse_post_body
|
172
196
|
end
|
173
197
|
end
|
174
198
|
|
@@ -275,6 +299,12 @@ module Angelo
|
|
275
299
|
Celluloid.sleep time
|
276
300
|
end
|
277
301
|
|
302
|
+
def filter which
|
303
|
+
fs = self.class.filters[which][:default]
|
304
|
+
fs += self.class.filters[which][request.path] if self.class.filters[which][request.path]
|
305
|
+
fs.each {|f| f.bind(self).call}
|
306
|
+
end
|
307
|
+
|
278
308
|
end
|
279
309
|
|
280
310
|
end
|
data/lib/angelo/mustermann.rb
CHANGED
@@ -33,9 +33,9 @@ module Angelo
|
|
33
33
|
super path, &block
|
34
34
|
end
|
35
35
|
|
36
|
-
def eventsource path, &block
|
36
|
+
def eventsource path, headers = nil, &block
|
37
37
|
path = ::Mustermann.new path
|
38
|
-
super path, &block
|
38
|
+
super path, headers, &block
|
39
39
|
end
|
40
40
|
|
41
41
|
def routes
|
@@ -46,12 +46,38 @@ module Angelo
|
|
46
46
|
@routes
|
47
47
|
end
|
48
48
|
|
49
|
+
def filter_by which, path, meth
|
50
|
+
pattern = ::Mustermann.new path
|
51
|
+
filters[which][pattern] ||= []
|
52
|
+
filters[which][pattern] << meth
|
53
|
+
end
|
54
|
+
|
49
55
|
end
|
50
56
|
|
51
57
|
def params
|
52
58
|
@params ||= super.merge mustermann.params(request.path)
|
53
59
|
end
|
54
60
|
|
61
|
+
def filter which
|
62
|
+
fs = self.class.filters[which][:default].dup
|
63
|
+
self.class.filters[which].each do |pattern, f|
|
64
|
+
if ::Mustermann === pattern and pattern.match request.path
|
65
|
+
fs << [f, pattern]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
fs.each do |f|
|
69
|
+
case f
|
70
|
+
when UnboundMethod
|
71
|
+
f.bind(self).call
|
72
|
+
when Array
|
73
|
+
@pre_filter_params = params
|
74
|
+
@params = @pre_filter_params.merge f[1].params(request.path)
|
75
|
+
f[0].each {|filter| filter.bind(self).call}
|
76
|
+
@params = @pre_filter_params
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
55
81
|
class RouteMap
|
56
82
|
|
57
83
|
def initialize
|
@@ -2,6 +2,11 @@ module Angelo
|
|
2
2
|
class Responder
|
3
3
|
class Eventsource < Responder
|
4
4
|
|
5
|
+
def initialize _headers = nil, &block
|
6
|
+
headers _headers if _headers
|
7
|
+
super &block
|
8
|
+
end
|
9
|
+
|
5
10
|
def request= request
|
6
11
|
@params = nil
|
7
12
|
@request = request
|
@@ -11,14 +16,14 @@ module Angelo
|
|
11
16
|
def handle_request
|
12
17
|
begin
|
13
18
|
if @response_handler
|
14
|
-
@base.
|
19
|
+
@base.filter :before
|
15
20
|
@body = catch(:halt) { @base.eventsource &@response_handler.bind(@base) }
|
16
21
|
if HALT_STRUCT === @body
|
17
22
|
raise RequestError.new 'unknown sse error' unless @body.body == :sse
|
18
23
|
end
|
19
24
|
|
20
25
|
# TODO any real reason not to run afters with SSE?
|
21
|
-
# @base.
|
26
|
+
# @base.filter :after
|
22
27
|
|
23
28
|
respond
|
24
29
|
else
|
@@ -26,15 +31,8 @@ module Angelo
|
|
26
31
|
end
|
27
32
|
rescue IOError => ioe
|
28
33
|
warn "#{ioe.class} - #{ioe.message}"
|
29
|
-
close_websocket
|
30
34
|
rescue => e
|
31
|
-
|
32
|
-
::STDERR.puts e.backtrace
|
33
|
-
begin
|
34
|
-
@connection.close
|
35
|
-
rescue Reel::StateError => rcse
|
36
|
-
close_websocket
|
37
|
-
end
|
35
|
+
handle_error e
|
38
36
|
end
|
39
37
|
end
|
40
38
|
|
@@ -25,9 +25,9 @@ module Angelo
|
|
25
25
|
Angelo.log @connection, @request, @websocket, :switching_protocols
|
26
26
|
@bound_response_handler ||= @response_handler.bind @base
|
27
27
|
@websocket.on_pong &Responder::Websocket.on_pong
|
28
|
-
@base.
|
28
|
+
@base.filter :before
|
29
29
|
@bound_response_handler[@websocket]
|
30
|
-
@base.
|
30
|
+
@base.filter :after
|
31
31
|
else
|
32
32
|
raise NotImplementedError
|
33
33
|
end
|
data/lib/angelo/responder.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'date'
|
2
|
-
|
3
1
|
module Angelo
|
4
2
|
|
5
3
|
class Responder
|
@@ -50,17 +48,15 @@ module Angelo
|
|
50
48
|
|
51
49
|
def handle_request
|
52
50
|
if @response_handler
|
53
|
-
@base.
|
51
|
+
@base.filter :before
|
54
52
|
@body = catch(:halt) { @response_handler.bind(@base).call || EMPTY_STRING }
|
55
53
|
|
56
54
|
# TODO any real reason not to run afters with SSE?
|
57
55
|
case @body
|
58
56
|
when HALT_STRUCT
|
59
|
-
if @body.body != :sse
|
60
|
-
@base.after
|
61
|
-
end
|
57
|
+
@base.filter :after if @body.body != :sse
|
62
58
|
else
|
63
|
-
@base.
|
59
|
+
@base.filter :after
|
64
60
|
end
|
65
61
|
|
66
62
|
respond
|
data/lib/angelo/version.rb
CHANGED
@@ -4,30 +4,70 @@ describe Angelo::Responder::Eventsource do
|
|
4
4
|
|
5
5
|
describe 'route builder' do
|
6
6
|
|
7
|
-
|
7
|
+
describe 'basics' do
|
8
|
+
|
9
|
+
define_app do
|
10
|
+
|
11
|
+
eventsource '/msg' do |c|
|
12
|
+
c.write sse_message 'hi'
|
13
|
+
c.close
|
14
|
+
end
|
15
|
+
|
16
|
+
eventsource '/event' do |c|
|
17
|
+
c.write sse_event :sse, 'bye'
|
18
|
+
c.close
|
19
|
+
end
|
20
|
+
|
21
|
+
eventsource '/headers', foo: 'bar' do |c|
|
22
|
+
c.write sse_event :sse, 'headers'
|
23
|
+
c.close
|
24
|
+
end
|
8
25
|
|
9
|
-
eventsource '/msg' do |c|
|
10
|
-
c.write sse_message 'hi'
|
11
|
-
c.close
|
12
26
|
end
|
13
27
|
|
14
|
-
|
15
|
-
|
16
|
-
|
28
|
+
it 'sends messages' do
|
29
|
+
get_sse '/msg' do |msg|
|
30
|
+
msg.must_equal "data: hi\n\n"
|
31
|
+
end
|
17
32
|
end
|
18
33
|
|
19
|
-
|
34
|
+
it 'sends events' do
|
35
|
+
get_sse '/event' do |msg|
|
36
|
+
msg.must_equal "event: sse\ndata: bye\n\n"
|
37
|
+
end
|
38
|
+
end
|
20
39
|
|
21
|
-
|
22
|
-
|
23
|
-
|
40
|
+
it 'accepts extra headers hash as second optional parameter' do
|
41
|
+
get_sse '/headers' do |msg|
|
42
|
+
msg.must_equal "event: sse\ndata: headers\n\n"
|
43
|
+
end
|
44
|
+
last_response.headers['Foo'].must_equal 'bar'
|
24
45
|
end
|
46
|
+
|
25
47
|
end
|
26
48
|
|
27
|
-
|
28
|
-
|
29
|
-
|
49
|
+
describe 'error handling' do
|
50
|
+
|
51
|
+
define_app do
|
52
|
+
|
53
|
+
before do
|
54
|
+
raise 'wrong'
|
55
|
+
end
|
56
|
+
|
57
|
+
eventsource '/msg' do |c|
|
58
|
+
c.write sse_message 'hi'
|
59
|
+
c.close
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'handles exceptions in before blocks' do
|
65
|
+
get_sse '/msg' do |msg|
|
66
|
+
msg.must_equal "wrong"
|
67
|
+
end
|
68
|
+
last_response.status.must_equal 500
|
30
69
|
end
|
70
|
+
|
31
71
|
end
|
32
72
|
|
33
73
|
end
|
@@ -52,6 +92,14 @@ describe 'eventsource helper' do
|
|
52
92
|
end
|
53
93
|
end
|
54
94
|
|
95
|
+
get '/headers' do
|
96
|
+
headers foo: 'bar'
|
97
|
+
eventsource do |c|
|
98
|
+
c.write sse_event :sse, 'headers'
|
99
|
+
c.close
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
55
103
|
end
|
56
104
|
|
57
105
|
it 'sends messages' do
|
@@ -66,4 +114,11 @@ describe 'eventsource helper' do
|
|
66
114
|
end
|
67
115
|
end
|
68
116
|
|
117
|
+
it 'allows headers to be set outside block' do
|
118
|
+
get_sse '/headers' do |msg|
|
119
|
+
msg.must_equal "event: sse\ndata: headers\n\n"
|
120
|
+
end
|
121
|
+
last_response.headers['Foo'].must_equal 'bar'
|
122
|
+
end
|
123
|
+
|
69
124
|
end
|
@@ -0,0 +1,294 @@
|
|
1
|
+
require_relative '../spec_helper.rb'
|
2
|
+
|
3
|
+
describe Angelo::Base do
|
4
|
+
|
5
|
+
describe 'before filter' do
|
6
|
+
|
7
|
+
describe 'single default' do
|
8
|
+
|
9
|
+
define_app do
|
10
|
+
|
11
|
+
before do
|
12
|
+
@set_by_before = params
|
13
|
+
end
|
14
|
+
|
15
|
+
[:get, :post, :put].each do |m|
|
16
|
+
__send__ m, '/before' do
|
17
|
+
content_type :json
|
18
|
+
@set_by_before
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'runs before filters before routes' do
|
25
|
+
|
26
|
+
get '/before', obj
|
27
|
+
last_response_must_be_json obj_s
|
28
|
+
|
29
|
+
[:post, :put].each do |m|
|
30
|
+
__send__ m, '/before', obj.to_json, {Angelo::CONTENT_TYPE_HEADER_KEY => Angelo::JSON_TYPE}
|
31
|
+
last_response_must_be_json obj
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'multiple default' do
|
39
|
+
|
40
|
+
define_app do
|
41
|
+
|
42
|
+
before do
|
43
|
+
@foo = params[:foo]
|
44
|
+
end
|
45
|
+
|
46
|
+
before do
|
47
|
+
@bar = params[:bar] if @foo
|
48
|
+
end
|
49
|
+
|
50
|
+
before do
|
51
|
+
@bat = params[:bat] if @bar
|
52
|
+
end
|
53
|
+
|
54
|
+
[:get, :post, :put].each do |m|
|
55
|
+
__send__ m, '/before' do
|
56
|
+
content_type :json
|
57
|
+
{ foo: @foo, bar: @bar, bat: @bat }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'runs before filters in order' do
|
64
|
+
|
65
|
+
get '/before', obj
|
66
|
+
last_response_must_be_json obj_s
|
67
|
+
|
68
|
+
[:post, :put].each do |m|
|
69
|
+
__send__ m, '/before', obj.to_json, {Angelo::CONTENT_TYPE_HEADER_KEY => Angelo::JSON_TYPE}
|
70
|
+
last_response_must_be_json obj
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'pathed' do
|
78
|
+
|
79
|
+
define_app do
|
80
|
+
|
81
|
+
before do
|
82
|
+
@foo = params[:foo]
|
83
|
+
end
|
84
|
+
|
85
|
+
before '/before_bar' do
|
86
|
+
@bar = params[:bar] if @foo
|
87
|
+
end
|
88
|
+
|
89
|
+
before path: '/before_bat' do
|
90
|
+
@bat = params[:bat] if @foo
|
91
|
+
end
|
92
|
+
|
93
|
+
[:get, :post, :put].each do |m|
|
94
|
+
|
95
|
+
__send__ m, '/before' do
|
96
|
+
content_type :json
|
97
|
+
{ foo: @foo, bar: @bar, bat: @bat }.select! {|k,v| !v.nil?}
|
98
|
+
end
|
99
|
+
|
100
|
+
__send__ m, '/before_bar' do
|
101
|
+
content_type :json
|
102
|
+
{ foo: @foo, bar: @bar, bat: @bat }.select! {|k,v| !v.nil?}
|
103
|
+
end
|
104
|
+
|
105
|
+
__send__ m, '/before_bat' do
|
106
|
+
content_type :json
|
107
|
+
{ foo: @foo, bar: @bar, bat: @bat }.select! {|k,v| !v.nil?}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'runs default before filter for all paths' do
|
114
|
+
|
115
|
+
get '/before', obj
|
116
|
+
last_response_must_be_json obj_s.select {|k,v| k == 'foo'}
|
117
|
+
|
118
|
+
[:post, :put].each do |m|
|
119
|
+
__send__ m, '/before', obj.to_json, {Angelo::CONTENT_TYPE_HEADER_KEY => Angelo::JSON_TYPE}
|
120
|
+
last_response_must_be_json obj.select {|k,v| k == 'foo'}
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'runs default and specific before filters' do
|
126
|
+
|
127
|
+
get '/before_bar', obj
|
128
|
+
last_response_must_be_json obj_s.select {|k,v| ['foo','bar'].include? k}
|
129
|
+
|
130
|
+
[:post, :put].each do |m|
|
131
|
+
__send__ m, '/before_bar', obj.to_json, {Angelo::CONTENT_TYPE_HEADER_KEY => Angelo::JSON_TYPE}
|
132
|
+
last_response_must_be_json obj.select {|k,v| ['foo','bar'].include? k}
|
133
|
+
end
|
134
|
+
|
135
|
+
get '/before_bat', obj
|
136
|
+
last_response_must_be_json obj_s.select {|k,v| ['foo','bat'].include? k}
|
137
|
+
|
138
|
+
[:post, :put].each do |m|
|
139
|
+
__send__ m, '/before_bat', obj.to_json, {Angelo::CONTENT_TYPE_HEADER_KEY => Angelo::JSON_TYPE}
|
140
|
+
last_response_must_be_json obj.select {|k,v| ['foo','bat'].include? k}
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
describe 'after filter' do
|
150
|
+
|
151
|
+
describe 'single default' do
|
152
|
+
|
153
|
+
invoked = 0
|
154
|
+
|
155
|
+
define_app do
|
156
|
+
|
157
|
+
before do
|
158
|
+
invoked += 2
|
159
|
+
end
|
160
|
+
|
161
|
+
after do
|
162
|
+
invoked *= 2
|
163
|
+
end
|
164
|
+
|
165
|
+
Angelo::HTTPABLE.each do |m|
|
166
|
+
__send__ m, '/after' do
|
167
|
+
invoked.to_s
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'runs after filters after routes' do
|
174
|
+
a = %w[2 6 14 30 62]
|
175
|
+
b = [4, 12, 28, 60, 124]
|
176
|
+
|
177
|
+
Angelo::HTTPABLE.each_with_index do |m,i|
|
178
|
+
__send__ m, '/after', obj
|
179
|
+
last_response_must_be_html a[i]
|
180
|
+
invoked.must_equal b[i]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
describe 'multiple default' do
|
187
|
+
|
188
|
+
invoked = 0
|
189
|
+
|
190
|
+
define_app do
|
191
|
+
|
192
|
+
after do
|
193
|
+
invoked += 2
|
194
|
+
end
|
195
|
+
|
196
|
+
after do
|
197
|
+
invoked *= 2
|
198
|
+
end
|
199
|
+
|
200
|
+
after do
|
201
|
+
invoked -= 2
|
202
|
+
end
|
203
|
+
|
204
|
+
Angelo::HTTPABLE.each do |m|
|
205
|
+
__send__ m, '/after' do
|
206
|
+
invoked.to_s
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'runs after filters in order' do
|
213
|
+
a = %w[0 2 6 14 30]
|
214
|
+
b = [2, 6, 14, 30, 62]
|
215
|
+
|
216
|
+
Angelo::HTTPABLE.each_with_index do |m,i|
|
217
|
+
__send__ m, '/after', obj
|
218
|
+
last_response_must_be_html a[i]
|
219
|
+
invoked.must_equal b[i]
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
|
225
|
+
describe 'pathed' do
|
226
|
+
|
227
|
+
invoked = 0
|
228
|
+
|
229
|
+
define_app do
|
230
|
+
|
231
|
+
after do
|
232
|
+
invoked += 2
|
233
|
+
end
|
234
|
+
|
235
|
+
after '/after_bar' do
|
236
|
+
invoked *= 2
|
237
|
+
end
|
238
|
+
|
239
|
+
after '/after_bat' do
|
240
|
+
invoked -= 4
|
241
|
+
end
|
242
|
+
|
243
|
+
Angelo::HTTPABLE.each do |m|
|
244
|
+
__send__ m, '/after' do
|
245
|
+
invoked.to_s
|
246
|
+
end
|
247
|
+
|
248
|
+
__send__ m, '/after_bar' do
|
249
|
+
invoked.to_s
|
250
|
+
end
|
251
|
+
|
252
|
+
__send__ m, '/after_bat' do
|
253
|
+
invoked.to_s
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'runs default and specific after filters' do
|
260
|
+
|
261
|
+
a = %w[0 2 4 6 8]
|
262
|
+
b = [2, 4, 6, 8, 10]
|
263
|
+
|
264
|
+
Angelo::HTTPABLE.each_with_index do |m,i|
|
265
|
+
__send__ m, '/after', obj
|
266
|
+
last_response_must_be_html a[i]
|
267
|
+
invoked.must_equal b[i]
|
268
|
+
end
|
269
|
+
|
270
|
+
c = %w[10 24 52 108 220]
|
271
|
+
d = [24, 52, 108, 220, 444]
|
272
|
+
|
273
|
+
Angelo::HTTPABLE.each_with_index do |m,i|
|
274
|
+
__send__ m, '/after_bar', obj
|
275
|
+
last_response_must_be_html c[i]
|
276
|
+
invoked.must_equal d[i]
|
277
|
+
end
|
278
|
+
|
279
|
+
e = %w[444 442 440 438 436]
|
280
|
+
f = [442, 440, 438, 436, 434]
|
281
|
+
|
282
|
+
Angelo::HTTPABLE.each_with_index do |m,i|
|
283
|
+
__send__ m, '/after_bat', obj
|
284
|
+
last_response_must_be_html e[i]
|
285
|
+
invoked.must_equal f[i]
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
end
|
293
|
+
|
294
|
+
end
|
@@ -94,4 +94,92 @@ HTML
|
|
94
94
|
|
95
95
|
end
|
96
96
|
|
97
|
+
describe 'filters' do
|
98
|
+
|
99
|
+
describe 'params in route blocks' do
|
100
|
+
|
101
|
+
define_app do
|
102
|
+
include Angelo::Mustermann
|
103
|
+
|
104
|
+
before '/before/:foo' do
|
105
|
+
@foo = params[:foo]
|
106
|
+
end
|
107
|
+
|
108
|
+
content_type :json
|
109
|
+
|
110
|
+
[:get, :post, :put].each do |m|
|
111
|
+
__send__ m, '/before/:bar' do
|
112
|
+
{ bar: params[:bar], foo: params[:foo], foo_from_before: @foo }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'does not infect route block params with filter pattern params' do
|
119
|
+
[:get, :post, :put].each do |m|
|
120
|
+
__send__ m, '/before/hi'
|
121
|
+
last_response_must_be_json 'bar' => 'hi', 'foo' => nil, 'foo_from_before' => 'hi'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'wildcard' do
|
128
|
+
|
129
|
+
define_app do
|
130
|
+
include Angelo::Mustermann
|
131
|
+
|
132
|
+
before do
|
133
|
+
@foo = params[:foo]
|
134
|
+
end
|
135
|
+
|
136
|
+
before path: '/before*' do
|
137
|
+
@bar = params[:bar] if @foo
|
138
|
+
@bat = params[:bat] if @foo
|
139
|
+
end
|
140
|
+
|
141
|
+
[:get, :post, :put].each do |m|
|
142
|
+
|
143
|
+
__send__ m, '/before' do
|
144
|
+
content_type :json
|
145
|
+
{ foo: @foo, bar: @bar, bat: @bat }.select {|k,v| !v.nil?}
|
146
|
+
end
|
147
|
+
|
148
|
+
__send__ m, '/before_bar' do
|
149
|
+
content_type :json
|
150
|
+
{ foo: @foo, bar: @bar, bat: @bat }.select {|k,v| !v.nil?}
|
151
|
+
end
|
152
|
+
|
153
|
+
__send__ m, '/before_bat' do
|
154
|
+
content_type :json
|
155
|
+
{ foo: @foo, bar: @bar, bat: @bat }.select {|k,v| !v.nil?}
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'runs wildcarded before filters' do
|
162
|
+
|
163
|
+
get '/before_bar', obj
|
164
|
+
last_response_must_be_json obj_s
|
165
|
+
|
166
|
+
[:post, :put].each do |m|
|
167
|
+
__send__ m, '/before_bar', obj.to_json, {Angelo::CONTENT_TYPE_HEADER_KEY => Angelo::JSON_TYPE}
|
168
|
+
last_response_must_be_json obj
|
169
|
+
end
|
170
|
+
|
171
|
+
get '/before_bat', obj
|
172
|
+
last_response_must_be_json obj_s
|
173
|
+
|
174
|
+
[:post, :put].each do |m|
|
175
|
+
__send__ m, '/before_bat', obj.to_json, {Angelo::CONTENT_TYPE_HEADER_KEY => Angelo::JSON_TYPE}
|
176
|
+
last_response_must_be_json obj
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
97
185
|
end
|
@@ -194,7 +194,7 @@ describe Angelo::Responder::Websocket do
|
|
194
194
|
Angelo::HTTPABLE.each do |m|
|
195
195
|
__send__ m, '/concur' do
|
196
196
|
websockets.each do |ws|
|
197
|
-
msg = "from #{params
|
197
|
+
msg = "from #{params[:foo]} #{m.to_s}"
|
198
198
|
ws.write msg
|
199
199
|
end
|
200
200
|
''
|
@@ -216,7 +216,7 @@ describe Angelo::Responder::Websocket do
|
|
216
216
|
}
|
217
217
|
|
218
218
|
websocket_wait_for '/concur', latch, expectation do
|
219
|
-
Angelo::HTTPABLE.each {|m| __send__ m, '/concur
|
219
|
+
Angelo::HTTPABLE.each {|m| __send__ m, '/concur?foo=http'}
|
220
220
|
latch.wait
|
221
221
|
end
|
222
222
|
|
data/test/angelo_spec.rb
CHANGED
@@ -2,14 +2,6 @@ require_relative './spec_helper'
|
|
2
2
|
|
3
3
|
describe Angelo::Base do
|
4
4
|
|
5
|
-
def obj
|
6
|
-
{'foo' => 'bar', 'bar' => 123.4567890123456, 'bat' => true}
|
7
|
-
end
|
8
|
-
|
9
|
-
def obj_s
|
10
|
-
obj.keys.reduce({}){|h,k| h[k] = obj[k].to_s; h}
|
11
|
-
end
|
12
|
-
|
13
5
|
describe 'the basics' do
|
14
6
|
|
15
7
|
define_app do
|
@@ -108,72 +100,6 @@ describe Angelo::Base do
|
|
108
100
|
|
109
101
|
end
|
110
102
|
|
111
|
-
describe 'before filter' do
|
112
|
-
|
113
|
-
define_app do
|
114
|
-
|
115
|
-
before do
|
116
|
-
@set_by_before = params
|
117
|
-
end
|
118
|
-
|
119
|
-
[:get, :post, :put].each do |m|
|
120
|
-
__send__ m, '/before' do
|
121
|
-
content_type :json
|
122
|
-
@set_by_before
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
it 'runs before filters before routes' do
|
129
|
-
|
130
|
-
get '/before', obj
|
131
|
-
last_response_must_be_json obj_s
|
132
|
-
|
133
|
-
[:post, :put].each do |m|
|
134
|
-
__send__ m, '/before', obj.to_json, {Angelo::CONTENT_TYPE_HEADER_KEY => Angelo::JSON_TYPE}
|
135
|
-
last_response_must_be_json obj
|
136
|
-
end
|
137
|
-
|
138
|
-
end
|
139
|
-
|
140
|
-
end
|
141
|
-
|
142
|
-
describe 'after filter' do
|
143
|
-
|
144
|
-
invoked = 0
|
145
|
-
|
146
|
-
define_app do
|
147
|
-
|
148
|
-
before do
|
149
|
-
invoked += 2
|
150
|
-
end
|
151
|
-
|
152
|
-
after do
|
153
|
-
invoked *= 2
|
154
|
-
end
|
155
|
-
|
156
|
-
Angelo::HTTPABLE.each do |m|
|
157
|
-
__send__ m, '/after' do
|
158
|
-
invoked.to_s
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'runs after filters after routes' do
|
165
|
-
a = %w[2 6 14 30 62]
|
166
|
-
b = [4, 12, 28, 60, 124]
|
167
|
-
|
168
|
-
Angelo::HTTPABLE.each_with_index do |m,i|
|
169
|
-
__send__ m, '/after', obj
|
170
|
-
last_response_must_be_html a[i]
|
171
|
-
invoked.must_equal b[i]
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
end
|
176
|
-
|
177
103
|
describe 'headers helper' do
|
178
104
|
|
179
105
|
headers_count = 0
|
@@ -385,7 +311,7 @@ describe Angelo::Base do
|
|
385
311
|
|
386
312
|
define_app do
|
387
313
|
|
388
|
-
|
314
|
+
Angelo::HTTPABLE.each do |m|
|
389
315
|
__send__ m, '/json' do
|
390
316
|
content_type :json
|
391
317
|
params
|
@@ -409,6 +335,13 @@ describe Angelo::Base do
|
|
409
335
|
last_response_must_be_json({})
|
410
336
|
end
|
411
337
|
|
338
|
+
(Angelo::HTTPABLE - [:post, :put]).each do |m|
|
339
|
+
it "returns a populated hash for #{m.to_s.upcase} requests" do
|
340
|
+
send m, '/json?foo=bar'
|
341
|
+
last_response_must_be_json('foo' => 'bar')
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
412
345
|
end
|
413
346
|
|
414
347
|
describe 'request_headers helper' do
|
data/test/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: angelo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.23
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenichi Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: reel
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- test/angelo/erb_spec.rb
|
70
70
|
- test/angelo/error_spec.rb
|
71
71
|
- test/angelo/eventsource_spec.rb
|
72
|
+
- test/angelo/filter_spec.rb
|
72
73
|
- test/angelo/mustermann_spec.rb
|
73
74
|
- test/angelo/params_spec.rb
|
74
75
|
- test/angelo/static_spec.rb
|