fabriq 0.1.0

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.
@@ -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