blather 0.5.12 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ develop
2
+
3
+ v0.6.0
4
+ Feature(benlangfeld): Very basic MUC and delayed message support
5
+ Bugfix(theozaurus): Disable connection timeout timer if client deliberately disconnects
6
+ Bugfix(mtrudel): Fix Roster#each to return roster_items as per documentation
7
+
1
8
  v0.5.12
2
9
  Bugfix(benlangfeld): Allow specifying the connection timeout in DSL setup
3
10
 
@@ -47,6 +47,8 @@
47
47
  blather/stanza/presence/c
48
48
  blather/stanza/presence/status
49
49
  blather/stanza/presence/subscription
50
+ blather/stanza/presence/muc
51
+ blather/stanza/presence/muc_user
50
52
 
51
53
  blather/stanza/pubsub
52
54
  blather/stanza/pubsub/affiliations
@@ -85,7 +87,7 @@ module Blather
85
87
  # Default logger level. Any internal call to log() will forward the log message to
86
88
  # the default log level
87
89
  attr_accessor :default_log_level
88
-
90
+
89
91
  def logger
90
92
  @@logger ||= Logger.new($stdout).tap {|logger| logger.level = Logger::INFO }
91
93
  end
@@ -76,7 +76,7 @@ module Blather
76
76
  #
77
77
  # @yield [Blather::RosterItem] yields each RosterItem
78
78
  def each(&block)
79
- items.each &block
79
+ items.values.each &block
80
80
  end
81
81
 
82
82
  # Get a duplicate of all RosterItems
@@ -375,6 +375,49 @@ class Stanza
375
375
  self << state
376
376
  end
377
377
  end
378
+
379
+ def delay
380
+ if d = find_first('ns:delay', :ns => "urn:xmpp:delay")
381
+ Delay.new d
382
+ end
383
+ end
384
+
385
+ def delayed?
386
+ !!delay
387
+ end
388
+
389
+ class Delay < XMPPNode
390
+ def self.new(stamp = nil, from = nil, description = nil)
391
+ new_node = super :delay
392
+
393
+ case stamp
394
+ when Nokogiri::XML::Node
395
+ new_node.inherit stamp
396
+ when Hash
397
+ new_node.stamp = stamp[:stamp]
398
+ new_node.from = stamp[:from]
399
+ new_node.description = stamp[:description]
400
+ else
401
+ new_node.stamp = stamp
402
+ new_node.from = from
403
+ new_node.description = description
404
+ end
405
+ new_node
406
+ end
407
+
408
+ def from
409
+ read_attr :from
410
+ end
411
+
412
+ def stamp
413
+ s = read_attr :stamp
414
+ s && Time.parse(s)
415
+ end
416
+
417
+ def description
418
+ content.strip
419
+ end
420
+ end
378
421
  end
379
422
 
380
423
  end
@@ -95,7 +95,7 @@ class Stanza
95
95
  if klass && klass != self
96
96
  klass.import(node)
97
97
  else
98
- klass = case node['type']
98
+ klass ||= case node['type']
99
99
  when nil, 'unavailable' then Status
100
100
  when /subscribe/ then Subscription
101
101
  else self
