blather 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/.rspec +3 -0
  2. data/.travis.yml +1 -8
  3. data/CHANGELOG.md +230 -0
  4. data/Guardfile +4 -4
  5. data/README.md +2 -8
  6. data/Rakefile +14 -27
  7. data/blather.gemspec +8 -18
  8. data/lib/blather.rb +1 -0
  9. data/lib/blather/client/client.rb +8 -0
  10. data/lib/blather/roster.rb +7 -0
  11. data/lib/blather/stanza/iq/roster.rb +1 -1
  12. data/lib/blather/stanza/message/muc_user.rb +2 -0
  13. data/lib/blather/stanza/muc/muc_user_base.rb +4 -3
  14. data/lib/blather/stanza/presence.rb +12 -14
  15. data/lib/blather/stanza/presence/c.rb +58 -62
  16. data/lib/blather/stanza/presence/muc.rb +14 -10
  17. data/lib/blather/stanza/presence/muc_user.rb +47 -36
  18. data/lib/blather/stanza/presence/status.rb +106 -101
  19. data/lib/blather/stanza/presence/subscription.rb +59 -60
  20. data/lib/blather/stream.rb +1 -3
  21. data/lib/blather/stream/features/resource.rb +0 -1
  22. data/lib/blather/version.rb +1 -2
  23. data/lib/blather/xmpp_node.rb +24 -3
  24. data/spec/blather/client/client_spec.rb +64 -64
  25. data/spec/blather/client/dsl/pubsub_spec.rb +127 -127
  26. data/spec/blather/client/dsl_spec.rb +11 -11
  27. data/spec/blather/errors/sasl_error_spec.rb +3 -3
  28. data/spec/blather/errors/stanza_error_spec.rb +26 -26
  29. data/spec/blather/errors/stream_error_spec.rb +22 -22
  30. data/spec/blather/errors_spec.rb +7 -7
  31. data/spec/blather/file_transfer_spec.rb +16 -18
  32. data/spec/blather/jid_spec.rb +29 -29
  33. data/spec/blather/roster_item_spec.rb +18 -18
  34. data/spec/blather/roster_spec.rb +18 -18
  35. data/spec/blather/stanza/discos/disco_info_spec.rb +56 -57
  36. data/spec/blather/stanza/discos/disco_items_spec.rb +33 -33
  37. data/spec/blather/stanza/iq/command_spec.rb +57 -57
  38. data/spec/blather/stanza/iq/ibb_spec.rb +27 -39
  39. data/spec/blather/stanza/iq/ping_spec.rb +13 -9
  40. data/spec/blather/stanza/iq/query_spec.rb +16 -16
  41. data/spec/blather/stanza/iq/roster_spec.rb +29 -30
  42. data/spec/blather/stanza/iq/s5b_spec.rb +10 -13
  43. data/spec/blather/stanza/iq/si_spec.rb +20 -23
  44. data/spec/blather/stanza/iq/vcard_spec.rb +22 -25
  45. data/spec/blather/stanza/iq_spec.rb +12 -12
  46. data/spec/blather/stanza/message/muc_user_spec.rb +36 -36
  47. data/spec/blather/stanza/message_spec.rb +56 -56
  48. data/spec/blather/stanza/presence/c_spec.rb +17 -7
  49. data/spec/blather/stanza/presence/muc_spec.rb +8 -8
  50. data/spec/blather/stanza/presence/muc_user_spec.rb +23 -23
  51. data/spec/blather/stanza/presence/status_spec.rb +42 -30
  52. data/spec/blather/stanza/presence/subscription_spec.rb +22 -23
  53. data/spec/blather/stanza/presence_spec.rb +72 -34
  54. data/spec/blather/stanza/pubsub/affiliations_spec.rb +12 -12
  55. data/spec/blather/stanza/pubsub/create_spec.rb +10 -10
  56. data/spec/blather/stanza/pubsub/event_spec.rb +31 -31
  57. data/spec/blather/stanza/pubsub/items_spec.rb +21 -21
  58. data/spec/blather/stanza/pubsub/publish_spec.rb +21 -21
  59. data/spec/blather/stanza/pubsub/retract_spec.rb +20 -20
  60. data/spec/blather/stanza/pubsub/subscribe_spec.rb +17 -17
  61. data/spec/blather/stanza/pubsub/subscription_spec.rb +28 -28
  62. data/spec/blather/stanza/pubsub/subscriptions_spec.rb +11 -11
  63. data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +22 -22
  64. data/spec/blather/stanza/pubsub_owner/delete_spec.rb +9 -9
  65. data/spec/blather/stanza/pubsub_owner/purge_spec.rb +9 -9
  66. data/spec/blather/stanza/pubsub_owner_spec.rb +6 -6
  67. data/spec/blather/stanza/pubsub_spec.rb +16 -16
  68. data/spec/blather/stanza/x_spec.rb +53 -53
  69. data/spec/blather/stanza_spec.rb +39 -39
  70. data/spec/blather/stream/client_spec.rb +133 -133
  71. data/spec/blather/stream/component_spec.rb +7 -7
  72. data/spec/blather/stream/parser_spec.rb +24 -24
  73. data/spec/blather/stream/ssl_spec.rb +7 -7
  74. data/spec/blather/xmpp_node_spec.rb +17 -7
  75. data/spec/blather_spec.rb +4 -4
  76. data/spec/spec_helper.rb +6 -54
  77. metadata +53 -68
  78. data/CHANGELOG +0 -220
