-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tests completed with a mock into what would be react native's AsyncStorage and community implementations of it (original package has been deprecated). Works in real browser tests. BREAKING CHANGE: 🧨 All functions return promises now. Options are different. Package renamed from better-web-storage.
- Loading branch information
Showing
6 changed files
with
330 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,18 @@ | ||
{ | ||
"name": "bws2", | ||
"name": "appstorage", | ||
"version": "1.0.0", | ||
"main": "cjs.js", | ||
"module": "es.js", | ||
"cdn": "browser.js", | ||
"types": "types.d.ts", | ||
"license": "MIT", | ||
"private": true, | ||
"author": { | ||
"name": "Danilo Alonso", | ||
"email": "[email protected]", | ||
"url": "https://github.com/damusix" | ||
}, | ||
"repository": "[email protected]:damusix/better-web-storage.git", | ||
"scripts": { | ||
"build": "sh scripts/build.sh", | ||
"test": "mocha -r esm -r ./test/_setup.js -r ts-node/register 'test/**/*.ts'", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,273 @@ | ||
import { AppStorage, StorageImplementation } from '../build'; | ||
import { expect } from 'chai'; | ||
|
||
const clearStores = () => { | ||
|
||
describe('SimpleAppStorage', function () { | ||
window.localStorage.clear() | ||
window.sessionStorage.clear() | ||
} | ||
|
||
it('should create an instance', function () { | ||
const defineProps = (obj: any, props: Record<string, any>) => { | ||
|
||
const entries = Object.entries(props); | ||
|
||
Object.defineProperties(obj, entries.reduce((o, [key, val]) => { | ||
|
||
return { | ||
...o, | ||
[key]: { | ||
configurable: false, | ||
enumerable: false, | ||
value: val, | ||
|
||
} | ||
}; | ||
}, {})); | ||
} | ||
|
||
const fakeStorage = { | ||
clear() { | ||
|
||
for (const key of Object.keys(asyncStorage)) { | ||
|
||
delete asyncStorage[key]; | ||
} | ||
|
||
return Promise.resolve(); | ||
}, | ||
getItem(key: string) { | ||
|
||
return Promise.resolve(asyncStorage[key]) | ||
}, | ||
removeItem(key: string) { | ||
|
||
delete asyncStorage[key]; | ||
|
||
return Promise.resolve(); | ||
}, | ||
setItem: (key: string, value: string) => { | ||
|
||
asyncStorage[key] = value; | ||
|
||
return Promise.resolve(); | ||
}, | ||
multiGet: (keys: string[]) => { | ||
|
||
return Object.entries(asyncStorage).filter( | ||
([key]) => keys.includes(key) | ||
); | ||
} | ||
}; | ||
|
||
const asyncStorage = {} as StorageImplementation; | ||
|
||
defineProps(asyncStorage, fakeStorage) | ||
Object.defineProperty(asyncStorage, 'length', { | ||
|
||
configurable: false, | ||
enumerable: false, | ||
get() { | ||
|
||
return Object.keys(asyncStorage).length; | ||
} | ||
}) | ||
|
||
|
||
describe('AppStorage', () => { | ||
|
||
before(clearStores) | ||
after(clearStores) | ||
|
||
it('References localStorage or sessionStorage', () => { | ||
|
||
const ls = new AppStorage(window.localStorage); | ||
const ss = new AppStorage(window.sessionStorage); | ||
|
||
expect(ls.storage).to.equal(window.localStorage); | ||
expect(ss.storage).to.equal(window.sessionStorage); | ||
}); | ||
|
||
// Test both local storage and session storage | ||
const testSuites: [string, StorageImplementation][] = [ | ||
// name storage reference | ||
['LocalStorage', window.localStorage], | ||
['SessionStorage', window.sessionStorage], | ||
['AsyncStorage', asyncStorage] | ||
]; | ||
|
||
testSuites.forEach(([name, storage]) => { | ||
|
||
const store: { | ||
store: AppStorage; | ||
prefixed?: AppStorage; | ||
} = { | ||
store: new AppStorage(storage) | ||
}; | ||
|
||
it(`${name}: Sets json stringified keys`, async () => { | ||
|
||
|
||
const val = [1,2,3,4]; | ||
await store.store.set('test', val); | ||
|
||
expect(storage.test).to.equal(JSON.stringify(val)); | ||
}); | ||
|
||
it(`${name}: Sets an entire object as keys`, async () => { | ||
|
||
const val = { | ||
one: 'two', | ||
buckle: 'myshow' | ||
}; | ||
|
||
await store.store.set(val); | ||
|
||
expect(storage.one).to.equal(JSON.stringify(val.one)); | ||
expect(storage.buckle).to.equal(JSON.stringify(val.buckle)); | ||
}); | ||
|
||
it(`${name}: Gets and parses a single key`, async () => { | ||
|
||
expect(await store.store.get('test')).to.include.members([1,2,3,4]) | ||
}); | ||
|
||
it(`${name}: Gets and returns an object of key values when passed multiple values`, async () => { | ||
|
||
const vals = await store.store.get(['one', 'buckle']); | ||
expect(vals).to.include({ | ||
one: 'two', | ||
buckle: 'myshow' | ||
}); | ||
}); | ||
|
||
it(`${name}: Checks to see if has keys`, async () => { | ||
|
||
expect(await store.store.has('test')).to.equal(true); | ||
expect(await store.store.has(['test', 'one', 'buckle'])).to.have.members([true, true, true]); | ||
expect(await store.store.has(['test', 'one', 'buckle', 'three'])).to.have.members([true, true, true, false]); | ||
}); | ||
|
||
it(`${name}: Removes item from store`, async () => { | ||
|
||
await store.store.rm('test'); | ||
expect(await store.store.get('test')).to.not.exist; | ||
}); | ||
|
||
it(`${name}: Retrieves storage length`, async () => { | ||
|
||
await store.store.set('test1', true); | ||
await store.store.set('test2', true); | ||
await store.store.set('test3', true); | ||
|
||
expect(store.store.length).to.equal(5); | ||
}); | ||
|
||
it(`${name}: Retrieves a copy of entire store`, async () => { | ||
|
||
expect(await store.store.get()).to.include({ | ||
one: 'two', | ||
buckle: 'myshow', | ||
test1: true, | ||
test2: true, | ||
test3: true | ||
}); | ||
}); | ||
|
||
it(`${name}: Clears storage`, async () => { | ||
|
||
await store.store.clear(); | ||
expect(store.store.length).to.equal(0); | ||
expect(storage.length).to.equal(0); | ||
}) | ||
|
||
it(`${name}: Sets keys using a prefix`, async () => { | ||
|
||
store.prefixed = new AppStorage(storage, 'test'); | ||
const store2 = new AppStorage(storage, 'test2'); | ||
|
||
await store.prefixed!.set('test', true); | ||
await store2.set('test', false); | ||
|
||
expect(storage.test).to.not.exist; | ||
expect(storage['test:test']).to.exist; | ||
expect(storage['test2:test']).to.exist; | ||
expect(storage['test:test']).to.equal('true'); | ||
expect(storage['test2:test']).to.equal('false'); | ||
}); | ||
|
||
it(`${name}: Retrieves prefixed storage length accurately`, async () => { | ||
|
||
await store.prefixed!.set('test1', true); | ||
await store.prefixed!.set('test2', true); | ||
await store.prefixed!.set('test3', true); | ||
expect(await storage.length).to.equal(5); | ||
expect(await store.prefixed!.length).to.equal(4); | ||
}); | ||
|
||
it(`${name}: Retrieves all prefixed items`, async () => { | ||
|
||
expect(await store.prefixed!.get()).to.include({ | ||
test: true, | ||
test1: true, | ||
test2: true, | ||
test3: true | ||
}); | ||
}) | ||
|
||
it(`${name}: Clears all prefixed items`, async () => { | ||
|
||
await store.prefixed!.clear(); | ||
expect(store.prefixed!.length).to.equal(0); | ||
expect(storage.length).to.equal(1); | ||
}); | ||
|
||
it(`${name}: Object assigns to a current object in store`, async () => { | ||
|
||
const cur = { a: true }; | ||
const assign = { b: false }; | ||
await store.store.set('cur', cur); | ||
|
||
expect(await store.store.get('cur')).to.not.include(assign); | ||
|
||
await store.store.assign('cur', assign); | ||
|
||
expect(await store.store.get('cur')).to.include(cur); | ||
expect(await store.store.get('cur')).to.include(assign); | ||
}); | ||
|
||
it(`${name}: Does not allow assigns if value not an object`, async () => { | ||
|
||
const cur = { a: true }; | ||
const assign = 'wat'; | ||
await store.store.set('cur', cur); | ||
|
||
try { | ||
|
||
await store.store.assign('cur', assign as any); | ||
expect(await store.store.get('cur')).to.not.include(assign); | ||
} | ||
catch (e) { | ||
|
||
expect(e).to.be.an('error'); | ||
} | ||
}); | ||
|
||
it(`${name}: Does not allow assigns if item not an object`, async () => { | ||
|
||
const cur = 'wat'; | ||
const assign = { a: true }; | ||
await store.store.set('cur', cur); | ||
|
||
try { | ||
|
||
await store.store.assign('cur', assign); | ||
expect(await store.store.get('cur')).to.not.include(assign); | ||
} | ||
catch (e) { | ||
|
||
expect(e).to.be.an('error'); | ||
} | ||
}); | ||
}); | ||
}); | ||
|
||
}); |
Oops, something went wrong.