1 |
|
2 |
|
3 |
|
4 | function createBlob(parts, properties) {
|
5 |
|
6 | parts = parts || [];
|
7 | properties = properties || {};
|
8 | try {
|
9 | return new Blob(parts, properties);
|
10 | } catch (e) {
|
11 | if (e.name !== 'TypeError') {
|
12 | throw e;
|
13 | }
|
14 | var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder :
|
15 | typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder :
|
16 | typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder :
|
17 | WebKitBlobBuilder;
|
18 | var builder = new Builder();
|
19 | for (var i = 0; i < parts.length; i += 1) {
|
20 | builder.append(parts[i]);
|
21 | }
|
22 | return builder.getBlob(properties.type);
|
23 | }
|
24 | }
|
25 |
|
26 | var DRIVERS = [
|
27 | localforage.INDEXEDDB,
|
28 | localforage.LOCALSTORAGE,
|
29 | localforage.WEBSQL
|
30 | ];
|
31 |
|
32 | DRIVERS.forEach(function(driverName) {
|
33 | if ((!localforage.supports(localforage.INDEXEDDB) &&
|
34 | driverName === localforage.INDEXEDDB) ||
|
35 | (!localforage.supports(localforage.LOCALSTORAGE) &&
|
36 | driverName === localforage.LOCALSTORAGE) ||
|
37 | (!localforage.supports(localforage.WEBSQL) &&
|
38 | driverName === localforage.WEBSQL)) {
|
39 |
|
40 |
|
41 | return;
|
42 | }
|
43 |
|
44 | describe('Type handler for ' + driverName, function() {
|
45 | 'use strict';
|
46 |
|
47 | this.timeout(30000);
|
48 |
|
49 | before(function(done) {
|
50 | localforage.setDriver(driverName).then(done);
|
51 | });
|
52 |
|
53 | beforeEach(function(done) {
|
54 | localforage.clear(done);
|
55 | });
|
56 |
|
57 | it('saves a string [callback]', function(done) {
|
58 | localforage.setItem('office', 'Initech', function(err, setValue) {
|
59 | expect(setValue).to.be('Initech');
|
60 |
|
61 | localforage.getItem('office', function(err, value) {
|
62 | expect(value).to.be(setValue);
|
63 | done();
|
64 | });
|
65 | });
|
66 | });
|
67 | it('saves a string [promise]', function(done) {
|
68 | localforage.setItem('office', 'Initech').then(function(setValue) {
|
69 | expect(setValue).to.be('Initech');
|
70 |
|
71 | return localforage.getItem('office');
|
72 | }).then(function(value) {
|
73 | expect(value).to.be('Initech');
|
74 | done();
|
75 | });
|
76 | });
|
77 |
|
78 | it('saves a string like "[object Blob]" [promise]', function(done) {
|
79 | localforage.setItem('fake Blob', '[object Blob]').then(function(setValue) {
|
80 | expect(setValue).to.be('[object Blob]');
|
81 |
|
82 | return localforage.getItem('fake Blob');
|
83 | }).then(function(value) {
|
84 | expect(value).to.be('[object Blob]');
|
85 | done();
|
86 | });
|
87 | });
|
88 |
|
89 | it('saves a number [callback]', function(done) {
|
90 | localforage.setItem('number', 546, function(err, setValue) {
|
91 | expect(setValue).to.be(546);
|
92 | expect(setValue).to.be.a('number');
|
93 |
|
94 | localforage.getItem('number', function(err, value) {
|
95 | expect(value).to.be(setValue);
|
96 | expect(value).to.be.a('number');
|
97 | done();
|
98 | });
|
99 | });
|
100 | });
|
101 | it('saves a number [promise]', function(done) {
|
102 | localforage.setItem('number', 546).then(function(setValue) {
|
103 | expect(setValue).to.be(546);
|
104 | expect(setValue).to.be.a('number');
|
105 |
|
106 | return localforage.getItem('number');
|
107 | }).then(function(value) {
|
108 | expect(value).to.be(546);
|
109 | expect(value).to.be.a('number');
|
110 | done();
|
111 | });
|
112 | });
|
113 |
|
114 | it('saves a boolean [callback]', function(done) {
|
115 | localforage.setItem('boolean', false, function(err, setValue) {
|
116 | expect(setValue).to.be(false);
|
117 | expect(setValue).to.be.a('boolean');
|
118 |
|
119 | localforage.getItem('boolean', function(err, value) {
|
120 | expect(value).to.be(setValue);
|
121 | expect(value).to.be.a('boolean');
|
122 | done();
|
123 | });
|
124 | });
|
125 | });
|
126 | it('saves a boolean [promise]', function(done) {
|
127 | localforage.setItem('boolean', false).then(function(setValue) {
|
128 | expect(setValue).to.be(false);
|
129 | expect(setValue).to.be.a('boolean');
|
130 |
|
131 | return localforage.getItem('boolean');
|
132 | }).then(function(value) {
|
133 | expect(value).to.be(false);
|
134 | expect(value).to.be.a('boolean');
|
135 | done();
|
136 | });
|
137 | });
|
138 |
|
139 | it('saves null [callback]', function(done) {
|
140 | localforage.setItem('null', null, function(err, setValue) {
|
141 | expect(setValue).to.be(null);
|
142 |
|
143 | localforage.getItem('null', function(err, value) {
|
144 | expect(value).to.be(null);
|
145 | done();
|
146 | });
|
147 | });
|
148 | });
|
149 | it('saves null [promise]', function(done) {
|
150 | localforage.setItem('null', null).then(function(setValue) {
|
151 | expect(setValue).to.be(null);
|
152 |
|
153 | return localforage.getItem('null');
|
154 | }).then(function(value) {
|
155 | expect(value).to.be(null);
|
156 | done();
|
157 | });
|
158 | });
|
159 |
|
160 | it('saves undefined as null [callback]', function(done) {
|
161 | localforage.setItem('null', undefined, function(err, setValue) {
|
162 | expect(setValue).to.be(null);
|
163 |
|
164 | localforage.getItem('null', function(err, value) {
|
165 | expect(value).to.be(null);
|
166 | done();
|
167 | });
|
168 | });
|
169 | });
|
170 | it('saves undefined as null [promise]', function(done) {
|
171 | localforage.setItem('null', undefined).then(function(setValue) {
|
172 | expect(setValue).to.be(null);
|
173 |
|
174 | return localforage.getItem('null');
|
175 | }).then(function(value) {
|
176 | expect(value).to.be(null);
|
177 | done();
|
178 | });
|
179 | });
|
180 |
|
181 | it('saves a float [callback]', function(done) {
|
182 | localforage.setItem('float', 546.041, function(err, setValue) {
|
183 | expect(setValue).to.be(546.041);
|
184 | expect(setValue).to.be.a('number');
|
185 |
|
186 | localforage.getItem('float', function(err, value) {
|
187 | expect(value).to.be(setValue);
|
188 | expect(value).to.be.a('number');
|
189 | done();
|
190 | });
|
191 | });
|
192 | });
|
193 | it('saves a float [promise]', function(done) {
|
194 | localforage.setItem('float', 546.041).then(function(setValue) {
|
195 | expect(setValue).to.be(546.041);
|
196 | expect(setValue).to.be.a('number');
|
197 |
|
198 | return localforage.getItem('float');
|
199 | }).then(function(value) {
|
200 | expect(value).to.be(546.041);
|
201 | expect(value).to.be.a('number');
|
202 | done();
|
203 | });
|
204 | });
|
205 |
|
206 | var arrayToSave = [2, 'one', true];
|
207 | it('saves an array [callback]', function(done) {
|
208 | localforage.setItem('array', arrayToSave, function(err, setValue) {
|
209 | expect(setValue.length).to.be(arrayToSave.length);
|
210 | expect(setValue instanceof Array).to.be(true);
|
211 |
|
212 | localforage.getItem('array', function(err, value) {
|
213 | expect(value.length).to.be(arrayToSave.length);
|
214 | expect(value instanceof Array).to.be(true);
|
215 | expect(value[1]).to.be.a('string');
|
216 | done();
|
217 | });
|
218 | });
|
219 | });
|
220 | it('saves an array [promise]', function(done) {
|
221 | localforage.setItem('array', arrayToSave).then(function(setValue) {
|
222 | expect(setValue.length).to.be(arrayToSave.length);
|
223 | expect(setValue instanceof Array).to.be(true);
|
224 |
|
225 | return localforage.getItem('array');
|
226 | }).then(function(value) {
|
227 | expect(value.length).to.be(arrayToSave.length);
|
228 | expect(value instanceof Array).to.be(true);
|
229 | expect(value[1]).to.be.a('string');
|
230 | done();
|
231 | });
|
232 | });
|
233 |
|
234 | var objectToSave = {
|
235 | floating: 43.01,
|
236 | nested: {
|
237 | array: [1, 2, 3]
|
238 | },
|
239 | nestedObjects: [
|
240 | {truth: true},
|
241 | {theCake: 'is a lie'},
|
242 | {happiness: 'is a warm gun'},
|
243 | false
|
244 | ],
|
245 | string: 'bar'
|
246 | };
|
247 | it('saves a nested object [callback]', function(done) {
|
248 | localforage.setItem('obj', objectToSave, function(err, setValue) {
|
249 | expect(Object.keys(setValue).length)
|
250 | .to.be(Object.keys(objectToSave).length);
|
251 | expect(setValue).to.be.an('object');
|
252 |
|
253 | localforage.getItem('obj', function(err, value) {
|
254 | expect(Object.keys(value).length)
|
255 | .to.be(Object.keys(objectToSave).length);
|
256 | expect(value).to.be.an('object');
|
257 | expect(value.nested).to.be.an('object');
|
258 | expect(value.nestedObjects[0].truth).to.be.a('boolean');
|
259 | expect(value.nestedObjects[1].theCake).to.be.a('string');
|
260 | expect(value.nestedObjects[3]).to.be(false);
|
261 | done();
|
262 | });
|
263 | });
|
264 | });
|
265 | it('saves a nested object [promise]', function(done) {
|
266 | localforage.setItem('obj', objectToSave).then(function(setValue) {
|
267 | expect(Object.keys(setValue).length)
|
268 | .to.be(Object.keys(objectToSave).length);
|
269 | expect(setValue).to.be.an('object');
|
270 |
|
271 | return localforage.getItem('obj');
|
272 | }).then(function(value) {
|
273 | expect(Object.keys(value).length)
|
274 | .to.be(Object.keys(objectToSave).length);
|
275 | expect(value).to.be.an('object');
|
276 | expect(value.nested).to.be.an('object');
|
277 | expect(value.nestedObjects[0].truth).to.be.a('boolean');
|
278 | expect(value.nestedObjects[1].theCake).to.be.a('string');
|
279 | expect(value.nestedObjects[3]).to.be(false);
|
280 | done();
|
281 | });
|
282 | });
|
283 |
|
284 |
|
285 | if (typeof ArrayBuffer !== 'undefined') {
|
286 | var runBinaryTest = function(url, done) {
|
287 | var request = new XMLHttpRequest();
|
288 |
|
289 | request.open('GET', url, true);
|
290 | request.responseType = 'arraybuffer';
|
291 |
|
292 |
|
293 | request.onreadystatechange = function() {
|
294 | if (request.readyState === request.DONE) {
|
295 | var response = request.response;
|
296 | localforage.setItem('ab', response, function(err, sab) {
|
297 | expect(sab.toString())
|
298 | .to.be('[object ArrayBuffer]');
|
299 | expect(sab.byteLength)
|
300 | .to.be(response.byteLength);
|
301 | }).then(function() {
|
302 |
|
303 |
|
304 |
|
305 | localforage.getItem('ab', function(err, arrayBuff) {
|
306 | expect(arrayBuff.toString())
|
307 | .to.be('[object ArrayBuffer]');
|
308 | expect(arrayBuff.byteLength)
|
309 | .to.be(response.byteLength);
|
310 | });
|
311 | done();
|
312 | });
|
313 | }
|
314 | };
|
315 |
|
316 | request.send();
|
317 | };
|
318 |
|
319 | it('saves binary (ArrayBuffer) data', function(done) {
|
320 | runBinaryTest('/test/photo.jpg', done);
|
321 | });
|
322 |
|
323 | it('saves odd length binary (ArrayBuffer) data', function(done) {
|
324 | runBinaryTest('/test/photo2.jpg', done);
|
325 | });
|
326 | } else {
|
327 | it.skip('saves binary (ArrayBuffer) data (ArrayBuffer type does not exist)');
|
328 | }
|
329 |
|
330 |
|
331 |
|
332 |
|
333 | if (typeof Blob === 'function') {
|
334 | it('saves binary (Blob) data', function(done) {
|
335 | var fileParts = ['<a id="a"><b id="b">hey!</b></a>'];
|
336 | var mimeString = 'text/html';
|
337 |
|
338 | var testBlob = createBlob(fileParts, { 'type' : mimeString });
|
339 |
|
340 | localforage.setItem('blob', testBlob, function(err, blob) {
|
341 | expect(err).to.be(null);
|
342 | expect(blob.toString())
|
343 | .to.be('[object Blob]');
|
344 | expect(blob.size)
|
345 | .to.be(testBlob.size);
|
346 | expect(blob.type)
|
347 | .to.be(testBlob.type);
|
348 | }).then(function() {
|
349 | localforage.getItem('blob', function(err, blob) {
|
350 | expect(err).to.be(null);
|
351 | expect(blob.toString())
|
352 | .to.be('[object Blob]');
|
353 | expect(blob.size)
|
354 | .to.be(testBlob.size);
|
355 | expect(blob.type)
|
356 | .to.be(testBlob.type);
|
357 | done();
|
358 | });
|
359 | });
|
360 | });
|
361 | } else {
|
362 | it.skip('saves binary (Blob) data (Blob type does not exist)');
|
363 | }
|
364 |
|
365 | if (typeof Blob === 'function') {
|
366 | it('saves binary (Blob) data, iterate back', function(done) {
|
367 | var fileParts = ['<a id="a"><b id="b">hey!</b></a>'];
|
368 | var mimeString = 'text/html';
|
369 |
|
370 | var testBlob = createBlob(fileParts, { 'type' : mimeString });
|
371 |
|
372 | localforage.setItem('blob', testBlob, function(err, blob) {
|
373 | expect(err).to.be(null);
|
374 | expect(blob.toString())
|
375 | .to.be('[object Blob]');
|
376 | expect(blob.size)
|
377 | .to.be(testBlob.size);
|
378 | expect(blob.type)
|
379 | .to.be(testBlob.type);
|
380 | }).then(function() {
|
381 | localforage.iterate(function(blob, key) {
|
382 | if (key !== 'blob') {
|
383 | return;
|
384 | }
|
385 | expect(blob.toString())
|
386 | .to.be('[object Blob]');
|
387 | expect(blob.size)
|
388 | .to.be(testBlob.size);
|
389 | expect(blob.type)
|
390 | .to.be(testBlob.type);
|
391 | done();
|
392 | });
|
393 | });
|
394 | });
|
395 | } else {
|
396 | it.skip('saves binary (Blob) data (Blob type does not exist)');
|
397 | }
|
398 | });
|
399 |
|
400 | describe('Typed Array handling in ' + driverName, function() {
|
401 | if (typeof Int8Array !== 'undefined') {
|
402 | it('saves an Int8Array', function(done) {
|
403 | var array = new Int8Array(8);
|
404 | array[2] = 65;
|
405 | array[4] = 0;
|
406 |
|
407 | localforage.setItem('array', array, function(err, writeValue) {
|
408 | localforage.getItem('array', function(err, readValue) {
|
409 | expect(readValue instanceof Int8Array).to.be(true);
|
410 | expect(readValue[2]).to.be(array[2]);
|
411 | expect(readValue[4]).to.be(writeValue[4]);
|
412 | expect(readValue.length).to.be(writeValue.length);
|
413 |
|
414 | done();
|
415 | });
|
416 | });
|
417 | });
|
418 | } else {
|
419 | it.skip("doesn't have the Int8Array type");
|
420 | }
|
421 |
|
422 | if (typeof Uint8Array !== 'undefined') {
|
423 | it('saves an Uint8Array', function(done) {
|
424 | var array = new Uint8Array(8);
|
425 | array[0] = 65;
|
426 | array[4] = 0;
|
427 |
|
428 | localforage.setItem('array', array, function(err, writeValue) {
|
429 | localforage.getItem('array', function(err, readValue) {
|
430 | expect(readValue instanceof Uint8Array).to.be(true);
|
431 | expect(readValue[0]).to.be(array[0]);
|
432 | expect(readValue[4]).to.be(writeValue[4]);
|
433 | expect(readValue.length).to.be(writeValue.length);
|
434 |
|
435 | done();
|
436 | });
|
437 | });
|
438 | });
|
439 | } else {
|
440 | it.skip("doesn't have the Uint8Array type");
|
441 | }
|
442 |
|
443 | if (typeof Uint8ClampedArray !== 'undefined') {
|
444 | it('saves an Uint8ClampedArray', function(done) {
|
445 | var array = new Uint8ClampedArray(8);
|
446 | array[0] = 0;
|
447 | array[1] = 93;
|
448 | array[2] = 350;
|
449 |
|
450 | localforage.setItem('array', array, function(err, writeValue) {
|
451 | localforage.getItem('array', function(err, readValue) {
|
452 | expect(readValue instanceof Uint8ClampedArray)
|
453 | .to.be(true);
|
454 | expect(readValue[0]).to.be(array[0]);
|
455 | expect(readValue[1]).to.be(array[1]);
|
456 | expect(readValue[2]).to.be(array[2]);
|
457 | expect(readValue[1]).to.be(writeValue[1]);
|
458 | expect(readValue.length).to.be(writeValue.length);
|
459 |
|
460 | done();
|
461 | });
|
462 | });
|
463 | });
|
464 | } else {
|
465 | it.skip("doesn't have the Uint8Array type");
|
466 | }
|
467 |
|
468 | if (typeof Int16Array !== 'undefined') {
|
469 | it('saves an Int16Array', function(done) {
|
470 | var array = new Int16Array(8);
|
471 | array[0] = 65;
|
472 | array[4] = 0;
|
473 |
|
474 | localforage.setItem('array', array, function(err, writeValue) {
|
475 | localforage.getItem('array', function(err, readValue) {
|
476 | expect(readValue instanceof Int16Array).to.be(true);
|
477 | expect(readValue[0]).to.be(array[0]);
|
478 | expect(readValue[4]).to.be(writeValue[4]);
|
479 | expect(readValue.length).to.be(writeValue.length);
|
480 |
|
481 | done();
|
482 | });
|
483 | });
|
484 | });
|
485 | } else {
|
486 | it.skip("doesn't have the Int16Array type");
|
487 | }
|
488 |
|
489 | if (typeof Uint16Array !== 'undefined') {
|
490 | it('saves an Uint16Array', function(done) {
|
491 | var array = new Uint16Array(8);
|
492 | array[0] = 65;
|
493 | array[4] = 0;
|
494 |
|
495 | localforage.setItem('array', array, function(err, writeValue) {
|
496 | localforage.getItem('array', function(err, readValue) {
|
497 | expect(readValue instanceof Uint16Array).to.be(true);
|
498 | expect(readValue[0]).to.be(array[0]);
|
499 | expect(readValue[4]).to.be(writeValue[4]);
|
500 | expect(readValue.length).to.be(writeValue.length);
|
501 |
|
502 | done();
|
503 | });
|
504 | });
|
505 | });
|
506 | } else {
|
507 | it.skip("doesn't have the Uint16Array type");
|
508 | }
|
509 |
|
510 | if (typeof Int32Array !== 'undefined') {
|
511 | it('saves an Int32Array', function(done) {
|
512 | var array = new Int32Array(8);
|
513 | array[0] = 65;
|
514 | array[4] = 0;
|
515 |
|
516 | localforage.setItem('array', array, function(err, writeValue) {
|
517 | localforage.getItem('array', function(err, readValue) {
|
518 | expect(readValue instanceof Int32Array).to.be(true);
|
519 | expect(readValue[0]).to.be(array[0]);
|
520 | expect(readValue[4]).to.be(writeValue[4]);
|
521 | expect(readValue.length).to.be(writeValue.length);
|
522 |
|
523 | done();
|
524 | });
|
525 | });
|
526 | });
|
527 | } else {
|
528 | it.skip("doesn't have the Int32Array type");
|
529 | }
|
530 |
|
531 | if (typeof Uint32Array !== 'undefined') {
|
532 | it('saves an Uint32Array', function(done) {
|
533 | var array = new Uint32Array(8);
|
534 | array[0] = 65;
|
535 | array[4] = 0;
|
536 |
|
537 | localforage.setItem('array', array, function(err, writeValue) {
|
538 | localforage.getItem('array', function(err, readValue) {
|
539 | expect(readValue instanceof Uint32Array).to.be(true);
|
540 | expect(readValue[0]).to.be(array[0]);
|
541 | expect(readValue[4]).to.be(writeValue[4]);
|
542 | expect(readValue.length).to.be(writeValue.length);
|
543 |
|
544 | done();
|
545 | });
|
546 | });
|
547 | });
|
548 | } else {
|
549 | it.skip("doesn't have the Uint32Array type");
|
550 | }
|
551 |
|
552 | if (typeof Float32Array !== 'undefined') {
|
553 | it('saves a Float32Array', function(done) {
|
554 | var array = new Float32Array(8);
|
555 | array[0] = 6.5;
|
556 | array[4] = 0.1;
|
557 |
|
558 | localforage.setItem('array', array, function(err, writeValue) {
|
559 | localforage.getItem('array', function(err, readValue) {
|
560 | expect(readValue instanceof Float32Array).to.be(true);
|
561 | expect(readValue[0]).to.be(array[0]);
|
562 | expect(readValue[4]).to.be(writeValue[4]);
|
563 | expect(readValue.length).to.be(writeValue.length);
|
564 |
|
565 | done();
|
566 | });
|
567 | });
|
568 | });
|
569 | } else {
|
570 | it.skip("doesn't have the Float32Array type");
|
571 | }
|
572 |
|
573 | if (typeof Float64Array !== 'undefined') {
|
574 | it('saves a Float64Array', function(done) {
|
575 | var array = new Float64Array(8);
|
576 | array[0] = 6.5;
|
577 | array[4] = 0.1;
|
578 |
|
579 | localforage.setItem('array', array, function(err, writeValue) {
|
580 | localforage.getItem('array', function(err, readValue) {
|
581 | expect(readValue instanceof Float64Array).to.be(true);
|
582 | expect(readValue[0]).to.be(array[0]);
|
583 | expect(readValue[4]).to.be(writeValue[4]);
|
584 | expect(readValue.length).to.be(writeValue.length);
|
585 |
|
586 | done();
|
587 | });
|
588 | });
|
589 | });
|
590 | } else {
|
591 | it.skip("doesn't have the Float64Array type");
|
592 | }
|
593 | });
|
594 | });
|