@@ -85,27 +85,25 @@ class Stanza
85
85
  # either a Status or Subscription object is created based
86
86
  # on the type attribute.
87
87
  # If neither is found it instantiates a Presence object
88
- def self.import(node) # :nodoc:
89
- klass = nil
90
- node.children.detect do |e|
88
+ def self.import(node, *decorators) # :nodoc:
89
+ node.children.each do |e|
91
90
  ns = e.namespace ? e.namespace.href : nil
92
- klass = class_from_registration(e.element_name, ns)
91
+ klass = class_from_registration e.element_name, ns
92
+ decorators << klass if klass
93
93
  end
94
94
 
95
- if klass && klass != self
96
- klass.import(node)
97
- else
98
- klass ||= case node['type']
99
- when nil, 'unavailable' then Status
100
- when /subscribe/ then Subscription
101
- else self
102
- end
103
- klass.new.inherit(node)
95
+ case node['type']
96
+ when nil, 'unavailable'
97
+ decorators << Status
98
+ when /subscribe/
99
+ decorators << Subscription
104
100
  end
101
+
102
+ super
105
103
  end
106
104
 
107
105
  # Ensure element_name is "presence" for all subclasses
108
- def self.new
106
+ def self.new(*args)
109
107
  super :presence
110
108
  end
111
109
 
@@ -22,82 +22,78 @@ class Presence
22
22
  new_node.hash = hash
23
23
  new_node.node = node
24
24
  new_node.ver = ver
25
- new_node
25
+ parse new_node.to_xml
26
26
  end
27
27
 
28
- def self.import(node)
29
- self.new.inherit(node)
30
- end
31
-
32
- # @private
33
- def inherit(node)
34
- inherit_attrs node.attributes
35
- self
36
- end
28
+ module InstanceMethods
37
29
 
38
- # Get the name of the node
39
- #
40
- # @return [String, nil]
41
- def node
42
- c[:node]
43
- end
30
+ # @private
31
+ def inherit(node)
32
+ c.remove
33
+ super
34
+ self
35
+ end
44
36
 
45
- # Set the name of the node
46
- #
47
- # @param [String, nil] node the new node name
48
- def node=(node)
49
- c[:node] = node
50
- end
37
+ # Get the name of the node
38
+ #
39
+ # @return [String, nil]
40
+ def node
41
+ c[:node]
42
+ end
51
43
 
52
- # Get the name of the hash
53
- #
54
- # @return [Symbol, nil]
55
- def hash
56
- c[:hash].to_sym
57
- end
44
+ # Set the name of the node
45
+ #
46
+ # @param [String, nil] node the new node name
47
+ def node=(node)
48
+ c[:node] = node
49
+ end
58
50
 
59
- # Set the name of the hash
60
- #
61
- # @param [String, nil] hash the new hash name
62
- def hash=(hash)
63
- if hash && !VALID_HASH_TYPES.include?(hash.to_s)
64
- raise ArgumentError, "Invalid Hash Type (#{hash}), use: #{VALID_HASH_TYPES*' '}"
51
+ # Get the name of the hash
52
+ #
53
+ # @return [Symbol, nil]
54
+ def hash
55
+ c[:hash] && c[:hash].to_sym
65
56
  end
66
- c[:hash] = hash
67
- end
68
57
 
