Test transfer (#4191)

* refactor: use Checkbox directly

* test: add test case for Transfer
This commit is contained in:
Benjy Cui 2016-12-16 17:59:52 +08:00 committed by 偏右
parent d7a110552b
commit d7498c0af6
10 changed files with 506 additions and 102 deletions

View File

@ -242,11 +242,17 @@ exports[`test renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -306,11 +312,17 @@ exports[`test renders ./components/locale-provider/demo/all.md correctly 1`] = `
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>

View File

@ -6,11 +6,17 @@ exports[`test renders ./components/transfer/demo/advanced.md correctly 1`] = `
style="width:250px;height:300px;">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -84,11 +90,17 @@ exports[`test renders ./components/transfer/demo/advanced.md correctly 1`] = `
style="width:250px;height:300px;">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -144,11 +156,17 @@ exports[`test renders ./components/transfer/demo/basic.md correctly 1`] = `
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -238,11 +256,17 @@ exports[`test renders ./components/transfer/demo/basic.md correctly 1`] = `
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -294,11 +318,17 @@ exports[`test renders ./components/transfer/demo/custom-item.md correctly 1`] =
style="width:300px;height:300px;">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -344,11 +374,17 @@ exports[`test renders ./components/transfer/demo/custom-item.md correctly 1`] =
style="width:300px;height:300px;">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -378,11 +414,17 @@ exports[`test renders ./components/transfer/demo/large-data.md correctly 1`] = `
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -427,11 +469,17 @@ exports[`test renders ./components/transfer/demo/large-data.md correctly 1`] = `
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -461,11 +509,17 @@ exports[`test renders ./components/transfer/demo/search.md correctly 1`] = `
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
@ -525,11 +579,17 @@ exports[`test renders ./components/transfer/demo/search.md correctly 1`] = `
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<span
class="ant-transfer-checkbox">
<label
class="ant-checkbox-wrapper">
<span
class="ant-transfer-checkbox-inner" />
</span>
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>

View File

@ -0,0 +1,143 @@
exports[`Transfer should render correctly 1`] = `
<div
class="ant-transfer">
<div
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<label
class="ant-checkbox-wrapper">
<span
class="ant-checkbox ant-checkbox-checked ant-checkbox-checked-1">
<span
class="ant-checkbox-inner" />
<input
checked=""
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
1/2
</span>
<span
class="ant-transfer-list-header-title" />
</span>
</div>
<div
class="ant-transfer-list-body">
<ul
class="ant-transfer-list-content">
<li
class="ant-transfer-list-content-item">
<label
class="ant-checkbox-wrapper">
<span
class="ant-checkbox ant-checkbox-checked ant-checkbox-checked-1">
<span
class="ant-checkbox-inner" />
<input
checked=""
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span />
</li>
<li
class="ant-transfer-list-content-item ant-transfer-list-content-item-disabled">
<label
class="ant-checkbox-wrapper">
<span
class="ant-checkbox ant-checkbox-disabled">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
disabled=""
type="checkbox" />
</span>
</label>
<span />
</li>
</ul>
<div
class="ant-transfer-list-body-not-found">
Not Found
</div>
</div>
</div>
<div
class="ant-transfer-operation">
<button
class="ant-btn ant-btn-primary ant-btn-sm"
disabled=""
type="button">
<span>
<i
class="anticon anticon-left" />
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-sm"
type="button">
<span>
<i
class="anticon anticon-right" />
</span>
</button>
</div>
<div
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<label
class="ant-checkbox-wrapper">
<span
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
1
</span>
<span
class="ant-transfer-list-header-title" />
</span>
</div>
<div
class="ant-transfer-list-body">
<ul
class="ant-transfer-list-content">
<li
class="ant-transfer-list-content-item">
<label
class="ant-checkbox-wrapper">
<span
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span />
</li>
</ul>
<div
class="ant-transfer-list-body-not-found">
Not Found
</div>
</div>
</div>
</div>
`;

View File

@ -0,0 +1,84 @@
exports[`List should render correctly 1`] = `
<div
class="ant-transfer-list">
<div
class="ant-transfer-list-header">
<label
class="ant-checkbox-wrapper">
<span
class="ant-checkbox-indeterminate ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span
class="ant-transfer-list-header-selected">
<span>
1/3
</span>
<span
class="ant-transfer-list-header-title" />
</span>
</div>
<div
class="ant-transfer-list-body">
<ul
class="ant-transfer-list-content">
<li
class="ant-transfer-list-content-item">
<label
class="ant-checkbox-wrapper">
<span
class="ant-checkbox ant-checkbox-checked ant-checkbox-checked-1">
<span
class="ant-checkbox-inner" />
<input
checked=""
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span />
</li>
<li
class="ant-transfer-list-content-item">
<label
class="ant-checkbox-wrapper">
<span
class="ant-checkbox">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
type="checkbox" />
</span>
</label>
<span />
</li>
<li
class="ant-transfer-list-content-item ant-transfer-list-content-item-disabled">
<label
class="ant-checkbox-wrapper">
<span
class="ant-checkbox ant-checkbox-disabled">
<span
class="ant-checkbox-inner" />
<input
class="ant-checkbox-input"
disabled=""
type="checkbox" />
</span>
</label>
<span />
</li>
</ul>
<div
class="ant-transfer-list-body-not-found">
Not Found
</div>
</div>
</div>
`;

View File

@ -0,0 +1,85 @@
import React from 'react';
import { render, mount } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import Transfer from '..';
import TransferList from '../list';
import TransferOperation from '../operation';
import TransferSearch from '../search';
import TransferItem from '../item';
import Button from '../../button';
import Checkbox from '../../checkbox';
const listCommonProps = {
dataSource: [{
key: 'a',
title: 'a',
}, {
key: 'b',
title: 'b',
}, {
key: 'c',
title: 'c',
disabled: true,
}],
selectedKeys: ['a'],
targetKeys: ['b'],
lazy: false,
};
describe('Transfer', () => {
it('should render correctly', () => {
const wrapper = render(<Transfer {...listCommonProps} />);
expect(renderToJson(wrapper)).toMatchSnapshot();
});
it('should move selected keys to corresponding list', () => {
const handleChange = jest.fn();
const wrapper = mount(<Transfer {...listCommonProps} onChange={handleChange} />);
wrapper.find(TransferOperation).find(Button).at(1).simulate('click'); // move selected keys to right list
expect(handleChange).toHaveBeenCalledWith(['a', 'b'], 'right', ['a']);
});
it('should uncheck checkbox when click on checked item', () => {
const handleSelectChange = jest.fn();
const wrapper = mount(<Transfer {...listCommonProps} onSelectChange={handleSelectChange} />);
wrapper.find(TransferItem).filterWhere(n => n.prop('item').key === 'a').simulate('click');
expect(handleSelectChange).toHaveBeenLastCalledWith([], []);
});
it('should check checkbox when click on unchecked item', () => {
const handleSelectChange = jest.fn();
const wrapper = mount(<Transfer {...listCommonProps} onSelectChange={handleSelectChange} />);
wrapper.find(TransferItem).filterWhere(n => n.prop('item').key === 'b').simulate('click');
expect(handleSelectChange).toHaveBeenLastCalledWith(['a'], ['b']);
});
it('should not check checkbox when click on disabled item', () => {
const handleSelectChange = jest.fn();
const wrapper = mount(<Transfer {...listCommonProps} onSelectChange={handleSelectChange} />);
wrapper.find(TransferItem).filterWhere(n => n.prop('item').key === 'c').simulate('click');
expect(handleSelectChange).not.toHaveBeenCalled();
});
it('should check all item when click on check all', () => {
const handleSelectChange = jest.fn();
const wrapper = mount(<Transfer {...listCommonProps} onSelectChange={handleSelectChange} />);
wrapper.find('.ant-transfer-list-header input[type="checkbox"]')
.filterWhere(n => !n.prop('checked')).simulate('change');
expect(handleSelectChange).toHaveBeenCalledWith(['a'], ['b']);
});
it('should uncheck all item when click on uncheck all', () => {
const handleSelectChange = jest.fn();
const wrapper = mount(<Transfer {...listCommonProps} onSelectChange={handleSelectChange} />);
wrapper.find('.ant-transfer-list-header input[type="checkbox"]')
.filterWhere(n => n.prop('checked')).simulate('change');
expect(handleSelectChange).toHaveBeenCalledWith([], []);
});
it('should call `filterOption` when use input in search box', () => {
const filterOption = (inputValue, option) => inputValue === option.title;
const wrapper = mount(<Transfer {...listCommonProps} showSearch filterOption={filterOption} />);
wrapper.find(TransferSearch).at(0).find('input').simulate('change', { target: { value: 'a' } });
expect(wrapper.find(TransferList).at(0).find(TransferItem).find(Checkbox)).toHaveLength(1);
});
});

View File

@ -0,0 +1,35 @@
import React from 'react';
import { render, mount } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import List from '../list';
import Checkbox from '../../checkbox';
const listCommonProps = {
prefixCls: 'ant-transfer-list',
dataSource: [{
key: 'a',
title: 'a',
}, {
key: 'b',
title: 'b',
}, {
key: 'c',
title: 'c',
disabled: true,
}],
checkedKeys: ['a'],
lazy: false,
};
describe('List', () => {
it('should render correctly', () => {
const wrapper = render(<List {...listCommonProps} />);
expect(renderToJson(wrapper)).toMatchSnapshot();
});
it('should check top Checkbox while all available items are checked', () => {
const wrapper = mount(<List {...listCommonProps} checkedKeys={['a', 'b']} />);
expect(wrapper.find('.ant-transfer-list-header').find(Checkbox).prop('checked'))
.toBeTruthy();
});
});

View File

@ -76,7 +76,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
body: PropTypes.func,
footer: PropTypes.func,
rowKey: PropTypes.func,
lazy: PropTypes.object,
lazy: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
};
static contextTypes = {

View File

@ -43,24 +43,29 @@ export default class Item extends React.Component<any, any> {
[`${prefixCls}-content-item-disabled`]: item.disabled,
});
const lazyProps = assign({
height: 32,
offset: 500,
throttle: 0,
debounce: false,
}, lazy);
return (
<Lazyload {...lazyProps}>
<li
className={className}
title={renderedText}
onClick={item.disabled ? undefined : () => onClick(item)}
>
<Checkbox checked={checked} disabled={item.disabled} />
<span>{renderedEl}</span>
</li>
</Lazyload>
const listItem = (
<li
className={className}
title={renderedText}
onClick={item.disabled ? undefined : () => onClick(item)}
>
<Checkbox checked={checked} disabled={item.disabled} />
<span>{renderedEl}</span>
</li>
);
let children: JSX.Element | null = null;
if (lazy) {
const lazyProps = assign({
height: 32,
offset: 500,
throttle: 0,
debounce: false,
}, lazy);
children = <Lazyload {...lazyProps}>{listItem}</Lazyload>;
} else {
children = listItem;
}
return children;
}
}

