Skip to content

Commit

Permalink
fix: [capricorn86#1181] Refactor storage mock
Browse files Browse the repository at this point in the history
  • Loading branch information
frankdiwang committed Feb 5, 2024
1 parent 6cbcc10 commit a15cbfd
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 20 deletions.
2 changes: 1 addition & 1 deletion packages/happy-dom/src/event/events/IStorageEventInit.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import IEventInit from '../IEventInit.js';
import Storage from '../../storage/Storage.js';
import { Storage } from '../../storage/Storage.js';

export default interface IStorageEventInit extends IEventInit {
key?: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/happy-dom/src/event/events/StorageEvent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Event from '../Event.js';
import IStorageEventInit from './IStorageEventInit.js';
import Storage from '../../storage/Storage.js';
import { Storage } from '../../storage/Storage.js';

/**
*
Expand Down
6 changes: 4 additions & 2 deletions packages/happy-dom/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ import Range from './range/Range.js';
import ResizeObserver from './resize-observer/ResizeObserver.js';
import Screen from './screen/Screen.js';
import Selection from './selection/Selection.js';
import Storage from './storage/Storage.js';
import { Storage, LocalStorage, SessionStorage } from './storage/Storage.js';
import NodeFilter from './tree-walker/NodeFilter.js';
import NodeIterator from './tree-walker/NodeIterator.js';
import TreeWalker from './tree-walker/TreeWalker.js';
Expand Down Expand Up @@ -432,5 +432,7 @@ export {
Window,
XMLDocument,
XMLParser,
XMLSerializer
XMLSerializer,
LocalStorage,
SessionStorage
};
36 changes: 27 additions & 9 deletions packages/happy-dom/src/storage/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Storage
*/
export default class Storage {
#store: { [k: string]: string } = {};

export class Storage {
/**
*
*/
constructor() {
if (new.target === Storage) {
throw Error('Storage is a base class and cannot be constructed directly.');
}
}
/**
* Returns length.
*
* @returns Length.
*/
public get length(): number {
return Object.keys(this.#store).length;
return Object.keys(this).length;
}

/**
Expand All @@ -22,7 +28,7 @@ export default class Storage {
* @returns Name.
*/
public key(index: number): string {
const name = Object.keys(this.#store)[index];
const name = Object.keys(this)[index];
return name === undefined ? null : name;
}

Expand All @@ -33,7 +39,7 @@ export default class Storage {
* @param item Item.
*/
public setItem(name: string, item: string): void {
this.#store[name] = item;
this[name] = item;
}

/**
Expand All @@ -43,7 +49,7 @@ export default class Storage {
* @returns Item.
*/
public getItem(name: string): string {
return this.#store[name] === undefined ? null : this.#store[name];
return this[name] === undefined ? null : this[name];
}

/**
Expand All @@ -52,13 +58,25 @@ export default class Storage {
* @param name Name.
*/
public removeItem(name: string): void {
delete this.#store[name];
delete this[name];
}

/**
* Clears storage.
*/
public clear(): void {
this.#store = {};
Object.keys(this).forEach((key) => {
delete this[key];
});
}
}

/**
* LocalStorage.
*/
export class LocalStorage extends Storage {}

/**
* SessionStorage.
*/
export class SessionStorage extends Storage {}
6 changes: 3 additions & 3 deletions packages/happy-dom/src/window/BrowserWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ import SubmitEvent from '../event/events/SubmitEvent.js';
import Screen from '../screen/Screen.js';
import IResponse from '../fetch/types/IResponse.js';
import IRequestInit from '../fetch/types/IRequestInit.js';
import Storage from '../storage/Storage.js';
import { Storage, LocalStorage, SessionStorage } from '../storage/Storage.js';
import HTMLCollection from '../nodes/element/HTMLCollection.js';
import HTMLFormControlsCollection from '../nodes/html-form-element/HTMLFormControlsCollection.js';
import NodeList from '../nodes/node/NodeList.js';
Expand Down Expand Up @@ -522,8 +522,8 @@ export default class BrowserWindow extends EventTarget implements IBrowserWindow
this.navigator = new Navigator(this);
this.history = new History();
this.screen = new Screen();
this.sessionStorage = new Storage();
this.localStorage = new Storage();
this.sessionStorage = new SessionStorage();
this.localStorage = new LocalStorage();
this.location = new Location(this.#browserFrame, options?.url ?? 'about:blank');
this.console = browserFrame.page.console;

Expand Down
2 changes: 1 addition & 1 deletion packages/happy-dom/src/window/IBrowserWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ import SubmitEvent from '../event/events/SubmitEvent.js';
import MessageEvent from '../event/events/MessageEvent.js';
import MessagePort from '../event/MessagePort.js';
import Screen from '../screen/Screen.js';
import Storage from '../storage/Storage.js';
import { Storage } from '../storage/Storage.js';
import NodeFilter from '../tree-walker/NodeFilter.js';
import HTMLCollection from '../nodes/element/HTMLCollection.js';
import HTMLFormControlsCollection from '../nodes/html-form-element/HTMLFormControlsCollection.js';
Expand Down
63 changes: 60 additions & 3 deletions packages/happy-dom/test/storage/Storage.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,68 @@
import Storage from '../../src/storage/Storage.js';
import { SessionStorage, Storage, LocalStorage } from '../../src/storage/Storage.js';
import { beforeEach, describe, it, expect } from 'vitest';

describe('Storage', () => {
describe('LocalStorage', () => {
let storage: Storage;

beforeEach(() => {
storage = new Storage();
storage = new LocalStorage();
});

describe('get length()', () => {
it('Returns length.', () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
expect(storage.length).toBe(2);
storage.setItem('key3', 'value3');
expect(storage.length).toBe(3);
});
});

describe('key()', () => {
it('Returns name of the nth name.', () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
expect(storage.key(0)).toBe('key1');
expect(storage.key(1)).toBe('key2');
expect(storage.key(2)).toBe(null);
});
});

describe('getItem()', () => {
it('Returns item.', () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
expect(storage.getItem('key1')).toBe('value1');
expect(storage.getItem('key2')).toBe('value2');
});
});

describe('setItem()', () => {
it('Returns item.', () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
expect(storage.getItem('key1')).toBe('value1');
expect(storage.getItem('key2')).toBe('value2');
});
});

describe('removeItem()', () => {
it('Removes an item.', () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
storage.removeItem('key2');
expect(storage.length).toBe(1);
expect(storage.getItem('key1')).toBe('value1');
expect(storage.getItem('key2')).toBe(null);
});
});
});

describe('SessionStorage', () => {
let storage: Storage;

beforeEach(() => {
storage = new SessionStorage();
});

describe('get length()', () => {
Expand Down

0 comments on commit a15cbfd

Please sign in to comment.