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

feat: add debug.deep and debug.shallow #37

Merged
merged 3 commits into from
Oct 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
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
48 changes: 44 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,52 @@ Log prettified shallowly rendered component or test instance (just like snapshot
import { debug } from 'react-native-testing-library';

debug(<Component />);
// console.log:
// <View>
// <Text>Component</Text>
// </View>
debug.shallow(<Component />); // an alias for `debug`
```

logs:

```jsx
<TouchableOpacity
activeOpacity={0.2}
onPress={[Function bound fn]}
>
<TextComponent
text="Press me"
/>
</TouchableOpacity>
```

There's also `debug.deep` that renders deeply to stdout.

```jsx
import { debug } from 'react-native-testing-library';

debug.deep(<Component />);
```

logs:

```jsx
<View
accessible={true}
isTVSelectable={true}
onResponderGrant={[Function bound touchableHandleResponderGrant]}
// ... more props
style={
Object {
\\"opacity\\": 1,
}
}
>
<Text>
Press me
</Text>
</View>
```

Optionally you can provide a string message as a second argument to `debug`, which will be displayed right after the component.

## `flushMicrotasksQueue`

Wait for microtasks queue to flush. Useful if you want to wait for some promises with `async/await`.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"react": "16.6.0-alpha.8af6728",
"react-native": "^0.57.3",
"react-test-renderer": "16.6.0-alpha.8af6728",
"strip-ansi": "^5.0.0",
"typescript": "^3.1.1"
},
"peerDependencies": {
Expand Down
34 changes: 34 additions & 0 deletions src/__tests__/__snapshots__/debug.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`debug 1`] = `
"<TouchableOpacity
activeOpacity={0.2}
onPress={[Function bound fn]}
>
<TextComponent
text=\\"Press me\\"
/>
</TouchableOpacity>"
`;

exports[`debug.deep 1`] = `
"<View
accessible={true}
isTVSelectable={true}
onResponderGrant={[Function bound touchableHandleResponderGrant]}
onResponderMove={[Function bound touchableHandleResponderMove]}
onResponderRelease={[Function bound touchableHandleResponderRelease]}
onResponderTerminate={[Function bound touchableHandleResponderTerminate]}
onResponderTerminationRequest={[Function bound touchableHandleResponderTerminationRequest]}
onStartShouldSetResponder={[Function bound touchableHandleStartShouldSetResponder]}
style={
Object {
\\"opacity\\": 1,
}
}
>
<Text>
Press me
</Text>
</View>"
`;
60 changes: 60 additions & 0 deletions src/__tests__/debug.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// @flow
/* eslint-disable no-console */
import React from 'react';
import { TouchableOpacity, Text } from 'react-native';
import stripAnsi from 'strip-ansi';
import { debug } from '..';

function TextComponent({ text }) {
return <Text>{text}</Text>;
}

class Button extends React.Component<*> {
render() {
return (
<TouchableOpacity onPress={this.props.onPress}>
<TextComponent text={this.props.text} />
</TouchableOpacity>
);
}
}

test('debug', () => {
// $FlowFixMe
console.log = jest.fn();
const component = <Button onPress={jest.fn} text="Press me" />;
debug(component);

const output = console.log.mock.calls[0][0];

expect(stripAnsi(output)).not.toEqual(output);
expect(stripAnsi(output)).toMatchSnapshot();

console.log.mockReset();

debug(component, 'test message');

expect(console.log).toBeCalledWith(output, 'test message');
});

test('debug.shallow', () => {
expect(debug.shallow).toBe(debug);
});

test('debug.deep', () => {
// $FlowFixMe
console.log = jest.fn();
const component = <Button onPress={jest.fn} text="Press me" />;
debug.deep(component);

const output = console.log.mock.calls[0][0];

expect(stripAnsi(output)).not.toEqual(output);
expect(stripAnsi(output)).toMatchSnapshot();

console.log.mockReset();

debug.deep(component, 'test message');

expect(console.log).toBeCalledWith(output, 'test message');
});
23 changes: 21 additions & 2 deletions src/debug.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
// @flow
/* eslint-disable no-console */
import * as React from 'react';
import prettyFormat, { plugins } from 'pretty-format'; // eslint-disable-line import/no-extraneous-dependencies
import shallow from './shallow';
import render from './render';

/**
* Log pretty-printed shallow test component instance
*/
export default function debug(
function debugShallow(
instance: ReactTestInstance | React.Element<*>,
message?: any
) {
const { output } = shallow(instance);
// eslint-disable-next-line no-console

console.log(format(output), message || '');
}

/**
* Log pretty-printed deep test component instance
*/
function debugDeep(instance: React.Element<*>, message?: any) {
const { toJSON } = render(instance);

console.log(format(toJSON()), message || '');
}

const format = input =>
prettyFormat(input, {
plugins: [plugins.ReactTestComponent, plugins.ReactElement],
highlight: true,
});

const debug = debugShallow;

debug.shallow = debugShallow;
debug.deep = debugDeep;

export default debug;
7 changes: 7 additions & 0 deletions typings/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,15 @@ const shallowTree: { output: React.ReactElement<any> } = shallow(

const waitForFlush: Promise<any> = flushMicrotasksQueue();

// debug API
debug(<TestComponent />);
debug(<TestComponent />, 'message');
debug(getByNameString);
debug(getByNameString, 'message');
debug.shallow(<TestComponent />);
debug.shallow(<TestComponent />, 'message');
debug.deep(<TestComponent />);
debug.deep(<TestComponent />, 'message');

const waitBy: Promise<ReactTestInstance> = waitForElement<ReactTestInstance>(
() => tree.getByName('View')
Expand Down
14 changes: 11 additions & 3 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ export type WaitForElementFunction = <T = any>(
interval?: number
) => Promise<T>;

export type DebugFunction = (
instance: ReactTestInstance | React.ReactElement<any>,
message?: string
) => void;

export type DebugAPI = DebugFunction & {
shallow: DebugFunction;
deep: (instance: React.ReactElement<any>, message?: string) => void;
};

export declare const render: (
component: React.ReactElement<any>,
options?: RenderOptions
Expand All @@ -59,8 +69,6 @@ export declare const shallow: <P = {}>(
instance: ReactTestInstance | React.ReactElement<P>
) => { output: React.ReactElement<P> };
export declare const flushMicrotasksQueue: () => Promise<any>;
export declare const debug: (
instance: ReactTestInstance | React.ReactElement<any>
) => void;
export declare const debug: DebugAPI;
export declare const fireEvent: FireEventAPI;
export declare const waitForElement: WaitForElementFunction;
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,11 @@ ansi-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=

ansi-regex@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9"
integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==

ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
Expand Down Expand Up @@ -6275,6 +6280,13 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"

strip-ansi@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f"
integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==
dependencies:
ansi-regex "^4.0.0"

strip-bom@3.0.0, strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
Expand Down