metybur 0.3.0 → 0.3.1
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/README.md +2 -1
- data/lib/metybur/collection.rb +6 -3
- data/lib/metybur/middleware/json_middleware.rb +13 -0
- data/lib/metybur/middleware/logging_middleware.rb +21 -0
- data/lib/metybur/middleware/ping_pong_middleware.rb +22 -0
- data/lib/metybur/version.rb +1 -1
- data/lib/metybur.rb +12 -15
- data/spec/metybur_spec.rb +25 -46
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 864d272f4639c0789e198773313fcad042332ad5
|
4
|
+
data.tar.gz: d840163bb51fd06be5af41af567a638d8528ee53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e39ffccc52cdc71c27e4f27750b86352f96f24251ca7eb49a966f00956d41b3a0ecdfc3f558073b63f53f8a0ca879e989f6de6ff700b9680fecc002b80b2385
|
7
|
+
data.tar.gz: 441ecdfcbd89231ccea2b0c608b2a354c73c15bbb1ef2beadcf949844bfdb0cafd1f1678c5290b9f29dd600c4fa08ff953a32b6469f7e274443562c09b279c08
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Metybur
|
2
2
|
[](https://travis-ci.org/clemenshelm/metybur)
|
3
|
+
[](http://badge.fury.io/rb/metybur)
|
3
4
|
|
4
5
|
A DDP client for Ruby to connect to Meteor apps.
|
5
6
|
|
@@ -9,7 +10,7 @@ You can also call Meteor methods from Ruby.
|
|
9
10
|
|
10
11
|
> ## Caution!
|
11
12
|
>
|
12
|
-
> This gem is just a few
|
13
|
+
> This gem is just a few weeks old so far and doesn't include basic features like proper error handling. Also only a subset of the DDP protocol is implemented so far. Everything described in this README should work, though.
|
13
14
|
>
|
14
15
|
> I'll keep working on it constantly, so I suppose there will be a complete and stable version soon. Stay tuned!
|
15
16
|
>
|
data/lib/metybur/collection.rb
CHANGED
@@ -9,8 +9,7 @@ class Metybur::Collection
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def on(event, &block)
|
12
|
-
|
13
|
-
@callbacks[event] << block
|
12
|
+
callback_for(event: event) << block
|
14
13
|
self
|
15
14
|
end
|
16
15
|
|
@@ -19,6 +18,10 @@ class Metybur::Collection
|
|
19
18
|
def handle_message(attributes)
|
20
19
|
event = attributes[:msg].to_sym
|
21
20
|
arguments = attributes.slice(:id, :fields, :cleared).values
|
22
|
-
|
21
|
+
callback_for(event: event).each { |callback| callback.call(*arguments) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def callback_for(event:)
|
25
|
+
@callbacks[event] ||= []
|
23
26
|
end
|
24
27
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Metybur::LoggingMiddleware
|
2
|
+
def initialize
|
3
|
+
@logger = Logger.new(Metybur::CONFIG[:log_stream])
|
4
|
+
@logger.level = Metybur::CONFIG[:log_level]
|
5
|
+
end
|
6
|
+
|
7
|
+
def open(event)
|
8
|
+
@logger.debug 'connection open'
|
9
|
+
event
|
10
|
+
end
|
11
|
+
|
12
|
+
def message(event)
|
13
|
+
@logger.debug "received message #{event.data}"
|
14
|
+
event
|
15
|
+
end
|
16
|
+
|
17
|
+
def close(event)
|
18
|
+
@logger.debug "connection closed (code #{event.code}). #{event.reason}"
|
19
|
+
event
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Metybur::PingPongMiddleware
|
2
|
+
def initialize(websocket)
|
3
|
+
# TODO: This dependency is dowdy. Get rid of it.
|
4
|
+
@websocket = websocket
|
5
|
+
end
|
6
|
+
|
7
|
+
def open(event)
|
8
|
+
event
|
9
|
+
end
|
10
|
+
|
11
|
+
def message(message)
|
12
|
+
return message unless message[:msg] == 'ping'
|
13
|
+
pong = {msg: 'pong'}
|
14
|
+
pong[:id] = message[:id] if message[:id]
|
15
|
+
@websocket.send(pong.to_json)
|
16
|
+
message
|
17
|
+
end
|
18
|
+
|
19
|
+
def close(event)
|
20
|
+
event
|
21
|
+
end
|
22
|
+
end
|
data/lib/metybur/version.rb
CHANGED
data/lib/metybur.rb
CHANGED
@@ -3,6 +3,9 @@ require 'faye/websocket'
|
|
3
3
|
require 'json'
|
4
4
|
require 'logger'
|
5
5
|
require_relative 'metybur/client'
|
6
|
+
require_relative 'metybur/middleware/logging_middleware'
|
7
|
+
require_relative 'metybur/middleware/json_middleware'
|
8
|
+
require_relative 'metybur/middleware/ping_pong_middleware'
|
6
9
|
|
7
10
|
module Metybur
|
8
11
|
CONFIG = {
|
@@ -15,28 +18,22 @@ module Metybur
|
|
15
18
|
websocket = CONFIG[:websocket_client_class].new(url)
|
16
19
|
client = Metybur::Client.new(websocket)
|
17
20
|
|
18
|
-
|
19
|
-
|
21
|
+
logging_middleware = Metybur::LoggingMiddleware.new
|
22
|
+
json_middleware = Metybur::JSONMiddleware.new
|
23
|
+
ping_pong_middleware = Metybur::PingPongMiddleware.new(websocket)
|
24
|
+
middleware = [logging_middleware, json_middleware, ping_pong_middleware]
|
25
|
+
|
20
26
|
websocket.on(:open) do |event|
|
21
|
-
|
27
|
+
middleware.inject(event) { |e, mw| mw.open(e) }
|
22
28
|
end
|
23
|
-
websocket.on(:message) do |
|
24
|
-
|
29
|
+
websocket.on(:message) do |event|
|
30
|
+
middleware.inject(event) { |e, mw| mw.message(e) }
|
25
31
|
end
|
26
32
|
websocket.on(:close) do |event|
|
27
|
-
|
33
|
+
middleware.inject(event) { |e, mw| mw.close(e) }
|
28
34
|
EM.stop_event_loop
|
29
35
|
end
|
30
36
|
|
31
|
-
websocket.on(:message) do |event|
|
32
|
-
message = JSON.parse(event.data, symbolize_names: true)
|
33
|
-
if message[:msg] == 'ping'
|
34
|
-
pong = {msg: 'pong'}
|
35
|
-
pong[:id] = message[:id] if message[:id]
|
36
|
-
websocket.send(pong.to_json)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
37
|
connect_message = {
|
41
38
|
msg: 'connect',
|
42
39
|
version: '1',
|
data/spec/metybur_spec.rb
CHANGED
@@ -86,17 +86,17 @@ describe Metybur do
|
|
86
86
|
end
|
87
87
|
|
88
88
|
context 'ping pong' do
|
89
|
-
|
89
|
+
before :each do
|
90
90
|
Metybur.connect(url)
|
91
|
+
end
|
91
92
|
|
93
|
+
it 'responds with pong to a ping' do
|
92
94
|
websocket.receive({msg: 'ping'}.to_json)
|
93
|
-
|
94
95
|
expect(last_sent_message[:msg]).to eq 'pong'
|
95
96
|
end
|
96
97
|
|
97
98
|
it 'includes the same id in the pong message' do
|
98
99
|
id = FFaker::Guid.guid
|
99
|
-
Metybur.connect(url)
|
100
100
|
|
101
101
|
websocket.receive({msg: 'ping', id: id}.to_json)
|
102
102
|
|
@@ -105,17 +105,15 @@ describe Metybur do
|
|
105
105
|
end
|
106
106
|
|
107
107
|
it "doesn't include an id if the ping message contained none" do
|
108
|
-
Metybur.connect(url)
|
109
|
-
|
110
108
|
websocket.receive({msg: 'ping'}.to_json)
|
111
|
-
|
112
109
|
expect(last_sent_message).not_to have_key :id
|
113
110
|
end
|
114
111
|
end
|
115
112
|
|
116
113
|
context 'logging' do
|
114
|
+
let(:output) { StringIO.new }
|
115
|
+
|
117
116
|
it "doesn't log any messages by default" do
|
118
|
-
output = StringIO.new
|
119
117
|
Metybur.log_stream = output
|
120
118
|
Metybur.connect(url)
|
121
119
|
|
@@ -125,7 +123,6 @@ describe Metybur do
|
|
125
123
|
end
|
126
124
|
|
127
125
|
it 'logs a message when the log level is set to debug' do
|
128
|
-
output = StringIO.new
|
129
126
|
Metybur.log_level = :debug
|
130
127
|
Metybur.log_stream = output
|
131
128
|
Metybur.connect(url)
|
@@ -150,13 +147,12 @@ describe Metybur do
|
|
150
147
|
end
|
151
148
|
|
152
149
|
context 'collections' do
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
meteor = Metybur.connect(url)
|
150
|
+
let(:collection) { FFaker::Lorem.word }
|
151
|
+
let(:id) { FFaker::Guid.guid }
|
152
|
+
let!(:meteor) { Metybur.connect(url) }
|
153
|
+
let(:fields) { {city: FFaker::Address.city} }
|
159
154
|
|
155
|
+
it 'gets notified when a record is added' do
|
160
156
|
wait_for_callback do |done|
|
161
157
|
meteor.collection(collection)
|
162
158
|
.on(:added) do |added_id, added_fields|
|
@@ -176,13 +172,8 @@ describe Metybur do
|
|
176
172
|
end
|
177
173
|
|
178
174
|
it 'gets notified when a record is changed' do
|
179
|
-
collection = FFaker::Internet.user_name
|
180
|
-
id = FFaker::Guid.guid
|
181
|
-
fields = {city: FFaker::Address.city}
|
182
175
|
cleared = [FFaker::Guid.guid]
|
183
176
|
|
184
|
-
meteor = Metybur.connect(url)
|
185
|
-
|
186
177
|
wait_for_callback do |done|
|
187
178
|
meteor.collection(collection)
|
188
179
|
.on(:changed) do |changed_id, changed_fields, cleared_fields|
|
@@ -204,11 +195,6 @@ describe Metybur do
|
|
204
195
|
end
|
205
196
|
|
206
197
|
it 'gets notified when a record is removed' do
|
207
|
-
collection = FFaker::Internet.user_name
|
208
|
-
id = FFaker::Guid.guid
|
209
|
-
|
210
|
-
meteor = Metybur.connect(url)
|
211
|
-
|
212
198
|
wait_for_callback do |done|
|
213
199
|
meteor.collection(collection)
|
214
200
|
.on(:removed) do |removed_id|
|
@@ -226,7 +212,6 @@ describe Metybur do
|
|
226
212
|
end
|
227
213
|
|
228
214
|
it 'lets the `on` method be chainable' do
|
229
|
-
meteor = Metybur.connect(url)
|
230
215
|
meteor.collection('my-collection')
|
231
216
|
.on(:added) { anything }
|
232
217
|
.on(:changed) { anything }
|
@@ -236,12 +221,6 @@ describe Metybur do
|
|
236
221
|
end
|
237
222
|
|
238
223
|
it 'registers multiple added callbacks' do
|
239
|
-
collection = FFaker::Internet.user_name
|
240
|
-
id = FFaker::Guid.guid
|
241
|
-
fields = {city: FFaker::Address.city}
|
242
|
-
|
243
|
-
meteor = Metybur.connect(url)
|
244
|
-
|
245
224
|
wait_for_callback(calls: 2) do |done|
|
246
225
|
meteor.collection(collection)
|
247
226
|
.on(:added) { |added_id, added_fields| done.call() }
|
@@ -257,8 +236,19 @@ describe Metybur do
|
|
257
236
|
end
|
258
237
|
end
|
259
238
|
|
239
|
+
it 'does nothing if there is no callback for an event' do
|
240
|
+
meteor.collection(collection)
|
241
|
+
|
242
|
+
message = {
|
243
|
+
msg: 'added',
|
244
|
+
collection: collection,
|
245
|
+
id: id,
|
246
|
+
fields: fields
|
247
|
+
}.to_json
|
248
|
+
websocket.receive message
|
249
|
+
end
|
250
|
+
|
260
251
|
it "doesn't get notified of a ping message" do
|
261
|
-
meteor = Metybur.connect(url)
|
262
252
|
meteor.collection('my-collection')
|
263
253
|
.on(:added) { fail('Callback got called') }
|
264
254
|
|
@@ -266,7 +256,6 @@ describe Metybur do
|
|
266
256
|
end
|
267
257
|
|
268
258
|
it "doesn't get notified of a record from another collection" do
|
269
|
-
meteor = Metybur.connect(url)
|
270
259
|
meteor.collection('my-collection')
|
271
260
|
.on(:added) { fail('Callback got called') }
|
272
261
|
|
@@ -281,6 +270,8 @@ describe Metybur do
|
|
281
270
|
end
|
282
271
|
|
283
272
|
context 'methods' do
|
273
|
+
let!(:meteor) { Metybur.connect(url) }
|
274
|
+
|
284
275
|
it 'calls a method through the call method' do
|
285
276
|
method = %w(postChatMessage sendEmail submitOrder).sample
|
286
277
|
params = %w(35 Vienna true).sample(2)
|
@@ -288,7 +279,6 @@ describe Metybur do
|
|
288
279
|
.to_a.sample(2)
|
289
280
|
params << Hash[hashParams]
|
290
281
|
|
291
|
-
meteor = Metybur.connect(url)
|
292
282
|
meteor.call(method, params)
|
293
283
|
|
294
284
|
expect(last_sent_message[:msg]).to eq 'method'
|
@@ -298,7 +288,6 @@ describe Metybur do
|
|
298
288
|
end
|
299
289
|
|
300
290
|
it 'calls a method called on the client directly' do
|
301
|
-
meteor = Metybur.connect(url)
|
302
291
|
meteor.activate('user', id: 'utrtrvlc')
|
303
292
|
|
304
293
|
expect(last_sent_message[:msg]).to eq 'method'
|
@@ -308,7 +297,6 @@ describe Metybur do
|
|
308
297
|
end
|
309
298
|
|
310
299
|
it 'camel-cases methods and parameters called on the client directly' do
|
311
|
-
meteor = Metybur.connect(url)
|
312
300
|
meteor.activate_user('Hans', user_id: 'utrtrvlc', is_admin: false)
|
313
301
|
|
314
302
|
expect(last_sent_message[:msg]).to eq 'method'
|
@@ -318,7 +306,6 @@ describe Metybur do
|
|
318
306
|
end
|
319
307
|
|
320
308
|
it 'passes the result to a block' do
|
321
|
-
meteor = Metybur.connect(url)
|
322
309
|
expectation = proc { |result| expect(result[:price]).to eq 99 }
|
323
310
|
|
324
311
|
wait_for_callback do |done|
|
@@ -337,17 +324,11 @@ describe Metybur do
|
|
337
324
|
end
|
338
325
|
|
339
326
|
it "doesn't trigger the callback for ping messages" do
|
340
|
-
meteor
|
341
|
-
|
342
|
-
meteor.get_product(27) do
|
343
|
-
fail
|
344
|
-
end
|
345
|
-
|
327
|
+
meteor.get_product(27) { fail }
|
346
328
|
websocket.receive({msg: 'ping'}.to_json)
|
347
329
|
end
|
348
330
|
|
349
331
|
it 'triggers the callback with the right result' do
|
350
|
-
meteor = Metybur.connect(url)
|
351
332
|
expectation = proc { |result| expect(result[:price]).to eq 99 }
|
352
333
|
|
353
334
|
wait_for_callback do |done|
|
@@ -371,7 +352,6 @@ describe Metybur do
|
|
371
352
|
end
|
372
353
|
|
373
354
|
it 'raises an error if an exception occurs in the method' do
|
374
|
-
meteor = Metybur.connect(url)
|
375
355
|
error = FFaker::Lorem.word
|
376
356
|
reason = FFaker::Lorem.sentence
|
377
357
|
details = FFaker::Lorem.paragraph
|
@@ -402,7 +382,6 @@ describe Metybur do
|
|
402
382
|
end
|
403
383
|
|
404
384
|
it 'raises an error if an exception occurs in the method' do
|
405
|
-
meteor = Metybur.connect(url)
|
406
385
|
error = FFaker::Lorem.word
|
407
386
|
reason = FFaker::Lorem.sentence
|
408
387
|
details = FFaker::Lorem.paragraph
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metybur
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Clemens Helm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faye-websocket
|
@@ -129,6 +129,9 @@ files:
|
|
129
129
|
- lib/metybur/client.rb
|
130
130
|
- lib/metybur/collection.rb
|
131
131
|
- lib/metybur/method.rb
|
132
|
+
- lib/metybur/middleware/json_middleware.rb
|
133
|
+
- lib/metybur/middleware/logging_middleware.rb
|
134
|
+
- lib/metybur/middleware/ping_pong_middleware.rb
|
132
135
|
- lib/metybur/version.rb
|
133
136
|
- metybur.gemspec
|
134
137
|
- spec/metybur_spec.rb
|
@@ -154,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
157
|
version: '0'
|
155
158
|
requirements: []
|
156
159
|
rubyforge_project:
|
157
|
-
rubygems_version: 2.
|
160
|
+
rubygems_version: 2.4.5
|
158
161
|
signing_key:
|
159
162
|
specification_version: 4
|
160
163
|
summary: DDP client for Ruby to connect to Meteor apps.
|