@@ -0,0 +1,19 @@
1
+ module Blather
2
+ class Stanza
3
+ class Presence
4
+
5
+ class MUC < Status
6
+ register :muc_join, :x, "http://jabber.org/protocol/muc"
7
+
8
+ private
9
+ def muc
10
+ unless muc = find_first('ns:x', :ns => self.class.registered_ns)
11
+ self << (muc = XMPPNode.new('x', self.document))
12
+ end
13
+ muc
14
+ end
15
+ end # MUC
16
+
17
+ end # Presence
18
+ end # Stanza
19
+ end # Blather
@@ -0,0 +1,143 @@
1
+ module Blather
2
+ class Stanza
3
+ class Presence
4
+
5
+ class MUCUser < Status
6
+ register :muc_user, :x, "http://jabber.org/protocol/muc#user"
7
+
8
+ def affiliation
9
+ item.affiliation
10
+ end
11
+
12
+ def affiliation=(val)
13
+ item.affiliation = val
14
+ end
15
+
16
+ def role
17
+ item.role
18
+ end
19
+
20
+ def role=(val)
21
+ item.role = val
22
+ end
23
+
24
+ def jid
25
+ item.jid
26
+ end
27
+
28
+ def jid=(val)
29
+ item.jid = val
30
+ end
31
+
32
+ def status_codes
33
+ status.map &:code
34
+ end
35
+
36
+ def status_codes=(val)
37
+ muc_user.remove_children :status
38
+ val.each do |code|
39
+ muc_user << Status.new(code)
40
+ end
41
+ end
42
+
43
+ private
44
+ def muc_user
45
+ unless muc_user = find_first('ns:x', :ns => self.class.registered_ns)
46
+ self << (muc_user = XMPPNode.new('x', self.document))
47
+ muc_user.namespace = self.class.registered_ns
48
+ end
49
+ muc_user
50
+ end
51
+
52
+ def item
53
+ if item = muc_user.find_first('ns:item', :ns => self.class.registered_ns)
54
+ Item.new item
55
+ else
56
+ muc_user << (item = Item.new nil, nil, nil, self.document)
57
+ item
58
+ end
59
+ end
60
+
61
+ def status
62
+ muc_user.find('ns:status', :ns => self.class.registered_ns).map do |status|
63
+ Status.new status
64
+ end
65
+ end
66
+
67
+ class Item < XMPPNode
68
+ def self.new(affiliation = nil, role = nil, jid = nil, document = nil)
69
+ new_node = super :item, document
70
+
71
+ case affiliation
72
+ when self
73
+ affiliation.document ||= document
74
+ return affiliation
75
+ when Nokogiri::XML::Node
76
+ new_node.inherit affiliation
77
+ when Hash
78
+ new_node.affiliation = affiliation[:affiliation]
79
+ new_node.role = affiliation[:role]
80
+ new_node.jid = affiliation[:jid]
81
+ else
82
+ new_node.affiliation = affiliation
83
+ new_node.role = role
84
+ new_node.jid = jid
85
+ end
86
+ new_node
87
+ end
88
+
89
+ def affiliation
90
+ read_attr :affiliation, :to_sym
91
+ end
92
+
93
+ def affiliation=(val)
94
+ write_attr :affiliation, val
95
+ end
96
+
97
+ def role
98
+ read_attr :role, :to_sym
99
+ end
100
+
101
+ def role=(val)
102
+ write_attr :role, val
103
+ end
104
+
105
+ def jid
106
+ read_attr :jid
107
+ end
108
+
109
+ def jid=(val)
110
+ write_attr :jid, val
111
+ end
112
+ end
113
+
114
+ class Status < XMPPNode
115
+ def self.new(code = nil)
116
+ new_node = super :status
117
+
118
+ case code
119
+ when self.class
120
+ return code
121
+ when Nokogiri::XML::Node
122
+ new_node.inherit code
123
+ when Hash
124
+ new_node.code = code[:code]
125
+ else
126
+ new_node.code = code
127
+ end
128
+ new_node
129
+ end
130
+
131
+ def code
132
+ read_attr :code, :to_i
133
+ end
134
+
135
+ def code=(val)
136
+ write_attr :code, val
137
+ end
138
+ end
139
+ end # MUC
140
+
141
+ end # Presence
142
+ end # Stanza
143
+ end # Blather
@@ -149,7 +149,7 @@ module Blather
149
149
  # @private
150
150
  def connection_completed
151
151
  if @connect_timeout
152
- EM::Timer.new @connect_timeout do
152
+ @connect_timer = EM::Timer.new @connect_timeout do
153
153
  raise ConnectionTimeout, "Stream timed out after #{@connect_timeout} seconds." unless started?
154
154
  end
155
155
  end
@@ -198,6 +198,7 @@ module Blather
198
198
  raise NoConnection unless @inited
199
199
  raise ConnectionFailed unless @connected
200
200
 
201
+ @connect_timer.cancel if @connect_timer
201
202
  # @keepalive.cancel
202
203
  @state = :stopped
203
204
  @client.receive_data @error if @error
@@ -1,4 +1,4 @@
1
1
  module Blather
2
2
  # Blather version number
3
- VERSION = '0.5.12'
3
+ VERSION = '0.6.0'
4
4
  end
