metybur 0.3.0 → 0.3.1

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
2
  SHA1:
3
- metadata.gz: f69ccd216fe6e46fe9472a0975e31de3c15a9c14
4
- data.tar.gz: 91fdac926fc0e44432c67da5e27a072e7e027ab8
3
+ metadata.gz: 864d272f4639c0789e198773313fcad042332ad5
4
+ data.tar.gz: d840163bb51fd06be5af41af567a638d8528ee53
5
5
  SHA512:
6
- metadata.gz: 020974269a114c7ed5edba2b2d8a7168931d7dd61ea81064a8a1df0a18464a564b703eb9fcae536e8d3ec1526ee2affab60cab47e1f1b7443e11cc41cdb127b2
7
- data.tar.gz: 9682e9bcd748d3aa069fab63548672a522dda50eae8dafe4beadea581641b95b095a7f35e6bae4720b176d2bea1357594eec7a818fd8ce68338d692d857d1122
6
+ metadata.gz: 5e39ffccc52cdc71c27e4f27750b86352f96f24251ca7eb49a966f00956d41b3a0ecdfc3f558073b63f53f8a0ca879e989f6de6ff700b9680fecc002b80b2385
7
+ data.tar.gz: 441ecdfcbd89231ccea2b0c608b2a354c73c15bbb1ef2beadcf949844bfdb0cafd1f1678c5290b9f29dd600c4fa08ff953a32b6469f7e274443562c09b279c08
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Metybur
2
2
  [![Build Status](https://travis-ci.org/clemenshelm/metybur.svg?branch=master)](https://travis-ci.org/clemenshelm/metybur)
3
+ [![Gem Version](https://badge.fury.io/rb/metybur.svg)](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 days 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
+ > 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
  >
@@ -9,8 +9,7 @@ class Metybur::Collection
9
9
  end
10
10
 
11
11
  def on(event, &block)
12
- @callbacks[event] ||= []
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
- @callbacks[event].each { |callback| callback.call(*arguments) }
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,13 @@
1
+ class Metybur::JSONMiddleware
2
+ def open(event)
3
+ event
4
+ end
5
+
6
+ def message(event)
7
+ JSON.parse(event.data, symbolize_names: true)
8
+ end
9
+
10
+ def close(event)
11
+ event
12
+ end
13
+ 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
@@ -1,3 +1,3 @@
1
1
  module Metybur
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
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
- logger = Logger.new(CONFIG[:log_stream])
19
- logger.level = CONFIG[:log_level]
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
- logger.debug 'connection open'
27
+ middleware.inject(event) { |e, mw| mw.open(e) }
22
28
  end
23
- websocket.on(:message) do |message|
24
- logger.debug "received message #{message.data}"
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
- logger.debug "connection closed (code #{event.code}). #{event.reason}"
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
- it 'responds with pong to a ping' do
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
- it 'gets notified when a record is added' do
154
- collection = FFaker::Internet.user_name
155
- id = FFaker::Guid.guid
156
- fields = {city: FFaker::Address.city}
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 = Metybur.connect(url)
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.0
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-05-12 00:00:00.000000000 Z
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.2.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.