Skip to content

Commit 7940193

Browse files
committed
saving
1 parent 580a0b6 commit 7940193

File tree

8 files changed

+122
-49
lines changed

8 files changed

+122
-49
lines changed

lib/index.react_native.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,15 @@ const createInstance = function(config: Config): Client | null {
114114
eventProcessor,
115115
logger,
116116
errorHandler,
117-
datafileManager: config.sdkKey
118-
? createHttpPollingDatafileManager(
119-
config.sdkKey,
120-
logger,
121-
config.datafile,
122-
config.datafileOptions,
123-
config.persistentCacheProvider,
124-
)
125-
: undefined,
117+
// datafileManager: config.sdkKey
118+
// ? createHttpPollingDatafileManager(
119+
// config.sdkKey,
120+
// logger,
121+
// config.datafile,
122+
// config.datafileOptions,
123+
// config.persistentCacheProvider,
124+
// )
125+
// : undefined,
126126
notificationCenter,
127127
isValidInstance: isValidInstance,
128128
odpManager: odpExplicitlyOff ? undefined

lib/project_config/project_config_manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ProjectConfig, tryCreatingProjectConfig } from '../core/project_config';
2-
import { Comsumer, Fn } from '../utils/type';
2+
import { Consumer, Fn } from '../utils/type';
33
import { RequestHandler } from '../utils/http_request_handler/http';
44
import { Ticker, ExponentialBackoff, IntervalTicker } from '../utils/ticker/ticker';
55
import { LoggerFacade } from '../modules/logging';
@@ -10,7 +10,7 @@ export interface ProjectConfigManager extends Service {
1010
setLogger(logger: LoggerFacade): void;
1111
getConfig(): ProjectConfig | undefined;
1212
getOptimizelyConfig(): OptimizelyConfig | undefined;
13-
onUpdate(listener: Comsumer<ProjectConfig>): Fn;
13+
onUpdate(listener: Consumer<ProjectConfig>): Fn;
1414
}
1515