@@ -12,35 +12,41 @@ describe Blather::DSL do
12
12
  end
13
13
 
14
14
  it 'wraps the setup' do
15
- args = ['jid', 'pass', 'host', 0000, nil]
16
- @client.expects(:setup).with *args
15
+ args = ['jid', 'pass', 'host', 0000]
16
+ @client.expects(:setup).with *(args + [nil, nil, nil])
17
17
  @dsl.setup *args
18
18
  end
19
19
 
20
20
  it 'allows host to be nil in setup' do
21
21
  args = ['jid', 'pass']
22
- @client.expects(:setup).with *(args + [nil, nil, nil])
22
+ @client.expects(:setup).with *(args + [nil, nil, nil, nil])
23
23
  @dsl.setup *args
24
24
  end
25
25
 
26
26
  it 'allows port to be nil in setup' do
27
27
  args = ['jid', 'pass', 'host']
28
- @client.expects(:setup).with *(args + [nil, nil])
28
+ @client.expects(:setup).with *(args + [nil, nil, nil])
29
29
  @dsl.setup *args
30
30
  end
31
31
 
32
32
  it 'allows certs to be nil in setup' do
33
33
  args = ['jid', 'pass', 'host', 'port']
34
- @client.expects(:setup).with *(args + [nil])
34
+ @client.expects(:setup).with *(args + [nil, nil])
35
35
  @dsl.setup *args
36
36
  end
37
-
37
+
38
38
  it 'accepts certs in setup' do
39
39
  args = ['jid', 'pass', 'host', 'port', 'certs']
40
- @client.expects(:setup).with *(args)
40
+ @client.expects(:setup).with *(args + [nil])
41
41
  @dsl.setup *args
42
42
  end
43
-
43
+
44
+ it 'accepts connection timeout in setup' do
45
+ args = ['jid', 'pass', 'host', 'port', 'certs', 30]
46
+ @client.expects(:setup).with *args
47
+ @dsl.setup *args
48
+ end
49
+
44
50
  it 'stops when shutdown is called' do
45
51
  @client.expects(:close)
46
52
  @dsl.shutdown
@@ -76,8 +76,12 @@ describe Blather::Roster do
76
76
  @roster.must_respond_to :each
77
77
  end
78
78
 
79
- it 'cycles through the items using #each' do
80
- @roster.map { |i| i }.sort.must_equal(@roster.items.sort)
79
+ it 'cycles through all the items using #each' do
80
+ @roster.map { |i| i }.sort.must_equal(@roster.items.values.sort)
81
+ end
82
+
83
+ it 'yields RosterItems from #each' do
84
+ @roster.map { |i| i.must_be_kind_of Blather::RosterItem }
81
85
  end
82
86
 
83
87
  it 'returns a duplicate of items through #items' do
@@ -51,6 +51,23 @@ def message_xml
51
51
  XML
52
52
  end
53
53
 
54
+ def delayed_message_xml
55
+ <<-XML
56
+ <message
57
+ from='coven@chat.shakespeare.lit/firstwitch'
58
+ id='162BEBB1-F6DB-4D9A-9BD8-CFDCC801A0B2'
59
+ to='hecate@shakespeare.lit/broom'
60
+ type='groupchat'>
61
+ <body>Thrice the brinded cat hath mew'd.</body>
62
+ <delay xmlns='urn:xmpp:delay'
63
+ from='coven@chat.shakespeare.lit'
64
+ stamp='2002-10-13T23:58:37Z'>
65
+ Too slow
66
+ </delay>
67
+ </message>
68
+ XML
69
+ end
70
+
54
71
  describe Blather::Stanza::Message do
55
72
  it 'registers itself' do
56
73
  Blather::XMPPNode.class_from_registration(:message, nil).must_equal Blather::Stanza::Message
@@ -245,4 +262,21 @@ describe Blather::Stanza::Message do
245
262
  r.form
246
263
  r.xpath('ns:x', :ns => Blather::Stanza::X.registered_ns).wont_be_empty
247
264
  end
