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,72 @@
1
+ require File.dirname(__FILE__) + '/../../../spec_helper'
2
+
3
+ describe Skates::Router::DSL do
4
+ before(:each) do
5
+ Skates.router = Skates::StanzaRouter.new
6
+ Skates.router.purge_routes!
7
+ class ControllerController; end
8
+ end
9
+
10
+ it "raises an exception if the route lacks a controller" do
11
+ lambda { Skates.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 { Skates.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 { Skates.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
+ Skates.router.draw do
30
+ xpath("//test"
31
+ ).to(:controller => "controller", :action => "action")
32
+ end
33
+ routes = Skates.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
+ Skates.router.draw do
40
+ disco_info.to(:controller => "controller", :action => "action")
41
+ end
42
+ route = Skates.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
+ Skates.router.draw do
48
+ disco_info("test").to(:controller => "controller", :action => "action")
49
+ end
50
+ route = Skates.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
+ Skates.router.draw do
58
+ disco_items.to(:controller => "controller", :action => "action")
59
+ end
60
+ route = Skates.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
+ Skates.router.draw do
66
+ disco_items("test").to(:controller => "controller", :action => "action")
67
+ end
68
+ route = Skates.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 Skates::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 { Skates::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 { Skates::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 { Skates::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 = Skates::Route.new("controller" => "bar", "action" => "bar", "xpath" => "//message")
27
+ mock_stanza.should_receive(:xpath).with(route.xpath, instance_of(Skates::XpathHelper)).and_return([])
28
+ route.accepts?(mock_stanza)
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+ describe Skates::StanzaRouter do
35
+
36
+ before(:each) do
37
+ @router = Skates::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(Skates::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(Skates::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 = Skates::Base::Controller
93
+ @xml = mock(Nokogiri::XML::Node)
94
+ @mock_stanza = mock(Skates::Base::Stanza)
95
+ @mock_controller = mock(Skates::Base::Controller, {:new => true, :evaluate => "hello world"})
96
+ Kernel.stub!(:const_get).with(@action.capitalize).and_return(Skates::Base::Stanza)
97
+ Skates::Base::Stanza.stub!(:new).with(@xml).and_return(@mock_stanza)
98
+ @connection = mock(Skates::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(Skates::Base::Stanza)
107
+ Skates::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(Skates::Route), mock(Skates::Route)])
139
+ @router.purge_routes!
140
+ @router.routes.should == []
141
+ end
142
+ end
143
+
144
+ describe "draw" do
145
+ before(:each) do
146
+ @dsl = Skates::Router::DSL.new
147
+ Skates::Router::DSL.stub!(:new).and_return(@dsl)
148
+ @routes = [mock(Skates::Route, :is_a? => true), mock(Skates::Route, :is_a? => true), mock(Skates::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
+ Skates::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(Skates::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 Skates::Runner do
5
+
6
+ before(:all) do
7
+ FileUtils.chdir("#{FileUtils.pwd}/templates/skates") unless ("#{FileUtils.pwd}" =~ /\/templates\/skates/ )
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
+ Skates::Runner.stub!(:require_directory).and_return(true)
17
+ end
18
+
19
+ it "should add the environment log file as an outputter to skates's default log" do
20
+ @logger = Log4r::RollingFileOutputter.new("#{Skates.environment}", :filename => "log/#{Skates.environment}.log", :trunc => false)
21
+ Log4r::RollingFileOutputter.should_receive(:new).with("test", :filename => "log/test.log", :trunc => false).and_return(@logger)
22
+ Skates.logger.should_receive(:add).with(@logger)
23
+ Skates::Runner.prepare("test")
24
+ end
25
+
26
+ it "should require all models" do
27
+ Skates::Runner.should_receive(:require_directory).with('app/models/*.rb').and_return(true)
28
+ Skates::Runner.prepare("test")
29
+ end
30
+
31
+ it "should require all stanzas" do
32
+ Skates::Runner.should_receive(:require_directory).with('app/stanzas/*.rb').and_return(true)
33
+ Skates::Runner.prepare("test")
34
+ end
35
+
36
+ it "should require all controllers" do
37
+ Skates::Runner.should_receive(:require_directory).with('app/controllers/*_controller.rb').and_return(true)
38
+ Skates::Runner.prepare("test")
39
+ end
40
+
41
+ it "should create a router" do
42
+ router = Skates::StanzaRouter.new
43
+ Skates::StanzaRouter.should_receive(:new).and_return(router)
44
+ Skates.should_receive(:router=).with(router)
45
+ Skates::Runner.prepare("test")
46
+ end
47
+
48
+ it "should load the routes" do
49
+ Skates::Runner.should_receive(:require).with('config/routes.rb')
50
+ Skates::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
+ Skates::Runner.prepare("test")
56
+ end
57
+
58
+ it "should assign the configuration" do
59
+ Skates::Runner.prepare("test")
60
+ Skates.config.should == YAML.load(@stub_config_content)["test"]
61
+ end
62
+
63
+ it "should cache the views" do
64
+ Skates.should_receive(:cache_views)
65
+ Skates::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
+ Skates::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
+ Skates::Runner.require_directory(@dir)
81
+ end
82
+ it "should require each of the files" do
83
+ @files.each do |f|
84
+ Skates::Runner.should_receive(:require).with(f).and_return(true)
85
+ end
86
+ Skates::Runner.require_directory(@dir)
87
+ end
88
+ end
89
+
90
+ describe ".run" do
91
+
92
+ before(:each) do
93
+ Skates::ClientConnection.stub!(:connect).and_return(true)
94
+ Skates::ComponentConnection.stub!(:connect).and_return(true)
95
+ EventMachine.stub!(:run).and_yield
96
+ end
97
+
98
+ it "should set the environment" do
99
+ Skates::Runner.run("test")
100
+ Skates.environment.should == "test"
101
+ end
102
+
103
+ it "should epoll the EventMachine" do
104
+ EventMachine.should_receive(:epoll)
105
+ Skates::Runner.run("test")
106
+ end
107
+
108
+ it "should run the EventMachine" do
109
+ EventMachine.should_receive(:run)
110
+ Skates::Runner.run("test")
111
+ end
112
+
113
+ it "should call prepare" do
114
+ Skates::Runner.should_receive(:prepare).with("test")
115
+ Skates::Runner.run("test")
116
+ end
117
+
118
+ it "should connect the client connection if specified by the config" do
119
+ Skates.stub!(:config).and_return({"application_type" => "client"})
120
+ Skates::ClientConnection.should_receive(:connect).with(Skates.config, Skates::Runner)
121
+ Skates::Runner.run("test")
122
+ end
123
+
124
+ it "should connect the component connection if no application_type specified by the config" do
125
+ Skates.stub!(:config).and_return({})
126
+ Skates::ComponentConnection.should_receive(:connect).with(Skates.config, Skates::Runner)
127
+ Skates::Runner.run("test")
128
+ end
129
+
130
+ end
131
+
132
+ describe ".connection_observers" do
133
+ it "should return an array" do
134
+ Skates::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 < Skates::Base::Controller; end
141
+ end
142
+
143
+ it "should not accept non-Skates::Base::Controller subclasses" do
144
+ Skates::Runner.add_connection_observer(Object).should be_false
145
+ end
146
+
147
+ it "should accept" do
148
+ Skates::Runner.add_connection_observer(MyController).should be_true
149
+ end
150
+
151
+ it "should add it to the list of observers" do
152
+ observers = Skates::Runner.connection_observers
153
+ Skates::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 = Skates::Runner.connection_observers
159
+ Skates::Runner.add_connection_observer(MyController)
160
+ Skates::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
+ Skates.router = Skates::StanzaRouter.new
170
+ Skates.router.stub!(:connected).with(@connection)
171
+ Skates.router.stub!(:execute_route).with(MyController, "on_connected")
172
+ end
173
+
174
+ it "should call connected on StanzaRouter" do
175
+ Skates.router.should_receive(:connected).with(@connection)
176
+ Skates::Runner.on_connected(@connection)
177
+ end
178
+
179
+ it "should call on_connected on the various observers and send the corresponding response" do
180
+ Skates::Runner.add_connection_observer(MyController)
181
+ Skates.router.should_receive(:execute_route).with(MyController, "on_connected")
182
+ Skates::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
+ Skates::Runner.on_disconnected()
191
+ end
192
+
193
+ it "should call on_disconnected on the various observers" do
194
+ class MyObserver < Skates::Base::Controller
195
+ def on_disconnected
196
+ end
197
+ end
198
+ my_observer = MyObserver.new
199
+ Skates::Runner.add_connection_observer(MyObserver)
200
+ MyObserver.should_receive(:new).and_return(my_observer)
201
+ my_observer.should_receive(:on_disconnected)
202
+ Skates::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
+ Skates.router.should_receive(:route).with(stanza)
210
+ Skates::Runner.on_stanza(stanza)
211
+ end
212
+ end
213
+ end