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,72 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+
3
+ describe Babylon::Router::DSL do
4
+ before(:each) do
5
+ Babylon.router = Babylon::StanzaRouter.new
6
+ Babylon.router.purge_routes!
7
+ class ControllerController; end
8
+ end
9
+
10
+ it "raises an exception if the route lacks a controller" do
11
+ lambda { Babylon.router.draw do
12
+ xpath("/test").to(:action => "foo")
13
+ end }.should raise_error(/controller/)
14
+ end
15
+
16
+ it "raises an exception if the route lacks an action" do
17
+ lambda { Babylon.router.draw do
18
+ xpath("/test").to(:controller => "foo")
19
+ end }.should raise_error(/action/)
20
+ end
21
+
22
+ it "raises an exception if the route has no destination" do
23
+ lambda { Babylon.router.draw do
24
+ xpath("//test")
25
+ end }.should raise_error(/destination/)
26
+ end
27
+
28
+ it "creates a route with the specified xpath, controller and action" do
29
+ Babylon.router.draw do
30
+ xpath("//test"
31
+ ).to(:controller => "controller", :action => "action")
32
+ end
33
+ routes = Babylon.router.instance_variable_get("@routes")
34
+ routes.length.should == 1
35
+ end
36
+
37
+ describe :disco_info do
38
+ it "matches the root disco#info namespace" do
39
+ Babylon.router.draw do
40
+ disco_info.to(:controller => "controller", :action => "action")
41
+ end
42
+ route = Babylon.router.instance_variable_get("@routes").last
43
+ route.xpath.should == "//iq[@type='get']/*[namespace(., 'query', 'http://jabber.org/protocol/disco#info')]"
44
+ end
45
+
46
+ it "matches the disco#info namespace for the specified node" do
47
+ Babylon.router.draw do
48
+ disco_info("test").to(:controller => "controller", :action => "action")
49
+ end
50
+ route = Babylon.router.instance_variable_get("@routes").last
51
+ route.xpath.should == "//iq[@type='get']/*[namespace(., 'query', 'http://jabber.org/protocol/disco#info') and @node = 'test']"
52
+ end
53
+ end
54
+
55
+ describe :disco_items do
56
+ it "matches the root disco#items namespace" do
57
+ Babylon.router.draw do
58
+ disco_items.to(:controller => "controller", :action => "action")
59
+ end
60
+ route = Babylon.router.instance_variable_get("@routes").last
61
+ route.xpath.should == "//iq[@type='get']/*[namespace(., 'query', 'http://jabber.org/protocol/disco#items')]"
62
+ end
63
+
64
+ it "matches the disco#items namespace for the specified node" do
65
+ Babylon.router.draw do
66
+ disco_items("test").to(:controller => "controller", :action => "action")
67
+ end
68
+ route = Babylon.router.instance_variable_get("@routes").last
69
+ route.xpath.should == "//iq[@type='get']/*[namespace(., 'query', 'http://jabber.org/protocol/disco#items') and @node = 'test']"
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,189 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Babylon::Route do
4
+ before(:each) do
5
+ @controller = "bar"
6
+ @action = "bar"
7
+ @xpath = "//message"
8
+ Kernel.stub!(:const_get).with("#{@controller.capitalize}Controller")
9
+ end
10
+
11
+ describe ".initialize" do
12
+ it "should raise an exception if no controller is specified" do
13
+ lambda { Babylon::Route.new("action" => @action, "xpath" => @xpath) }.should raise_error(/controller/)
14
+ end
15
+ it "should raise an exception if no action is specified" do
16
+ lambda { Babylon::Route.new("controller" => @controller, "xpath" => @xpath) }.should raise_error(/action/)
17
+ end
18
+ it "should raise an exception if no xpath is specified" do
19
+ lambda { Babylon::Route.new("action" => @action, "controller" => @controller) }.should raise_error(/xpath/)
20
+ end
21
+ end
22
+
23
+ describe ".accepts?" do
24
+ it "should check the stanza with Xpath" do
25
+ mock_stanza = mock(Object)
26
+ route = Babylon::Route.new("controller" => "bar", "action" => "bar", "xpath" => "//message")
27
+ mock_stanza.should_receive(:xpath).with(route.xpath, instance_of(Babylon::XpathHelper)).and_return([])
28
+ route.accepts?(mock_stanza)
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+ describe Babylon::StanzaRouter do
35
+
36
+ before(:each) do
37
+ @router = Babylon::StanzaRouter.new
38
+ end
39
+
40
+ describe "initialize" do
41
+ it "should have an empty array as routes" do
42
+ @router.routes.should == []
43
+ end
44
+ end
45
+
46
+ describe "connected" do
47
+ it "should set the connection" do
48
+ connection = mock(Object)
49
+ @router.connected(connection)
50
+ @router.connection.should == connection
51
+ end
52
+ end
53
+
54
+ describe "route" do
55
+ before(:each) do
56
+ @xml = mock(Nokogiri::XML::Node)
57
+ 3.times do |t|
58
+ @router.routes << mock(Babylon::Route, :accepts? => false)
59
+ end
60
+ end
61
+
62
+ it "should check each routes to see if they match the stanza and take the first of the matching" do
63
+ @router.routes.each do |r|
64
+ r.should_receive(:accepts?).with(@xml)
65
+ end
66
+ @router.route(@xml)
67
+ end
68
+
69
+ describe "if one route is found" do
70
+ before(:each) do
71
+ @accepting_route = mock(Babylon::Route, :accepts? => true, :action => "action", :controller => "controller", :xpath => "xpath")
72
+ @router.routes << @accepting_route
73
+ end
74
+
75
+ it "should call execute_route" do
76
+ @router.should_receive(:execute_route).with(@accepting_route.controller, @accepting_route.action, @xml)
77
+ @router.route(@xml)
78
+ end
79
+ end
80
+
81
+ describe "if no route matches the stanza" do
82
+ it "should return false" do
83
+ @router.route(@xml).should be_false
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ describe "execute_route" do
90
+ before(:each) do
91
+ @action = "action"
92
+ @controller = Babylon::Base::Controller
93
+ @xml = mock(Nokogiri::XML::Node)
94
+ @mock_stanza = mock(Babylon::Base::Stanza)
95
+ @mock_controller = mock(Babylon::Base::Controller, {:new => true, :evaluate => "hello world"})
96
+ Kernel.stub!(:const_get).with(@action.capitalize).and_return(Babylon::Base::Stanza)
97
+ Babylon::Base::Stanza.stub!(:new).with(@xml).and_return(@mock_stanza)
98
+ @connection = mock(Babylon::XmppConnection, :send_xml => true)
99
+ @router.stub!(:connection).and_return(@connection)
100
+ @controller.stub!(:new).and_return(@mock_controller)
101
+ @mock_controller.stub!(:perform).with(@action)
102
+ end
103
+
104
+ describe "when the Stanza class exists" do
105
+ it "should instantiate the route's stanza " do
106
+ Kernel.should_receive(:const_get).with(@action.capitalize).and_return(Babylon::Base::Stanza)
107
+ Babylon::Base::Stanza.should_receive(:new).with(@xml).and_return(@mock_stanza)
108
+ @router.execute_route(@controller, @action, @xml)
109
+ end
110
+
111
+ it "should instantiate the route's controller" do
112
+ @controller.should_receive(:new).with(@mock_stanza).and_return(@mock_controller)
113
+ @router.execute_route(@controller, @action, @xml)
114
+ end
115
+ end
116
+
117
+ describe "when the stanza class doesn't exist" do
118
+ it "should instantiate the route's controller with the xml" do
119
+ Kernel.should_receive(:const_get).with(@action.capitalize).and_raise(NameError)
120
+ @controller.should_receive(:new).with(@xml).and_return(@mock_controller)
121
+ @router.execute_route(@controller, @action, @xml)
122
+ end
123
+ end
124
+
125
+ it "should call perform on the controller with the action's name" do
126
+ @mock_controller.should_receive(:perform).with(@action)
127
+ @router.execute_route(@controller, @action, @xml)
128
+ end
129
+
130
+ it "should send the controller's response to the connection" do
131
+ @connection.should_receive(:send_xml).with(@mock_controller.evaluate)
132
+ @router.execute_route(@controller, @action, @xml)
133
+ end
134
+ end
135
+
136
+ describe "purge_routes!" do
137
+ it "should delete all routes" do
138
+ @router.instance_variable_set("@routes", [mock(Babylon::Route), mock(Babylon::Route)])
139
+ @router.purge_routes!
140
+ @router.routes.should == []
141
+ end
142
+ end
143
+
144
+ describe "draw" do
145
+ before(:each) do
146
+ @dsl = Babylon::Router::DSL.new
147
+ Babylon::Router::DSL.stub!(:new).and_return(@dsl)
148
+ @routes = [mock(Babylon::Route, :is_a? => true), mock(Babylon::Route, :is_a? => true), mock(Babylon::Route, :is_a? => true)]
149
+ @router.stub!(:sort)
150
+ @dsl.stub!(:routes).and_return(@routes)
151
+ end
152
+
153
+ it "shoudl instantiate a new DSL" do
154
+ Babylon::Router::DSL.should_receive(:new).and_return(@dsl)
155
+ @router.draw {}
156
+ end
157
+
158
+ it "should instance_eval the block" do
159
+ block = Proc.new {}
160
+ @dsl.should_receive(:instance_eval).with(&block)
161
+ @router.draw &block
162
+ end
163
+
164
+ it "should check that each route is a Route" do
165
+ @dsl.should_receive(:routes).twice.and_return(@routes)
166
+ @router.draw {}
167
+ end
168
+
169
+ it "should raise an error if one of the routes is not valid" do
170
+ @dsl.should_receive(:routes).and_return([mock(Babylon::Route, :is_a? => false)])
171
+ lambda {
172
+ @router.draw {}
173
+ }.should raise_error()
174
+ end
175
+
176
+ it "should assign the dsl routes as @routes" do
177
+ @dsl.should_receive(:routes).twice.and_return(@routes)
178
+ @router.draw {}
179
+ @router.routes.should == @routes
180
+ end
181
+
182
+ it "should sort the routes" do
183
+ @router.should_receive(:sort)
184
+ @router.draw {}
185
+ end
186
+
187
+ end
188
+
189
+ end
@@ -0,0 +1,213 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.dirname(__FILE__) + '/../../em_mock'
3
+
4
+ describe Babylon::Runner do
5
+
6
+ before(:all) do
7
+ FileUtils.chdir("#{FileUtils.pwd}/templates/babylon") unless ("#{FileUtils.pwd}" =~ /\/templates\/babylon/ )
8
+ end
9
+
10
+ describe ".prepare" do
11
+
12
+ before(:each) do
13
+ @stub_config_file = File.open("config/config.yaml")
14
+ @stub_config_content = File.read("config/config.yaml")
15
+ File.stub!(:open).with('config/config.yaml').and_return(@stub_config_file)
16
+ Babylon::Runner.stub!(:require_directory).and_return(true)
17
+ end
18
+
19
+ it "should add the environment log file as an outputter to babylon's default log" do
20
+ @logger = Log4r::RollingFileOutputter.new("#{Babylon.environment}", :filename => "log/#{Babylon.environment}.log", :trunc => false)
21
+ Log4r::RollingFileOutputter.should_receive(:new).with("test", :filename => "log/test.log", :trunc => false).and_return(@logger)
22
+ Babylon.logger.should_receive(:add).with(@logger)
23
+ Babylon::Runner.prepare("test")
24
+ end
25
+
26
+ it "should require all models" do
27
+ Babylon::Runner.should_receive(:require_directory).with('app/models/*.rb').and_return(true)
28
+ Babylon::Runner.prepare("test")
29
+ end
30
+
31
+ it "should require all stanzas" do
32
+ Babylon::Runner.should_receive(:require_directory).with('app/stanzas/*.rb').and_return(true)
33
+ Babylon::Runner.prepare("test")
34
+ end
35
+
36
+ it "should require all controllers" do
37
+ Babylon::Runner.should_receive(:require_directory).with('app/controllers/*_controller.rb').and_return(true)
38
+ Babylon::Runner.prepare("test")
39
+ end
40
+
41
+ it "should create a router" do
42
+ router = Babylon::StanzaRouter.new
43
+ Babylon::StanzaRouter.should_receive(:new).and_return(router)
44
+ Babylon.should_receive(:router=).with(router)
45
+ Babylon::Runner.prepare("test")
46
+ end
47
+
48
+ it "should load the routes" do
49
+ Babylon::Runner.should_receive(:require).with('config/routes.rb')
50
+ Babylon::Runner.prepare("test")
51
+ end
52
+
53
+ it "should load the configuration file" do
54
+ File.should_receive(:open).with('config/config.yaml').and_return(@stub_config_file)
55
+ Babylon::Runner.prepare("test")
56
+ end
57
+
58
+ it "should assign the configuration" do
59
+ Babylon::Runner.prepare("test")
60
+ Babylon.config.should == YAML.load(@stub_config_content)["test"]
61
+ end
62
+
63
+ it "should cache the views" do
64
+ Babylon.should_receive(:cache_views)
65
+ Babylon::Runner.prepare("test")
66
+ end
67
+ end
68
+
69
+ describe "require_directory" do
70
+ before(:each) do
71
+ @dir = "/my/dir"
72
+ @files = ["hello.rb", "byebye.rb"]
73
+ Dir.stub!(:glob).with(@dir).and_return(@files)
74
+ @files.each do |f|
75
+ Babylon::Runner.stub!(:require).with(f).and_return(true)
76
+ end
77
+ end
78
+ it "should list all files in the directory" do
79
+ Dir.should_receive(:glob).with(@dir).and_return(@files)
80
+ Babylon::Runner.require_directory(@dir)
81
+ end
82
+ it "should require each of the files" do
83
+ @files.each do |f|
84
+ Babylon::Runner.should_receive(:require).with(f).and_return(true)
85
+ end
86
+ Babylon::Runner.require_directory(@dir)
87
+ end
88
+ end
89
+
90
+ describe ".run" do
91
+
92
+ before(:each) do
93
+ Babylon::ClientConnection.stub!(:connect).and_return(true)
94
+ Babylon::ComponentConnection.stub!(:connect).and_return(true)
95
+ EventMachine.stub!(:run).and_yield
96
+ end
97
+
98
+ it "should set the environment" do
99
+ Babylon::Runner.run("test")
100
+ Babylon.environment.should == "test"
101
+ end
102
+
103
+ it "should epoll the EventMachine" do
104
+ EventMachine.should_receive(:epoll)
105
+ Babylon::Runner.run("test")
106
+ end
107
+
108
+ it "should run the EventMachine" do
109
+ EventMachine.should_receive(:run)
110
+ Babylon::Runner.run("test")
111
+ end
112
+
113
+ it "should call prepare" do
114
+ Babylon::Runner.should_receive(:prepare).with("test")
115
+ Babylon::Runner.run("test")
116
+ end
117
+
118
+ it "should connect the client connection if specified by the config" do
119
+ Babylon.stub!(:config).and_return({"application_type" => "client"})
120
+ Babylon::ClientConnection.should_receive(:connect).with(Babylon.config, Babylon::Runner)
121
+ Babylon::Runner.run("test")
122
+ end
123
+
124
+ it "should connect the component connection if no application_type specified by the config" do
125
+ Babylon.stub!(:config).and_return({})
126
+ Babylon::ComponentConnection.should_receive(:connect).with(Babylon.config, Babylon::Runner)
127
+ Babylon::Runner.run("test")
128
+ end
129
+
130
+ end
131
+
132
+ describe ".connection_observers" do
133
+ it "should return an array" do
134
+ Babylon::Runner.connection_observers.should be_an_instance_of(Array)
135
+ end
136
+ end
137
+
138
+ describe ".add_connection_observer" do
139
+ before(:each) do
140
+ class MyController < Babylon::Base::Controller; end
141
+ end
142
+
143
+ it "should not accept non-Babylon::Base::Controller subclasses" do
144
+ Babylon::Runner.add_connection_observer(Object).should be_false
145
+ end
146
+
147
+ it "should accept" do
148
+ Babylon::Runner.add_connection_observer(MyController).should be_true
149
+ end
150
+
151
+ it "should add it to the list of observers" do
152
+ observers = Babylon::Runner.connection_observers
153
+ Babylon::Runner.add_connection_observer(MyController)
154
+ observers.include?(MyController).should be_true
155
+ end
156
+
157
+ it "should not add it twice" do
158
+ observers = Babylon::Runner.connection_observers
159
+ Babylon::Runner.add_connection_observer(MyController)
160
+ Babylon::Runner.add_connection_observer(MyController)
161
+ observers.should == [MyController]
162
+ end
163
+
164
+ end
165
+
166
+ describe ".on_connected" do
167
+ before(:each) do
168
+ @connection = mock(Object)
169
+ Babylon.router = Babylon::StanzaRouter.new
170
+ Babylon.router.stub!(:connected).with(@connection)
171
+ Babylon.router.stub!(:execute_route).with(MyController, "on_connected")
172
+ end
173
+
174
+ it "should call connected on StanzaRouter" do
175
+ Babylon.router.should_receive(:connected).with(@connection)
176
+ Babylon::Runner.on_connected(@connection)
177
+ end
178
+
179
+ it "should call on_connected on the various observers and send the corresponding response" do
180
+ Babylon::Runner.add_connection_observer(MyController)
181
+ Babylon.router.should_receive(:execute_route).with(MyController, "on_connected")
182
+ Babylon::Runner.on_connected(@connection)
183
+ end
184
+ end
185
+
186
+ describe ".on_disconnected" do
187
+ it "should stop the event loop" do
188
+ connection = mock(Object)
189
+ EventMachine.should_receive(:stop_event_loop)
190
+ Babylon::Runner.on_disconnected()
191
+ end
192
+
193
+ it "should call on_disconnected on the various observers" do
194
+ class MyObserver < Babylon::Base::Controller
195
+ def on_disconnected
196
+ end
197
+ end
198
+ my_observer = MyObserver.new
199
+ Babylon::Runner.add_connection_observer(MyObserver)
200
+ MyObserver.should_receive(:new).and_return(my_observer)
201
+ my_observer.should_receive(:on_disconnected)
202
+ Babylon::Runner.on_disconnected
203
+ end
204
+ end
205
+
206
+ describe ".on_stanza" do
207
+ it "should call route on StanzaRouter" do
208
+ stanza = mock(Object)
209
+ Babylon.router.should_receive(:route).with(stanza)
210
+ Babylon::Runner.on_stanza(stanza)
211
+ end
212
+ end
213
+ end