265
+
266
+ it 'is not delayed' do
267
+ n = Blather::XMPPNode.import(parse_stanza(message_xml).root)
268
+ n.delay.must_equal nil
269
+ n.delayed?.must_equal false
270
+ end
271
+
272
+ describe "with a delay" do
273
+ it "is delayed" do
274
+ n = Blather::XMPPNode.import(parse_stanza(delayed_message_xml).root)
275
+ n.delayed?.must_equal true
276
+ n.delay.must_be_instance_of Blather::Stanza::Message::Delay
277
+ n.delay.from.must_equal 'coven@chat.shakespeare.lit'
278
+ n.delay.stamp.must_equal Time.new(2002, 10, 13, 23, 58, 37, 0)
279
+ n.delay.description.must_equal "Too slow"
280
+ end
281
+ end
248
282
  end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ def muc_xml
4
+ <<-XML
5
+ <presence from='hag66@shakespeare.lit/pda'
6
+ id='n13mt3l'
7
+ to='coven@chat.shakespeare.lit/thirdwitch'>
8
+ <x xmlns='http://jabber.org/protocol/muc'/>
9
+ </presence>
10
+ XML
11
+ end
12
+
13
+ describe 'Blather::Stanza::Presence::MUC' do
14
+ it 'registers itself' do
15
+ Blather::XMPPNode.class_from_registration(:x, 'http://jabber.org/protocol/muc' ).must_equal Blather::Stanza::Presence::MUC
16
+ end
17
+
18
+ it 'must be importable' do
19
+ c = Blather::XMPPNode.import(parse_stanza(muc_xml).root).must_be_instance_of Blather::Stanza::Presence::MUC
20
+ end
21
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ def muc_user_xml
4
+ <<-XML
5
+ <presence from='hag66@shakespeare.lit/pda'
6
+ id='n13mt3l'
7
+ to='coven@chat.shakespeare.lit/thirdwitch'>
8
+ <x xmlns='http://jabber.org/protocol/muc#user'>
9
+ <item affiliation='none'
10
+ jid='hag66@shakespeare.lit/pda'
11
+ role='participant'/>
12
+ <status code='100'/>
13
+ <status code='110'/>
14
+ </x>
15
+ </presence>
16
+ XML
17
+ end
18
+
19
+ describe 'Blather::Stanza::Presence::MUCUser' do
20
+ it 'registers itself' do
21
+ Blather::XMPPNode.class_from_registration(:x, 'http://jabber.org/protocol/muc#user' ).must_equal Blather::Stanza::Presence::MUCUser
22
+ end
23
+
24
+ it 'must be importable' do
25
+ muc_user = Blather::XMPPNode.import(parse_stanza(muc_user_xml).root)
26
+ muc_user.must_be_instance_of Blather::Stanza::Presence::MUCUser
27
+ muc_user.affiliation.must_equal :none
28
+ muc_user.jid.must_equal 'hag66@shakespeare.lit/pda'
29
+ muc_user.role.must_equal :participant
30
+ muc_user.status_codes.must_equal [100, 110]
31
+ end
32
+
33
+ it "must be able to set the affiliation" do
34
+ muc_user = Blather::Stanza::Presence::MUCUser.new
35
+ muc_user.affiliation.must_equal nil
36
+ muc_user.affiliation = :none
37
+ muc_user.affiliation.must_equal :none
38
+ end
39
+
40
+ it "must be able to set the role" do
41
+ muc_user = Blather::Stanza::Presence::MUCUser.new
42
+ muc_user.role.must_equal nil
43
+ muc_user.role = :participant
44
+ muc_user.role.must_equal :participant
45
+ end
46
+
47
+ it "must be able to set the jid" do
48
+ muc_user = Blather::Stanza::Presence::MUCUser.new
49
+ muc_user.jid.must_equal nil
50
+ muc_user.jid = 'foo@bar.com'
51
+ muc_user.jid.must_equal 'foo@bar.com'
52
+ end
53
+
54
+ it "must be able to set the status codes" do
55
+ muc_user = Blather::Stanza::Presence::MUCUser.new
56
+ muc_user.status_codes.must_equal []
57
+ muc_user.status_codes = [100, 110]
58
+ muc_user.status_codes.must_equal [100, 110]
59
+ muc_user.status_codes = [500]
60
+ muc_user.status_codes.must_equal [500]
61
+ end
62
+ end
@@ -51,7 +51,7 @@ describe Blather::Stanza::Presence::Status do
51
51
 
