Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: better logger #1727

Merged
merged 2 commits into from
Jan 8, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
chore: logger
mdjastrzebski committed Jan 8, 2025
commit 80f162a85fb97479dd84e86bf3d1c6c3d96a3be7
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -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"
28 changes: 13 additions & 15 deletions src/__tests__/render-debug.test.tsx
Original file line number Diff line number Diff line change
@@ -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();
});
7 changes: 3 additions & 4 deletions src/helpers/debug.ts
Original file line number Diff line number Diff line change
@@ -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));
}
}
25 changes: 25 additions & 0 deletions src/helpers/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as nodeConsole from 'console';
import * as nodeUtil from 'util';
import chalk from 'chalk';

export const logger = {
debug(message: any, ...args: any[]) {
const output = nodeUtil.format('RNTL: ', message, ...args);
nodeConsole.debug(chalk.dim(output));
},

info(message: any, ...args: any[]) {
const output = nodeUtil.format('RNTL: ', message, ...args);
nodeConsole.info(output);
},

warn(message: any, ...args: any[]) {
const output = nodeUtil.format('RNTL: ', message, ...args);
nodeConsole.warn(chalk.yellow(output));
},

error(message: any, ...args: any[]) {
const output = nodeUtil.format('RNTL: ', message, ...args);
nodeConsole.error(chalk.red(output));
},
};
3 changes: 2 additions & 1 deletion src/queries/__tests__/label-text.test.tsx
Original file line number Diff line number Diff line change
@@ -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();
4 changes: 2 additions & 2 deletions src/queries/make-queries.ts
Original file line number Diff line number Diff line change
@@ -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:

4 changes: 2 additions & 2 deletions src/render.tsx
Original file line number Diff line number Diff line change
@@ -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.',
);
}
3 changes: 2 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
@@ -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: