forked from meganz/Dexie.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tests-yield.js
316 lines (285 loc) · 10.2 KB
/
tests-yield.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
import Dexie from 'dexie';
import {module, stop, start, asyncTest, equal, ok} from 'QUnit';
import {resetDatabase} from './dexie-unittest-utils';
const db = new Dexie("TestYieldDb");
const async = Dexie.async;
const spawn = Dexie.spawn;
db.version(1).stores({
friends: '++id,name,*groups',
pets: '++id,name'
});
module("yield", {
setup: function () {
stop();
resetDatabase(db).catch(function (e) {
ok(false, "Error resetting database: " + e);
}).finally(start);
},
teardown: function () {
}
});
asyncTest ("db.transaction() with yield", async(function* () {
var finallyWasReached = false;
try {
yield db.transaction('rw', 'friends', 'pets', function* () {
// Add a cat and store it's final ID
var catId = yield db.pets.add({ name: "Tito", kind: "cat" });
// Add a dog in the same way.
var dogId = yield db.pets.add({ name: "Josephina", kind: "dog" });
// Add a friend who owns the pets
db.friends.add({ name: "Gurra G", pets: [catId, dogId] });
var gurra = yield db.friends.where('name').equals("Gurra G").first();
ok(!!gurra, "Gurra could be found with yield");
// Now retrieve the pet objects that Gurra is referring to:
var gurrasPets = yield db.pets.where('id').anyOf(gurra.pets).toArray();
equal(gurrasPets.length, 2, "Gurras all two pets could be retrieved via yield");
equal(gurrasPets[0].kind, "cat", "Gurras first pet is a cat");
equal(gurrasPets[1].kind, "dog", "Gurras second pet is a dog");
});
} catch(e) {
ok(false, "Caught error: " + e);
} finally {
finallyWasReached = true;
}
ok(finallyWasReached, "finally was reached");
start();
}));
asyncTest ("Catching indexedDB error event", 2, async(function* ()
{
try {
yield db.pets.add({id: 1, name: "Tidi", kind: "Honeybadger"});
ok(true, "Should come so far");
yield db.pets.add({id: 1, name: "Todoo", kind: "Snake"}); // Should generate an IDB error event!
ok(false, "Should not come here");
} catch (e) {
equal(e.name, "ConstraintError", "Caught indexedDB DOMError event ConstraintError");
}
start();
}));
asyncTest ("Catching error prevents transaction from aborting", 5, async(function* () {
try {
yield db.transaction('rw', 'pets', function*(){
try {
yield db.pets.add({id: 1, name: "Tidi", kind: "Honeybadger"});
ok(true, "Should come so far");
yield db.pets.add({id: 1, name: "Todoo", kind: "Snake"}); // Should generate an IDB error event!
ok(false, "Should not come here");
} catch (e) {
equal(e.name, "ConstraintError", "Caught indexedDB DOMError event ConstraintError");
}
});
ok (true, "Should come here - transaction committed because we caught the error");
ok ((yield db.pets.get(1)), "A pet with ID 1 exists in DB");
equal ((yield db.pets.get(1)).name, "Tidi", "It was Tidi in the first position");
} finally {
start();
}
}));
asyncTest("Transaction not committing when not catching error event", 4, async(function* ()
{
try {
yield db.transaction('rw', 'pets', function* ()
{
yield db.pets.add({id: 1, name: "Tidi", kind: "Honeybadger"});
ok(true, "Should come so far");
yield db.pets.add({id: 1, name: "Todoo", kind: "Snake"}); // Should generate an IDB error event!
ok(false, "Should not come here");
});
ok(false, "Should not come here");
} catch (e) {
ok(true, "Transaction should fail");
equal (e.name, "ConstraintError", "Error caught was a ConstraintError!");
equal ((yield db.pets.count()), 0, "Pets table should still be empty because transaction failed");
} finally {
start();
}
}));
asyncTest("Should allow yielding a non-promise", async(function* () {
try {
var x = yield 3;
equal(x, 3, "Could yield a non-promise");
} catch (e) {
ok(false, "Yielding a non-Thenable wasn't be allowed");
} finally {
start();
}
}));
asyncTest("Should allow yielding an array with a mix of values and thenables", async(function* () {
try {
var results = yield [1, 2, Dexie.Promise.resolve(3)];
equal(results.length, 3, "Yielded array is of size 3");
equal(results[0], 1, "First value is 1");
equal(results[1], 2, "Second value is 2");
equal(results[2], 3, "Third value is 3");
} catch (e) {
ok(false, "Got exception when trying to do yield an array of mixed values/promises");
} finally {
start();
}
}));
asyncTest("Should allow yielding an array of non-promises only", async(function* () {
try {
var results = yield [1,2,3];
equal(results.length, 3, "Yielded array is of size 3");
equal(results[0], 1, "First value is 1");
equal(results[1], 2, "Second value is 2");
equal(results[2], 3, "Third value is 3");
} catch (e) {
ok(false, e);
} finally {
start();
}
}));
asyncTest("Should allow yielding an empty array", async(function* () {
try {
var results = yield [];
equal(results.length, 0, "Yielded array is of size 0");
} catch (e) {
ok(false, e);
} finally {
start();
}
}));
asyncTest("Should allow yielding an array of different kind of any kind of promise", function () {
spawn (function*()
{
var results = yield [Promise.resolve(1), Dexie.Promise.resolve(2), Promise.resolve(3)];
equal(results.length, 3, "Yielded array is of size 3");
equal(results[0], 1, "First value is 1");
equal(results[1], 2, "Second value is 2");
equal(results[2], 3, "Third value is 3");
return 4;
}).then (function(x) {
equal(x, 4, "Finally got the value 4");
}).catch (function(e) {
ok(false, "Something is rotten in the state of Denmark: " + e);
}).then(start);
});
asyncTest("Throw after yield 1", function () {
spawn (function*()
{
try {
yield Promise.resolve(3);
ok(true, "yielded a value");
throw "error";
} catch (e) {
ok(e === "error", "Catched exception: " + e);
}
return 4;
}).then (function(x) {
equal(x, 4, "Finally got the value 4");
}).catch (function(e) {
ok(false, "Something is rotten in the state of Denmark: " + e);
}).then(start);
});
asyncTest("Throw after yield 2", function () {
Promise.resolve(spawn (function*()
{
try {
yield 3;
ok(true, "yielded a value");
throw "error";
} catch (e) {
ok(e === "error", "Catched exception: " + e);
}
return 4;
})).then (function(x) {
equal(x, 4, "Finally got the value 4");
}).catch (function(e) {
ok(false, "Something is rotten in the state of Denmark: " + e);
}).then(start);
});
asyncTest("Throw before yield", function () {
Promise.resolve(spawn (function*()
{
try {
throw "error";
} catch (e) {
ok(e === "error", "Catched exception: " + e);
}
return 4;
})).then (function(x) {
equal(x, 4, "Finally got the value 4");
}).catch (function(e) {
ok(false, "Something is rotten in the state of Denmark: " + e);
}).then(start);
});
asyncTest("Catch rejected promise", function () {
spawn (function*() {
try {
yield new Promise(function(resolve, reject) { reject("fault fault!"); });
ok(false, "Shouldn't come here");
} catch (e) {
ok(e === "fault fault!", "Catched exception: " + e);
}
return 4;
}).then (function(x) {
equal(x, 4, "Finally got the value 4");
}).catch (function(e) {
ok(false, "Something is rotten in the state of Denmark: " + e);
}).then(start);
});
asyncTest("Catch rejected promise in an array", function () {
spawn (function*() {
try {
yield [1, 2, new Promise(function(resolve, reject) { reject("fault fault!"); }), 4];
ok(false, "Shouldn't come here");
} catch (e) {
ok(e === "fault fault!", "Catched exception: " + e);
}
return 4;
}).then (function(x) {
equal(x, 4, "Finally got the value 4");
}).catch (function(e) {
ok(false, "Something is rotten in the state of Denmark: " + e);
}).then(start);
});
asyncTest("Should allow returning a promise", function () {
spawn (function*()
{
return Promise.resolve(3);
}).then (function(result) {
equal(result, 3, "Returning a directly should also be allowed");
}).catch (function(e) {
ok(false, e);
}).then(start);
});
asyncTest("Should be able to do 'return yield Promise.resolve(x);'", function () {
spawn (function*()
{
return yield Promise.resolve(3);
}).then (function() {
ok(true, "Should be able to do 'return yield Promise.resolve(x);'");
}).catch (function(e) {
ok(false, "Error occurred: " + e);
}).then(start);
});
asyncTest("Arrow functions and let", async(function*() {
let x = yield [1, 2, Promise.resolve(3)];
let y = x.map(a => a - 1);
equal(y[0], 0);
equal(y[1], 1);
equal(y[2], 2);
start();
}));
asyncTest("Calling sub async function", async(function*(){
var addFriend = async(function* addFriend(friend) {
let friendId = yield db.friends.add(friend);
return yield db.friends.get (friendId);
});
var deleteFriends = async(function* deleteFriends() {
return yield db.friends.where('name').anyOf("Foo", "Bar").delete();
});
try {
let foo = yield addFriend({name: "Foo"});
let bar = yield addFriend({name: "Bar"});
ok(foo.name == "Foo", "Foo got its name");
ok(bar.name == "Bar", "Bar got its name");
let numDeleted = yield deleteFriends();
ok (true, numDeleted + " friends successfully deleted")
} catch (e) {
ok(false, e);
} finally {
start();
}
}));