blather 0.4.13 → 0.4.14

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -169,6 +169,7 @@ than a change set made directly on master.
169
169
  * [Nolan Darilek](http://github.com/thewordnerd)
170
170
  * [Tim Carey-Smith](http://github.com/halorgium)
171
171
  * [Ben Langfeld](http://github.com/benlangfeld)
172
+ * [Anton Mironov](http://github.com/mironov)
172
173
 
173
174
  # Copyright
174
175
 
@@ -90,8 +90,8 @@ module Blather
90
90
  #
91
91
  # @return [Hash<group => Array<RosterItem>>]
92
92
  def grouped
93
- self.inject(Hash.new{|h,k|h[k]=[]}) do |hash, item|
94
- item[1].groups.each { |group| hash[group] << item[1] }
93
+ @items.values.sort.inject(Hash.new{|h,k|h[k]=[]}) do |hash, item|
94
+ item.groups.each { |group| hash[group] << item }
95
95
  hash
96
96
  end
97
97
  end
@@ -108,4 +108,4 @@ module Blather
108
108
  end
109
109
  end # Roster
110
110
 
111
- end # Blather
111
+ end # Blather
@@ -117,6 +117,17 @@ module Blather
117
117
  n.groups = groups
118
118
  r
119
119
  end
120
+
121
+ def <=>(o)
122
+ self.jid.to_s <=> o.jid.to_s
123
+ end
124
+
125
+ def eql?(o)
126
+ o.is_a?(RosterItem) &&
127
+ o.jid == self.jid &&
128
+ o.groups == self.groups
129
+ end
130
+ alias_method :==, :eql?
120
131
  end #RosterItem
121
132
 
122
- end
133
+ end
@@ -159,6 +159,9 @@ class Stanza
159
159
  class Message < Stanza
160
160
  VALID_TYPES = [:chat, :error, :groupchat, :headline, :normal].freeze
161
161
 
162
+ VALID_CHAT_STATES = [:active, :composing, :gone, :inactive, :paused].freeze
163
+ CHAT_STATE_NS = 'http://jabber.org/protocol/chatstates'.freeze
164
+
162
165
  HTML_NS = 'http://jabber.org/protocol/xhtml-im'.freeze
163
166
  HTML_BODY_NS = 'http://www.w3.org/1999/xhtml'.freeze
164
167
 
@@ -189,6 +192,7 @@ class Stanza
189
192
  node.to = to
190
193
  node.type = type
191
194
  node.body = body
195
+ node.chat_state = :active if [:chat, :groupchat].include?(type)
192
196
  node
193
197
  end
194
198
 
@@ -262,8 +266,9 @@ class Stanza
262
266
  end
263
267
 
264
268
  unless b = h.find_first('ns:body', :ns => HTML_BODY_NS)
265
- h << (b = XMPPNode.new('body', self.document))
269
+ b = XMPPNode.new('body', self.document)
266
270
  b.namespace = HTML_BODY_NS
271
+ h << b
267
272
  end
268
273
 
269
274
  b
@@ -273,7 +278,7 @@ class Stanza
273
278
  #
274
279
  # @return [String]
275
280
  def xhtml
276
- self.xhtml_node.content.strip
281
+ self.xhtml_node.inner_html.strip
277
282
  end
278
283
 
279
284
  # Set the message xhtml
@@ -281,7 +286,7 @@ class Stanza
281
286
  #
282
287
  # @param [#to_s] valid xhtml
283
288
  def xhtml=(xhtml_body)
284
- self.xhtml_node.content = Nokogiri::XML(xhtml_body).to_xhtml
289
+ self.xhtml_node.inner_html = Nokogiri::XML::DocumentFragment.parse(xhtml_body)
285
290
  end
286
291
 
287
292
  # Get the message subject
@@ -331,6 +336,32 @@ class Stanza
331
336
  def form
332
337
  X.find_or_create self
333
338
  end
339
+
340
+ # Get the message chat state
341
+ #
342
+ # @return [Symbol]
343
+ def chat_state
344
+ if (elem = find_first('ns:*', :ns => CHAT_STATE_NS)) && VALID_CHAT_STATES.include?(name = elem.name.to_sym)
345
+ name
346
+ end
347
+ end
348
+
349
+ # Set the message chat state
350
+ #
351
+ # @param [#to_s] chat_state the message chat state. Must be one of VALID_CHAT_STATES
352
+ def chat_state=(chat_state)
353
+ if chat_state && !VALID_CHAT_STATES.include?(chat_state.to_sym)
354
+ raise ArgumentError, "Invalid Chat State (#{chat_state}), use: #{VALID_CHAT_STATES*' '}"
355
+ end
356
+
357
+ xpath('ns:*', :ns => CHAT_STATE_NS).remove
358
+
359
+ if chat_state
360
+ state = XMPPNode.new(chat_state, self.document)
361
+ state.namespace = CHAT_STATE_NS
362
+ self << state
363
+ end
364
+ end
334
365
  end
335
366
 
336
367
  end
@@ -113,8 +113,9 @@ module Blather
113
113
  #
114
114
  # @param [#to_xml, #to_s] stanza the stanza to send over the wire
115
115
  def send(stanza)
116
- Blather.logger.debug "SENDING: (#{caller[1]}) #{stanza}"
117
- send_data stanza.respond_to?(:to_xml) ? stanza.to_xml : stanza.to_s
116
+ data = stanza.respond_to?(:to_xml) ? stanza.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML) : stanza.to_s
117
+ Blather.logger.debug "SENDING: (#{caller[1]}) #{data}"
118
+ send_data data
118
119
  end
119
120
 
120
121
  # Called by EM.connect to initialize stream variables
@@ -37,11 +37,6 @@ class Stream # :nodoc:
37
37
  node[attr.localname] = attr.value
38
38
  end
39
39
 
40
- if !@receiver.stopped?
41
- @current << node if @current
42
- @current = node
43
- end
44
-
45
40
  ns_keys = namespaces.map { |pre, href| pre }
46
41
  namespaces.delete_if { |pre, href| NS_TO_IGNORE.include? href }
47
42
  @namespace_definitions.push []
@@ -53,6 +48,11 @@ class Stream # :nodoc:
53
48
  @namespaces[[prefix, uri]] ||= node.add_namespace(prefix, uri) if prefix && !ns_keys.include?(prefix)
54
49
  node.namespace = @namespaces[[prefix, uri]]
55
50
 
51
+ if !@receiver.stopped?
52
+ @current << node if @current
53
+ @current = node
54
+ end
55
+
56
56
  deliver(node) if elem == 'stream'
57
57
 
58
58
  # $stderr.puts "\n\n"
@@ -33,7 +33,7 @@ module Blather
33
33
  # @return [Class, nil] the class appropriate for the name/ns combination
34
34
  def self.class_from_registration(name, ns = nil)
35
35
  name = name.to_s
36
- @@registrations[[name, ns]] || @@registrations[[name, nil]]
36
+ @@registrations[[name, ns]]
37
37
  end
38
38
 
39
39
  # Import an XML::Node to the appropriate class
@@ -93,4 +93,12 @@ describe Blather::RosterItem do
93
93
  i = Blather::RosterItem.new 'n@d'
94
94
  i.groups.must_equal [nil]
95
95
  end
96
+
97
+ it 'can determine equality' do
98
+ item1 = Blather::RosterItem.new 'n@d'
99
+ item2 = Blather::RosterItem.new 'n@d'
100
+ item1.groups = %w[group1 group2]
101
+ item2.groups = %w[group1 group2]
102
+ (item1 == item2).must_equal true
103
+ end
96
104
  end
@@ -109,8 +109,9 @@ describe Blather::Stanza::Message do
109
109
  msg = Blather::Stanza::Message.new
110
110
  msg << (h = Blather::XMPPNode.new('html', msg.document))
111
111
  h.namespace = Blather::Stanza::Message::HTML_NS
112
- h << (b = Blather::XMPPNode.new('body', msg.document))
112
+ b = Blather::XMPPNode.new('body', msg.document)
113
113
  b.namespace = Blather::Stanza::Message::HTML_BODY_NS
114
+ h << b
114
115
 
115
116
  msg.xhtml_node.must_equal(b)
116
117
  end
@@ -119,14 +120,21 @@ describe Blather::Stanza::Message do
119
120
  msg = Blather::Stanza::Message.new
120
121
  xhtml = "<some>xhtml</some>"
121
122
  msg.xhtml = xhtml
122
- msg.xhtml_node.content.strip.must_equal(xhtml)
123
+ msg.xhtml_node.inner_html.strip.must_equal(xhtml)
123
124
  end
124
125
 
125
126
  it 'sets valid xhtml even if the input is not valid' do
126
127
  msg = Blather::Stanza::Message.new
127
128
  xhtml = "<some>xhtml"
128
129
  msg.xhtml = xhtml
129
- msg.xhtml_node.content.strip.must_equal("<some>xhtml</some>")
130
+ msg.xhtml_node.inner_html.strip.must_equal("<some>xhtml</some>")
131
+ end
132
+
133
+ it 'sets xhtml with more than one root node' do
134
+ msg = Blather::Stanza::Message.new
135
+ xhtml = "<i>xhtml</i> more xhtml"
136
+ msg.xhtml = xhtml
137
+ msg.xhtml_node.inner_html.strip.must_equal("<i>xhtml</i> more xhtml")
130
138
  end
131
139
 
132
140
  it 'has an xhtml getter' do
@@ -136,6 +144,45 @@ describe Blather::Stanza::Message do
136
144
  msg.xhtml.must_equal(xhtml)
137
145
  end
138
146
 
147
+ it 'has a chat state setter' do
148
+ msg = Blather::Stanza::Message.new
149
+ msg.chat_state = :composing
150
+ msg.xpath('ns:composing', :ns => Blather::Stanza::Message::CHAT_STATE_NS).wont_be_empty
151
+ end
152
+
153
+ it 'will only add one chat state at a time' do
154
+ msg = Blather::Stanza::Message.new
155
+ msg.chat_state = :composing
156
+ msg.chat_state = :paused
157
+
158
+ msg.xpath('ns:*', :ns => Blather::Stanza::Message::CHAT_STATE_NS).size.must_equal(1)
159
+ end
160
+
161
+ it 'ensures chat state setter accepts strings' do
162
+ msg = Blather::Stanza::Message.new
163
+ msg.chat_state = "gone"
164
+ msg.xpath('ns:gone', :ns => Blather::Stanza::Message::CHAT_STATE_NS).wont_be_empty
165
+ end
166
+
167
+ it 'ensures chat state is one of Blather::Stanza::Message::VALID_CHAT_STATES' do
168
+ lambda do
169
+ msg = Blather::Stanza::Message.new
170
+ msg.chat_state = :invalid_chat_state
171
+ end.must_raise(Blather::ArgumentError)
172
+
173
+ Blather::Stanza::Message::VALID_CHAT_STATES.each do |valid_chat_state|
174
+ msg = Blather::Stanza::Message.new
175
+ msg.chat_state = valid_chat_state
176
+ msg.chat_state.must_equal valid_chat_state
177
+ end
178
+ end
179
+
180
+ it 'has a chat state getter' do
181
+ msg = Blather::Stanza::Message.new
182
+ msg.chat_state = :paused
183
+ msg.chat_state.must_equal(:paused)
184
+ end
185
+
139
186
  it 'makes a form child available' do
140
187
  n = Blather::XMPPNode.import(parse_stanza(message_xml).root)
141
188
  n.form.fields.size.must_equal 1
@@ -1008,4 +1008,17 @@ describe Blather::Stream::Client do
1008
1008
  comp.expects(:send_data).with { |s| s.wont_match(/^<message[^>]*from=/); true }
1009
1009
  comp.send msg
1010
1010
  end
1011
+
1012
+ it 'sends xml without formatting' do
1013
+ client = mock()
1014
+ client.stubs(:jid)
1015
+ client.stubs(:jid=)
1016
+
1017
+ msg = Blather::Stanza::Message.new 'to@jid.com', 'body'
1018
+ msg.xhtml = '<i>xhtml</i> body'
1019
+
1020
+ comp = Blather::Stream::Client.new nil, client, 'node@jid.com/resource', 'pass'
1021
+ comp.expects(:send_data).with { |s| s.wont_match(/\n/); true }
1022
+ comp.send msg
1023
+ end
1011
1024
  end
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,7 @@ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), *%w[.. lib]))
3
3
 
