skates 0.1.11
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/LICENSE +20 -0
- data/README.rdoc +113 -0
- data/Rakefile +143 -0
- data/bin/skates +6 -0
- data/lib/skates.rb +108 -0
- data/lib/skates/base/controller.rb +116 -0
- data/lib/skates/base/stanza.rb +23 -0
- data/lib/skates/base/view.rb +58 -0
- data/lib/skates/client_connection.rb +210 -0
- data/lib/skates/component_connection.rb +87 -0
- data/lib/skates/generator.rb +139 -0
- data/lib/skates/router.rb +101 -0
- data/lib/skates/router/dsl.rb +61 -0
- data/lib/skates/runner.rb +137 -0
- data/lib/skates/xmpp_connection.rb +172 -0
- data/lib/skates/xmpp_parser.rb +117 -0
- data/lib/skates/xpath_helper.rb +13 -0
- data/spec/bin/babylon_spec.rb +0 -0
- data/spec/em_mock.rb +42 -0
- data/spec/lib/babylon/base/controller_spec.rb +205 -0
- data/spec/lib/babylon/base/stanza_spec.rb +15 -0
- data/spec/lib/babylon/base/view_spec.rb +92 -0
- data/spec/lib/babylon/client_connection_spec.rb +304 -0
- data/spec/lib/babylon/component_connection_spec.rb +135 -0
- data/spec/lib/babylon/generator_spec.rb +10 -0
- data/spec/lib/babylon/router/dsl_spec.rb +72 -0
- data/spec/lib/babylon/router_spec.rb +189 -0
- data/spec/lib/babylon/runner_spec.rb +213 -0
- data/spec/lib/babylon/xmpp_connection_spec.rb +197 -0
- data/spec/lib/babylon/xmpp_parser_spec.rb +275 -0
- data/spec/lib/babylon/xpath_helper_spec.rb +25 -0
- data/spec/spec_helper.rb +34 -0
- data/templates/skates/app/controllers/controller.rb +7 -0
- data/templates/skates/app/stanzas/stanza.rb +6 -0
- data/templates/skates/app/views/view.rb +6 -0
- data/templates/skates/config/boot.rb +16 -0
- data/templates/skates/config/config.yaml +24 -0
- data/templates/skates/config/dependencies.rb +1 -0
- data/templates/skates/config/routes.rb +22 -0
- data/templates/skates/log/development.log +0 -0
- data/templates/skates/log/production.log +0 -0
- data/templates/skates/log/test.log +0 -0
- data/templates/skates/script/component +36 -0
- data/templates/skates/tmp/pids/README +2 -0
- data/test/skates_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +160 -0
@@ -0,0 +1,197 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../../em_mock'
|
3
|
+
|
4
|
+
describe Skates::XmppConnection do
|
5
|
+
|
6
|
+
include SkatesSpecHelper
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
@params = {"jid" => "jid@server", "password" => "password", "port" => 1234, "host" => "myhost.com"}
|
10
|
+
@connection = Skates::XmppConnection.connect(@params, handler_mock)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "connect" do
|
14
|
+
it "should connect EventMachine and return it" do
|
15
|
+
EventMachine.should_receive(:connect).with(@params["host"], @params["port"], Skates::XmppConnection, hash_including("handler" => handler_mock)).and_return(@connection)
|
16
|
+
Skates::XmppConnection.connect(@params, handler_mock).should == @connection
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should rescue Connection Errors" do
|
20
|
+
EventMachine.stub!(:connect).with(@params["host"], @params["port"], Skates::XmppConnection, hash_including("handler" => handler_mock)).and_raise(RuntimeError)
|
21
|
+
lambda {
|
22
|
+
Skates::XmppConnection.connect(@params, handler_mock)
|
23
|
+
}.should raise_error(Skates::NotConnected)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "initialize" do
|
29
|
+
it "should assign @connected to false" do
|
30
|
+
@connection.instance_variable_get("@connected").should be_false
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should assign @jid to params['jid']" do
|
34
|
+
@connection.instance_variable_get("@jid").should == @params["jid"]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should assign @password to params['password']" do
|
38
|
+
@connection.instance_variable_get("@password").should == @params["password"]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should assign @host to params['host']" do
|
42
|
+
@connection.instance_variable_get("@host").should == @params["host"]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should assign @port to params['port']" do
|
46
|
+
@connection.instance_variable_get("@port").should == @params["port"]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should assign @handler to params['handler']" do
|
50
|
+
@connection.instance_variable_get("@handler").should == handler_mock
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should assign @buffer to ''" do
|
54
|
+
@connection.instance_variable_get("@buffer").should == ""
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "post_init" do
|
59
|
+
it "assigne a new parser" do
|
60
|
+
parser = Skates::XmppParser.new(@connection.method(:receive_stanza))
|
61
|
+
Skates::XmppParser.should_receive(:new).and_return(parser)
|
62
|
+
@connection.post_init
|
63
|
+
@connection.instance_variable_get("@parser").should == parser
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "connection_completed" do
|
68
|
+
it "should set @connected to true" do
|
69
|
+
@connection.connection_completed
|
70
|
+
@connection.instance_variable_get("@connected").should be_true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "unbind" do
|
75
|
+
it "should set @connected to false" do
|
76
|
+
@connection.connection_completed
|
77
|
+
@connection.unbind
|
78
|
+
@connection.instance_variable_get("@connected").should be_false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "receive_stanza" do
|
83
|
+
|
84
|
+
before(:each) do
|
85
|
+
@doc = Nokogiri::XML::Document.new
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "with an stanza that starts with stream:error" do
|
89
|
+
|
90
|
+
before(:each) do
|
91
|
+
@error_stanza = Nokogiri::XML::Node.new("stream:error", @doc)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should close the connection" do
|
95
|
+
@connection.should_receive(:close_connection)
|
96
|
+
@connection.receive_stanza(@error_stanza)
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "with a malformed stanza error" do
|
100
|
+
before(:each) do
|
101
|
+
@xml_not_well_formed_stanza = Nokogiri::XML::Node.new("xml-not-well-formed", @doc)
|
102
|
+
@xml_not_well_formed_stanza.add_namespace("xmlns", "urn:ietf:params:xml:ns:xmpp-streams")
|
103
|
+
@error_stanza.add_child(@xml_not_well_formed_stanza)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "with a stanza that is not an error" do
|
110
|
+
it "should call the on_stanza block" do
|
111
|
+
stanza = Nokogiri::XML::Node.new("message", @doc)
|
112
|
+
handler_mock.should_receive(:on_stanza)
|
113
|
+
@connection.receive_stanza(stanza)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "send_chunk" do
|
120
|
+
it "should raise an error if not connected" do
|
121
|
+
@connection.instance_variable_set("@connected", false)
|
122
|
+
lambda {
|
123
|
+
@connection.__send__(:send_chunk, "hello world")
|
124
|
+
}.should raise_error(Skates::NotConnected)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should raise an error if the stanza size is above the limit" do
|
128
|
+
@connection.instance_variable_set("@connected", true)
|
129
|
+
string = "a" * (Skates::XmppConnection.max_stanza_size + 1)
|
130
|
+
lambda {
|
131
|
+
@connection.__send__(:send_chunk, string)
|
132
|
+
}.should raise_error(Skates::StanzaTooBig)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should return if the string is blank" do
|
136
|
+
@connection.instance_variable_set("@connected", true)
|
137
|
+
@connection.should_not_receive(:send_data)
|
138
|
+
@connection.__send__(:send_chunk, "")
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should cann send_data with the string" do
|
142
|
+
@connection.instance_variable_set("@connected", true)
|
143
|
+
string = "hello world"
|
144
|
+
@connection.should_receive(:send_data).with(string)
|
145
|
+
@connection.__send__(:send_chunk, string)
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "send_xml" do
|
151
|
+
|
152
|
+
before(:each) do
|
153
|
+
@connection.instance_variable_set("@connected", true)
|
154
|
+
@connection.stub!(:send_chunk).and_return(true)
|
155
|
+
@doc = Nokogiri::XML::Document.new
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "with a nodeset as argument" do
|
159
|
+
before(:each) do
|
160
|
+
iq = Nokogiri::XML::Node.new("iq", @doc)
|
161
|
+
message = Nokogiri::XML::Node.new("message", @doc)
|
162
|
+
presence = Nokogiri::XML::Node.new("presence", @doc)
|
163
|
+
@node_set = Nokogiri::XML::NodeSet.new(@doc, [message, presence, iq])
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should call send_chunk for each of the nodes in the set" do
|
167
|
+
@node_set.each do |node|
|
168
|
+
@connection.should_receive(:send_chunk).with(node.to_s)
|
169
|
+
end
|
170
|
+
@connection.send_xml(@node_set)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "with an argument with is not a NodeSet" do
|
175
|
+
before(:each) do
|
176
|
+
@message = Nokogiri::XML::Node.new("message", @doc)
|
177
|
+
end
|
178
|
+
it "should call send_chunk for the node" do
|
179
|
+
@connection.should_receive(:send_chunk).with(@message.to_s)
|
180
|
+
@connection.send_xml(@message)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "receive_data" do
|
186
|
+
before(:each) do
|
187
|
+
@connection.instance_variable_get("@parser").stub!(:push).and_return(true)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should push the received data to the parser" do
|
191
|
+
data = "<hello>hello world!</hello>"
|
192
|
+
@connection.instance_variable_get("@parser").should_receive(:push).with(data).and_return(true)
|
193
|
+
@connection.__send__(:receive_data, data)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
@@ -0,0 +1,275 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Skates::XmppParser do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@last_stanza = ""
|
7
|
+
@proc = mock(Proc, :call => true)
|
8
|
+
@parser = Skates::XmppParser.new(@proc)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".reset" do
|
12
|
+
it "should reset the document to nil" do
|
13
|
+
@parser.reset
|
14
|
+
@parser.elem.should be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should reset the element to nil (no element is being parsed)" do
|
18
|
+
@parser.reset
|
19
|
+
@parser.elem.should be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should reset the parser to a parser" do
|
23
|
+
new_parser = Nokogiri::XML::SAX::PushParser.new(@parser, "UTF-8")
|
24
|
+
Nokogiri::XML::SAX::PushParser.should_receive(:new).with(@parser, "UTF-8").and_return(new_parser)
|
25
|
+
@parser.reset
|
26
|
+
@parser.parser.should == new_parser
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe ".push" do
|
31
|
+
it "should send the data to the parser" do
|
32
|
+
data = "<name>me</name>"
|
33
|
+
@parser.parser.should_receive(:<<).with(data)
|
34
|
+
@parser.push(data)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe ".characters" do
|
39
|
+
before(:each) do
|
40
|
+
@parser.doc = Nokogiri::XML::Document.new
|
41
|
+
@parser.elem = Nokogiri::XML::Element.new("element", @parser.doc)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should add the characters to the buffer" do
|
45
|
+
chars = "hello my name is julien"
|
46
|
+
@parser.characters(chars)
|
47
|
+
@parser.instance_variable_get("@buffer").should == chars
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should concatenate the text if we receive in both pieces" do
|
51
|
+
chars = "hello my name is julien"
|
52
|
+
@parser.characters(chars)
|
53
|
+
@parser.instance_variable_get("@buffer").should == chars
|
54
|
+
chars2 = "and I'm french!"
|
55
|
+
@parser.characters(chars2)
|
56
|
+
@parser.instance_variable_get("@buffer").should == chars + chars2
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe ".start_element" do
|
61
|
+
|
62
|
+
before(:each) do
|
63
|
+
@new_elem_name = "new"
|
64
|
+
@new_elem_attributes = ["to", "you@yourserver.com/home", "xmlns", "http://ns.com"]
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should create a new doc if we don't have one" do
|
68
|
+
new_doc = Nokogiri::XML::Document.new
|
69
|
+
@parser.doc = nil
|
70
|
+
Nokogiri::XML::Document.should_receive(:new).and_return(new_doc)
|
71
|
+
@parser.start_element(@new_elem_name, @new_elem_attributes)
|
72
|
+
@parser.doc.should == new_doc
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should not create a new doc we already have one" do
|
76
|
+
@parser.doc = Nokogiri::XML::Document.new
|
77
|
+
Nokogiri::XML::Document.should_not_receive(:new)
|
78
|
+
@parser.start_element(@new_elem_name, @new_elem_attributes)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should create a new element" do
|
82
|
+
@doc = Nokogiri::XML::Document.new
|
83
|
+
@parser.doc = @doc
|
84
|
+
@new_elem = Nokogiri::XML::Element.new(@new_elem_name, @parser.doc)
|
85
|
+
Nokogiri::XML::Element.should_receive(:new).and_return(@new_elem)
|
86
|
+
@parser.start_element(@new_elem_name, @new_elem_attributes)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should add the new element as a child to the current element if there is one" do
|
90
|
+
@doc = Nokogiri::XML::Document.new
|
91
|
+
@parser.doc = @doc
|
92
|
+
@current = Nokogiri::XML::Element.new("element", @parser.doc)
|
93
|
+
@parser.elem = @current
|
94
|
+
@new_elem = Nokogiri::XML::Element.new(@new_elem_name, @parser.doc)
|
95
|
+
Nokogiri::XML::Element.stub!(:new).and_return(@new_elem)
|
96
|
+
@parser.start_element(@new_elem_name, @new_elem_attributes)
|
97
|
+
@new_elem.parent.should == @current
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should add the new element as the child of the doc if there is none" do
|
101
|
+
@doc = Nokogiri::XML::Document.new
|
102
|
+
@parser.doc = @doc
|
103
|
+
@new_elem = Nokogiri::XML::Element.new(@new_elem_name, @parser.doc)
|
104
|
+
Nokogiri::XML::Element.stub!(:new).and_return(@new_elem)
|
105
|
+
@parser.start_element(@new_elem_name, @new_elem_attributes)
|
106
|
+
@new_elem.parent.should == @doc
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should add the right attributes and namespaces to the newly created element" do
|
110
|
+
@parser.start_element(@new_elem_name, @new_elem_attributes)
|
111
|
+
@parser.elem["to"].should == "you@yourserver.com/home"
|
112
|
+
# TODO : FIX NAMESPACES : @parser.elem.namespaces.should == {"xmlns"=>"http://ns.com"}
|
113
|
+
@parser.elem.namespaces.should == {}
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "when the new element is of name stream:stream" do
|
117
|
+
it "should callback" do
|
118
|
+
@proc.should_receive(:call)
|
119
|
+
@parser.start_element("stream:stream", [])
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should reinit to nil the doc and the elem" do
|
123
|
+
@parser.start_element("stream:stream", [])
|
124
|
+
@parser.doc.should == nil
|
125
|
+
@parser.elem.should == nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe ".end_element" do
|
131
|
+
before(:each) do
|
132
|
+
@doc = Nokogiri::XML::Document.new
|
133
|
+
@parser.doc = @doc
|
134
|
+
@current = Nokogiri::XML::Element.new("element", @parser.doc)
|
135
|
+
@parser.elem = @current
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should add the content of the buffer to the @elem" do
|
139
|
+
@elem = Nokogiri::XML::Element.new("element", @parser.doc)
|
140
|
+
chars = "hello world"
|
141
|
+
@parser.instance_variable_set("@buffer", chars)
|
142
|
+
@parser.elem = @elem
|
143
|
+
@parser.end_element("element")
|
144
|
+
@elem.content.should == chars
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "when we're finishing the doc's root" do
|
148
|
+
before(:each) do
|
149
|
+
@parser.doc.root = @current
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should callback" do
|
153
|
+
@proc.should_receive(:call)
|
154
|
+
@parser.end_element("element")
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should reinit to nil the doc and the elem" do
|
158
|
+
@parser.end_element("element")
|
159
|
+
@parser.doc.should == nil
|
160
|
+
@parser.elem.should == nil
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "when we're finishing another element" do
|
165
|
+
before(:each) do
|
166
|
+
@parser.doc.root = Nokogiri::XML::Element.new("root", @parser.doc)
|
167
|
+
@current.parent = @parser.doc.root
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should go back up one level" do
|
171
|
+
@parser.end_element("element")
|
172
|
+
@parser.elem = @current.parent
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe ".add_namespaces_and_attributes_to_node" do
|
178
|
+
before(:each) do
|
179
|
+
@doc = Nokogiri::XML::Document.new
|
180
|
+
@parser.doc = @doc
|
181
|
+
@element = Nokogiri::XML::Element.new("element", @parser.doc)
|
182
|
+
@attrs = ["from", "me", "xmlns:atom", "http://www.w3.org/2005/Atom" ,"to", "you", "xmlns", "http://namespace.com"]
|
183
|
+
@parser.elem = @element
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should assign even elements to attributes value or namespaces urls" do
|
187
|
+
@parser.__send__(:add_namespaces_and_attributes_to_current_node, @attrs)
|
188
|
+
even = []
|
189
|
+
@attrs.size.times do |i|
|
190
|
+
even << @attrs[i*2]
|
191
|
+
end
|
192
|
+
even.compact!
|
193
|
+
@element.attributes.keys.each do |k|
|
194
|
+
even.should include(k)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should assign odd elements to attributes names of namespaces prefixes" do
|
199
|
+
@parser.__send__(:add_namespaces_and_attributes_to_current_node, @attrs)
|
200
|
+
even = []
|
201
|
+
@attrs.size.times do |i|
|
202
|
+
even << @attrs[i*2+1]
|
203
|
+
end
|
204
|
+
even.compact!
|
205
|
+
@element.attributes.values.each do |v|
|
206
|
+
even.should include("#{v}")
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should add namespace for each attribute name that starts with xmlns" do
|
211
|
+
@parser.__send__(:add_namespaces_and_attributes_to_current_node, @attrs)
|
212
|
+
# TODO: FIX NAMESPACES @element.namespaces.values.should == ["http://www.w3.org/2005/Atom", "http://namespace.com"]
|
213
|
+
@element.namespaces.values.should == []
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should escape characters correctly" do
|
217
|
+
@attrs = ["url", "http://api.flickr.com/services/feeds/photos_public.gne?id=49724566@N00&lang=en-us&format=atom"]
|
218
|
+
@parser.__send__(:add_namespaces_and_attributes_to_current_node, @attrs)
|
219
|
+
@element["url"].should == "http://api.flickr.com/services/feeds/photos_public.gne?id=49724566@N00&lang=en-us&format=atom"
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
describe "a communication with an XMPP Client" do
|
225
|
+
|
226
|
+
before(:each) do
|
227
|
+
@stanzas = []
|
228
|
+
@proc = Proc.new { |stanza|
|
229
|
+
@stanzas << stanza
|
230
|
+
}
|
231
|
+
@parser = Skates::XmppParser.new(@proc)
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should parse the right information" do
|
235
|
+
string = "<stream:stream
|
236
|
+
xmlns:stream='http://etherx.jabber.org/streams'
|
237
|
+
xmlns='jabber:component:accept'
|
238
|
+
from='plays.shakespeare.lit'
|
239
|
+
id='3BF96D32'>
|
240
|
+
<handshake/>
|
241
|
+
<message from='juliet@example.com'
|
242
|
+
to='romeo@example.net'
|
243
|
+
xml:lang='en'>
|
244
|
+
<body>Art thou not Romeo, and a Montague?</body>
|
245
|
+
<link href='http://sfbay.craigslist.org/search/sss?query=%2522mac+mini%2522+Intel+Core+Duo&minAsk=min&maxAsk=max&format=rss&format=rss' />
|
246
|
+
</message>"
|
247
|
+
pieces = rand(string.size/30)
|
248
|
+
# So we have to pick 'pieces' number between 0 and string.size
|
249
|
+
indices = []
|
250
|
+
pieces.times do |i|
|
251
|
+
indices[i] = rand(string.size)
|
252
|
+
end
|
253
|
+
# Now let's sort indices
|
254
|
+
indices.sort!
|
255
|
+
substrings = []
|
256
|
+
prev_index = 0
|
257
|
+
indices.each do |index|
|
258
|
+
substrings << string[prev_index, (index-prev_index)]
|
259
|
+
prev_index = index
|
260
|
+
end
|
261
|
+
substrings << string[prev_index, string.size]
|
262
|
+
#Just to make sure we split the string the right way!
|
263
|
+
substrings.join("").should == string
|
264
|
+
|
265
|
+
substrings.each do |s|
|
266
|
+
@parser.push(s)
|
267
|
+
end
|
268
|
+
|
269
|
+
@stanzas.join("").should == "<stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:component:accept\" from=\"plays.shakespeare.lit\" id=\"3BF96D32\"/><handshake/><message from=\"juliet@example.com\" to=\"romeo@example.net\" xml:lang=\"en\">\n <body>Art thou not Romeo, and a Montague?</body>\n <link href=\"http://sfbay.craigslist.org/search/sss?query=%2522mac+mini%2522+Intel+Core+Duo&minAsk=min&maxAsk=max&format=rss&format=rss\"/>\n</message>"
|
270
|
+
@stanzas.last.at("link")["href"].should == "http://sfbay.craigslist.org/search/sss?query=%2522mac+mini%2522+Intel+Core+Duo&minAsk=min&maxAsk=max&format=rss&format=rss"
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|