View File

@ -1,11 +1,12 @@
import React from 'react';
import Search from './search';
import classNames from 'classnames';
import Animate from 'rc-animate';
import PureRenderMixin from 'rc-util/lib/PureRenderMixin';
import assign from 'object-assign';
import { TransferItem } from './index';
import Search from './search';
import Item from './item';
import Checkbox from '../checkbox';
function noop() {
}
@ -30,7 +31,7 @@ export interface TransferListProps {
position?: string;
notFoundContent?: React.ReactNode | string;
filterOption: (filterText: any, item: any) => boolean;
lazy?: {};
lazy?: boolean | {};
}
export interface TransferListContext {
@ -45,6 +46,7 @@ export default class TransferList extends React.Component<TransferListProps, any
titleText: '',
showSearch: false,
render: noop,
lazy: {},
};
static contextTypes = {
@ -101,27 +103,6 @@ export default class TransferList extends React.Component<TransferListProps, any
this.props.handleClear();
}
renderCheckbox({ prefixCls, filteredDataSource, checked, checkPart, disabled, checkable }) {
const checkAll = (!checkPart) && checked;
const checkboxCls = classNames({
[`${prefixCls}-checkbox`]: true,
[`${prefixCls}-checkbox-indeterminate`]: checkPart,
[`${prefixCls}-checkbox-checked`]: checkAll,
[`${prefixCls}-checkbox-disabled`]: disabled,
});
return (
<span
ref="checkbox"
className={checkboxCls}
onClick={() => this.props.handleSelectAll(filteredDataSource, checkAll)}
>
{(typeof checkable !== 'boolean') ? checkable : null}
</span>
);
}
render() {
const { prefixCls, dataSource, titleText, filter, checkedKeys, lazy, filterOption,
body = noop, footer = noop, showSearch, render = noop, style } = this.props;
@ -167,8 +148,6 @@ export default class TransferList extends React.Component<TransferListProps, any
notFoundContent = notFoundContent || transferLocale.notFoundContent;
}
const checkStatus = this.getCheckStatus(filteredDataSource);
const outerPrefixCls = prefixCls.replace('-list', '');
const search = showSearch ? (
<div className={`${prefixCls}-body-search-wrapper`}>
<Search
@ -204,19 +183,21 @@ export default class TransferList extends React.Component<TransferListProps, any
</div>
) : null;
const renderedCheckbox = this.renderCheckbox({
prefixCls: outerPrefixCls,
checked: checkStatus === 'all',
checkPart: checkStatus === 'part',
checkable: <span className={`${outerPrefixCls}-checkbox-inner`} />,
filteredDataSource,
disabled: false,
});
const checkStatus = this.getCheckStatus(filteredDataSource);
const checkedAll = checkStatus === 'all';
const checkAllCheckbox = (
<Checkbox
ref="checkbox"
checked={checkedAll}
indeterminate={checkStatus === 'part'}
onChange={() => this.props.handleSelectAll(filteredDataSource, checkedAll)}
/>
);
return (
<div className={listCls} style={style}>
<div className={`${prefixCls}-header`}>
{renderedCheckbox}
{checkAllCheckbox}
<span className={`${prefixCls}-header-selected`}>
<span>
{(checkedKeys.length > 0 ? `${checkedKeys.length}/` : '') + dataSource.length} {unit}

View File

@ -3,7 +3,6 @@
@import "../../checkbox/style/mixin";
@transfer-prefix-cls: ~"@{ant-prefix}-transfer";
.antCheckboxFn(@checkbox-prefix-cls: ~"@{ant-prefix}-transfer-checkbox");
.@{transfer-prefix-cls} {
position: relative;