fabriq 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,92 @@
1
+ require_relative "../../helper"
2
+ require_relative "../../../lib/fabriq/logging"
3
+ require_relative "../../../lib/fabriq/config"
4
+
5
+ describe Fabriq::Config do
6
+
7
+ before do
8
+ @config = Fabriq::Config
9
+ @config.plugin_port = @plugin_port = mock('PluginPort')
10
+ end
11
+
12
+ describe "#load" do
13
+ before do
14
+ @plugin_port.stubs(:require_plugins)
15
+ @config.stubs(:require)
16
+ end
17
+
18
+ it "fails if a configuration file cannot be found" do
19
+ @config.expects(:fail_if_configuration_file_not_found)
20
+ @config.load
21
+ end
22
+
23
+ it "let Fabrig::PluginPort require all plugins" do
24
+ @plugin_port.expects(:require_plugins)
25
+ @config.load
26
+ end
27
+
28
+ it "requires the configuration file" do
29
+ @config.stubs(:configuration_file_path).returns("/path/to/config.rb")
30
+ @config.expects(:require).with("/path/to/config.rb")
31
+ @config.load
32
+ end
33
+ end
34
+
35
+ describe '#fail_if_configuration_file_not_found' do
36
+ it "throws a RuntimeError if a configuration file is not locatable" do
37
+ @config.stubs(:configuration_file_available?).returns(false)
38
+ -> { @config.fail_if_configuration_file_not_found }.must_raise(RuntimeError)
39
+ end
40
+
41
+ it "does not raise an Error if a config file is available" do
42
+ @config.stubs(:configuration_file_available?).returns(true)
43
+ @config.fail_if_configuration_file_not_found
44
+ end
45
+ end
46
+
47
+ describe '#configuration_file_available?' do
48
+ it "returns true if #configuration_file_path returns a string" do
49
+ @config.stubs(:configuration_file_path).returns("/path/to/file")
50
+ @config.configuration_file_available?.must_equal(true)
51
+ end
52
+
53
+ it "returns false if #configuration_file_path is nil" do
54
+ @config.stubs(:configuration_file_path).returns(nil)
55
+ @config.configuration_file_available?.must_equal(false)
56
+ end
57
+ end
58
+
59
+ describe '#configuration_file_path' do
60
+ before do
61
+ File.stubs(:expand_path).returns("/home")
62
+ end
63
+
64
+ it "returns nil if a config file cannot be found in assumed locations" do
65
+ File.stubs(:exist?).returns(false)
66
+ @config.configuration_file_path.must_be_nil
67
+ end
68
+
69
+ it "returns a path if a config file is available in the current execution path (pwd)" do
70
+ Dir.stubs(:pwd).returns("/path/to")
71
+ File.stubs(:exist?).with("/home/.fabriq/config.rb")
72
+ File.expects(:exist?).with("/path/to/config.rb").returns(true)
73
+ @config.configuration_file_path.must_equal("/path/to/config.rb")
74
+ end
75
+
76
+ it "returns a path if a config file is available in the current home (~/.fabriq)" do
77
+ File.expects(:exist?).with("/home/.fabriq/config.rb").returns(true)
78
+ @config.configuration_file_path.must_equal("/home/.fabriq/config.rb")
79
+ end
80
+ end
81
+
82
+ describe '#register_plugin' do
83
+ it "sends #register_plugin to the PluginPort passing klass and config block" do
84
+ config_block = -> {}
85
+ @plugin_port.expects(:register_plugin).with() do |klass, block|
86
+ klass.must_equal(self.class)
87
+ block.must_equal(&config_block)
88
+ end
89
+ @config.register_plugin(self.class, &config_block)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,33 @@
1
+ require_relative "../../helper"
2
+ require_relative "../../../lib/fabriq/logging"
3
+
4
+ describe Fabriq::Logging do
5
+
6
+ before do
7
+ @config = mock('Config')
8
+ @logging = Object.new
9
+ @logging.extend(Fabriq::Logging)
10
+ @logging.stubs(:config).returns(@config)
11
+ end
12
+
13
+ describe '#info' do
14
+ it "logs a message using the info severity" do
15
+ @logging.expects(:send_output).with(:info ,"Test")
16
+ @logging.info("Test")
17
+ end
18
+ end
19
+
20
+ describe '#error' do
21
+ it "logs a message using the error severity" do
22
+ @logging.expects(:send_output).with(:error ,"Test")
23
+ @logging.error("Test")
24
+ end
25
+ end
26
+
27
+ describe '#debug' do
28
+ it "logs a message using the debug severity" do
29
+ @logging.expects(:send_output).with(:debug ,"Test")
30
+ @logging.debug("Test")
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,106 @@
1
+ require_relative "../../helper"
2
+ require_relative "../../../lib/fabriq/logging"
3
+ require_relative "../../../lib/fabriq/plugin_port"
4
+
5
+ describe Fabriq::PluginPort do
6
+
7
+ before do
8
+ @port = Fabriq::PluginPort
9
+ end
10
+
11
+ describe '#plugin_load_paths' do
12
+ before do
13
+ Dir.stubs(:glob)
14
+ File.stubs(:expand_path).returns("/home")
15
+ end
16
+
17
+ it "returns all plugins in HOME/.fabriq/plugins" do
18
+ Dir.expects(:glob).with("/home/.fabriq/plugins/*").returns( ["plugin_dir"] )
19
+ @port.plugin_load_paths.must_include("plugin_dir")
20
+ end
21
+
22
+ it "returns all plugins in current run path/plugins" do
23
+ Dir.stubs(:pwd).returns("/path/pwd")
24
+ Dir.expects(:glob).with("/path/pwd/plugins/*").returns( ["plugin_dir"] )
25
+ @port.plugin_load_paths.must_include("plugin_dir")
26
+ end
27
+ end
28
+
29
+ describe '#require_plugins' do
30
+ before do
31
+ File.stubs(:exist?).returns(true)
32
+ end
33
+
34
+ it "requires all plugins from path" do
35
+ @port.stubs(:plugin_load_paths).returns(["plugin/path"])
36
+ @port.expects(:require_plugin_from_path).with("plugin/path")
37
+ @port.require_plugins
38
+ end
39
+
40
+ it "skips plugin paths that doesn't exist" do
41
+ File.stubs(:exist?).returns(false)
42
+ @port.stubs(:plugin_load_paths).returns(["plugin/path"])
43
+ @port.expects(:require_plugin_from_path).never
44
+ @port.require_plugins
45
+ end
46
+ end
47
+
48
+ describe '#require_plugin_from_path' do
49
+ before do
50
+ File.stubs(:exist?).returns(true)
51
+ end
52
+
53
+ it "requires the plugins main file" do
54
+ @port.expects(:require).with("/plugin/maja_calendar/lib/maja_calendar.rb")
55
+ @port.require_plugin_from_path("/plugin/maja_calendar")
56
+ end
57
+
58
+ it "logs an error message if the plugin's main file could not be found" do
59
+ File.stubs(:exist?).returns(false)
60
+ @port.expects(:error)
61
+ @port.require_plugin_from_path("/plugin/maja_calendar")
62
+ end
63
+ end
64
+
65
+ describe '#register_plugin' do
66
+ before do
67
+ @plugin_klass = mock('Plugin Klass')
68
+ @plugin_instance = mock('Plugin Instance')
69
+ @plugin_klass.stubs(:init).returns(@plugin_instance)
70
+ @port.stubs(:invoke_plugin_callback)
71
+ end
72
+
73
+ it "inits the plugin" do
74
+ @plugin_klass.expects(:init)
75
+ @port.register_plugin(@plugin_klass)
76
+ end
77
+
78
+ it "appends the initialized plugin to the plugins collection" do
79
+ @port.register_plugin(@plugin_klass)
80
+ @port.plugins.must_include(@plugin_instance)
81
+ end
82
+
83
+ it "invokes the plugin configuration, passing the plugins configurator object" do
84
+ configurator = mock('configurator')
85
+ config_proc = -> {}
86
+ @plugin_instance.stubs(:configurator).returns(configurator)
87
+ config_proc.expects(:call).with(configurator)
88
+ @port.register_plugin(@plugin_klass, &config_proc)
89
+ end
90
+
91
+ it "sends the 'registered' event to the plugin" do
92
+ @port.expects(:invoke_plugin_callback).with(@plugin_instance, :registered)
93
+ @port.register_plugin(@plugin_klass)
94
+ end
95
+ end
96
+
97
+ describe '#initialize_plugins' do
98
+ it "sends the 'initialized' event to each registered plugin" do
99
+ plugin = mock('Plugin')
100
+ @port.plugins = [ plugin ]
101
+ @port.expects(:invoke_plugin_callback).with(plugin, :initialized)
102
+ @port.initialize_plugins
103
+ end
104
+ end
105
+
106
+ end
@@ -0,0 +1,49 @@
1
+ require_relative "../../../helper"
2
+ require_relative "../../../../lib/fabriq/skype/message"
3
+
4
+ describe Fabriq::Skype::Message do
5
+
6
+ before do
7
+ @room = mock('Room')
8
+ @message = Fabriq::Skype::Message.new(@room, "Lorem Ipsum")
9
+ @message.config = @config = mock('Config')
10
+ end
11
+
12
+ describe "#private_session?" do
13
+ it "returns false" do
14
+ @room.stubs(:private_session?).returns(false)
15
+ @message.private_session?.must_equal(false)
16
+ end
17
+
18
+ it "returns true if the room is a private session" do
19
+ @room.stubs(:private_session?).returns(true)
20
+ @message.private_session?.must_equal(true)
21
+ end
22
+ end
23
+
24
+ describe '#direct?' do
25
+ it "returns false if no Config#skype_name is set" do
26
+ @config.stubs(:skype_name).returns(nil)
27
+ @message.direct?.must_equal(false)
28
+ end
29
+
30
+ it "returns false if beginning of message does not contain the configured skype name" do
31
+ @message.body = "@peter Hallo"
32
+ @config.stubs(:skype_name).returns("Maja")
33
+ @message.direct?.must_equal(false)
34
+ end
35
+
36
+ it "returns true if the beginning of the message contains the configured skype name" do
37
+ @message.body = "@Maja Hallo"
38
+ @config.stubs(:skype_name).returns("Maja")
39
+ @message.direct?.must_equal(true)
40
+ end
41
+
42
+ it "returns true if the beginning of the message contains the configured skype name, ignoring case" do
43
+ @message.body = "@Maja Hallo"
44
+ @config.stubs(:skype_name).returns("maja")
45
+ @message.direct?.must_equal(true)
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,67 @@
1
+ require_relative "../../../helper"
2
+ require_relative "../../../../lib/fabriq/skype/message"
3
+ require_relative "../../../../lib/fabriq/skype/room"
4
+
5
+ describe Fabriq::Skype::Room do
6
+
7
+ before do
8
+ @adapter = mock('Adapter')
9
+ @members = []
10
+ @room = Fabriq::Skype::Room.new(@adapter, "ab-99", @members, "raw")
11
+ end
12
+
13
+ describe '#private_session?' do
14
+ it "returns true if 2 members are in the room" do
15
+ @room.members = ["a", "b"]
16
+ @room.private_session?.must_equal(true)
17
+ end
18
+
19
+ it "returns false if more than 2 members are in the room" do
20
+ @room.members = ["a", "b", "c"]
21
+ @room.private_session?.must_equal(false)
22
+ end
23
+ end
24
+
25
+ describe '#send_message' do
26
+ before do
27
+ @adapter.stubs(:enqueue_outgoing_message)
28
+ end
29
+
30
+ it "builds a message from the passed string" do
31
+ opts = {}
32
+ @room.expects(:build_message_from_string).with("test", opts)
33
+ @room.send_message("test", opts)
34
+ end
35
+
36
+ it "enqueues the message in the outgoing channel" do
37
+ message = mock('Message')
38
+ @room.stubs(:build_message_from_string).returns(message)
39
+ @adapter.expects(:enqueue_outgoing_message).with(message)
40
+ @room.send_message("test")
41
+ end
42
+ end
43
+
44
+ describe '#build_message_from_string' do
45
+ it "creates a message object" do
46
+ @room.build_message_from_string("text").must_be_kind_of(Fabriq::Skype::Message)
47
+ end
48
+
49
+ it "assigns itself as room to the new message" do
50
+ @room.build_message_from_string("text").room.must_equal(@room)
51
+ end
52
+
53
+ it "assigns the passed body to the new message" do
54
+ @room.build_message_from_string("text").body.must_equal("text")
55
+ end
56
+
57
+ it "adds @name to the message if opts[to] is passed" do
58
+ @room.build_message_from_string("text", to: "treas").body.must_match(/@treas:/)
59
+ end
60
+
61
+ it "does not add @name if its a private session" do
62
+ @room.stubs(:private_session?).returns(true)
63
+ @room.build_message_from_string("text", to: "treas").body.wont_match(/@treas:/)
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,167 @@
1
+ require_relative "../../helper"
2
+ require_relative "../../../lib/fabriq/skype_proxy"
3
+
4
+ describe Fabriq::SkypeProxy do
5
+ before do
6
+ @adapter = mock('Adapter')
7
+ @skype_proxy = Fabriq::SkypeProxy.new(@adapter)
8
+ end
9
+
10
+ describe '#initialize' do
11
+ it "assigns the passed adapter" do
12
+ @skype_proxy.adapter.must_equal(@adapter)
13
+ end
14
+
15
+ it "initializes the outgoing message collection" do
16
+ @skype_proxy.outgoing_messages.must_equal([])
17
+ end
18
+ end
19
+
20
+ describe '#on_incoming_message' do
21
+ it "stores the passed block" do
22
+ proc = -> {}
23
+ @skype_proxy.on_incoming_message(&proc)
24
+ @skype_proxy.instance_variable_get(:@incoming_message_callbacks).must_include(proc)
25
+ end
26
+ end
27
+
28
+ describe '#subscribe_adapter_message_received' do
29
+ before do
30
+ @adapter.stubs(:message_received)
31
+ end
32
+
33
+ it "prepares the collection for received messages" do
34
+ @skype_proxy.subscribe_adapter_message_received
35
+ @skype_proxy.instance_variable_get(:@received_messages).must_equal([])
36
+ end
37
+
38
+ it "subscribes the #adapter's message_received event" do
39
+ @adapter.expects(:message_received)
40
+ @skype_proxy.subscribe_adapter_message_received
41
+ end
42
+
43
+ it "appends messages coming from #adapter#message_received" do
44
+ message = mock('Message')
45
+ @adapter.stubs(:message_received).yields(message)
46
+ @skype_proxy.subscribe_adapter_message_received
47
+ @skype_proxy.instance_variable_get(:@received_messages).must_include(message)
48
+ end
49
+ end
50
+
51
+ describe '#start' do
52
+ before do
53
+ @skype_proxy.stubs(:subscribe_adapter_message_received)
54
+ @skype_proxy.stubs(:start_queue_worker_threads)
55
+ end
56
+
57
+ it "hooks into the #adapters message_received callback" do
58
+ @skype_proxy.expects(:subscribe_adapter_message_received)
59
+ @skype_proxy.start
60
+ end
61
+
62
+ it "starts the queue worker threads" do
63
+ @skype_proxy.expects(:start_queue_worker_threads)
64
+ @skype_proxy.start
65
+ end
66
+ end
67
+
68
+ describe '#start_queue_worker_threads' do
69
+ before do
70
+ @skype_proxy.stubs(:run_in_thread).yields
71
+ @skype_proxy.stubs(:start_incoming_queue_worker)
72
+ @skype_proxy.stubs(:start_outgoing_queue_worker)
73
+ end
74
+
75
+ it "invokes #start_incoming_queue_worker in its own thread" do
76
+ @skype_proxy.expects(:start_incoming_queue_worker)
77
+ @skype_proxy.start_queue_worker_threads
78
+ end
79
+
80
+ it "invokes #start_outgoing_queue_worker in its own thread" do
81
+ @skype_proxy.expects(:start_outgoing_queue_worker)
82
+ @skype_proxy.start_queue_worker_threads
83
+ end
84
+ end
85
+
86
+ describe '#start_incoming_queue_worker' do
87
+ it "instruments a throttled run loop" do
88
+ @skype_proxy.expects(:run_in_throttled_loop)
89
+ @skype_proxy.start_incoming_queue_worker
90
+ end
91
+
92
+ it "calls #handle_incoming_messages_synchronized on every run loop round" do
93
+ @skype_proxy.stubs(:run_in_throttled_loop).yields
94
+ @skype_proxy.expects(:handle_incoming_messages_synchronized)
95
+ @skype_proxy.start_incoming_queue_worker
96
+ end
97
+ end
98
+
99
+ describe '#start_outgoing_queue_worker' do
100
+ it "instruments a throttled run loop" do
101
+ @skype_proxy.expects(:run_in_throttled_loop)
102
+ @skype_proxy.start_outgoing_queue_worker
103
+ end
104
+
105
+ it "calls #handle_outgoing_messages_synchronized on every run loop round" do
106
+ @skype_proxy.stubs(:run_in_throttled_loop).yields
107
+ @skype_proxy.expects(:handle_outgoing_messages_synchronized)
108
+ @skype_proxy.start_outgoing_queue_worker
109
+ end
110
+ end
111
+
112
+ describe '#handle_incoming_messages_synchronized' do
113
+ before do
114
+ @skype_proxy.instance_variable_get(:@incoming_mutex).stubs(:synchronize).yields
115
+ end
116
+
117
+ it "synchronizes processing using a mutex" do
118
+ @skype_proxy.instance_variable_get(:@incoming_mutex).expects(:synchronize)
119
+ @skype_proxy.handle_incoming_messages_synchronized
120
+ end
121
+
122
+ it "passes the oldest received message to all subscribed callbacks" do
123
+ message = mock('Message')
124
+ @skype_proxy.instance_variable_set(:@received_messages, [message])
125
+ @skype_proxy.expects(:invoke_incoming_message_subscribers).with(message)
126
+ @skype_proxy.handle_incoming_messages_synchronized
127
+ end
128
+ end
129
+
130
+ describe '#handle_outgoing_messages_synchronized' do
131
+ before do
132
+ @skype_proxy.instance_variable_get(:@outgoing_mutex).stubs(:synchronize).yields
133
+ end
134
+
135
+ it "synchronizes processing using a mutex" do
136
+ @skype_proxy.instance_variable_get(:@outgoing_mutex).expects(:synchronize)
137
+ @skype_proxy.handle_outgoing_messages_synchronized
138
+ end
139
+
140
+ it "sends outgoing messages using the adapter" do
141
+ message = mock('Message')
142
+ @adapter.expects(:send_message).with(message)
143
+ @skype_proxy.instance_variable_set(:@outgoing_messages, [message])
144
+ @skype_proxy.handle_outgoing_messages_synchronized
145
+ end
146
+ end
147
+
148
+ describe '#invoke_incoming_message_subscribers' do
149
+ before do
150
+ @message = mock("Message")
151
+ @callback = -> {}
152
+ @skype_proxy.instance_variable_set(:@incoming_message_callbacks, [@callback])
153
+ end
154
+
155
+ it "invokes each subscribed callback in its own thread" do
156
+ @skype_proxy.expects(:run_in_thread)
157
+ @skype_proxy.invoke_incoming_message_subscribers(@message)
158
+ end
159
+
160
+ it "invokes each subscribed callback passing the passed message" do
161
+ @callback.expects(:call).with(@message)
162
+ @skype_proxy.stubs(:run_in_thread).yields
163
+ @skype_proxy.invoke_incoming_message_subscribers(@message)
164
+ end
165
+ end
166
+
167
+ end