From b6ab85b4d10076ca51ad989270aa863630c063bc Mon Sep 17 00:00:00 2001 From: Eli Bishop Date: Wed, 16 Jan 2019 11:33:08 -0800 Subject: [PATCH 1/2] add feature store test for prefix option --- package-lock.json | 2 +- test/feature_store_test_base.js | 18 ++++++++++++++++-- test/redis_feature_store-test.js | 8 ++++---- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3b99cfd..b69f93f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ldclient-node", - "version": "5.6.2", + "version": "5.7.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/test/feature_store_test_base.js b/test/feature_store_test_base.js index 911f1da..dd809f0 100644 --- a/test/feature_store_test_base.js +++ b/test/feature_store_test_base.js @@ -6,9 +6,10 @@ const { asyncify } = require('./async_utils'); // caching disabled. // // Parameters: -// - makeStore(): creates an instance of the feature store. +// - makeStore(options): creates an instance of the feature store; add options to the +// configuration, if provided // - clearExistingData(callback): if specified, will be called before each test to clear any -// storage that the store instances may be sharing. +// storage that the store instances may be sharing; this also implies that the feature store // - isCached: true if the instances returned by makeStore() have caching enabled. If // applicable, @@ -97,6 +98,19 @@ function baseFeatureStoreTests(makeStore, clearExistingData, isCached) { testInitStateDetection('can detect if another instance has initialized the store, even with empty data', { features: {} }); + + it('is independent from other instances with different prefixes', async () => { + var flag = { key: 'flag', version: 1 }; + var storeA = makeStore({ prefix: 'a' }); + await asyncify(cb => storeA.init({ features: { flag: flag } }, cb)); + var storeB = makeStore({ prefix: 'b' }); + await asyncify(cb => storeB.init({ features: { } }, cb)); + var storeB1 = makeStore({ prefix: 'b' }); // this ensures we're not just reading cached data + var item = await asyncify(cb => storeB1.get(dataKind.features, 'flag', cb)); + expect(item).toBe(null); + item = await asyncify(cb => storeA.get(dataKind.features, 'flag', cb)); + expect(item).toEqual(flag); + }); } it('gets existing feature', async () => { diff --git a/test/redis_feature_store-test.js b/test/redis_feature_store-test.js index 1ba8837..ed0f4e3 100644 --- a/test/redis_feature_store-test.js +++ b/test/redis_feature_store-test.js @@ -8,12 +8,12 @@ describe('RedisFeatureStore', function() { var extraRedisClient = redis.createClient(redisOpts); - function makeCachedStore() { - return new RedisFeatureStore(redisOpts, 30); + function makeCachedStore(options) { + return new RedisFeatureStore(redisOpts, 30, options && options.prefix); } - function makeUncachedStore() { - return new RedisFeatureStore(redisOpts, 0); + function makeUncachedStore(options) { + return new RedisFeatureStore(redisOpts, 0, options && options.prefix); } function clearExistingData(callback) { From 9b206f95b7d083b362adc0e7d7a6bc3e7b0ced85 Mon Sep 17 00:00:00 2001 From: Eli Bishop Date: Wed, 16 Jan 2019 11:40:14 -0800 Subject: [PATCH 2/2] revise test interface for backward compatibility --- test/feature_store_test_base.js | 35 ++++++++++++++++---------------- test/redis_feature_store-test.js | 14 ++++++++----- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/test/feature_store_test_base.js b/test/feature_store_test_base.js index dd809f0..1afe1dd 100644 --- a/test/feature_store_test_base.js +++ b/test/feature_store_test_base.js @@ -6,14 +6,13 @@ const { asyncify } = require('./async_utils'); // caching disabled. // // Parameters: -// - makeStore(options): creates an instance of the feature store; add options to the -// configuration, if provided +// - makeStore(): creates an instance of the feature store // - clearExistingData(callback): if specified, will be called before each test to clear any // storage that the store instances may be sharing; this also implies that the feature store -// - isCached: true if the instances returned by makeStore() have caching enabled. If -// applicable, +// - isCached: true if the instances returned by makeStore() have caching enabled. +// - makeStoreWithPrefix(prefix): creates an uncached instance of the store with a key prefix -function baseFeatureStoreTests(makeStore, clearExistingData, isCached) { +function baseFeatureStoreTests(makeStore, clearExistingData, isCached, makeStoreWithPrefix) { var feature1 = { key: 'foo', version: 10 @@ -99,18 +98,20 @@ function baseFeatureStoreTests(makeStore, clearExistingData, isCached) { testInitStateDetection('can detect if another instance has initialized the store, even with empty data', { features: {} }); - it('is independent from other instances with different prefixes', async () => { - var flag = { key: 'flag', version: 1 }; - var storeA = makeStore({ prefix: 'a' }); - await asyncify(cb => storeA.init({ features: { flag: flag } }, cb)); - var storeB = makeStore({ prefix: 'b' }); - await asyncify(cb => storeB.init({ features: { } }, cb)); - var storeB1 = makeStore({ prefix: 'b' }); // this ensures we're not just reading cached data - var item = await asyncify(cb => storeB1.get(dataKind.features, 'flag', cb)); - expect(item).toBe(null); - item = await asyncify(cb => storeA.get(dataKind.features, 'flag', cb)); - expect(item).toEqual(flag); - }); + if (makeStoreWithPrefix) { + it('is independent from other instances with different prefixes', async () => { + var flag = { key: 'flag', version: 1 }; + var storeA = makeStoreWithPrefix('a'); + await asyncify(cb => storeA.init({ features: { flag: flag } }, cb)); + var storeB = makeStoreWithPrefix('b'); + await asyncify(cb => storeB.init({ features: { } }, cb)); + var storeB1 = makeStoreWithPrefix('b'); // this ensures we're not just reading cached data + var item = await asyncify(cb => storeB1.get(dataKind.features, 'flag', cb)); + expect(item).toBe(null); + item = await asyncify(cb => storeA.get(dataKind.features, 'flag', cb)); + expect(item).toEqual(flag); + }); + } } it('gets existing feature', async () => { diff --git a/test/redis_feature_store-test.js b/test/redis_feature_store-test.js index ed0f4e3..8c790a6 100644 --- a/test/redis_feature_store-test.js +++ b/test/redis_feature_store-test.js @@ -8,12 +8,16 @@ describe('RedisFeatureStore', function() { var extraRedisClient = redis.createClient(redisOpts); - function makeCachedStore(options) { - return new RedisFeatureStore(redisOpts, 30, options && options.prefix); + function makeCachedStore() { + return new RedisFeatureStore(redisOpts, 30); } - function makeUncachedStore(options) { - return new RedisFeatureStore(redisOpts, 0, options && options.prefix); + function makeUncachedStore() { + return new RedisFeatureStore(redisOpts, 0); + } + + function makeStoreWithPrefix(prefix) { + return new RedisFeatureStore(redisOpts, 0, prefix); } function clearExistingData(callback) { @@ -21,7 +25,7 @@ describe('RedisFeatureStore', function() { } testBase.baseFeatureStoreTests(makeCachedStore, clearExistingData, true); - testBase.baseFeatureStoreTests(makeUncachedStore, clearExistingData, false); + testBase.baseFeatureStoreTests(makeUncachedStore, clearExistingData, false, makeStoreWithPrefix); testBase.concurrentModificationTests(makeUncachedStore, function(hook) {