metybur 0.0.1 → 0.1.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 +4 -4
- data/README.md +21 -2
- data/lib/metybur/collection.rb +14 -4
- data/lib/metybur/version.rb +1 -1
- data/lib/metybur.rb +1 -14
- data/spec/metybur_spec.rb +133 -53
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16de5f618ad1003be841607f85eba295cf4bb6ae
|
4
|
+
data.tar.gz: bd1dc5ca319577920cf96f22109eb61446b07b24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c9ddb24c0714374d16e2d55b92721127e65c3a7603aa78e86ae6a8148a66d870867f99ff539088558acadc836023d7be75fbf7009327c9138f7289326ef493f
|
7
|
+
data.tar.gz: 36b0c96d11d27111276dc932387987280409b72011e2a2f585ce75887da72ff44d0929977c39a1b3c5c5905c9da42a157dd0f9e8d371e50bf7a1830bfcbb0860
|
data/README.md
CHANGED
@@ -34,7 +34,7 @@ Or install it yourself as:
|
|
34
34
|
### Connecting to a Meteor app
|
35
35
|
|
36
36
|
Metybur runs in an [EventMachine](http://eventmachine.rubyforge.org/) loop.
|
37
|
-
Therefore all
|
37
|
+
Therefore all your code must be wrapped in an `EM.run` block.
|
38
38
|
|
39
39
|
```ruby
|
40
40
|
require 'eventmachine'
|
@@ -93,6 +93,23 @@ Once you've subscribed, you will receive all records that are already in the rec
|
|
93
93
|
@chat_messages = {}
|
94
94
|
meteor.collection('chat-messages')
|
95
95
|
.on(:added) { |id, attributes| @chat_messages[id] = attributes }
|
96
|
+
.on(:changed) { |id, attributes, cleared|
|
97
|
+
chat_message = @chat_messages[id]
|
98
|
+
chat_message.merge!(attributes)
|
99
|
+
cleared.each { |field| chat_message.delete(field) }
|
100
|
+
}
|
101
|
+
.on(:removed) { |id| @chat_messages.delete(id) }
|
102
|
+
```
|
103
|
+
|
104
|
+
You can also assign multiple callbacks to one event:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
@chat_messages = {}
|
108
|
+
collection = meteor.collection('chat-messages')
|
109
|
+
|
110
|
+
collection.on(:added) { |id, attributes| @chat_messages[id] = attributes }
|
111
|
+
|
112
|
+
collection.on(:added) { |id, attributes| puts "received message #{attributes[:text]}" }
|
96
113
|
```
|
97
114
|
|
98
115
|
### Remote Procedure Calls
|
@@ -107,9 +124,11 @@ This corresponds to the following method call in Meteor:
|
|
107
124
|
|
108
125
|
```javascript
|
109
126
|
// Javascript
|
110
|
-
Meteor.call('postChatMessage', { inRoom: 'General' });
|
127
|
+
Meteor.call('postChatMessage', ['Hey there!', { inRoom: 'General' }]);
|
111
128
|
```
|
112
129
|
|
130
|
+
Methods and hash keys will be camel-cased for you, so you can stick to the Ruby naming convention.
|
131
|
+
|
113
132
|
If you prefer the Meteor syntax, you can also call the method like this:
|
114
133
|
|
115
134
|
```ruby
|
data/lib/metybur/collection.rb
CHANGED
@@ -1,14 +1,24 @@
|
|
1
1
|
class Metybur::Collection
|
2
2
|
def initialize(collection_name, websocket)
|
3
|
+
@callbacks = {}
|
4
|
+
|
3
5
|
websocket.on(:message) do |event|
|
4
6
|
attributes = JSON.parse(event.data, symbolize_names: true)
|
5
|
-
|
6
|
-
@added_callback.call(attributes[:id], attributes[:fields])
|
7
|
-
end
|
7
|
+
handle_message(attributes) if attributes[:collection] == collection_name
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
def on(event, &block)
|
12
|
-
@
|
12
|
+
@callbacks[event] ||= []
|
13
|
+
@callbacks[event] << block
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def handle_message(attributes)
|
20
|
+
event = attributes[:msg].to_sym
|
21
|
+
arguments = attributes.slice(:id, :fields, :cleared).values
|
22
|
+
@callbacks[event].each { |callback| callback.call(*arguments) }
|
13
23
|
end
|
14
24
|
end
|
data/lib/metybur/version.rb
CHANGED
data/lib/metybur.rb
CHANGED
@@ -44,20 +44,7 @@ module Metybur
|
|
44
44
|
|
45
45
|
password = credentials.delete(:password)
|
46
46
|
return client unless password
|
47
|
-
|
48
|
-
login_message = {
|
49
|
-
msg: 'method',
|
50
|
-
id: 'abc',
|
51
|
-
method: 'login',
|
52
|
-
params: [
|
53
|
-
{
|
54
|
-
user: credentials,
|
55
|
-
password: password
|
56
|
-
}
|
57
|
-
]
|
58
|
-
}
|
59
|
-
|
60
|
-
websocket.send(login_message.to_json)
|
47
|
+
client.login(user: credentials, password: password)
|
61
48
|
|
62
49
|
client
|
63
50
|
end
|
data/spec/metybur_spec.rb
CHANGED
@@ -10,6 +10,7 @@ describe Metybur do
|
|
10
10
|
|
11
11
|
let(:url) { FFaker::Internet.http_url }
|
12
12
|
let(:websocket) { WebsocketMock.instance }
|
13
|
+
let(:last_sent_message) { parse(websocket.sent.last) }
|
13
14
|
|
14
15
|
def parse(string_data)
|
15
16
|
JSON.parse(string_data, symbolize_names: true)
|
@@ -33,11 +34,10 @@ describe Metybur do
|
|
33
34
|
|
34
35
|
Metybur.connect url, email: email, password: password
|
35
36
|
|
36
|
-
|
37
|
-
expect(
|
38
|
-
expect(
|
39
|
-
expect(
|
40
|
-
expect(login_message[:params][0])
|
37
|
+
expect(last_sent_message[:msg]).to eq 'method'
|
38
|
+
expect(last_sent_message).to have_key :id # we don't care about the value here
|
39
|
+
expect(last_sent_message[:method]).to eq 'login'
|
40
|
+
expect(last_sent_message[:params][0])
|
41
41
|
.to eq user: { email: email },
|
42
42
|
password: password
|
43
43
|
end
|
@@ -48,11 +48,10 @@ describe Metybur do
|
|
48
48
|
|
49
49
|
Metybur.connect url, username: username, password: password
|
50
50
|
|
51
|
-
|
52
|
-
expect(
|
53
|
-
expect(
|
54
|
-
expect(
|
55
|
-
expect(login_message[:params][0])
|
51
|
+
expect(last_sent_message[:msg]).to eq 'method'
|
52
|
+
expect(last_sent_message).to have_key :id # we don't care about the value here
|
53
|
+
expect(last_sent_message[:method]).to eq 'login'
|
54
|
+
expect(last_sent_message[:params][0])
|
56
55
|
.to eq user: { username: username },
|
57
56
|
password: password
|
58
57
|
end
|
@@ -63,11 +62,10 @@ describe Metybur do
|
|
63
62
|
|
64
63
|
Metybur.connect url, id: userid, password: password
|
65
64
|
|
66
|
-
|
67
|
-
expect(
|
68
|
-
expect(
|
69
|
-
expect(
|
70
|
-
expect(login_message[:params][0])
|
65
|
+
expect(last_sent_message[:msg]).to eq 'method'
|
66
|
+
expect(last_sent_message).to have_key :id # we don't care about the value here
|
67
|
+
expect(last_sent_message[:method]).to eq 'login'
|
68
|
+
expect(last_sent_message[:params][0])
|
71
69
|
.to eq user: { id: userid },
|
72
70
|
password: password
|
73
71
|
end
|
@@ -75,8 +73,7 @@ describe Metybur do
|
|
75
73
|
it "doesn't log in without credentials" do
|
76
74
|
Metybur.connect url
|
77
75
|
|
78
|
-
|
79
|
-
expect(last_message[:msg]).to eq 'connect'
|
76
|
+
expect(last_sent_message[:msg]).to eq 'connect'
|
80
77
|
end
|
81
78
|
end
|
82
79
|
|
@@ -86,8 +83,7 @@ describe Metybur do
|
|
86
83
|
|
87
84
|
websocket.receive({msg: 'ping'}.to_json)
|
88
85
|
|
89
|
-
|
90
|
-
expect(last_message[:msg]).to eq 'pong'
|
86
|
+
expect(last_sent_message[:msg]).to eq 'pong'
|
91
87
|
end
|
92
88
|
end
|
93
89
|
|
@@ -122,38 +118,125 @@ describe Metybur do
|
|
122
118
|
meteor = Metybur.connect url
|
123
119
|
meteor.subscribe(record_set)
|
124
120
|
|
125
|
-
|
126
|
-
expect(
|
127
|
-
expect(
|
128
|
-
expect(last_message[:name]).to eq record_set
|
121
|
+
expect(last_sent_message[:msg]).to eq 'sub'
|
122
|
+
expect(last_sent_message).to have_key :id # we don't care about the value here
|
123
|
+
expect(last_sent_message[:name]).to eq record_set
|
129
124
|
end
|
130
125
|
end
|
131
126
|
|
132
127
|
context 'collections' do
|
128
|
+
def wait_for_callback(calls: 1)
|
129
|
+
times_called = 0
|
130
|
+
done = -> { times_called += 1 }
|
131
|
+
yield done
|
132
|
+
fail("Callback only got called #{times_called} time(s).") if times_called < calls
|
133
|
+
end
|
134
|
+
|
133
135
|
it 'gets notified when a record is added' do
|
134
136
|
collection = FFaker::Internet.user_name
|
135
|
-
|
137
|
+
id = FFaker::Guid.guid
|
138
|
+
fields = {city: FFaker::Address.city}
|
139
|
+
|
140
|
+
meteor = Metybur.connect url
|
141
|
+
|
142
|
+
wait_for_callback do |done|
|
143
|
+
meteor.collection(collection)
|
144
|
+
.on(:added) do |added_id, added_fields|
|
145
|
+
done.call()
|
146
|
+
expect(added_id).to eq id
|
147
|
+
expect(added_fields).to eq fields
|
148
|
+
end
|
149
|
+
|
150
|
+
message = {
|
151
|
+
msg: 'added',
|
152
|
+
collection: collection,
|
153
|
+
id: id,
|
154
|
+
fields: fields
|
155
|
+
}.to_json
|
156
|
+
websocket.receive message
|
157
|
+
end
|
158
|
+
end
|
136
159
|
|
160
|
+
it 'gets notified when a record is changed' do
|
161
|
+
collection = FFaker::Internet.user_name
|
137
162
|
id = FFaker::Guid.guid
|
138
163
|
fields = {city: FFaker::Address.city}
|
164
|
+
cleared = [FFaker::Guid.guid]
|
139
165
|
|
140
166
|
meteor = Metybur.connect url
|
141
|
-
meteor.collection(collection)
|
142
|
-
.on(:added) do |added_id, added_fields|
|
143
|
-
callback_called = true
|
144
|
-
expect(added_id).to eq id
|
145
|
-
expect(added_fields).to eq fields
|
146
|
-
end
|
147
167
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
168
|
+
wait_for_callback do |done|
|
169
|
+
meteor.collection(collection)
|
170
|
+
.on(:changed) do |changed_id, changed_fields, cleared_fields|
|
171
|
+
done.call()
|
172
|
+
expect(changed_id).to eq id
|
173
|
+
expect(changed_fields).to eq fields
|
174
|
+
expect(cleared_fields).to eq cleared
|
175
|
+
end
|
176
|
+
|
177
|
+
message = {
|
178
|
+
msg: 'changed',
|
179
|
+
collection: collection,
|
180
|
+
id: id,
|
181
|
+
fields: fields,
|
182
|
+
cleared: cleared
|
183
|
+
}.to_json
|
184
|
+
websocket.receive message
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'gets notified when a record is removed' do
|
189
|
+
collection = FFaker::Internet.user_name
|
190
|
+
id = FFaker::Guid.guid
|
191
|
+
|
192
|
+
meteor = Metybur.connect url
|
193
|
+
|
194
|
+
wait_for_callback do |done|
|
195
|
+
meteor.collection(collection)
|
196
|
+
.on(:removed) do |removed_id|
|
197
|
+
done.call()
|
198
|
+
expect(removed_id).to eq id
|
199
|
+
end
|
200
|
+
|
201
|
+
message = {
|
202
|
+
msg: 'removed',
|
203
|
+
collection: collection,
|
204
|
+
id: id
|
205
|
+
}.to_json
|
206
|
+
websocket.receive message
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'lets the `on` method be chainable' do
|
211
|
+
meteor = Metybur.connect(url)
|
212
|
+
meteor.collection('my-collection')
|
213
|
+
.on(:added) { anything }
|
214
|
+
.on(:changed) { anything }
|
215
|
+
.on(:removed) { anything }
|
216
|
+
|
217
|
+
# Succeeds if there is no error
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'registers multiple added callbacks' do
|
221
|
+
collection = FFaker::Internet.user_name
|
222
|
+
id = FFaker::Guid.guid
|
223
|
+
fields = {city: FFaker::Address.city}
|
224
|
+
|
225
|
+
meteor = Metybur.connect url
|
155
226
|
|
156
|
-
|
227
|
+
wait_for_callback(calls: 2) do |done|
|
228
|
+
meteor.collection(collection)
|
229
|
+
.on(:added) { |added_id, added_fields| done.call() }
|
230
|
+
.on(:added) { |added_id, added_fields| done.call() }
|
231
|
+
|
232
|
+
message = {
|
233
|
+
msg: 'added',
|
234
|
+
collection: collection,
|
235
|
+
id: id,
|
236
|
+
fields: fields
|
237
|
+
}.to_json
|
238
|
+
websocket.receive message
|
239
|
+
end
|
157
240
|
end
|
158
241
|
|
159
242
|
it "doesn't get notified of a ping message" do
|
@@ -190,33 +273,30 @@ describe Metybur do
|
|
190
273
|
meteor = Metybur.connect(url)
|
191
274
|
meteor.call(method, params)
|
192
275
|
|
193
|
-
|
194
|
-
expect(
|
195
|
-
expect(
|
196
|
-
expect(
|
197
|
-
expect(last_message[:params]).to eq params
|
276
|
+
expect(last_sent_message[:msg]).to eq 'method'
|
277
|
+
expect(last_sent_message[:method]).to eq method
|
278
|
+
expect(last_sent_message).to have_key :id # we don't care about the value here
|
279
|
+
expect(last_sent_message[:params]).to eq params
|
198
280
|
end
|
199
281
|
|
200
282
|
it 'calls a method called on the client directly' do
|
201
283
|
meteor = Metybur.connect(url)
|
202
284
|
meteor.activate('user', id: 'utrtrvlc')
|
203
285
|
|
204
|
-
|
205
|
-
expect(
|
206
|
-
expect(
|
207
|
-
expect(
|
208
|
-
expect(last_message[:params]).to eq ['user', {id: 'utrtrvlc'}]
|
286
|
+
expect(last_sent_message[:msg]).to eq 'method'
|
287
|
+
expect(last_sent_message[:method]).to eq 'activate'
|
288
|
+
expect(last_sent_message).to have_key :id # we don't care about the value here
|
289
|
+
expect(last_sent_message[:params]).to eq ['user', {id: 'utrtrvlc'}]
|
209
290
|
end
|
210
291
|
|
211
292
|
it 'camel-cases methods and parameters called on the client directly' do
|
212
293
|
meteor = Metybur.connect(url)
|
213
294
|
meteor.activate_user('Hans', user_id: 'utrtrvlc', is_admin: false)
|
214
295
|
|
215
|
-
|
216
|
-
expect(
|
217
|
-
expect(
|
218
|
-
expect(
|
219
|
-
expect(last_message[:params]).to eq ['Hans', {userId: 'utrtrvlc', isAdmin: false}]
|
296
|
+
expect(last_sent_message[:msg]).to eq 'method'
|
297
|
+
expect(last_sent_message[:method]).to eq 'activateUser'
|
298
|
+
expect(last_sent_message).to have_key :id # we don't care about the value here
|
299
|
+
expect(last_sent_message[:params]).to eq ['Hans', {userId: 'utrtrvlc', isAdmin: false}]
|
220
300
|
end
|
221
301
|
end
|
222
302
|
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.0
|
4
|
+
version: 0.1.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-
|
11
|
+
date: 2015-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faye-websocket
|
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
153
|
version: '0'
|
154
154
|
requirements: []
|
155
155
|
rubyforge_project:
|
156
|
-
rubygems_version: 2.
|
156
|
+
rubygems_version: 2.2.2
|
157
157
|
signing_key:
|
158
158
|
specification_version: 4
|
159
159
|
summary: DDP client for Ruby to connect to Meteor apps.
|