4
4
  require 'blather'
5
5
  require 'rubygems'
6
+ gem 'minitest', '>=1.7.1'
6
7
  require 'minitest/spec'
7
8
  require 'mocha'
8
9
  require 'mocha/expectation_error'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blather
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 13
10
- version: 0.4.13
9
+ - 14
10
+ version: 0.4.14
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeff Smick
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-10 00:00:00 -07:00
18
+ date: 2010-09-02 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -50,6 +50,22 @@ dependencies:
50
50
  version: 1.4.0
51
51
  type: :runtime
52
52
  version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: minitest
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 9
62
+ segments:
63
+ - 1
64
+ - 7
65
+ - 1
66
+ version: 1.7.1
67
+ type: :development
68
+ version_requirements: *id003
53
69
  description: An XMPP DSL for Ruby written on top of EventMachine and Nokogiri
54
70
  email: sprsquish@gmail.com
55
71
  executables: []
@@ -122,49 +138,6 @@ files:
122
138
  - lib/blather/xmpp_node.rb
123
139
  - LICENSE
124
140
  - README.md
125
- - spec/blather/client/client_spec.rb
126
- - spec/blather/client/dsl/pubsub_spec.rb
127
- - spec/blather/client/dsl_spec.rb
128
- - spec/blather/core_ext/nokogiri_spec.rb
129
- - spec/blather/errors/sasl_error_spec.rb
130
- - spec/blather/errors/stanza_error_spec.rb
131
- - spec/blather/errors/stream_error_spec.rb
132
- - spec/blather/errors_spec.rb
133
- - spec/blather/jid_spec.rb
134
- - spec/blather/roster_item_spec.rb
135
- - spec/blather/roster_spec.rb
136
- - spec/blather/stanza/discos/disco_info_spec.rb
137
- - spec/blather/stanza/discos/disco_items_spec.rb
138
- - spec/blather/stanza/iq/command_spec.rb
139
- - spec/blather/stanza/iq/query_spec.rb
140
- - spec/blather/stanza/iq/roster_spec.rb
141
- - spec/blather/stanza/iq_spec.rb
142
- - spec/blather/stanza/message_spec.rb
143
- - spec/blather/stanza/presence/status_spec.rb
144
- - spec/blather/stanza/presence/subscription_spec.rb
145
- - spec/blather/stanza/presence_spec.rb
146
- - spec/blather/stanza/pubsub/affiliations_spec.rb
147
- - spec/blather/stanza/pubsub/create_spec.rb
148
- - spec/blather/stanza/pubsub/event_spec.rb
149
- - spec/blather/stanza/pubsub/items_spec.rb
150
- - spec/blather/stanza/pubsub/publish_spec.rb
151
- - spec/blather/stanza/pubsub/retract_spec.rb
152
- - spec/blather/stanza/pubsub/subscribe_spec.rb
153
- - spec/blather/stanza/pubsub/subscription_spec.rb
154
- - spec/blather/stanza/pubsub/subscriptions_spec.rb
155
- - spec/blather/stanza/pubsub/unsubscribe_spec.rb
156
- - spec/blather/stanza/pubsub_owner/delete_spec.rb
157
- - spec/blather/stanza/pubsub_owner/purge_spec.rb
158
- - spec/blather/stanza/pubsub_owner_spec.rb
159
- - spec/blather/stanza/pubsub_spec.rb
160
- - spec/blather/stanza/x_spec.rb
161
- - spec/blather/stanza_spec.rb
162
- - spec/blather/stream/client_spec.rb
163
- - spec/blather/stream/component_spec.rb
164
- - spec/blather/stream/parser_spec.rb
165
- - spec/blather/xmpp_node_spec.rb
166
- - spec/fixtures/pubsub.rb
167
- - spec/spec_helper.rb
168
141
  has_rdoc: true