1616
export type DatafileOptions = {

lib/project_config/static_project_config_manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { EventEmitter } from '../utils/event_emitter/event_emitter';
55
import { ResolvablePromise, resolvablePromise } from '../utils/promise/resolvablePromise';
66
import { ProjectConfig, tryCreatingProjectConfig, toDatafile } from '../core/project_config';
77
import { createOptimizelyConfig } from '../core/optimizely_config';
8-
import { Comsumer, Fn } from '../utils/type';
8+
import { Consumer, Fn } from '../utils/type';
99
import { OptimizelyConfig } from '../shared_types';
1010

1111
export class StaticProjectConfigManager implements ProjectConfigManager {
@@ -74,7 +74,7 @@ export class StaticProjectConfigManager implements ProjectConfigManager {
7474
return this.config;
7575
}
7676

77-
onUpdate(listener: Comsumer<ProjectConfig>): Fn {
77+
onUpdate(listener: Consumer<ProjectConfig>): Fn {
7878
return this.eventEmitter.on('update', listener);
7979
}
8080

lib/utils/event_emitter/event_emitter.spec.ts

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { it, vi, expect } from 'vitest';
22

33
import { EventEmitter } from './event_emitter';
4+
import exp from 'constants';
45

5-
it('should call all registered listeners on emit event', () => {
6-
const emitter = new EventEmitter<{ foo: number, bar: string }>();
6+
it('should call all registered listeners correctly on emit event', () => {
7+
const emitter = new EventEmitter<{ foo: number, bar: string, baz: boolean}>();
78
const fooListener1 = vi.fn();
89
const fooListener2 = vi.fn();
910

@@ -16,19 +17,48 @@ it('should call all registered listeners on emit event', () => {
1617
emitter.on('bar', barListener1);
1718
emitter.on('bar', barListener2);
1819

20+
const bazListener = vi.fn();
21+
emitter.on('baz', bazListener);
22+
1923
emitter.emit('foo', 1);
24+
emitter.emit('bar', 'hello');
25+
26+
expect(fooListener1).toHaveBeenCalledOnce();
2027
expect(fooListener1).toHaveBeenCalledWith(1);
28+
expect(fooListener2).toHaveBeenCalledOnce();
2129
expect(fooListener2).toHaveBeenCalledWith(1);
22-
})
30+
expect(barListener1).toHaveBeenCalledOnce();
31+
expect(barListener1).toHaveBeenCalledWith('hello');
32+
expect(barListener2).toHaveBeenCalledOnce();
33+
expect(barListener2).toHaveBeenCalledWith('hello');
2334

24-
// it('should remove listeners', () => {
25-
// const emitter = new EventEmitter();
26-
// const cb = jest.fn();
27-
// emitter.on('foo', cb);
28-
// emitter.off('foo', cb);
29-
// emitter.emit('foo');
30-
// expect(cb).not.toHaveBeenCalled();
31-
// })
35+
expect(bazListener).not.toHaveBeenCalled();
36+
});
37+
38+
it('should remove listeners correctly', () => {
39+
const emitter = new EventEmitter<{ foo: number, bar: string }>();
40+
const fooListener1 = vi.fn();
41+
const fooListener2 = vi.fn();
42+
43+
const dispose = emitter.on('foo', fooListener1);
44+
emitter.on('foo', fooListener2);
45+
46+
const barListener1 = vi.fn();
47+
const barListener2 = vi.fn();
48+
49+
emitter.on('bar', barListener1);
50+
emitter.on('bar', barListener2);
51+
52+
dispose();
53+
emitter.emit('foo', 1);
54+
emitter.emit('bar', 'hello');
55+
56+
expect(fooListener1).not.toHaveBeenCalled();
57+
expect(fooListener2).toHaveBeenCalledOnce();
58+
expect(fooListener2).toHaveBeenCalledWith(1);
59+
expect(barListener1).toHaveBeenCalledWith('hello');
60+
expect(barListener1).toHaveBeenCalledWith('hello');
61+
})
3262

3363
// it('should remove all listeners', () => {
3464
// const emitter = new EventEmitter();

lib/utils/event_emitter/event_emitter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ export class EventEmitter<T> {
3030
if (!this.listeners[eventName]) {
3131
this.listeners[eventName] = new Map();
3232
}
33+
3334
const curId = this.id++;
34-
this.listeners[eventName].set(curId, listener);
35+
this.listeners[eventName]?.set(curId, listener);
3536
return () => {
3637
this.listeners[eventName]?.delete(curId);
3738
}

lib/utils/type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import exp from "constants";
33
export type Fn = () => void;
44
export type AsyncTransformer<A, B> = (arg: A) => Promise<B>;
55

6-
export type Comsumer<T> = (arg: T) => void;
6+
export type Consumer<T> = (arg: T) => void;
77
export type AsyncComsumer<T> = (arg: T) => Promise<void>;
88

99
export type Producer<T> = () => T;

tests/index.react_native.spec.ts

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import packageJSON from '../package.json';
2424
import optimizelyFactory from '../lib/index.react_native';
2525
import configValidator from '../lib/utils/config_validator';
2626
import eventProcessorConfigValidator from '../lib/utils/event_processor_config_validator';
27+
import { getMockProjectConfigManager } from './mock/project_config_manager';
28+
import { createProjectConfig } from '../lib/core/project_config';
2729

2830
vi.mock('@react-native-community/netinfo');
2931
vi.mock('react-native-get-random-values')
@@ -71,27 +73,21 @@ describe('javascript-sdk/react-native', () => {
7173
it('should not throw if the provided config is not valid', () => {
7274
expect(function() {
7375
const optlyInstance = optimizelyFactory.createInstance({
74-
datafile: {},
76+
projectConfigManager: getMockProjectConfigManager(),
7577
// @ts-ignore
7678
logger: silentLogger,
7779
});
78-
// Invalid datafile causes onReady Promise rejection - catch this error
79-
// @ts-ignore
80-
optlyInstance.onReady().catch(function() {});
8180
}).not.toThrow();
8281
});
8382

8483
it('should create an instance of optimizely', () => {
8584
const optlyInstance = optimizelyFactory.createInstance({
86-
datafile: {},
85+
projectConfigManager: getMockProjectConfigManager(),
8786
errorHandler: fakeErrorHandler,
8887
eventDispatcher: fakeEventDispatcher,
8988
// @ts-ignore
9089
logger: silentLogger,
9190
});
92-
// Invalid datafile causes onReady Promise rejection - catch this error
93-
// @ts-ignore
94-
optlyInstance.onReady().catch(function() {});
9591

9692
expect(optlyInstance).toBeInstanceOf(Optimizely);
9793
// @ts-ignore
@@ -100,15 +96,13 @@ describe('javascript-sdk/react-native', () => {
10096

10197
it('should set the React Native JS client engine and javascript SDK version', () => {
10298
const optlyInstance = optimizelyFactory.createInstance({
103-
datafile: {},
99+
projectConfigManager: getMockProjectConfigManager(),
104100
errorHandler: fakeErrorHandler,
105101
eventDispatcher: fakeEventDispatcher,
106102
// @ts-ignore
107103
logger: silentLogger,
108104
});
109-
// Invalid datafile causes onReady Promise rejection - catch this error
110-
// @ts-ignore
111-
optlyInstance.onReady().catch(function() {});
105+
112106
// @ts-ignore
113107
expect('react-native-js-sdk').toEqual(optlyInstance.clientEngine);
114108
// @ts-ignore
@@ -118,15 +112,12 @@ describe('javascript-sdk/react-native', () => {
118112
it('should allow passing of "react-sdk" as the clientEngine and convert it to "react-native-sdk"', () => {
119113
const optlyInstance = optimizelyFactory.createInstance({
120114
clientEngine: 'react-sdk',
121-
datafile: {},
115+
projectConfigManager: getMockProjectConfigManager(),
122116
errorHandler: fakeErrorHandler,
123117
eventDispatcher: fakeEventDispatcher,
124118
// @ts-ignore
125119
logger: silentLogger,
126120
});
127-
// Invalid datafile causes onReady Promise rejection - catch this error
128-
// @ts-ignore
129-
optlyInstance.onReady().catch(function() {});
130121
// @ts-ignore
131122
expect('react-native-sdk').toEqual(optlyInstance.clientEngine);
132123
});
@@ -142,7 +133,9 @@ describe('javascript-sdk/react-native', () => {
142133

143134
it('should call logging.setLogLevel', () => {
144135
optimizelyFactory.createInstance({
145-
datafile: testData.getTestProjectConfig(),
136+
projectConfigManager: getMockProjectConfigManager({
137+
initConfig: createProjectConfig(testData.getTestProjectConfig()),
138+
}),
146139
logLevel: optimizelyFactory.enums.LOG_LEVEL.ERROR,
147140
});
148141
expect(logging.setLogLevel).toBeCalledTimes(1);
@@ -162,7 +155,9 @@ describe('javascript-sdk/react-native', () => {
162155
it('should call logging.setLogHandler with the supplied logger', () => {
163156
const fakeLogger = { log: function() {} };
164157
optimizelyFactory.createInstance({
165-
datafile: testData.getTestProjectConfig(),
158+
projectConfigManager: getMockProjectConfigManager({
159+
initConfig: createProjectConfig(testData.getTestProjectConfig()),
160+
}),
166161
// @ts-ignore
167162
logger: fakeLogger,
168163
});
@@ -184,7 +179,9 @@ describe('javascript-sdk/react-native', () => {
184179

185180
it('should use default event flush interval when none is provided', () => {
186181
optimizelyFactory.createInstance({
187-
datafile: testData.getTestProjectConfigWithFeatures(),
182+
projectConfigManager: getMockProjectConfigManager({
183+
initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()),
184+
}),
188185
errorHandler: fakeErrorHandler,
189186
eventDispatcher: fakeEventDispatcher,
190187
// @ts-ignore
@@ -212,7 +209,9 @@ describe('javascript-sdk/react-native', () => {
212209

213210
it('should ignore the event flush interval and use the default instead', () => {
214211
optimizelyFactory.createInstance({
215-
datafile: testData.getTestProjectConfigWithFeatures(),
212+
projectConfigManager: getMockProjectConfigManager({
213+
initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()),
214+
}),
216215
errorHandler: fakeErrorHandler,
217216
eventDispatcher: fakeEventDispatcher,
218217
// @ts-ignore
@@ -242,7 +241,9 @@ describe('javascript-sdk/react-native', () => {
242241

243242
it('should use the provided event flush interval', () => {
244243
optimizelyFactory.createInstance({
245-
datafile: testData.getTestProjectConfigWithFeatures(),
244+
projectConfigManager: getMockProjectConfigManager({
245+
initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()),
246+
}),
246247
errorHandler: fakeErrorHandler,
247248
eventDispatcher: fakeEventDispatcher,
248249
// @ts-ignore
@@ -262,7 +263,9 @@ describe('javascript-sdk/react-native', () => {
262263

263264
it('should use default event batch size when none is provided', () => {
264265
optimizelyFactory.createInstance({
265-
datafile: testData.getTestProjectConfigWithFeatures(),
266+
projectConfigManager: getMockProjectConfigManager({
267+
initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()),
268+
}),
266269
errorHandler: fakeErrorHandler,
267270
eventDispatcher: fakeEventDispatcher,
268271
// @ts-ignore
@@ -319,7 +322,9 @@ describe('javascript-sdk/react-native', () => {
319322

320323
it('should use the provided event batch size', () => {
321324
optimizelyFactory.createInstance({
322-
datafile: testData.getTestProjectConfigWithFeatures(),
325+
projectConfigManager: getMockProjectConfigManager({
326+
initConfig: createProjectConfig(testData.getTestProjectConfigWithFeatures()),
327+
}),
323328
errorHandler: fakeErrorHandler,
324329
eventDispatcher: fakeEventDispatcher,
325330
// @ts-ignore

tests/mock/project_config_manager.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { vi, vitest } from 'vitest';
2+
3+
import { ProjectConfigManager } from "../../lib/project_config/project_config_manager";
4+
import { ProjectConfig } from '../../lib/core/project_config';
5+
import { Consumer } from '../../lib/utils/type';
6+
7+
type MockOpt = {
8+
initConfig?: ProjectConfig,
9+
onRunning?: Promise<void>,
10+
onTerminated?: Promise<void>,
11+
}
12+
13+
export const getMockProjectConfigManager = (opt: MockOpt = {}): ProjectConfigManager => {
14+
return {
15+
config: opt.initConfig,
16+
start: vi.fn(),
17+
onRunning: () => opt.onRunning || Promise.resolve(),
18+
stop: vi.fn(),
19+
onTerminated: () => opt.onTerminated || Promise.resolve(),
20+
getConfig: function() {
21+
return this.config;
22+
},
23+
setConfig: function(config: ProjectConfig) {
24+
this.config = config;
25+
},
26+
onUpdate: function(listener: Consumer<ProjectConfig>) {
27+
if (this.listeners === undefined) {
28+
this.listeners = [];
29+
}
30+
this.listeners.push(listener);
31+
return () => {};
32+
},
33+
pushUpdate: function(config: ProjectConfig) {
34+
this.listeners.forEach((listener: any) => listener(config));
35+
}
36+
} as any as ProjectConfigManager;
37+
};

0 commit comments

Comments
 (0)