angelo 0.1.22 → 0.1.23
Sign up to get free protection for your applications and to get access to all the features.
- 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
|