mohiam-babylon 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +111 -0
  3. data/Rakefile +145 -0
  4. data/bin/babylon +6 -0
  5. data/lib/babylon.rb +119 -0
  6. data/lib/babylon/base/controller.rb +116 -0
  7. data/lib/babylon/base/stanza.rb +23 -0
  8. data/lib/babylon/base/view.rb +49 -0
  9. data/lib/babylon/client_connection.rb +210 -0
  10. data/lib/babylon/component_connection.rb +87 -0
  11. data/lib/babylon/generator.rb +139 -0
  12. data/lib/babylon/router.rb +103 -0
  13. data/lib/babylon/router/dsl.rb +61 -0
  14. data/lib/babylon/runner.rb +148 -0
  15. data/lib/babylon/xmpp_connection.rb +172 -0
  16. data/lib/babylon/xmpp_parser.rb +111 -0
  17. data/lib/babylon/xpath_helper.rb +13 -0
  18. data/spec/bin/babylon_spec.rb +0 -0
  19. data/spec/em_mock.rb +42 -0
  20. data/spec/lib/babylon/base/controller_spec.rb +205 -0
  21. data/spec/lib/babylon/base/stanza_spec.rb +15 -0
  22. data/spec/lib/babylon/base/view_spec.rb +86 -0
  23. data/spec/lib/babylon/client_connection_spec.rb +304 -0
  24. data/spec/lib/babylon/component_connection_spec.rb +135 -0
  25. data/spec/lib/babylon/generator_spec.rb +10 -0
  26. data/spec/lib/babylon/router/dsl_spec.rb +72 -0
  27. data/spec/lib/babylon/router_spec.rb +189 -0
  28. data/spec/lib/babylon/runner_spec.rb +213 -0
  29. data/spec/lib/babylon/xmpp_connection_spec.rb +197 -0
  30. data/spec/lib/babylon/xmpp_parser_spec.rb +275 -0
  31. data/spec/lib/babylon/xpath_helper_spec.rb +25 -0
  32. data/spec/spec_helper.rb +34 -0
  33. data/templates/babylon/app/controllers/controller.rb +7 -0
  34. data/templates/babylon/app/stanzas/stanza.rb +6 -0
  35. data/templates/babylon/app/views/view.rb +6 -0
  36. data/templates/babylon/config/boot.rb +16 -0
  37. data/templates/babylon/config/config.yaml +24 -0
  38. data/templates/babylon/config/dependencies.rb +1 -0
  39. data/templates/babylon/config/routes.rb +22 -0
  40. data/templates/babylon/log/development.log +0 -0
  41. data/templates/babylon/log/production.log +0 -0
  42. data/templates/babylon/log/test.log +52 -0
  43. data/templates/babylon/script/component +46 -0
  44. data/templates/babylon/tmp/pids/README +2 -0
  45. data/test/babylon_test.rb +7 -0
  46. data/test/test_helper.rb +10 -0
  47. metadata +179 -0
@@ -0,0 +1,197 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.dirname(__FILE__) + '/../../em_mock'
3
+
4
+ describe Babylon::XmppConnection do
5
+
6
+ include BabylonSpecHelper
7
+
8
+ before(:each) do
9
+ @params = {"jid" => "jid@server", "password" => "password", "port" => 1234, "host" => "myhost.com"}
10
+ @connection = Babylon::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"], Babylon::XmppConnection, hash_including("handler" => handler_mock)).and_return(@connection)
16
+ Babylon::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"], Babylon::XmppConnection, hash_including("handler" => handler_mock)).and_raise(RuntimeError)
21
+ lambda {
22
+ Babylon::XmppConnection.connect(@params, handler_mock)
23
+ }.should raise_error(Babylon::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 = Babylon::XmppParser.new(@connection.method(:receive_stanza))
61
+ Babylon::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(Babylon::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" * (Babylon::XmppConnection.max_stanza_size + 1)
130
+ lambda {
131
+ @connection.__send__(:send_chunk, string)
132
+ }.should raise_error(Babylon::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 Babylon::XmppParser do
4
+
5
+ before(:each) do
6
+ @last_stanza = ""
7
+ @proc = mock(Proc, :call => true)
8
+ @parser = Babylon::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&amp;lang=en-us&amp;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 = Babylon::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&amp;minAsk=min&amp;maxAsk=max&amp;format=rss&amp;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&amp;minAsk=min&amp;maxAsk=max&amp;format=rss&amp;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