[refactor] Migrate from Mocha+Chai to Jest (#6079)

* [refactor] Migrate from Mocha+Chai to Jest

This change migrates all the existing unit tests
- to Jest's global expect and matchers from chai's imported expect, asserts and matchers.
- to Jest's describe/test from mocha's describe/it

The majority of the mechanical changes to tests are achieved through running jest-codemods. The only two note-worthy manual tweaks:
1. Setting a testURL of http://localhost in jest config and adjusting a few tests to leverage this value instead of relying on about:blank.
2. Re-enabling ExploreChartPanel_spec which was previously commented out as we cannot have empty tests with nothing in it with Jest. :)

This change also removes dependencies to Mocha and Chai.

* Remove the test:one command as it now does the same thing as test.

* Fixing lint errors. The diff looks large but is large done through `yarn run lint --fix`

The only noteworthy change is the one in eslintrc for tests. The env has been updated from mocha to jest.

* Adding eslint-plugin-jest and further modify tests.

- One small fix in sqllab's Timer Spec for a test that is not using the spy it created for testing.
- Deletion of a duplicated test caught by eslint-plugin-jest.

* - Make istanbul coverage work with Jest.

- Remove dependency on stand-alone istanbul and babel-istanbul as they're built-into jest. Yes!

* Attempt to fix dynamic imports in tests.

* run sequentially and log heap usage

* - tweaking maxworkers for travis and specifying coverageDirectory for codecov