169
142
  homepage: http://github.com/sprsquish/blather
170
143
  licenses: []
@@ -195,32 +168,41 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
168
  requirements: []
196
169
 
197
170
  rubyforge_project: squishtech
198
- rubygems_version: 1.3.7
171
+ rubygems_version: 1.3.6
199
172
  signing_key:
200
173
  specification_version: 3
201
174
  summary: Simpler XMPP built for speed
202
175
  test_files:
176
+ - spec/spec_helper.rb
177
+ - spec/blather/errors_spec.rb
178
+ - spec/blather/jid_spec.rb
179
+ - spec/blather/roster_item_spec.rb
180
+ - spec/blather/roster_spec.rb
181
+ - spec/blather/stanza_spec.rb
182
+ - spec/blather/xmpp_node_spec.rb
183
+ - spec/fixtures/pubsub.rb
203
184
  - spec/blather/client/client_spec.rb
204
- - spec/blather/client/dsl/pubsub_spec.rb
205
185
  - spec/blather/client/dsl_spec.rb
206
186
  - spec/blather/core_ext/nokogiri_spec.rb
207
187
  - spec/blather/errors/sasl_error_spec.rb
208
188
  - spec/blather/errors/stanza_error_spec.rb
209
189
  - spec/blather/errors/stream_error_spec.rb
