From c2b735cae38c15d00804141d581b12ba92723a14 Mon Sep 17 00:00:00 2001 From: Greg Poole Date: Wed, 7 Feb 2024 11:48:45 +1100 Subject: [PATCH 1/3] Add failing tests for multiple inits --- tests/index.js | 54 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/tests/index.js b/tests/index.js index 5135ac1..9682972 100644 --- a/tests/index.js +++ b/tests/index.js @@ -100,6 +100,49 @@ describe('node-persist ' + pkg.version + ' tests:', async function() { }); }); + describe('initialisation', function() { + let options = { + dir: randDir(), + // logging: true, + writeQueue: true, + writeQueueWriteOnlyLast: true + }; + + let storage; + beforeEach(async () => { + storage = nodePersist.create(); + }) + + it('should init()', async function() { + await storage.init(options); + assert.equal(storage.options.dir, options.dir); + assert.ok(fs.existsSync(options.dir)); + }); + + it('should initSync()', async function() { + storage.initSync(options); + assert.equal(storage.options.dir, options.dir); + assert.ok(fs.existsSync(options.dir)); + }); + + it('should fail if init() or initAsync() are called more than once per instance', async function() { + await storage.init(options); + + let initError; + try { + await storage.init(options); + } catch(err) { + initError = err + } + + assert.include(initError != null ? initError.message : '', 'node-persist has already been initialised'); + + assert.throws(() => { + storage.initSync(options) + }, 'node-persist has already been initialised', undefined, 'initSync() should throw an error when called after init()'); + }) + }) + describe('operations', function() { let options = { dir: randDir(), @@ -126,17 +169,6 @@ describe('node-persist ' + pkg.version + ' tests:', async function() { let generatedItemsKeys = Object.keys(generatedItems); describe('general items operations', function() { - it('should init()', async function() { - await storage.init(options); - assert.equal(storage.options.dir, options.dir); - assert.ok(fs.existsSync(options.dir)); - }); - - it('should initSync()', function() { - storage.initSync(options); - assert.equal(storage.options.dir, options.dir); - assert.ok(fs.existsSync(options.dir)); - }); it('should setItem()', async function() { await storage.setItem('item1', items.item1); From 78bfd0cb4c60a9acbd3fa7a0834be53699efe2c4 Mon Sep 17 00:00:00 2001 From: Greg Poole Date: Wed, 7 Feb 2024 11:50:26 +1100 Subject: [PATCH 2/3] Add multi-init guard and fix tests that now fail with multi-init check --- src/local-storage.js | 10 ++++++++++ tests/index.js | 9 +++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/local-storage.js b/src/local-storage.js index e296449..3f690e3 100644 --- a/src/local-storage.js +++ b/src/local-storage.js @@ -79,6 +79,11 @@ const LocalStorage = function (options) { LocalStorage.prototype = { init: async function (options) { + if (this.initialised) { + throw new Error("node-persist has already been initialised, did you call init or initSync twice?") + } + this.initialised = true + if (options) { this.setOptions(options); } @@ -92,6 +97,11 @@ LocalStorage.prototype = { }, initSync: function (options) { + if (this.initialised) { + throw new Error("node-persist has already been initialised, did you call init or initSync twice?") + } + this.initialised = true + if (options) { this.setOptions(options); } diff --git a/tests/index.js b/tests/index.js index 9682972..7fcbdaf 100644 --- a/tests/index.js +++ b/tests/index.js @@ -150,7 +150,11 @@ describe('node-persist ' + pkg.version + ' tests:', async function() { writeQueue: true, writeQueueWriteOnlyLast: true }; - let storage = nodePersist.create(); + let storage; + beforeEach(async () => { + storage = nodePersist.create(); + await storage.init(options); + }) let items = { 'item1': 1, @@ -264,9 +268,10 @@ describe('node-persist ' + pkg.version + ' tests:', async function() { let options = { dir: randDir() }; - let storage = nodePersist.create(); + let storage; beforeEach(async function() { + storage = nodePersist.create(); await storage.init(options); await storage.setItem('item1', items.item1); await storage.setItem('item2', items.item2); From d3bc780eeee2972864c6004456a4c8baf74020af Mon Sep 17 00:00:00 2001 From: Greg Poole Date: Wed, 7 Feb 2024 12:34:29 +1100 Subject: [PATCH 3/3] Add guard against reinitialising global instance multiple times --- src/local-storage.js | 4 ++-- src/node-persist.js | 3 +++ tests/index.js | 52 ++++++++++++++++++++++++++++++-------------- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/local-storage.js b/src/local-storage.js index 3f690e3..3c5f0bb 100644 --- a/src/local-storage.js +++ b/src/local-storage.js @@ -80,7 +80,7 @@ LocalStorage.prototype = { init: async function (options) { if (this.initialised) { - throw new Error("node-persist has already been initialised, did you call init or initSync twice?") + throw new Error("LocalStorage has already been initialised, did you call init or initSync twice?") } this.initialised = true @@ -98,7 +98,7 @@ LocalStorage.prototype = { initSync: function (options) { if (this.initialised) { - throw new Error("node-persist has already been initialised, did you call init or initSync twice?") + throw new Error("LocalStorage has already been initialised, did you call init or initSync twice?") } this.initialised = true diff --git a/src/node-persist.js b/src/node-persist.js index 87a8738..31ef536 100644 --- a/src/node-persist.js +++ b/src/node-persist.js @@ -21,6 +21,9 @@ const LocalStorage = require('./local-storage'); * An options hash can be optionally passed. */ nodePersist.init = async function (userOptions) { + if (nodePersist.defaultInstance) { + throw new Error('node-persist has already been initialized') + } const localStorage = nodePersist.defaultInstance = nodePersist.create(userOptions); let ret = await localStorage.init(userOptions); mixin(nodePersist, localStorage, {skip: ['init', 'create']}); diff --git a/tests/index.js b/tests/index.js index 7fcbdaf..506e324 100644 --- a/tests/index.js +++ b/tests/index.js @@ -31,6 +31,39 @@ describe('node-persist ' + pkg.version + ' tests:', async function() { rmdir(TEST_BASE_DIR, done); }); + describe('default instance', function() { + this.beforeEach(() => { + // Reset global state + nodePersist.defaultInstance = null; + }) + + it('should create the default instance of LocalStorage sync and use it', async function() { + await nodePersist.init({dir: randDir()}); + assert.ok(nodePersist.defaultInstance instanceof LocalStorage); + await nodePersist.setItem('item8877', 'hello'); + assert.equal(await nodePersist.getItem('item8877'), 'hello', `write/read didn't work`); + }); + + it('should create a default instance', async function() { + let dir = randDir(); + let options = await nodePersist.init({dir: dir}); + assert.equal(options.dir, dir, `Options don't match`); + }); + + it('should not allow init to be called more than once', async function() { + await nodePersist.init(); + + let initError; + try { + await nodePersist.init(); + } catch(err) { + initError = err + } + + assert.include(initError != null ? initError.message : '', 'node-persist has already been initialized'); + }); + }) + describe('instances', function() { let dir1, dir2, storage1, storage2, storage11, storage22, storageSync; @@ -85,19 +118,6 @@ describe('node-persist ' + pkg.version + ' tests:', async function() { await storageSync.setItem('item9977', 'hello'); assert.equal(await storageSync.getItem('item9977'), 'hello', `write/read didn't work`); }); - - it('should create the default instance of LocalStorage sync and use it', async function() { - await nodePersist.init({dir: randDir()}); - assert.ok(nodePersist.defaultInstance instanceof LocalStorage); - await nodePersist.setItem('item8877', 'hello'); - assert.equal(await nodePersist.getItem('item8877'), 'hello', `write/read didn't work`); - }); - - it('should create a default instance', async function() { - let dir = randDir(); - let options = await nodePersist.init({dir: dir}); - assert.equal(options.dir, dir, `Options don't match`); - }); }); describe('initialisation', function() { @@ -135,12 +155,12 @@ describe('node-persist ' + pkg.version + ' tests:', async function() { initError = err } - assert.include(initError != null ? initError.message : '', 'node-persist has already been initialised'); + assert.include(initError != null ? initError.message : '', 'LocalStorage has already been initialised'); assert.throws(() => { storage.initSync(options) - }, 'node-persist has already been initialised', undefined, 'initSync() should throw an error when called after init()'); - }) + }, 'LocalStorage has already been initialised', undefined, 'initSync() should throw an error when called after init()'); + }); }) describe('operations', function() {