Implement column formatter (#13)

fix #12
This commit is contained in:
Allen 2017-08-20 04:04:45 -05:00 committed by GitHub
parent 6b7d1f9aa2
commit 7c424a2373
7 changed files with 78 additions and 17 deletions

View File

@ -41,6 +41,7 @@
"jest-babel": "^1.0.1", "jest-babel": "^1.0.1",
"lerna": "^2.0.0", "lerna": "^2.0.0",
"react-test-renderer": "^15.6.1", "react-test-renderer": "^15.6.1",
"sinon": "^3.2.1",
"webpack": "^3.5.4", "webpack": "^3.5.4",
"webpack-dev-server": "^2.7.1" "webpack-dev-server": "^2.7.1"
}, },

View File

@ -6,8 +6,13 @@ import Row from './row';
const Body = ({ columns, data, keyField }) => ( const Body = ({ columns, data, keyField }) => (
<tbody> <tbody>
{ {
data.map(row => ( data.map((row, index) => (
<Row key={ row[keyField] } row={ row } columns={ columns } /> <Row
key={ row[keyField] }
row={ row }
rowIndex={ index }
columns={ columns }
/>
)) ))
} }
</tbody> </tbody>

View File

@ -2,12 +2,20 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
const Cell = ({ value }) => ( const Cell = ({ row, rowIndex, column }) => {
<td>{ value }</td> let content = row[column.dataField];
); if (column.formatter) {
content = column.formatter(content, row, rowIndex, column.formatExtraData);
}
return (
<td>{ content }</td>
);
};
Cell.propTypes = { Cell.propTypes = {
value: PropTypes.any.isRequired row: PropTypes.object.isRequired,
rowIndex: PropTypes.number.isRequired,
column: PropTypes.object.isRequired
}; };
export default Cell; export default Cell;

View File

@ -3,18 +3,25 @@ import PropTypes from 'prop-types';
import Cell from './cell'; import Cell from './cell';
const Row = ({ row, columns }) => ( const Row = ({ row, rowIndex, columns }) => (
<tr> <tr>
{ {
columns.map(column => columns.map(column =>
<Cell key={ row[column.dataField] } value={ row[column.dataField] } /> (
) <Cell
key={ row[column.dataField] }
row={ row }
rowIndex={ rowIndex }
column={ column }
/>
))
} }
</tr> </tr>
); );
Row.propTypes = { Row.propTypes = {
row: PropTypes.object.isRequired, row: PropTypes.object.isRequired,
rowIndex: PropTypes.number.isRequired,
columns: PropTypes.array.isRequired columns: PropTypes.array.isRequired
}; };

View File

@ -41,7 +41,7 @@ describe('BootstrapTable', () => {
}); });
}); });
describe('when hover is true', () => { describe('when hover props is true', () => {
beforeEach(() => { beforeEach(() => {
wrapper = shallow(<BootstrapTable keyField="id" columns={ columns } data={ data } hover />); wrapper = shallow(<BootstrapTable keyField="id" columns={ columns } data={ data } hover />);
}); });
@ -51,7 +51,7 @@ describe('BootstrapTable', () => {
}); });
}); });
describe('when striped is true', () => { describe('when striped props is true', () => {
beforeEach(() => { beforeEach(() => {
wrapper = shallow(<BootstrapTable keyField="id" columns={ columns } data={ data } striped />); wrapper = shallow(<BootstrapTable keyField="id" columns={ columns } data={ data } striped />);
}); });
@ -61,7 +61,7 @@ describe('BootstrapTable', () => {
}); });
}); });
describe('when condensed is true', () => { describe('when condensed props is true', () => {
beforeEach(() => { beforeEach(() => {
wrapper = shallow(<BootstrapTable keyField="id" columns={ columns } data={ data } condensed />); wrapper = shallow(<BootstrapTable keyField="id" columns={ columns } data={ data } condensed />);
}); });
@ -71,7 +71,7 @@ describe('BootstrapTable', () => {
}); });
}); });
describe('when bordered is false', () => { describe('when bordered props is false', () => {
beforeEach(() => { beforeEach(() => {
wrapper = shallow(<BootstrapTable keyField="id" columns={ columns } data={ data } bordered={ false } />); wrapper = shallow(<BootstrapTable keyField="id" columns={ columns } data={ data } bordered={ false } />);
}); });

View File

@ -1,20 +1,60 @@
import React from 'react'; import React from 'react';
import sinon from 'sinon';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import Cell from '../src/cell'; import Cell from '../src/cell';
describe('Cell', () => { describe('Cell', () => {
let wrapper; let wrapper;
const value = 'test'; const row = {
id: 1,
name: 'A'
};
describe('simplest cell', () => { describe('simplest cell', () => {
const column = {
dataField: 'id',
text: 'ID'
};
beforeEach(() => { beforeEach(() => {
wrapper = shallow(<Cell value={ value } />); wrapper = shallow(<Cell row={ row } rowIndex={ 1 } column={ column } />);
}); });
it('should render successfully', () => { it('should render successfully', () => {
expect(wrapper.length).toBe(1); expect(wrapper.length).toBe(1);
expect(wrapper.contains(<td>{ value }</td>)).toBe(true); expect(wrapper.contains(<td>{ row[column.dataField] }</td>)).toBe(true);
});
});
describe('when formatter prop is defined', () => {
const rowIndex = 1;
const column = {
dataField: 'id',
text: 'ID',
formatExtraData: []
};
const formatterResult = (<h3>{ row[column.dataField] }</h3>);
const formatter = sinon.stub()
.withArgs(row[column.dataField], row, rowIndex, column.formatExtraData)
.returns(formatterResult);
column.formatter = formatter; // defined column formatter
beforeEach(() => {
wrapper = shallow(<Cell row={ row } rowIndex={ rowIndex } column={ column } />);
});
afterEach(() => { formatter.reset(); });
it('should render successfully', () => {
expect(wrapper.length).toBe(1);
expect(wrapper.contains(<td><h3>{ row[column.dataField] }</h3></td>)).toBe(true);
});
it('should call custom formatter correctly', () => {
expect(formatter.callCount).toBe(1);
expect(formatter.calledWith(row[column.dataField],
row, rowIndex, column.formatExtraData)).toBe(true);
}); });
}); });
}); });

View File

@ -21,7 +21,7 @@ describe('Row', () => {
describe('simplest row', () => { describe('simplest row', () => {
beforeEach(() => { beforeEach(() => {
wrapper = shallow(<Row columns={ columns } row={ row } />); wrapper = shallow(<Row rowIndex={ 1 } columns={ columns } row={ row } />);
}); });
it('should render successfully', () => { it('should render successfully', () => {