69
- # Get the ver
70
- #
71
- # @return [String, nil]
72
- def ver
73
- c[:ver]
74
- end
58
+ # Set the name of the hash
59
+ #
60
+ # @param [String, nil] hash the new hash name
61
+ def hash=(hash)
62
+ if hash && !VALID_HASH_TYPES.include?(hash.to_s)
63
+ raise ArgumentError, "Invalid Hash Type (#{hash}), use: #{VALID_HASH_TYPES*' '}"
64
+ end
65
+ c[:hash] = hash
66
+ end
75
67
 
76
- # Set the ver
77
- #
78
- # @param [String, nil] ver the new ver
79
- def ver=(ver)
80
- c[:ver] = ver
81
- end
68
+ # Get the ver
69
+ #
70
+ # @return [String, nil]
71
+ def ver
72
+ c[:ver]
73
+ end
82
74
 
83
- # C node accessor
84
- # If a c node exists it will be returned.
85
- # Otherwise a new node will be created and returned
86
- #
87
- # @return [Blather::XMPPNode]
88
- def c
89
- c = if self.class.registered_ns
90
- find_first('ns:c', :ns => self.class.registered_ns)
91
- else
92
- find_first('c')
75
+ # Set the ver
76
+ #
77
+ # @param [String, nil] ver the new ver
78
+ def ver=(ver)
79
+ c[:ver] = ver
93
80
  end
94
81
 
95
- unless c
96
- (self << (c = XMPPNode.new('c', self.document)))
97
- c.namespace = self.class.registered_ns
82
+ # C node accessor
83
+ # If a c node exists it will be returned.
84
+ # Otherwise a new node will be created and returned
85
+ #
86
+ # @return [Blather::XMPPNode]
87
+ def c
88
+ unless c = find_first('ns:c', :ns => C.registered_ns)
89
+ self << (c = XMPPNode.new('c', self.document))
90
+ c.namespace = self.class.registered_ns
91
+ end
92
+ c
98
93
  end
99
- c
100
94
  end
95
+
96
+ include InstanceMethods
101
97
  end # C
102
98
  end #Presence
103
99
  end #Stanza
@@ -11,19 +11,23 @@ class Presence
11
11
  new_node
12
12
  end
13
13
 
14
- def inherit(node)
15
- muc.remove
16
- super
17
- self
18
- end
14
+ module InstanceMethods
15
+ def inherit(node)
16
+ muc.remove
17
+ super
18
+ self
19
+ end
19
20
 
20
- def muc
21
- unless muc = find_first('ns:x', :ns => self.class.registered_ns)
22
- self << (muc = XMPPNode.new('x', self.document))
23
- muc.namespace = self.class.registered_ns
21
+ def muc
22
+ unless muc = find_first('ns:x', :ns => MUC.registered_ns)
23
+ self << (muc = XMPPNode.new('x', self.document))
24
+ muc.namespace = self.class.registered_ns
25
+ end
26
+ muc
24
27
  end
25
- muc
26
28
  end
29
+
30
+ include InstanceMethods
27
31
  end # MUC
28
32
 
29
33
  end # Presence
@@ -4,59 +4,70 @@ module Blather
4
4
  class Stanza
5
5
  class Presence
6
6
 
7
- class MUCUser < Status
7
+ class MUCUser < Presence
8
8
  include Blather::Stanza::MUC::MUCUserBase
9
9
 
10
- def affiliation
11
- item.affiliation
10
+ def self.decorator_modules
11
+ super + [Blather::Stanza::MUC::MUCUserBase]
12
12
  end
13
13
 
14
- def affiliation=(val)
15
- item.affiliation = val
16
- end
14
+ register :muc_user_presence, :x, MUC_USER_NAMESPACE
17
15
 
18
- def role
19
- item.role
20
- end
16
+ module InstanceMethods
21
17
 
22
- def role=(val)
23
- item.role = val
24
- end
18
+ def affiliation
19
+ item.affiliation
20
+ end
25
21
 
26
- def jid
27
- item.jid
28
- end
22
+ def affiliation=(val)
23
+ item.affiliation = val
24
+ end
29
25
 
30
- def jid=(val)
31
- item.jid = val
32
- end
26
+ def role
27
+ item.role
28
+ end
33
29
 
34
- def status_codes
35
- status.map &:code
36
- end
30
+ def role=(val)
31
+ item.role = val
32
+ end
37
33
 
38
- def status_codes=(val)
39
- muc_user.remove_children :status
40
- val.each do |code|
41
- muc_user << Status.new(code)
34
+ def jid
35
+ item.jid
42
36
  end
43
- end
44
37
 
