chore: better logger (#1727)

This commit is contained in:
Maciej Jastrzebski
2025-01-08 10:03:21 +01:00
committed by GitHub
parent f8a0d440fc
commit b4d594228c
8 changed files with 57 additions and 25 deletions
+1
View File
@@ -47,6 +47,7 @@
"typings/index.flow.js"
],
"dependencies": {
"chalk": "^4.1.2",
"jest-matcher-utils": "^29.7.0",
"pretty-format": "^29.7.0",
"redent": "^3.0.0"
+13 -15
View File
@@ -1,8 +1,8 @@
/* eslint-disable no-console */
import * as React from 'react';
import { Pressable, Text, TextInput, View } from 'react-native';
import stripAnsi from 'strip-ansi';
import { configure, fireEvent, render, screen } from '..';
import { logger } from '../helpers/logger';
const PLACEHOLDER_FRESHNESS = 'Add custom freshness';
const PLACEHOLDER_CHEF = 'Who inspected freshness?';
@@ -13,13 +13,11 @@ const DEFAULT_INPUT_CUSTOMER = 'What banana?';
const ignoreWarnings = ['Using debug("message") is deprecated'];
const realConsoleWarn = console.warn;
beforeEach(() => {
jest.spyOn(console, 'log').mockImplementation(() => {});
jest.spyOn(console, 'warn').mockImplementation((message) => {
if (!ignoreWarnings.some((warning) => message.includes(warning))) {
realConsoleWarn(message);
jest.spyOn(logger, 'info').mockImplementation(() => {});
jest.spyOn(logger, 'warn').mockImplementation((message) => {
if (!ignoreWarnings.some((warning) => `${message}`.includes(warning))) {
logger.warn(message);
}
});
});
@@ -99,12 +97,12 @@ test('debug', () => {
screen.debug('my custom message');
screen.debug({ message: 'another custom message' });
const mockCalls = jest.mocked(console.log).mock.calls;
const mockCalls = jest.mocked(logger.info).mock.calls;
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
expect(stripAnsi(mockCalls[1][0] + mockCalls[1][1])).toMatchSnapshot('with message');
expect(stripAnsi(mockCalls[2][0] + mockCalls[2][1])).toMatchSnapshot('another custom message');
const mockWarnCalls = jest.mocked(console.warn).mock.calls;
const mockWarnCalls = jest.mocked(logger.warn).mock.calls;
expect(mockWarnCalls[0]).toMatchInlineSnapshot(`
[
"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', () => {
screen.debug();
const mockCalls = jest.mocked(console.log).mock.calls;
const mockCalls = jest.mocked(logger.info).mock.calls;
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot(
'bananaFresh button message should now be "fresh"',
);
@@ -128,7 +126,7 @@ test('debug with only children prop', () => {
render(<Banana />);
screen.debug({ mapProps: () => ({}) });
const mockCalls = jest.mocked(console.log).mock.calls;
const mockCalls = jest.mocked(logger.info).mock.calls;
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
});
@@ -146,7 +144,7 @@ test('debug with only prop whose value is bananaChef', () => {
},
});
const mockCalls = jest.mocked(console.log).mock.calls;
const mockCalls = jest.mocked(logger.info).mock.calls;
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
});
@@ -156,7 +154,7 @@ test('debug with only props from TextInput components', () => {
mapProps: (props, node) => (node.type === 'TextInput' ? props : {}),
});
const mockCalls = jest.mocked(console.log).mock.calls;
const mockCalls = jest.mocked(logger.info).mock.calls;
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
});
@@ -170,7 +168,7 @@ test('debug should use debugOptions from config when no option is specified', ()
);
screen.debug();
const mockCalls = jest.mocked(console.log).mock.calls;
const mockCalls = jest.mocked(logger.info).mock.calls;
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
});
@@ -191,6 +189,6 @@ test('debug should use given options over config debugOptions', () => {
);
screen.debug({ mapProps: (props) => props });
const mockCalls = jest.mocked(console.log).mock.calls;
const mockCalls = jest.mocked(logger.info).mock.calls;
expect(stripAnsi(mockCalls[0][0])).toMatchSnapshot();
});
+3 -4
View File
@@ -1,5 +1,6 @@
import type { ReactTestRendererJSON } from 'react-test-renderer';
import format, { FormatOptions } from './format';
import { logger } from './logger';
export type DebugOptions = {
message?: string;
@@ -17,10 +18,8 @@ export function debug(
const formatOptions = typeof options === 'object' ? { mapProps: options?.mapProps } : undefined;
if (message) {
// eslint-disable-next-line no-console
console.log(`${message}\n\n`, format(instance, formatOptions));
logger.info(`${message}\n\n`, format(instance, formatOptions));
} else {
// eslint-disable-next-line no-console
console.log(format(instance, formatOptions));
logger.info(format(instance, formatOptions));
}
}
+32
View File
@@ -0,0 +1,32 @@
import * as nodeConsole from 'console';
import * as nodeUtil from 'util';
import chalk from 'chalk';
import redent from 'redent';
export const logger = {
debug(message: any, ...args: any[]) {
const output = formatMessage('●', message, ...args);
nodeConsole.debug(chalk.dim(output));
},
info(message: any, ...args: any[]) {
const output = formatMessage('●', message, ...args);
nodeConsole.info(output);
},
warn(message: any, ...args: any[]) {
const output = formatMessage('▲', message, ...args);
nodeConsole.warn(chalk.yellow(output));
},
error(message: any, ...args: any[]) {
const output = formatMessage('■', message, ...args);
nodeConsole.error(chalk.red(output));
},
};
function formatMessage(symbol: string, message: any, ...args: any[]) {
const formatted = nodeUtil.format(message, ...args);
const indented = redent(formatted, 4);
return ` ${symbol} ${indented.trimStart()}\n`;
}
+2 -1
View File
@@ -1,6 +1,7 @@
import * as React from 'react';
import { View, Text, TextInput, Image, Pressable } from 'react-native';
import { render, screen } from '../..';
import { logger } from '../../helpers/logger';
const BUTTON_LABEL = 'cool button';
const BUTTON_HINT = 'click this button';
@@ -105,7 +106,7 @@ test('getAllByLabelText, queryAllByLabelText, findAllByLabelText with exact as f
describe('findBy options deprecations', () => {
let warnSpy: jest.SpyInstance;
beforeEach(() => {
warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
warnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {});
});
afterEach(() => {
warnSpy.mockRestore();
+2 -2
View File
@@ -3,6 +3,7 @@ import { ErrorWithStack } from '../helpers/errors';
import waitFor from '../wait-for';
import type { WaitForOptions } from '../wait-for';
import format from '../helpers/format';
import { logger } from '../helpers/logger';
import { screen } from '../screen';
import { defaultMapProps } from '../helpers/format-default';
@@ -69,8 +70,7 @@ function extractDeprecatedWaitForOptions(options?: WaitForOptions) {
deprecatedKeys.forEach((key) => {
const option = options[key];
if (option) {
// eslint-disable-next-line no-console
console.warn(
logger.warn(
`Use of option "${key}" in a findBy* query options (2nd parameter) is deprecated. Please pass this option in the waitForOptions (3rd parameter).
Example:
+2 -2
View File
@@ -10,6 +10,7 @@ import { addToCleanupQueue } from './cleanup';
import { getConfig } from './config';
import { getHostSelves } from './helpers/component-tree';
import { debug, DebugOptions } from './helpers/debug';
import { logger } from './helpers/logger';
import { validateStringsRenderedWithinText } from './helpers/string-validation';
import { renderWithAct } from './render-act';
import { setRenderResult } from './screen';
@@ -161,8 +162,7 @@ function makeDebug(instance: ReactTestInstance, renderer: ReactTestRenderer): De
: { ...defaultDebugOptions, ...options };
if (typeof options === 'string') {
// eslint-disable-next-line no-console
console.warn(
logger.warn(
'Using debug("message") is deprecated and will be removed in future release, please use debug({ message: "message" }) instead.',
);
}
+2 -1
View File
@@ -2650,6 +2650,7 @@ __metadata:
"@types/react-test-renderer": "npm:^18.3.0"
babel-jest: "npm:^29.7.0"
babel-plugin-module-resolver: "npm:^5.0.2"
chalk: "npm:^4.1.2"
del-cli: "npm:^6.0.0"
eslint: "npm:^8.57.1"
eslint-plugin-prettier: "npm:^4.2.1"
@@ -3773,7 +3774,7 @@ __metadata:
languageName: node
linkType: hard
"chalk@npm:^4.0.0, chalk@npm:^4.1.0":
"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2":
version: 4.1.2
resolution: "chalk@npm:4.1.2"
dependencies: