1616
1717import { vi , describe , it , expect , beforeEach } from 'vitest' ;
1818import { DEBUG , INFO , WARN , ERROR , LogLevel } from '@optimizely/optimizely-sdk' ;
19- import type { LoggerConfig , LogHandler } from '@optimizely/optimizely-sdk' ;
20- import { storeLoggerConfig , getLoggerConfig } from './loggerConfigRegistry' ;
19+ import type { LogHandler } from '@optimizely/optimizely-sdk' ;
2120import { createReactLogger } from './ReactLogger' ;
22- import type { ReactLoggerConfig } from './ReactLogger' ;
21+ import type { ReactLogger } from './ReactLogger' ;
2322
2423const mockOpaqueLogger = vi . hoisted ( ( ) => ( { __opaque : true } ) ) ;
2524
@@ -31,66 +30,57 @@ vi.mock('@optimizely/optimizely-sdk', async (importOriginal) => {
3130 } ;
3231} ) ;
3332
34- import { createLogger } from './createLogger' ;
33+ import { createLogger , REACT_LOGGER } from './createLogger' ;
3534
3635describe ( 'createLogger' , ( ) => {
3736 beforeEach ( ( ) => {
3837 vi . clearAllMocks ( ) ;
3938 } ) ;
4039
4140 it ( 'should return the opaque logger from the JS SDK' , ( ) => {
42- const config : LoggerConfig = { level : INFO } ;
43- const result = createLogger ( config ) ;
41+ const result = createLogger ( { level : INFO } ) ;
4442 expect ( result ) . toBe ( mockOpaqueLogger ) ;
4543 } ) ;
4644
47- it ( 'should store the resolved config in the registry ' , ( ) => {
45+ it ( 'should attach a ReactLogger via the REACT_LOGGER symbol ' , ( ) => {
4846 const mockHandler : LogHandler = { log : vi . fn ( ) } ;
49- createLogger ( { level : INFO , logHandler : mockHandler } ) ;
50-
51- const storedConfig = getLoggerConfig ( mockOpaqueLogger ) ;
52- expect ( storedConfig ) . toBeDefined ( ) ;
53- expect ( storedConfig ! . logLevel ) . toBe ( LogLevel . Info ) ;
54- expect ( storedConfig ! . logHandler ) . toBe ( mockHandler ) ;
47+ const result = createLogger ( { level : INFO , logHandler : mockHandler } ) ;
48+
49+ const reactLogger = ( result as Record < symbol , unknown > ) [ REACT_LOGGER ] as ReactLogger ;
50+ expect ( reactLogger ) . toBeDefined ( ) ;
51+ expect ( reactLogger . debug ) . toBeTypeOf ( 'function' ) ;
52+ expect ( reactLogger . info ) . toBeTypeOf ( 'function' ) ;
53+ expect ( reactLogger . warn ) . toBeTypeOf ( 'function' ) ;
54+ expect ( reactLogger . error ) . toBeTypeOf ( 'function' ) ;
5555 } ) ;
5656
57- describe ( 'log level resolution' , ( ) => {
58- it . each ( [
59- { preset : DEBUG , expected : LogLevel . Debug , name : 'DEBUG' } ,
60- { preset : INFO , expected : LogLevel . Info , name : 'INFO' } ,
61- { preset : WARN , expected : LogLevel . Warn , name : 'WARN' } ,
62- { preset : ERROR , expected : LogLevel . Error , name : 'ERROR' } ,
63- ] ) ( 'should resolve $name preset to LogLevel.$name' , ( { preset, expected } ) => {
64- createLogger ( { level : preset } ) ;
65- const storedConfig = getLoggerConfig ( mockOpaqueLogger ) ;
66- expect ( storedConfig ! . logLevel ) . toBe ( expected ) ;
67- } ) ;
68- } ) ;
69- } ) ;
57+ it ( 'should create a ReactLogger that uses the provided logHandler' , ( ) => {
58+ const mockHandler : LogHandler = { log : vi . fn ( ) } ;
59+ const result = createLogger ( { level : INFO , logHandler : mockHandler } ) ;
7060
71- describe ( 'loggerConfigRegistry' , ( ) => {
72- it ( 'should return undefined for unknown logger objects' , ( ) => {
73- expect ( getLoggerConfig ( { } ) ) . toBeUndefined ( ) ;
74- } ) ;
61+ const reactLogger = ( result as Record < symbol , unknown > ) [ REACT_LOGGER ] as ReactLogger ;
62+ reactLogger . info ( 'hello' ) ;
7563
76- it ( 'should store and retrieve config for a given logger' , ( ) => {
77- const logger = { } ;
78- const config : ReactLoggerConfig = { logLevel : LogLevel . Warn } ;
79- storeLoggerConfig ( logger , config ) ;
80- expect ( getLoggerConfig ( logger ) ) . toBe ( config ) ;
64+ expect ( mockHandler . log ) . toHaveBeenCalledWith ( LogLevel . Info , '[OPTIMIZELY - REACT] - INFO hello' ) ;
8165 } ) ;
8266
83- it ( 'should support multiple loggers with different configs' , ( ) => {
84- const logger1 = { } ;
85- const logger2 = { } ;
86- const config1 : ReactLoggerConfig = { logLevel : LogLevel . Debug } ;
87- const config2 : ReactLoggerConfig = { logLevel : LogLevel . Error } ;
88-
89- storeLoggerConfig ( logger1 , config1 ) ;
90- storeLoggerConfig ( logger2 , config2 ) ;
91-
92- expect ( getLoggerConfig ( logger1 ) ) . toBe ( config1 ) ;
93- expect ( getLoggerConfig ( logger2 ) ) . toBe ( config2 ) ;
67+ describe ( 'log level resolution' , ( ) => {
68+ it . each ( [
69+ { preset : DEBUG , expectedCalls : 4 , name : 'DEBUG' } ,
70+ { preset : INFO , expectedCalls : 3 , name : 'INFO' } ,
71+ { preset : WARN , expectedCalls : 2 , name : 'WARN' } ,
72+ { preset : ERROR , expectedCalls : 1 , name : 'ERROR' } ,
73+ ] ) ( 'should resolve $name preset correctly' , ( { preset, expectedCalls } ) => {
74+ const mockHandler : LogHandler = { log : vi . fn ( ) } ;
75+ const result = createLogger ( { level : preset , logHandler : mockHandler } ) ;
76+
77+ const reactLogger = ( result as Record < symbol , unknown > ) [ REACT_LOGGER ] as ReactLogger ;
78+ reactLogger . debug ( 'd' ) ;
79+ reactLogger . info ( 'i' ) ;
80+ reactLogger . warn ( 'w' ) ;
81+ reactLogger . error ( 'e' ) ;
82+ expect ( mockHandler . log ) . toHaveBeenCalledTimes ( expectedCalls ) ;
83+ } ) ;
9484 } ) ;
9585} ) ;
9686
@@ -106,8 +96,8 @@ describe('createReactLogger', () => {
10696 logger . error ( 'should appear' ) ;
10797
10898 expect ( mockHandler . log ) . toHaveBeenCalledTimes ( 2 ) ;
109- expect ( mockHandler . log ) . toHaveBeenCalledWith ( LogLevel . Warn , '[ReactSDK] should appear' ) ;
110- expect ( mockHandler . log ) . toHaveBeenCalledWith ( LogLevel . Error , '[ReactSDK] should appear' ) ;
99+ expect ( mockHandler . log ) . toHaveBeenCalledWith ( LogLevel . Warn , '[OPTIMIZELY - REACT] - WARN should appear' ) ;
100+ expect ( mockHandler . log ) . toHaveBeenCalledWith ( LogLevel . Error , '[OPTIMIZELY - REACT] - ERROR should appear' ) ;
111101 } ) ;
112102
113103 it ( 'should allow all messages when level is Debug' , ( ) => {
@@ -132,7 +122,7 @@ describe('createReactLogger', () => {
132122 logger . error ( 'e' ) ;
133123
134124 expect ( mockHandler . log ) . toHaveBeenCalledTimes ( 1 ) ;
135- expect ( mockHandler . log ) . toHaveBeenCalledWith ( LogLevel . Error , '[ReactSDK] e' ) ;
125+ expect ( mockHandler . log ) . toHaveBeenCalledWith ( LogLevel . Error , '[OPTIMIZELY - REACT] - ERROR e' ) ;
136126 } ) ;
137127 } ) ;
138128
@@ -143,7 +133,7 @@ describe('createReactLogger', () => {
143133
144134 logger . info ( 'hello' ) ;
145135
146- expect ( mockHandler . log ) . toHaveBeenCalledWith ( LogLevel . Info , '[ReactSDK] hello' ) ;
136+ expect ( mockHandler . log ) . toHaveBeenCalledWith ( LogLevel . Info , '[OPTIMIZELY - REACT] - INFO hello' ) ;
147137 } ) ;
148138
149139 it ( 'should use default console handler when logHandler is not provided' , ( ) => {
@@ -152,13 +142,13 @@ describe('createReactLogger', () => {
152142
153143 logger . info ( 'hello' ) ;
154144
155- expect ( consoleSpy ) . toHaveBeenCalledWith ( '[ReactSDK] hello' ) ;
145+ expect ( consoleSpy ) . toHaveBeenCalledWith ( '[OPTIMIZELY - REACT] - INFO hello' ) ;
156146 consoleSpy . mockRestore ( ) ;
157147 } ) ;
158148 } ) ;
159149
160150 describe ( 'message prefix' , ( ) => {
161- it ( 'should prepend [ReactSDK ] to all messages' , ( ) => {
151+ it ( 'should prepend [OPTIMIZELY - REACT ] to all messages' , ( ) => {
162152 const mockHandler : LogHandler = { log : vi . fn ( ) } ;
163153 const logger = createReactLogger ( { logLevel : LogLevel . Debug , logHandler : mockHandler } ) ;
164154
@@ -168,7 +158,7 @@ describe('createReactLogger', () => {
168158 logger . error ( 'test' ) ;
169159
170160 for ( const call of ( mockHandler . log as ReturnType < typeof vi . fn > ) . mock . calls ) {
171- expect ( call [ 1 ] ) . toMatch ( / ^ \[ R e a c t S D K \] / ) ;
161+ expect ( call [ 1 ] ) . toMatch ( / ^ \[ O P T I M I Z E L Y - R E A C T \] - ( D E B U G | I N F O | W A R N | E R R O R ) / ) ;
172162 }
173163 } ) ;
174164 } ) ;
0 commit comments