-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8273 from spalger/backport/4.6/smallerState
Backport smaller state representation to 4.6
- Loading branch information
Showing
27 changed files
with
1,554 additions
and
199 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
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 |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import expect from 'expect.js'; | ||
|
||
import StubBrowserStorage from '../stub_browser_storage'; | ||
|
||
describe('StubBrowserStorage', () => { | ||
describe('#getItem() / #setItem()', () => { | ||
it('stores items as strings', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setItem(1, 1); | ||
expect(store.getItem(1)).to.be('1'); | ||
}); | ||
|
||
it('stores keys as strings', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setItem(1, 1); | ||
expect(store.key(0)).to.be('1'); | ||
}); | ||
|
||
it('returns null for missing keys', () => { | ||
const store = new StubBrowserStorage(); | ||
expect(store.getItem('unknown key')).to.be(null); | ||
}); | ||
}); | ||
|
||
describe('#length', () => { | ||
it('reports the number of items stored', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setItem(1, 1); | ||
store.setItem(2, 2); | ||
store.setItem(3, 3); | ||
store.setItem(4, 4); | ||
expect(store).to.have.length(4); | ||
}); | ||
|
||
it('does not trip on items getting reset', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setItem(1, 1); | ||
store.setItem(1, 2); | ||
expect(store).to.have.length(1); | ||
}); | ||
}); | ||
|
||
describe('#key()', () => { | ||
it('returns the key as a specific index', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setItem(1, 2); | ||
expect(store.key(0)).to.be('1'); | ||
expect(store.key(1)).to.be(undefined); | ||
}); | ||
}); | ||
|
||
describe('#setStubbedSizeLimit', () => { | ||
it('allows limiting the storage size', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setStubbedSizeLimit(10); | ||
store.setItem('abc', 'def'); // store size is 6, key.length + val.length | ||
expect(() => { | ||
store.setItem('ghi', 'jkl'); | ||
}).throwError(/quota/); | ||
}); | ||
|
||
it('allows defining the limit as infinity', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setStubbedSizeLimit(Infinity); | ||
store.setItem('abc', 'def'); | ||
store.setItem('ghi', 'jkl'); // unlike the previous test, this doesn't throw | ||
}); | ||
|
||
it('throws an error if the limit is below the current size', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setItem('key', 'val'); | ||
expect(() => { | ||
store.setStubbedSizeLimit(5); | ||
}).throwError(Error); | ||
}); | ||
|
||
it('respects removed items', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setStubbedSizeLimit(10); | ||
store.setItem('abc', 'def'); | ||
store.removeItem('abc'); | ||
store.setItem('ghi', 'jkl'); // unlike the previous test, this doesn't throw | ||
}); | ||
}); | ||
|
||
describe('#getStubbedSizeLimit', () => { | ||
it('returns the size limit', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setStubbedSizeLimit(10); | ||
expect(store.getStubbedSizeLimit()).to.equal(10); | ||
}); | ||
}); | ||
|
||
describe('#getStubbedSize', () => { | ||
it('returns the size', () => { | ||
const store = new StubBrowserStorage(); | ||
store.setItem(1, 1); | ||
expect(store.getStubbedSize()).to.equal(2); | ||
}); | ||
}); | ||
}); |
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 |
---|---|---|
@@ -0,0 +1,109 @@ | ||
export default class StubBrowserStorage { | ||
constructor() { | ||
this._keys = []; | ||
this._values = []; | ||
this._size = 0; | ||
this._sizeLimit = 5000000; // 5mb, minimum browser storage size | ||
} | ||
|
||
// ----------------------------------------------------------------------------------------------- | ||
// Browser-specific methods. | ||
// ----------------------------------------------------------------------------------------------- | ||
|
||
get length() { | ||
return this._keys.length; | ||
} | ||
|
||
key(i) { | ||
return this._keys[i]; | ||
} | ||
|
||
getItem(key) { | ||
key = String(key); | ||
|
||
const i = this._keys.indexOf(key); | ||
if (i === -1) return null; | ||
return this._values[i]; | ||
} | ||
|
||
setItem(key, value) { | ||
key = String(key); | ||
value = String(value); | ||
const sizeOfAddition = this._getSizeOfAddition(key, value); | ||
this._updateSize(sizeOfAddition); | ||
|
||
const i = this._keys.indexOf(key); | ||
if (i === -1) { | ||
this._keys.push(key); | ||
this._values.push(value); | ||
} else { | ||
this._values[i] = value; | ||
} | ||
} | ||
|
||
removeItem(key) { | ||
key = String(key); | ||
const sizeOfRemoval = this._getSizeOfRemoval(key); | ||
this._updateSize(sizeOfRemoval); | ||
|
||
const i = this._keys.indexOf(key); | ||
if (i === -1) return; | ||
this._keys.splice(i, 1); | ||
this._values.splice(i, 1); | ||
} | ||
|
||
// ----------------------------------------------------------------------------------------------- | ||
// Test-specific methods. | ||
// ----------------------------------------------------------------------------------------------- | ||
|
||
getStubbedKeys() { | ||
return this._keys.slice(); | ||
} | ||
|
||
getStubbedValues() { | ||
return this._values.slice(); | ||
} | ||
|
||
setStubbedSizeLimit(sizeLimit) { | ||
// We can't reconcile a size limit with the "stored" items, if the stored items size exceeds it. | ||
if (sizeLimit < this._size) { | ||
throw new Error(`You can't set a size limit smaller than the current size.`); | ||
} | ||
|
||
this._sizeLimit = sizeLimit; | ||
} | ||
|
||
getStubbedSizeLimit() { | ||
return this._sizeLimit; | ||
} | ||
|
||
getStubbedSize() { | ||
return this._size; | ||
} | ||
|
||
_getSizeOfAddition(key, value) { | ||
const i = this._keys.indexOf(key); | ||
if (i === -1) { | ||
return key.length + value.length; | ||
} | ||
// Return difference of what's been stored, and what *will* be stored. | ||
return value.length - this._values[i].length; | ||
} | ||
|
||
_getSizeOfRemoval(key) { | ||
const i = this._keys.indexOf(key); | ||
if (i === -1) { | ||
return 0; | ||
} | ||
// Return negative value. | ||
return -(key.length + this._values[i].length); | ||
} | ||
|
||
_updateSize(delta) { | ||
if (this._size + delta > this._sizeLimit) { | ||
throw new Error('something about quota exceeded, browsers are not consistent here'); | ||
} | ||
|
||
this._size += delta; | ||
} | ||
} |
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 was deleted.
Oops, something went wrong.
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
Oops, something went wrong.