45
- def item
46
- if item = muc_user.find_first('ns:item', :ns => self.class.registered_ns)
47
- Item.new item
48
- else
49
- muc_user << (item = Item.new nil, nil, nil, self.document)
50
- item
38
+ def jid=(val)
39
+ item.jid = val
40
+ end
41
+
42
+ def status_codes
43
+ status.map &:code
44
+ end
45
+
46
+ def status_codes=(val)
47
+ muc_user.remove_children :status
48
+ val.each do |code|
49
+ muc_user << Status.new(code)
50
+ end
51
51
  end
52
- end
53
52
 
54
- def status
55
- muc_user.find('ns:status', :ns => self.class.registered_ns).map do |status|
56
- Status.new status
53
+ def item
54
+ if item = muc_user.find_first('ns:item', :ns => MUCUser.registered_ns)
55
+ Item.new item
56
+ else
57
+ muc_user << (item = Item.new nil, nil, nil, self.document)
58
+ item
59
+ end
60
+ end
61
+
62
+ def status
63
+ muc_user.find('ns:status', :ns => MUCUser.registered_ns).map do |status|
64
+ Status.new status
65
+ end
57
66
  end
58
67
  end
59
68
 
69
+ include InstanceMethods
70
+
60
71
  class Item < XMPPNode
61
72
  def self.new(affiliation = nil, role = nil, jid = nil, document = nil)
62
73
  new_node = super :item, document
@@ -93,127 +93,132 @@ class Presence
93
93
  node
94
94
  end
95
95
 
96
- # Check if the state is available
97
- #
98
- # @return [true, false]
99
- def available?
100
- self.state == :available
101
- end
102
-
103
- # Check if the state is away
104
- #
105
- # @return [true, false]
106
- def away?
107
- self.state == :away
108
- end
96
+ module InstanceMethods
109
97
 
110
- # Check if the state is chat
111
- #
112
- # @return [true, false]
113
- def chat?
114
- self.state == :chat
115
- end
98
+ # Check if the state is available
99
+ #
100
+ # @return [true, false]
101
+ def available?
102
+ self.state == :available
103
+ end
116
104
 
117
- # Check if the state is dnd
118
- #
119
- # @return [true, false]
120
- def dnd?
121
- self.state == :dnd
122
- end
105
+ # Check if the state is away
106
+ #
107
+ # @return [true, false]
108
+ def away?
109
+ self.state == :away
110
+ end
123
111
 
124
- # Check if the state is xa
125
- #
126
- # @return [true, false]
127
- def xa?
128
- self.state == :xa
129
- end
112
+ # Check if the state is chat
113
+ #
114
+ # @return [true, false]
115
+ def chat?
116
+ self.state == :chat
117
+ end
130
118
 
131
- # Set the type attribute
132
- # Ensures type is nil or :unavailable
133
- #
134
- # @param [<:unavailable, nil>] type the type
135
- def type=(type)
136
- if type && type.to_sym != :unavailable
137
- raise ArgumentError, "Invalid type (#{type}). Must be nil or unavailable"
119
+ # Check if the state is dnd
120
+ #
121
+ # @return [true, false]
122
+ def dnd?
123
+ self.state == :dnd
138
124
  end
139
- super
140
- end
141
125
 
142
- # Set the state
143
- # Ensure state is one of :available, :away, :chat, :dnd, :xa or nil
144
- #
145
- # @param [<:available, :away, :chat, :dnd, :xa, nil>] state
146
- def state=(state) # :nodoc:
147
- state = state.to_sym if state
148
- state = nil if state == :available
149
- if state && !VALID_STATES.include?(state)
150
- raise ArgumentError, "Invalid Status (#{state}), use: #{VALID_STATES*' '}"
126
+ # Check if the state is xa
127
+ #
128
+ # @return [true, false]
129
+ def xa?
130
+ self.state == :xa
151
131
  end
152
132
 
153
- set_content_for :show, state
154
- end
133
+ # Set the type attribute
134
+ # Ensures type is nil or :unavailable
135
+ #
136
+ # @param [<:unavailable, nil>] type the type
137
+ def type=(type)
138
+ if type && type.to_sym != :unavailable
139
+ raise ArgumentError, "Invalid type (#{type}). Must be nil or unavailable"
140
+ end
141
+ super
142
+ end
155
143
 
