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

[enhancement] #960 allow debug() to exclude props #961

Merged
merged 1 commit into from
Jun 12, 2017
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
25 changes: 13 additions & 12 deletions src/Debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,28 @@ function indentChildren(childrenStrs, indentLength) {
: '';
}

export function debugNode(node, indentLength = 2) {
export function debugNode(node, indentLength = 2, options = {}) {
if (typeof node === 'string' || typeof node === 'number') return escape(node);
if (!node) return '';

const childrenStrs = compact(childrenOfNode(node).map(n => debugNode(n, indentLength)));
const childrenStrs = compact(childrenOfNode(node).map(n => debugNode(n, indentLength, options)));
const type = typeName(node);
const props = propsString(node);

const props = options.ignoreProps ? '' : propsString(node);
const beforeProps = props ? ' ' : '';
const nodeClose = childrenStrs.length ? `</${type}>` : '/>';
const afterProps = childrenStrs.length
? '>'
: ' ';
const childrenIndented = indentChildren(childrenStrs, indentLength);
const nodeClose = childrenStrs.length ? `</${type}>` : '/>';
return `<${type}${beforeProps}${props}${afterProps}${childrenIndented}${nodeClose}`;
}

export function debugNodes(nodes) {
return nodes.map(node => debugNode(node)).join('\n\n\n');
export function debugNodes(nodes, options = {}) {
return nodes.map(node => debugNode(node, undefined, options)).join('\n\n\n');
}

export function debugInst(inst, indentLength = 2) {
export function debugInst(inst, indentLength = 2, options = {}) {
if (typeof inst === 'string' || typeof inst === 'number') return escape(inst);
if (!inst) return '';

Expand All @@ -93,7 +94,7 @@ export function debugInst(inst, indentLength = 2) {

if (!inst.getPublicInstance) {
const internal = internalInstance(inst);
return debugInst(internal, indentLength);
return debugInst(internal, indentLength, options);
}
const publicInst = inst.getPublicInstance();

Expand All @@ -103,7 +104,7 @@ export function debugInst(inst, indentLength = 2) {
// do stuff with publicInst
const currentElement = inst._currentElement;
const type = typeName(currentElement);
const props = propsString(currentElement);
const props = options.ignoreProps ? '' : propsString(currentElement);
const children = [];
if (isDOMComponent(publicInst)) {
const renderedChildren = renderedChildrenOfInst(inst);
Expand All @@ -125,7 +126,7 @@ export function debugInst(inst, indentLength = 2) {
children.push(inst._renderedComponent);
}

const childrenStrs = compact(children.map(n => debugInst(n, indentLength)));
const childrenStrs = compact(children.map(n => debugInst(n, indentLength, options)));

const beforeProps = props ? ' ' : '';
const nodeClose = childrenStrs.length ? `</${type}>` : '/>';
Expand All @@ -136,6 +137,6 @@ export function debugInst(inst, indentLength = 2) {
return `<${type}${beforeProps}${props}${afterProps}${childrenIndented}${nodeClose}`;
}

export function debugInsts(insts) {
return insts.map(inst => debugInst(inst)).join('\n\n\n');
export function debugInsts(insts, options = {}) {
return insts.map(inst => debugInst(inst, undefined, options)).join('\n\n\n');
}
6 changes: 4 additions & 2 deletions src/ReactWrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -934,10 +934,12 @@ class ReactWrapper {
/**
* Returns an HTML-like string of the shallow render for debugging purposes.
*
* @param {Object} options - (Optional) Property bag of additional options.
* options.ignoreProps - if true, props are omitted from the string.
* @returns {String}
*/
debug() {
return debugInsts(this.getNodes());
debug(options = {}) {
return debugInsts(this.getNodes(), options);
}

/**
Expand Down
10 changes: 6 additions & 4 deletions src/ShallowWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ class ShallowWrapper {
*
* NOTE: can only be called on wrapper of a single node.
*
* @param options object
* @param {Object} options
* @returns {ShallowWrapper}
*/
shallow(options) {
Expand Down Expand Up @@ -1049,10 +1049,12 @@ class ShallowWrapper {
/**
* Returns an HTML-like string of the shallow render for debugging purposes.
*
* @param {Object} options - (Optional) Property bag of additional options.
* options.ignoreProps - if true, props are omitted from the string.
* @returns {String}
*/
debug() {
return debugNodes(this.getNodes());
debug(options = {}) {
return debugNodes(this.getNodes(), options);
}

/**
Expand All @@ -1070,7 +1072,7 @@ class ShallowWrapper {
* Primarily useful for HOCs (higher-order components), this method may only be
* run on a single, non-DOM node, and will return the node, shallow-rendered.
*
* @param options object
* @param {Object} options
* @returns {ShallowWrapper}
*/
dive(options = {}) {
Expand Down
94 changes: 94 additions & 0 deletions test/Debug-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -571,4 +571,98 @@ describe('debug', () => {
</span>`);
});
});

describe('debug shallow wrapper', () => {
it('options.ignoreProps causes props to be omitted', () => {
class Foo extends React.Component {
render() {
return (
<div className="foo">
{this.props.fooVal}
</div>
);
}
}

class Bar extends React.Component {
render() {
return (
<div className="class1">
<Foo fooVal="baz" />
<span className="class2">span text</span>
</div>
);
}
}

expect(shallow(<Bar />).debug({ ignoreProps: false })).to.eql(
`<div className="class1">
<Foo fooVal="baz" />
<span className="class2">
span text
</span>
</div>`);

expect(shallow(<Bar />).debug({ ignoreProps: true })).to.eql(
`<div>
<Foo />
<span>
span text
</span>
</div>`);
});
});

describeWithDOM('debug React wrapper', () => {
it('options.ignoreProps causes props to be omitted', () => {
class Foo extends React.Component {
render() {
return (
<div className="foo">
{this.props.fooVal}
</div>
);
}
}

class Bar extends React.Component {
render() {
return (
<div className="class1">
<Foo fooVal="baz" />
<span className="class2">span text</span>
</div>
);
}
}

expect(mount(<Bar />).debug({ ignoreProps: false })).to.eql(
`<Bar>
<div className="class1">
<Foo fooVal="baz">
<div className="foo">
baz
</div>
</Foo>
<span className="class2">
span text
</span>
</div>
</Bar>`);

expect(mount(<Bar />).debug({ ignoreProps: true })).to.eql(
`<Bar>
<div>
<Foo>
<div>
baz
</div>
</Foo>
<span>
span text
</span>
</div>
</Bar>`);
});
});
});