@wutiange/log-listener-plugin 2.0.1-alpha.3 → 2.0.1-alpha.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,150 +1,150 @@
1
- import Server from '../Server';
2
- import { sleep } from '../utils';
3
-
4
- // Mock dependencies
5
- jest.mock('../utils', () => {
6
- const actual = jest.requireActual('../utils');
7
- return {
8
- ...actual, // 保留所有真实实现
9
- sleep: jest.fn() // 只模拟 sleep 函数
10
- };
11
- });
12
-
13
-
14
- // Mock require for react-native-zeroconf
15
- jest.mock('react-native-zeroconf', () => undefined, { virtual: true });
16
-
17
- // Mock fetch
18
- global.fetch = jest.fn();
19
-
20
- describe('Server', () => {
21
- let server: Server;
22
-
23
- beforeEach(() => {
24
- // Clear all mocks before each test
25
- jest.clearAllMocks();
26
- (global.fetch as jest.Mock).mockReset();
27
- });
28
-
29
- describe('Constructor and URL Management', () => {
30
- it('should initialize with default values', () => {
31
- server = new Server();
32
- expect(server.getUrls()).toEqual([]);
33
- });
34
-
35
- it('should initialize with custom URL', () => {
36
- server = new Server('localhost:8080');
37
- expect(server.getUrls()).toEqual(['http://localhost:8080']);
38
- });
39
-
40
- it('should handle URLs with and without http prefix', () => {
41
- server = new Server();
42
- server.updateUrl('localhost:8080');
43
- expect(server.getUrls()).toEqual(['http://localhost:8080']);
44
-
45
- server.updateUrl('http://localhost:8080');
46
- expect(server.getUrls()).toEqual(['http://localhost:8080']);
47
- });
48
- });
49
-
50
- describe('ZeroConf Handling', () => {
51
- it('should handle case when zeroconf is not available', () => {
52
- server = new Server();
53
- const mockListener = jest.fn();
54
- server.addUrlsListener(mockListener);
55
-
56
- // Since Zeroconf is not available, the listener should not be called
57
- expect(mockListener).not.toHaveBeenCalled();
58
- });
59
-
60
- // Test with mock Zeroconf implementation
61
- it('should handle case when zeroconf is available', () => {
62
- // Temporarily mock require to return a mock Zeroconf implementation
63
- const mockZeroconfInstance = {
64
- on: jest.fn(),
65
- scan: jest.fn()
66
- };
67
-
68
- jest.doMock('react-native-zeroconf', () => ({
69
- __esModule: true,
70
- default: jest.fn(() => mockZeroconfInstance)
71
- }), { virtual: true });
72
-
73
- server = new Server();
74
- const mockListener = jest.fn();
75
- server.addUrlsListener(mockListener);
76
-
77
- // Verify that Zeroconf methods were not called since module is mocked as undefined
78
- expect(mockListener).not.toHaveBeenCalled();
79
- });
80
- });
81
-
82
- describe('Data Sending', () => {
83
- beforeEach(() => {
84
- server = new Server('localhost:8080');
85
- (global.fetch as jest.Mock).mockImplementation(() =>
86
- Promise.resolve({ ok: true })
87
- );
88
- });
89
-
90
- it('should send log data', async () => {
91
- const testData = { message: 'test log' };
92
- await server.log(testData);
93
-
94
- expect(global.fetch).toHaveBeenCalledWith(
95
- 'http://localhost:8080/log',
96
- expect.objectContaining({
97
- method: 'POST',
98
- headers: {
99
- 'Content-Type': 'application/json;charset=utf-8'
100
- },
101
- body: expect.any(String)
102
- })
103
- );
104
- });
105
-
106
- it('should send network data', async () => {
107
- const testData = { url: 'test.com' };
108
- await server.network(testData);
109
-
110
- expect(global.fetch).toHaveBeenCalledWith(
111
- 'http://localhost:8080/network',
112
- expect.objectContaining({
113
- method: 'POST',
114
- headers: {
115
- 'Content-Type': 'application/json;charset=utf-8'
116
- },
117
- body: expect.any(String)
118
- })
119
- );
120
- });
121
-
122
- it('should handle timeout', async () => {
123
- server.updateTimeout(100);
124
- (sleep as jest.Mock).mockImplementation(() => Promise.reject(new Error('Timeout')));
125
-
126
- const testData = { message: 'test' };
127
- await server.log(testData);
128
-
129
- expect(global.fetch).toHaveBeenCalled();
130
- expect(sleep).toHaveBeenCalledWith(100, true);
131
- });
132
- });
133
-
134
- describe('Base Data Management', () => {
135
- it('should update base data', async () => {
136
- server = new Server('localhost:8080');
137
- const baseData = { userId: '123' };
138
- server.updateBaseData(baseData);
139
-
140
- await server.log({ message: 'test' });
141
-
142
- expect(global.fetch).toHaveBeenCalledWith(
143
- expect.any(String),
144
- expect.objectContaining({
145
- body: expect.stringContaining('"userId":"123"')
146
- })
147
- );
148
- });
149
- });
1
+ import Server from '../Server';
2
+ import { sleep } from '../utils';
3
+
4
+ // Mock dependencies
5
+ jest.mock('../utils', () => {
6
+ const actual = jest.requireActual('../utils');
7
+ return {
8
+ ...actual, // 保留所有真实实现
9
+ sleep: jest.fn() // 只模拟 sleep 函数
10
+ };
11
+ });
12
+
13
+
14
+ // Mock require for react-native-zeroconf
15
+ jest.mock('react-native-zeroconf', () => undefined, { virtual: true });
16
+
17
+ // Mock fetch
18
+ global.fetch = jest.fn();
19
+
20
+ describe('Server', () => {
21
+ let server: Server;
22
+
23
+ beforeEach(() => {
24
+ // Clear all mocks before each test
25
+ jest.clearAllMocks();
26
+ (global.fetch as jest.Mock).mockReset();
27
+ });
28
+
29
+ describe('Constructor and URL Management', () => {
30
+ it('should initialize with default values', () => {
31
+ server = new Server();
32
+ expect(server.getBaseUrlArr()).toEqual(new Set([]));
33
+ });
34
+
35
+ it('should initialize with custom URL', () => {
36
+ server = new Server('localhost:8080');
37
+ expect(server.getBaseUrlArr()).toEqual(new Set(['http://localhost:8080']));
38
+ });
39
+
40
+ it('should handle URLs with and without http prefix', () => {
41
+ server = new Server();
42
+ server.updateUrl('localhost:8080');
43
+ expect(server.getBaseUrlArr()).toEqual(new Set(['http://localhost:8080']));
44
+
45
+ server.updateUrl('http://localhost:8080');
46
+ expect(server.getBaseUrlArr()).toEqual(new Set(['http://localhost:8080']));
47
+ });
48
+ });
49
+
50
+ describe('ZeroConf Handling', () => {
51
+ it('should handle case when zeroconf is not available', () => {
52
+ server = new Server();
53
+ const mockListener = jest.fn();
54
+ server.addUrlsListener(mockListener);
55
+
56
+ // Since Zeroconf is not available, the listener should not be called
57
+ expect(mockListener).not.toHaveBeenCalled();
58
+ });
59
+
60
+ // Test with mock Zeroconf implementation
61
+ it('should handle case when zeroconf is available', () => {
62
+ // Temporarily mock require to return a mock Zeroconf implementation
63
+ const mockZeroconfInstance = {
64
+ on: jest.fn(),
65
+ scan: jest.fn()
66
+ };
67
+
68
+ jest.doMock('react-native-zeroconf', () => ({
69
+ __esModule: true,
70
+ default: jest.fn(() => mockZeroconfInstance)
71
+ }), { virtual: true });
72
+
73
+ server = new Server();
74
+ const mockListener = jest.fn();
75
+ server.addUrlsListener(mockListener);
76
+
77
+ // Verify that Zeroconf methods were not called since module is mocked as undefined
78
+ expect(mockListener).not.toHaveBeenCalled();
79
+ });
80
+ });
81
+
82
+ describe('Data Sending', () => {
83
+ beforeEach(() => {
84
+ server = new Server('localhost:8080');
85
+ (global.fetch as jest.Mock).mockImplementation(() =>
86
+ Promise.resolve({ ok: true })
87
+ );
88
+ });
89
+
90
+ it('should send log data', async () => {
91
+ const testData = { message: 'test log' };
92
+ await server.log(testData);
93
+
94
+ expect(global.fetch).toHaveBeenCalledWith(
95
+ 'http://localhost:8080/log',
96
+ expect.objectContaining({
97
+ method: 'POST',
98
+ headers: {
99
+ 'Content-Type': 'application/json;charset=utf-8'
100
+ },
101
+ body: expect.any(String)
102
+ })
103
+ );
104
+ });
105
+
106
+ it('should send network data', async () => {
107
+ const testData = { url: 'test.com' };
108
+ await server.network(testData);
109
+
110
+ expect(global.fetch).toHaveBeenCalledWith(
111
+ 'http://localhost:8080/network',
112
+ expect.objectContaining({
113
+ method: 'POST',
114
+ headers: {
115
+ 'Content-Type': 'application/json;charset=utf-8'
116
+ },
117
+ body: expect.any(String)
118
+ })
119
+ );
120
+ });
121
+
122
+ it('should handle timeout', async () => {
123
+ server.updateTimeout(100);
124
+ (sleep as jest.Mock).mockImplementation(() => Promise.reject(new Error('Timeout')));
125
+
126
+ const testData = { message: 'test' };
127
+ await server.log(testData);
128
+
129
+ expect(global.fetch).toHaveBeenCalled();
130
+ expect(sleep).toHaveBeenCalledWith(100, true);
131
+ });
132
+ });
133
+
134
+ describe('Base Data Management', () => {
135
+ it('should update base data', async () => {
136
+ server = new Server('localhost:8080');
137
+ const baseData = { userId: '123' };
138
+ server.updateBaseData(baseData);
139
+
140
+ await server.log({ message: 'test' });
141
+
142
+ expect(global.fetch).toHaveBeenCalledWith(
143
+ expect.any(String),
144
+ expect.objectContaining({
145
+ body: expect.stringContaining('"userId":"123"')
146
+ })
147
+ );
148
+ });
149
+ });
150
150
  });
@@ -1,113 +1,114 @@
1
- import { createClassWithErrorHandling, hasPort } from '../utils';
2
-
3
- describe('createClassWithErrorHandling', () => {
4
- class TestClass {
5
- normalMethod(): string {
6
- return 'normal';
7
- }
8
-
9
- errorMethod(): void {
10
- throw new Error('Test error');
11
- }
12
-
13
- async asyncMethod(): Promise<string> {
14
- return 'async';
15
- }
16
-
17
- async asyncErrorMethod(): Promise<void> {
18
- throw new Error('Async test error');
19
- }
20
- }
21
-
22
- let consoleErrorSpy: jest.SpyInstance;
23
-
24
- beforeEach(() => {
25
- consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
26
- });
27
-
28
- afterEach(() => {
29
- consoleErrorSpy.mockRestore();
30
- });
31
-
32
- test('should not interfere with normal methods', () => {
33
- const EnhancedClass = createClassWithErrorHandling(TestClass);
34
- const instance = new EnhancedClass();
35
- expect(instance.normalMethod()).toBe('normal');
36
- });
37
-
38
- test('should catch and log errors from methods', () => {
39
- const EnhancedClass = createClassWithErrorHandling(TestClass);
40
- const instance = new EnhancedClass();
41
- expect(() => instance.errorMethod()).toThrow('Test error');
42
- expect(consoleErrorSpy).toHaveBeenCalledWith('Error in errorMethod:', expect.any(Error));
43
- });
44
-
45
- test('should not interfere with async methods that resolve', async () => {
46
- const EnhancedClass = createClassWithErrorHandling(TestClass);
47
- const instance = new EnhancedClass();
48
- await expect(instance.asyncMethod()).resolves.toBe('async');
49
- });
50
-
51
- test('should catch and log errors from async methods that reject', async () => {
52
- const EnhancedClass = createClassWithErrorHandling(TestClass);
53
- const instance = new EnhancedClass();
54
- await expect(instance.asyncErrorMethod()).rejects.toThrow('Async test error');
55
- expect(consoleErrorSpy).toHaveBeenCalledWith('Error in asyncErrorMethod:', expect.any(Error));
56
- });
57
-
58
- test('should handle methods added after instantiation', () => {
59
- const EnhancedClass = createClassWithErrorHandling(TestClass);
60
- const instance = new EnhancedClass();
61
- (instance as any).dynamicMethod = function(): void {
62
- throw new Error('Dynamic method error');
63
- };
64
- expect(() => (instance as any).dynamicMethod()).toThrow('Dynamic method error');
65
- expect(consoleErrorSpy).toHaveBeenCalledWith('Error in dynamicMethod:', expect.any(Error));
66
- });
67
- });
68
-
69
-
70
- describe('hasPort function', () => {
71
- test('should return true for URLs with explicit ports', () => {
72
- expect(hasPort('http://example.com:8080')).toBe(true);
73
- expect(hasPort('ftp://example.com:210')).toBe(true);
74
- });
75
-
76
- test('should return false for URLs without explicit ports', () => {
77
- expect(hasPort('http://example.com')).toBe(false);
78
- expect(hasPort('https://example.com')).toBe(false);
79
- expect(hasPort('ftp://example.com')).toBe(false);
80
- });
81
-
82
- test('should return false for invalid URLs', () => {
83
- expect(hasPort('not a url')).toBe(false);
84
- expect(hasPort('http:/example.com')).toBe(false);
85
- expect(hasPort('example.com:8080')).toBe(false);
86
- });
87
-
88
- test('should return false for empty input', () => {
89
- expect(hasPort('')).toBe(false);
90
- });
91
-
92
- test('should return false for non-string input', () => {
93
- expect(hasPort(null as any)).toBe(false);
94
- expect(hasPort(undefined as any)).toBe(false);
95
- expect(hasPort(123 as any)).toBe(false);
96
- expect(hasPort({} as any)).toBe(false);
97
- });
98
-
99
- test('should handle URLs with default ports correctly', () => {
100
- expect(hasPort('http://example.com:80')).toBe(false);
101
- expect(hasPort('https://example.com:443')).toBe(false);
102
- });
103
-
104
- test('should handle URLs with IPv6 addresses', () => {
105
- expect(hasPort('http://[2001:db8::1]:8080')).toBe(true);
106
- expect(hasPort('https://[2001:db8::1]')).toBe(false);
107
- });
108
-
109
- test('should handle URLs with userinfo', () => {
110
- expect(hasPort('http://user:pass@example.com:8080')).toBe(true);
111
- expect(hasPort('http://user:pass@example.com')).toBe(false);
112
- });
1
+ import logger from '../logger';
2
+ import { createClassWithErrorHandling, hasPort } from '../utils';
3
+
4
+ describe('createClassWithErrorHandling', () => {
5
+ class TestClass {
6
+ normalMethod(): string {
7
+ return 'normal';
8
+ }
9
+
10
+ errorMethod(): void {
11
+ throw new Error('Test error');
12
+ }
13
+
14
+ async asyncMethod(): Promise<string> {
15
+ return 'async';
16
+ }
17
+
18
+ async asyncErrorMethod(): Promise<void> {
19
+ throw new Error('Async test error');
20
+ }
21
+ }
22
+
23
+ let consoleErrorSpy: jest.SpyInstance;
24
+
25
+ beforeEach(() => {
26
+ consoleErrorSpy = jest.spyOn(logger, 'error').mockImplementation(() => {});
27
+ });
28
+
29
+ afterEach(() => {
30
+ consoleErrorSpy.mockRestore();
31
+ });
32
+
33
+ test('should not interfere with normal methods', () => {
34
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
35
+ const instance = new EnhancedClass();
36
+ expect(instance.normalMethod()).toBe('normal');
37
+ });
38
+
39
+ test('should catch and log errors from methods', () => {
40
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
41
+ const instance = new EnhancedClass();
42
+ expect(() => instance.errorMethod()).toThrow('Test error');
43
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error in errorMethod:', expect.any(Error));
44
+ });
45
+
46
+ test('should not interfere with async methods that resolve', async () => {
47
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
48
+ const instance = new EnhancedClass();
49
+ await expect(instance.asyncMethod()).resolves.toBe('async');
50
+ });
51
+
52
+ test('should catch and log errors from async methods that reject', async () => {
53
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
54
+ const instance = new EnhancedClass();
55
+ await expect(instance.asyncErrorMethod()).rejects.toThrow('Async test error');
56
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error in asyncErrorMethod:', expect.any(Error));
57
+ });
58
+
59
+ test('should handle methods added after instantiation', () => {
60
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
61
+ const instance = new EnhancedClass();
62
+ (instance as any).dynamicMethod = function(): void {
63
+ throw new Error('Dynamic method error');
64
+ };
65
+ expect(() => (instance as any).dynamicMethod()).toThrow('Dynamic method error');
66
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error in dynamicMethod:', expect.any(Error));
67
+ });
68
+ });
69
+
70
+
71
+ describe('hasPort function', () => {
72
+ test('should return true for URLs with explicit ports', () => {
73
+ expect(hasPort('http://example.com:8080')).toBe(true);
74
+ expect(hasPort('ftp://example.com:210')).toBe(true);
75
+ });
76
+
77
+ test('should return false for URLs without explicit ports', () => {
78
+ expect(hasPort('http://example.com')).toBe(false);
79
+ expect(hasPort('https://example.com')).toBe(false);
80
+ expect(hasPort('ftp://example.com')).toBe(false);
81
+ });
82
+
83
+ test('should return false for invalid URLs', () => {
84
+ expect(hasPort('not a url')).toBe(false);
85
+ expect(hasPort('http:/example.com')).toBe(false);
86
+ expect(hasPort('example.com:8080')).toBe(false);
87
+ });
88
+
89
+ test('should return false for empty input', () => {
90
+ expect(hasPort('')).toBe(false);
91
+ });
92
+
93
+ test('should return false for non-string input', () => {
94
+ expect(hasPort(null as any)).toBe(false);
95
+ expect(hasPort(undefined as any)).toBe(false);
96
+ expect(hasPort(123 as any)).toBe(false);
97
+ expect(hasPort({} as any)).toBe(false);
98
+ });
99
+
100
+ test('should handle URLs with default ports correctly', () => {
101
+ expect(hasPort('http://example.com:80')).toBe(false);
102
+ expect(hasPort('https://example.com:443')).toBe(false);
103
+ });
104
+
105
+ test('should handle URLs with IPv6 addresses', () => {
106
+ expect(hasPort('http://[2001:db8::1]:8080')).toBe(true);
107
+ expect(hasPort('https://[2001:db8::1]')).toBe(false);
108
+ });
109
+
110
+ test('should handle URLs with userinfo', () => {
111
+ expect(hasPort('http://user:pass@example.com:8080')).toBe(true);
112
+ expect(hasPort('http://user:pass@example.com')).toBe(false);
113
+ });
113
114
  });