diff --git a/README.md b/README.md index f78dce1..c11006b 100644 --- a/README.md +++ b/README.md @@ -143,21 +143,26 @@ IDBFS based file systems can acquire new functionality by using adapters. These of storage providers without altering them in anway. An adapter can be used with any provider, and multiple adapters can be used together in order to compose complex functionality on top of a provider. -There are currently 4 adapters available: +There are currently 5 adapters available: +* `FileSystem.adapters.Compression(provider)` - a default compression adapter that uses [Zlib](https://github.com/imaya/zlib.js) +* `FileSystem.adapters.Encryption(passphrase, provider)` - a default encryption adapter that uses [AES encryption](http://code.google.com/p/crypto-js/#AES) + +You can also pick from other encryption cipher algorithms: * `FileSystem.adapters.AES(passphrase, provider)` - extends a provider with [AES encryption](http://code.google.com/p/crypto-js/#AES) * `FileSystem.adapters.TripleDES(passphrase, provider)` - extends a provider with [TripleDES encryption](http://code.google.com/p/crypto-js/#DES,_Triple_DES) * `FileSystem.adapters.Rabbit(passphrase, provider)` - extends a provider with [Rabbit encryption](http://code.google.com/p/crypto-js/#Rabbit) -* `FileSystem.adapters.Encryption(passphrase, provider)` - a default encryption adapter that uses [AES encryption](http://code.google.com/p/crypto-js/#AES) ```javascript var FileSystem = IDBFS.FileSystem; var providers = FileSystem.providers; var adapters = FileSystem.adapters; -// Create a WebSQL-based, Encrypted File System. +// Create a WebSQL-based, Encrypted, Compressed File System by +// composing a provider and adatpers. var webSQLProvider = new providers.WebSQL(); var encryptionAdatper = new adapters.Encryption('super-secret-passphrase', webSQLProvider); -var fs1 = new FileSystem({ provider: encryptionAdapter }); +var compressionAdatper = new adatpers.Compression(encryptionAdapter); +var fs = new FileSystem({ provider: compressionAdapter }); ``` You can also write your own adapter if you need to add new capabilities to the providers. Adapters share the same diff --git a/lib/zlib.js b/lib/zlib.js new file mode 100644 index 0000000..34f0e8f --- /dev/null +++ b/lib/zlib.js @@ -0,0 +1,40 @@ +/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';function l(d){throw d;}var u=void 0,x=!0,aa=this;function z(d,a){var c=d.split("."),f=aa;!(c[0]in f)&&f.execScript&&f.execScript("var "+c[0]);for(var b;c.length&&(b=c.shift());)!c.length&&a!==u?f[b]=a:f=f[b]?f[b]:f[b]={}};var E="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array;function G(d,a){this.index="number"===typeof a?a:0;this.i=0;this.buffer=d instanceof(E?Uint8Array:Array)?d:new (E?Uint8Array:Array)(32768);2*this.buffer.length<=this.index&&l(Error("invalid index"));this.buffer.length<=this.index&&this.f()}G.prototype.f=function(){var d=this.buffer,a,c=d.length,f=new (E?Uint8Array:Array)(c<<1);if(E)f.set(d);else for(a=0;a>>8&255]<<16|N[d>>>16&255]<<8|N[d>>>24&255])>>32-a:N[d]>>8-a);if(8>a+e)g=g<>a-h-1&1,8===++e&&(e=0,f[b++]=N[g],g=0,b===f.length&&(f=this.f()));f[b]=g;this.buffer=f;this.i=e;this.index=b};G.prototype.finish=function(){var d=this.buffer,a=this.index,c;0O;++O){for(var P=O,Q=P,ga=7,P=P>>>1;P;P>>>=1)Q<<=1,Q|=P&1,--ga;fa[O]=(Q<>>0}var N=fa;function ha(d){this.buffer=new (E?Uint16Array:Array)(2*d);this.length=0}ha.prototype.getParent=function(d){return 2*((d-2)/4|0)};ha.prototype.push=function(d,a){var c,f,b=this.buffer,e;c=this.length;b[this.length++]=a;for(b[this.length++]=d;0b[f])e=b[c],b[c]=b[f],b[f]=e,e=b[c+1],b[c+1]=b[f+1],b[f+1]=e,c=f;else break;return this.length}; +ha.prototype.pop=function(){var d,a,c=this.buffer,f,b,e;a=c[0];d=c[1];this.length-=2;c[0]=c[this.length];c[1]=c[this.length+1];for(e=0;;){b=2*e+2;if(b>=this.length)break;b+2c[b]&&(b+=2);if(c[b]>c[e])f=c[e],c[e]=c[b],c[b]=f,f=c[e+1],c[e+1]=c[b+1],c[b+1]=f;else break;e=b}return{index:d,value:a,length:this.length}};function R(d){var a=d.length,c=0,f=Number.POSITIVE_INFINITY,b,e,g,h,k,n,q,r,p;for(r=0;rc&&(c=d[r]),d[r]>=1;for(p=n;pS;S++)switch(x){case 143>=S:oa.push([S+48,8]);break;case 255>=S:oa.push([S-144+400,9]);break;case 279>=S:oa.push([S-256+0,7]);break;case 287>=S:oa.push([S-280+192,8]);break;default:l("invalid literal: "+S)} +ia.prototype.j=function(){var d,a,c,f,b=this.input;switch(this.h){case 0:c=0;for(f=b.length;c>>8&255;p[m++]=n&255;p[m++]=n>>>8&255;if(E)p.set(e,m),m+=e.length,p=p.subarray(0,m);else{q=0;for(r=e.length;qv)for(;0< +v--;)H[F++]=0,K[0]++;else for(;0v?v:138,C>v-3&&C=C?(H[F++]=17,H[F++]=C-3,K[17]++):(H[F++]=18,H[F++]=C-11,K[18]++),v-=C;else if(H[F++]=I[t],K[I[t]]++,v--,3>v)for(;0v?v:6,C>v-3&&CA;A++)ra[A]=ka[gb[A]];for(W=19;4=b:return[265,b-11,1];case 14>=b:return[266,b-13,1];case 16>=b:return[267,b-15,1];case 18>=b:return[268,b-17,1];case 22>=b:return[269,b-19,2];case 26>=b:return[270,b-23,2];case 30>=b:return[271,b-27,2];case 34>=b:return[272, +b-31,2];case 42>=b:return[273,b-35,3];case 50>=b:return[274,b-43,3];case 58>=b:return[275,b-51,3];case 66>=b:return[276,b-59,3];case 82>=b:return[277,b-67,4];case 98>=b:return[278,b-83,4];case 114>=b:return[279,b-99,4];case 130>=b:return[280,b-115,4];case 162>=b:return[281,b-131,5];case 194>=b:return[282,b-163,5];case 226>=b:return[283,b-195,5];case 257>=b:return[284,b-227,5];case 258===b:return[285,b-258,0];default:l("invalid length: "+b)}}var a=[],c,f;for(c=3;258>=c;c++)f=d(c),a[c]=f[2]<<24|f[1]<< +16|f[0];return a}(),wa=E?new Uint32Array(va):va; +function pa(d,a){function c(b,c){var a=b.G,d=[],e=0,f;f=wa[b.length];d[e++]=f&65535;d[e++]=f>>16&255;d[e++]=f>>24;var g;switch(x){case 1===a:g=[0,a-1,0];break;case 2===a:g=[1,a-2,0];break;case 3===a:g=[2,a-3,0];break;case 4===a:g=[3,a-4,0];break;case 6>=a:g=[4,a-5,1];break;case 8>=a:g=[5,a-7,1];break;case 12>=a:g=[6,a-9,2];break;case 16>=a:g=[7,a-13,2];break;case 24>=a:g=[8,a-17,3];break;case 32>=a:g=[9,a-25,3];break;case 48>=a:g=[10,a-33,4];break;case 64>=a:g=[11,a-49,4];break;case 96>=a:g=[12,a- +65,5];break;case 128>=a:g=[13,a-97,5];break;case 192>=a:g=[14,a-129,6];break;case 256>=a:g=[15,a-193,6];break;case 384>=a:g=[16,a-257,7];break;case 512>=a:g=[17,a-385,7];break;case 768>=a:g=[18,a-513,8];break;case 1024>=a:g=[19,a-769,8];break;case 1536>=a:g=[20,a-1025,9];break;case 2048>=a:g=[21,a-1537,9];break;case 3072>=a:g=[22,a-2049,10];break;case 4096>=a:g=[23,a-3073,10];break;case 6144>=a:g=[24,a-4097,11];break;case 8192>=a:g=[25,a-6145,11];break;case 12288>=a:g=[26,a-8193,12];break;case 16384>= +a:g=[27,a-12289,12];break;case 24576>=a:g=[28,a-16385,13];break;case 32768>=a:g=[29,a-24577,13];break;default:l("invalid distance")}f=g;d[e++]=f[0];d[e++]=f[1];d[e++]=f[2];var h,k;h=0;for(k=d.length;h=e;)w[e++]=0;for(e=0;29>=e;)y[e++]=0}w[256]=1;f=0;for(b=a.length;f=b){r&&c(r,-1);e=0;for(g=b-f;eg&&a+ge&&(b=f,e=g);if(258===g)break}return new ta(e,a-b)} +function qa(d,a){var c=d.length,f=new ha(572),b=new (E?Uint8Array:Array)(c),e,g,h,k,n;if(!E)for(k=0;k2*b[m-1]+e[m]&&(b[m]=2*b[m-1]+e[m]),h[m]=Array(b[m]),k[m]=Array(b[m]);for(p=0;pd[p]?(h[m][s]=w,k[m][s]=a,y+=2):(h[m][s]=d[p],k[m][s]=p,++p);n[m]=0;1===e[m]&&f(m)}return g} +function sa(d){var a=new (E?Uint16Array:Array)(d.length),c=[],f=[],b=0,e,g,h,k;e=0;for(g=d.length;e>>=1}return a};function T(d,a){this.l=[];this.m=32768;this.e=this.g=this.c=this.q=0;this.input=E?new Uint8Array(d):d;this.s=!1;this.n=za;this.B=!1;if(a||!(a={}))a.index&&(this.c=a.index),a.bufferSize&&(this.m=a.bufferSize),a.bufferType&&(this.n=a.bufferType),a.resize&&(this.B=a.resize);switch(this.n){case Aa:this.b=32768;this.a=new (E?Uint8Array:Array)(32768+this.m+258);break;case za:this.b=0;this.a=new (E?Uint8Array:Array)(this.m);this.f=this.J;this.t=this.H;this.o=this.I;break;default:l(Error("invalid inflate mode"))}} +var Aa=0,za=1,Ba={D:Aa,C:za}; +T.prototype.p=function(){for(;!this.s;){var d=Y(this,3);d&1&&(this.s=x);d>>>=1;switch(d){case 0:var a=this.input,c=this.c,f=this.a,b=this.b,e=u,g=u,h=u,k=f.length,n=u;this.e=this.g=0;e=a[c++];e===u&&l(Error("invalid uncompressed block header: LEN (first byte)"));g=e;e=a[c++];e===u&&l(Error("invalid uncompressed block header: LEN (second byte)"));g|=e<<8;e=a[c++];e===u&&l(Error("invalid uncompressed block header: NLEN (first byte)"));h=e;e=a[c++];e===u&&l(Error("invalid uncompressed block header: NLEN (second byte)"));h|= +e<<8;g===~h&&l(Error("invalid uncompressed block header: length verify"));c+g>a.length&&l(Error("input buffer is broken"));switch(this.n){case Aa:for(;b+g>f.length;){n=k-b;g-=n;if(E)f.set(a.subarray(c,c+n),b),b+=n,c+=n;else for(;n--;)f[b++]=a[c++];this.b=b;f=this.f();b=this.b}break;case za:for(;b+g>f.length;)f=this.f({v:2});break;default:l(Error("invalid inflate mode"))}if(E)f.set(a.subarray(c,c+g),b),b+=g,c+=g;else for(;g--;)f[b++]=a[c++];this.c=c;this.b=b;this.a=f;break;case 1:this.o(Ca,Ra);break; +case 2:Sa(this);break;default:l(Error("unknown BTYPE: "+d))}}return this.t()}; +var Ta=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],Ua=E?new Uint16Array(Ta):Ta,Va=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],Wa=E?new Uint16Array(Va):Va,Xa=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],Ya=E?new Uint8Array(Xa):Xa,Za=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],$a=E?new Uint16Array(Za):Za,ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10, +10,11,11,12,12,13,13],bb=E?new Uint8Array(ab):ab,cb=new (E?Uint8Array:Array)(288),Z,db;Z=0;for(db=cb.length;Z=Z?8:255>=Z?9:279>=Z?7:8;var Ca=R(cb),eb=new (E?Uint8Array:Array)(30),fb,hb;fb=0;for(hb=eb.length;fb>>a;d.e=f-a;d.c=e;return g} +function ib(d,a){for(var c=d.g,f=d.e,b=d.input,e=d.c,g=a[0],h=a[1],k,n,q;f>>16;d.g=c>>q;d.e=f-q;d.c=e;return n&65535} +function Sa(d){function a(a,b,c){var d,f,e,g;for(g=0;ge)f>=b&&(this.b=f,c=this.f(),f=this.b),c[f++]=e;else{g=e-257;k=Wa[g];0=b&&(this.b=f,c=this.f(),f=this.b);for(;k--;)c[f]=c[f++-h]}for(;8<=this.e;)this.e-=8,this.c--;this.b=f}; +T.prototype.I=function(d,a){var c=this.a,f=this.b;this.u=d;for(var b=c.length,e,g,h,k;256!==(e=ib(this,d));)if(256>e)f>=b&&(c=this.f(),b=c.length),c[f++]=e;else{g=e-257;k=Wa[g];0b&&(c=this.f(),b=c.length);for(;k--;)c[f]=c[f++-h]}for(;8<=this.e;)this.e-=8,this.c--;this.b=f}; +T.prototype.f=function(){var d=new (E?Uint8Array:Array)(this.b-32768),a=this.b-32768,c,f,b=this.a;if(E)d.set(b.subarray(32768,d.length));else{c=0;for(f=d.length;cc;++c)b[c]=b[a+c];this.b=32768;return b}; +T.prototype.J=function(d){var a,c=this.input.length/this.c+1|0,f,b,e,g=this.input,h=this.a;d&&("number"===typeof d.v&&(c=d.v),"number"===typeof d.F&&(c+=d.F));2>c?(f=(g.length-this.c)/this.u[2],e=258*(f/2)|0,b=ea&&(this.a.length=a),d=this.a);return this.buffer=d};function jb(d){if("string"===typeof d){var a=d.split(""),c,f;c=0;for(f=a.length;c>>0;d=a}for(var b=1,e=0,g=d.length,h,k=0;0>>0};function kb(d,a){var c,f;this.input=d;this.c=0;if(a||!(a={}))a.index&&(this.c=a.index),a.verify&&(this.M=a.verify);c=d[this.c++];f=d[this.c++];switch(c&15){case lb:this.method=lb;break;default:l(Error("unsupported compression method"))}0!==((c<<8)+f)%31&&l(Error("invalid fcheck flag:"+((c<<8)+f)%31));f&32&&l(Error("fdict flag is not supported"));this.A=new T(d,{index:this.c,bufferSize:a.bufferSize,bufferType:a.bufferType,resize:a.resize})} +kb.prototype.p=function(){var d=this.input,a,c;a=this.A.p();this.c=this.A.c;this.M&&(c=(d[this.c++]<<24|d[this.c++]<<16|d[this.c++]<<8|d[this.c++])>>>0,c!==jb(a)&&l(Error("invalid adler-32 checksum")));return a};var lb=8;function mb(d,a){this.input=d;this.a=new (E?Uint8Array:Array)(32768);this.h=$.k;var c={},f;if((a||!(a={}))&&"number"===typeof a.compressionType)this.h=a.compressionType;for(f in a)c[f]=a[f];c.outputBuffer=this.a;this.z=new ia(this.input,c)}var $=na; +mb.prototype.j=function(){var d,a,c,f,b,e,g,h=0;g=this.a;d=lb;switch(d){case lb:a=Math.LOG2E*Math.log(32768)-8;break;default:l(Error("invalid compression method"))}c=a<<4|d;g[h++]=c;switch(d){case lb:switch(this.h){case $.NONE:b=0;break;case $.r:b=1;break;case $.k:b=2;break;default:l(Error("unsupported compression type"))}break;default:l(Error("invalid compression method"))}f=b<<6|0;g[h++]=f|31-(256*c+f)%31;e=jb(this.input);this.z.b=h;g=this.z.j();h=g.length;E&&(g=new Uint8Array(g.buffer),g.length<= +h+4&&(this.a=new Uint8Array(g.length+4),this.a.set(g),g=this.a),g=g.subarray(0,h+4));g[h++]=e>>24&255;g[h++]=e>>16&255;g[h++]=e>>8&255;g[h++]=e&255;return g};function nb(d,a){var c,f,b,e;if(Object.keys)c=Object.keys(a);else for(f in c=[],b=0,a)c[b++]=f;b=0;for(e=c.length;b>> 2] >>> (24 - (i % 4) * 8)) & 0xff; + u8[i] = b; + } + return u8; + } + function toWordArray(u8arr) { + var len = u8arr.length; + var words = []; + for (var i = 0; i < len; i++) { + words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8); + } + return WordArray.create(words, len); + } + + + // UTF8 Text De/Encoders + require('encoding'); + function encode(str) { + return (new TextEncoder('utf-8')).encode(str); + } + function decode(u8arr) { + return (new TextDecoder('utf-8')).decode(u8arr); + } + + function CryptoContext(context, encrypt, decrypt) { this.context = context; this.encrypt = encrypt; @@ -43,13 +78,34 @@ define(function(require) { // prompting the user to enter it when the file system is being opened. function CryptoAdapter(passphrase, provider) { this.provider = provider; - this.encrypt = function(plain) { - return CryptoJS[encryptionType].encrypt(plain, passphrase) - .toString(); + + // Cache cipher algorithm we'll use in encrypt/decrypt + var cipher = CryptoJS[encryptionType]; + + // To encrypt: + // 1) accept a buffer (Uint8Array) containing binary data + // 2) convert the buffer to a CipherJS WordArray + // 3) encrypt the WordArray using the chosen cipher algorithm + passphrase + // 4) convert the resulting ciphertext to a UTF8 encoded Uint8Array and return + this.encrypt = function(buffer) { + var wordArray = toWordArray(buffer); + var encrypted = cipher.encrypt(wordArray, passphrase); + var utf8EncodedBuf = encode(encrypted); + return utf8EncodedBuf; }; - this.decrypt = function(encrypted) { - return CryptoJS[encryptionType].decrypt(encrypted, passphrase) - .toString(CryptoJS.enc.Utf8); + + // To decrypt: + // 1) accept a buffer (Uint8Array) containing a UTF8 encoded Uint8Array + // 2) convert the buffer to string (i.e., the ciphertext we got from encrypting) + // 3) decrypt the ciphertext string + // 4) convert the decrypted cipherParam object to a UTF8 string + // 5) encode the UTF8 string to a Uint8Array buffer and return + this.decrypt = function(buffer) { + var encryptedStr = decode(buffer); + var decrypted = cipher.decrypt(encryptedStr, passphrase); + var decryptedUtf8 = decrypted.toString(CryptoJS.enc.Utf8); + var utf8EncodedBuf = encode(decryptedUtf8); + return utf8EncodedBuf; }; } CryptoAdapter.isSupported = function() { diff --git a/src/adapters/zlib.js b/src/adapters/zlib.js new file mode 100644 index 0000000..e7cfe16 --- /dev/null +++ b/src/adapters/zlib.js @@ -0,0 +1,63 @@ +define(function(require) { + + // Zlib compression, see + // https://github.com/imaya/zlib.js/blob/master/bin/zlib.min.js + require("zlib"); + + var Inflate = Zlib.Inflate; + function inflate(compressed) { + return (new Inflate(compressed)).decompress(); + } + + var Deflate = Zlib.Deflate; + function deflate(buffer) { + return (new Deflate(buffer)).compress(); + } + + function ZlibContext(context) { + this.context = context; + } + ZlibContext.prototype.clear = function(callback) { + this.context.clear(callback); + }; + ZlibContext.prototype.get = function(key, callback) { + this.context.get(key, function(err, result) { + if(err) { + callback(err); + return; + } + // Deal with result being null + if(result) { + result = inflate(result); + } + callback(null, result); + }); + }; + ZlibContext.prototype.put = function(key, value, callback) { + value = deflate(value); + this.context.put(key, value, callback); + }; + ZlibContext.prototype.delete = function(key, callback) { + this.context.delete(key, callback); + }; + + + function ZlibAdapter(provider, inflate, deflate) { + this.provider = provider; + } + ZlibAdapter.isSupported = function() { + return true; + }; + + ZlibAdapter.prototype.open = function(callback) { + this.provider.open(callback); + }; + ZlibAdapter.prototype.getReadOnlyContext = function() { + return new ZlibContext(this.provider.getReadOnlyContext()); + }; + ZlibAdapter.prototype.getReadWriteContext = function() { + return new ZlibContext(this.provider.getReadWriteContext()); + }; + + return ZlibAdapter; +}); diff --git a/tests/spec/adapters/adapters.crypto.spec.js b/tests/spec/adapters/adapters.general.spec.js similarity index 69% rename from tests/spec/adapters/adapters.crypto.spec.js rename to tests/spec/adapters/adapters.general.spec.js index adbcb85..a22272f 100644 --- a/tests/spec/adapters/adapters.crypto.spec.js +++ b/tests/spec/adapters/adapters.general.spec.js @@ -1,20 +1,31 @@ define(["IDBFS"], function(IDBFS) { - // We reuse the same set of tests for all crypto adapters. - // buildTestsFor() creates a set of tests bound to a crypto + // We reuse the same set of tests for all adapters. + // buildTestsFor() creates a set of tests bound to an // adapter, and uses a Memory() provider internally. - function buildTestsFor(adapterName) { - var passphrase = '' + Date.now(); + function buildTestsFor(adapterName, buildAdapter) { + function encode(str) { + // TextEncoder is either native, or shimmed by IDBFS + return (new TextEncoder("utf-8")).encode(str); + } + + // Make some string + binary buffer versions of things we'll need + var valueStr = "value", valueBuffer = encode(valueStr); + var value1Str = "value1", value1Buffer = encode(value1Str); + var value2Str = "value2", value2Buffer = encode(value2Str); function createProvider() { var memoryProvider = new IDBFS.FileSystem.providers.Memory(); - return new IDBFS.FileSystem.adapters[adapterName](passphrase, memoryProvider); + return buildAdapter(memoryProvider); } describe("IDBFS.FileSystem.adapters." + adapterName, function() { it("is supported -- if it isn't, none of these tests can run.", function() { - expect(IDBFS.FileSystem.adapters[adapterName].isSupported()).toEqual(true); + // Allow for combined adapters (e.g., 'AES+Zlib') joined by '+' + adapterName.split('+').forEach(function(name) { + expect(IDBFS.FileSystem.adapters[name].isSupported()).toEqual(true); + }); }); it("has open, getReadOnlyContext, and getReadWriteContext instance methods", function() { @@ -47,7 +58,7 @@ define(["IDBFS"], function(IDBFS) { }); }); - describe("Read/Write operations on a Memory provider with an " + adapterName + "adapter", function() { + describe("Read/Write operations on a Memory provider with an " + adapterName + " adapter", function() { it("should allow put() and get()", function() { var complete = false; var _error, _result; @@ -57,7 +68,7 @@ define(["IDBFS"], function(IDBFS) { _error = err; var context = provider.getReadWriteContext(); - context.put("key", "value", function(err, result) { + context.put("key", valueBuffer, function(err, result) { _error = _error || err; context.get("key", function(err, result) { _error = _error || err; @@ -74,7 +85,7 @@ define(["IDBFS"], function(IDBFS) { runs(function() { expect(_error).toEqual(null); - expect(_result).toEqual("value"); + expect(_result).toEqual(valueBuffer); }); }); @@ -87,7 +98,7 @@ define(["IDBFS"], function(IDBFS) { _error = err; var context = provider.getReadWriteContext(); - context.put("key", "value", function(err, result) { + context.put("key", valueBuffer, function(err, result) { _error = _error || err; context.delete("key", function(err, result) { _error = _error || err; @@ -120,9 +131,9 @@ define(["IDBFS"], function(IDBFS) { _error = err; var context = provider.getReadWriteContext(); - context.put("key1", "value1", function(err, result) { + context.put("key1", value1Buffer, function(err, result) { _error = _error || err; - context.put("key2", "value2", function(err, result) { + context.put("key2", value2Buffer, function(err, result) { _error = _error || err; context.clear(function(err) { @@ -164,7 +175,7 @@ define(["IDBFS"], function(IDBFS) { _error = err; var context = provider.getReadOnlyContext(); - context.put("key1", "value1", function(err, result) { + context.put("key1", value1Buffer, function(err, result) { _error = _error || err; _result = result; @@ -185,8 +196,32 @@ define(["IDBFS"], function(IDBFS) { }); } - buildTestsFor('AES'); - buildTestsFor('TripleDES'); - buildTestsFor('Rabbit'); + + // Encryption + buildTestsFor('AES', function buildAdapter(provider) { + var passphrase = '' + Date.now(); + return new IDBFS.FileSystem.adapters.AES(passphrase, provider); + }); + buildTestsFor('TripleDES', function buildAdapter(provider) { + var passphrase = '' + Date.now(); + return new IDBFS.FileSystem.adapters.TripleDES(passphrase, provider); + }); + buildTestsFor('Rabbit', function buildAdapter(provider) { + var passphrase = '' + Date.now(); + return new IDBFS.FileSystem.adapters.Rabbit(passphrase, provider); + }); + + // Compression + buildTestsFor('Zlib', function buildAdapter(provider) { + return new IDBFS.FileSystem.adapters.Zlib(provider); + }); + + // AES + Zlib together + buildTestsFor('AES+Zlib', function buildAdapter(provider) { + var passphrase = '' + Date.now(); + var zlib = new IDBFS.FileSystem.adapters.Zlib(provider); + var AESwithZlib = new IDBFS.FileSystem.adapters.AES(passphrase, zlib); + return AESwithZlib; + }); }); diff --git a/tests/spec/adapters/adapters.spec.js b/tests/spec/adapters/adapters.spec.js index 9d55a59..c3b223a 100644 --- a/tests/spec/adapters/adapters.spec.js +++ b/tests/spec/adapters/adapters.spec.js @@ -19,5 +19,13 @@ define(["IDBFS"], function(IDBFS) { it("has a default Encryption constructor", function() { expect(typeof IDBFS.FileSystem.adapters.Encryption).toEqual('function'); }); + + it("has a Zlib constructor", function() { + expect(typeof IDBFS.FileSystem.adapters.Zlib).toEqual('function'); + }); + + it("has a default Compression constructor", function() { + expect(typeof IDBFS.FileSystem.adapters.Compression).toEqual('function'); + }); }); }); diff --git a/tests/test-manifest.js b/tests/test-manifest.js index 698fe61..0f30a63 100644 --- a/tests/test-manifest.js +++ b/tests/test-manifest.js @@ -36,7 +36,7 @@ define([ // IDBFS.FileSystem.adapters.* "spec/adapters/adapters.spec", - "spec/adapters/adapters.crypto.spec", + "spec/adapters/adapters.general.spec", // Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test) "spec/node-js/simple/test-fs-mkdir",