1 |
|
2 | var DRIVERS = [
|
3 | localforage.INDEXEDDB,
|
4 | localforage.LOCALSTORAGE,
|
5 | localforage.WEBSQL
|
6 | ];
|
7 |
|
8 | var SUPPORTED_DRIVERS = DRIVERS.filter(function(driverName) {
|
9 | return localforage.supports(driverName);
|
10 | });
|
11 |
|
12 | var driverApiMethods = [
|
13 | 'getItem',
|
14 | 'setItem',
|
15 | 'clear',
|
16 | 'length',
|
17 | 'removeItem',
|
18 | 'key',
|
19 | 'keys'
|
20 | ];
|
21 |
|
22 |
|
23 | var indexedDB = (indexedDB || window.indexedDB ||
|
24 | window.webkitIndexedDB ||
|
25 | window.mozIndexedDB || window.OIndexedDB ||
|
26 | window.msIndexedDB);
|
27 |
|
28 | describe('localForage API', function() {
|
29 |
|
30 | it('has Promises available', function() {
|
31 | expect(Promise).to.be.a('function');
|
32 | });
|
33 | });
|
34 |
|
35 | describe('localForage', function() {
|
36 | var appropriateDriver =
|
37 | (localforage.supports(localforage.INDEXEDDB) &&
|
38 | localforage.INDEXEDDB) ||
|
39 | (localforage.supports(localforage.WEBSQL) &&
|
40 | localforage.WEBSQL) ||
|
41 | (localforage.supports(localforage.LOCALSTORAGE) &&
|
42 | localforage.LOCALSTORAGE);
|
43 |
|
44 | it('automatically selects the most appropriate driver (' +
|
45 | appropriateDriver + ')', function(done) {
|
46 | this.timeout(10000);
|
47 | localforage.ready().then(function() {
|
48 | expect(localforage.driver()).to.be(appropriateDriver);
|
49 | done();
|
50 | }, function(error) {
|
51 | expect(error).to.be.an(Error);
|
52 | expect(error.message).to
|
53 | .be('No available storage method found.');
|
54 | expect(localforage.driver()).to.be(null);
|
55 | done();
|
56 | });
|
57 | });
|
58 |
|
59 | it('errors when a requested driver is not found [callback]', function(done) {
|
60 | localforage.getDriver('UnknownDriver', null, function(error) {
|
61 | expect(error).to.be.an(Error);
|
62 | expect(error.message).to
|
63 | .be('Driver not found.');
|
64 | done();
|
65 | });
|
66 | });
|
67 |
|
68 | it('errors when a requested driver is not found [promise]', function(done) {
|
69 | localforage.getDriver('UnknownDriver').then(null, function(error) {
|
70 | expect(error).to.be.an(Error);
|
71 | expect(error.message).to
|
72 | .be('Driver not found.');
|
73 | done();
|
74 | });
|
75 | });
|
76 |
|
77 | it('retrieves the serializer [callback]', function(done) {
|
78 | localforage.getSerializer(function(serializer) {
|
79 | expect(serializer).to.be.an('object');
|
80 | done();
|
81 | });
|
82 | });
|
83 |
|
84 | it('retrieves the serializer [promise]', function(done) {
|
85 | var serializerPromise = localforage.getSerializer();
|
86 | expect(serializerPromise).to.be.an('object');
|
87 | expect(serializerPromise.then).to.be.a('function');
|
88 |
|
89 | serializerPromise.then(function(serializer) {
|
90 | expect(serializer).to.be.an('object');
|
91 | done();
|
92 | });
|
93 | });
|
94 |
|
95 | it('does not support object parameter to setDriver', function(done) {
|
96 | var driverPreferedOrder = {
|
97 | '0': localforage.INDEXEDDB,
|
98 | '1': localforage.WEBSQL,
|
99 | '2': localforage.LOCALSTORAGE,
|
100 | length: 3
|
101 | };
|
102 |
|
103 | localforage.setDriver(driverPreferedOrder).then(null, function(error) {
|
104 | expect(error).to.be.an(Error);
|
105 | expect(error.message).to
|
106 | .be('No available storage method found.');
|
107 | done();
|
108 | });
|
109 | });
|
110 |
|
111 | it('skips drivers that fail to initilize', function(done) {
|
112 | var failingStorageDriver = (function() {
|
113 | function driverDummyMethod() {
|
114 | return Promise.reject(new Error('Driver Method Failed.'));
|
115 | }
|
116 |
|
117 | return {
|
118 | _driver: 'failingStorageDriver',
|
119 | _initStorage: function _initStorage() {
|
120 | return Promise.reject(new Error('Driver Failed to Initialize.'));
|
121 | },
|
122 | iterate: driverDummyMethod,
|
123 | getItem: driverDummyMethod,
|
124 | setItem: driverDummyMethod,
|
125 | removeItem: driverDummyMethod,
|
126 | clear: driverDummyMethod,
|
127 | length: driverDummyMethod,
|
128 | key: driverDummyMethod,
|
129 | keys: driverDummyMethod
|
130 | };
|
131 | })();
|
132 |
|
133 | var driverPreferedOrder = [
|
134 | failingStorageDriver._driver,
|
135 | localforage.INDEXEDDB,
|
136 | localforage.WEBSQL,
|
137 | localforage.LOCALSTORAGE
|
138 | ];
|
139 |
|
140 | localforage.defineDriver(failingStorageDriver).then(function() {
|
141 | return localforage.setDriver(driverPreferedOrder);
|
142 | }).then(function() {
|
143 | return localforage.ready();
|
144 | }).then(function() {
|
145 | expect(localforage.driver()).to.be(appropriateDriver);
|
146 | done();
|
147 | });
|
148 |
|
149 | });
|
150 |
|
151 | describe('createInstance()', function() {
|
152 | var oldConsoleInfo;
|
153 |
|
154 | before(function() {
|
155 | oldConsoleInfo = console.info;
|
156 | var logs = [];
|
157 | console.info = function() {
|
158 | console.info.logs.push({
|
159 | args: arguments
|
160 | });
|
161 | oldConsoleInfo.apply(this, arguments);
|
162 | };
|
163 | console.info.logs = logs;
|
164 | });
|
165 |
|
166 | after(function() {
|
167 | console.info = oldConsoleInfo;
|
168 | });
|
169 |
|
170 | it('does not log unnecessary messages', function() {
|
171 | var oldLogCount = console.info.logs.length;
|
172 | var localforage2 = localforage.createInstance();
|
173 | var localforage3 = localforage.createInstance();
|
174 |
|
175 | return Promise.all([
|
176 | localforage.ready(),
|
177 | localforage2.ready(),
|
178 | localforage3.ready()
|
179 | ]).then(function() {
|
180 | expect(console.info.logs.length).to.be(oldLogCount);
|
181 | });
|
182 | });
|
183 | });
|
184 |
|
185 | });
|
186 |
|
187 | SUPPORTED_DRIVERS.forEach(function(driverName) {
|
188 | describe(driverName + ' driver', function() {
|
189 | 'use strict';
|
190 |
|
191 | this.timeout(30000);
|
192 |
|
193 | before(function(done) {
|
194 | localforage.setDriver(driverName).then(done);
|
195 | });
|
196 |
|
197 | beforeEach(function(done) {
|
198 | localStorage.clear();
|
199 | localforage.ready().then(function() {
|
200 | localforage.clear(done);
|
201 | });
|
202 | });
|
203 |
|
204 | it('has a localStorage API', function() {
|
205 | expect(localforage.getItem).to.be.a('function');
|
206 | expect(localforage.setItem).to.be.a('function');
|
207 | expect(localforage.clear).to.be.a('function');
|
208 | expect(localforage.length).to.be.a('function');
|
209 | expect(localforage.removeItem).to.be.a('function');
|
210 | expect(localforage.key).to.be.a('function');
|
211 | });
|
212 |
|
213 | it('has the localForage API', function() {
|
214 | expect(localforage._initStorage).to.be.a('function');
|
215 | expect(localforage.config).to.be.a('function');
|
216 | expect(localforage.defineDriver).to.be.a('function');
|
217 | expect(localforage.driver).to.be.a('function');
|
218 | expect(localforage.supports).to.be.a('function');
|
219 | expect(localforage.iterate).to.be.a('function');
|
220 | expect(localforage.getItem).to.be.a('function');
|
221 | expect(localforage.setItem).to.be.a('function');
|
222 | expect(localforage.clear).to.be.a('function');
|
223 | expect(localforage.length).to.be.a('function');
|
224 | expect(localforage.removeItem).to.be.a('function');
|
225 | expect(localforage.key).to.be.a('function');
|
226 | expect(localforage.getDriver).to.be.a('function');
|
227 | expect(localforage.setDriver).to.be.a('function');
|
228 | expect(localforage.ready).to.be.a('function');
|
229 | expect(localforage.createInstance).to.be.a('function');
|
230 | expect(localforage.getSerializer).to.be.a('function');
|
231 | expect(localforage.dropInstance).to.be.a('function');
|
232 | });
|
233 |
|
234 |
|
235 | it('supports ' + driverName + ' database driver', function() {
|
236 | expect(localforage.supports(driverName) === true);
|
237 | expect(localforage.supports('I am not a driver') === false);
|
238 | });
|
239 |
|
240 | it('sets the right database driver', function() {
|
241 | expect(localforage.driver() === driverName);
|
242 | });
|
243 |
|
244 | it('has an empty length by default', function(done) {
|
245 | localforage.length(function(err, length) {
|
246 | expect(length).to.be(0);
|
247 | done();
|
248 | });
|
249 | });
|
250 |
|
251 | if (driverName === localforage.INDEXEDDB) {
|
252 | describe('Blob support', function() {
|
253 | var transaction;
|
254 | var called;
|
255 | var db;
|
256 | var blob = new Blob([''], {type: 'image/png'});
|
257 |
|
258 | before(function() {
|
259 | db = localforage._dbInfo.db;
|
260 | transaction = db.transaction;
|
261 | db.transaction = function() {
|
262 | called += 1;
|
263 | return transaction.apply(db, arguments);
|
264 | };
|
265 | });
|
266 |
|
267 | beforeEach(function() {
|
268 | called = 0;
|
269 | });
|
270 |
|
271 | it('not check for non Blob', function(done) {
|
272 | localforage.setItem('key', {}).then(function() {
|
273 | expect(called).to.be(1);
|
274 | done();
|
275 | }, function(error) {
|
276 | done(error || 'error');
|
277 | });
|
278 | });
|
279 |
|
280 | it('check for Blob', function(done) {
|
281 | localforage.setItem('key', blob).then(function() {
|
282 | expect(called).to.be.above(1);
|
283 | done();
|
284 | }, function(error) {
|
285 | done(error || 'error');
|
286 | });
|
287 | });
|
288 |
|
289 | it('check for Blob once', function(done) {
|
290 | localforage.setItem('key', blob).then(function() {
|
291 | expect(called).to.be(1);
|
292 | done();
|
293 | }, function(error) {
|
294 | done(error || 'error');
|
295 | });
|
296 | });
|
297 |
|
298 | after(function() {
|
299 | localforage._dbInfo.db.transaction = transaction;
|
300 | });
|
301 | });
|
302 |
|
303 | describe('recover (reconnect) from IDBDatabase InvalidStateError', function() {
|
304 |
|
305 | beforeEach(function(done) {
|
306 | Promise.all([
|
307 | localforage.setItem('key', 'value1'),
|
308 | localforage.setItem('key1', 'value1'),
|
309 | localforage.setItem('key2', 'value2'),
|
310 | localforage.setItem('key3', 'value3')
|
311 | ]).then(function() {
|
312 | localforage._dbInfo.db.close();
|
313 | done();
|
314 | }, function(error) {
|
315 | done(error || 'error');
|
316 | });
|
317 | });
|
318 |
|
319 | it('retrieves an item from the storage', function(done) {
|
320 | localforage.getItem('key').then(function(value) {
|
321 | expect(value).to.be('value1');
|
322 | done();
|
323 | }, function(error) {
|
324 | done(error || 'error');
|
325 | });
|
326 | });
|
327 |
|
328 | it('retrieves more than one items from the storage', function(done) {
|
329 | Promise.all([
|
330 | localforage.getItem('key1'),
|
331 | localforage.getItem('key2'),
|
332 | localforage.getItem('key3')
|
333 | ]).then(function(values) {
|
334 | expect(values).to.eql([
|
335 | 'value1',
|
336 | 'value2',
|
337 | 'value3'
|
338 | ]);
|
339 | done();
|
340 | }, function(error) {
|
341 | done(error || 'error');
|
342 | });
|
343 | });
|
344 |
|
345 | it('stores and retrieves an item from the storage', function(done) {
|
346 | localforage.setItem('key', 'value1b').then(function() {
|
347 | return localforage.getItem('key');
|
348 | }).then(function(value) {
|
349 | expect(value).to.be('value1b');
|
350 | done();
|
351 | }, function(error) {
|
352 | done(error || 'error');
|
353 | });
|
354 | });
|
355 |
|
356 | it('stores and retrieves more than one items from the storage', function(done) {
|
357 | Promise.all([
|
358 | localforage.setItem('key1', 'value1b'),
|
359 | localforage.setItem('key2', 'value2b'),
|
360 | localforage.setItem('key3', 'value3b')
|
361 | ]).then(function() {
|
362 | return Promise.all([
|
363 | localforage.getItem('key1'),
|
364 | localforage.getItem('key2'),
|
365 | localforage.getItem('key3')
|
366 | ]);
|
367 | }).then(function(values) {
|
368 | expect(values).to.eql([
|
369 | 'value1b',
|
370 | 'value2b',
|
371 | 'value3b'
|
372 | ]);
|
373 | done();
|
374 | }, function(error) {
|
375 | done(error || 'error');
|
376 | });
|
377 | });
|
378 | });
|
379 | }
|
380 |
|
381 | if (driverName === localforage.WEBSQL) {
|
382 | describe('on QUOTA ERROR', function() {
|
383 | var transaction;
|
384 | var called;
|
385 | var db;
|
386 |
|
387 | function getQuotaErrorCode(transaction) {
|
388 | return new Promise(function(resolve) {
|
389 | transaction(function(t) {
|
390 | t.executeSql('');
|
391 | }, function(err) {
|
392 | resolve(err.QUOTA_ERR);
|
393 | });
|
394 | }).catch(function(err) {
|
395 | return err.QUOTA_ERR;
|
396 | });
|
397 | }
|
398 |
|
399 | beforeEach(function() {
|
400 | called = 0;
|
401 | db = localforage._dbInfo.db;
|
402 | transaction = db.transaction;
|
403 |
|
404 | db.transaction = function(fn, errFn) {
|
405 | called += 1;
|
406 |
|
407 |
|
408 | db.transaction = transaction;
|
409 |
|
410 | getQuotaErrorCode(transaction).then(function(QUOTA_ERR) {
|
411 | var error = new Error();
|
412 | error.code = QUOTA_ERR;
|
413 | errFn(error);
|
414 | });
|
415 | };
|
416 | });
|
417 |
|
418 | it('should retry setItem', function(done) {
|
419 | localforage.setItem('key', {}).then(function() {
|
420 | expect(called).to.be(1);
|
421 | done();
|
422 | }, function(error) {
|
423 | done(error || 'error');
|
424 | });
|
425 | });
|
426 |
|
427 | after(function() {
|
428 | db.transaction = transaction || db.transaction;
|
429 | });
|
430 | });
|
431 | }
|
432 |
|
433 | it('should iterate [callback]', function(done) {
|
434 | localforage.setItem('officeX', 'InitechX', function(err, setValue) {
|
435 | expect(setValue).to.be('InitechX');
|
436 |
|
437 | localforage.getItem('officeX', function(err, value) {
|
438 | expect(value).to.be(setValue);
|
439 |
|
440 | localforage.setItem('officeY', 'InitechY', function(err, setValue) {
|
441 | expect(setValue).to.be('InitechY');
|
442 |
|
443 | localforage.getItem('officeY', function(err, value) {
|
444 | expect(value).to.be(setValue);
|
445 |
|
446 | var accumulator = {};
|
447 | var iterationNumbers = [];
|
448 |
|
449 | localforage.iterate(function(value, key, iterationNumber) {
|
450 | accumulator[key] = value;
|
451 | iterationNumbers.push(iterationNumber);
|
452 | }, function() {
|
453 | try {
|
454 | expect(accumulator.officeX).to.be('InitechX');
|
455 | expect(accumulator.officeY).to.be('InitechY');
|
456 | expect(iterationNumbers).to.eql([1, 2]);
|
457 | done();
|
458 | } catch (e) {
|
459 | done(e);
|
460 | }
|
461 | });
|
462 | });
|
463 | });
|
464 | });
|
465 | });
|
466 | });
|
467 |
|
468 | it('should iterate [promise]', function(done) {
|
469 | var accumulator = {};
|
470 | var iterationNumbers = [];
|
471 |
|
472 | return localforage.setItem('officeX',
|
473 | 'InitechX').then(function(setValue) {
|
474 | expect(setValue).to.be('InitechX');
|
475 | return localforage.getItem('officeX');
|
476 | }).then(function(value) {
|
477 | expect(value).to.be('InitechX');
|
478 | return localforage.setItem('officeY', 'InitechY');
|
479 | }).then(function(setValue) {
|
480 | expect(setValue).to.be('InitechY');
|
481 | return localforage.getItem('officeY');
|
482 | }).then(function(value) {
|
483 | expect(value).to.be('InitechY');
|
484 |
|
485 | return localforage.iterate(function(value, key,
|
486 | iterationNumber) {
|
487 | accumulator[key] = value;
|
488 | iterationNumbers.push(iterationNumber);
|
489 | });
|
490 | }).then(function() {
|
491 | expect(accumulator.officeX).to.be('InitechX');
|
492 | expect(accumulator.officeY).to.be('InitechY');
|
493 | expect(iterationNumbers).to.eql([1, 2]);
|
494 | done();
|
495 | });
|
496 | });
|
497 |
|
498 | it('should break iteration with defined return value [callback]', function(done) {
|
499 | var breakCondition = 'Some value!';
|
500 |
|
501 | localforage.setItem('officeX', 'InitechX', function(err, setValue) {
|
502 | expect(setValue).to.be('InitechX');
|
503 |
|
504 | localforage.getItem('officeX', function(err, value) {
|
505 | expect(value).to.be(setValue);
|
506 |
|
507 | localforage.setItem('officeY', 'InitechY', function(err, setValue) {
|
508 | expect(setValue).to.be('InitechY');
|
509 |
|
510 | localforage.getItem('officeY', function(err, value) {
|
511 | expect(value).to.be(setValue);
|
512 |
|
513 |
|
514 | localforage.iterate(function() {
|
515 |
|
516 | return breakCondition;
|
517 | }, function(err, loopResult) {
|
518 |
|
519 |
|
520 | expect(loopResult).to.be(breakCondition);
|
521 |
|
522 | done();
|
523 | });
|
524 | });
|
525 | });
|
526 | });
|
527 | });
|
528 | });
|
529 |
|
530 | it('should break iteration with defined return value [promise]', function(done) {
|
531 | var breakCondition = 'Some value!';
|
532 |
|
533 | localforage.setItem('officeX', 'InitechX').then(function(setValue) {
|
534 | expect(setValue).to.be('InitechX');
|
535 | return localforage.getItem('officeX');
|
536 | }).then(function(value) {
|
537 | expect(value).to.be('InitechX');
|
538 | return localforage.setItem('officeY', 'InitechY');
|
539 | }).then(function(setValue) {
|
540 | expect(setValue).to.be('InitechY');
|
541 | return localforage.getItem('officeY');
|
542 | }).then(function(value) {
|
543 | expect(value).to.be('InitechY');
|
544 | return localforage.iterate(function() {
|
545 | return breakCondition;
|
546 | });
|
547 | }).then(function(result) {
|
548 | expect(result).to.be(breakCondition);
|
549 | done();
|
550 | });
|
551 | });
|
552 |
|
553 | it('should iterate() through only its own keys/values', function(done) {
|
554 | localStorage.setItem('local', 'forage');
|
555 | localforage.setItem('office', 'Initech').then(function() {
|
556 | return localforage.setItem('name', 'Bob');
|
557 | }).then(function() {
|
558 |
|
559 |
|
560 | var numberOfItems = 0;
|
561 | var iterationNumberConcat = '';
|
562 |
|
563 | localStorage.setItem('locals', 'forages');
|
564 |
|
565 | localforage.iterate(function(value, key, iterationNumber) {
|
566 | expect(key).to.not.be('local');
|
567 | expect(value).to.not.be('forage');
|
568 | numberOfItems++;
|
569 | iterationNumberConcat += iterationNumber;
|
570 | }, function(err) {
|
571 | if (!err) {
|
572 |
|
573 |
|
574 | expect(numberOfItems).to.be(2);
|
575 |
|
576 |
|
577 |
|
578 | expect(iterationNumberConcat).to.be('12');
|
579 |
|
580 | done();
|
581 | }
|
582 | });
|
583 | });
|
584 | });
|
585 |
|
586 |
|
587 | it('nested getItem inside clear works [callback]', function(done) {
|
588 | localforage.setItem('hello', 'Hello World !', function() {
|
589 | localforage.clear(function() {
|
590 | localforage.getItem('hello', function(secondValue) {
|
591 | expect(secondValue).to.be(null);
|
592 | done();
|
593 | });
|
594 | });
|
595 | });
|
596 | });
|
597 | it('nested getItem inside clear works [promise]', function(done) {
|
598 | localforage.setItem('hello', 'Hello World !').then(function() {
|
599 | return localforage.clear();
|
600 | }).then(function() {
|
601 | return localforage.getItem('hello');
|
602 | }).then(function(secondValue) {
|
603 | expect(secondValue).to.be(null);
|
604 | done();
|
605 | });
|
606 | });
|
607 |
|
608 |
|
609 |
|
610 |
|
611 |
|
612 | it('returns null for undefined key [callback]', function(done) {
|
613 | localforage.getItem('key', function(err, value) {
|
614 | expect(value).to.be(null);
|
615 | done();
|
616 | });
|
617 | });
|
618 |
|
619 | it('returns null for undefined key [promise]', function(done) {
|
620 | localforage.getItem('key').then(function(value) {
|
621 | expect(value).to.be(null);
|
622 | done();
|
623 | });
|
624 | });
|
625 |
|
626 | it('saves an item [callback]', function(done) {
|
627 | localforage.setItem('office', 'Initech', function(err, setValue) {
|
628 | expect(setValue).to.be('Initech');
|
629 |
|
630 | localforage.getItem('office', function(err, value) {
|
631 | expect(value).to.be(setValue);
|
632 | done();
|
633 | });
|
634 | });
|
635 | });
|
636 |
|
637 | it('saves an item [promise]', function(done) {
|
638 | localforage.setItem('office', 'Initech').then(function(setValue) {
|
639 | expect(setValue).to.be('Initech');
|
640 |
|
641 | return localforage.getItem('office');
|
642 | }).then(function(value) {
|
643 | expect(value).to.be('Initech');
|
644 | done();
|
645 | });
|
646 | });
|
647 |
|
648 | it('saves an item over an existing key [callback]', function(done) {
|
649 | localforage.setItem('4th floor', 'Mozilla', function(err, setValue) {
|
650 | expect(setValue).to.be('Mozilla');
|
651 |
|
652 | localforage.setItem('4th floor', 'Quora', function(err, newValue) {
|
653 | expect(newValue).to.not.be(setValue);
|
654 | expect(newValue).to.be('Quora');
|
655 |
|
656 | localforage.getItem('4th floor', function(err, value) {
|
657 | expect(value).to.not.be(setValue);
|
658 | expect(value).to.be(newValue);
|
659 | done();
|
660 | });
|
661 | });
|
662 | });
|
663 | });
|
664 | it('saves an item over an existing key [promise]', function(done) {
|
665 | localforage.setItem('4e', 'Mozilla').then(function(setValue) {
|
666 | expect(setValue).to.be('Mozilla');
|
667 |
|
668 | return localforage.setItem('4e', 'Quora');
|
669 | }).then(function(newValue) {
|
670 | expect(newValue).to.not.be('Mozilla');
|
671 | expect(newValue).to.be('Quora');
|
672 |
|
673 | return localforage.getItem('4e');
|
674 | }).then(function(value) {
|
675 | expect(value).to.not.be('Mozilla');
|
676 | expect(value).to.be('Quora');
|
677 | done();
|
678 | });
|
679 | });
|
680 |
|
681 | it('returns null when saving undefined [callback]', function(done) {
|
682 | localforage.setItem('undef', undefined, function(err, setValue) {
|
683 | expect(setValue).to.be(null);
|
684 |
|
685 | done();
|
686 | });
|
687 | });
|
688 | it('returns null when saving undefined [promise]', function(done) {
|
689 | localforage.setItem('undef', undefined).then(function(setValue) {
|
690 | expect(setValue).to.be(null);
|
691 |
|
692 | done();
|
693 | });
|
694 | });
|
695 |
|
696 | it('returns null when saving null [callback]', function(done) {
|
697 | localforage.setItem('null', null, function(err, setValue) {
|
698 | expect(setValue).to.be(null);
|
699 |
|
700 | done();
|
701 | });
|
702 | });
|
703 | it('returns null when saving null [promise]', function(done) {
|
704 | localforage.setItem('null', null).then(function(setValue) {
|
705 | expect(setValue).to.be(null);
|
706 |
|
707 | done();
|
708 | });
|
709 | });
|
710 |
|
711 | it('returns null for a non-existant key [callback]', function(done) {
|
712 | localforage.getItem('undef', function(err, value) {
|
713 | expect(value).to.be(null);
|
714 |
|
715 | done();
|
716 | });
|
717 | });
|
718 | it('returns null for a non-existant key [promise]', function(done) {
|
719 | localforage.getItem('undef').then(function(value) {
|
720 | expect(value).to.be(null);
|
721 |
|
722 | done();
|
723 | });
|
724 | });
|
725 |
|
726 |
|
727 |
|
728 |
|
729 |
|
730 |
|
731 |
|
732 |
|
733 |
|
734 |
|
735 |
|
736 | it('returns null from an undefined key [callback]', function(done) {
|
737 | localforage.key(0, function(err, key) {
|
738 | expect(key).to.be(null);
|
739 |
|
740 | done();
|
741 | });
|
742 | });
|
743 | it('returns null from an undefined key [promise]', function(done) {
|
744 | localforage.key(0).then(function(key) {
|
745 | expect(key).to.be(null);
|
746 |
|
747 | done();
|
748 | });
|
749 | });
|
750 |
|
751 | it('returns key name [callback]', function(done) {
|
752 | localforage.setItem('office', 'Initech').then(function() {
|
753 | localforage.key(0, function(err, key) {
|
754 | expect(key).to.be('office');
|
755 |
|
756 | done();
|
757 | });
|
758 | });
|
759 | });
|
760 | it('returns key name [promise]', function(done) {
|
761 | localforage.setItem('office', 'Initech').then(function() {
|
762 | return localforage.key(0);
|
763 | }).then(function(key) {
|
764 | expect(key).to.be('office');
|
765 |
|
766 | done();
|
767 | });
|
768 | });
|
769 |
|
770 | it('removes an item [callback]', function(done) {
|
771 | localforage.setItem('office', 'Initech', function() {
|
772 | localforage.setItem('otherOffice', 'Initrode', function() {
|
773 | localforage.removeItem('office', function() {
|
774 | localforage.getItem('office', function(err, emptyValue) {
|
775 | expect(emptyValue).to.be(null);
|
776 |
|
777 | localforage.getItem('otherOffice', function(err, value) {
|
778 | expect(value).to.be('Initrode');
|
779 |
|
780 | done();
|
781 | });
|
782 | });
|
783 | });
|
784 | });
|
785 | });
|
786 | });
|
787 | it('removes an item [promise]', function(done) {
|
788 | localforage.setItem('office', 'Initech').then(function() {
|
789 | return localforage.setItem('otherOffice', 'Initrode');
|
790 | }).then(function() {
|
791 | return localforage.removeItem('office');
|
792 | }).then(function() {
|
793 | return localforage.getItem('office');
|
794 | }).then(function(emptyValue) {
|
795 | expect(emptyValue).to.be(null);
|
796 |
|
797 | return localforage.getItem('otherOffice');
|
798 | }).then(function(value) {
|
799 | expect(value).to.be('Initrode');
|
800 |
|
801 | done();
|
802 | });
|
803 | });
|
804 |
|
805 | it('removes all items [callback]', function(done) {
|
806 | localforage.setItem('office', 'Initech', function() {
|
807 | localforage.setItem('otherOffice', 'Initrode', function() {
|
808 | localforage.length(function(err, length) {
|
809 | expect(length).to.be(2);
|
810 |
|
811 | localforage.clear(function() {
|
812 | localforage.getItem('office', function(err, value) {
|
813 | expect(value).to.be(null);
|
814 |
|
815 | localforage.length(function(err, length) {
|
816 | expect(length).to.be(0);
|
817 |
|
818 | done();
|
819 | });
|
820 | });
|
821 | });
|
822 | });
|
823 | });
|
824 | });
|
825 | });
|
826 | it('removes all items [promise]', function(done) {
|
827 | localforage.setItem('office', 'Initech').then(function() {
|
828 | return localforage.setItem('otherOffice', 'Initrode');
|
829 | }).then(function() {
|
830 | return localforage.length();
|
831 | }).then(function(length) {
|
832 | expect(length).to.be(2);
|
833 |
|
834 | return localforage.clear();
|
835 | }).then(function() {
|
836 | return localforage.getItem('office');
|
837 | }).then(function(value) {
|
838 | expect(value).to.be(null);
|
839 |
|
840 | return localforage.length();
|
841 | }).then(function(length) {
|
842 | expect(length).to.be(0);
|
843 |
|
844 | done();
|
845 | });
|
846 | });
|
847 |
|
848 | if (driverName === localforage.LOCALSTORAGE) {
|
849 | it('removes only own items upon clear', function(done) {
|
850 | localStorage.setItem('local', 'forage');
|
851 |
|
852 | localforage.setItem('office', 'Initech').then(function() {
|
853 | return localforage.clear();
|
854 | }).then(function() {
|
855 | expect(localStorage.getItem('local')).to.be('forage');
|
856 |
|
857 | localStorage.clear();
|
858 |
|
859 | done();
|
860 | });
|
861 | });
|
862 |
|
863 | it('returns only its own keys from keys()', function(done) {
|
864 | localStorage.setItem('local', 'forage');
|
865 |
|
866 | localforage.setItem('office', 'Initech').then(function() {
|
867 | return localforage.keys();
|
868 | }).then(function(keys) {
|
869 | expect(keys).to.eql(['office']);
|
870 |
|
871 | localStorage.clear();
|
872 |
|
873 | done();
|
874 | });
|
875 | });
|
876 |
|
877 | it('counts only its own items with length()', function(done) {
|
878 | localStorage.setItem('local', 'forage');
|
879 | localStorage.setItem('another', 'value');
|
880 |
|
881 | localforage.setItem('office', 'Initech').then(function() {
|
882 | return localforage.length();
|
883 | }).then(function(length) {
|
884 | expect(length).to.be(1);
|
885 |
|
886 | localStorage.clear();
|
887 |
|
888 | done();
|
889 | });
|
890 | });
|
891 | }
|
892 |
|
893 | it('has a length after saving an item [callback]', function(done) {
|
894 | localforage.length(function(err, length) {
|
895 | expect(length).to.be(0);
|
896 | localforage.setItem('rapper', 'Black Thought', function() {
|
897 | localforage.length(function(err, length) {
|
898 | expect(length).to.be(1);
|
899 |
|
900 | done();
|
901 | });
|
902 | });
|
903 | });
|
904 | });
|
905 | it('has a length after saving an item [promise]', function(done) {
|
906 | localforage.length().then(function(length) {
|
907 | expect(length).to.be(0);
|
908 |
|
909 | return localforage.setItem('lame rapper', 'Vanilla Ice');
|
910 | }).then(function() {
|
911 | return localforage.length();
|
912 | }).then(function(length) {
|
913 | expect(length).to.be(1);
|
914 |
|
915 | done();
|
916 | });
|
917 | });
|
918 |
|
919 |
|
920 |
|
921 | it('casts an undefined key to a String', function(done) {
|
922 | localforage.setItem(undefined, 'goodness!').then(function(value) {
|
923 | expect(value).to.be('goodness!');
|
924 |
|
925 | return localforage.getItem(undefined);
|
926 | }).then(function(value) {
|
927 | expect(value).to.be('goodness!');
|
928 |
|
929 | return localforage.removeItem(undefined);
|
930 | }).then(function() {
|
931 | return localforage.length();
|
932 | }).then(function(length) {
|
933 | expect(length).to.be(0);
|
934 | done();
|
935 | });
|
936 | });
|
937 |
|
938 | it('casts a null key to a String', function(done) {
|
939 | localforage.setItem(null, 'goodness!').then(function(value) {
|
940 | expect(value).to.be('goodness!');
|
941 |
|
942 | return localforage.getItem(null);
|
943 | }).then(function(value) {
|
944 | expect(value).to.be('goodness!');
|
945 |
|
946 | return localforage.removeItem(null);
|
947 | }).then(function() {
|
948 | return localforage.length();
|
949 | }).then(function(length) {
|
950 | expect(length).to.be(0);
|
951 | done();
|
952 | });
|
953 | });
|
954 |
|
955 | it('casts a float key to a String', function(done) {
|
956 | localforage.setItem(537.35737, 'goodness!').then(function(value) {
|
957 | expect(value).to.be('goodness!');
|
958 |
|
959 | return localforage.getItem(537.35737);
|
960 | }).then(function(value) {
|
961 | expect(value).to.be('goodness!');
|
962 |
|
963 | return localforage.removeItem(537.35737);
|
964 | }).then(function() {
|
965 | return localforage.length();
|
966 | }).then(function(length) {
|
967 | expect(length).to.be(0);
|
968 | done();
|
969 | });
|
970 | });
|
971 |
|
972 | it('is retrieved by getDriver [callback]', function(done) {
|
973 | localforage.getDriver(driverName, function(driver) {
|
974 | expect(typeof driver).to.be('object');
|
975 | driverApiMethods.concat('_initStorage').forEach(function(methodName) {
|
976 | expect(typeof driver[methodName]).to.be('function');
|
977 | });
|
978 | expect(driver._driver).to.be(driverName);
|
979 | done();
|
980 | });
|
981 | });
|
982 |
|
983 | it('is retrieved by getDriver [promise]', function(done) {
|
984 | localforage.getDriver(driverName).then(function(driver) {
|
985 | expect(typeof driver).to.be('object');
|
986 | driverApiMethods.concat('_initStorage').forEach(function(methodName) {
|
987 | expect(typeof driver[methodName]).to.be('function');
|
988 | });
|
989 | expect(driver._driver).to.be(driverName);
|
990 | done();
|
991 | });
|
992 | });
|
993 |
|
994 | if (driverName === localforage.WEBSQL ||
|
995 | driverName === localforage.LOCALSTORAGE) {
|
996 | it('exposes the serializer on the dbInfo object', function(done) {
|
997 | localforage.ready().then(function() {
|
998 | expect(localforage._dbInfo.serializer).to.be.an('object');
|
999 | done();
|
1000 | });
|
1001 | });
|
1002 | }
|
1003 | });
|
1004 |
|
1005 | function prepareStorage(storageName) {
|
1006 |
|
1007 |
|
1008 | if (driverName === localforage.INDEXEDDB) {
|
1009 | return new Promise(function(resolve) {
|
1010 | indexedDB.deleteDatabase(storageName).onsuccess = resolve;
|
1011 | });
|
1012 | }
|
1013 |
|
1014 |
|
1015 | return Promise.resolve();
|
1016 | }
|
1017 |
|
1018 | describe(driverName + ' driver multiple instances', function() {
|
1019 | 'use strict';
|
1020 |
|
1021 | this.timeout(30000);
|
1022 |
|
1023 | var localforage2 = null;
|
1024 | var localforage3 = null;
|
1025 |
|
1026 | before(function(done) {
|
1027 |
|
1028 | prepareStorage('storage2').then(function() {
|
1029 | localforage2 = localforage.createInstance({
|
1030 | name: 'storage2',
|
1031 |
|
1032 |
|
1033 |
|
1034 |
|
1035 | size: 1024,
|
1036 | storeName: 'storagename2'
|
1037 | });
|
1038 |
|
1039 |
|
1040 |
|
1041 | localforage3 = localforage.createInstance({
|
1042 | name: 'storage2',
|
1043 |
|
1044 |
|
1045 |
|
1046 |
|
1047 | size: 1024,
|
1048 | storeName: 'storagename3'
|
1049 | });
|
1050 |
|
1051 | Promise.all([
|
1052 | localforage.setDriver(driverName),
|
1053 | localforage2.setDriver(driverName),
|
1054 | localforage3.setDriver(driverName)
|
1055 | ]).then(function() {
|
1056 | done();
|
1057 | });
|
1058 | });
|
1059 | });
|
1060 |
|
1061 | beforeEach(function(done) {
|
1062 | Promise.all([
|
1063 | localforage.clear(),
|
1064 | localforage2.clear(),
|
1065 | localforage3.clear()
|
1066 | ]).then(function() {
|
1067 | done();
|
1068 | });
|
1069 | });
|
1070 |
|
1071 | it('is not be able to access values of other instances', function(done) {
|
1072 | Promise.all([
|
1073 | localforage.setItem('key1', 'value1a'),
|
1074 | localforage2.setItem('key2', 'value2a'),
|
1075 | localforage3.setItem('key3', 'value3a')
|
1076 | ]).then(function() {
|
1077 | return Promise.all([
|
1078 | localforage.getItem('key2').then(function(value) {
|
1079 | expect(value).to.be(null);
|
1080 | }),
|
1081 | localforage2.getItem('key1').then(function(value) {
|
1082 | expect(value).to.be(null);
|
1083 | }),
|
1084 | localforage2.getItem('key3').then(function(value) {
|
1085 | expect(value).to.be(null);
|
1086 | }),
|
1087 | localforage3.getItem('key2').then(function(value) {
|
1088 | expect(value).to.be(null);
|
1089 | })
|
1090 | ]);
|
1091 | }).then(function() {
|
1092 | done();
|
1093 | }, function(errors) {
|
1094 | done(new Error(errors));
|
1095 | });
|
1096 | });
|
1097 |
|
1098 | it('retrieves the proper value when using the same key with other instances', function(done) {
|
1099 | Promise.all([
|
1100 | localforage.setItem('key', 'value1'),
|
1101 | localforage2.setItem('key', 'value2'),
|
1102 | localforage3.setItem('key', 'value3')
|
1103 | ]).then(function() {
|
1104 | return Promise.all([
|
1105 | localforage.getItem('key').then(function(value) {
|
1106 | expect(value).to.be('value1');
|
1107 | }),
|
1108 | localforage2.getItem('key').then(function(value) {
|
1109 | expect(value).to.be('value2');
|
1110 | }),
|
1111 | localforage3.getItem('key').then(function(value) {
|
1112 | expect(value).to.be('value3');
|
1113 | })
|
1114 | ]);
|
1115 | }).then(function() {
|
1116 | done();
|
1117 | }, function(errors) {
|
1118 | done(new Error(errors));
|
1119 | });
|
1120 | });
|
1121 | });
|
1122 |
|
1123 |
|
1124 | describe(driverName + ' driver multiple instances (concurrent on same database)', function() {
|
1125 |
|
1126 | 'use strict';
|
1127 |
|
1128 | this.timeout(30000);
|
1129 |
|
1130 | before(function() {
|
1131 | return Promise.all([
|
1132 | prepareStorage('storage3'),
|
1133 | prepareStorage('commonStorage'),
|
1134 | prepareStorage('commonStorage2'),
|
1135 | prepareStorage('commonStorage3')
|
1136 | ]);
|
1137 | });
|
1138 |
|
1139 | it('chains operation on multiple stores', function() {
|
1140 | var localforage1 = localforage.createInstance({
|
1141 | name: 'storage3',
|
1142 | storeName: 'store1',
|
1143 | size: 1024
|
1144 | });
|
1145 |
|
1146 | var localforage2 = localforage.createInstance({
|
1147 | name: 'storage3',
|
1148 | storeName: 'store2',
|
1149 | size: 1024
|
1150 | });
|
1151 |
|
1152 | var localforage3 = localforage.createInstance({
|
1153 | name: 'storage3',
|
1154 | storeName: 'store3',
|
1155 | size: 1024
|
1156 | });
|
1157 |
|
1158 | var promise1 = localforage1.setItem('key', 'value1').then(function() {
|
1159 | return localforage1.getItem('key');
|
1160 | }).then(function(value) {
|
1161 | expect(value).to.be('value1');
|
1162 | });
|
1163 |
|
1164 | var promise2 = localforage2.setItem('key', 'value2').then(function() {
|
1165 | return localforage2.getItem('key');
|
1166 | }).then(function(value) {
|
1167 | expect(value).to.be('value2');
|
1168 | });
|
1169 |
|
1170 | var promise3 = localforage3.setItem('key', 'value3').then(function() {
|
1171 | return localforage3.getItem('key');
|
1172 | }).then(function(value) {
|
1173 | expect(value).to.be('value3');
|
1174 | });
|
1175 |
|
1176 | return Promise.all([
|
1177 | promise1,
|
1178 | promise2,
|
1179 | promise3
|
1180 | ]);
|
1181 | });
|
1182 |
|
1183 | it('can create multiple instances of the same store', function() {
|
1184 | var localforage1;
|
1185 | var localforage2;
|
1186 | var localforage3;
|
1187 |
|
1188 | Promise.resolve()
|
1189 | .then(function() {
|
1190 | localforage1 = localforage.createInstance({
|
1191 | name: 'commonStorage',
|
1192 | storeName: 'commonStore',
|
1193 | size: 1024
|
1194 | });
|
1195 | return localforage1.ready();
|
1196 | })
|
1197 | .then(function() {
|
1198 | localforage2 = localforage.createInstance({
|
1199 | name: 'commonStorage',
|
1200 | storeName: 'commonStore',
|
1201 | size: 1024
|
1202 | });
|
1203 | return localforage2.ready();
|
1204 | })
|
1205 | .then(function() {
|
1206 | localforage3 = localforage.createInstance({
|
1207 | name: 'commonStorage',
|
1208 | storeName: 'commonStore',
|
1209 | size: 1024
|
1210 | });
|
1211 | return localforage3.ready();
|
1212 | }).then(function() {
|
1213 | return Promise.resolve()
|
1214 | .then(function() {
|
1215 | return localforage1.setItem('key1', 'value1').then(function() {
|
1216 | return localforage1.getItem('key1');
|
1217 | }).then(function(value) {
|
1218 | expect(value).to.be('value1');
|
1219 | });
|
1220 | })
|
1221 | .then(function() {
|
1222 | return localforage2.setItem('key2', 'value2').then(function() {
|
1223 | return localforage2.getItem('key2');
|
1224 | }).then(function(value) {
|
1225 | expect(value).to.be('value2');
|
1226 | });
|
1227 | })
|
1228 | .then(function() {
|
1229 | return localforage3.setItem('key3', 'value3').then(function() {
|
1230 | return localforage3.getItem('key3');
|
1231 | }).then(function(value) {
|
1232 | expect(value).to.be('value3');
|
1233 | });
|
1234 | });
|
1235 | });
|
1236 | });
|
1237 |
|
1238 | it('can create multiple instances of the same store and do concurrent operations', function() {
|
1239 | var localforage1;
|
1240 | var localforage2;
|
1241 | var localforage3;
|
1242 | var localforage3b;
|
1243 |
|
1244 | Promise.resolve()
|
1245 | .then(function() {
|
1246 | localforage1 = localforage.createInstance({
|
1247 | name: 'commonStorage2',
|
1248 | storeName: 'commonStore',
|
1249 | size: 1024
|
1250 | });
|
1251 | return localforage1.ready();
|
1252 | })
|
1253 | .then(function() {
|
1254 | localforage2 = localforage.createInstance({
|
1255 | name: 'commonStorage2',
|
1256 | storeName: 'commonStore',
|
1257 | size: 1024
|
1258 | });
|
1259 | return localforage2.ready();
|
1260 | })
|
1261 | .then(function() {
|
1262 | localforage3 = localforage.createInstance({
|
1263 | name: 'commonStorage2',
|
1264 | storeName: 'commonStore',
|
1265 | size: 1024
|
1266 | });
|
1267 | return localforage3.ready();
|
1268 | })
|
1269 | .then(function() {
|
1270 | localforage3b = localforage.createInstance({
|
1271 | name: 'commonStorage2',
|
1272 | storeName: 'commonStore',
|
1273 | size: 1024
|
1274 | });
|
1275 | return localforage3b.ready();
|
1276 | }).then(function() {
|
1277 | var promise1 = localforage1.setItem('key1', 'value1').then(function() {
|
1278 | return localforage1.getItem('key1');
|
1279 | }).then(function(value) {
|
1280 | expect(value).to.be('value1');
|
1281 | });
|
1282 |
|
1283 | var promise2 = localforage2.setItem('key2', 'value2').then(function() {
|
1284 | return localforage2.getItem('key2');
|
1285 | }).then(function(value) {
|
1286 | expect(value).to.be('value2');
|
1287 | });
|
1288 |
|
1289 | var promise3 = localforage3.setItem('key3', 'value3').then(function() {
|
1290 | return localforage3.getItem('key3');
|
1291 | }).then(function(value) {
|
1292 | expect(value).to.be('value3');
|
1293 | });
|
1294 |
|
1295 | var promise4 = localforage3b.setItem('key3', 'value3').then(function() {
|
1296 | return localforage3.getItem('key3');
|
1297 | }).then(function(value) {
|
1298 | expect(value).to.be('value3');
|
1299 | });
|
1300 |
|
1301 | return Promise.all([
|
1302 | promise1,
|
1303 | promise2,
|
1304 | promise3,
|
1305 | promise4
|
1306 | ]);
|
1307 | });
|
1308 | });
|
1309 |
|
1310 | it('can create multiple instances of the same store concurrently', function() {
|
1311 | var localforage1 = localforage.createInstance({
|
1312 | name: 'commonStorage3',
|
1313 | storeName: 'commonStore',
|
1314 | size: 1024
|
1315 | });
|
1316 |
|
1317 | var localforage2 = localforage.createInstance({
|
1318 | name: 'commonStorage3',
|
1319 | storeName: 'commonStore',
|
1320 | size: 1024
|
1321 | });
|
1322 |
|
1323 | var localforage3 = localforage.createInstance({
|
1324 | name: 'commonStorage3',
|
1325 | storeName: 'commonStore',
|
1326 | size: 1024
|
1327 | });
|
1328 |
|
1329 | var localforage3b = localforage.createInstance({
|
1330 | name: 'commonStorage3',
|
1331 | storeName: 'commonStore',
|
1332 | size: 1024
|
1333 | });
|
1334 |
|
1335 | var promise1 = localforage1.setItem('key1', 'value1').then(function() {
|
1336 | return localforage1.getItem('key1');
|
1337 | }).then(function(value) {
|
1338 | expect(value).to.be('value1');
|
1339 | });
|
1340 |
|
1341 | var promise2 = localforage2.setItem('key2', 'value2').then(function() {
|
1342 | return localforage2.getItem('key2');
|
1343 | }).then(function(value) {
|
1344 | expect(value).to.be('value2');
|
1345 | });
|
1346 |
|
1347 | var promise3 = localforage3.setItem('key3', 'value3').then(function() {
|
1348 | return localforage3.getItem('key3');
|
1349 | }).then(function(value) {
|
1350 | expect(value).to.be('value3');
|
1351 | });
|
1352 |
|
1353 | var promise4 = localforage3b.setItem('key3', 'value3').then(function() {
|
1354 | return localforage3.getItem('key3');
|
1355 | }).then(function(value) {
|
1356 | expect(value).to.be('value3');
|
1357 | });
|
1358 |
|
1359 | return Promise.all([
|
1360 | promise1,
|
1361 | promise2,
|
1362 | promise3,
|
1363 | promise4
|
1364 | ]);
|
1365 | });
|
1366 | });
|
1367 |
|
1368 | describe(driverName + ' driver', function() {
|
1369 | 'use strict';
|
1370 |
|
1371 | var driverPreferedOrder;
|
1372 |
|
1373 | before(function() {
|
1374 |
|
1375 |
|
1376 | driverPreferedOrder = ['I am a not supported driver'];
|
1377 |
|
1378 | if (!localforage.supports(localforage.WEBSQL)) {
|
1379 | driverPreferedOrder.push(localforage.WEBSQL);
|
1380 | }
|
1381 | if (!localforage.supports(localforage.INDEXEDDB)) {
|
1382 | driverPreferedOrder.push(localforage.INDEXEDDB);
|
1383 | }
|
1384 | if (!localforage.supports(localforage.LOCALSTORAGE)) {
|
1385 | driverPreferedOrder.push(localforage.localStorage);
|
1386 | }
|
1387 |
|
1388 | driverPreferedOrder.push(driverName);
|
1389 |
|
1390 | driverPreferedOrder.push('I am another not supported driver');
|
1391 | });
|
1392 |
|
1393 | it('is used according to setDriver preference order', function(done) {
|
1394 | localforage.setDriver(driverPreferedOrder).then(function() {
|
1395 | expect(localforage.driver()).to.be(driverName);
|
1396 | done();
|
1397 | });
|
1398 | });
|
1399 | });
|
1400 |
|
1401 | describe(driverName + ' driver when the callback throws an Error', function() {
|
1402 | 'use strict';
|
1403 |
|
1404 | var testObj = {
|
1405 | throwFunc: function() {
|
1406 | testObj.throwFuncCalls++;
|
1407 | throw new Error('Thrown test error');
|
1408 | },
|
1409 | throwFuncCalls: 0
|
1410 | };
|
1411 |
|
1412 | beforeEach(function(done) {
|
1413 | testObj.throwFuncCalls = 0;
|
1414 | done();
|
1415 | });
|
1416 |
|
1417 | it('resolves the promise of getItem()', function(done) {
|
1418 | localforage.getItem('key', testObj.throwFunc).then(function() {
|
1419 | expect(testObj.throwFuncCalls).to.be(1);
|
1420 | done();
|
1421 | });
|
1422 | });
|
1423 |
|
1424 | it('resolves the promise of setItem()', function(done) {
|
1425 | localforage.setItem('key', 'test', testObj.throwFunc).then(function() {
|
1426 | expect(testObj.throwFuncCalls).to.be(1);
|
1427 | done();
|
1428 | });
|
1429 | });
|
1430 |
|
1431 | it('resolves the promise of clear()', function(done) {
|
1432 | localforage.clear(testObj.throwFunc).then(function() {
|
1433 | expect(testObj.throwFuncCalls).to.be(1);
|
1434 | done();
|
1435 | });
|
1436 | });
|
1437 |
|
1438 | it('resolves the promise of length()', function(done) {
|
1439 | localforage.length(testObj.throwFunc).then(function() {
|
1440 | expect(testObj.throwFuncCalls).to.be(1);
|
1441 | done();
|
1442 | });
|
1443 | });
|
1444 |
|
1445 | it('resolves the promise of removeItem()', function(done) {
|
1446 | localforage.removeItem('key', testObj.throwFunc).then(function() {
|
1447 | expect(testObj.throwFuncCalls).to.be(1);
|
1448 | done();
|
1449 | });
|
1450 | });
|
1451 |
|
1452 | it('resolves the promise of key()', function(done) {
|
1453 | localforage.key('key', testObj.throwFunc).then(function() {
|
1454 | expect(testObj.throwFuncCalls).to.be(1);
|
1455 | done();
|
1456 | });
|
1457 | });
|
1458 |
|
1459 | it('resolves the promise of keys()', function(done) {
|
1460 | localforage.keys(testObj.throwFunc).then(function() {
|
1461 | expect(testObj.throwFuncCalls).to.be(1);
|
1462 | done();
|
1463 | });
|
1464 | });
|
1465 | });
|
1466 |
|
1467 | describe(driverName + ' driver when ready() gets rejected', function() {
|
1468 | 'use strict';
|
1469 |
|
1470 | this.timeout(30000);
|
1471 |
|
1472 | var _oldReady;
|
1473 |
|
1474 | beforeEach(function(done) {
|
1475 | _oldReady = localforage.ready;
|
1476 | localforage.ready = function() {
|
1477 | return Promise.reject();
|
1478 | };
|
1479 | done();
|
1480 | });
|
1481 |
|
1482 | afterEach(function(done) {
|
1483 | localforage.ready = _oldReady;
|
1484 | _oldReady = null;
|
1485 | done();
|
1486 | });
|
1487 |
|
1488 | driverApiMethods.forEach(function(methodName) {
|
1489 | it('rejects ' + methodName + '() promise', function(done) {
|
1490 | localforage[methodName]().then(null, function(/*err*/) {
|
1491 | done();
|
1492 | });
|
1493 | });
|
1494 | });
|
1495 | });
|
1496 | });
|
1497 |
|
1498 | DRIVERS.forEach(function(driverName) {
|
1499 | describe(driverName + ' driver instance', function() {
|
1500 | it('creates a new instance and sets the driver', function(done) {
|
1501 | var localforage2 = localforage.createInstance({
|
1502 | name: 'storage2',
|
1503 | driver: driverName,
|
1504 |
|
1505 |
|
1506 |
|
1507 |
|
1508 | size: 1024,
|
1509 | storeName: 'storagename2'
|
1510 | });
|
1511 |
|
1512 |
|
1513 |
|
1514 |
|
1515 | localforage2.length().then(function() {
|
1516 | expect(localforage2.driver()).to.be(driverName);
|
1517 | done();
|
1518 | }, function() {
|
1519 | expect(localforage2.driver()).to.be(null);
|
1520 | done();
|
1521 | });
|
1522 | });
|
1523 | });
|
1524 | });
|
1525 |
|
1526 | SUPPORTED_DRIVERS.forEach(function(driverName) {
|
1527 | describe(driverName + ' driver dropInstance', function() {
|
1528 |
|
1529 | this.timeout(30000);
|
1530 |
|
1531 | var nodropInstance;
|
1532 | var nodropInstanceOptions = {
|
1533 | name: 'dropStoreDb',
|
1534 | driver: driverName,
|
1535 | size: 1024,
|
1536 | storeName: 'nodropStore'
|
1537 | };
|
1538 |
|
1539 | var dropStoreInstance1;
|
1540 | var dropStoreInstance1Options = {
|
1541 | name: 'dropStoreDb',
|
1542 | driver: driverName,
|
1543 | size: 1024,
|
1544 | storeName: 'dropStore'
|
1545 | };
|
1546 |
|
1547 | var dropStoreInstance2;
|
1548 | var dropStoreInstance2Options = {
|
1549 | name: 'dropStoreDb',
|
1550 | driver: driverName,
|
1551 | size: 1024,
|
1552 | storeName: 'dropStore2'
|
1553 | };
|
1554 |
|
1555 | var dropStoreInstance3;
|
1556 | var dropStoreInstance3Options = {
|
1557 | name: 'dropStoreDb',
|
1558 | driver: driverName,
|
1559 | size: 1024,
|
1560 | storeName: 'dropStore3'
|
1561 | };
|
1562 |
|
1563 | var dropDbInstance;
|
1564 | var dropDbInstanceOptions = {
|
1565 | name: 'dropDb',
|
1566 | driver: driverName,
|
1567 | size: 1024,
|
1568 | storeName: 'dropStore'
|
1569 | };
|
1570 |
|
1571 | var dropDb2Instance;
|
1572 | var dropDb2InstanceOptions = {
|
1573 | name: 'dropDb2',
|
1574 | driver: driverName,
|
1575 | size: 1024,
|
1576 | storeName: 'dropStore'
|
1577 | };
|
1578 |
|
1579 | before(function() {
|
1580 | nodropInstance = localforage.createInstance(nodropInstanceOptions);
|
1581 | dropStoreInstance1 = localforage.createInstance(dropStoreInstance1Options);
|
1582 | dropStoreInstance2 = localforage.createInstance(dropStoreInstance2Options);
|
1583 | dropStoreInstance3 = localforage.createInstance(dropStoreInstance2Options);
|
1584 | dropDbInstance = localforage.createInstance(dropDbInstanceOptions);
|
1585 | dropDb2Instance = localforage.createInstance(dropDb2InstanceOptions);
|
1586 | return Promise.resolve().then(function() {
|
1587 | return nodropInstance.setItem('key1', 'value0');
|
1588 | }).then(function() {
|
1589 | return dropStoreInstance1.setItem('key1', 'value1');
|
1590 | }).then(function() {
|
1591 | return dropStoreInstance2.setItem('key1', 'value2');
|
1592 | }).then(function() {
|
1593 | return dropStoreInstance3.setItem('key1', 'value3');
|
1594 | }).then(function() {
|
1595 | return dropDbInstance.setItem('key1', 'value3');
|
1596 | }).then(function() {
|
1597 | return dropDb2Instance.setItem('key1', 'value3');
|
1598 | });
|
1599 | });
|
1600 |
|
1601 | function expectStoreToNotExistAsync(options) {
|
1602 | return new Promise(function(resolve, reject) {
|
1603 | if (driverName === localforage.INDEXEDDB) {
|
1604 | var req = indexedDB.open(options.name);
|
1605 | req.onsuccess = function() {
|
1606 | var db = req.result;
|
1607 | if (!db) {
|
1608 | reject();
|
1609 | return;
|
1610 | }
|
1611 | expect(db.objectStoreNames.contains(options.storeName)).to.be(false);
|
1612 | db.close();
|
1613 | resolve();
|
1614 | };
|
1615 | req.onerror = req.onblocked = reject;
|
1616 | } else if (driverName === localforage.WEBSQL) {
|
1617 | var db = openDatabase(options.name, '', '', 0);
|
1618 | db.transaction(function(t) {
|
1619 | t.executeSql(
|
1620 | "SELECT name FROM sqlite_master WHERE type='table' AND name = ?",
|
1621 | [options.storeName],
|
1622 | function(t, results) {
|
1623 | expect(results.rows.length).to.be(0);
|
1624 | resolve();
|
1625 | },
|
1626 | reject
|
1627 | );
|
1628 | }, reject);
|
1629 | } else if (driverName === localforage.LOCALSTORAGE) {
|
1630 | var keyPrefix = (function _getKeyPrefix(options, defaultConfig) {
|
1631 | var keyPrefix = options.name + '/';
|
1632 |
|
1633 | if (options.storeName !== defaultConfig.storeName) {
|
1634 | keyPrefix += options.storeName + '/';
|
1635 | }
|
1636 | return keyPrefix;
|
1637 | })(options, {
|
1638 | name: 'localforage',
|
1639 | storeName: 'keyvaluepairs'
|
1640 | });
|
1641 |
|
1642 | var foundLocalStorageKey = false;
|
1643 | for (var i = 0, length = localStorage.length; i < length; i++) {
|
1644 | if (localStorage.key(i).indexOf(keyPrefix) === 0) {
|
1645 | foundLocalStorageKey = true;
|
1646 | break;
|
1647 | }
|
1648 | }
|
1649 | expect(foundLocalStorageKey).to.be(false);
|
1650 | resolve();
|
1651 | } else {
|
1652 | throw new Error('Not Implemented Exception');
|
1653 | }
|
1654 | });
|
1655 | }
|
1656 |
|
1657 | it('drops the current instance without affecting the rest', function() {
|
1658 | return dropStoreInstance1.dropInstance().then(function() {
|
1659 | return nodropInstance.getItem('key1');
|
1660 | }).then(function(value) {
|
1661 | expect(value).to.be('value0');
|
1662 | });
|
1663 | });
|
1664 |
|
1665 | it('can recreate and set values to previously dropped instances', function() {
|
1666 | return dropStoreInstance1.dropInstance().then(function() {
|
1667 | return dropStoreInstance1.getItem('key1');
|
1668 | }).then(function(value) {
|
1669 | expect(value).to.be(null);
|
1670 | return dropStoreInstance1.length();
|
1671 | }).then(function(length) {
|
1672 | expect(length).to.be(0);
|
1673 | }).then(function() {
|
1674 | return dropStoreInstance1.setItem('key1', 'newvalue2');
|
1675 | }).then(function() {
|
1676 | return dropStoreInstance1.getItem('key1');
|
1677 | }).then(function(value) {
|
1678 | expect(value).to.be('newvalue2');
|
1679 | });
|
1680 | });
|
1681 |
|
1682 | it('drops an other instance without affecting the rest', function() {
|
1683 | var opts = {
|
1684 | name: dropStoreInstance2Options.name,
|
1685 | storeName: dropStoreInstance2Options.storeName
|
1686 | };
|
1687 | return nodropInstance.dropInstance(opts).then(function() {
|
1688 | return nodropInstance.getItem('key1');
|
1689 | }).then(function(value) {
|
1690 | expect(value).to.be('value0');
|
1691 | });
|
1692 | });
|
1693 |
|
1694 | it('the dropped instance is completely removed', function() {
|
1695 | var opts = {
|
1696 | name: dropStoreInstance3Options.name,
|
1697 | storeName: dropStoreInstance3Options.storeName
|
1698 | };
|
1699 | return dropStoreInstance3.dropInstance().then(function() {
|
1700 | return expectStoreToNotExistAsync(opts);
|
1701 | });
|
1702 | });
|
1703 |
|
1704 | function expectDBToNotExistAsync(options) {
|
1705 | return new Promise(function(resolve, reject) {
|
1706 | if (driverName === localforage.INDEXEDDB) {
|
1707 | var req = indexedDB.open(options.name);
|
1708 | req.onsuccess = function() {
|
1709 | var db = req.result;
|
1710 | if (!db) {
|
1711 | reject();
|
1712 | return;
|
1713 | }
|
1714 | expect(db.objectStoreNames.length).to.be(0);
|
1715 | db.close();
|
1716 | resolve();
|
1717 | };
|
1718 | req.onerror = req.onblocked = reject;
|
1719 | } else if (driverName === localforage.WEBSQL) {
|
1720 | var db = openDatabase(options.name, '', '', 0);
|
1721 | db.transaction(function(t) {
|
1722 | t.executeSql(
|
1723 | "SELECT name FROM sqlite_master WHERE type='table'",
|
1724 | [],
|
1725 | function(t, results) {
|
1726 | var stores = Array.prototype.filter.call(results.rows, function(obj) {
|
1727 | return obj && obj.name && obj.name.indexOf('__') !== 0;
|
1728 | });
|
1729 | expect(stores.length).to.be(0);
|
1730 | resolve();
|
1731 | },
|
1732 | reject
|
1733 | );
|
1734 | }, reject);
|
1735 | } else if (driverName === localforage.LOCALSTORAGE) {
|
1736 | var keyPrefix = (function _getKeyPrefix(options) {
|
1737 | return options.name + '/';
|
1738 | })(options);
|
1739 |
|
1740 | var foundLocalStorageKey = false;
|
1741 | for (var i = 0, length = localStorage.length; i < length; i++) {
|
1742 | if (localStorage.key(i).indexOf(keyPrefix) === 0) {
|
1743 | foundLocalStorageKey = true;
|
1744 | break;
|
1745 | }
|
1746 | }
|
1747 | expect(foundLocalStorageKey).to.be(false);
|
1748 | resolve();
|
1749 | } else {
|
1750 | throw new Error('Not Implemented Exception');
|
1751 | }
|
1752 | });
|
1753 | }
|
1754 |
|
1755 | it('the dropped "DB" can be recreated', function() {
|
1756 | var opts = {
|
1757 | name: dropDbInstanceOptions.name
|
1758 | };
|
1759 | return dropDbInstance.dropInstance(opts).then(function() {
|
1760 | return dropDbInstance.getItem('key1');
|
1761 | }).then(function(value) {
|
1762 | expect(value).to.be(null);
|
1763 | });
|
1764 | });
|
1765 |
|
1766 | it('the dropped "DB" is completely removed', function() {
|
1767 | var opts = {
|
1768 | name: dropDb2InstanceOptions.name
|
1769 | };
|
1770 | return dropDb2Instance.dropInstance(opts).then(function() {
|
1771 | return expectDBToNotExistAsync(opts);
|
1772 | });
|
1773 | });
|
1774 | });
|
1775 | });
|