- remove dynamic import in shim.js now that it is set in babelrc for tests only.
This commit is contained in:
Christine Chambers
2018-10-15 13:10:18 -07:00
committed by Chris Williams
parent 46c86672c8
commit 9029701f24
177 changed files with 2539 additions and 2166 deletions

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { shallow } from 'enzyme';
import { expect } from 'chai';
import { Table, Thead, Td, Th, Tr } from 'reactable';
@@ -105,9 +104,9 @@ describe('AlteredSliceTag', () => {
it('correctly determines form data differences', () => {
const diffs = wrapper.instance().getDiffs(props);
expect(diffs).to.deep.equal(expectedDiffs);
expect(wrapper.instance().state.diffs).to.deep.equal(expectedDiffs);
expect(wrapper.instance().state.hasDiffs).to.equal(true);
expect(diffs).toEqual(expectedDiffs);
expect(wrapper.instance().state.diffs).toEqual(expectedDiffs);
expect(wrapper.instance().state.hasDiffs).toBe(true);
});
it('does not run when there are no differences', () => {
@@ -116,9 +115,9 @@ describe('AlteredSliceTag', () => {
currentFormData: props.origFormData,
};
wrapper = shallow(<AlteredSliceTag {...props} />);
expect(wrapper.instance().state.diffs).to.deep.equal({});
expect(wrapper.instance().state.hasDiffs).to.equal(false);
expect(wrapper.instance().render()).to.equal(null);
expect(wrapper.instance().state.diffs).toEqual({});
expect(wrapper.instance().state.hasDiffs).toBe(false);
expect(wrapper.instance().render()).toBeNull();
});
it('sets new diffs when receiving new props', () => {
@@ -131,59 +130,59 @@ describe('AlteredSliceTag', () => {
wrapper.instance().componentWillReceiveProps(newProps);
const newDiffs = wrapper.instance().state.diffs;
const expectedBeta = { before: undefined, after: 10 };
expect(newDiffs.beta).to.deep.equal(expectedBeta);
expect(newDiffs.beta).toEqual(expectedBeta);
});
it('does not set new state when props are the same', () => {
const currentDiff = wrapper.instance().state.diffs;
wrapper.instance().componentWillReceiveProps(props);
// Check equal references
expect(wrapper.instance().state.diffs).to.equal(currentDiff);
expect(wrapper.instance().state.diffs).toBe(currentDiff);
});
it('renders a ModalTrigger', () => {
expect(wrapper.find(ModalTrigger)).to.have.lengthOf(1);
expect(wrapper.find(ModalTrigger)).toHaveLength(1);
});
describe('renderTriggerNode', () => {
it('renders a TooltipWrapper', () => {
const triggerNode = shallow(<div>{wrapper.instance().renderTriggerNode()}</div>);
expect(triggerNode.find(TooltipWrapper)).to.have.lengthOf(1);
expect(triggerNode.find(TooltipWrapper)).toHaveLength(1);
});
});
describe('renderModalBody', () => {
it('renders a Table', () => {
const modalBody = shallow(<div>{wrapper.instance().renderModalBody()}</div>);
expect(modalBody.find(Table)).to.have.lengthOf(1);
expect(modalBody.find(Table)).toHaveLength(1);
});
it('renders a Thead', () => {
const modalBody = shallow(<div>{wrapper.instance().renderModalBody()}</div>);
expect(modalBody.find(Thead)).to.have.lengthOf(1);
expect(modalBody.find(Thead)).toHaveLength(1);
});
it('renders Th', () => {
const modalBody = shallow(<div>{wrapper.instance().renderModalBody()}</div>);
const th = modalBody.find(Th);
expect(th).to.have.lengthOf(3);
expect(th).toHaveLength(3);
['control', 'before', 'after'].forEach((v, i) => {
expect(th.get(i).props.column).to.equal(v);
expect(th.get(i).props.column).toBe(v);
});
});
it('renders the correct number of Tr', () => {
const modalBody = shallow(<div>{wrapper.instance().renderModalBody()}</div>);
const tr = modalBody.find(Tr);
expect(tr).to.have.lengthOf(7);
expect(tr).toHaveLength(7);
});
it('renders the correct number of Td', () => {
const modalBody = shallow(<div>{wrapper.instance().renderModalBody()}</div>);
const td = modalBody.find(Td);
expect(td).to.have.lengthOf(21);
expect(td).toHaveLength(21);
['control', 'before', 'after'].forEach((v, i) => {
expect(td.get(i).props.column).to.equal(v);
expect(td.get(i).props.column).toBe(v);
});
});
});
@@ -191,58 +190,56 @@ describe('AlteredSliceTag', () => {
describe('renderRows', () => {
it('returns an array of rows with one Tr and three Td', () => {
const rows = wrapper.instance().renderRows();
expect(rows).to.have.lengthOf(7);
expect(rows).toHaveLength(7);
const fakeRow = shallow(<div>{rows[0]}</div>);
expect(fakeRow.find(Tr)).to.have.lengthOf(1);
expect(fakeRow.find(Td)).to.have.lengthOf(3);
expect(fakeRow.find(Tr)).toHaveLength(1);
expect(fakeRow.find(Td)).toHaveLength(3);
});
});
describe('formatValue', () => {
it('returns "N/A" for undefined values', () => {
expect(wrapper.instance().formatValue(undefined, 'b')).to.equal('N/A');
expect(wrapper.instance().formatValue(undefined, 'b')).toBe('N/A');
});
it('returns "null" for null values', () => {
expect(wrapper.instance().formatValue(null, 'b')).to.equal('null');
expect(wrapper.instance().formatValue(null, 'b')).toBe('null');
});
it('returns "Max" and "Min" for BoundsControl', () => {
expect(wrapper.instance().formatValue([5, 6], 'y_axis_bounds')).to.equal(
'Min: 5, Max: 6',
);
expect(wrapper.instance().formatValue([5, 6], 'y_axis_bounds')).toBe('Min: 5, Max: 6');
});
it('returns stringified objects for CollectionControl', () => {
const value = [{ 1: 2, alpha: 'bravo' }, { sent: 'imental', w0ke: 5 }];
const expected = '{"1":2,"alpha":"bravo"}, {"sent":"imental","w0ke":5}';
expect(wrapper.instance().formatValue(value, 'column_collection')).to.equal(expected);
expect(wrapper.instance().formatValue(value, 'column_collection')).toBe(expected);
});
it('returns boolean values as string', () => {
expect(wrapper.instance().formatValue(true, 'b')).to.equal('true');
expect(wrapper.instance().formatValue(false, 'b')).to.equal('false');
expect(wrapper.instance().formatValue(true, 'b')).toBe('true');
expect(wrapper.instance().formatValue(false, 'b')).toBe('false');
});
it('returns Array joined by commas', () => {
const value = [5, 6, 7, 8, 'hello', 'goodbye'];
const expected = '5, 6, 7, 8, hello, goodbye';
expect(wrapper.instance().formatValue(value)).to.equal(expected);
expect(wrapper.instance().formatValue(value)).toBe(expected);
});
it('stringifies objects', () => {
const value = { 1: 2, alpha: 'bravo' };
const expected = '{"1":2,"alpha":"bravo"}';
expect(wrapper.instance().formatValue(value)).to.equal(expected);
expect(wrapper.instance().formatValue(value)).toBe(expected);
});
it('does nothing to strings and numbers', () => {
expect(wrapper.instance().formatValue(5)).to.equal(5);
expect(wrapper.instance().formatValue('hello')).to.equal('hello');
expect(wrapper.instance().formatValue(5)).toBe(5);
expect(wrapper.instance().formatValue('hello')).toBe('hello');
});
it('returns "[]" for empty filters', () => {
expect(wrapper.instance().formatValue([], 'adhoc_filters')).to.equal('[]');
expect(wrapper.instance().formatValue([], 'adhoc_filters')).toBe('[]');
});
it('correctly formats filters with array values', () => {
@@ -263,7 +260,7 @@ describe('AlteredSliceTag', () => {
},
];
const expected = 'a in [1, g, 7, ho], b not in [hu, ho, ha]';
expect(wrapper.instance().formatValue(filters, 'adhoc_filters')).to.equal(expected);
expect(wrapper.instance().formatValue(filters, 'adhoc_filters')).toBe(expected);
});
it('correctly formats filters with string values', () => {
@@ -284,7 +281,7 @@ describe('AlteredSliceTag', () => {
},
];
const expected = 'a == gucci, b LIKE moshi moshi';
expect(wrapper.instance().formatValue(filters, 'adhoc_filters')).to.equal(expected);
expect(wrapper.instance().formatValue(filters, 'adhoc_filters')).toBe(expected);
});
});
});

View File

@@ -1,7 +1,6 @@
import React from 'react';
import Select from 'react-select';
import { shallow } from 'enzyme';
import { expect } from 'chai';
import sinon from 'sinon';
import AsyncSelect from '../../../src/components/AsyncSelect';
@@ -20,14 +19,14 @@ describe('AsyncSelect', () => {
it('is valid element', () => {
expect(
React.isValidElement(<AsyncSelect {...mockedProps} />),
).to.equal(true);
).toBe(true);
});
it('has one select', () => {
const wrapper = shallow(
<AsyncSelect {...mockedProps} />,
);
expect(wrapper.find(Select)).to.have.length(1);
expect(wrapper.find(Select)).toHaveLength(1);
});
it('calls onChange on select change', () => {
@@ -35,7 +34,7 @@ describe('AsyncSelect', () => {
<AsyncSelect {...mockedProps} />,
);
wrapper.find(Select).simulate('change', { value: 1 });
expect(mockedProps.onChange).to.have.property('callCount', 1);
expect(mockedProps.onChange).toHaveProperty('callCount', 1);
});
describe('auto select', () => {
@@ -55,7 +54,7 @@ describe('AsyncSelect', () => {
);
wrapper.instance().fetchOptions();
const spy = sinon.spy(wrapper.instance(), 'onChange');
expect(spy.callCount).to.equal(0);
expect(spy.callCount).toBe(0);
});
it('should auto select first option', () => {
const wrapper = shallow(
@@ -64,8 +63,8 @@ describe('AsyncSelect', () => {
const spy = sinon.spy(wrapper.instance(), 'onChange');
server.respond();
expect(spy.callCount).to.equal(1);
expect(spy.calledWith(wrapper.instance().state.options[0])).to.equal(true);
expect(spy.callCount).toBe(1);
expect(spy.calledWith(wrapper.instance().state.options[0])).toBe(true);
});
it('should not auto select when value prop is set', () => {
const wrapper = shallow(
@@ -75,8 +74,8 @@ describe('AsyncSelect', () => {
wrapper.instance().fetchOptions();
server.respond();
expect(spy.callCount).to.equal(0);
expect(wrapper.find(Select)).to.have.length(1);
expect(spy.callCount).toBe(0);
expect(wrapper.find(Select)).toHaveLength(1);
});
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import { Label } from 'react-bootstrap';
@@ -14,12 +13,12 @@ describe('CachedLabel', () => {
it('is valid', () => {
expect(
React.isValidElement(<CachedLabel {...defaultProps} />),
).to.equal(true);
).toBe(true);
});
it('renders', () => {
const wrapper = shallow(
<CachedLabel {...defaultProps} />,
);
expect(wrapper.find(Label)).to.have.length(1);
expect(wrapper.find(Label)).toHaveLength(1);
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import sinon from 'sinon';
import { shallow } from 'enzyme';
@@ -20,19 +19,19 @@ describe('Checkbox', () => {
wrapper = factory({});
});
it('is a valid element', () => {
expect(React.isValidElement(<Checkbox {...defaultProps} />)).to.equal(true);
expect(React.isValidElement(<Checkbox {...defaultProps} />)).toBe(true);
});
it('inits checked when checked', () => {
expect(wrapper.find('i.fa-check.text-primary')).to.have.length(1);
expect(wrapper.find('i.fa-check.text-primary')).toHaveLength(1);
});
it('inits unchecked when not checked', () => {
const el = factory({ checked: false });
expect(el.find('i.fa-check.text-primary')).to.have.length(0);
expect(el.find('i.fa-check.text-transparent')).to.have.length(1);
expect(el.find('i.fa-check.text-primary')).toHaveLength(0);
expect(el.find('i.fa-check.text-transparent')).toHaveLength(1);
});
it('unchecks when clicked', () => {
expect(wrapper.find('i.fa-check.text-transparent')).to.have.length(0);
expect(wrapper.find('i.fa-check.text-transparent')).toHaveLength(0);
wrapper.find('i').first().simulate('click');
expect(defaultProps.onChange.calledOnce).to.equal(true);
expect(defaultProps.onChange.calledOnce).toBe(true);
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import ColumnOption from '../../../src/components/ColumnOption';
@@ -25,25 +24,25 @@ describe('ColumnOption', () => {
props = Object.assign({}, defaultProps);
});
it('is a valid element', () => {
expect(React.isValidElement(<ColumnOption {...defaultProps} />)).to.equal(true);
expect(React.isValidElement(<ColumnOption {...defaultProps} />)).toBe(true);
});
it('shows a label with verbose_name', () => {
const lbl = wrapper.find('.option-label');
expect(lbl).to.have.length(1);
expect(lbl.first().text()).to.equal('Foo');
expect(lbl).toHaveLength(1);
expect(lbl.first().text()).toBe('Foo');
});
it('shows 2 InfoTooltipWithTrigger', () => {
expect(wrapper.find(InfoTooltipWithTrigger)).to.have.length(2);
expect(wrapper.find(InfoTooltipWithTrigger)).toHaveLength(2);
});
it('shows only 1 InfoTooltipWithTrigger when no descr', () => {
props.column.description = null;
wrapper = shallow(factory(props));
expect(wrapper.find(InfoTooltipWithTrigger)).to.have.length(1);
expect(wrapper.find(InfoTooltipWithTrigger)).toHaveLength(1);
});
it('shows a label with column_name when no verbose_name', () => {
props.column.verbose_name = null;
wrapper = shallow(factory(props));
expect(wrapper.find('.option-label').first().text()).to.equal('foo');
expect(wrapper.find('.option-label').first().text()).toBe('foo');
});
it('shows a column type label when showType is true', () => {
wrapper = shallow(factory({
@@ -54,13 +53,13 @@ describe('ColumnOption', () => {
type: 'str',
},
}));
expect(wrapper.find(ColumnTypeLabel)).to.have.length(1);
expect(wrapper.find(ColumnTypeLabel)).toHaveLength(1);
});
it('column with expression has correct column label if showType is true', () => {
props.showType = true;
wrapper = shallow(factory(props));
expect(wrapper.find(ColumnTypeLabel)).to.have.length(1);
expect(wrapper.find(ColumnTypeLabel).props().type).to.equal('expression');
expect(wrapper.find(ColumnTypeLabel)).toHaveLength(1);
expect(wrapper.find(ColumnTypeLabel).props().type).toBe('expression');
});
it('shows no column type label when type is null', () => {
wrapper = shallow(factory({
@@ -71,13 +70,13 @@ describe('ColumnOption', () => {
type: null,
},
}));
expect(wrapper.find(ColumnTypeLabel)).to.have.length(0);
expect(wrapper.find(ColumnTypeLabel)).toHaveLength(0);
});
it('dttm column has correct column label if showType is true', () => {
props.showType = true;
props.column.is_dttm = true;
wrapper = shallow(factory(props));
expect(wrapper.find(ColumnTypeLabel)).to.have.length(1);
expect(wrapper.find(ColumnTypeLabel).props().type).to.equal('time');
expect(wrapper.find(ColumnTypeLabel)).toHaveLength(1);
expect(wrapper.find(ColumnTypeLabel).props().type).toBe('time');
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import ColumnTypeLabel from '../../../src/components/ColumnTypeLabel';
@@ -17,35 +16,35 @@ describe('ColumnOption', () => {
}
it('is a valid element', () => {
expect(React.isValidElement(<ColumnTypeLabel {...defaultProps} />)).to.equal(true);
expect(React.isValidElement(<ColumnTypeLabel {...defaultProps} />)).toBe(true);
});
it('string type shows ABC icon', () => {
const lbl = getWrapper({}).find('.type-label');
expect(lbl).to.have.length(1);
expect(lbl.first().text()).to.equal('ABC');
expect(lbl).toHaveLength(1);
expect(lbl.first().text()).toBe('ABC');
});
it('int type shows # icon', () => {
const lbl = getWrapper({ type: 'int(164)' }).find('.type-label');
expect(lbl).to.have.length(1);
expect(lbl.first().text()).to.equal('#');
expect(lbl).toHaveLength(1);
expect(lbl.first().text()).toBe('#');
});
it('bool type shows T/F icon', () => {
const lbl = getWrapper({ type: 'BOOL' }).find('.type-label');
expect(lbl).to.have.length(1);
expect(lbl.first().text()).to.equal('T/F');
expect(lbl).toHaveLength(1);
expect(lbl.first().text()).toBe('T/F');
});
it('expression type shows function icon', () => {
const lbl = getWrapper({ type: 'expression' }).find('.type-label');
expect(lbl).to.have.length(1);
expect(lbl.first().text()).to.equal('ƒ');
expect(lbl).toHaveLength(1);
expect(lbl.first().text()).toBe('ƒ');
});
it('unknown type shows question mark', () => {
const lbl = getWrapper({ type: 'unknown' }).find('.type-label');
expect(lbl).to.have.length(1);
expect(lbl.first().text()).to.equal('?');
expect(lbl).toHaveLength(1);
expect(lbl.first().text()).toBe('?');
});
it('unknown type shows question mark', () => {
it('datetime type displays', () => {
const lbl = getWrapper({ type: 'datetime' }).find('.fa-clock-o');
expect(lbl).to.have.length(1);
expect(lbl).toHaveLength(1);
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import CopyToClipboard from '../../../src/components/CopyToClipboard';
@@ -11,6 +10,6 @@ describe('CopyToClipboard', () => {
it('renders', () => {
expect(
React.isValidElement(<CopyToClipboard {...defaultProps} />),
).to.equal(true);
).toBe(true);
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import FilterableTable from '../../../../src/components/FilterableTable/FilterableTable';
@@ -17,11 +16,11 @@ describe('FilterableTable', () => {
wrapper = mount(<FilterableTable {...mockedProps} />);
});
it('is valid element', () => {
expect(React.isValidElement(<FilterableTable {...mockedProps} />)).to.equal(true);
expect(React.isValidElement(<FilterableTable {...mockedProps} />)).toBe(true);
});
it('renders a grid with 2 rows', () => {
expect(wrapper.find('.ReactVirtualized__Grid')).to.have.length(1);
expect(wrapper.find('.ReactVirtualized__Table__row')).to.have.length(2);
expect(wrapper.find('.ReactVirtualized__Grid')).toHaveLength(1);
expect(wrapper.find('.ReactVirtualized__Table__row')).toHaveLength(2);
});
it('filters on a string', () => {
const props = {
@@ -29,7 +28,7 @@ describe('FilterableTable', () => {
filterText: 'b1',
};
wrapper = mount(<FilterableTable {...props} />);
expect(wrapper.find('.ReactVirtualized__Table__row')).to.have.length(1);
expect(wrapper.find('.ReactVirtualized__Table__row')).toHaveLength(1);
});
it('filters on a number', () => {
const props = {
@@ -37,6 +36,6 @@ describe('FilterableTable', () => {
filterText: '100',
};
wrapper = mount(<FilterableTable {...props} />);
expect(wrapper.find('.ReactVirtualized__Table__row')).to.have.length(1);
expect(wrapper.find('.ReactVirtualized__Table__row')).toHaveLength(1);
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import MetricOption from '../../../src/components/MetricOption';
@@ -26,43 +25,43 @@ describe('MetricOption', () => {
props = Object.assign({}, defaultProps);
});
it('is a valid element', () => {
expect(React.isValidElement(<MetricOption {...defaultProps} />)).to.equal(true);
expect(React.isValidElement(<MetricOption {...defaultProps} />)).toBe(true);
});
it('shows a label with verbose_name', () => {
const lbl = wrapper.find('.option-label');
expect(lbl).to.have.length(1);
expect(lbl.first().text()).to.equal('Foo');
expect(lbl).toHaveLength(1);
expect(lbl.first().text()).toBe('Foo');
});
it('shows 3 InfoTooltipWithTrigger', () => {
expect(wrapper.find(InfoTooltipWithTrigger)).to.have.length(3);
expect(wrapper.find(InfoTooltipWithTrigger)).toHaveLength(3);
});
it('shows only 2 InfoTooltipWithTrigger when no descr', () => {
props.metric.description = null;
wrapper = shallow(factory(props));
expect(wrapper.find(InfoTooltipWithTrigger)).to.have.length(2);
expect(wrapper.find(InfoTooltipWithTrigger)).toHaveLength(2);
});
it('shows a label with metric_name when no verbose_name', () => {
props.metric.verbose_name = null;
wrapper = shallow(factory(props));
expect(wrapper.find('.option-label').first().text()).to.equal('foo');
expect(wrapper.find('.option-label').first().text()).toBe('foo');
});
it('shows only 1 InfoTooltipWithTrigger when no descr and no warning', () => {
props.metric.warning_text = null;
wrapper = shallow(factory(props));
expect(wrapper.find(InfoTooltipWithTrigger)).to.have.length(1);
expect(wrapper.find(InfoTooltipWithTrigger)).toHaveLength(1);
});
it('sets target="_blank" when openInNewWindow is true', () => {
props.url = 'https://github.com/apache/incubator-superset';
wrapper = shallow(factory(props));
expect(wrapper.find('a').prop('target')).to.equal(null);
expect(wrapper.find('a').prop('target')).toBeNull();
props.openInNewWindow = true;
wrapper = shallow(factory(props));
expect(wrapper.find('a').prop('target')).to.equal('_blank');
expect(wrapper.find('a').prop('target')).toBe('_blank');
});
it('shows a metric type label when showType is true', () => {
props.showType = true;
wrapper = shallow(factory(props));
expect(wrapper.find(ColumnTypeLabel)).to.have.length(1);
expect(wrapper.find(ColumnTypeLabel)).toHaveLength(1);
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import ModalTrigger from '../../../src/components/ModalTrigger';
@@ -13,6 +12,6 @@ describe('ModalTrigger', () => {
it('is a valid element', () => {
expect(
React.isValidElement(<ModalTrigger {...defaultProps} />),
).to.equal(true);
).toBe(true);
});
});

View File

@@ -1,7 +1,6 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import sinon from 'sinon';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import VirtualizedSelect from 'react-virtualized-select';
import Select, { Creatable } from 'react-select';
@@ -44,25 +43,25 @@ describe('OnPasteSelect', () => {
it('renders the supplied selectWrap component', () => {
const select = wrapper.find(Select);
expect(select).to.have.lengthOf(1);
expect(select).toHaveLength(1);
});
it('renders custom selectWrap components', () => {
props.selectWrap = Creatable;
wrapper = shallow(<OnPasteSelect {...props} />);
expect(wrapper.find(Creatable)).to.have.lengthOf(1);
expect(wrapper.find(Creatable)).toHaveLength(1);
props.selectWrap = VirtualizedSelect;
wrapper = shallow(<OnPasteSelect {...props} />);
expect(wrapper.find(VirtualizedSelect)).to.have.lengthOf(1);
expect(wrapper.find(VirtualizedSelect)).toHaveLength(1);
});
describe('onPaste', () => {
it('calls onChange with pasted values', () => {
wrapper.instance().onPaste(evt);
expected = props.options.slice(0, 4);
expect(props.onChange.calledWith(expected)).to.be.true;
expect(evt.preventDefault.called).to.be.true;
expect(props.isValidNewOption.callCount).to.equal(5);
expect(props.onChange.calledWith(expected)).toBe(true);
expect(evt.preventDefault.called).toBe(true);
expect(props.isValidNewOption.callCount).toBe(5);
});
it('calls onChange without any duplicate values and adds new values', () => {
@@ -75,10 +74,10 @@ describe('OnPasteSelect', () => {
{ label: 'Chi na', value: 'Chi na' },
];
wrapper.instance().onPaste(evt);
expect(props.onChange.calledWith(expected)).to.be.true;
expect(evt.preventDefault.called).to.be.true;
expect(props.isValidNewOption.callCount).to.equal(9);
expect(props.options[0].value).to.equal(expected[2].value);
expect(props.onChange.calledWith(expected)).toBe(true);
expect(evt.preventDefault.called).toBe(true);
expect(props.isValidNewOption.callCount).toBe(9);
expect(props.options[0].value).toBe(expected[2].value);
props.options.splice(0, 1);
});
@@ -96,9 +95,9 @@ describe('OnPasteSelect', () => {
props.options[2],
];
wrapper.instance().onPaste(evt);
expect(props.onChange.calledWith(expected)).to.be.true;
expect(evt.preventDefault.called).to.be.true;
expect(props.isValidNewOption.callCount).to.equal(11);
expect(props.onChange.calledWith(expected)).toBe(true);
expect(evt.preventDefault.called).toBe(true);
expect(props.isValidNewOption.callCount).toBe(11);
});
});
});

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { shallow } from 'enzyme';
import { expect } from 'chai';
import InfoTooltipWithTrigger from '../../../src/components/InfoTooltipWithTrigger';
import OptionDescription from '../../../src/components/OptionDescription';
@@ -22,10 +21,10 @@ describe('OptionDescription', () => {
});
it('renders an InfoTooltipWithTrigger', () => {
expect(wrapper.find(InfoTooltipWithTrigger)).to.have.lengthOf(1);
expect(wrapper.find(InfoTooltipWithTrigger)).toHaveLength(1);
});
it('renders a span with the label', () => {
expect(wrapper.find('.option-label').text()).to.equal('Some option');
expect(wrapper.find('.option-label').text()).toBe('Some option');
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import PopoverSection from '../../../src/components/PopoverSection';
@@ -22,12 +21,12 @@ describe('PopoverSection', () => {
wrapper = factory();
});
it('renders', () => {
expect(React.isValidElement(<PopoverSection {...defaultProps} />)).to.equal(true);
expect(React.isValidElement(<PopoverSection {...defaultProps} />)).toBe(true);
});
it('is show an icon when selected', () => {
expect(wrapper.find('.fa-check')).to.have.length(1);
expect(wrapper.find('.fa-check')).toHaveLength(1);
});
it('is show no icon when not selected', () => {
expect(factory({ isSelected: false }).find('.fa-check')).to.have.length(0);
expect(factory({ isSelected: false }).find('.fa-check')).toHaveLength(0);
});
});

View File

@@ -1,6 +1,5 @@
import React from 'react';
import configureStore from 'redux-mock-store';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import { OverlayTrigger } from 'react-bootstrap';
@@ -21,6 +20,6 @@ describe('URLShortLinkButton', () => {
it('renders OverlayTrigger', () => {
const wrapper = setup();
expect(wrapper.find(OverlayTrigger)).have.length(1);
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
});
});

View File

@@ -1,6 +1,5 @@
import React from 'react';
import configureStore from 'redux-mock-store';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import URLShortLinkModal from '../../../src/components/URLShortLinkModal';
@@ -21,6 +20,6 @@ describe('URLShortLinkModal', () => {
it('renders ModalTrigger', () => {
const wrapper = setup();
expect(wrapper.find(ModalTrigger)).have.length(1);
expect(wrapper.find(ModalTrigger)).toHaveLength(1);
});
});

View File

@@ -2,7 +2,6 @@
import React from 'react';
import sinon from 'sinon';
import PropTypes from 'prop-types';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import VirtualizedRendererWrap from '../../../src/components/VirtualizedRendererWrap';
@@ -38,38 +37,34 @@ describe('VirtualizedRendererWrap', () => {
it('uses the provided renderer', () => {
const option = wrapper.find(TestOption);
expect(option).to.have.lengthOf(1);
expect(option).toHaveLength(1);
});
it('renders nothing when no option is provided', () => {
props.option = null;
wrapper = shallow(<RendererWrap {...props} />);
const option = wrapper.find(TestOption);
expect(option).to.have.lengthOf(0);
expect(option).toHaveLength(0);
});
it('renders unfocused, unselected options with the default class', () => {
const optionDiv = wrapper.find('div');
expect(optionDiv).to.have.lengthOf(1);
expect(optionDiv.props().className).to.equal('VirtualizedSelectOption');
expect(optionDiv).toHaveLength(1);
expect(optionDiv.props().className).toBe('VirtualizedSelectOption');
});
it('renders focused option with the correct class', () => {
props.option = props.focusedOption;
wrapper = shallow(<RendererWrap {...props} />);
const optionDiv = wrapper.find('div');
expect(optionDiv.props().className).to.equal(
'VirtualizedSelectOption VirtualizedSelectFocusedOption',
);
expect(optionDiv.props().className).toBe('VirtualizedSelectOption VirtualizedSelectFocusedOption');
});
it('renders disabled option with the correct class', () => {
props.option.disabled = true;
wrapper = shallow(<RendererWrap {...props} />);
const optionDiv = wrapper.find('div');
expect(optionDiv.props().className).to.equal(
'VirtualizedSelectOption VirtualizedSelectDisabledOption',
);
expect(optionDiv.props().className).toBe('VirtualizedSelectOption VirtualizedSelectDisabledOption');
props.option.disabled = false;
});
@@ -77,29 +72,25 @@ describe('VirtualizedRendererWrap', () => {
props.valueArray = [props.option, props.focusedOption];
wrapper = shallow(<RendererWrap {...props} />);
const optionDiv = wrapper.find('div');
expect(optionDiv.props().className).to.equal(
'VirtualizedSelectOption VirtualizedSelectSelectedOption',
);
expect(optionDiv.props().className).toBe('VirtualizedSelectOption VirtualizedSelectSelectedOption');
});
it('renders options with custom classes', () => {
props.option.className = 'CustomClass';
wrapper = shallow(<RendererWrap {...props} />);
const optionDiv = wrapper.find('div');
expect(optionDiv.props().className).to.equal(
'VirtualizedSelectOption CustomClass',
);
expect(optionDiv.props().className).toBe('VirtualizedSelectOption CustomClass');
});
it('calls focusedOption on its own option onMouseEnter', () => {
const optionDiv = wrapper.find('div');
optionDiv.simulate('mouseEnter');
expect(props.focusOption.calledWith(props.option)).to.be.true;
expect(props.focusOption.calledWith(props.option)).toBe(true);
});
it('calls selectValue on its own option onClick', () => {
const optionDiv = wrapper.find('div');
optionDiv.simulate('click');
expect(props.selectValue.calledWith(props.option)).to.be.true;
expect(props.selectValue.calledWith(props.option)).toBe(true);
});
});