1+ import { BrowserLogger , BrowserPerformanceMonitor , BrowserExecutionTracker } from '../browser' ;
2+
3+ // Mock the performance API
4+ const originalPerformance = global . performance ;
5+ beforeAll ( ( ) => {
6+ // Create a custom performance object with memory property
7+ const mockPerformance = {
8+ now : jest . fn ( ) . mockImplementation ( ( ) => Date . now ( ) ) ,
9+ // Add other required properties from Performance interface
10+ timing : { } as any ,
11+ navigation : { } as any ,
12+ timeOrigin : 0 ,
13+ // Custom property for Chrome's performance.memory
14+ memory : {
15+ usedJSHeapSize : 1000000 ,
16+ totalJSHeapSize : 2000000 ,
17+ jsHeapSizeLimit : 4000000
18+ }
19+ } ;
20+
21+ // @ts -ignore - Ignore type checking for the test mock
22+ global . performance = mockPerformance ;
23+ } ) ;
24+
25+ afterAll ( ( ) => {
26+ global . performance = originalPerformance ;
27+ } ) ;
28+
29+ describe ( 'BrowserLogger' , ( ) => {
30+ let browserLogger : BrowserLogger ;
31+ let consoleInfoSpy : jest . SpyInstance ;
32+ let consoleWarnSpy : jest . SpyInstance ;
33+ let consoleErrorSpy : jest . SpyInstance ;
34+ let consoleDebugSpy : jest . SpyInstance ;
35+ let consoleLogSpy : jest . SpyInstance ;
36+
37+ beforeEach ( ( ) => {
38+ browserLogger = new BrowserLogger ( ) ;
39+
40+ // Spy on console methods
41+ consoleInfoSpy = jest . spyOn ( console , 'info' ) . mockImplementation ( ) ;
42+ consoleWarnSpy = jest . spyOn ( console , 'warn' ) . mockImplementation ( ) ;
43+ consoleErrorSpy = jest . spyOn ( console , 'error' ) . mockImplementation ( ) ;
44+ consoleDebugSpy = jest . spyOn ( console , 'debug' ) . mockImplementation ( ) ;
45+ consoleLogSpy = jest . spyOn ( console , 'log' ) . mockImplementation ( ) ;
46+ } ) ;
47+
48+ afterEach ( ( ) => {
49+ consoleInfoSpy . mockRestore ( ) ;
50+ consoleWarnSpy . mockRestore ( ) ;
51+ consoleErrorSpy . mockRestore ( ) ;
52+ consoleDebugSpy . mockRestore ( ) ;
53+ consoleLogSpy . mockRestore ( ) ;
54+ } ) ;
55+
56+ test ( 'info method should log a message' , ( ) => {
57+ browserLogger . info ( 'Test info message' ) ;
58+ expect ( consoleInfoSpy ) . toHaveBeenCalledWith ( 'Test info message' , [ ] ) ;
59+ } ) ;
60+
61+ test ( 'warn method should log a warning message' , ( ) => {
62+ browserLogger . warn ( 'Test warning message' ) ;
63+ expect ( consoleWarnSpy ) . toHaveBeenCalledWith ( 'Test warning message' , [ ] ) ;
64+ } ) ;
65+
66+ test ( 'error method should log an error message' , ( ) => {
67+ browserLogger . error ( 'Test error message' ) ;
68+ expect ( consoleErrorSpy ) . toHaveBeenCalledWith ( 'Test error message' , [ ] ) ;
69+ } ) ;
70+
71+ test ( 'debug method should log a debug message' , ( ) => {
72+ browserLogger . debug ( 'Test debug message' ) ;
73+ expect ( consoleDebugSpy ) . toHaveBeenCalledWith ( 'Test debug message' , [ ] ) ;
74+ } ) ;
75+
76+ test ( 'debug messages should be suppressed in production mode' , ( ) => {
77+ browserLogger . setMode ( 'prod' ) ;
78+ browserLogger . debug ( 'This should not be logged' ) ;
79+ expect ( consoleDebugSpy ) . not . toHaveBeenCalled ( ) ;
80+ } ) ;
81+
82+ test ( 'track should return the result of the tracked function' , ( ) => {
83+ const result = browserLogger . track ( ( ) => 'test-result' ) ;
84+ expect ( result ) . toBe ( 'test-result' ) ;
85+ expect ( consoleLogSpy ) . toHaveBeenCalled ( ) ;
86+ } ) ;
87+
88+ test ( 'setMode and getMode should work correctly' , ( ) => {
89+ expect ( browserLogger . getMode ( ) ) . toBe ( 'dev' ) ;
90+ browserLogger . setMode ( 'staging' ) ;
91+ expect ( browserLogger . getMode ( ) ) . toBe ( 'staging' ) ;
92+ browserLogger . setMode ( 'prod' ) ;
93+ expect ( browserLogger . getMode ( ) ) . toBe ( 'prod' ) ;
94+ } ) ;
95+ } ) ;
96+
97+ describe ( 'BrowserPerformanceMonitor' , ( ) => {
98+ let performanceMonitor : BrowserPerformanceMonitor ;
99+
100+ beforeEach ( ( ) => {
101+ performanceMonitor = new BrowserPerformanceMonitor ( { defaultThreshold : 100 } ) ;
102+ } ) ;
103+
104+ test ( 'startTimer and endTimer should measure duration' , ( ) => {
105+ const id = performanceMonitor . startTimer ( 'test-timer' ) ;
106+ const duration = performanceMonitor . endTimer ( id ) ;
107+ expect ( duration ) . toBeGreaterThanOrEqual ( 0 ) ;
108+ } ) ;
109+
110+ test ( 'isBottleneck should return true for durations above threshold' , ( ) => {
111+ expect ( performanceMonitor . isBottleneck ( 150 ) ) . toBe ( true ) ;
112+ expect ( performanceMonitor . isBottleneck ( 50 ) ) . toBe ( false ) ;
113+ } ) ;
114+
115+ test ( 'getMemoryUsage should return memory usage information' , ( ) => {
116+ const memoryUsage = performanceMonitor . getMemoryUsage ( ) ;
117+ expect ( memoryUsage ) . toHaveProperty ( 'heapUsed' ) ;
118+ expect ( memoryUsage ) . toHaveProperty ( 'heapTotal' ) ;
119+ expect ( memoryUsage . heapUsed ) . toBe ( 1000000 ) ;
120+ expect ( memoryUsage . heapTotal ) . toBe ( 2000000 ) ;
121+ } ) ;
122+ } ) ;
123+
124+ describe ( 'BrowserExecutionTracker' , ( ) => {
125+ let executionTracker : BrowserExecutionTracker ;
126+
127+ beforeEach ( ( ) => {
128+ executionTracker = new BrowserExecutionTracker ( { defaultThreshold : 100 } ) ;
129+ } ) ;
130+
131+ test ( 'track should return the result of the tracked function' , ( ) => {
132+ const result = executionTracker . track ( ( ) => 'test-result' ) ;
133+ expect ( result ) . toBe ( 'test-result' ) ;
134+ } ) ;
135+
136+ test ( 'track should record execution data' , ( ) => {
137+ executionTracker . track ( ( ) => { } , { label : 'testFunction' } ) ;
138+
139+ const flowChart = executionTracker . generateFlowChart ( ) ;
140+ expect ( flowChart ) . toContain ( 'testFunction' ) ;
141+ expect ( flowChart ) . toContain ( 'Execution Flow' ) ;
142+ } ) ;
143+
144+ test ( 'getCallStack should return the current call stack' , ( ) => {
145+ executionTracker . track ( ( ) => {
146+ const callStack = executionTracker . getCallStack ( ) ;
147+ expect ( callStack . length ) . toBe ( 1 ) ;
148+ expect ( callStack [ 0 ] ) . toBe ( 'testFunction' ) ;
149+ } , { label : 'testFunction' } ) ;
150+ } ) ;
151+
152+ test ( 'clear should reset execution data' , ( ) => {
153+ executionTracker . track ( ( ) => { } , { label : 'testFunction' } ) ;
154+
155+ let flowChart = executionTracker . generateFlowChart ( ) ;
156+ expect ( flowChart ) . toContain ( 'testFunction' ) ;
157+
158+ executionTracker . clear ( ) ;
159+
160+ flowChart = executionTracker . generateFlowChart ( ) ;
161+ expect ( flowChart ) . not . toContain ( 'testFunction' ) ;
162+ } ) ;
163+ } ) ;
0 commit comments