metybur 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8193384592b340b1a3f5fe89ca5c17df23dbabe
4
- data.tar.gz: 7ef7c3b8a4eeb9f66ce756a7f7b3dc19e4293f3b
3
+ metadata.gz: 6cd1e4839ca1350e3e953be00f1428c1fbf31b84
4
+ data.tar.gz: e344a1a7e9537edd9eeb1f925518880b9f431e17
5
5
  SHA512:
6
- metadata.gz: 053934c755a3801efb5f502991f73c50335ccd148525c761eef46f007527226c384f9604e69e0b37c181d2e44da7558dce0ae5b2f8a9e826ce7e5a22ac3114d0
7
- data.tar.gz: ac70963429fdf3b0136f409508246f5e18f9130fb821b4bbfde614082db19365f4011b11fcf3037944f7564b51625650a784ec09d1d0d2e15efbfa15ef4df8f8
6
+ metadata.gz: 863a4003723aade726d6a753a15dacb6d5666f7dd5b5453048ed8eb9557f48dfb940d530431d3cc38e358de4fcdd3fd73793bb4f1af8264e85919d12409e062e
7
+ data.tar.gz: dd9b0fa2281be1a3441d6069c408b1b896e665dd93f5c3c57114ed9ce9fd2756295361cf7afccba14d299e4a019772bfaccbe1c336951ca7f545f535d7c59ca4
data/README.md CHANGED
@@ -137,6 +137,24 @@ meteor.call('postChatMessage', inRoom: 'General')
137
137
 
138
138
  Note that you have to choose this syntax, if your Meteor method name collides with a Metybur method (like `collection` or `subscribe`).
139
139
 
140
+ #### Results
141
+
142
+ Since methods are executed asynchronously, they won't return a result immediately:
143
+
144
+ ```ruby
145
+ # Doesn't work!
146
+ messages = meteor.chat_messages(in_room: 'General')
147
+ messages.each { |message| puts message }
148
+ ```
149
+
150
+ Instead, pass a block to the method. The block will get called once the result arrives.
151
+
152
+ ```ruby
153
+ meteor.chat_messages(in_room: 'General') do |messages|
154
+ messages.each { |message| puts message }
155
+ end
156
+ ```
157
+
140
158
  ### Logging
141
159
 
142
160
  To debug your application, you can lower the log level to see all incoming websocket messages.
@@ -1,5 +1,6 @@
1
1
  require 'active_support/inflector'
2
2
  require_relative 'collection'
3
+ require_relative 'method'
3
4
 
4
5
  class Metybur::Client
5
6
  def initialize(websocket)
@@ -19,17 +20,15 @@ class Metybur::Client
19
20
  Metybur::Collection.new(name, @websocket)
20
21
  end
21
22
 
22
- def call(method, params)
23
- message = {
24
- msg: 'method',
25
- id: 'efg',
26
- method: method,
27
- params: params
28
- }.to_json
29
- @websocket.send message
23
+ def method(name)
24
+ Metybur::Method.new(name, @websocket)
25
+ end
26
+
27
+ def call(method_name, params, &block)
28
+ method(method_name).call(params, &block)
30
29
  end
31
30
 
32
- def method_missing(method, *params)
31
+ def method_missing(method, *params, &block)
33
32
  method = method.to_s.camelize(:lower)
34
33
  params.map! do |param|
35
34
  case param
@@ -40,6 +39,6 @@ class Metybur::Client
40
39
  param
41
40
  end
42
41
  end
43
- call(method, params)
42
+ call(method, params, &block)
44
43
  end
45
44
  end
@@ -0,0 +1,33 @@
1
+ class Metybur::Method
2
+ def initialize(name, websocket)
3
+ require 'securerandom'
4
+
5
+ @name = name
6
+ @websocket = websocket
7
+ @callbacks = {}
8
+
9
+ @websocket.on(:message) do |event|
10
+ attributes = JSON.parse(event.data, symbolize_names: true)
11
+ handle_message(attributes) if attributes[:msg] == 'result'
12
+ end
13
+ end
14
+
15
+ def call(params, &block)
16
+ id = SecureRandom.uuid
17
+ message = {
18
+ msg: 'method',
19
+ id: id,
20
+ method: @name,
21
+ params: params
22
+ }.to_json
23
+ @websocket.send message
24
+ @callbacks[id] = block
25
+ end
26
+
27
+ private
28
+
29
+ def handle_message(attributes)
30
+ id = attributes[:id]
31
+ @callbacks[id].call attributes[:result] if @callbacks[id]
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module Metybur
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/metybur.rb CHANGED
@@ -31,7 +31,9 @@ module Metybur
31
31
  websocket.on(:message) do |event|
