Skip to content

Commit 27b9a95

Browse files
author
jfusco
committed
Adding functionality for delimiters option - finishing unit tests for tags and tag components - refactored tests for tags component - installled class properties plugin so we could use static members inside a React Component class - fixing unit test task runner - changing tag container to an unordered list element
1 parent 8a7535d commit 27b9a95

File tree

15 files changed

+555
-246
lines changed

15 files changed

+555
-246
lines changed

.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@
22
"presets": [
33
"react",
44
"es2015"
5+
],
6+
"plugins": [
7+
"transform-class-properties"
58
]
69
}

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ render(<Application />, document.getElementById('application'));
5757
#### Options
5858
* **[`initialTags`](#initialTags)**
5959
* **[`placeholder`](#placeholder)**
60+
* **[`delimiters`](#delimiters)**
6061
* **[`change`](#change)**
6162
* **[`added`](#added)**
63+
* **[`removed`](#removed)**
6264
* **[`readOnly`](#readOnly)**
6365
* **[`removeTagWithDeleteKey`](#removeTagWithDeleteKey)**
6466
* **[`removeTagIcon`](#removeTagIcon)**
@@ -81,6 +83,15 @@ A `string` used as placeholder text in the tags input field
8183
<Tags placeholder="Add a tag" />
8284
```
8385

86+
<a name="delimiters"></a>
87+
##### delimiters ~ optional ~ default `[13, 9, 32]`
88+
An `array` of keyCodes used to tell the tags component which delimiter to use to add a tag
89+
90+
[Here](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode) is more info and a list of keyCodes
91+
```js
92+
<Tags delimiters={[13, 9, 32, 188]} />
93+
```
94+
8495
<a name="change"></a>
8596
##### change ~ optional
8697
A `function` fired anytime there is a change - returns the new `array` of tags

__tests__/Tag-test.js

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
'use strict';
2+
3+
jest.disableAutomock();
4+
5+
import React from 'react';
6+
import { findDOMNode } from 'react-dom';
7+
import { createRenderer, Simulate, renderIntoDocument } from 'react-addons-test-utils';
8+
import Tag from '../src/js/Tag';
9+
10+
const TAG_NAME = 'foo';
11+
12+
describe('Tag', () => {
13+
let renderer,
14+
tag;
15+
16+
beforeEach(() => {
17+
renderer = createRenderer();
18+
19+
renderer.render(
20+
<Tag
21+
name={TAG_NAME} />
22+
);
23+
24+
tag = renderer.getRenderOutput();
25+
});
26+
27+
afterEach(() => {
28+
renderer = null;
29+
tag = null;
30+
});
31+
32+
it('should render', () => {
33+
expect(tag).not.toBeUndefined();
34+
expect(tag.type).toBe('li');
35+
});
36+
37+
it('should render with a name', () => {
38+
const props = tag.props.children;
39+
40+
expect(props[0]).toBe(TAG_NAME);
41+
});
42+
});
43+
44+
45+
describe('Tag - "readOnly"', () => {
46+
let renderer;
47+
48+
beforeEach(() => {
49+
renderer = createRenderer();
50+
});
51+
52+
afterEach(() => {
53+
renderer = null;
54+
});
55+
56+
describe('when readOnly is false', () => {
57+
it('should render the removeTagIcon', () => {
58+
renderer.render(
59+
<Tag
60+
name={TAG_NAME}
61+
readOnly={false} />
62+
);
63+
64+
const tag = renderer.getRenderOutput();
65+
const removeIcon = tag.props.children[1];
66+
67+
expect(removeIcon).not.toBeNull();
68+
expect(removeIcon.type).toBe('a');
69+
});
70+
});
71+
72+
describe('when readOnly is true', () => {
73+
it('should not render the removeTagIcon', () => {
74+
renderer.render(
75+
<Tag
76+
name={TAG_NAME}
77+
readOnly={true} />
78+
);
79+
80+
const tag = renderer.getRenderOutput();
81+
82+
expect(tag.props.children[1]).toBeNull();
83+
});
84+
});
85+
});
86+
87+
describe('Tag - "removeTagIcon"', () => {
88+
let renderer;
89+
90+
beforeEach(() => {
91+
renderer = createRenderer();
92+
});
93+
94+
afterEach(() => {
95+
renderer = null;
96+
});
97+
98+
describe('when a custom element is passed in', () => {
99+
it('should render the element', () => {
100+
const customRemoveIcon = (
101+
<i className="icon-remove"></i>
102+
);
103+
104+
renderer.render(
105+
<Tag
106+
name={TAG_NAME}
107+
removeTagIcon={customRemoveIcon} />
108+
);
109+
110+
const tag = renderer.getRenderOutput();
111+
const removeIcon = tag.props.children[1].props.children;
112+
113+
expect(tag.props.children[1].type).toBe('a');
114+
expect(removeIcon.type).toBe('i');
115+
expect(removeIcon.props.className).toBe('icon-remove');
116+
});
117+
});
118+
119+
describe('when a custom string is passed in', () => {
120+
it('should render the string', () => {
121+
const renderer = createRenderer();
122+
123+
const customRemoveString = 'remove';
124+
125+
renderer.render(
126+
<Tag
127+
name={TAG_NAME}
128+
removeTagIcon={customRemoveString} />
129+
);
130+
131+
const tag = renderer.getRenderOutput();
132+
const removeIcon = tag.props.children[1].props.children;
133+
134+
expect(tag.props.children[1].type).toBe('a');
135+
expect(removeIcon).toBe('remove');
136+
});
137+
});
138+
});
139+
140+
describe('Tag - "removeTag"', () => {
141+
it('should be called when clicking the remove icon', () => {
142+
const onRemoveClick = jest.genMockFunction();
143+
144+
const tag = renderIntoDocument(
145+
<div>
146+
<Tag
147+
name={TAG_NAME}
148+
removeTag={onRemoveClick} />
149+
</div>
150+
);
151+
152+
const statelessTag = findDOMNode(tag).children[0];
153+
const removeIcon = statelessTag.getElementsByTagName('a')[0];
154+
155+
Simulate.click(removeIcon);
156+
157+
expect(onRemoveClick).toBeCalled();
158+
});
159+
});

0 commit comments

Comments
 (0)