52
52
  it 'returns :available if <show/> is blank' do
53
53
  status = Blather::XMPPNode.import(parse_stanza(<<-NODE).root)
54
- <presence><show/><presence/>
54
+ <presence><show/></presence>
55
55
  NODE
56
56
  status.state.must_equal :available
57
57
  end
@@ -35,27 +35,41 @@ describe Blather::Stanza::Presence do
35
35
  end
36
36
 
37
37
  it 'creates a Status object when importing a node with type == nil' do
38
- s = Blather::Stanza::Presence.import(Blather::XMPPNode.new)
38
+ s = Blather::Stanza::Presence.import(parse_stanza('<presence/>').root)
39
39
  s.must_be_kind_of Blather::Stanza::Presence::Status
40
40
  s.state.must_equal :available
41
41
  end
42
42
 
43
43
  it 'creates a Status object when importing a node with type == "unavailable"' do
44
- n = Blather::XMPPNode.new
45
- n[:type] = :unavailable
46
- s = Blather::Stanza::Presence.import(n)
44
+ s = Blather::Stanza::Presence.import(parse_stanza('<presence type="unavailable"/>').root)
47
45
  s.must_be_kind_of Blather::Stanza::Presence::Status
48
46
  s.state.must_equal :unavailable
49
47
  end
50
48
 
51
49
  it 'creates a Subscription object when importing a node with type == "subscribe"' do
52
- n = Blather::XMPPNode.new
53
- n[:type] = :subscribe
54
- s = Blather::Stanza::Presence.import(n)
50
+ s = Blather::Stanza::Presence.import(parse_stanza('<presence type="subscribe"/>').root)
55
51
  s.must_be_kind_of Blather::Stanza::Presence::Subscription
56
52
  s.type.must_equal :subscribe
57
53
  end
58
54
 
55
+ it 'creates a MUC object when importing a node with a form in the MUC namespace' do
56
+ n = Blather::XMPPNode.new
57
+ x = Blather::XMPPNode.new 'x'
58
+ x.namespace = "http://jabber.org/protocol/muc"
59
+ n << x
60
+ s = Blather::Stanza::Presence.import(n)
61
+ s.must_be_kind_of Blather::Stanza::Presence::MUC
62
+ end
63
+
64
+ it 'creates a MUCUser object when importing a node with a form in the MUC#user namespace' do
65
+ n = Blather::XMPPNode.new
66
+ x = Blather::XMPPNode.new 'x'
67
+ x.namespace = "http://jabber.org/protocol/muc#user"
68
+ n << x
69
+ s = Blather::Stanza::Presence.import(n)
70
+ s.must_be_kind_of Blather::Stanza::Presence::MUCUser
71
+ end
72
+
59
73
  it 'creates a Presence object when importing a node with type equal to something unknown' do
60
74
  n = Blather::XMPPNode.new
61
75
  n[:type] = :foo
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blather
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.12
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-06 00:00:00.000000000 Z
12
+ date: 2012-02-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
16
- requirement: &2164563300 !ruby/object:Gem::Requirement
16
+ requirement: &2152558880 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.12.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2164563300
24
+ version_requirements: *2152558880
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: nokogiri
27
- requirement: &2164562780 !ruby/object:Gem::Requirement
27
+ requirement: &2152558220 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.4.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2164562780
35
+ version_requirements: *2152558220
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: niceogiri
38
- requirement: &2164562300 !ruby/object:Gem::Requirement
38
+ requirement: &2152557520 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.1.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2164562300
46
+ version_requirements: *2152557520
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activesupport
49
- requirement: &2164561820 !ruby/object:Gem::Requirement
49
+ requirement: &2152556180 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 3.0.7
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2164561820
57
+ version_requirements: *2152556180
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: minitest
60
- requirement: &2164561340 !ruby/object:Gem::Requirement
60
+ requirement: &2152554880 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.7.1
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2164561340
68
+ version_requirements: *2152554880
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: mocha
71
- requirement: &2164560860 !ruby/object:Gem::Requirement
71
+ requirement: &2152554100 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.9.12
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2164560860
79
+ version_requirements: *2152554100
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: bundler
82
- requirement: &2164560380 !ruby/object:Gem::Requirement
82
+ requirement: &2152553380 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 1.0.0
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *2164560380
90
+ version_requirements: *2152553380
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rcov
93
- requirement: &2164559860 !ruby/object:Gem::Requirement
93
+ requirement: &2152552260 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: 0.9.9
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *2164559860
101
+ version_requirements: *2152552260
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: yard
104
- requirement: &2164559380 !ruby/object:Gem::Requirement
104
+ requirement: &2152551640 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: 0.6.1
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *2164559380
112
+ version_requirements: *2152551640
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: rake
115
- requirement: &2164558980 !ruby/object:Gem::Requirement
115
+ requirement: &2152551040 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: '0'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *2164558980
123
+ version_requirements: *2152551040
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: guard-minitest
126
- requirement: &2164558520 !ruby/object:Gem::Requirement
126
+ requirement: &2152550100 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,10 +131,10 @@ dependencies:
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *2164558520
134
+ version_requirements: *2152550100
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: bluecloth
137
- requirement: &2164558020 !ruby/object:Gem::Requirement
137
+ requirement: &2152548880 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ! '>='
@@ -142,10 +142,10 @@ dependencies:
142
142
  version: '0'