156
- # Get the state of the status
157
- #
158
- # @return [<:available, :away, :chat, :dnd, :xa>]
159
- def state
160
- state = type || content_from(:show)
161
- state = :available if state.blank?
162
- state.to_sym
163
- end
144
+ # Set the state
145
+ # Ensure state is one of :available, :away, :chat, :dnd, :xa or nil
146
+ #
147
+ # @param [<:available, :away, :chat, :dnd, :xa, nil>] state
148
+ def state=(state) # :nodoc:
149
+ state = state.to_sym if state
150
+ state = nil if state == :available
151
+ if state && !VALID_STATES.include?(state)
152
+ raise ArgumentError, "Invalid Status (#{state}), use: #{VALID_STATES*' '}"
153
+ end
154
+
155
+ set_content_for :show, state
156
+ end
164
157
 
165
- # Set the priority of the status
166
- # Ensures priority is between -128 and 127
167
- #
168
- # @param [Fixnum<-128...127>] new_priority
169
- def priority=(new_priority) # :nodoc:
170
- if new_priority && !(-128..127).include?(new_priority.to_i)
171
- raise ArgumentError, 'Priority must be between -128 and +127'
158
+ # Get the state of the status
159
+ #
160
+ # @return [<:available, :away, :chat, :dnd, :xa>]
161
+ def state
162
+ state = type || content_from(:show)
163
+ state = :available if state.blank?
164
+ state.to_sym
172
165
  end
173
- set_content_for :priority, new_priority
174
- end
175
166
 
176
- # Get the priority of the status
177
- #
178
- # @return [Fixnum<-128...127>]
179
- def priority
180
- read_content(:priority).to_i
181
- end
167
+ # Set the priority of the status
168
+ # Ensures priority is between -128 and 127
169
+ #
170
+ # @param [Fixnum<-128...127>] new_priority
171
+ def priority=(new_priority) # :nodoc:
172
+ if new_priority && !(-128..127).include?(new_priority.to_i)
173
+ raise ArgumentError, 'Priority must be between -128 and +127'
174
+ end
175
+ set_content_for :priority, new_priority
176
+ end
182
177
 
183
- # Get the status message
184
- #
185
- # @return [String, nil]
186
- def message
187
- read_content :status
188
- end
178
+ # Get the priority of the status
179
+ #
180
+ # @return [Fixnum<-128...127>]
181
+ def priority
182
+ read_content(:priority).to_i
183
+ end
189
184
 
190
- # Set the status message
191
- #
192
- # @param [String, nil] message
193
- def message=(message)
194
- set_content_for :status, message
195
- end
185
+ # Get the status message
186
+ #
187
+ # @return [String, nil]
188
+ def message
189
+ read_content :status
190
+ end
196
191
 
197
- # Compare status based on priority and state:
198
- # unavailable status is always less valuable than others
199
- # Raises an error if the JIDs aren't the same
200
- #
201
- # @param [Blather::Stanza::Presence::Status] o
202
- # @return [true,false]
203
- def <=>(o)
204
- unless self.from && o.from && self.from.stripped == o.from.stripped
205
- raise ArgumentError, "Cannot compare status from different JIDs: #{[self.from, o.from].inspect}"
192
+ # Set the status message
193
+ #
194
+ # @param [String, nil] message
195
+ def message=(message)
196
+ set_content_for :status, message
206
197
  end
207
198
 
208
- if (self.type.nil? && o.type.nil?) || (!self.type.nil? && !o.type.nil?)
209
- self.priority <=> o.priority
210
- elsif self.type.nil? && !o.type.nil?
211
- 1
212
- elsif !self.type.nil? && o.type.nil?
213
- -1
199
+ # Compare status based on priority and state:
200
+ # unavailable status is always less valuable than others
201
+ # Raises an error if the JIDs aren't the same
202
+ #
203
+ # @param [Blather::Stanza::Presence::Status] o
204
+ # @return [true,false]
205
+ def <=>(o)
206
+ unless self.from && o.from && self.from.stripped == o.from.stripped
207
+ raise ArgumentError, "Cannot compare status from different JIDs: #{[self.from, o.from].inspect}"
208
+ end
209
+
210
+ if (self.type.nil? && o.type.nil?) || (!self.type.nil? && !o.type.nil?)
211
+ self.priority <=> o.priority
212
+ elsif self.type.nil? && !o.type.nil?
213
+ 1
214
+ elsif !self.type.nil? && o.type.nil?
215
+ -1
216
+ end
214
217
  end
215
218
  end
216
219
 
220
+ include InstanceMethods
221
+
217
222
  end #Status
218
223
 
219
224
  end #Presence