32
32
  message = JSON.parse(event.data, symbolize_names: true)
33
33
  if message[:msg] == 'ping'
34
- websocket.send({msg: 'pong'}.to_json)
34
+ pong = {msg: 'pong'}
35
+ pong[:id] = message[:id] if message[:id]
36
+ websocket.send(pong.to_json)
35
37
  end
36
38
  end
37
39
 
data/spec/metybur_spec.rb CHANGED
@@ -16,8 +16,16 @@ describe Metybur do
16
16
  JSON.parse(string_data, symbolize_names: true)
17
17
  end
18
18
 
19
+ def wait_for_callback(options = {})
20
+ calls = options[:calls] || 1 # No keyword arguments in Ruby 1.9.3
21
+ times_called = 0
22
+ done = -> { times_called += 1 }
23
+ yield done
24
+ fail("Callback only got called #{times_called} time(s).") if times_called < calls
25
+ end
26
+
19
27
  it 'connects to a Meteor URL' do
20
- Metybur.connect url
28
+ Metybur.connect(url)
21
29
 
22
30
  expect(websocket.url).to eq url
23
31
  connect_message = parse(websocket.sent.first)
@@ -32,7 +40,7 @@ describe Metybur do
32
40
  email = FFaker::Internet.email
33
41
  password = FFaker::Internet.password
34
42
 
35
- Metybur.connect url, email: email, password: password
43
+ Metybur.connect(url, email: email, password: password)
36
44
 
37
45
  expect(last_sent_message[:msg]).to eq 'method'
38
46
  expect(last_sent_message).to have_key :id # we don't care about the value here
@@ -46,7 +54,7 @@ describe Metybur do
46
54
  username = FFaker::Internet.user_name
47
55
  password = FFaker::Internet.password
48
56
 
49
- Metybur.connect url, username: username, password: password
57
+ Metybur.connect(url, username: username, password: password)
50
58
 
51
59
  expect(last_sent_message[:msg]).to eq 'method'
52
60
  expect(last_sent_message).to have_key :id # we don't care about the value here
@@ -60,7 +68,7 @@ describe Metybur do
60
68
  userid = FFaker::Guid.guid
61
69
  password = FFaker::Internet.password
62
70
 
63
- Metybur.connect url, id: userid, password: password
71
+ Metybur.connect(url, id: userid, password: password)
64
72
 
65
73
  expect(last_sent_message[:msg]).to eq 'method'
66
74
  expect(last_sent_message).to have_key :id # we don't care about the value here
@@ -71,7 +79,7 @@ describe Metybur do
71
79
  end
72
80
 
73
81
  it "doesn't log in without credentials" do
74
- Metybur.connect url
82
+ Metybur.connect(url)
75
83
 
76
84
  expect(last_sent_message[:msg]).to eq 'connect'
77
85
  end
@@ -79,20 +87,37 @@ describe Metybur do
79
87
 
80
88
  context 'ping pong' do
81
89
  it 'responds with pong to a ping' do
82
- Metybur.connect url
90
+ Metybur.connect(url)
83
91
 
84
92
  websocket.receive({msg: 'ping'}.to_json)
85
93
 
86
94
  expect(last_sent_message[:msg]).to eq 'pong'
87
95
  end
88
- end
89
96
 
97
+ it 'includes the same id in the pong message' do
98
+ id = FFaker::Guid.guid
99
+ Metybur.connect(url)
100
+
101
+ websocket.receive({msg: 'ping', id: id}.to_json)
102
+
103
+ expect(last_sent_message[:msg]).to eq 'pong'
104
+ expect(last_sent_message[:id]).to eq id
105
+ end
106
+
107
+ it "doesn't include an id if the ping message contained none" do
108
+ Metybur.connect(url)
109
+
110
+ websocket.receive({msg: 'ping'}.to_json)
111
+
112
+ expect(last_sent_message).not_to have_key :id
113
+ end
114
+ end
90
115
 
91
116
  context 'logging' do
92
117
  it "doesn't log any messages by default" do
93
118
  output = StringIO.new
94
119
  Metybur.log_stream = output
95
- Metybur.connect url
120
+ Metybur.connect(url)
96
121
 
97
122
  websocket.receive({msg: 'logged_message'}.to_json)
98
123
 
@@ -103,7 +128,7 @@ describe Metybur do
103
128
  output = StringIO.new
104
129
  Metybur.log_level = :debug
105
130
  Metybur.log_stream = output
106
- Metybur.connect url
131
+ Metybur.connect(url)
107
132
 
108
133
  websocket.receive({msg: 'logged_message'}.to_json)
109
134
 