143
143
  type: :development
144
144
  prerelease: false
145
- version_requirements: *2164558020
145
+ version_requirements: *2152548880
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: growl_notify
148
- requirement: &2164557480 !ruby/object:Gem::Requirement
148
+ requirement: &2152547320 !ruby/object:Gem::Requirement
149
149
  none: false
150
150
  requirements:
151
151
  - - ! '>='
@@ -153,10 +153,10 @@ dependencies:
153
153
  version: '0'
154
154
  type: :development
155
155
  prerelease: false
156
- version_requirements: *2164557480
156
+ version_requirements: *2152547320
157
157
  - !ruby/object:Gem::Dependency
158
158
  name: rb-fsevent
159
- requirement: &2164556920 !ruby/object:Gem::Requirement
159
+ requirement: &2152546580 !ruby/object:Gem::Requirement
160
160
  none: false
161
161
  requirements:
162
162
  - - ! '>='
@@ -164,7 +164,7 @@ dependencies:
164
164
  version: '0'
165
165
  type: :development
166
166
  prerelease: false
167
- version_requirements: *2164556920
167
+ version_requirements: *2152546580
168
168
  description: An XMPP DSL for Ruby written on top of EventMachine and Nokogiri
169
169
  email: sprsquish@gmail.com
170
170
  executables: []
@@ -230,6 +230,8 @@ files:
230
230
  - lib/blather/stanza/message.rb
231
231
  - lib/blather/stanza/presence.rb
232
232
  - lib/blather/stanza/presence/c.rb
233
+ - lib/blather/stanza/presence/muc.rb
234
+ - lib/blather/stanza/presence/muc_user.rb
233
235
  - lib/blather/stanza/presence/status.rb
234
236
  - lib/blather/stanza/presence/subscription.rb
235
237
  - lib/blather/stanza/pubsub.rb
@@ -283,6 +285,8 @@ files:
283
285
  - spec/blather/stanza/iq_spec.rb
284
286
  - spec/blather/stanza/message_spec.rb
285
287
  - spec/blather/stanza/presence/c_spec.rb
288
+ - spec/blather/stanza/presence/muc_spec.rb
289
+ - spec/blather/stanza/presence/muc_user_spec.rb
286
290
  - spec/blather/stanza/presence/status_spec.rb
287
291
  - spec/blather/stanza/presence/subscription_spec.rb
288
292
  - spec/blather/stanza/presence_spec.rb
@@ -363,6 +367,8 @@ test_files:
363
367
  - spec/blather/stanza/iq_spec.rb
364
368
  - spec/blather/stanza/message_spec.rb
365
369
  - spec/blather/stanza/presence/c_spec.rb
370
+ - spec/blather/stanza/presence/muc_spec.rb
371
+ - spec/blather/stanza/presence/muc_user_spec.rb
366
372
  - spec/blather/stanza/presence/status_spec.rb
367
373
  - spec/blather/stanza/presence/subscription_spec.rb
368
374
  - spec/blather/stanza/presence_spec.rb