Comparison

spec/util_async_spec.lua @ 8618:680b1caa2dea

util.async: tests: replace peeking at internal state with monitoring correct callback behaviour
author Matthew Wild <mwild1@gmail.com>
date Sat, 17 Mar 2018 17:59:58 +0000
parent 8617:fafb4036771c
child 8622:92fee8a6c988
comparison
equal deleted inserted replaced
8617:fafb4036771c 8618:680b1caa2dea
83 end 83 end
84 assert.equal(last_item, values[#values]); 84 assert.equal(last_item, values[#values]);
85 end); 85 end);
86 86
87 describe("#errors", function () 87 describe("#errors", function ()
88 describe("should notify", function ()
89 local last_processed_item, last_error;
90 local r;
91 r = async.runner(function (item)
92 if item == "error" then
93 error({ e = "test error" });
94 end
95 last_processed_item = item;
96 end, mock{
97 ready = function () end;
98 waiting = function () end;
99 error = function (runner, err)
100 assert.equal(r, runner);
101 last_error = err;
102 end;
103 });
104
105 -- Simple item, no error
106 r:run("hello");
107 assert.equal(r.state, "ready");
108 assert.equal(last_processed_item, "hello");
109 assert.spy(r.watchers.ready).was_not.called();
110 assert.spy(r.watchers.error).was_not.called();
111
112 -- Trigger an error inside the runner
113 assert.equal(last_error, nil);
114 r:run("error");
115 test("the correct watcher functions", function ()
116 -- Only the error watcher should have been called
117 assert.spy(r.watchers.ready).was_not.called();
118 assert.spy(r.watchers.waiting).was_not.called();
119 assert.spy(r.watchers.error).was.called(1);
120 end);
121 test("with the correct error", function ()
122 -- The error watcher state should be correct, to
123 -- demonstrate the error was passed correctly
124 assert.is_table(last_error);
125 assert.equal(last_error.e, "test error");
126 last_error = nil;
127 end);
128 assert.equal(r.state, "ready");
129 assert.equal(last_processed_item, "hello");
130 end);
131
132
88 local last_processed_item, last_error; 133 local last_processed_item, last_error;
89 local r; 134 local r;
90 local wait, done; 135 local wait, done;
91 r = async.runner(function (item) 136 r = async.runner(function (item)
92 if item == "error" then 137 if item == "error" then
95 wait, done = async.waiter(); 140 wait, done = async.waiter();
96 wait(); 141 wait();
97 error({ e = "post wait error" }); 142 error({ e = "post wait error" });
98 end 143 end
99 last_processed_item = item; 144 last_processed_item = item;
100 end, { 145 end, mock({
146 ready = function () end;
147 waiting = function () end;
101 error = function (runner, err) 148 error = function (runner, err)
102 assert.equal(r, runner); 149 assert.equal(r, runner);
103 last_error = err; 150 last_error = err;
104 end; 151 end;
105 }); 152 }));
106 153
107 randomize(false); 154 randomize(false);
108 155
109 it("should notify", function ()
110 local last_processed_item, last_error;
111 local r;
112 r = async.runner(function (item)
113 if item == "error" then
114 error({ e = "test error" });
115 end
116 last_processed_item = item;
117 end, {
118 error = function (runner, err)
119 assert.equal(r, runner);
120 last_error = err;
121 end;
122 });
123
124 r:run("hello");
125 assert.equal(r.state, "ready");
126 assert.equal(last_processed_item, "hello");
127
128 assert.equal(last_error, nil);
129 r:run("error");
130 assert.is_table(last_error);
131 assert.equal(last_error.e, "test error");
132 last_error = nil;
133 assert.equal(r.state, "ready");
134 assert.equal(last_processed_item, "hello");
135 end);
136 it("should not be fatal to the runner", function () 156 it("should not be fatal to the runner", function ()
137 r:run("world"); 157 r:run("world");
138 assert.equal(r.state, "ready"); 158 assert.equal(r.state, "ready");
159 assert.spy(r.watchers.ready).was_not.called();
139 assert.equal(last_processed_item, "world"); 160 assert.equal(last_processed_item, "world");
140 end); 161 end);
141 it("should work despite a #waiter", function () 162 it("should work despite a #waiter", function ()
142 -- This test covers an important case where a runner 163 -- This test covers an important case where a runner
143 -- throws an error while being executed outside of the 164 -- throws an error while being executed outside of the
144 -- main loop. This happens when it was blocked ('waiting'), 165 -- main loop. This happens when it was blocked ('waiting'),
145 -- and then released (via a call to done()). 166 -- and then released (via a call to done()).
146 last_error = nil; 167 last_error = nil;
147 r:run("wait"); 168 r:run("wait");
148 assert.equal(r.state, "waiting"); 169 assert.equal(r.state, "waiting");
170 assert.spy(r.watchers.waiting).was.called(1);
149 done(); 171 done();
150 -- At this point an error happens (state goes error->ready) 172 -- At this point an error happens (state goes error->ready)
151 assert.equal(r.state, "ready"); 173 assert.equal(r.state, "ready");
174 assert.spy(r.watchers.error).was.called(1);
175 assert.spy(r.watchers.ready).was.called(1);
152 assert.is_table(last_error); 176 assert.is_table(last_error);
153 assert.equal(last_error.e, "post wait error"); 177 assert.equal(last_error.e, "post wait error");
154 last_error = nil; 178 last_error = nil;
155 r:run("hello again"); 179 r:run("hello again");
180 assert.spy(r.watchers.ready).was.called(1);
181 assert.spy(r.watchers.waiting).was.called(1);
182 assert.spy(r.watchers.error).was.called(1);
156 assert.equal(r.state, "ready"); 183 assert.equal(r.state, "ready");
157 assert.equal(last_processed_item, "hello again"); 184 assert.equal(last_processed_item, "hello again");
158 end); 185 end);
159 186
160 it("should continue to process work items", function () 187 it("should continue to process work items", function ()
161 local wait, done, last_item; 188 local wait, done, last_item;
162 local runner_func = spy.new(function (item) 189 local runner_func = spy.new(function (item)
163 if item == "error" then 190 if item == "error" then
164 error("test error"); 191 error("test error");
165 elseif item == "wait-error" then 192 end
193 last_item = item;
194 end);
195 local runner = async.runner(runner_func, mock{
196 ready = function () end;
197 waiting = function () end;
198 error = function () end;
199 });
200 runner:enqueue("one");
201 runner:enqueue("error");
202 runner:enqueue("two");
203 runner:run();
204 assert.equal(r.state, "ready");
205 assert.spy(runner_func).was.called(3);
206 assert.spy(runner.watchers.error).was.called(1);
207 assert.spy(runner.watchers.ready).was.called(0);
208 assert.spy(runner.watchers.waiting).was.called(0);
209 assert.equal(last_item, "two");
210 end);
211
212 it("should continue to process work items during resume", function ()
213 local wait, done, last_item;
214 local runner_func = spy.new(function (item)
215 if item == "wait-error" then
166 wait, done = async.waiter(); 216 wait, done = async.waiter();
167 wait(); 217 wait();
168 error("test error"); 218 error("test error");
169 end 219 end
170 last_item = item; 220 last_item = item;
171 end); 221 end);
172 local runner = async.runner(runner_func, { error = spy.new(function () end) }); 222 local runner = async.runner(runner_func, mock{
173 runner:enqueue("one"); 223 ready = function () end;
174 runner:enqueue("error"); 224 waiting = function () end;
175 runner:enqueue("two"); 225 error = function () end;
176 runner:run(); 226 });
177 assert.equal(r.state, "ready");
178 assert.equal(r.state, r.notified_state);
179 assert.spy(runner_func).was.called(3);
180 assert.spy(runner.watchers.error).was.called(1);
181 assert.equal(last_item, "two");
182 end);
183
184 it("should continue to process work items during resume", function ()
185 local wait, done, last_item;
186 local runner_func = spy.new(function (item)
187 if item == "error" then
188 error("test error");
189 elseif item == "wait-error" then
190 wait, done = async.waiter();
191 wait();
192 error("test error");
193 end
194 last_item = item;
195 end);
196 local runner = async.runner(runner_func, { error = spy.new(function () end) });
197 runner:enqueue("one"); 227 runner:enqueue("one");
198 runner:enqueue("wait-error"); 228 runner:enqueue("wait-error");
199 runner:enqueue("two"); 229 runner:enqueue("two");
200 runner:run(); 230 runner:run();
201 done(); 231 done();
202 assert.equal(r.state, "ready"); 232 assert.equal(r.state, "ready");
203 assert.equal(r.state, r.notified_state);
204 assert.spy(runner_func).was.called(3); 233 assert.spy(runner_func).was.called(3);
205 assert.spy(runner.watchers.error).was.called(1); 234 assert.spy(runner.watchers.error).was.called(1);
235 assert.spy(runner.watchers.waiting).was.called(1);
236 assert.spy(runner.watchers.ready).was.called(1);
206 assert.equal(last_item, "two"); 237 assert.equal(last_item, "two");
207 end); 238 end);
208 end); 239 end);
209 end); 240 end);
210 describe("#waiter", function() 241 describe("#waiter", function()