@@ -115,7 +140,7 @@ describe Metybur do
115
140
  it 'subscribes to a published record set' do
116
141
  record_set = FFaker::Internet.user_name
117
142
 
118
- meteor = Metybur.connect url
143
+ meteor = Metybur.connect(url)
119
144
  meteor.subscribe(record_set)
120
145
 
121
146
  expect(last_sent_message[:msg]).to eq 'sub'
@@ -125,20 +150,12 @@ describe Metybur do
125
150
  end
126
151
 
127
152
  context 'collections' do
128
- def wait_for_callback(options = {})
129
- calls = options[:calls] || 1 # No keyword arguments in Ruby 1.9.3
130
- times_called = 0
131
- done = -> { times_called += 1 }
132
- yield done
133
- fail("Callback only got called #{times_called} time(s).") if times_called < calls
134
- end
135
-
136
153
  it 'gets notified when a record is added' do
137
154
  collection = FFaker::Internet.user_name
138
155
  id = FFaker::Guid.guid
139
156
  fields = {city: FFaker::Address.city}
140
157
 
141
- meteor = Metybur.connect url
158
+ meteor = Metybur.connect(url)
142
159
 
143
160
  wait_for_callback do |done|
144
161
  meteor.collection(collection)
@@ -164,7 +181,7 @@ describe Metybur do
164
181
  fields = {city: FFaker::Address.city}
165
182
  cleared = [FFaker::Guid.guid]
166
183
 
167
- meteor = Metybur.connect url
184
+ meteor = Metybur.connect(url)
168
185
 
169
186
  wait_for_callback do |done|
170
187
  meteor.collection(collection)
@@ -190,7 +207,7 @@ describe Metybur do
190
207
  collection = FFaker::Internet.user_name
191
208
  id = FFaker::Guid.guid
192
209
 
193
- meteor = Metybur.connect url
210
+ meteor = Metybur.connect(url)
194
211
 
195
212
  wait_for_callback do |done|
196
213
  meteor.collection(collection)
@@ -223,7 +240,7 @@ describe Metybur do
223
240
  id = FFaker::Guid.guid
224
241
  fields = {city: FFaker::Address.city}
225
242
 
226
- meteor = Metybur.connect url
243
+ meteor = Metybur.connect(url)
227
244
 
228
245
  wait_for_callback(calls: 2) do |done|
229
246
  meteor.collection(collection)
@@ -299,5 +316,56 @@ describe Metybur do
299
316
  expect(last_sent_message).to have_key :id # we don't care about the value here
300
317
  expect(last_sent_message[:params]).to eq ['Hans', {userId: 'utrtrvlc', isAdmin: false}]
301
318
  end
319
+
320
+ it 'passes the result to a block' do
321
+ meteor = Metybur.connect(url)
322
+
323
+ wait_for_callback do |done|
324
+ meteor.get_product(27) do |product|
325
+ done.call
326
+ expect(product[:price]).to eq 99
327
+ end
328
+
329
+ id = last_sent_message[:id]
330
+ websocket.receive({
331
+ msg: 'result',
332
+ id: id,
333
+ result: {price: 99}
334
+ }.to_json)
335
+ end
336
+ end
337
+
338
+ it "doesn't trigger the callback for ping messages" do
339
+ meteor = Metybur.connect(url)
340
+
341
+ meteor.get_product(27) do |product|
342
+ fail
343
+ end
344
+
345
+ websocket.receive({msg: 'ping'}.to_json)
346
+ end
347
+
348
+ it 'triggers the callback with the right result' do
349
+ meteor = Metybur.connect(url)
350
+
351
+ wait_for_callback do |done|
352
+ meteor.get_product(27) do |product|
353
+ done.call
354
+ expect(product[:price]).to eq 99
355
+ end
356
+
357
+ id = last_sent_message[:id]
358
+ websocket.receive({
359
+ msg: 'result',
360
+ id: 'abc',
361
+ result: {price: 19}
362
+ }.to_json)
363
+ websocket.receive({
364
+ msg: 'result',
365
+ id: id,
366
+ result: {price: 99}
367
+ }.to_json)
368
+ end
369
+ end
302
370
  end
303
371
  end
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.1.1
4
+ version: 0.2.0
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-08 00:00:00.000000000 Z
11
+ date: 2015-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faye-websocket
@@ -128,6 +128,7 @@ files:
128
128
  - lib/metybur.rb
129
129
  - lib/metybur/client.rb
130
130
  - lib/metybur/collection.rb
131
+ - lib/metybur/method.rb
131
132
  - lib/metybur/version.rb
132
133
  - metybur.gemspec
133
134
  - spec/metybur_spec.rb