[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,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 AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../../../../src/explore/AdhocFilter';
@@ -55,7 +54,7 @@ function setup(overrides) {
describe('AdhocFilterControl', () => {
it('renders an onPasteSelect', () => {
const { wrapper } = setup();
expect(wrapper.find(OnPasteSelect)).to.have.lengthOf(1);
expect(wrapper.find(OnPasteSelect)).toHaveLength(1);
});
it('handles saved metrics being selected to filter on', () => {
@@ -64,7 +63,7 @@ describe('AdhocFilterControl', () => {
select.simulate('change', [{ saved_metric_name: 'sum__value' }]);
const adhocFilter = onChange.lastCall.args[0][0];
expect(adhocFilter instanceof AdhocFilter).to.be.true;
expect(adhocFilter instanceof AdhocFilter).toBe(true);
expect(adhocFilter.equals((
new AdhocFilter({
expressionType: EXPRESSION_TYPES.SQL,
@@ -73,7 +72,7 @@ describe('AdhocFilterControl', () => {
comparator: 0,
clause: CLAUSES.HAVING,
})
))).to.be.true;
))).toBe(true);
});
it('handles adhoc metrics being selected to filter on', () => {
@@ -82,7 +81,7 @@ describe('AdhocFilterControl', () => {
select.simulate('change', [sumValueAdhocMetric]);
const adhocFilter = onChange.lastCall.args[0][0];
expect(adhocFilter instanceof AdhocFilter).to.be.true;
expect(adhocFilter instanceof AdhocFilter).toBe(true);
expect(adhocFilter.equals((
new AdhocFilter({
expressionType: EXPRESSION_TYPES.SQL,
@@ -91,7 +90,7 @@ describe('AdhocFilterControl', () => {
comparator: 0,
clause: CLAUSES.HAVING,
})
))).to.be.true;
))).toBe(true);
});
it('handles columns being selected to filter on', () => {
@@ -100,7 +99,7 @@ describe('AdhocFilterControl', () => {
select.simulate('change', [columns[0]]);
const adhocFilter = onChange.lastCall.args[0][0];
expect(adhocFilter instanceof AdhocFilter).to.be.true;
expect(adhocFilter instanceof AdhocFilter).toBe(true);
expect(adhocFilter.equals((
new AdhocFilter({
expressionType: EXPRESSION_TYPES.SIMPLE,
@@ -109,7 +108,7 @@ describe('AdhocFilterControl', () => {
comparator: '',
clause: CLAUSES.WHERE,
})
))).to.be.true;
))).toBe(true);
});
it('persists existing filters even when new filters are added', () => {
@@ -118,11 +117,11 @@ describe('AdhocFilterControl', () => {
select.simulate('change', [simpleAdhocFilter, columns[0]]);
const existingAdhocFilter = onChange.lastCall.args[0][0];
expect(existingAdhocFilter instanceof AdhocFilter).to.be.true;
expect(existingAdhocFilter.equals(simpleAdhocFilter)).to.be.true;
expect(existingAdhocFilter instanceof AdhocFilter).toBe(true);
expect(existingAdhocFilter.equals(simpleAdhocFilter)).toBe(true);
const newAdhocFilter = onChange.lastCall.args[0][1];
expect(newAdhocFilter instanceof AdhocFilter).to.be.true;
expect(newAdhocFilter instanceof AdhocFilter).toBe(true);
expect(newAdhocFilter.equals((
new AdhocFilter({
expressionType: EXPRESSION_TYPES.SIMPLE,
@@ -131,6 +130,6 @@ describe('AdhocFilterControl', () => {
comparator: '',
clause: CLAUSES.WHERE,
})
))).to.be.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 { FormGroup } from 'react-bootstrap';
@@ -58,67 +57,67 @@ function setup(overrides) {
describe('AdhocFilterEditPopoverSimpleTabContent', () => {
it('renders the simple tab form', () => {
const { wrapper } = setup();
expect(wrapper.find(FormGroup)).to.have.lengthOf(3);
expect(wrapper.find(FormGroup)).toHaveLength(3);
});
it('passes the new adhocFilter to onChange after onSubjectChange', () => {
const { wrapper, onChange } = setup();
wrapper.instance().onSubjectChange({ type: 'VARCHAR(255)', column_name: 'source' });
expect(onChange.calledOnce).to.be.true;
expect(onChange.calledOnce).toBe(true);
expect(onChange.lastCall.args[0].equals((
simpleAdhocFilter.duplicateWith({ subject: 'source' })
))).to.be.true;
))).toBe(true);
});
it('may alter the clause in onSubjectChange if the old clause is not appropriate', () => {
const { wrapper, onChange } = setup();
wrapper.instance().onSubjectChange(sumValueAdhocMetric);
expect(onChange.calledOnce).to.be.true;
expect(onChange.calledOnce).toBe(true);
expect(onChange.lastCall.args[0].equals((
simpleAdhocFilter.duplicateWith({
subject: sumValueAdhocMetric.label,
clause: CLAUSES.HAVING,
})
))).to.be.true;
))).toBe(true);
});
it('will convert from individual comparator to array if the operator changes to multi', () => {
const { wrapper, onChange } = setup();
wrapper.instance().onOperatorChange({ operator: 'in' });
expect(onChange.calledOnce).to.be.true;
expect(onChange.lastCall.args[0].comparator).to.have.lengthOf(1);
expect(onChange.lastCall.args[0].comparator[0]).to.equal('10');
expect(onChange.lastCall.args[0].operator).to.equal('in');
expect(onChange.calledOnce).toBe(true);
expect(onChange.lastCall.args[0].comparator).toHaveLength(1);
expect(onChange.lastCall.args[0].comparator[0]).toBe('10');
expect(onChange.lastCall.args[0].operator).toBe('in');
});
it('will convert from array to individual comparators if the operator changes from multi', () => {
const { wrapper, onChange } = setup({ adhocFilter: simpleMultiAdhocFilter });
wrapper.instance().onOperatorChange({ operator: '<' });
expect(onChange.calledOnce).to.be.true;
expect(onChange.calledOnce).toBe(true);
expect(onChange.lastCall.args[0].equals((
simpleAdhocFilter.duplicateWith({ operator: '<', comparator: '10' })
))).to.be.true;
))).toBe(true);
});
it('passes the new adhocFilter to onChange after onComparatorChange', () => {
const { wrapper, onChange } = setup();
wrapper.instance().onComparatorChange('20');
expect(onChange.calledOnce).to.be.true;
expect(onChange.calledOnce).toBe(true);
expect(onChange.lastCall.args[0].equals((
simpleAdhocFilter.duplicateWith({ comparator: '20' })
))).to.be.true;
))).toBe(true);
});
it('will filter operators for table datasources', () => {
const { wrapper } = setup({ datasource: { type: 'table' } });
expect(wrapper.instance().isOperatorRelevant('regex')).to.be.false;
expect(wrapper.instance().isOperatorRelevant('LIKE')).to.be.true;
expect(wrapper.instance().isOperatorRelevant('regex')).toBe(false);
expect(wrapper.instance().isOperatorRelevant('LIKE')).toBe(true);
});
it('will filter operators for druid datasources', () => {
const { wrapper } = setup({ datasource: { type: 'druid' } });
expect(wrapper.instance().isOperatorRelevant('regex')).to.be.true;
expect(wrapper.instance().isOperatorRelevant('LIKE')).to.be.false;
expect(wrapper.instance().isOperatorRelevant('regex')).toBe(true);
expect(wrapper.instance().isOperatorRelevant('LIKE')).toBe(false);
});
it('expands when its multi comparator input field expands', () => {
@@ -128,7 +127,7 @@ describe('AdhocFilterEditPopoverSimpleTabContent', () => {
{ _selectRef: { select: { control: { clientHeight: 57 } } } };
wrapper.instance().handleMultiComparatorInputHeightChange();
expect(onHeightChange.calledOnce).to.be.true;
expect(onHeightChange.lastCall.args[0]).to.equal(27);
expect(onHeightChange.calledOnce).toBe(true);
expect(onHeightChange.lastCall.args[0]).toBe(27);
});
});

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 { FormGroup } from 'react-bootstrap';
@@ -30,24 +29,24 @@ function setup(overrides) {
describe('AdhocFilterEditPopoverSqlTabContent', () => {
it('renders the sql tab form', () => {
const { wrapper } = setup();
expect(wrapper.find(FormGroup)).to.have.lengthOf(2);
expect(wrapper.find(FormGroup)).toHaveLength(2);
});
it('passes the new clause to onChange after onSqlExpressionClauseChange', () => {
const { wrapper, onChange } = setup();
wrapper.instance().onSqlExpressionClauseChange(CLAUSES.HAVING);
expect(onChange.calledOnce).to.be.true;
expect(onChange.calledOnce).toBe(true);
expect(onChange.lastCall.args[0].equals((
sqlAdhocFilter.duplicateWith({ clause: CLAUSES.HAVING })
))).to.be.true;
))).toBe(true);
});
it('passes the new query to onChange after onSqlExpressionChange', () => {
const { wrapper, onChange } = setup();
wrapper.instance().onSqlExpressionChange('value < 5');
expect(onChange.calledOnce).to.be.true;
expect(onChange.calledOnce).toBe(true);
expect(onChange.lastCall.args[0].equals((
sqlAdhocFilter.duplicateWith({ sqlExpression: 'value < 5' })
))).to.be.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 { Button, Popover, Tab, Tabs } from 'react-bootstrap';
@@ -60,42 +59,42 @@ function setup(overrides) {
describe('AdhocFilterEditPopover', () => {
it('renders simple tab content by default', () => {
const { wrapper } = setup();
expect(wrapper.find(Popover)).to.have.lengthOf(1);
expect(wrapper.find(Tabs)).to.have.lengthOf(1);
expect(wrapper.find(Tab)).to.have.lengthOf(2);
expect(wrapper.find(Button)).to.have.lengthOf(2);
expect(wrapper.find(AdhocFilterEditPopoverSimpleTabContent)).to.have.lengthOf(1);
expect(wrapper.find(Popover)).toHaveLength(1);
expect(wrapper.find(Tabs)).toHaveLength(1);
expect(wrapper.find(Tab)).toHaveLength(2);
expect(wrapper.find(Button)).toHaveLength(2);
expect(wrapper.find(AdhocFilterEditPopoverSimpleTabContent)).toHaveLength(1);
});
it('renders sql tab content when the adhoc filter expressionType is sql', () => {
const { wrapper } = setup({ adhocFilter: sqlAdhocFilter });
expect(wrapper.find(Popover)).to.have.lengthOf(1);
expect(wrapper.find(Tabs)).to.have.lengthOf(1);
expect(wrapper.find(Tab)).to.have.lengthOf(2);
expect(wrapper.find(Button)).to.have.lengthOf(2);
expect(wrapper.find(AdhocFilterEditPopoverSqlTabContent)).to.have.lengthOf(1);
expect(wrapper.find(Popover)).toHaveLength(1);
expect(wrapper.find(Tabs)).toHaveLength(1);
expect(wrapper.find(Tab)).toHaveLength(2);
expect(wrapper.find(Button)).toHaveLength(2);
expect(wrapper.find(AdhocFilterEditPopoverSqlTabContent)).toHaveLength(1);
});
it('overwrites the adhocFilter in state with onAdhocFilterChange', () => {
const { wrapper } = setup();
wrapper.instance().onAdhocFilterChange(sqlAdhocFilter);
expect(wrapper.state('adhocFilter')).to.deep.equal(sqlAdhocFilter);
expect(wrapper.state('adhocFilter')).toEqual(sqlAdhocFilter);
});
it('prevents saving if the filter is invalid', () => {
const { wrapper } = setup();
expect(wrapper.find(Button).find({ disabled: true })).to.have.lengthOf(0);
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(0);
wrapper.instance().onAdhocFilterChange(simpleAdhocFilter.duplicateWith({ operator: null }));
expect(wrapper.find(Button).find({ disabled: true })).to.have.lengthOf(1);
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(1);
wrapper.instance().onAdhocFilterChange(sqlAdhocFilter);
expect(wrapper.find(Button).find({ disabled: true })).to.have.lengthOf(0);
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(0);
});
it('highlights save if changes are present', () => {
const { wrapper } = setup();
expect(wrapper.find(Button).find({ bsStyle: 'primary' })).to.have.lengthOf(0);
expect(wrapper.find(Button).find({ bsStyle: 'primary' })).toHaveLength(0);
wrapper.instance().onAdhocFilterChange(sqlAdhocFilter);
expect(wrapper.find(Button).find({ bsStyle: 'primary' })).to.have.lengthOf(1);
expect(wrapper.find(Button).find({ bsStyle: 'primary' })).toHaveLength(1);
});
it('will initiate a drag when clicked', () => {
@@ -103,9 +102,9 @@ describe('AdhocFilterEditPopover', () => {
wrapper.instance().onDragDown = sinon.spy();
wrapper.instance().forceUpdate();
expect(wrapper.find('i.glyphicon-resize-full')).to.have.lengthOf(1);
expect(wrapper.instance().onDragDown.calledOnce).to.be.false;
expect(wrapper.find('i.glyphicon-resize-full')).toHaveLength(1);
expect(wrapper.instance().onDragDown.calledOnce).toBe(false);
wrapper.find('i.glyphicon-resize-full').simulate('mouseDown', {});
expect(wrapper.instance().onDragDown.calledOnce).to.be.true;
expect(wrapper.instance().onDragDown.calledOnce).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 { Label, OverlayTrigger } from 'react-bootstrap';
@@ -32,7 +31,7 @@ function setup(overrides) {
describe('AdhocFilterOption', () => {
it('renders an overlay trigger wrapper for the label', () => {
const { wrapper } = setup();
expect(wrapper.find(OverlayTrigger)).to.have.lengthOf(1);
expect(wrapper.find(Label)).to.have.lengthOf(1);
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
expect(wrapper.find(Label)).toHaveLength(1);
});
});

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 { OverlayTrigger } from 'react-bootstrap';
@@ -34,14 +33,14 @@ function setup(overrides) {
describe('AdhocMetricEditPopoverTitle', () => {
it('renders an OverlayTrigger wrapper with the title', () => {
const { wrapper } = setup();
expect(wrapper.find(OverlayTrigger)).to.have.lengthOf(1);
expect(wrapper.find(OverlayTrigger).find('span').text()).to.equal('My Metric\xa0');
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
expect(wrapper.find(OverlayTrigger).find('span').text()).toBe('My Metric\xa0');
});
it('transfers to edit mode when clicked', () => {
const { wrapper } = setup();
expect(wrapper.state('isEditable')).to.be.false;
expect(wrapper.state('isEditable')).toBe(false);
wrapper.simulate('click');
expect(wrapper.state('isEditable')).to.be.true;
expect(wrapper.state('isEditable')).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 { Button, FormGroup, Popover } from 'react-bootstrap';
@@ -43,60 +42,60 @@ function setup(overrides) {
describe('AdhocMetricEditPopover', () => {
it('renders a popover with edit metric form contents', () => {
const { wrapper } = setup();
expect(wrapper.find(Popover)).to.have.lengthOf(1);
expect(wrapper.find(FormGroup)).to.have.lengthOf(3);
expect(wrapper.find(Button)).to.have.lengthOf(2);
expect(wrapper.find(Popover)).toHaveLength(1);
expect(wrapper.find(FormGroup)).toHaveLength(3);
expect(wrapper.find(Button)).toHaveLength(2);
});
it('overwrites the adhocMetric in state with onColumnChange', () => {
const { wrapper } = setup();
wrapper.instance().onColumnChange(columns[0]);
expect(wrapper.state('adhocMetric')).to.deep.equal(sumValueAdhocMetric.duplicateWith({ column: columns[0] }));
expect(wrapper.state('adhocMetric')).toEqual(sumValueAdhocMetric.duplicateWith({ column: columns[0] }));
});
it('overwrites the adhocMetric in state with onAggregateChange', () => {
const { wrapper } = setup();
wrapper.instance().onAggregateChange({ aggregate: AGGREGATES.AVG });
expect(wrapper.state('adhocMetric')).to.deep.equal(sumValueAdhocMetric.duplicateWith({ aggregate: AGGREGATES.AVG }));
expect(wrapper.state('adhocMetric')).toEqual(sumValueAdhocMetric.duplicateWith({ aggregate: AGGREGATES.AVG }));
});
it('overwrites the adhocMetric in state with onSqlExpressionChange', () => {
const { wrapper } = setup({ adhocMetric: sqlExpressionAdhocMetric });
wrapper.instance().onSqlExpressionChange('COUNT(1)');
expect(wrapper.state('adhocMetric')).to.deep.equal(sqlExpressionAdhocMetric.duplicateWith({ sqlExpression: 'COUNT(1)' }));
expect(wrapper.state('adhocMetric')).toEqual(sqlExpressionAdhocMetric.duplicateWith({ sqlExpression: 'COUNT(1)' }));
});
it('overwrites the adhocMetric in state with onLabelChange', () => {
const { wrapper } = setup();
wrapper.instance().onLabelChange({ target: { value: 'new label' } });
expect(wrapper.state('adhocMetric').label).to.equal('new label');
expect(wrapper.state('adhocMetric').hasCustomLabel).to.be.true;
expect(wrapper.state('adhocMetric').label).toBe('new label');
expect(wrapper.state('adhocMetric').hasCustomLabel).toBe(true);
});
it('returns to default labels when the custom label is cleared', () => {
const { wrapper } = setup();
wrapper.instance().onLabelChange({ target: { value: 'new label' } });
wrapper.instance().onLabelChange({ target: { value: '' } });
expect(wrapper.state('adhocMetric').label).to.equal('SUM(value)');
expect(wrapper.state('adhocMetric').hasCustomLabel).to.be.false;
expect(wrapper.state('adhocMetric').label).toBe('SUM(value)');
expect(wrapper.state('adhocMetric').hasCustomLabel).toBe(false);
});
it('prevents saving if no column or aggregate is chosen', () => {
const { wrapper } = setup();
expect(wrapper.find(Button).find({ disabled: true })).to.have.lengthOf(0);
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(0);
wrapper.instance().onColumnChange(null);
expect(wrapper.find(Button).find({ disabled: true })).to.have.lengthOf(1);
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(1);
wrapper.instance().onColumnChange({ column: columns[0] });
expect(wrapper.find(Button).find({ disabled: true })).to.have.lengthOf(0);
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(0);
wrapper.instance().onAggregateChange(null);
expect(wrapper.find(Button).find({ disabled: true })).to.have.lengthOf(1);
expect(wrapper.find(Button).find({ disabled: true })).toHaveLength(1);
});
it('highlights save if changes are present', () => {
const { wrapper } = setup();
expect(wrapper.find(Button).find({ bsStyle: 'primary' })).to.have.lengthOf(0);
expect(wrapper.find(Button).find({ bsStyle: 'primary' })).toHaveLength(0);
wrapper.instance().onColumnChange({ column: columns[1] });
expect(wrapper.find(Button).find({ bsStyle: 'primary' })).to.have.lengthOf(1);
expect(wrapper.find(Button).find({ bsStyle: 'primary' })).toHaveLength(1);
});
it('will initiate a drag when clicked', () => {
@@ -104,9 +103,9 @@ describe('AdhocMetricEditPopover', () => {
wrapper.instance().onDragDown = sinon.spy();
wrapper.instance().forceUpdate();
expect(wrapper.find('i.glyphicon-resize-full')).to.have.lengthOf(1);
expect(wrapper.instance().onDragDown.calledOnce).to.be.false;
expect(wrapper.find('i.glyphicon-resize-full')).toHaveLength(1);
expect(wrapper.instance().onDragDown.calledOnce).toBe(false);
wrapper.find('i.glyphicon-resize-full').simulate('mouseDown');
expect(wrapper.instance().onDragDown.calledOnce).to.be.true;
expect(wrapper.instance().onDragDown.calledOnce).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 { Label, OverlayTrigger } from 'react-bootstrap';
@@ -35,7 +34,7 @@ function setup(overrides) {
describe('AdhocMetricOption', () => {
it('renders an overlay trigger wrapper for the label', () => {
const { wrapper } = setup();
expect(wrapper.find(OverlayTrigger)).to.have.lengthOf(1);
expect(wrapper.find(Label)).to.have.lengthOf(1);
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
expect(wrapper.find(Label)).toHaveLength(1);
});
});

View File

@@ -1,6 +1,5 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import AdhocMetricStaticOption from '../../../../src/explore/components/AdhocMetricStaticOption';
@@ -16,6 +15,6 @@ const sumValueAdhocMetric = new AdhocMetric({
describe('AdhocMetricStaticOption', () => {
it('renders the adhoc metrics label', () => {
const wrapper = shallow(<AdhocMetricStaticOption adhocMetric={sumValueAdhocMetric} />);
expect(wrapper.text()).to.equal('SUM(source)');
expect(wrapper.text()).toBe('SUM(source)');
});
});

View File

@@ -1,6 +1,5 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import AggregateOption from '../../../../src/explore/components/AggregateOption';
@@ -8,6 +7,6 @@ import AggregateOption from '../../../../src/explore/components/AggregateOption'
describe('AggregateOption', () => {
it('renders the aggregate', () => {
const wrapper = shallow(<AggregateOption aggregate={{ aggregate_name: 'SUM' }} />);
expect(wrapper.text()).to.equal('SUM');
expect(wrapper.text()).toBe('SUM');
});
});

View File

@@ -2,7 +2,6 @@
import React from 'react';
import { FormControl } from 'react-bootstrap';
import sinon from 'sinon';
import { expect } from 'chai';
import { mount } from 'enzyme';
import BoundsControl from '../../../../src/explore/components/controls/BoundsControl';
@@ -21,17 +20,17 @@ describe('BoundsControl', () => {
});
it('renders two FormControls', () => {
expect(wrapper.find(FormControl)).to.have.lengthOf(2);
expect(wrapper.find(FormControl)).toHaveLength(2);
});
it('errors on non-numeric', () => {
wrapper.find(FormControl).first().simulate('change', { target: { value: 's' } });
expect(defaultProps.onChange.calledWith([null, null])).to.be.true;
expect(defaultProps.onChange.getCall(0).args[1][0]).to.contain('value should be numeric');
expect(defaultProps.onChange.calledWith([null, null])).toBe(true);
expect(defaultProps.onChange.getCall(0).args[1][0]).toContain('value should be numeric');
});
it('casts to numeric', () => {
wrapper.find(FormControl).first().simulate('change', { target: { value: '1' } });
wrapper.find(FormControl).last().simulate('change', { target: { value: '5' } });
expect(defaultProps.onChange.calledWith([1, 5])).to.be.true;
expect(defaultProps.onChange.calledWith([1, 5])).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 CheckboxControl from '../../../../src/explore/components/controls/CheckboxControl';
@@ -24,9 +23,9 @@ describe('CheckboxControl', () => {
it('renders a Checkbox', () => {
const controlHeader = wrapper.find(ControlHeader);
expect(controlHeader).to.have.lengthOf(1);
expect(controlHeader).toHaveLength(1);
const headerWrapper = controlHeader.shallow();
expect(headerWrapper.find(Checkbox)).to.have.length(1);
expect(headerWrapper.find(Checkbox)).toHaveLength(1);
});
});

View File

@@ -1,6 +1,5 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import { OverlayTrigger } from 'react-bootstrap';
import { SketchPicker } from 'react-color';
@@ -26,18 +25,12 @@ describe('ColorPickerControl', () => {
it('renders a OverlayTrigger', () => {
const controlHeader = wrapper.find(ControlHeader);
expect(controlHeader).to.have.lengthOf(1);
expect(wrapper.find(OverlayTrigger)).to.have.length(1);
});
it('renders a OverlayTrigger', () => {
const controlHeader = wrapper.find(ControlHeader);
expect(controlHeader).to.have.lengthOf(1);
expect(wrapper.find(OverlayTrigger)).to.have.length(1);
expect(controlHeader).toHaveLength(1);
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
});
it('renders a Popover with a SketchPicker', () => {
const popOver = shallow(inst.renderPopover());
expect(popOver.find(SketchPicker)).to.have.lengthOf(1);
expect(popOver.find(SketchPicker)).toHaveLength(1);
});
});

View File

@@ -1,6 +1,5 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import { Creatable } from 'react-select';
@@ -19,6 +18,6 @@ describe('ColorSchemeControl', () => {
});
it('renders a Creatable', () => {
expect(wrapper.find(Creatable)).to.have.length(1);
expect(wrapper.find(Creatable)).toHaveLength(1);
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import { Panel } from 'react-bootstrap';
@@ -25,12 +24,12 @@ describe('ControlPanelSection', () => {
it('is a valid element', () => {
expect(
React.isValidElement(<ControlPanelSection {...defaultProps} />),
).to.equal(true);
).toBe(true);
});
it('renders a Panel component', () => {
wrapper = shallow(<ControlPanelSection {...defaultProps} />);
expect(wrapper.find(Panel)).to.have.length(1);
expect(wrapper.find(Panel)).toHaveLength(1);
});
describe('with optional props', () => {
@@ -40,12 +39,11 @@ describe('ControlPanelSection', () => {
});
it('renders a label if present', () => {
expect(wrapper.find(Panel).dive().text()).to.contain('my label');
expect(wrapper.find(Panel).dive().text()).toContain('my label');
});
it('renders a InfoTooltipWithTrigger if label and tooltip is present', () => {
expect(wrapper.find(Panel).dive().find(InfoTooltipWithTrigger))
.to.have.length(1);
expect(wrapper.find(Panel).dive().find(InfoTooltipWithTrigger)).toHaveLength(1);
});
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import { getFormDataFromControls, defaultControls }
from '../../../../src/explore/store';
@@ -25,6 +24,6 @@ describe('ControlPanelsContainer', () => {
});
it('renders ControlPanelSections', () => {
expect(wrapper.find(ControlPanelSection)).to.have.lengthOf(6);
expect(wrapper.find(ControlPanelSection)).toHaveLength(6);
});
});

View File

@@ -1,17 +1,16 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import ControlSetRow from '../../../../src/explore/components/ControlRow';
describe('ControlSetRow', () => {
it('renders a single row with one element', () => {
const wrapper = shallow(<ControlSetRow controls={[<a />]} />);
expect(wrapper.find('.row')).to.have.lengthOf(1);
expect(wrapper.find('.row').find('a')).to.have.lengthOf(1);
expect(wrapper.find('.row')).toHaveLength(1);
expect(wrapper.find('.row').find('a')).toHaveLength(1);
});
it('renders a single row with two elements', () => {
const wrapper = shallow(<ControlSetRow controls={[<a />, <a />]} />);
expect(wrapper.find('.row')).to.have.lengthOf(1);
expect(wrapper.find('.row').find('a')).to.have.lengthOf(2);
expect(wrapper.find('.row')).toHaveLength(1);
expect(wrapper.find('.row').find('a')).toHaveLength(2);
});
});

View File

@@ -1,7 +1,6 @@
import React from 'react';
import sinon from 'sinon';
import configureStore from 'redux-mock-store';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import DatasourceModal from '../../../../src/datasource/DatasourceModal';
import DatasourceControl from '../../../../src/explore/components/controls/DatasourceControl';
@@ -34,6 +33,6 @@ describe('DatasourceControl', () => {
it('renders a Modal', () => {
const wrapper = setup();
expect(wrapper.find(DatasourceModal)).to.have.lengthOf(1);
expect(wrapper.find(DatasourceModal)).toHaveLength(1);
});
});

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 { Button, Label } from 'react-bootstrap';
@@ -25,37 +24,37 @@ describe('DateFilterControl', () => {
it('renders a ControlHeader', () => {
const controlHeader = wrapper.find(ControlHeader);
expect(controlHeader).to.have.lengthOf(1);
expect(controlHeader).toHaveLength(1);
});
it('renders 3 Buttons', () => {
const label = wrapper.find(Label).first();
label.simulate('click');
setTimeout(() => {
expect(wrapper.find(Button)).to.have.length(3);
expect(wrapper.find(Button)).toHaveLength(3);
}, 10);
});
it('loads the right state', () => {
const label = wrapper.find(Label).first();
label.simulate('click');
setTimeout(() => {
expect(wrapper.state().num).to.equal('90');
expect(wrapper.state().num).toBe('90');
}, 10);
});
it('renders 2 dimmed sections', () => {
const label = wrapper.find(Label).first();
label.simulate('click');
setTimeout(() => {
expect(wrapper.find(Button)).to.have.length(3);
expect(wrapper.find(Button)).toHaveLength(3);
}, 10);
});
it('opens and closes', () => {
const label = wrapper.find(Label).first();
label.simulate('click');
setTimeout(() => {
expect(wrapper.find('.popover')).to.have.length(1);
expect(wrapper.find('.popover')).toHaveLength(1);
expect(wrapper.find('.ok')).first().simulate('click');
setTimeout(() => {
expect(wrapper.find('.popover')).to.have.length(0);
expect(wrapper.find('.popover')).toHaveLength(0);
}, 10);
}, 10);
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import ModalTrigger from './../../../../src/components/ModalTrigger';
@@ -20,10 +19,10 @@ describe('DisplayQueryButton', () => {
};
it('is valid', () => {
expect(React.isValidElement(<DisplayQueryButton {...defaultProps} />)).to.equal(true);
expect(React.isValidElement(<DisplayQueryButton {...defaultProps} />)).toBe(true);
});
it('renders a dropdown', () => {
const wrapper = mount(<DisplayQueryButton {...defaultProps} />);
expect(wrapper.find(ModalTrigger)).to.have.lengthOf(3);
expect(wrapper.find(ModalTrigger)).toHaveLength(3);
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow, mount } from 'enzyme';
import { OverlayTrigger } from 'react-bootstrap';
import sinon from 'sinon';
@@ -13,12 +12,12 @@ describe('EmbedCodeButton', () => {
};
it('renders', () => {
expect(React.isValidElement(<EmbedCodeButton {...defaultProps} />)).to.equal(true);
expect(React.isValidElement(<EmbedCodeButton {...defaultProps} />)).toBe(true);
});
it('renders overlay trigger', () => {
const wrapper = shallow(<EmbedCodeButton {...defaultProps} />);
expect(wrapper.find(OverlayTrigger)).to.have.length(1);
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
});
it('returns correct embed code', () => {
@@ -35,11 +34,11 @@ describe('EmbedCodeButton', () => {
' seamless\n' +
' frameBorder="0"\n' +
' scrolling="no"\n' +
' src="nullendpoint_url&height=1000"\n' +
' src="http://localhostendpoint_url&height=1000"\n' +
'>\n' +
'</iframe>'
);
expect(wrapper.instance().generateEmbedHTML()).to.equal(embedHTML);
expect(wrapper.instance().generateEmbedHTML()).toBe(embedHTML);
stub.restore();
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import ExploreActionButtons from
'../../../../src/explore/components/ExploreActionButtons';
@@ -15,11 +14,11 @@ describe('ExploreActionButtons', () => {
it('renders', () => {
expect(
React.isValidElement(<ExploreActionButtons {...defaultProps} />),
).to.equal(true);
).toBe(true);
});
it('should render 5 children/buttons', () => {
const wrapper = shallow(<ExploreActionButtons {...defaultProps} />);
expect(wrapper.children()).to.have.length(5);
expect(wrapper.children()).toHaveLength(5);
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import ExploreChartHeader from '../../../../src/explore/components/ExploreChartHeader';
@@ -29,11 +28,11 @@ describe('ExploreChartHeader', () => {
it('is valid', () => {
expect(
React.isValidElement(<ExploreChartHeader {...mockProps} />),
).to.equal(true);
).toBe(true);
});
it('renders', () => {
expect(wrapper.find(EditableTitle)).to.have.lengthOf(1);
expect(wrapper.find(ExploreActionButtons)).to.have.lengthOf(1);
expect(wrapper.find(EditableTitle)).toHaveLength(1);
expect(wrapper.find(ExploreActionButtons)).toHaveLength(1);
});
});

View File

@@ -1,21 +0,0 @@
// this test must be commented out because ChartContainer is now importing files
// from visualizations/*.js which are also importing css files which breaks in the testing env
// import React from 'react';
// import { expect } from 'chai';
//
// import ChartContainer from '../../../../src/explore/components/ChartContainer';
// describe('ChartContainer', () => {
// const mockProps = {
// sliceName: 'Trend Line',
// vizType: 'line',
// height: '500px',
// };
// it('renders when vizType is line', () => {
// expect(
// React.isValidElement(<ChartContainer {...mockProps} />)
// ).to.equal(true);
// });
// });

View File

@@ -0,0 +1,17 @@
import React from 'react';
import ChartContainer from '../../../../src/explore/components/ExploreChartPanel';
describe('ChartContainer', () => {
const mockProps = {
sliceName: 'Trend Line',
vizType: 'line',
height: '500px',
};
it('renders when vizType is line', () => {
expect(
React.isValidElement(<ChartContainer {...mockProps} />),
).toBe(true);
});
});

View File

@@ -1,7 +1,6 @@
import React from 'react';
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import getInitialState from '../../../../src/explore/reducers/getInitialState';
@@ -20,7 +19,7 @@ describe('ExploreViewContainer', () => {
let store;
let wrapper;
before(() => {
beforeAll(() => {
const bootstrapData = {
common: {
feature_flags: {
@@ -46,24 +45,24 @@ describe('ExploreViewContainer', () => {
});
it('should set feature flags', () => {
expect(wrapper.prop('isFeatureEnabled')('FOO_BAR')).to.equal(true);
expect(wrapper.prop('isFeatureEnabled')('FOO_BAR')).toBe(true);
});
it('renders', () => {
expect(
React.isValidElement(<ExploreViewContainer />),
).to.equal(true);
).toBe(true);
});
it('renders QueryAndSaveButtons', () => {
expect(wrapper.dive().find(QueryAndSaveBtns)).to.have.length(1);
expect(wrapper.dive().find(QueryAndSaveBtns)).toHaveLength(1);
});
it('renders ControlPanelsContainer', () => {
expect(wrapper.dive().find(ControlPanelsContainer)).to.have.length(1);
expect(wrapper.dive().find(ControlPanelsContainer)).toHaveLength(1);
});
it('renders ChartContainer', () => {
expect(wrapper.dive().find(ChartContainer)).to.have.length(1);
expect(wrapper.dive().find(ChartContainer)).toHaveLength(1);
});
});

View File

@@ -1,6 +1,5 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import FilterDefinitionOption from '../../../../src/explore/components/FilterDefinitionOption';
@@ -18,18 +17,18 @@ const sumValueAdhocMetric = new AdhocMetric({
describe('FilterDefinitionOption', () => {
it('renders a ColumnOption given a column', () => {
const wrapper = shallow(<FilterDefinitionOption option={{ column_name: 'a_column' }} />);
expect(wrapper.find(ColumnOption)).to.have.lengthOf(1);
expect(wrapper.find(ColumnOption)).toHaveLength(1);
});
it('renders a AdhocMetricStaticOption given an adhoc metric', () => {
const wrapper = shallow(<FilterDefinitionOption option={sumValueAdhocMetric} />);
expect(wrapper.find(AdhocMetricStaticOption)).to.have.lengthOf(1);
expect(wrapper.find(AdhocMetricStaticOption)).toHaveLength(1);
});
it('renders the metric name given a saved metric', () => {
const wrapper = shallow((
<FilterDefinitionOption option={{ saved_metric_name: 'my_custom_metric' }} />
));
expect(wrapper.text()).to.equal('<ColumnTypeLabel />my_custom_metric');
expect(wrapper.text()).toBe('<ColumnTypeLabel />my_custom_metric');
});
});

View File

@@ -1,6 +1,5 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import { OverlayTrigger } from 'react-bootstrap';
@@ -26,13 +25,13 @@ describe('FixedOrMetricControl', () => {
it('renders a OverlayTrigger', () => {
const controlHeader = wrapper.find(ControlHeader);
expect(controlHeader).to.have.lengthOf(1);
expect(wrapper.find(OverlayTrigger)).to.have.length(1);
expect(controlHeader).toHaveLength(1);
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
});
it('renders a TextControl and a SelectControl', () => {
const popOver = shallow(inst.renderPopover());
expect(popOver.find(TextControl)).to.have.lengthOf(1);
expect(popOver.find(SelectControl)).to.have.lengthOf(1);
expect(popOver.find(TextControl)).toHaveLength(1);
expect(popOver.find(SelectControl)).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 MetricDefinitionOption from '../../../../src/explore/components/MetricDefinitionOption';
@@ -18,16 +17,16 @@ describe('MetricDefinitionOption', () => {
it('renders a MetricOption given a saved metric', () => {
const wrapper = setup({ option: { metric_name: 'a_saved_metric' } });
expect(wrapper.find(MetricOption)).to.have.lengthOf(1);
expect(wrapper.find(MetricOption)).toHaveLength(1);
});
it('renders a ColumnOption given a column', () => {
const wrapper = setup({ option: { column_name: 'a_column' } });
expect(wrapper.find(ColumnOption)).to.have.lengthOf(1);
expect(wrapper.find(ColumnOption)).toHaveLength(1);
});
it('renders an AggregateOption given an aggregate metric', () => {
const wrapper = setup({ option: { aggregate_name: 'an_aggregate' } });
expect(wrapper.find(AggregateOption)).to.have.lengthOf(1);
expect(wrapper.find(AggregateOption)).toHaveLength(1);
});
});

View File

@@ -1,6 +1,5 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import MetricDefinitionValue from '../../../../src/explore/components/MetricDefinitionValue';
@@ -17,13 +16,13 @@ const sumValueAdhocMetric = new AdhocMetric({
describe('MetricDefinitionValue', () => {
it('renders a MetricOption given a saved metric', () => {
const wrapper = shallow(<MetricDefinitionValue option={{ metric_name: 'a_saved_metric' }} />);
expect(wrapper.find(MetricOption)).to.have.lengthOf(1);
expect(wrapper.find(MetricOption)).toHaveLength(1);
});
it('renders an AdhocMetricOption given an adhoc metric', () => {
const wrapper = shallow((
<MetricDefinitionValue onMetricEdit={() => {}} option={sumValueAdhocMetric} />
));
expect(wrapper.find(AdhocMetricOption)).to.have.lengthOf(1);
expect(wrapper.find(AdhocMetricOption)).toHaveLength(1);
});
});

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 MetricsControl from '../../../../src/explore/components/controls/MetricsControl';
@@ -49,14 +48,14 @@ describe('MetricsControl', () => {
it('renders an OnPasteSelect', () => {
const { wrapper } = setup();
expect(wrapper.find(OnPasteSelect)).to.have.lengthOf(1);
expect(wrapper.find(OnPasteSelect)).toHaveLength(1);
});
describe('constructor', () => {
it('unifies options for the dropdown select with aggregates', () => {
const { wrapper } = setup();
expect(wrapper.state('options')).to.deep.equal([
expect(wrapper.state('options')).toEqual([
{ optionName: '_col_source', type: 'VARCHAR(255)', column_name: 'source' },
{ optionName: '_col_target', type: 'VARCHAR(255)', column_name: 'target' },
{ optionName: '_col_value', type: 'DOUBLE', column_name: 'value' },
@@ -83,9 +82,9 @@ describe('MetricsControl', () => {
});
const adhocMetric = wrapper.state('value')[0];
expect(adhocMetric instanceof AdhocMetric).to.be.true;
expect(adhocMetric.optionName.length).to.be.above(10);
expect(wrapper.state('value')).to.deep.equal([
expect(adhocMetric instanceof AdhocMetric).toBe(true);
expect(adhocMetric.optionName.length).toBeGreaterThan(10);
expect(wrapper.state('value')).toEqual([
{
expressionType: EXPRESSION_TYPES.SIMPLE,
column: { type: 'double', column_name: 'value' },
@@ -108,7 +107,7 @@ describe('MetricsControl', () => {
const { wrapper, onChange } = setup();
const select = wrapper.find(OnPasteSelect);
select.simulate('change', [{ metric_name: 'sum__value' }]);
expect(onChange.lastCall.args).to.deep.equal([['sum__value']]);
expect(onChange.lastCall.args).toEqual([['sum__value']]);
});
it('handles columns being selected', () => {
@@ -117,8 +116,8 @@ describe('MetricsControl', () => {
select.simulate('change', [valueColumn]);
const adhocMetric = onChange.lastCall.args[0][0];
expect(adhocMetric instanceof AdhocMetric).to.be.true;
expect(onChange.lastCall.args).to.deep.equal([[{
expect(adhocMetric instanceof AdhocMetric).toBe(true);
expect(onChange.lastCall.args).toEqual([[{
expressionType: EXPRESSION_TYPES.SIMPLE,
column: valueColumn,
aggregate: AGGREGATES.SUM,
@@ -145,16 +144,16 @@ describe('MetricsControl', () => {
select.simulate('change', [{ aggregate_name: 'SUM', optionName: 'SUM' }]);
expect(setInputSpy.calledWith('SUM()')).to.be.true;
expect(handleInputSpy.calledWith({ target: { value: 'SUM()' } })).to.be.true;
expect(onChange.lastCall.args).to.deep.equal([[]]);
expect(setInputSpy.calledWith('SUM()')).toBe(true);
expect(handleInputSpy.calledWith({ target: { value: 'SUM()' } })).toBe(true);
expect(onChange.lastCall.args).toEqual([[]]);
});
it('preserves existing selected AdhocMetrics', () => {
const { wrapper, onChange } = setup();
const select = wrapper.find(OnPasteSelect);
select.simulate('change', [{ metric_name: 'sum__value' }, sumValueAdhocMetric]);
expect(onChange.lastCall.args).to.deep.equal([['sum__value', sumValueAdhocMetric]]);
expect(onChange.lastCall.args).toEqual([['sum__value', sumValueAdhocMetric]]);
});
});
@@ -167,7 +166,7 @@ describe('MetricsControl', () => {
const editedMetric = sumValueAdhocMetric.duplicateWith({ aggregate: AGGREGATES.AVG });
wrapper.instance().onMetricEdit(editedMetric);
expect(onChange.lastCall.args).to.deep.equal([[
expect(onChange.lastCall.args).toEqual([[
editedMetric,
]]);
});
@@ -177,17 +176,17 @@ describe('MetricsControl', () => {
it('handles an aggregate in the input', () => {
const { wrapper } = setup();
expect(wrapper.state('aggregateInInput')).to.be.null;
expect(wrapper.state('aggregateInInput')).toBeNull();
wrapper.instance().checkIfAggregateInInput('AVG(');
expect(wrapper.state('aggregateInInput')).to.equal(AGGREGATES.AVG);
expect(wrapper.state('aggregateInInput')).toBe(AGGREGATES.AVG);
});
it('handles no aggregate in the input', () => {
const { wrapper } = setup();
expect(wrapper.state('aggregateInInput')).to.be.null;
expect(wrapper.state('aggregateInInput')).toBeNull();
wrapper.instance().checkIfAggregateInInput('colu');
expect(wrapper.state('aggregateInInput')).to.be.null;
expect(wrapper.state('aggregateInInput')).toBeNull();
});
});
@@ -202,7 +201,7 @@ describe('MetricsControl', () => {
expression: 'SUM(FANCY(metric))',
},
'a',
)).to.be.true;
)).toBe(true);
});
it('includes auto generated avg metrics for druid', () => {
@@ -215,7 +214,7 @@ describe('MetricsControl', () => {
expression: 'AVG(metric)',
},
'a',
)).to.be.true;
)).toBe(true);
});
it('includes columns and aggregates', () => {
@@ -224,12 +223,12 @@ describe('MetricsControl', () => {
expect(!!wrapper.instance().selectFilterOption(
{ type: 'VARCHAR(255)', column_name: 'source', optionName: '_col_source' },
'sou',
)).to.be.true;
)).toBe(true);
expect(!!wrapper.instance().selectFilterOption(
{ aggregate_name: 'AVG', optionName: '_aggregate_AVG' },
'av',
)).to.be.true;
)).toBe(true);
});
it('includes columns based on verbose_name', () => {
@@ -238,7 +237,7 @@ describe('MetricsControl', () => {
expect(!!wrapper.instance().selectFilterOption(
{ metric_name: 'sum__num', verbose_name: 'babies', optionName: '_col_sum_num' },
'bab',
)).to.be.true;
)).toBe(true);
});
it('excludes auto generated avg metrics for sqla', () => {
@@ -251,7 +250,7 @@ describe('MetricsControl', () => {
expression: 'AVG(metric)',
},
'a',
)).to.be.false;
)).toBe(false);
});
it('includes custom made simple saved metrics', () => {
@@ -264,7 +263,7 @@ describe('MetricsControl', () => {
expression: 'SUM(value)',
},
'sum',
)).to.be.true;
)).toBe(true);
});
it('excludes auto generated metrics', () => {
@@ -277,7 +276,7 @@ describe('MetricsControl', () => {
expression: 'SUM(value)',
},
'sum',
)).to.be.false;
)).toBe(false);
expect(!!wrapper.instance().selectFilterOption(
{
@@ -286,7 +285,7 @@ describe('MetricsControl', () => {
expression: 'SUM("table"."value")',
},
'sum',
)).to.be.false;
)).toBe(false);
});
it('filters out metrics if the input begins with an aggregate', () => {
@@ -296,7 +295,7 @@ describe('MetricsControl', () => {
expect(!!wrapper.instance().selectFilterOption(
{ metric_name: 'metric', expression: 'SUM(FANCY(metric))' },
'SUM(',
)).to.be.false;
)).toBe(false);
});
it('includes columns if the input begins with an aggregate', () => {
@@ -306,7 +305,7 @@ describe('MetricsControl', () => {
expect(!!wrapper.instance().selectFilterOption(
{ type: 'DOUBLE', column_name: 'value' },
'SUM(',
)).to.be.true;
)).toBe(true);
});
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import sinon from 'sinon';
@@ -14,7 +13,7 @@ describe('QueryAndSaveButtons', () => {
// It must render
it('renders', () => {
expect(React.isValidElement(<QueryAndSaveButtons {...defaultProps} />)).to.equal(true);
expect(React.isValidElement(<QueryAndSaveButtons {...defaultProps} />)).toBe(true);
});
// Test the output
@@ -26,18 +25,18 @@ describe('QueryAndSaveButtons', () => {
});
it('renders 2 buttons', () => {
expect(wrapper.find(Button)).to.have.lengthOf(2);
expect(wrapper.find(Button)).toHaveLength(2);
});
it('renders buttons with correct text', () => {
expect(wrapper.find(Button).contains(' Run Query')).to.eql(true);
expect(wrapper.find(Button).contains(' Save')).to.eql(true);
expect(wrapper.find(Button).contains(' Run Query')).toBe(true);
expect(wrapper.find(Button).contains(' Save')).toBe(true);
});
it('calls onQuery when query button is clicked', () => {
const queryButton = wrapper.find('.query');
queryButton.simulate('click');
expect(defaultProps.onQuery.called).to.eql(true);
expect(defaultProps.onQuery.called).toBe(true);
});
});
});

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('RowCountLabel', () => {
};
it('is valid', () => {
expect(React.isValidElement(<RowCountLabel {...defaultProps} />)).to.equal(true);
expect(React.isValidElement(<RowCountLabel {...defaultProps} />)).toBe(true);
});
it('renders a Label and a TooltipWrapper', () => {
const wrapper = shallow(<RowCountLabel {...defaultProps} />);
expect(wrapper.find(Label)).to.have.lengthOf(1);
expect(wrapper.find(TooltipWrapper)).to.have.lengthOf(1);
expect(wrapper.find(Label)).toHaveLength(1);
expect(wrapper.find(TooltipWrapper)).toHaveLength(1);
});
it('renders a warning when limit is reached', () => {
const props = {
@@ -27,6 +26,6 @@ describe('RowCountLabel', () => {
limit: 100,
};
const wrapper = shallow(<RowCountLabel {...props} />);
expect(wrapper.find(Label).first().props().bsStyle).to.equal('warning');
expect(wrapper.find(Label).first().props().bsStyle).toBe('warning');
});
});

View File

@@ -1,5 +1,4 @@
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import RunQueryActionButton
@@ -25,10 +24,10 @@ describe('RunQueryActionButton', () => {
it('is a valid react element', () => {
expect(
React.isValidElement(<RunQueryActionButton {...defaultProps} />),
).to.equal(true);
).toBe(true);
});
it('renders a single Button', () => {
expect(wrapper.find(Button)).to.have.lengthOf(1);
expect(wrapper.find(Button)).toHaveLength(1);
});
});

View File

@@ -2,7 +2,6 @@ import React from 'react';
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { expect } from 'chai';
import { shallow, mount } from 'enzyme';
import { Modal, Button, Radio } from 'react-bootstrap';
import sinon from 'sinon';
@@ -51,25 +50,25 @@ describe('SaveModal', () => {
it('renders a Modal with 7 inputs and 2 buttons', () => {
const wrapper = getWrapper();
expect(wrapper.find(Modal)).to.have.lengthOf(1);
expect(wrapper.find('input')).to.have.lengthOf(2);
expect(wrapper.find(Button)).to.have.lengthOf(2);
expect(wrapper.find(Radio)).to.have.lengthOf(5);
expect(wrapper.find(Modal)).toHaveLength(1);
expect(wrapper.find('input')).toHaveLength(2);
expect(wrapper.find(Button)).toHaveLength(2);
expect(wrapper.find(Radio)).toHaveLength(5);
});
it('does not show overwrite option for new slice', () => {
const wrapperNewSlice = getWrapper();
wrapperNewSlice.setProps({ slice: null });
expect(wrapperNewSlice.find('#overwrite-radio')).to.have.lengthOf(0);
expect(wrapperNewSlice.find('#saveas-radio')).to.have.lengthOf(1);
expect(wrapperNewSlice.find('#overwrite-radio')).toHaveLength(0);
expect(wrapperNewSlice.find('#saveas-radio')).toHaveLength(1);
});
it('disable overwrite option for non-owner', () => {
const wrapperForNonOwner = getWrapper();
wrapperForNonOwner.setProps({ can_overwrite: false });
const overwriteRadio = wrapperForNonOwner.find('#overwrite-radio');
expect(overwriteRadio).to.have.lengthOf(1);
expect(overwriteRadio.prop('disabled')).to.equal(true);
expect(overwriteRadio).toHaveLength(1);
expect(overwriteRadio.prop('disabled')).toBe(true);
});
it('saves a new slice', () => {
@@ -78,14 +77,14 @@ describe('SaveModal', () => {
wrapperForNewSlice.instance().changeAction('saveas');
const saveasRadio = wrapperForNewSlice.find('#saveas-radio');
saveasRadio.simulate('click');
expect(wrapperForNewSlice.state().action).to.equal('saveas');
expect(wrapperForNewSlice.state().action).toBe('saveas');
});
it('overwrite a slice', () => {
const wrapperForOverwrite = getWrapper();
const overwriteRadio = wrapperForOverwrite.find('#overwrite-radio');
overwriteRadio.simulate('click');
expect(wrapperForOverwrite.state().action).to.equal('overwrite');
expect(wrapperForOverwrite.state().action).toBe('overwrite');
});
it('componentDidMount', () => {
@@ -94,8 +93,8 @@ describe('SaveModal', () => {
mount(<SaveModal {...defaultProps} />, {
context: { store },
});
expect(SaveModal.prototype.componentDidMount.calledOnce).to.equal(true);
expect(saveModalActions.fetchDashboards.calledOnce).to.equal(true);
expect(SaveModal.prototype.componentDidMount.calledOnce).toBe(true);
expect(saveModalActions.fetchDashboards.calledOnce).toBe(true);
SaveModal.prototype.componentDidMount.restore();
saveModalActions.fetchDashboards.restore();
@@ -105,13 +104,13 @@ describe('SaveModal', () => {
const wrapper = getWrapper();
wrapper.instance().onChange('newSliceName', mockEvent);
expect(wrapper.state().newSliceName).to.equal(mockEvent.target.value);
expect(wrapper.state().newSliceName).toBe(mockEvent.target.value);
wrapper.instance().onChange('saveToDashboardId', mockEvent);
expect(wrapper.state().saveToDashboardId).to.equal(mockEvent.value);
expect(wrapper.state().saveToDashboardId).toBe(mockEvent.value);
wrapper.instance().onChange('newDashboardName', mockEvent);
expect(wrapper.state().newDashboardName).to.equal(mockEvent.target.value);
expect(wrapper.state().newDashboardName).toBe(mockEvent.target.value);
});
describe('saveOrOverwrite', () => {
@@ -132,7 +131,7 @@ describe('SaveModal', () => {
const wrapper = getWrapper();
wrapper.instance().saveOrOverwrite(true);
const args = saveModalActions.saveSlice.getCall(0).args;
expect(args[0]).to.deep.equal(defaultProps.form_data);
expect(args[0]).toEqual(defaultProps.form_data);
});
it('existing dashboard', () => {
const wrapper = getWrapper();
@@ -140,12 +139,12 @@ describe('SaveModal', () => {
wrapper.setState({ addToDash: 'existing' });
wrapper.instance().saveOrOverwrite(true);
expect(wrapper.state().alert).to.equal('Please select a dashboard');
expect(wrapper.state().alert).toBe('Please select a dashboard');
wrapper.setState({ saveToDashboardId });
wrapper.instance().saveOrOverwrite(true);
const args = saveModalActions.saveSlice.getCall(0).args;
expect(args[1].save_to_dashboard_id).to.equal(saveToDashboardId);
expect(args[1].save_to_dashboard_id).toBe(saveToDashboardId);
});
it('new dashboard', () => {
const wrapper = getWrapper();
@@ -153,12 +152,12 @@ describe('SaveModal', () => {
wrapper.setState({ addToDash: 'new' });
wrapper.instance().saveOrOverwrite(true);
expect(wrapper.state().alert).to.equal('Please enter a dashboard name');
expect(wrapper.state().alert).toBe('Please enter a dashboard name');
wrapper.setState({ newDashboardName });
wrapper.instance().saveOrOverwrite(true);
const args = saveModalActions.saveSlice.getCall(0).args;
expect(args[1].new_dashboard_name).to.equal(newDashboardName);
expect(args[1].new_dashboard_name).toBe(newDashboardName);
});
});
@@ -187,28 +186,27 @@ describe('SaveModal', () => {
it('makes the ajax request', () => {
makeRequest();
expect(ajaxStub.callCount).to.equal(1);
expect(ajaxStub.callCount).toBe(1);
});
it('calls correct url', () => {
const url = '/dashboardasync/api/read?_flt_0_owners=' + userID;
makeRequest();
expect(ajaxStub.getCall(0).args[0].url).to.be.equal(url);
expect(ajaxStub.getCall(0).args[0].url).toBe(url);
});
it('calls correct actions on error', () => {
ajaxStub.yieldsTo('error', { responseJSON: { error: 'error text' } });
makeRequest();
expect(dispatch.callCount).to.equal(1);
expect(dispatch.getCall(0).args[0].type).to.equal(saveModalActions.FETCH_DASHBOARDS_FAILED);
expect(dispatch.callCount).toBe(1);
expect(dispatch.getCall(0).args[0].type).toBe(saveModalActions.FETCH_DASHBOARDS_FAILED);
});
it('calls correct actions on success', () => {
ajaxStub.yieldsTo('success', mockDashboardData);
makeRequest();
expect(dispatch.callCount).to.equal(1);
expect(dispatch.getCall(0).args[0].type)
.to.equal(saveModalActions.FETCH_DASHBOARDS_SUCCEEDED);
expect(dispatch.callCount).toBe(1);
expect(dispatch.getCall(0).args[0].type).toBe(saveModalActions.FETCH_DASHBOARDS_SUCCEEDED);
});
});
@@ -218,8 +216,8 @@ describe('SaveModal', () => {
wrapper.setProps({ alert: 'old alert' });
wrapper.instance().removeAlert();
expect(saveModalActions.removeSaveModalAlert.callCount).to.equal(1);
expect(wrapper.state().alert).to.be.a('null');
expect(saveModalActions.removeSaveModalAlert.callCount).toBe(1);
expect(wrapper.state().alert).toBeNull();
saveModalActions.removeSaveModalAlert.restore();
});
});

View File

@@ -3,7 +3,6 @@ import React from 'react';
import Select, { Creatable } from 'react-select';
import VirtualizedSelect from 'react-virtualized-select';
import sinon from 'sinon';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import OnPasteSelect from '../../../../src/components/OnPasteSelect';
import VirtualizedRendererWrap from '../../../../src/components/VirtualizedRendererWrap';
@@ -29,43 +28,43 @@ describe('SelectControl', () => {
});
it('renders an OnPasteSelect', () => {
expect(wrapper.find(OnPasteSelect)).to.have.lengthOf(1);
expect(wrapper.find(OnPasteSelect)).toHaveLength(1);
});
it('calls onChange when toggled', () => {
const select = wrapper.find(OnPasteSelect);
select.simulate('change', { value: 50 });
expect(defaultProps.onChange.calledWith(50)).to.be.true;
expect(defaultProps.onChange.calledWith(50)).toBe(true);
});
it('passes VirtualizedSelect as selectWrap', () => {
const select = wrapper.find(OnPasteSelect);
expect(select.props().selectWrap).to.equal(VirtualizedSelect);
expect(select.props().selectWrap).toBe(VirtualizedSelect);
});
it('passes Creatable as selectComponent when freeForm=true', () => {
wrapper = shallow(<SelectControl {...defaultProps} freeForm />);
const select = wrapper.find(OnPasteSelect);
expect(select.props().selectComponent).to.equal(Creatable);
expect(select.props().selectComponent).toBe(Creatable);
});
it('passes Select as selectComponent when freeForm=false', () => {
const select = wrapper.find(OnPasteSelect);
expect(select.props().selectComponent).to.equal(Select);
expect(select.props().selectComponent).toBe(Select);
});
it('wraps optionRenderer in a VirtualizedRendererWrap', () => {
const select = wrapper.find(OnPasteSelect);
const defaultOptionRenderer = SelectControl.defaultProps.optionRenderer;
const wrappedRenderer = VirtualizedRendererWrap(defaultOptionRenderer);
expect(select.props().optionRenderer).to.be.a('Function');
expect(typeof select.props().optionRenderer).toBe('function');
// different instances of wrapper with same inner renderer are unequal
expect(select.props().optionRenderer.name).to.equal(wrappedRenderer.name);
expect(select.props().optionRenderer.name).toBe(wrappedRenderer.name);
});
describe('getOptions', () => {
it('returns the correct options', () => {
expect(wrapper.instance().getOptions(defaultProps)).to.deep.equal(options);
expect(wrapper.instance().getOptions(defaultProps)).toEqual(options);
});
it('returns the correct options when freeform is set to true', () => {
@@ -78,7 +77,7 @@ describe('SelectControl', () => {
{ value: 'one', label: 'one' },
{ value: 'two', label: 'two' },
];
expect(wrapper.instance().getOptions(freeFormProps)).to.deep.equal(newOptions);
expect(wrapper.instance().getOptions(freeFormProps)).toEqual(newOptions);
});
});
@@ -95,7 +94,7 @@ describe('SelectControl', () => {
value: null,
};
wrapper.setProps(newProps);
expect(wrapper.state().options).to.deep.equal(updatedOptions);
expect(wrapper.state().options).toEqual(updatedOptions);
});
});
});

View File

@@ -2,7 +2,6 @@
import React from 'react';
import { FormControl } from 'react-bootstrap';
import sinon from 'sinon';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import AceEditor from 'react-ace';
@@ -21,20 +20,20 @@ describe('SelectControl', () => {
});
it('renders a FormControl', () => {
expect(wrapper.find(FormControl)).to.have.lengthOf(1);
expect(wrapper.find(FormControl)).toHaveLength(1);
});
it('calls onChange when toggled', () => {
const select = wrapper.find(FormControl);
select.simulate('change', { target: { value: 'x' } });
expect(defaultProps.onChange.calledWith('x')).to.be.true;
expect(defaultProps.onChange.calledWith('x')).toBe(true);
});
it('renders a AceEditor when language is specified', () => {
const props = Object.assign({}, defaultProps);
props.language = 'markdown';
wrapper = shallow(<TextAreaControl {...props} />);
expect(wrapper.find(FormControl)).to.have.lengthOf(0);
expect(wrapper.find(AceEditor)).to.have.lengthOf(1);
expect(wrapper.find(FormControl)).toHaveLength(0);
expect(wrapper.find(AceEditor)).toHaveLength(1);
});
});

View File

@@ -2,7 +2,6 @@
import React from 'react';
import { FormControl, OverlayTrigger } from 'react-bootstrap';
import sinon from 'sinon';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import TimeSeriesColumnControl from '../../../../src/explore/components/controls/TimeSeriesColumnControl';
@@ -22,11 +21,11 @@ describe('SelectControl', () => {
});
it('renders an OverlayTrigger', () => {
expect(wrapper.find(OverlayTrigger)).to.have.lengthOf(1);
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
});
it('renders an Popover', () => {
const popOver = shallow(inst.renderPopover());
expect(popOver.find(FormControl)).to.have.lengthOf(3);
expect(popOver.find(FormControl)).toHaveLength(3);
});
});

View File

@@ -1,6 +1,5 @@
/* eslint-disable no-unused-expressions */
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import { OverlayTrigger, Label } from 'react-bootstrap';
@@ -30,16 +29,16 @@ describe('ViewportControl', () => {
it('renders a OverlayTrigger', () => {
const controlHeader = wrapper.find(ControlHeader);
expect(controlHeader).to.have.lengthOf(1);
expect(wrapper.find(OverlayTrigger)).to.have.length(1);
expect(controlHeader).toHaveLength(1);
expect(wrapper.find(OverlayTrigger)).toHaveLength(1);
});
it('renders a Popover with 5 TextControl', () => {
const popOver = shallow(inst.renderPopover());
expect(popOver.find(TextControl)).to.have.lengthOf(5);
expect(popOver.find(TextControl)).toHaveLength(5);
});
it('renders a summary in the label', () => {
expect(wrapper.find(Label).first().render().text()).to.equal('6° 51\' 8.50" | 31° 13\' 21.56"');
expect(wrapper.find(Label).first().render().text()).toBe('6° 51\' 8.50" | 31° 13\' 21.56"');
});
});

View File

@@ -1,6 +1,5 @@
import React from 'react';
import sinon from 'sinon';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import { Modal } from 'react-bootstrap';
import VizTypeControl from '../../../../src/explore/components/controls/VizTypeControl';
@@ -20,17 +19,17 @@ describe('VizTypeControl', () => {
});
it('renders a Modal', () => {
expect(wrapper.find(Modal)).to.have.lengthOf(1);
expect(wrapper.find(Modal)).toHaveLength(1);
});
it('calls onChange when toggled', () => {
const select = wrapper.find('.viztype-selector-container').first();
select.simulate('click');
expect(defaultProps.onChange.called).to.equal(true);
expect(defaultProps.onChange.called).toBe(true);
});
it('filters images based on text input', () => {
expect(wrapper.find('img').length).to.be.above(20);
expect(wrapper.find('img').length).toBeGreaterThan(20);
wrapper.setState({ filter: 'time' });
expect(wrapper.find('img').length).to.be.below(10);
expect(wrapper.find('img').length).toBeLessThan(10);
});
});