210
- - spec/blather/errors_spec.rb
211
- - spec/blather/jid_spec.rb
212
- - spec/blather/roster_item_spec.rb
213
- - spec/blather/roster_spec.rb
190
+ - spec/blather/stanza/iq_spec.rb
191
+ - spec/blather/stanza/message_spec.rb
192
+ - spec/blather/stanza/presence_spec.rb
193
+ - spec/blather/stanza/pubsub_owner_spec.rb
194
+ - spec/blather/stanza/pubsub_spec.rb
195
+ - spec/blather/stanza/x_spec.rb
196
+ - spec/blather/stream/client_spec.rb
197
+ - spec/blather/stream/component_spec.rb
198
+ - spec/blather/stream/parser_spec.rb
214
199
  - spec/blather/stanza/discos/disco_info_spec.rb
215
200
  - spec/blather/stanza/discos/disco_items_spec.rb
216
201
  - spec/blather/stanza/iq/command_spec.rb
217
202
  - spec/blather/stanza/iq/query_spec.rb
218
203
  - spec/blather/stanza/iq/roster_spec.rb
219
- - spec/blather/stanza/iq_spec.rb
220
- - spec/blather/stanza/message_spec.rb
221
204
  - spec/blather/stanza/presence/status_spec.rb
222
205
  - spec/blather/stanza/presence/subscription_spec.rb
223
- - spec/blather/stanza/presence_spec.rb
224
206
  - spec/blather/stanza/pubsub/affiliations_spec.rb
225
207
  - spec/blather/stanza/pubsub/create_spec.rb
226
208
  - spec/blather/stanza/pubsub/event_spec.rb
@@ -233,13 +215,4 @@ test_files:
233
215
  - spec/blather/stanza/pubsub/unsubscribe_spec.rb
234
216
  - spec/blather/stanza/pubsub_owner/delete_spec.rb
235
217
  - spec/blather/stanza/pubsub_owner/purge_spec.rb
236
- - spec/blather/stanza/pubsub_owner_spec.rb
237
- - spec/blather/stanza/pubsub_spec.rb
238
- - spec/blather/stanza/x_spec.rb
239
- - spec/blather/stanza_spec.rb
240
- - spec/blather/stream/client_spec.rb
241
- - spec/blather/stream/component_spec.rb
242
- - spec/blather/stream/parser_spec.rb
243
- - spec/blather/xmpp_node_spec.rb
244
- - spec/fixtures/pubsub.rb
245
- - spec/spec_helper.rb
218
+ - spec/blather/client/dsl/pubsub_spec.rb