diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 86a9b49..fda9ec3 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -23,23 +23,12 @@ let gaToSplit = GoogleAnalyticsToSplit; gaToSplit = GoogleAnalyticsToSplitFull; let splitToGa = SplitToGoogleAnalytics; splitToGa = SplitToGoogleAnalyticsFull; let pluggableStorage = PluggableStorage; pluggableStorage = PluggableStorageFull; -let stringPromise: Promise; -let splitNamesPromise: Promise; -let splitViewPromise: Promise; -let splitViewsPromise: Promise; -let treatmentsPromise: Promise; -let treatmentWithConfigPromise: Promise; -let treatmentsWithConfigPromise: Promise; -let trackPromise: Promise; - /**** Interfaces ****/ // Facade return interface -let AsyncSDK: SplitIO.IAsyncSDK; let SDK: SplitIO.ISDK; +let AsyncSDK: SplitIO.IAsyncSDK; // Settings interfaces -// let nodeSettings: SplitIO.INodeSettings; -// let asyncSettings: SplitIO.INodeAsyncSettings; let browserSettings: SplitIO.IBrowserSettings; let browserAsyncSettings: SplitIO.IBrowserAsyncSettings; // Client & Manager APIs @@ -47,123 +36,9 @@ let client: SplitIO.IClient; let manager: SplitIO.IManager; let asyncClient: SplitIO.IAsyncClient; let asyncManager: SplitIO.IAsyncManager; -// Utility interfaces -let impressionListener: SplitIO.IImpressionListener; - -/**** Custom Types ****/ - -// Common -let treatment: SplitIO.Treatment = 'on'; -let treatmentWithConfig: SplitIO.TreatmentWithConfig = { - treatment: 'control', - config: null -}; -treatmentWithConfig = { treatment: 'off', config: '{}' }; -let asyncTreatment: SplitIO.AsyncTreatment = stringPromise; -let asyncTreatmentWithConfig: SplitIO.AsyncTreatmentWithConfig = treatmentWithConfigPromise; -let tracked: boolean; -let treatmentsMap: SplitIO.Treatments = { - feature1: 'on', - feature2: 'control' -}; -let treatmentsWithConfigMap: SplitIO.TreatmentsWithConfig = { - feature1: { treatment: 'control', config: null }, - feature2: { treatment: 'off', config: '{"color":"blue"}' } -}; -let treatments: SplitIO.Treatments = treatmentsMap; -let treatmentsWithConfig: SplitIO.TreatmentsWithConfig = treatmentsWithConfigMap; -let asyncTreatments: SplitIO.AsyncTreatments = treatmentsPromise; -let asyncTreatmentsWithConfig: SplitIO.AsyncTreatmentsWithConfig = treatmentsWithConfigPromise; -let splitEvent: SplitIO.Event; -const attributes: SplitIO.Attributes = { - attr1: 1, - attr2: '2', - attr3: Date.now(), - attr4: ['str1', 2], - attr5: ['str1', 'str2'], - attr6: [1, 2], - attr7: true -}; -// const splitKeyObj: SplitIO.SplitKeyObject = { -// matchingKey: 'matchingKey', -// bucketingKey: 'bucketingKey' -// }; -let splitKey: SplitIO.SplitKey; -// Mocks -// let mockedFeaturesPath: SplitIO.MockedFeaturesFilePath; -let mockedFeaturesMap: SplitIO.MockedFeaturesMap; -// Split Data -let splitView: SplitIO.SplitView; -let splitViews: SplitIO.SplitViews; -let splitNames: SplitIO.SplitNames; -let splitNamesAsync: SplitIO.SplitNamesAsync; -let splitViewAsync: SplitIO.SplitViewAsync; -let splitViewsAsync: SplitIO.SplitViewsAsync; -// Impression data -let impressionData: SplitIO.ImpressionData; -// Storages -let syncStorage: SplitIO.StorageSync; -let syncStorageFactory: SplitIO.StorageSyncFactory = InLocalStorage(); -let localStorageOptions: SplitIO.InLocalStorageOptions = { - prefix: 'PREFIX' -}; -syncStorageFactory = InLocalStorage(localStorageOptions); -// mockedFeaturesPath = 'path/to/file'; -mockedFeaturesMap = { - feature1: 'treatment', - feature2: { treatment: 'treatment2', config: "{ 'prop': 'value'}" }, - feature3: { treatment: 'treatment3', config: null } -}; - -// Treatment can be the string or the promise which will resolve to treatment string -treatment = 'some treatment'; // Sync case -asyncTreatment = stringPromise; // Async case - -// Treatments can be the object or the promise which will resolve to treatments object -treatments = { - someFeature: 'treatment' -}; // Sync -asyncTreatments = treatmentsPromise; // Async +/**** Tests for SDK interface ****/ -// SplitViews can be the SplitViewData or the promise which will resolve to SplitViewData obj -splitView = { - name: 'asd', - killed: false, - trafficType: 'user', - treatments: ['on', 'off'], - changeNumber: 18294, - configs: { - off: '{"dimensions":"{\"height\":20,\"width\":40}"}' - } -}; -splitViews = [splitView]; - -splitViewAsync = splitViewPromise; -splitNamesAsync = splitNamesPromise; -splitViewsAsync = splitViewsPromise; - -// Split key can be a string -splitKey = 'someKey'; -// splitKey = splitKeyObj; - -/**** Tests for ISDK interface ****/ - -// // For node with sync storage -// nodeSettings = { -// core: { -// authorizationKey: 'key' -// } -// }; -// // For node with async storage -// asyncSettings = { -// core: { -// authorizationKey: 'key' -// }, -// storage: { -// type: 'REDIS' -// } -// }; // For browser browserSettings = { core: { @@ -184,283 +59,41 @@ browserAsyncSettings = { }; // With sync settings should return ISDK, if settings have async storage it should return IAsyncSDK SDK = SplitFactory(browserSettings); +SDK = SplitFactoryFull(browserSettings); AsyncSDK = SplitFactory(browserAsyncSettings); -// SDK = SplitFactory(nodeSettings); -// AsyncSDK = SplitFactory(asyncSettings); - -// The settings values the SDK expose. -const instantiatedSettingsCore: { - authorizationKey: string, - key?: SplitIO.SplitKey, - trafficType?: string, - labelsEnabled: boolean, - IPAddressesEnabled?: boolean -} = SDK.settings.core; -// const instantiatedSettingsMode: ('standalone' | 'consumer') = SDK.settings.mode; -const instantiatedSettingsScheduler: { [key: string]: number } = SDK.settings.scheduler; -const instantiatedSettingsStartup: { [key: string]: number } = SDK.settings.startup; -const instantiatedStorage: SplitIO.StorageSync = SDK.settings.storage; -const instantiatedSettingsUrls: { [key: string]: string } = SDK.settings.urls; -const instantiatedSettingsVersion: string = SDK.settings.version; -let instantiatedSettingsFeatures = SDK.settings.features as SplitIO.MockedFeaturesMap; -// // We should be able to write on features prop. The rest are readonly props. -instantiatedSettingsFeatures.something = 'something'; -SDK.settings.features = { 'split_x': 'on' }; +AsyncSDK = SplitFactoryFull(browserAsyncSettings); // Client and Manager client = SDK.client(); -client = SDK.client('a customer key'); -// client = SDK.client('a customer key', 'a traffic type'); // Not valid in Browser JS SDK +client = SDK.client('a customer key'); // `client = SDK.client('a customer key', 'a traffic type');` Not valid in Browser JS SDK manager = SDK.manager(); -// // Today async clients are only possible on Node. Shared client creation not available here. + asyncClient = AsyncSDK.client(); +asyncClient = AsyncSDK.client('a customer key'); asyncManager = AsyncSDK.manager(); -// Logger -SDK.Logger.enable(); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.DEBUG); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.INFO); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.WARN); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.ERROR); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.NONE); -SDK.Logger.disable(); - -AsyncSDK.Logger.enable(); -AsyncSDK.Logger.setLogLevel(AsyncSDK.Logger.LogLevel.DEBUG); -AsyncSDK.Logger.setLogLevel(AsyncSDK.Logger.LogLevel.INFO); -AsyncSDK.Logger.setLogLevel(AsyncSDK.Logger.LogLevel.WARN); -AsyncSDK.Logger.setLogLevel(AsyncSDK.Logger.LogLevel.ERROR); -AsyncSDK.Logger.setLogLevel(AsyncSDK.Logger.LogLevel.NONE); -AsyncSDK.Logger.disable(); - -/**** Tests for IClient interface ****/ - -// Events constants we get -const eventConsts: { [key: string]: SplitIO.Event } = client.Event; -splitEvent = client.Event.SDK_READY; -splitEvent = client.Event.SDK_READY_FROM_CACHE; -splitEvent = client.Event.SDK_READY_TIMED_OUT; -splitEvent = client.Event.SDK_UPDATE; - -// Client implements methods from IEventEmitter that is a subset of NodeJS.Events. Testing a few. -client = client.on(splitEvent, () => { }); -const a: boolean = client.emit(splitEvent); -client = client.removeAllListeners(splitEvent); -client = client.removeAllListeners(); -// const b: number = client.listenerCount(splitEvent); // Not part of IEventEmitter - -// Ready and destroy -const readyPromise: Promise = client.ready(); -const destroyPromise: Promise = client.destroy(); - -// We can call getTreatment without a key. -// treatment = client.getTreatment(splitKey, 'mySplit'); -treatment = client.getTreatment('mySplit'); -// Attributes parameter is optional. -// treatment = client.getTreatment(splitKey, 'mySplit', attributes); -treatment = client.getTreatment('mySplit', attributes); - -// We can call getTreatments without a key. -// treatments = client.getTreatments(splitKey, ['mySplit']); -treatments = client.getTreatments(['mySplit']); -// Attributes parameter is optional. -// treatments = client.getTreatments(splitKey, ['mySplit'], attributes); -treatments = client.getTreatments(['mySplit'], attributes); - -// We can call getTreatmentWithConfig without a key. -// treatmentWithConfig = client.getTreatmentWithConfig(splitKey, 'mySplit'); -treatmentWithConfig = client.getTreatmentWithConfig('mySplit'); -// Attributes parameter is optional. -// treatmentWithConfig = client.getTreatmentWithConfig(splitKey, 'mySplit', attributes); -treatmentWithConfig = client.getTreatmentWithConfig('mySplit', attributes); - -// We can call getTreatmentsWithConfig without a key. -// treatmentsWithConfig = client.getTreatmentsWithConfig(splitKey, ['mySplit']); -treatmentsWithConfig = client.getTreatmentsWithConfig(['mySplit']); -// Attributes parameter is optional. -// treatmentsWithConfig = client.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); -treatmentsWithConfig = client.getTreatmentsWithConfig(['mySplit'], attributes); - -// We can call track without a key. Traffic type can also be binded to the client. -// tracked = client.track(splitKey, 'myTrafficType', 'myEventType'); // all params -tracked = client.track('myTrafficType', 'myEventType'); // key binded, tt provided. -// tracked = client.track('myEventType'); // key and tt binded. Not valid in Browser JS SDK -// Value parameter is optional on all signatures. -// tracked = client.track(splitKey, 'myTrafficType', 'myEventType', 10); -tracked = client.track('myTrafficType', 'myEventType', 10); -// tracked = client.track('myEventType', 10); // Not valid in Browser JS SDK -// Properties parameter is optional on all signatures. -// tracked = client.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: false, prop4: null }); -tracked = client.track('myTrafficType', 'myEventType', null, { prop1: 1, prop2: '2', prop3: false, prop4: null }); -// tracked = client.track('myEventType', undefined, { prop1: 1, prop2: '2', prop3: false, prop4: null }); // Not valid in Browser JS SDK - -/*** Repeating tests for Async Client ***/ - -// Events constants we get (same as for sync client, just for interface checking) -const eventConstsAsync: { [key: string]: SplitIO.Event } = asyncClient.Event; -splitEvent = asyncClient.Event.SDK_READY; -splitEvent = asyncClient.Event.SDK_READY_FROM_CACHE; -splitEvent = asyncClient.Event.SDK_READY_TIMED_OUT; -splitEvent = asyncClient.Event.SDK_UPDATE; - -// Client implements methods from NodeJS.Events. (same as for sync client, just for interface checking) -asyncClient = asyncClient.on(splitEvent, () => { }); -const a1: boolean = asyncClient.emit(splitEvent); -asyncClient = asyncClient.removeAllListeners(splitEvent); -asyncClient = asyncClient.removeAllListeners(); -// const b1: number = asyncClient.listenerCount(splitEvent); // Not part of IEventEmitter - -// Ready and destroy (same as for sync client, just for interface checking) -const readyPromise1: Promise = asyncClient.ready(); -asyncClient.destroy(); - -// We can call getTreatment -asyncTreatment = asyncClient.getTreatment('mySplit'); -// asyncTreatment = asyncClient.getTreatment(splitKey, 'mySplit'); -// Attributes parameter is optional -asyncTreatment = asyncClient.getTreatment('mySplit', attributes); -// asyncTreatment = asyncClient.getTreatment(splitKey, 'mySplit', attributes); +/**** Tests for Client and Manager interfaces ****/ -// We can call getTreatments -asyncTreatments = asyncClient.getTreatments(['mySplit']); -// asyncTreatments = asyncClient.getTreatments(splitKey, ['mySplit']); -// Attributes parameter is optional -asyncTreatments = asyncClient.getTreatments(['mySplit'], attributes); -// asyncTreatments = asyncClient.getTreatments(splitKey, ['mySplit'], attributes); - -// We can call getTreatmentWithConfig -asyncTreatmentWithConfig = asyncClient.getTreatmentWithConfig('mySplit'); -// asyncTreatmentWithConfig = asyncClient.getTreatmentWithConfig(splitKey, 'mySplit'); -// Attributes parameter is optional -asyncTreatmentWithConfig = asyncClient.getTreatmentWithConfig('mySplit', attributes); -// asyncTreatmentWithConfig = asyncClient.getTreatmentWithConfig(splitKey, 'mySplit', attributes); - -// We can call getTreatments but always with a key. -asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfig(['mySplit']); -// asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfig(splitKey, ['mySplit']); -// Attributes parameter is optional -asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfig(['mySplit'], attributes); -// asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); - -// We can call track. -trackPromise = asyncClient.track('myTrafficType', 'myEventType'); // all required params -// trackPromise = asyncClient.track(splitKey, 'myTrafficType', 'myEventType'); // all required params -// Value parameter is optional. -trackPromise = asyncClient.track('myTrafficType', 'myEventType', 10); -// trackPromise = asyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10); -// Properties parameter is optional -trackPromise = asyncClient.track('myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: true, prop4: null }); -// trackPromise = asyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: true, prop4: null }); - -/**** Tests for IManager interface ****/ - -splitNames = manager.names(); -splitView = manager.split('mySplit'); -splitViews = manager.splits(); - -// Manager implements ready promise. -const managerReadyPromise: Promise = manager.ready(); - -// Manager implements methods from NodeJS.Events. Testing a few. -manager = manager.on(splitEvent, () => { }); -const aa: boolean = manager.emit(splitEvent); -manager = manager.removeAllListeners(splitEvent); -manager = manager.removeAllListeners(); -// const bb: number = manager.listenerCount(splitEvent); // Not part of IEventEmitter - -// manager exposes Event constants too -const managerEventConsts: { [key: string]: SplitIO.Event } = manager.Event; -splitEvent = manager.Event.SDK_READY; -splitEvent = manager.Event.SDK_READY_FROM_CACHE; -splitEvent = manager.Event.SDK_READY_TIMED_OUT; -splitEvent = manager.Event.SDK_UPDATE; - -/*** Repeating tests for Async Manager ***/ - -splitNamesAsync = asyncManager.names(); -splitViewAsync = asyncManager.split('mySplit'); -splitViewsAsync = asyncManager.splits(); - -// asyncManager implements ready promise. -const asyncManagerReadyPromise: Promise = asyncManager.ready(); - -// asyncManager implements methods from NodeJS.Events. Testing a few. -asyncManager = asyncManager.on(splitEvent, () => { }); -const aaa: boolean = asyncManager.emit(splitEvent); -asyncManager = asyncManager.removeAllListeners(splitEvent); -asyncManager = asyncManager.removeAllListeners(); -// const bbb: number = asyncManager.listenerCount(splitEvent); // Not part of IEventEmitter - -// asyncManager exposes Event constants too -const asyncManagerEventConsts: { [key: string]: SplitIO.Event } = asyncManager.Event; -splitEvent = asyncManager.Event.SDK_READY; -splitEvent = asyncManager.Event.SDK_READY_FROM_CACHE; -splitEvent = asyncManager.Event.SDK_READY_TIMED_OUT; -splitEvent = asyncManager.Event.SDK_UPDATE; - -/*** Tests for IImpressionListener interface ***/ -class MyImprListener implements SplitIO.IImpressionListener { - logImpression(data: SplitIO.ImpressionData) { - impressionData = data; - } -} - -const MyImprListenerMap: SplitIO.IImpressionListener = { - logImpression: (data: SplitIO.ImpressionData) => { - impressionData = data; - } -}; - -impressionListener = MyImprListenerMap; -impressionListener = new MyImprListener(); -impressionListener.logImpression(impressionData); - -/**** Tests for attribute binding ****/ -let stored: boolean = client.setAttribute('stringAttribute', 'value'); -stored = client.setAttribute('numberAttribtue', 1); -stored = client.setAttribute('booleanAttribute', true); -stored = client.setAttribute('stringArrayAttribute', ['value1', 'value2']); -stored = client.setAttribute('numberArrayAttribute', [1, 2]); - -let storedAttributeValue: SplitIO.AttributeType = client.getAttribute('stringAttribute'); -storedAttributeValue = client.getAttribute('numberAttribute'); -storedAttributeValue = client.getAttribute('booleanAttribute'); -storedAttributeValue = client.getAttribute('stringArrayAttribute'); -storedAttributeValue = client.getAttribute('numberArrayAttribute'); - -let removed: boolean = client.removeAttribute('numberAttribute'); -removed = client.clearAttributes(); - -let attr: SplitIO.Attributes = { - stringAttribute: 'value', - numberAttribute: 1, - booleanAttribute: true, - stringArrayAttribute: ['value1', 'value2'], - numberArrayAttribute: [1, 2] -}; - -stored = client.setAttributes(attr); -let storedAttr: SplitIO.Attributes = client.getAttributes(); -removed = client.clearAttributes(); - -/**** Tests for user consent API ****/ - -let userConsent: SplitIO.ConsentStatus; -userConsent = SDK.UserConsent.getStatus(); -SDK.UserConsent.setStatus(true); -SDK.UserConsent.setStatus(false); - -userConsent = AsyncSDK.UserConsent.getStatus(); -AsyncSDK.UserConsent.setStatus(true); -AsyncSDK.UserConsent.setStatus(false); - -userConsent = SDK.UserConsent.Status.DECLINED; -userConsent = SDK.UserConsent.Status.GRANTED; -userConsent = AsyncSDK.UserConsent.Status.UNKNOWN; +// Client and manager interfaces implement methods from IEventEmitter that is a subset of NodeJS.EventEmitter. Testing a few. +let splitEvent: SplitIO.Event; +[client, asyncClient, manager, asyncManager].forEach((eventEmitter: SplitIO.IEventEmitter) => { + eventEmitter = eventEmitter.on(splitEvent, () => { }); + const a: boolean = eventEmitter.emit(splitEvent); + eventEmitter = eventEmitter.removeAllListeners(splitEvent); + eventEmitter = eventEmitter.removeAllListeners(); + // const b: number = eventEmitter.listenerCount(splitEvent); // Not part of IEventEmitter +}); /**** Tests for fully crowded settings interfaces ****/ -// Split filters +// Config parameters +let syncStorage: SplitIO.StorageSync; +let syncStorageFactory: SplitIO.StorageSyncFactory = InLocalStorage(); +let localStorageOptions: SplitIO.InLocalStorageOptions = { + prefix: 'PREFIX' +}; +syncStorageFactory = InLocalStorage(localStorageOptions); +let impressionListener: SplitIO.IImpressionListener; let splitFilters: SplitIO.SplitFilter[] = [{ type: 'byName', values: ['my_split_1', 'my_split_1'] }, { type: 'byPrefix', values: ['my_split', 'test_split_'] }] // Browser integrations @@ -488,8 +121,8 @@ let customSplitToGoogleAnalyticsConfig: SplitIO.SplitToGoogleAnalyticsOptions = let fullBrowserSettings: SplitIO.IBrowserSettings = { core: { - authorizationKey: 'asd', - key: 'asd', + authorizationKey: 'api-key', + key: 'some-key', // trafficType: 'myTT', // Not valid in Browser JS SDK labelsEnabled: false }, @@ -517,7 +150,7 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { streaming: 'https://asd.com/streaming', telemetry: 'https://asd.com/telemetry' }, - features: mockedFeaturesMap, + features: { 'feature_1': 'treatment' }, storage: syncStorageFactory, impressionListener: impressionListener, debug: true, @@ -541,8 +174,8 @@ fullBrowserSettings.userConsent = 'UNKNOWN'; let fullBrowserAsyncSettings: SplitIO.IBrowserAsyncSettings = { mode: 'consumer', core: { - authorizationKey: 'asd', - key: 'asd', + authorizationKey: 'api-key', + key: 'some-key', // trafficType: 'myTT', // Not valid in Browser JS SDK labelsEnabled: false }, @@ -591,85 +224,3 @@ fullBrowserSettings.debug = DebugLoggerFull(); fullBrowserSettings.debug = InfoLoggerFull(); fullBrowserSettings.debug = WarnLoggerFull(); fullBrowserSettings.debug = ErrorLoggerFull(); - -// fullBrowserSettings.integrations[0].type = 'GOOGLE_ANALYTICS_TO_SPLIT'; - -// let fullNodeSettings: SplitIO.INodeSettings = { -// core: { -// authorizationKey: 'asd', -// labelsEnabled: false, -// IPAddressesEnabled: false -// }, -// scheduler: { -// featuresRefreshRate: 1, -// impressionsRefreshRate: 1, -// metricsRefreshRate: 1, -// segmentsRefreshRate: 1, -// offlineRefreshRate: 1, -// eventsPushRate: 1, -// eventsQueueSize: 1, -// pushRetryBackoffBase: 1 -// }, -// startup: { -// readyTimeout: 1, -// requestTimeoutBeforeReady: 1, -// retriesOnFailureBeforeReady: 1, -// eventsFirstPushWindow: 1 -// }, -// urls: { -// sdk: 'https://asd.com/sdk', -// events: 'https://asd.com/events', -// auth: 'https://asd.com/auth', -// streaming: 'https://asd.com/streaming' -// }, -// features: mockedFeaturesPath, -// storage: { -// type: 'MEMORY' -// }, -// impressionListener: impressionListener, -// mode: 'standalone', -// debug: false, -// streamingEnabled: false, -// sync: { -// splitFilters: splitFilters, -// impressionsMode: 'OPTIMIZED' -// } -// }; -// fullNodeSettings.storage.type = 'MEMORY'; -// fullNodeSettings.mode = 'consumer'; - -// let fullAsyncSettings: SplitIO.INodeAsyncSettings = { -// core: { -// authorizationKey: 'asd', -// labelsEnabled: false, -// IPAddressesEnabled: false -// }, -// scheduler: { -// featuresRefreshRate: 1, -// impressionsRefreshRate: 1, -// metricsRefreshRate: 1, -// segmentsRefreshRate: 1, -// offlineRefreshRate: 1, -// eventsPushRate: 1, -// eventsQueueSize: 1 -// }, -// startup: { -// readyTimeout: 1, -// requestTimeoutBeforeReady: 1, -// retriesOnFailureBeforeReady: 1 -// }, -// features: mockedFeaturesPath, -// storage: { -// type: 'REDIS', -// options: { -// opt1: 'whatever' -// }, -// prefix: 'PREFIX' -// }, -// impressionListener: impressionListener, -// mode: 'standalone', -// debug: true, -// sync: { -// splitFilters: splitFilters -// } -// };