qs 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +6 -1
- data/LICENSE.txt +1 -1
- data/bench/config.qs +46 -0
- data/bench/queue.rb +8 -0
- data/bench/report.rb +114 -0
- data/bench/report.txt +11 -0
- data/bin/qs +7 -0
- data/lib/qs/cli.rb +124 -0
- data/lib/qs/client.rb +121 -0
- data/lib/qs/config_file.rb +79 -0
- data/lib/qs/daemon.rb +350 -0
- data/lib/qs/daemon_data.rb +46 -0
- data/lib/qs/error_handler.rb +58 -0
- data/lib/qs/job.rb +70 -0
- data/lib/qs/job_handler.rb +90 -0
- data/lib/qs/logger.rb +23 -0
- data/lib/qs/payload_handler.rb +136 -0
- data/lib/qs/pid_file.rb +42 -0
- data/lib/qs/process.rb +136 -0
- data/lib/qs/process_signal.rb +20 -0
- data/lib/qs/qs_runner.rb +49 -0
- data/lib/qs/queue.rb +69 -0
- data/lib/qs/redis_item.rb +33 -0
- data/lib/qs/route.rb +52 -0
- data/lib/qs/runner.rb +26 -0
- data/lib/qs/test_helpers.rb +17 -0
- data/lib/qs/test_runner.rb +43 -0
- data/lib/qs/version.rb +1 -1
- data/lib/qs.rb +92 -2
- data/qs.gemspec +7 -2
- data/test/helper.rb +8 -1
- data/test/support/app_daemon.rb +74 -0
- data/test/support/config.qs +7 -0
- data/test/support/config_files/empty.qs +0 -0
- data/test/support/config_files/invalid.qs +1 -0
- data/test/support/config_files/valid.qs +7 -0
- data/test/support/config_invalid_run.qs +3 -0
- data/test/support/config_no_run.qs +0 -0
- data/test/support/factory.rb +14 -0
- data/test/support/pid_file_spy.rb +19 -0
- data/test/support/runner_spy.rb +17 -0
- data/test/system/daemon_tests.rb +226 -0
- data/test/unit/cli_tests.rb +188 -0
- data/test/unit/client_tests.rb +269 -0
- data/test/unit/config_file_tests.rb +59 -0
- data/test/unit/daemon_data_tests.rb +96 -0
- data/test/unit/daemon_tests.rb +702 -0
- data/test/unit/error_handler_tests.rb +163 -0
- data/test/unit/job_handler_tests.rb +253 -0
- data/test/unit/job_tests.rb +132 -0
- data/test/unit/logger_tests.rb +38 -0
- data/test/unit/payload_handler_tests.rb +276 -0
- data/test/unit/pid_file_tests.rb +70 -0
- data/test/unit/process_signal_tests.rb +61 -0
- data/test/unit/process_tests.rb +371 -0
- data/test/unit/qs_runner_tests.rb +166 -0
- data/test/unit/qs_tests.rb +217 -0
- data/test/unit/queue_tests.rb +132 -0
- data/test/unit/redis_item_tests.rb +49 -0
- data/test/unit/route_tests.rb +81 -0
- data/test/unit/runner_tests.rb +63 -0
- data/test/unit/test_helper_tests.rb +61 -0
- data/test/unit/test_runner_tests.rb +128 -0
- metadata +180 -15
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'qs'
|
3
|
+
|
4
|
+
require 'hella-redis/connection_spy'
|
5
|
+
require 'ns-options/assert_macros'
|
6
|
+
require 'qs/job'
|
7
|
+
require 'qs/queue'
|
8
|
+
|
9
|
+
module Qs
|
10
|
+
|
11
|
+
class UnitTests < Assert::Context
|
12
|
+
desc "Qs"
|
13
|
+
setup do
|
14
|
+
Qs.reset!
|
15
|
+
@module = Qs
|
16
|
+
end
|
17
|
+
teardown do
|
18
|
+
Qs.reset!
|
19
|
+
Qs.init
|
20
|
+
end
|
21
|
+
subject{ @module }
|
22
|
+
|
23
|
+
should have_imeths :config, :configure, :init, :reset!
|
24
|
+
should have_imeths :enqueue, :push
|
25
|
+
should have_imeths :serialize, :deserialize
|
26
|
+
should have_imeths :client, :redis, :redis_config
|
27
|
+
|
28
|
+
should "know its config" do
|
29
|
+
assert_instance_of Config, subject.config
|
30
|
+
end
|
31
|
+
|
32
|
+
should "allow configuring its config" do
|
33
|
+
yielded = nil
|
34
|
+
subject.configure{ |c| yielded = c }
|
35
|
+
assert_equal subject.config, yielded
|
36
|
+
end
|
37
|
+
|
38
|
+
should "not have a client or redis connection by default" do
|
39
|
+
assert_nil subject.client
|
40
|
+
assert_nil subject.redis
|
41
|
+
end
|
42
|
+
|
43
|
+
should "know its redis config" do
|
44
|
+
expected = subject.config.redis.to_hash
|
45
|
+
assert_equal expected, subject.redis_config
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
class InitTests < UnitTests
|
51
|
+
desc "when init"
|
52
|
+
setup do
|
53
|
+
@module.config.serializer = proc{ |v| v.to_s }
|
54
|
+
@module.config.deserializer = proc{ |v| v.to_i }
|
55
|
+
@module.config.redis.ip = Factory.string
|
56
|
+
@module.config.redis.port = Factory.integer
|
57
|
+
@module.config.redis.db = Factory.integer
|
58
|
+
|
59
|
+
@client_spy = nil
|
60
|
+
Assert.stub(Client, :new) do |*args|
|
61
|
+
@client_spy = ClientSpy.new(*args)
|
62
|
+
end
|
63
|
+
|
64
|
+
@module.init
|
65
|
+
end
|
66
|
+
|
67
|
+
should "set its configured redis url" do
|
68
|
+
expected = RedisUrl.new(
|
69
|
+
subject.config.redis.ip,
|
70
|
+
subject.config.redis.port,
|
71
|
+
subject.config.redis.db
|
72
|
+
)
|
73
|
+
assert_equal expected, subject.config.redis.url
|
74
|
+
end
|
75
|
+
|
76
|
+
should "build a client" do
|
77
|
+
assert_equal @client_spy, subject.client
|
78
|
+
assert_equal @client_spy.redis, subject.redis
|
79
|
+
assert_equal subject.redis_config, @client_spy.redis_config
|
80
|
+
end
|
81
|
+
|
82
|
+
should "call enqueue on its client using `enqueue`" do
|
83
|
+
queue = Qs::Queue.new{ name Factory.string }
|
84
|
+
job_name = Factory.string
|
85
|
+
job_params = { Factory.string => Factory.string }
|
86
|
+
subject.enqueue(queue, job_name, job_params)
|
87
|
+
|
88
|
+
call = @client_spy.enqueue_calls.last
|
89
|
+
assert_equal queue, call.queue
|
90
|
+
assert_equal job_name, call.job_name
|
91
|
+
assert_equal job_params, call.job_params
|
92
|
+
end
|
93
|
+
|
94
|
+
should "call push on its client using `push`" do
|
95
|
+
queue_name = Factory.string
|
96
|
+
payload = { Factory.string => Factory.string }
|
97
|
+
subject.push(queue_name, payload)
|
98
|
+
|
99
|
+
call = @client_spy.push_calls.last
|
100
|
+
assert_equal queue_name, call.queue_name
|
101
|
+
assert_equal payload, call.payload
|
102
|
+
end
|
103
|
+
|
104
|
+
should "use the configured serializer using `serialize`" do
|
105
|
+
value = Factory.integer
|
106
|
+
result = subject.serialize(value)
|
107
|
+
assert_equal value.to_s, result
|
108
|
+
end
|
109
|
+
|
110
|
+
should "use the configured deserializer using `deserialize`" do
|
111
|
+
value = Factory.integer.to_s
|
112
|
+
result = subject.deserialize(value)
|
113
|
+
assert_equal value.to_i, result
|
114
|
+
end
|
115
|
+
|
116
|
+
should "not reset its client or redis connection when init again" do
|
117
|
+
client = subject.client
|
118
|
+
redis = subject.redis
|
119
|
+
subject.init
|
120
|
+
assert_same client, subject.client
|
121
|
+
assert_same redis, subject.redis
|
122
|
+
end
|
123
|
+
|
124
|
+
should "reset itself using `reset!`" do
|
125
|
+
subject.reset!
|
126
|
+
assert_nil subject.config.redis.url
|
127
|
+
assert_nil subject.client
|
128
|
+
assert_nil subject.redis
|
129
|
+
assert_raises(NoMethodError){ subject.serialize(Factory.integer) }
|
130
|
+
assert_raises(NoMethodError){ subject.deserialize(Factory.integer) }
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
class ConfigTests < UnitTests
|
136
|
+
include NsOptions::AssertMacros
|
137
|
+
|
138
|
+
desc "Config"
|
139
|
+
setup do
|
140
|
+
@config = Config.new
|
141
|
+
end
|
142
|
+
subject{ @config }
|
143
|
+
|
144
|
+
should have_options :serializer, :deserializer, :timeout
|
145
|
+
should have_namespace :redis
|
146
|
+
|
147
|
+
should "know its default serializer/deserializer" do
|
148
|
+
payload = { Factory.string => Factory.string }
|
149
|
+
|
150
|
+
exp = JSON.dump(payload)
|
151
|
+
serialized_payload = subject.serializer.call(payload)
|
152
|
+
assert_equal exp, serialized_payload
|
153
|
+
exp = JSON.load(exp)
|
154
|
+
assert_equal exp, subject.deserializer.call(serialized_payload)
|
155
|
+
end
|
156
|
+
|
157
|
+
should "know its default timeout" do
|
158
|
+
assert_nil subject.timeout
|
159
|
+
end
|
160
|
+
|
161
|
+
should "know its default redis options" do
|
162
|
+
assert_equal 'localhost', subject.redis.ip
|
163
|
+
assert_equal 6379, subject.redis.port
|
164
|
+
assert_equal 0, subject.redis.db
|
165
|
+
assert_equal 'qs', subject.redis.redis_ns
|
166
|
+
assert_equal 'ruby', subject.redis.driver
|
167
|
+
assert_equal 1, subject.redis.timeout
|
168
|
+
assert_equal 4, subject.redis.size
|
169
|
+
assert_nil subject.redis.url
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
class RedisUrlTests < UnitTests
|
175
|
+
desc "RedisUrl"
|
176
|
+
subject{ RedisUrl }
|
177
|
+
|
178
|
+
should "build a redis url when passed an ip, port and db" do
|
179
|
+
ip = Factory.string
|
180
|
+
port = Factory.integer
|
181
|
+
db = Factory.integer
|
182
|
+
expected = "redis://#{ip}:#{port}/#{db}"
|
183
|
+
assert_equal expected, subject.new(ip, port, db)
|
184
|
+
end
|
185
|
+
|
186
|
+
should "not return a url with an ip, port or db" do
|
187
|
+
assert_nil subject.new(nil, Factory.integer, Factory.integer)
|
188
|
+
assert_nil subject.new(Factory.string, nil, Factory.integer)
|
189
|
+
assert_nil subject.new(Factory.string, Factory.integer, nil)
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
class ClientSpy
|
195
|
+
attr_reader :redis_config, :redis
|
196
|
+
attr_reader :enqueue_calls, :push_calls
|
197
|
+
|
198
|
+
def initialize(redis_confg)
|
199
|
+
@redis_config = redis_confg
|
200
|
+
@redis = Factory.string
|
201
|
+
@enqueue_calls = []
|
202
|
+
@push_calls = []
|
203
|
+
end
|
204
|
+
|
205
|
+
def enqueue(queue, job_name, job_params = nil)
|
206
|
+
@enqueue_calls << EnqueueCall.new(queue, job_name, job_params)
|
207
|
+
end
|
208
|
+
|
209
|
+
def push(queue_name, payload)
|
210
|
+
@push_calls << PushCall.new(queue_name, payload)
|
211
|
+
end
|
212
|
+
|
213
|
+
EnqueueCall = Struct.new(:queue, :job_name, :job_params)
|
214
|
+
PushCall = Struct.new(:queue_name, :payload)
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'qs/queue'
|
3
|
+
|
4
|
+
require 'test/support/factory'
|
5
|
+
|
6
|
+
class Qs::Queue
|
7
|
+
|
8
|
+
class UnitTests < Assert::Context
|
9
|
+
desc "Qs::Queue"
|
10
|
+
setup do
|
11
|
+
@queue = Qs::Queue.new do
|
12
|
+
name Factory.string
|
13
|
+
end
|
14
|
+
end
|
15
|
+
subject{ @queue }
|
16
|
+
|
17
|
+
should have_readers :routes, :enqueued_jobs
|
18
|
+
should have_imeths :name, :redis_key, :job_handler_ns, :job
|
19
|
+
should have_imeths :enqueue, :add
|
20
|
+
should have_imeths :reset!
|
21
|
+
|
22
|
+
should "default its routes to an empty array" do
|
23
|
+
assert_equal [], subject.routes
|
24
|
+
end
|
25
|
+
|
26
|
+
should "default its enqueued jobs to an empty array" do
|
27
|
+
assert_equal [], subject.enqueued_jobs
|
28
|
+
end
|
29
|
+
|
30
|
+
should "allow setting its name" do
|
31
|
+
name = Factory.string
|
32
|
+
subject.name name
|
33
|
+
assert_equal name, subject.name
|
34
|
+
end
|
35
|
+
|
36
|
+
should "know its redis key" do
|
37
|
+
result = subject.redis_key
|
38
|
+
assert_equal RedisKey.new(subject.name), result
|
39
|
+
assert_same result, subject.redis_key
|
40
|
+
end
|
41
|
+
|
42
|
+
should "not have a job handler ns by default" do
|
43
|
+
assert_nil subject.job_handler_ns
|
44
|
+
end
|
45
|
+
|
46
|
+
should "allow setting its job handler ns" do
|
47
|
+
namespace = Factory.string
|
48
|
+
subject.job_handler_ns namespace
|
49
|
+
assert_equal namespace, subject.job_handler_ns
|
50
|
+
end
|
51
|
+
|
52
|
+
should "allow adding routes using `job`" do
|
53
|
+
job_name = Factory.string
|
54
|
+
handler_name = Factory.string
|
55
|
+
subject.job job_name, handler_name
|
56
|
+
|
57
|
+
route = subject.routes.last
|
58
|
+
assert_instance_of Qs::Route, route
|
59
|
+
assert_equal job_name, route.name
|
60
|
+
assert_equal handler_name, route.handler_class_name
|
61
|
+
end
|
62
|
+
|
63
|
+
should "use its job handler ns when adding routes" do
|
64
|
+
namespace = Factory.string
|
65
|
+
subject.job_handler_ns namespace
|
66
|
+
|
67
|
+
job_name = Factory.string
|
68
|
+
handler_name = Factory.string
|
69
|
+
subject.job job_name, handler_name
|
70
|
+
|
71
|
+
route = subject.routes.last
|
72
|
+
expected = "#{namespace}::#{handler_name}"
|
73
|
+
assert_equal expected, route.handler_class_name
|
74
|
+
end
|
75
|
+
|
76
|
+
should "know its custom inspect" do
|
77
|
+
reference = '0x0%x' % (subject.object_id << 1)
|
78
|
+
expected = "#<#{subject.class}:#{reference} " \
|
79
|
+
"@name=#{subject.name.inspect} " \
|
80
|
+
"@job_handler_ns=#{subject.job_handler_ns.inspect}>"
|
81
|
+
assert_equal expected, subject.inspect
|
82
|
+
end
|
83
|
+
|
84
|
+
should "require a name when initialized" do
|
85
|
+
assert_raises(InvalidError){ Qs::Queue.new }
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
class EnqueueTests < UnitTests
|
91
|
+
setup do
|
92
|
+
@enqueue_args = nil
|
93
|
+
Assert.stub(Qs, :enqueue){ |*args| @enqueue_args = args }
|
94
|
+
|
95
|
+
@job_name = Factory.string
|
96
|
+
@job_params = { Factory.string => Factory.string }
|
97
|
+
end
|
98
|
+
|
99
|
+
should "add jobs using `enqueue`" do
|
100
|
+
result = subject.enqueue(@job_name, @job_params)
|
101
|
+
exp = [subject, @job_name, @job_params]
|
102
|
+
assert_equal exp, @enqueue_args
|
103
|
+
assert_equal @enqueue_args, result
|
104
|
+
end
|
105
|
+
|
106
|
+
should "add jobs using `add`" do
|
107
|
+
result = subject.add(@job_name, @job_params)
|
108
|
+
exp = [subject, @job_name, @job_params]
|
109
|
+
assert_equal exp, @enqueue_args
|
110
|
+
assert_equal @enqueue_args, result
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
class RedisKeyTests < UnitTests
|
116
|
+
desc "RedisKey"
|
117
|
+
subject{ RedisKey }
|
118
|
+
|
119
|
+
should have_imeths :parse_name, :new
|
120
|
+
|
121
|
+
should "know how to build a redis key" do
|
122
|
+
assert_equal "queues:#{@queue.name}", subject.new(@queue.name)
|
123
|
+
end
|
124
|
+
|
125
|
+
should "know how to parse a queue name from a key" do
|
126
|
+
redis_key = subject.new(@queue.name)
|
127
|
+
assert_equal @queue.name, subject.parse_name(redis_key)
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'qs/redis_item'
|
3
|
+
|
4
|
+
class Qs::RedisItem
|
5
|
+
|
6
|
+
class UnitTests < Assert::Context
|
7
|
+
desc "Qs::RedisItem"
|
8
|
+
setup do
|
9
|
+
@queue_redis_key = Factory.string
|
10
|
+
@serialized_payload = Factory.string
|
11
|
+
@redis_item = Qs::RedisItem.new(@queue_redis_key, @serialized_payload)
|
12
|
+
end
|
13
|
+
subject{ @redis_item }
|
14
|
+
|
15
|
+
should have_readers :queue_redis_key, :serialized_payload
|
16
|
+
should have_accessors :started, :finished
|
17
|
+
should have_accessors :job, :handler_class
|
18
|
+
should have_accessors :exception, :time_taken
|
19
|
+
|
20
|
+
should "know its queue redis key and serialized payload" do
|
21
|
+
assert_equal @queue_redis_key, subject.queue_redis_key
|
22
|
+
assert_equal @serialized_payload, subject.serialized_payload
|
23
|
+
end
|
24
|
+
|
25
|
+
should "defaults its other attributes" do
|
26
|
+
assert_false subject.started
|
27
|
+
assert_false subject.finished
|
28
|
+
|
29
|
+
assert_nil subject.job
|
30
|
+
assert_nil subject.handler_class
|
31
|
+
assert_nil subject.exception
|
32
|
+
assert_nil subject.time_taken
|
33
|
+
end
|
34
|
+
|
35
|
+
should "know if it equals another item" do
|
36
|
+
exp = Qs::RedisItem.new(@queue_redis_key, @serialized_payload)
|
37
|
+
assert_equal exp, subject
|
38
|
+
|
39
|
+
redis_key = Qs::Queue::RedisKey.new(Factory.string)
|
40
|
+
exp = Qs::RedisItem.new(redis_key, @serialized_payload)
|
41
|
+
assert_not_equal exp, subject
|
42
|
+
|
43
|
+
exp = Qs::RedisItem.new(@queue_redis_key, Factory.string)
|
44
|
+
assert_not_equal exp, subject
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'qs/route'
|
3
|
+
|
4
|
+
require 'qs/daemon_data'
|
5
|
+
require 'qs/logger'
|
6
|
+
require 'qs/job'
|
7
|
+
require 'test/support/runner_spy'
|
8
|
+
|
9
|
+
class Qs::Route
|
10
|
+
|
11
|
+
class UnitTests < Assert::Context
|
12
|
+
desc "Qs::Route"
|
13
|
+
setup do
|
14
|
+
@name = Factory.string
|
15
|
+
@handler_class_name = TestHandler.to_s
|
16
|
+
@route = Qs::Route.new(@name, @handler_class_name)
|
17
|
+
end
|
18
|
+
subject{ @route }
|
19
|
+
|
20
|
+
should have_readers :name, :handler_class_name, :handler_class
|
21
|
+
should have_imeths :validate!, :run
|
22
|
+
|
23
|
+
should "know its name and handler class name" do
|
24
|
+
assert_equal @name, subject.name
|
25
|
+
assert_equal @handler_class_name, subject.handler_class_name
|
26
|
+
end
|
27
|
+
|
28
|
+
should "not know its handler class by default" do
|
29
|
+
assert_nil subject.handler_class
|
30
|
+
end
|
31
|
+
|
32
|
+
should "constantize its handler class after being validated" do
|
33
|
+
subject.validate!
|
34
|
+
assert_equal TestHandler, subject.handler_class
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
class RunTests < UnitTests
|
40
|
+
desc "when run"
|
41
|
+
setup do
|
42
|
+
@job = Qs::Job.new(Factory.string, Factory.string => Factory.string)
|
43
|
+
@daemon_data = Qs::DaemonData.new(:logger => Qs::NullLogger.new)
|
44
|
+
|
45
|
+
@runner_spy = nil
|
46
|
+
Assert.stub(Qs::QsRunner, :new) do |*args|
|
47
|
+
@runner_spy = RunnerSpy.new(*args)
|
48
|
+
end
|
49
|
+
|
50
|
+
@route.run(@job, @daemon_data)
|
51
|
+
end
|
52
|
+
|
53
|
+
should "build and run a qs runner" do
|
54
|
+
assert_not_nil @runner_spy
|
55
|
+
assert_equal @route.handler_class, @runner_spy.handler_class
|
56
|
+
expected = {
|
57
|
+
:job => @job,
|
58
|
+
:params => @job.params,
|
59
|
+
:logger => @daemon_data.logger
|
60
|
+
}
|
61
|
+
assert_equal expected, @runner_spy.args
|
62
|
+
assert_true @runner_spy.run_called
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
class InvalidHandlerClassNameTests < UnitTests
|
68
|
+
desc "with an invalid handler class name"
|
69
|
+
setup do
|
70
|
+
@route = Qs::Route.new(@name, Factory.string)
|
71
|
+
end
|
72
|
+
|
73
|
+
should "raise a no handler class error when validated" do
|
74
|
+
assert_raises(Qs::NoHandlerClassError){ subject.validate! }
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
TestHandler = Class.new
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'qs/runner'
|
3
|
+
|
4
|
+
require 'qs/job_handler'
|
5
|
+
require 'qs/logger'
|
6
|
+
|
7
|
+
class Qs::Runner
|
8
|
+
|
9
|
+
class UnitTests < Assert::Context
|
10
|
+
desc "Qs::Runner"
|
11
|
+
setup do
|
12
|
+
@runner_class = Qs::Runner
|
13
|
+
end
|
14
|
+
subject{ @runner_class }
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
class InitTests < UnitTests
|
19
|
+
desc "when init"
|
20
|
+
setup do
|
21
|
+
@handler_class = TestJobHandler
|
22
|
+
@runner = @runner_class.new(@handler_class)
|
23
|
+
end
|
24
|
+
subject{ @runner }
|
25
|
+
|
26
|
+
should have_readers :handler_class, :handler
|
27
|
+
should have_readers :job, :params, :logger
|
28
|
+
should have_imeths :run
|
29
|
+
|
30
|
+
should "know its handler class and handler" do
|
31
|
+
assert_equal @handler_class, subject.handler_class
|
32
|
+
assert_instance_of @handler_class, subject.handler
|
33
|
+
end
|
34
|
+
|
35
|
+
should "not set its job, params or logger by default" do
|
36
|
+
assert_nil subject.job
|
37
|
+
assert_equal({}, subject.params)
|
38
|
+
assert_instance_of Qs::NullLogger, subject.logger
|
39
|
+
end
|
40
|
+
|
41
|
+
should "allow passing a job, params and logger" do
|
42
|
+
args = {
|
43
|
+
:job => Factory.string,
|
44
|
+
:params => Factory.string,
|
45
|
+
:logger => Factory.string
|
46
|
+
}
|
47
|
+
runner = @runner_class.new(@handler_class, args)
|
48
|
+
assert_equal args[:job], runner.job
|
49
|
+
assert_equal args[:params], runner.params
|
50
|
+
assert_equal args[:logger], runner.logger
|
51
|
+
end
|
52
|
+
|
53
|
+
should "raise a not implemented error when run" do
|
54
|
+
assert_raises(NotImplementedError){ subject.run }
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
class TestJobHandler
|
60
|
+
include Qs::JobHandler
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'assert'
|
2
|
+
require 'qs/test_helpers'
|
3
|
+
|
4
|
+
require 'qs/job_handler'
|
5
|
+
require 'test/support/runner_spy'
|
6
|
+
|
7
|
+
module Qs::TestHelpers
|
8
|
+
|
9
|
+
class UnitTests < Assert::Context
|
10
|
+
desc "Qs::TestHelpers"
|
11
|
+
setup do
|
12
|
+
@test_helpers = Qs::TestHelpers
|
13
|
+
end
|
14
|
+
subject{ @test_helpers }
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
class MixinTests < UnitTests
|
19
|
+
desc "as a mixin"
|
20
|
+
setup do
|
21
|
+
context_class = Class.new{ include Qs::TestHelpers }
|
22
|
+
@context = context_class.new
|
23
|
+
end
|
24
|
+
subject{ @context }
|
25
|
+
|
26
|
+
should have_imeths :test_runner, :test_handler
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
class HandlerTestRunnerTests < MixinTests
|
31
|
+
desc "for handler testing"
|
32
|
+
setup do
|
33
|
+
@handler_class = Class.new
|
34
|
+
@args = { Factory.string => Factory.string }
|
35
|
+
|
36
|
+
@runner_spy = nil
|
37
|
+
Assert.stub(Qs::TestRunner, :new) do |*args|
|
38
|
+
@runner_spy = RunnerSpy.new(*args)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
should "build a test runner for a given handler" do
|
43
|
+
result = subject.test_runner(@handler_class, @args)
|
44
|
+
|
45
|
+
assert_not_nil @runner_spy
|
46
|
+
assert_equal @handler_class, @runner_spy.handler_class
|
47
|
+
assert_equal @args, @runner_spy.args
|
48
|
+
assert_equal @runner_spy, result
|
49
|
+
end
|
50
|
+
|
51
|
+
should "return an initialized handler instance" do
|
52
|
+
result = subject.test_handler(@handler_class, @args)
|
53
|
+
|
54
|
+
assert_not_nil @runner_spy
|
55
|
+
assert_equal @runner_spy.handler, result
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|