Skip to content

Commit

Permalink
Add name method (#335)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB authored and lelandrichardson committed May 8, 2016
1 parent a8fc7f4 commit 8138b73
Show file tree
Hide file tree
Showing 11 changed files with 329 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
* [last()](/docs/api/ShallowWrapper/last.md)
* [map(fn)](/docs/api/ShallowWrapper/map.md)
* [matchesElement(node)](/docs/api/ShallowWrapper/matchesElement.md)
* [name()](/docs/api/ShallowWrapper/name.md)
* [not(selector)](/docs/api/ShallowWrapper/not.md)
* [parent()](/docs/api/ShallowWrapper/parent.md)
* [parents()](/docs/api/ShallowWrapper/parents.md)
Expand Down Expand Up @@ -93,6 +94,7 @@
* [map(fn)](/docs/api/ReactWrapper/map.md)
* [matchesElement(node)](/docs/api/ReactWrapper/matchesElement.md)
* [mount()](/docs/api/ReactWrapper/mount.md)
* [name()](/docs/api/ReactWrapper/name.md)
* [not(selector)](/docs/api/ReactWrapper/not.md)
* [parent()](/docs/api/ReactWrapper/parent.md)
* [parents()](/docs/api/ReactWrapper/parents.md)
Expand Down
34 changes: 34 additions & 0 deletions docs/api/ReactWrapper/name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# `.name() => String|null`

Returns the name of the current node of this wrapper. If it's a composite component, this will be
the name of the component. If it's native DOM node, it will be a string of the tag name. If it's
`null`, it will be `null`.

The order of precedence on returning the name is: `type.displayName` -> `type.name` -> `type`.

Note: can only be called on a wrapper of a single node.


#### Returns

`String|null`: The name of the current node



#### Examples

```jsx
const wrapper = mount(<div/>);
expect(wrapper.name()).to.equal('div');
```

```jsx
const wrapper = mount(<Foo />);
expect(wrapper.name()).to.equal('Foo');
```

```jsx
Foo.displayName = 'A cool custom name';
const wrapper = mount(<Foo />);
expect(wrapper.name()).to.equal('A cool custom name');
```
36 changes: 36 additions & 0 deletions docs/api/ShallowWrapper/name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# `.name() => String|null`

Returns the name of the current node of this wrapper. If it's a composite component, this will be
the name of the top-most rendered component. If it's native DOM node, it will be a string of the
tag name. If it's `null`, it will be `null`.

The order of precedence on returning the name is: `type.displayName` -> `type.name` -> `type`.

Note: can only be called on a wrapper of a single node.


#### Returns

`String|null`: The name of the current node



#### Examples

```jsx
const wrapper = shallow(<div/>);
expect(wrapper.name()).to.equal('div');
```

```jsx
const SomeWrappingComponent = () => <Foo />;
const wrapper = shallow(<SomeWrappingComponent />);
expect(wrapper.name()).to.equal('Foo');
```

```jsx
Foo.displayName = 'A cool custom name';
const SomeWrappingComponent = () => <Foo />;
const wrapper = shallow(<SomeWrappingComponent />);
expect(wrapper.name()).to.equal('A cool custom name');
```
3 changes: 3 additions & 0 deletions docs/api/mount.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ Returns a string representation of the current render tree for debugging purpose
#### [`.type() => String|Function`](ReactWrapper/type.md)
Returns the type of the current node of the wrapper.

#### [`.name() => String`](ReactWrapper/name.md)
Returns the name of the current node of the wrapper.

#### [`.forEach(fn) => ReactWrapper`](ReactWrapper/forEach.md)
Iterates through each node of the current wrapper and executes the provided function

Expand Down
3 changes: 3 additions & 0 deletions docs/api/shallow.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ Returns a string representation of the current shallow render tree for debugging
#### [`.type() => String|Function`](ShallowWrapper/type.md)
Returns the type of the current node of the wrapper.

#### [`.name() => String`](ShallowWrapper/name.md)
Returns the name of the current node of the wrapper.

#### [`.forEach(fn) => ShallowWrapper`](ShallowWrapper/forEach.md)
Iterates through each node of the current wrapper and executes the provided function

Expand Down
12 changes: 12 additions & 0 deletions src/ReactWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
containsChildrenSubArray,
propsOfNode,
typeOfNode,
displayNameOfNode,
} from './Utils';
import {
debugInsts,
Expand Down Expand Up @@ -616,6 +617,17 @@ export default class ReactWrapper {
return this.single(n => typeOfNode(getNode(n)));
}

/**
* Returns the name of the root node of this wrapper.
*
* In order of precedence => type.displayName -> type.name -> type.
*
* @returns {String}
*/
name() {
return this.single(n => displayNameOfNode(getNode(n)));
}

/**
* Returns whether or not the current root node has the given class name or not.
*
Expand Down
12 changes: 12 additions & 0 deletions src/ShallowWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
propsOfNode,
typeOfNode,
isReactElementAlike,
displayNameOfNode,
} from './Utils';
import {
debugNodes,
Expand Down Expand Up @@ -612,6 +613,17 @@ export default class ShallowWrapper {
return this.single(typeOfNode);
}

/**
* Returns the name of the root node of this wrapper.
*
* In order of precedence => type.displayName -> type.name -> type.
*
* @returns {String}
*/
name() {
return this.single(displayNameOfNode);
}

/**
* Returns whether or not the current root node has the given class name or not.
*
Expand Down
8 changes: 8 additions & 0 deletions src/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,11 @@ export function mapNativeEventNames(event) {

return nativeToReactEventMap[event] || event;
}

export function displayNameOfNode(node) {
const { type } = node;

if (!type) return null;

return type.displayName || type.name || type;
}
84 changes: 84 additions & 0 deletions test/ReactWrapper-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2187,4 +2187,88 @@ describeWithDOM('mount', () => {
expect(spy2.callCount).to.equal(0);
});
});

describe('.name()', () => {
describe('node with displayName', () => {
it('should return the displayName of the node', () => {
class Foo extends React.Component {
render() { return <div />; }
}

Foo.displayName = 'CustomWrapper';

const wrapper = mount(<Foo />);
expect(wrapper.name()).to.equal('CustomWrapper');
});

describeIf(!REACT013, 'stateless function components', () => {
it('should return the name of the node', () => {
function SFC() {
return <div />;
}

SFC.displayName = 'CustomWrapper';

const wrapper = mount(<SFC />);
expect(wrapper.name()).to.equal('CustomWrapper');
});
});

describe('React.createClass', () => {
it('should return the name of the node', () => {
const Foo = React.createClass({
displayName: 'CustomWrapper',
render() {
return <div />;
},
});

const wrapper = mount(<Foo />);
expect(wrapper.name()).to.equal('CustomWrapper');
});
});
});

describe('node without displayName', () => {
it('should return the name of the node', () => {
class Foo extends React.Component {
render() { return <div />; }
}

const wrapper = mount(<Foo />);
expect(wrapper.name()).to.equal('Foo');
});

describeIf(!REACT013, 'stateless function components', () => {
it('should return the name of the node', () => {
function SFC() {
return <div />;
}

const wrapper = mount(<SFC />);
expect(wrapper.name()).to.equal('SFC');
});
});

describe('React.createClass', () => {
it('should return the name of the node', () => {
const Foo = React.createClass({
render() {
return <div />;
},
});

const wrapper = mount(<Foo />);
expect(wrapper.name()).to.equal('Foo');
});
});
});

describe('DOM node', () => {
it('should return the name of the node', () => {
const wrapper = mount(<div />);
expect(wrapper.name()).to.equal('div');
});
});
});
});
104 changes: 104 additions & 0 deletions test/ShallowWrapper-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2539,4 +2539,108 @@ describe('shallow', () => {
expect(spy2.callCount).to.equal(0);
});
});
describe('.name()', () => {
describe('node with displayName', () => {
it('should return the displayName of the node', () => {
class Foo extends React.Component {
render() { return <div />; }
}

class Wrapper extends React.Component {
render() { return <Foo />; }
}

Foo.displayName = 'CustomWrapper';

const wrapper = shallow(<Wrapper />);
expect(wrapper.name()).to.equal('CustomWrapper');
});

describeIf(!REACT013, 'stateless function components', () => {
it('should return the name of the node', () => {
function SFC() {
return <div />;
}
const Wrapper = () => <SFC />;

SFC.displayName = 'CustomWrapper';

const wrapper = shallow(<Wrapper />);
expect(wrapper.name()).to.equal('CustomWrapper');
});
});

describe('React.createClass', () => {
it('should return the name of the node', () => {
const Foo = React.createClass({
displayName: 'CustomWrapper',
render() {
return <div />;
},
});
const Wrapper = React.createClass({
render() {
return <Foo />;
},
});

const wrapper = shallow(<Wrapper />);
expect(wrapper.name()).to.equal('CustomWrapper');
});
});
});

describe('node without displayName', () => {
it('should return the name of the node', () => {
class Foo extends React.Component {
render() { return <div />; }
}

class Wrapper extends React.Component {
render() { return <Foo />; }
}

const wrapper = shallow(<Wrapper />);
expect(wrapper.name()).to.equal('Foo');
});

describeIf(!REACT013, 'stateless function components', () => {
it('should return the name of the node', () => {
function SFC() {
return <div />;
}
const Wrapper = () => <SFC />;

const wrapper = shallow(<Wrapper />);
expect(wrapper.name()).to.equal('SFC');
});
});

describe('React.createClass', () => {
it('should return the name of the node', () => {
const Foo = React.createClass({
render() {
return <div />;
},
});
const Wrapper = React.createClass({
render() {
return <Foo />;
},
});

const wrapper = shallow(<Wrapper />);
expect(wrapper.name()).to.equal('Foo');
});
});
});

describe('DOM node', () => {
it('should return the name of the node', () => {
const wrapper = shallow(<div />);
expect(wrapper.name()).to.equal('div');
});
});
});

});
Loading

0 comments on commit 8138b73

Please sign in to comment.