Skip to content

Commit b4d5942

Browse files
chore: better logger (#1727)
1 parent f8a0d44 commit b4d5942

File tree

8 files changed

+57
-25
lines changed

8 files changed

+57
-25
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"typings/index.flow.js"
4848
],
4949
"dependencies": {
50+
"chalk": "^4.1.2",
5051
"jest-matcher-utils": "^29.7.0",
5152
"pretty-format": "^29.7.0",
5253
"redent": "^3.0.0"

src/__tests__/render-debug.test.tsx

+13-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
/* eslint-disable no-console */
21
import * as React from 'react';
32
import { Pressable, Text, TextInput, View } from 'react-native';
43
import stripAnsi from 'strip-ansi';
54
import { configure, fireEvent, render, screen } from '..';
5+
import { logger } from '../helpers/logger';
66

77
const PLACEHOLDER_FRESHNESS = 'Add custom freshness';
88
const PLACEHOLDER_CHEF = 'Who inspected freshness?';
@@ -13,13 +13,11 @@ const DEFAULT_INPUT_CUSTOMER = 'What banana?';
1313

1414
const ignoreWarnings = ['Using debug("message") is deprecated'];
1515

16-
const realConsoleWarn = console.warn;
17-
1816
beforeEach(() => {
19-
jest.spyOn(console, 'log').mockImplementation(() => {});
20-
jest.spyOn(console, 'warn').mockImplementation((message) => {
21-
if (!ignoreWarnings.some((warning) => message.includes(warning))) {
22-
realConsoleWarn(message);
17+
jest.spyOn(logger, 'info').mockImplementation(() => {});
18+
jest.spyOn(logger, 'warn').mockImplementation((message) => {
19+
if (!ignoreWarnings.some((warning) => `${message}`.includes(warning))) {
20+
logger.warn(message);
2321
}
2422
});
2523
});
@@ -99,12 +97,12 @@ test('debug', () => {
9997
screen.debug('my custom message');
10098
screen.debug({ message: 'another custom message' });
10199

102-
const mockCalls = jest.mocked(console.log).mock.calls;
100+
const mockCalls = jest.mocked(logger.info).mock.calls;
103101
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
104102
expect(stripAnsi(mockCalls[1][0] + mockCalls[1][1])).toMatchSnapshot('with message');
105103
expect(stripAnsi(mockCalls[2][0] + mockCalls[2][1])).toMatchSnapshot('another custom message');
106104

107-
const mockWarnCalls = jest.mocked(console.warn).mock.calls;
105+
const mockWarnCalls = jest.mocked(logger.warn).mock.calls;
108106
expect(mockWarnCalls[0]).toMatchInlineSnapshot(`
109107
[
110108
"Using debug("message") is deprecated and will be removed in future release, please use debug({ message: "message" }) instead.",
@@ -118,7 +116,7 @@ test('debug changing component', () => {
118116

119117
screen.debug();
120118

121-
const mockCalls = jest.mocked(console.log).mock.calls;
119+
const mockCalls = jest.mocked(logger.info).mock.calls;
122120
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot(
123121
'bananaFresh button message should now be "fresh"',
124122
);
@@ -128,7 +126,7 @@ test('debug with only children prop', () => {
128126
render(<Banana />);
129127
screen.debug({ mapProps: () => ({}) });
130128

131-
const mockCalls = jest.mocked(console.log).mock.calls;
129+
const mockCalls = jest.mocked(logger.info).mock.calls;
132130
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
133131
});
134132

@@ -146,7 +144,7 @@ test('debug with only prop whose value is bananaChef', () => {
146144
},
147145
});
148146

149-
const mockCalls = jest.mocked(console.log).mock.calls;
147+
const mockCalls = jest.mocked(logger.info).mock.calls;
150148
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
151149
});
152150

@@ -156,7 +154,7 @@ test('debug with only props from TextInput components', () => {
156154
mapProps: (props, node) => (node.type === 'TextInput' ? props : {}),
157155
});
158156

159-
const mockCalls = jest.mocked(console.log).mock.calls;
157+
const mockCalls = jest.mocked(logger.info).mock.calls;
160158
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
161159
});
162160

@@ -170,7 +168,7 @@ test('debug should use debugOptions from config when no option is specified', ()
170168
);
171169
screen.debug();
172170

173-
const mockCalls = jest.mocked(console.log).mock.calls;
171+
const mockCalls = jest.mocked(logger.info).mock.calls;
174172
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
175173
});
176174

@@ -191,6 +189,6 @@ test('debug should use given options over config debugOptions', () => {
191189
);
192190
screen.debug({ mapProps: (props) => props });
193191

194-
const mockCalls = jest.mocked(console.log).mock.calls;
192+
const mockCalls = jest.mocked(logger.info).mock.calls;
195193
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
196194
});

src/helpers/debug.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ReactTestRendererJSON } from 'react-test-renderer';
22
import format, { FormatOptions } from './format';
3+
import { logger } from './logger';
34

45
export type DebugOptions = {
56
message?: string;
@@ -17,10 +18,8 @@ export function debug(
1718
const formatOptions = typeof options === 'object' ? { mapProps: options?.mapProps } : undefined;
1819

1920
if (message) {
20-
// eslint-disable-next-line no-console
21-
console.log(`${message}\n\n`, format(instance, formatOptions));
21+
logger.info(`${message}\n\n`, format(instance, formatOptions));
2222
} else {
23-
// eslint-disable-next-line no-console
24-
console.log(format(instance, formatOptions));
23+
logger.info(format(instance, formatOptions));
2524
}
2625
}

src/helpers/logger.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import * as nodeConsole from 'console';
2+
import * as nodeUtil from 'util';
3+
import chalk from 'chalk';
4+
import redent from 'redent';
5+
6+
export const logger = {
7+
debug(message: any, ...args: any[]) {
8+
const output = formatMessage('●', message, ...args);
9+
nodeConsole.debug(chalk.dim(output));
10+
},
11+
12+
info(message: any, ...args: any[]) {
13+
const output = formatMessage('●', message, ...args);
14+
nodeConsole.info(output);
15+
},
16+
17+
warn(message: any, ...args: any[]) {
18+
const output = formatMessage('▲', message, ...args);
19+
nodeConsole.warn(chalk.yellow(output));
20+
},
21+
22+
error(message: any, ...args: any[]) {
23+
const output = formatMessage('■', message, ...args);
24+
nodeConsole.error(chalk.red(output));
25+
},
26+
};
27+
28+
function formatMessage(symbol: string, message: any, ...args: any[]) {
29+
const formatted = nodeUtil.format(message, ...args);
30+
const indented = redent(formatted, 4);
31+
return ` ${symbol} ${indented.trimStart()}\n`;
32+
}

src/queries/__tests__/label-text.test.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from 'react';
22
import { View, Text, TextInput, Image, Pressable } from 'react-native';
33
import { render, screen } from '../..';
4+
import { logger } from '../../helpers/logger';
45

56
const BUTTON_LABEL = 'cool button';
67
const BUTTON_HINT = 'click this button';
@@ -105,7 +106,7 @@ test('getAllByLabelText, queryAllByLabelText, findAllByLabelText with exact as f
105106
describe('findBy options deprecations', () => {
106107
let warnSpy: jest.SpyInstance;
107108
beforeEach(() => {
108-
warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
109+
warnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {});
109110
});
110111
afterEach(() => {
111112
warnSpy.mockRestore();

src/queries/make-queries.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ErrorWithStack } from '../helpers/errors';
33
import waitFor from '../wait-for';
44
import type { WaitForOptions } from '../wait-for';
55
import format from '../helpers/format';
6+
import { logger } from '../helpers/logger';
67
import { screen } from '../screen';
78
import { defaultMapProps } from '../helpers/format-default';
89

@@ -69,8 +70,7 @@ function extractDeprecatedWaitForOptions(options?: WaitForOptions) {
6970
deprecatedKeys.forEach((key) => {
7071
const option = options[key];
7172
if (option) {
72-
// eslint-disable-next-line no-console
73-
console.warn(
73+
logger.warn(
7474
`Use of option "${key}" in a findBy* query options (2nd parameter) is deprecated. Please pass this option in the waitForOptions (3rd parameter).
7575
Example:
7676

src/render.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { addToCleanupQueue } from './cleanup';
1010
import { getConfig } from './config';
1111
import { getHostSelves } from './helpers/component-tree';
1212
import { debug, DebugOptions } from './helpers/debug';
13+
import { logger } from './helpers/logger';
1314
import { validateStringsRenderedWithinText } from './helpers/string-validation';
1415
import { renderWithAct } from './render-act';
1516
import { setRenderResult } from './screen';
@@ -161,8 +162,7 @@ function makeDebug(instance: ReactTestInstance, renderer: ReactTestRenderer): De
161162
: { ...defaultDebugOptions, ...options };
162163

163164
if (typeof options === 'string') {
164-
// eslint-disable-next-line no-console
165-
console.warn(
165+
logger.warn(
166166
'Using debug("message") is deprecated and will be removed in future release, please use debug({ message: "message" }) instead.',
167167
);
168168
}

yarn.lock

+2-1
Original file line numberDiff line numberDiff line change
@@ -2650,6 +2650,7 @@ __metadata:
26502650
"@types/react-test-renderer": "npm:^18.3.0"
26512651
babel-jest: "npm:^29.7.0"
26522652
babel-plugin-module-resolver: "npm:^5.0.2"
2653+
chalk: "npm:^4.1.2"
26532654
del-cli: "npm:^6.0.0"
26542655
eslint: "npm:^8.57.1"
26552656
eslint-plugin-prettier: "npm:^4.2.1"
@@ -3773,7 +3774,7 @@ __metadata:
37733774
languageName: node
37743775
linkType: hard
37753776

3776-
"chalk@npm:^4.0.0, chalk@npm:^4.1.0":
3777+
"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2":
37773778
version: 4.1.2
37783779
resolution: "chalk@npm:4.1.2"
37793780
dependencies:

0 commit comments

Comments
 (0)