blather 0.4.7 → 0.4.8
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.
- data/README.md +162 -0
- data/examples/{print_heirarchy.rb → print_hierarchy.rb} +5 -5
- data/examples/stream_only.rb +27 -0
- data/lib/blather.rb +4 -0
- data/lib/blather/client/client.rb +91 -73
- data/lib/blather/client/dsl.rb +156 -32
- data/lib/blather/client/dsl/pubsub.rb +86 -54
- data/lib/blather/core_ext/active_support.rb +9 -9
- data/lib/blather/core_ext/active_support/inheritable_attributes.rb +2 -2
- data/lib/blather/core_ext/nokogiri.rb +12 -7
- data/lib/blather/errors.rb +25 -14
- data/lib/blather/errors/sasl_error.rb +21 -3
- data/lib/blather/errors/stanza_error.rb +37 -21
- data/lib/blather/errors/stream_error.rb +27 -17
- data/lib/blather/jid.rb +79 -24
- data/lib/blather/roster.rb +39 -21
- data/lib/blather/roster_item.rb +43 -21
- data/lib/blather/stanza.rb +88 -40
- data/lib/blather/stanza/disco.rb +12 -2
- data/lib/blather/stanza/disco/disco_info.rb +112 -20
- data/lib/blather/stanza/disco/disco_items.rb +81 -12
- data/lib/blather/stanza/iq.rb +94 -38
- data/lib/blather/stanza/iq/query.rb +16 -22
- data/lib/blather/stanza/iq/roster.rb +98 -20
- data/lib/blather/stanza/message.rb +266 -111
- data/lib/blather/stanza/presence.rb +118 -42
- data/lib/blather/stanza/presence/status.rb +140 -60
- data/lib/blather/stanza/presence/subscription.rb +44 -10
- data/lib/blather/stanza/pubsub.rb +70 -15
- data/lib/blather/stanza/pubsub/affiliations.rb +36 -7
- data/lib/blather/stanza/pubsub/create.rb +26 -4
- data/lib/blather/stanza/pubsub/errors.rb +13 -4
- data/lib/blather/stanza/pubsub/event.rb +56 -10
- data/lib/blather/stanza/pubsub/items.rb +46 -6
- data/lib/blather/stanza/pubsub/publish.rb +52 -7
- data/lib/blather/stanza/pubsub/retract.rb +45 -6
- data/lib/blather/stanza/pubsub/subscribe.rb +30 -4
- data/lib/blather/stanza/pubsub/subscription.rb +74 -6
- data/lib/blather/stanza/pubsub/subscriptions.rb +35 -9
- data/lib/blather/stanza/pubsub/unsubscribe.rb +30 -4
- data/lib/blather/stanza/pubsub_owner.rb +17 -7
- data/lib/blather/stanza/pubsub_owner/delete.rb +23 -5
- data/lib/blather/stanza/pubsub_owner/purge.rb +23 -5
- data/lib/blather/stream.rb +96 -29
- data/lib/blather/stream/parser.rb +6 -9
- data/lib/blather/xmpp_node.rb +101 -153
- data/spec/blather/client/client_spec.rb +1 -1
- data/spec/blather/errors_spec.rb +5 -5
- data/spec/blather/stanza/message_spec.rb +56 -0
- data/spec/blather/stanza/presence/status_spec.rb +1 -1
- data/spec/blather/stanza_spec.rb +3 -3
- data/spec/blather/xmpp_node_spec.rb +19 -74
- metadata +6 -10
- data/README.rdoc +0 -185
- data/examples/drb_client.rb +0 -5
- data/examples/ping.rb +0 -11
- data/examples/pong.rb +0 -6
- data/examples/pubsub/cli.rb +0 -64
- data/examples/pubsub/ping_pong.rb +0 -18
@@ -42,7 +42,6 @@ class Stream # :nodoc:
|
|
42
42
|
@current = node
|
43
43
|
end
|
44
44
|
|
45
|
-
|
46
45
|
ns_keys = namespaces.map { |pre, href| pre }
|
47
46
|
namespaces.delete_if { |pre, href| NS_TO_IGNORE.include? href }
|
48
47
|
@namespace_definitions.push []
|
@@ -56,14 +55,12 @@ class Stream # :nodoc:
|
|
56
55
|
|
57
56
|
deliver(node) if elem == 'stream'
|
58
57
|
|
59
|
-
|
60
|
-
$stderr.puts
|
61
|
-
$stderr.puts
|
62
|
-
$stderr.puts @namespaces.inspect
|
63
|
-
$stderr.puts
|
64
|
-
$stderr.puts node.
|
65
|
-
$stderr.puts node.document.to_s.gsub(/\n\s*/,'')
|
66
|
-
=end
|
58
|
+
# $stderr.puts "\n\n"
|
59
|
+
# $stderr.puts [elem, attrs, prefix, uri, namespaces].inspect
|
60
|
+
# $stderr.puts @namespaces.inspect
|
61
|
+
# $stderr.puts [@namespaces[[prefix, uri]].prefix, @namespaces[[prefix, uri]].href].inspect if @namespaces[[prefix, uri]]
|
62
|
+
# $stderr.puts node.inspect
|
63
|
+
# $stderr.puts node.document.to_s.gsub(/\n\s*/,'')
|
67
64
|
end
|
68
65
|
|
69
66
|
def end_element_namespace(elem, prefix, uri)
|
data/lib/blather/xmpp_node.rb
CHANGED
@@ -1,42 +1,50 @@
|
|
1
1
|
module Blather
|
2
2
|
|
3
|
-
##
|
4
3
|
# Base XML Node
|
5
|
-
# All XML classes subclass XMPPNode
|
6
|
-
# it allows the addition of helpers
|
4
|
+
# All XML classes subclass XMPPNode it allows the addition of helpers
|
7
5
|
class XMPPNode < Nokogiri::XML::Node
|
6
|
+
# @private
|
8
7
|
BASE_NAMES = %w[presence message iq].freeze
|
9
8
|
|
9
|
+
# @private
|
10
10
|
@@registrations = {}
|
11
11
|
|
12
12
|
class_inheritable_accessor :registered_ns,
|
13
13
|
:registered_name
|
14
14
|
|
15
|
-
|
16
|
-
# Lets a subclass register itself
|
15
|
+
# Register a new stanza class to a name and/or namespace
|
17
16
|
#
|
18
17
|
# This registers a namespace that is used when looking
|
19
18
|
# up the class name of the object to instantiate when a new
|
20
19
|
# stanza is received
|
20
|
+
#
|
21
|
+
# @param [#to_s] name the name of the node
|
22
|
+
# @param [String, nil] ns the namespace the node belongs to
|
21
23
|
def self.register(name, ns = nil)
|
22
24
|
self.registered_name = name.to_s
|
23
25
|
self.registered_ns = ns
|
24
26
|
@@registrations[[self.registered_name, self.registered_ns]] = self
|
25
27
|
end
|
26
28
|
|
27
|
-
##
|
28
29
|
# Find the class to use given the name and namespace of a stanza
|
29
|
-
|
30
|
+
#
|
31
|
+
# @param [#to_s] name the name to lookup
|
32
|
+
# @param [String, nil] xmlns the namespace the node belongs to
|
33
|
+
# @return [Class, nil] the class appropriate for the name/ns combination
|
34
|
+
def self.class_from_registration(name, ns = nil)
|
30
35
|
name = name.to_s
|
31
|
-
@@registrations[[name,
|
36
|
+
@@registrations[[name, ns]] || @@registrations[[name, nil]]
|
32
37
|
end
|
33
38
|
|
34
|
-
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
39
|
+
# Import an XML::Node to the appropriate class
|
40
|
+
#
|
41
|
+
# Looks up the class the node should be then creates it based on the
|
42
|
+
# elements of the XML::Node
|
43
|
+
# @param [XML::Node] node the node to import
|
44
|
+
# @return the appropriate object based on the node name and namespace
|
38
45
|
def self.import(node)
|
39
|
-
|
46
|
+
ns = (node.namespace.href if node.namespace)
|
47
|
+
klass = class_from_registration(node.element_name, ns)
|
40
48
|
if klass && klass != self
|
41
49
|
klass.import(node)
|
42
50
|
else
|
@@ -44,151 +52,71 @@ module Blather
|
|
44
52
|
end
|
45
53
|
end
|
46
54
|
|
47
|
-
|
48
|
-
# Provides an attribute reader helper. Default behavior is to
|
49
|
-
# conver the values of the attribute into a symbol. This can
|
50
|
-
# be turned off by passing <tt>:to_sym => false</tt>
|
55
|
+
# Create a new Node object
|
51
56
|
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
# n[:type] = 'foo'
|
59
|
-
# n.type == :foo
|
60
|
-
# n[:name] = 'bar'
|
61
|
-
# n.name == 'bar'
|
62
|
-
def self.attribute_reader(*syms)
|
63
|
-
opts = syms.last.is_a?(Hash) ? syms.pop : {}
|
64
|
-
convert_str = "val.#{opts[:call]} if val" if opts[:call]
|
65
|
-
syms.flatten.each do |sym|
|
66
|
-
class_eval(<<-END, __FILE__, __LINE__)
|
67
|
-
def #{sym}
|
68
|
-
val = self[:#{sym}]
|
69
|
-
#{convert_str}
|
70
|
-
end
|
71
|
-
END
|
72
|
-
end
|
73
|
-
end
|
57
|
+
# @param [String, nil] name the element name
|
58
|
+
# @param [XML::Document, nil] doc the document to attach the node to. If
|
59
|
+
# not provided one will be created
|
60
|
+
# @return a new object with the registered name and namespace
|
61
|
+
def self.new(name = nil, doc = nil)
|
62
|
+
name ||= self.registered_name
|
74
63
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
# attribute_writer :type
|
80
|
-
# end
|
81
|
-
#
|
82
|
-
# n = Node.new
|
83
|
-
# n.type = 'foo'
|
84
|
-
# n[:type] == 'foo'
|
85
|
-
def self.attribute_writer(*syms)
|
86
|
-
syms.flatten.each do |sym|
|
87
|
-
next if sym.is_a?(Hash)
|
88
|
-
class_eval(<<-END, __FILE__, __LINE__)
|
89
|
-
def #{sym}=(value)
|
90
|
-
self[:#{sym}] = value
|
91
|
-
end
|
92
|
-
END
|
93
|
-
end
|
64
|
+
node = super name.to_s, (doc || Nokogiri::XML::Document.new)
|
65
|
+
node.document.root = node unless doc
|
66
|
+
node.namespace = self.registered_ns unless BASE_NAMES.include?(name.to_s)
|
67
|
+
node
|
94
68
|
end
|
95
69
|
|
96
|
-
|
97
|
-
# Provides an attribute accessor helper combining
|
98
|
-
# <tt>attribute_reader</tt> and <tt>attribute_writer</tt>
|
99
|
-
#
|
100
|
-
# class Node
|
101
|
-
# attribute_accessor :type
|
102
|
-
# attribute_accessor :name, :to_sym => false
|
103
|
-
# end
|
70
|
+
# Helper method to read an attribute
|
104
71
|
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
attribute_writer *syms
|
72
|
+
# @param [#to_sym] attr_name the name of the attribute
|
73
|
+
# @param [String, Symbol, nil] to_call the name of the method to call on
|
74
|
+
# the returned value
|
75
|
+
# @return nil or the value
|
76
|
+
def read_attr(attr_name, to_call = nil)
|
77
|
+
val = self[attr_name.to_sym]
|
78
|
+
val && to_call ? val.__send__(to_call) : val
|
113
79
|
end
|
114
80
|
|
115
|
-
|
116
|
-
# Provides a content reader helper that returns the content of a node
|
117
|
-
# +method+ is the method to create
|
118
|
-
# +conversion+ is a method to call on the content before sending it back
|
119
|
-
# +node+ is the name of the content node (this defaults to the method name)
|
81
|
+
# Helper method to write a value to an attribute
|
120
82
|
#
|
121
|
-
#
|
122
|
-
#
|
123
|
-
|
124
|
-
|
125
|
-
# end
|
126
|
-
#
|
127
|
-
# n = Node.new 'foo'
|
128
|
-
# n.to_s == "<foo><body>foobarbaz</body><type>error</type><identity>1000</identity></foo>"
|
129
|
-
# n.body == 'foobarbaz'
|
130
|
-
# n.type == :error
|
131
|
-
# n.id == 1000
|
132
|
-
def self.content_attr_reader(method, conversion = nil, node = nil)
|
133
|
-
node ||= method
|
134
|
-
conversion = "val.#{conversion} if val.respond_to?(:#{conversion})" if conversion
|
135
|
-
class_eval(<<-END, __FILE__, __LINE__)
|
136
|
-
def #{method}
|
137
|
-
val = content_from :#{node}
|
138
|
-
#{conversion}
|
139
|
-
end
|
140
|
-
END
|
83
|
+
# @param [#to_sym] attr_name the name of the attribute
|
84
|
+
# @param [#to_s] value the value to set the attribute to
|
85
|
+
def write_attr(attr_name, value)
|
86
|
+
self[attr_name.to_sym] = value
|
141
87
|
end
|
142
88
|
|
143
|
-
|
144
|
-
# Provides a content writer helper that creates or updates the content of a node
|
145
|
-
# +method+ is the method to create
|
146
|
-
# +node+ is the name of the node to create (defaults to the method name)
|
147
|
-
#
|
148
|
-
# class Node
|
149
|
-
# content_attr_writer :body
|
150
|
-
# content_attr_writer :id, :identity
|
151
|
-
# end
|
89
|
+
# Helper method to read the content of a node
|
152
90
|
#
|
153
|
-
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
#
|
157
|
-
def
|
158
|
-
|
159
|
-
|
160
|
-
def #{method}=(val)
|
161
|
-
set_content_for :#{node}, val
|
162
|
-
end
|
163
|
-
END
|
164
|
-
end
|
165
|
-
|
166
|
-
##
|
167
|
-
# Provides a quick way of building +content_attr_reader+ and +content_attr_writer+
|
168
|
-
# for the same method and node
|
169
|
-
def self.content_attr_accessor(method, conversion = nil, node = nil)
|
170
|
-
content_attr_reader method, conversion, node
|
171
|
-
content_attr_writer method, node
|
91
|
+
# @param [#to_sym] node the name of the node
|
92
|
+
# @param [String, Symbol, nil] to_call the name of the method to call on
|
93
|
+
# the returned value
|
94
|
+
# @return nil or the value
|
95
|
+
def read_content(node, to_call = nil)
|
96
|
+
val = content_from node.to_sym
|
97
|
+
val && to_call ? val.__send__(to_call) : val
|
172
98
|
end
|
173
99
|
|
174
|
-
|
175
|
-
#
|
176
|
-
|
177
|
-
name ||= self.registered_name
|
178
|
-
|
179
|
-
node = super name.to_s, (doc || Nokogiri::XML::Document.new)
|
180
|
-
node.document.root = node unless doc
|
181
|
-
node.namespace = self.registered_ns unless BASE_NAMES.include?(name.to_s)
|
182
|
-
node
|
183
|
-
end
|
184
|
-
|
185
|
-
##
|
186
|
-
# Quickway of turning itself into a proper object
|
100
|
+
# Turn the object into a proper stanza
|
101
|
+
#
|
102
|
+
# @return a stanza object
|
187
103
|
def to_stanza
|
188
104
|
self.class.import self
|
189
105
|
end
|
190
106
|
|
107
|
+
# @private
|
191
108
|
alias_method :nokogiri_namespace=, :namespace=
|
109
|
+
# Attach a namespace to the node
|
110
|
+
#
|
111
|
+
# @overload namespace=(ns)
|
112
|
+
# Attach an already created XML::Namespace
|
113
|
+
# @param [XML::Namespace] ns the namespace object
|
114
|
+
# @overload namespace=(ns)
|
115
|
+
# Create a new namespace and attach it
|
116
|
+
# @param [String] ns the namespace uri
|
117
|
+
# @overload namespace=(namespaces)
|
118
|
+
# Createa and add new namespaces from a hash
|
119
|
+
# @param [Hash] namespaces a hash of prefix => uri pairs
|
192
120
|
def namespace=(namespaces)
|
193
121
|
case namespaces
|
194
122
|
when Nokogiri::XML::Namespace
|
@@ -206,34 +134,46 @@ module Blather
|
|
206
134
|
end
|
207
135
|
end
|
208
136
|
|
137
|
+
# Helper method to get the node's namespace
|
138
|
+
#
|
139
|
+
# @return [XML::Namespace, nil] The node's namespace object if it exists
|
209
140
|
def namespace_href
|
210
141
|
namespace.href if namespace
|
211
142
|
end
|
212
143
|
|
213
|
-
##
|
214
144
|
# Remove a child with the name and (optionally) namespace given
|
145
|
+
#
|
146
|
+
# @param [String] name the name or xpath of the node to remove
|
147
|
+
# @param [String, nil] ns the namespace the node is in
|
215
148
|
def remove_child(name, ns = nil)
|
216
149
|
child = xpath(name, ns).first
|
217
150
|
child.remove if child
|
218
151
|
end
|
219
152
|
|
220
|
-
|
221
|
-
#
|
153
|
+
# Remove all children with a given name regardless of namespace
|
154
|
+
#
|
155
|
+
# @param [String] name the name of the nodes to remove
|
222
156
|
def remove_children(name)
|
223
157
|
xpath("./*[local-name()='#{name}']").remove
|
224
158
|
end
|
225
159
|
|
226
|
-
|
227
|
-
#
|
160
|
+
# The content of the named node
|
161
|
+
#
|
162
|
+
# @param [String] name the name or xpath of the node
|
163
|
+
# @param [String, nil] ns the namespace the node is in
|
164
|
+
# @return [String, nil] the content of the node
|
228
165
|
def content_from(name, ns = nil)
|
229
166
|
child = xpath(name, ns).first
|
230
167
|
child.content if child
|
231
168
|
end
|
232
169
|
|
233
|
-
##
|
234
170
|
# Sets the content for the specified node.
|
235
171
|
# If the node exists it is updated. If not a new node is created
|
236
|
-
# If the node exists and the content is nil, the node will be removed
|
172
|
+
# If the node exists and the content is nil, the node will be removed
|
173
|
+
# entirely
|
174
|
+
#
|
175
|
+
# @param [String] node the name of the node to update/create
|
176
|
+
# @param [String, nil] content the content to set within the node
|
237
177
|
def set_content_for(node, content = nil)
|
238
178
|
if content
|
239
179
|
child = xpath(node).first
|
@@ -246,8 +186,10 @@ module Blather
|
|
246
186
|
|
247
187
|
alias_method :copy, :dup
|
248
188
|
|
249
|
-
|
250
|
-
#
|
189
|
+
# Inherit the attributes and children of an XML::Node
|
190
|
+
#
|
191
|
+
# @param [XML::Node] stanza the node to inherit
|
192
|
+
# @return [self]
|
251
193
|
def inherit(stanza)
|
252
194
|
set_namespace stanza.namespace if stanza.namespace
|
253
195
|
inherit_attrs stanza.attributes
|
@@ -259,12 +201,18 @@ module Blather
|
|
259
201
|
self
|
260
202
|
end
|
261
203
|
|
262
|
-
|
263
|
-
#
|
204
|
+
# Inherit a set of attributes
|
205
|
+
#
|
206
|
+
# @param [Hash] attrs a hash of attributes to set on the node
|
207
|
+
# @return [self]
|
264
208
|
def inherit_attrs(attrs)
|
265
209
|
attrs.each { |name, value| self[name] = value }
|
266
210
|
self
|
267
211
|
end
|
268
|
-
end #XMPPNode
|
269
212
|
|
270
|
-
|
213
|
+
def inspect
|
214
|
+
self.to_xml
|
215
|
+
end
|
216
|
+
end # XMPPNode
|
217
|
+
|
218
|
+
end # Blather
|
@@ -164,7 +164,7 @@ describe Blather::Client do
|
|
164
164
|
@client.receive_data stanza
|
165
165
|
end
|
166
166
|
|
167
|
-
it 'allows for passing to the next handler in the
|
167
|
+
it 'allows for passing to the next handler in the hierarchy' do
|
168
168
|
stanza = Blather::Stanza::Iq::Query.new
|
169
169
|
response = mock(:query => nil, :iq => nil)
|
170
170
|
@client.register_handler(:query) do |_|
|
data/spec/blather/errors_spec.rb
CHANGED
@@ -2,15 +2,15 @@ require File.join(File.dirname(__FILE__), *%w[.. spec_helper])
|
|
2
2
|
|
3
3
|
describe Blather::BlatherError do
|
4
4
|
it 'is handled by :error' do
|
5
|
-
Blather::BlatherError.new.
|
5
|
+
Blather::BlatherError.new.handler_hierarchy.must_equal [:error]
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
describe 'Blather::ParseError' do
|
10
10
|
before { @error = Blather::ParseError.new('</generate-parse-error>"') }
|
11
11
|
|
12
|
-
it 'is registers with the handler
|
13
|
-
@error.
|
12
|
+
it 'is registers with the handler hierarchy' do
|
13
|
+
@error.handler_hierarchy.must_equal [:parse_error, :error]
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'contains the error message' do
|
@@ -22,8 +22,8 @@ end
|
|
22
22
|
describe 'Blather::UnknownResponse' do
|
23
23
|
before { @error = Blather::UnknownResponse.new(Blather::XMPPNode.new('foo-bar')) }
|
24
24
|
|
25
|
-
it 'is registers with the handler
|
26
|
-
@error.
|
25
|
+
it 'is registers with the handler hierarchy' do
|
26
|
+
@error.handler_hierarchy.must_equal [:unknown_response_error, :error]
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'holds on to a copy of the failure node' do
|
@@ -73,4 +73,60 @@ describe Blather::Stanza::Message do
|
|
73
73
|
Blather::Stanza::Message.new.must_respond_to :"#{valid_type}?"
|
74
74
|
end
|
75
75
|
end
|
76
|
+
|
77
|
+
it 'ensures an html node exists when asked for xhtml_node' do
|
78
|
+
search_args = [
|
79
|
+
'/message/html_ns:html',
|
80
|
+
{:html_ns => Blather::Stanza::Message::HTML_NS}
|
81
|
+
]
|
82
|
+
msg = Blather::Stanza::Message.new
|
83
|
+
msg.find_first(*search_args).must_be_nil
|
84
|
+
|
85
|
+
msg.xhtml_node
|
86
|
+
msg.find_first(*search_args).wont_be_nil
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'ensures a body node exists when asked for xhtml_node' do
|
90
|
+
search_args = [
|
91
|
+
'/message/html_ns:html/body_ns:body',
|
92
|
+
{:html_ns => Blather::Stanza::Message::HTML_NS,
|
93
|
+
:body_ns => Blather::Stanza::Message::HTML_BODY_NS}
|
94
|
+
]
|
95
|
+
msg = Blather::Stanza::Message.new
|
96
|
+
msg.find_first(*search_args).must_be_nil
|
97
|
+
|
98
|
+
msg.xhtml_node
|
99
|
+
msg.find_first(*search_args).wont_be_nil
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns an existing node when asked for xhtml_node' do
|
103
|
+
msg = Blather::Stanza::Message.new
|
104
|
+
msg << (h = Blather::XMPPNode.new('html', msg.document))
|
105
|
+
h.namespace = Blather::Stanza::Message::HTML_NS
|
106
|
+
h << (b = Blather::XMPPNode.new('body', msg.document))
|
107
|
+
b.namespace = Blather::Stanza::Message::HTML_BODY_NS
|
108
|
+
|
109
|
+
msg.xhtml_node.must_equal(b)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'has an xhtml setter' do
|
113
|
+
msg = Blather::Stanza::Message.new
|
114
|
+
xhtml = "<some>xhtml</some>"
|
115
|
+
msg.xhtml = xhtml
|
116
|
+
msg.xhtml_node.content.strip.must_equal(xhtml)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'sets valid xhtml even if the input is not valid' do
|
120
|
+
msg = Blather::Stanza::Message.new
|
121
|
+
xhtml = "<some>xhtml"
|
122
|
+
msg.xhtml = xhtml
|
123
|
+
msg.xhtml_node.content.strip.must_equal("<some>xhtml</some>")
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'has an xhtml getter' do
|
127
|
+
msg = Blather::Stanza::Message.new
|
128
|
+
xhtml = "<some>xhtml</some>"
|
129
|
+
msg.xhtml = xhtml
|
130
|
+
msg.xhtml.must_equal(xhtml)
|
131
|
+
end
|
76
132
|
end
|