julien51-babylon 0.1.0 → 0.1.2

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/Rakefile CHANGED
@@ -9,7 +9,7 @@ begin
9
9
  gem.email = "julien.genestoux@gmail.com"
10
10
  gem.homepage = "http://github.com/julien51/babylon"
11
11
  gem.authors = ["julien Genestoux"]
12
- gem.requirements = ["eventmachine", "yaml", "fileutils", "log4r", "nokogiri", "sax-machine", "templater", "daemons"]
12
+ gem.requirements = ["eventmachine", "yaml", "fileutils", "log4r", "nokogiri", "sax-machine", "templater", "daemons", "optparse", "digest/sha1", "base64", "resolv"]
13
13
  gem.executables = "babylon"
14
14
  gem.files = [ "bin/babylon",
15
15
  "lib/babylon.rb",
data/lib/babylon.rb CHANGED
@@ -7,6 +7,11 @@ require 'nokogiri'
7
7
  require 'yaml'
8
8
  require 'fileutils'
9
9
  require 'sax-machine'
10
+ require 'digest/sha1'
11
+ require 'base64'
12
+ require 'resolv'
13
+ require "templater"
14
+
10
15
 
11
16
  require 'babylon/xmpp_connection'
12
17
  require 'babylon/xmpp_parser'
@@ -1,5 +1,3 @@
1
- require "sax-machine"
2
-
3
1
  module Babylon
4
2
  module Base
5
3
  ##
@@ -5,9 +5,6 @@ module Babylon
5
5
  # So far, SASL Plain authenticationonly is supported
6
6
  # Upon stanza reception, and depending on the status (connected... etc), this component will handle or forward the stanzas.
7
7
  class ClientConnection < XmppConnection
8
- require 'digest/sha1'
9
- require 'base64'
10
- require 'resolv'
11
8
 
12
9
  attr_reader :binding_iq_id, :session_iq_id
13
10
 
@@ -56,15 +53,15 @@ module Babylon
56
53
  # Builds the stream stanza for this client
57
54
  def stream_stanza
58
55
  doc = Nokogiri::XML::Document.new
59
- stream = Nokogiri::XML::Node.new("stream", doc)
56
+ stream = Nokogiri::XML::Node.new("stream:stream", doc)
60
57
  doc.add_child(stream)
61
- stream.add_namespace(nil, stream_namespace())
62
- stream.add_namespace("stream", "http://etherx.jabber.org/streams")
58
+ stream["xmlns"] = stream_namespace
59
+ stream["xmlns:stream"] = "http://etherx.jabber.org/streams"
63
60
  stream["to"] = jid.split("/").first.split("@").last
64
61
  stream["version"] = "1.0"
65
62
  paste_content_here = Nokogiri::XML::Node.new("paste_content_here", doc)
66
63
  stream.add_child(paste_content_here)
67
- doc.to_xml.split('<stream:paste_content_here/>').first
64
+ doc.to_xml.split('<paste_content_here/>').first
68
65
  end
69
66
 
70
67
  ##
@@ -100,7 +97,7 @@ module Babylon
100
97
  doc = Nokogiri::XML::Document.new
101
98
  starttls = Nokogiri::XML::Node.new("starttls", doc)
102
99
  doc.add_child(starttls)
103
- starttls.add_namespace(nil, "urn:ietf:params:xml:ns:xmpp-tls")
100
+ starttls["xmlns"] = "urn:ietf:params:xml:ns:xmpp-tls"
104
101
  send_xml(starttls.to_s)
105
102
  @state = :wait_for_proceed
106
103
  elsif stanza.at("mechanisms") # tls is ok
@@ -109,7 +106,7 @@ module Babylon
109
106
  auth = Nokogiri::XML::Node.new("auth", doc)
110
107
  doc.add_child(auth)
111
108
  auth['mechanism'] = "PLAIN"
112
- auth.add_namespace(nil, "urn:ietf:params:xml:ns:xmpp-sasl")
109
+ auth["xmlns"] = "urn:ietf:params:xml:ns:xmpp-sasl"
113
110
  auth.content = Base64::encode64([jid, jid.split("@").first, @password].join("\000")).gsub(/\s/, '')
114
111
  send_xml(auth.to_s)
115
112
  @state = :wait_for_success
@@ -142,7 +139,7 @@ module Babylon
142
139
  iq["type"] = "set"
143
140
  iq["id"] = binding_iq_id.to_s
144
141
  bind = Nokogiri::XML::Node.new("bind", doc)
145
- bind.add_namespace(nil, "urn:ietf:params:xml:ns:xmpp-bind")
142
+ bind["xmlns"] = "urn:ietf:params:xml:ns:xmpp-bind"
146
143
  iq.add_child(bind)
147
144
  resource = Nokogiri::XML::Node.new("resource", doc)
148
145
  if jid.split("/").size == 2
@@ -169,7 +166,7 @@ module Babylon
169
166
  iq["type"] = "set"
170
167
  iq["id"] = session_iq_id.to_s
171
168
  session = Nokogiri::XML::Node.new("session", doc)
172
- session.add_namespace(nil, "urn:ietf:params:xml:ns:xmpp-session")
169
+ session["xmlns"] = "urn:ietf:params:xml:ns:xmpp-session"
173
170
  iq.add_child(session)
174
171
  send_xml(iq.to_s)
175
172
  @state = :wait_for_confirmed_session
@@ -3,7 +3,6 @@ module Babylon
3
3
  # ComponentConnection is in charge of the XMPP connection itself.
4
4
  # Upon stanza reception, and depending on the status (connected... etc), this component will handle or forward the stanzas.
5
5
  class ComponentConnection < XmppConnection
6
- require 'digest/sha1'
7
6
 
8
7
  ##
9
8
  # Creates a new ComponentConnection and waits for data in the stream
@@ -19,14 +18,14 @@ module Babylon
19
18
  def connection_completed
20
19
  super
21
20
  doc = Nokogiri::XML::Document.new
22
- stream = Nokogiri::XML::Node.new("stream", doc)
23
- stream.add_namespace(nil, stream_namespace)
24
- stream.add_namespace("stream", "http://etherx.jabber.org/streams")
21
+ stream = Nokogiri::XML::Node.new("stream:stream", doc)
22
+ stream["xmlns"] = stream_namespace
23
+ stream["xmlns:stream"] = "http://etherx.jabber.org/streams"
25
24
  stream["to"] = jid
26
25
  doc.add_child(stream)
27
26
  paste_content_here= Nokogiri::XML::Node.new("paste_content_here", doc)
28
27
  stream.add_child(paste_content_here)
29
- start, stop = doc.to_xml.split('<stream:paste_content_here/>')
28
+ start, stop = doc.to_xml.split('<paste_content_here/>')
30
29
  send_xml(start)
31
30
  end
32
31
 
@@ -1,5 +1,3 @@
1
- require "templater"
2
-
3
1
  module Babylon
4
2
  module Generator
5
3
  extend Templater::Manifold
@@ -12,7 +12,9 @@ module Babylon
12
12
  Babylon.config = YAML.load(config_file)[Babylon.environment]
13
13
 
14
14
  # Add an outputter to the logger
15
- Babylon.logger.add(Log4r::FileOutputter.new("#{Babylon.environment}", :filename => "log/#{Babylon.environment}.log", :trunc => false))
15
+ log_file = Log4r::RollingFileOutputter.new("#{Babylon.environment}", :filename => "log/#{Babylon.environment}.log", :trunc => false)
16
+ log_file.formatter = Log4r::PatternFormatter.new(:pattern => "%d (#{Process.pid}) [%l] :: %m", :date_pattern => "%d/%m %H:%M")
17
+ Babylon.logger.add(log_file)
16
18
 
17
19
  # Requiring all models, stanza, controllers
18
20
  ['app/models/*.rb', 'app/stanzas/*.rb', 'app/controllers/*_controller.rb'].each do |dir|
@@ -89,7 +89,7 @@ module Babylon
89
89
  def add_namespaces_and_attributes_to_current_node(attrs)
90
90
  (attrs.size / 2).times do |i|
91
91
  name, value = attrs[2 * i], attrs[2 * i + 1]
92
- # TODO : FIX namespaces :they give a lot of problems with XPath
92
+ # TODO : FIX namespaces :they give a lot of problems with Nokogiri
93
93
  # if name == "xmlns"
94
94
  # @elem.add_namespace(nil, value)
95
95
  # elsif name =~ /\Axmlns:/
File without changes
data/spec/em_mock.rb ADDED
@@ -0,0 +1,42 @@
1
+ ##
2
+ # Mock for EventMachine
3
+ module EventMachine
4
+
5
+ def self.mock?
6
+ true
7
+ end
8
+
9
+ ##
10
+ # Mock for the Connection Class
11
+ class Connection
12
+ def self.new(*args)
13
+ allocate.instance_eval do
14
+ # Call a superclass's #initialize if it has one
15
+ initialize(*args)
16
+ # Store signature and run #post_init
17
+ post_init
18
+ self
19
+ end
20
+ end
21
+ end
22
+
23
+ ##
24
+ # Stub for run
25
+ def self.run(proc)
26
+ proc.call
27
+ end
28
+
29
+ ##
30
+ # Stub for epoll
31
+ def self.epoll; end
32
+
33
+ ##
34
+ # Stub! to stop the event loop.
35
+ def self.stop_event_loop; end
36
+
37
+ ##
38
+ # Stub for connect (should return a connection object)
39
+ def self.connect(host, port, handler, params)
40
+ handler.new(params)
41
+ end
42
+ end
@@ -0,0 +1,205 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+
3
+ describe Babylon::Base::Controller do
4
+
5
+ before(:each) do
6
+ Babylon.views.stub!(:[]).and_return("") # Stubbing read for view
7
+ end
8
+
9
+ describe ".initialize" do
10
+ before(:each) do
11
+ @params = {:a => "a", :b => 1, :c => {:key => "value"}, :stanza => "<hello>world</hello>"}
12
+ end
13
+
14
+ it "should have a stanza instance" do
15
+ stanza = mock(Object)
16
+ c = Babylon::Base::Controller.new(stanza)
17
+
18
+ c.instance_variables.should be_include "@stanza"
19
+ c.instance_variable_get("@stanza").should == stanza
20
+ end
21
+
22
+ it "should not be rendered yet" do
23
+ c = Babylon::Base::Controller.new(@params)
24
+ c.rendered.should_not be_true
25
+ end
26
+ end
27
+
28
+ describe ".perform" do
29
+ before(:each) do
30
+ @action = :subscribe
31
+ params = {:stanza => "<hello>world</hello>"}
32
+ @controller = Babylon::Base::Controller.new(params)
33
+ @controller.class.send(:define_method, @action) do # Defining the action method
34
+ # Do something
35
+ end
36
+ end
37
+
38
+ it "should setup the action to the param" do
39
+ @controller.perform(@action) do
40
+ # Do something
41
+ end
42
+ @controller.instance_variable_get("@action_name").should == @action
43
+ end
44
+
45
+ it "should call the action" do
46
+ @controller.should_receive(:send).with(@action).and_return()
47
+ @controller.perform(@action) do
48
+ # Do something
49
+ end
50
+ end
51
+
52
+ it "should write an error to the log in case of failure of the action" do
53
+ @controller.stub!(:send).with(@action).and_raise(StandardError)
54
+ Babylon.logger.should_receive(:error)
55
+ @controller.perform(@action) do
56
+ # Do something
57
+ end
58
+ end
59
+
60
+ it "should call render" do
61
+ @controller.should_receive(:render)
62
+ @controller.perform(@action) do
63
+ # Do something
64
+ end
65
+ end
66
+ end
67
+
68
+ describe ".render" do
69
+ before(:each) do
70
+ @controller = Babylon::Base::Controller.new({})
71
+ @controller.action_name = :subscribe
72
+ end
73
+
74
+ it "should assign a value to view" do
75
+ @controller.render
76
+ @controller.instance_variable_get("@view").should_not be_nil
77
+ end
78
+
79
+ describe "with :nothing option" do
80
+ it "should not render any file" do
81
+ @controller.should_not_receive(:render_for_file)
82
+ @controller.render :nothing => true
83
+ end
84
+ end
85
+
86
+ describe "with no option" do
87
+ it "should call render with default_file_name if no option is provided" do
88
+ @controller.should_receive(:default_template_name)
89
+ @controller.render
90
+ end
91
+ end
92
+
93
+ describe "with an :action option" do
94
+ it "should call render with the file name corresponding to the action given as option" do
95
+ action = :unsubscribe
96
+ @controller.should_receive(:default_template_name).with("#{action}")
97
+ @controller.render(:action => action)
98
+ end
99
+ end
100
+
101
+ describe "with a file option" do
102
+ it "should call render_for_file with the correct path if an option file is provided" do
103
+ file = "myfile"
104
+ @controller.should_receive(:render_for_file)
105
+ @controller.render(:file => file)
106
+ end
107
+ end
108
+
109
+ it "should not render twice when called twice" do
110
+ @controller.render
111
+ @controller.should_not_receive(:render_for_file)
112
+ @controller.render
113
+ end
114
+ end
115
+
116
+ describe ".assigns" do
117
+
118
+ before(:each) do
119
+ @stanza = mock(Babylon::Base::Stanza)
120
+ @controller = Babylon::Base::Controller.new(@stanza)
121
+ end
122
+
123
+ it "should be a hash" do
124
+ @controller.assigns.should be_an_instance_of(Hash)
125
+ end
126
+
127
+ it "should only contain the @stanza if the action hasn't been called yet" do
128
+ @controller.assigns.should_not be_empty
129
+ @controller.assigns["stanza"].should == @stanza
130
+ end
131
+
132
+ it "should return an hash containing all instance variables defined in the action" do
133
+ vars = {"a" => 1, "b" => "b", "c" => { "d" => 4}}
134
+ class MyController < Babylon::Base::Controller
135
+ def do_something
136
+ @a = 1
137
+ @b = "b"
138
+ @c = { "d" => 4 }
139
+ end
140
+ end
141
+ @controller = MyController.new(@stanza)
142
+ @controller.do_something
143
+ @controller.assigns.should == vars.merge("stanza" => @stanza)
144
+ end
145
+ end
146
+
147
+ describe ".evaluate" do
148
+ before(:each) do
149
+ @controller = Babylon::Base::Controller.new()
150
+ end
151
+
152
+ it "should evaluate the view" do
153
+ view = mock(Babylon::Base::View)
154
+ response = "hello"
155
+ @controller.instance_variable_set("@view", view)
156
+ view.should_receive(:evaluate).and_return(response)
157
+ @controller.evaluate.should == response
158
+ end
159
+ end
160
+
161
+ describe ".view_path" do
162
+ it "should return complete file path to the file given in param" do
163
+ @controller = Babylon::Base::Controller.new()
164
+ file_name = "myfile"
165
+ @controller.__send__(:view_path, file_name).should == File.join("app/views", "#{"Babylon::Base::Controller".gsub("Controller","").downcase}", file_name)
166
+ end
167
+ end
168
+
169
+ describe ".default_template_name" do
170
+ before(:each) do
171
+ @controller = Babylon::Base::Controller.new()
172
+ end
173
+
174
+ it "should return the view file name if a file is given in param" do
175
+ @controller.__send__(:default_template_name, "myaction").should == "myaction.xml.builder"
176
+ end
177
+
178
+ it "should return the view file name based on the action_name if no file has been given" do
179
+ @controller.action_name = "a_great_action"
180
+ @controller.__send__(:default_template_name).should == "a_great_action.xml.builder"
181
+ end
182
+ end
183
+
184
+ describe ".render_for_file" do
185
+
186
+ before(:each) do
187
+ @controller = Babylon::Base::Controller.new()
188
+ @block = Proc.new {
189
+ # Do something
190
+ }
191
+ @controller.class.send(:define_method, "action") do # Defining the action method
192
+ # Do something
193
+ end
194
+ @controller.perform(:action, &@block)
195
+ @view = Babylon::Base::View.new("path_to_a_file", {})
196
+ end
197
+
198
+ it "should instantiate a new view, with the file provided and the hashed_variables" do
199
+ Babylon::Base::View.should_receive(:new).with("path_to_a_file",an_instance_of(Hash)).and_return(@view)
200
+ @controller.__send__(:render_for_file, "path_to_a_file")
201
+ end
202
+
203
+ end
204
+
205
+ end
@@ -0,0 +1,15 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+
3
+ describe Babylon::Base::Stanza do
4
+
5
+ describe "initialize" do
6
+ before(:each) do
7
+ @stanza_string = "<presence />"
8
+ @stanza = Babylon::Base::Stanza.new(@stanza_string)
9
+ end
10
+
11
+ it "should call parse with the string passed to the builder"
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,64 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+
3
+ describe Babylon::Base::View do
4
+ describe ".initialize" do
5
+
6
+ before(:each) do
7
+ @view = Babylon::Base::View.new("/a/path/to/a/view/file", {:a => "a", :b => 123, :c => {:d => "d", :e => "123"}})
8
+ end
9
+
10
+ it "should assign @view_template to path" do
11
+ @view.view_template == "/a/path/to/a/view/file"
12
+ end
13
+
14
+ it "should assign any variable passed in hash" do
15
+ {:a => "a", :b => 123, :c => {:d => "d", :e => "123"}}.each do |key, value|
16
+ @view.instance_variable_get("@#{key}").should == value
17
+ end
18
+ end
19
+ end
20
+
21
+ describe ".evaluate" do
22
+ before(:each) do
23
+ @view_template = "/a/path/to/a/view/file"
24
+ @view = Babylon::Base::View.new(@view_template, {:a => "a", :b => 123, :c => {:d => "d", :e => "123"}})
25
+ @xml_string = <<-eoxml
26
+ xml.message(:to => "you", :from => "me", :type => :chat) do
27
+ xml.body("salut")
28
+ end
29
+ eoxml
30
+ Babylon.views.stub!(:[]).with(@view_template).and_return(@xml_string)
31
+ end
32
+
33
+ it "should read the template file" do
34
+ Babylon.views.should_receive(:[]).twice.with(@view_template).and_return(@xml_string)
35
+ @view.evaluate
36
+ end
37
+
38
+ it "should raise an error if the view file couldn't be found" do
39
+ Babylon.views.stub!(:[]).with(@view_template).and_raise(nil)
40
+ lambda {
41
+ @view.evaluate
42
+ }.should raise_error(Babylon::Base::ViewFileNotFound)
43
+ end
44
+
45
+ it "should return a Nokogiri NodeSet" do
46
+ Babylon.views.stub!(:[]).with(@view_template).and_return(@xml_string)
47
+ @view.evaluate.should be_an_instance_of(Nokogiri::XML::NodeSet)
48
+ end
49
+
50
+ it "should call eval on the view file" do
51
+ Babylon.views.stub!(:[]).with(@view_template).and_return(@xml_string)
52
+ @view.should_receive(:eval).with(@xml_string)
53
+ @view.evaluate
54
+ end
55
+
56
+ it "should be able to access context's variables" do
57
+ @view = Babylon::Base::View.new("/a/path/to/a/view/file", {:a => "a", :b => 123, :c => {:d => "d", :e => "123"}})
58
+ @view.instance_variable_get("@a").should == "a"
59
+ @view.instance_variable_get("@b").should == 123
60
+ @view.instance_variable_get("@c").should == {:e=>"123", :d=>"d"}
61
+ end
62
+ end
63
+
64
+ end