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.
Files changed (47) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +113 -0
  3. data/Rakefile +143 -0
  4. data/bin/skates +6 -0
  5. data/lib/skates.rb +108 -0
  6. data/lib/skates/base/controller.rb +116 -0
  7. data/lib/skates/base/stanza.rb +23 -0
  8. data/lib/skates/base/view.rb +58 -0
  9. data/lib/skates/client_connection.rb +210 -0
  10. data/lib/skates/component_connection.rb +87 -0
  11. data/lib/skates/generator.rb +139 -0
  12. data/lib/skates/router.rb +101 -0
  13. data/lib/skates/router/dsl.rb +61 -0
  14. data/lib/skates/runner.rb +137 -0
  15. data/lib/skates/xmpp_connection.rb +172 -0
  16. data/lib/skates/xmpp_parser.rb +117 -0
  17. data/lib/skates/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 +92 -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/skates/app/controllers/controller.rb +7 -0
  34. data/templates/skates/app/stanzas/stanza.rb +6 -0
  35. data/templates/skates/app/views/view.rb +6 -0
  36. data/templates/skates/config/boot.rb +16 -0
  37. data/templates/skates/config/config.yaml +24 -0
  38. data/templates/skates/config/dependencies.rb +1 -0
  39. data/templates/skates/config/routes.rb +22 -0
  40. data/templates/skates/log/development.log +0 -0
  41. data/templates/skates/log/production.log +0 -0
  42. data/templates/skates/log/test.log +0 -0
  43. data/templates/skates/script/component +36 -0
  44. data/templates/skates/tmp/pids/README +2 -0
  45. data/test/skates_test.rb +7 -0
  46. data/test/test_helper.rb +10 -0
  47. 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&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 = 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&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