import { shallow } from 'enzyme';
import * as React from 'react';
import {
ElectronReleaseChannel,
RunResult,
VersionSource,
VersionState,
} from '../../../src/interfaces';
import { Bisector } from '../../../src/renderer/bisect';
import { BisectDialog } from '../../../src/renderer/components/dialog-bisect';
import { RunnerMock, StateMock } from '../../mocks/mocks';
jest.mock('../../../src/renderer/bisect');
describe('BisectDialog component', () => {
const NUM_VERSIONS = 10;
let runner: RunnerMock;
let store: StateMock;
const generateVersionRange = (rangeLength: number) =>
new Array(rangeLength).fill(0).map((_, i) => ({
state: VersionState.ready,
version: `${i + 1}.0.0`,
source: VersionSource.local,
}));
beforeEach(() => {
({ runner, state: store } = (window as any).ElectronFiddle.app);
store.versionsToShow = generateVersionRange(NUM_VERSIONS);
store.versions = Object.fromEntries(
store.versionsToShow.map((ver) => [ver.version, ver]),
);
store.channelsToShow = [ElectronReleaseChannel.stable];
});
it('renders', () => {
const wrapper = shallow();
// start and end selected
wrapper.setState({
startIndex: 3,
endIndex: 0,
allVersions: generateVersionRange(NUM_VERSIONS),
});
expect(wrapper).toMatchSnapshot();
// no selection
wrapper.setState({
startIndex: undefined,
endIndex: undefined,
allVersions: generateVersionRange(NUM_VERSIONS),
});
expect(wrapper).toMatchSnapshot();
// only start selected
wrapper.setState({
startIndex: 3,
endIndex: undefined,
allVersions: generateVersionRange(NUM_VERSIONS),
});
expect(wrapper).toMatchSnapshot();
// Incorrect order
wrapper.setState({
startIndex: 3,
endIndex: 4,
allVersions: generateVersionRange(NUM_VERSIONS),
});
expect(wrapper).toMatchSnapshot();
// Help displayed
(wrapper.instance() as any).showHelp();
expect(wrapper).toMatchSnapshot();
});
describe('onBeginSelect()', () => {
it('sets the begin version', () => {
const wrapper = shallow();
const instance: BisectDialog = wrapper.instance() as any;
expect(instance.state.startIndex).toBe(NUM_VERSIONS);
instance.onBeginSelect(store.versionsToShow[2]);
expect(instance.state.startIndex).toBe(2);
});
});
describe('onEndSelect()', () => {
it('sets the end version', () => {
const wrapper = shallow();
const instance: BisectDialog = wrapper.instance() as any;
expect(instance.state.endIndex).toBe(0);
instance.onEndSelect(store.versionsToShow[2]);
expect(instance.state.endIndex).toBe(2);
});
});
describe('onSubmit()', () => {
it('initiates a bisect instance and sets a version', async () => {
const version = '1.0.0';
(Bisector as jest.Mock).mockReturnValue({
getCurrentVersion: () => ({ version }),
});
const versions = generateVersionRange(NUM_VERSIONS);
const wrapper = shallow();
wrapper.setState({
allVersions: versions,
endIndex: 0,
startIndex: versions.length - 1,
});
const instance: BisectDialog = wrapper.instance() as any;
await instance.onSubmit();
expect(Bisector).toHaveBeenCalledWith(versions.reverse());
expect(store.Bisector).toBeDefined();
expect(store.setVersion).toHaveBeenCalledWith(version);
});
it('does nothing if endIndex or startIndex are falsy', async () => {
const wrapper = shallow();
wrapper.setState({
startIndex: undefined,
endIndex: 0,
});
const instance1: BisectDialog = wrapper.instance() as any;
await instance1.onSubmit();
expect(Bisector).not.toHaveBeenCalled();
wrapper.setState({
startIndex: 4,
endIndex: undefined,
});
const instance2: BisectDialog = wrapper.instance() as any;
await instance2.onSubmit();
expect(Bisector).not.toHaveBeenCalled();
});
});
describe('onAuto()', () => {
it('initiates autobisect', async () => {
// setup: dialog state
const wrapper = shallow();
wrapper.setState({
allVersions: generateVersionRange(NUM_VERSIONS),
endIndex: 0,
startIndex: 4,
});
runner.autobisect.mockResolvedValue(RunResult.SUCCESS);
// click the 'auto' button
const instance1: BisectDialog = wrapper.instance() as any;
await instance1.onAuto();
// check the results
expect(runner.autobisect).toHaveBeenCalled();
});
it('does nothing if endIndex or startIndex are falsy', async () => {
const wrapper = shallow();
wrapper.setState({
startIndex: undefined,
endIndex: 0,
});
const instance1: BisectDialog = wrapper.instance() as any;
await instance1.onAuto();
expect(Bisector).not.toHaveBeenCalled();
wrapper.setState({
startIndex: 4,
endIndex: undefined,
});
const instance2: BisectDialog = wrapper.instance() as any;
await instance2.onAuto();
expect(Bisector).not.toHaveBeenCalled();
});
});
describe('items disabled', () => {
let instance: BisectDialog;
beforeEach(() => {
const wrapper = shallow();
instance = wrapper.instance() as any;
});
describe('isEarliestItemDisabled', () => {
const endIndex = 2;
it('enables a version older than the "latest version"', () => {
instance.setState({ endIndex });
expect(
instance.isEarliestItemDisabled(store.versionsToShow[endIndex + 1]),
).toBeFalsy();
});
it('disables a version newer than the "latest version"', () => {
instance.setState({ endIndex });
expect(
instance.isEarliestItemDisabled(store.versionsToShow[endIndex - 1]),
).toBeTruthy();
});
});
describe('isLatestItemDisabled', () => {
const startIndex = 2;
it('enables a version newer than the "earliest version"', () => {
instance.setState({ startIndex });
expect(
instance.isLatestItemDisabled(store.versionsToShow[startIndex - 1]),
).toBeFalsy();
});
it('disables a version older than the "earliest version"', () => {
instance.setState({ startIndex });
expect(
instance.isLatestItemDisabled(store.versionsToShow[startIndex + 1]),
).toBeTruthy();
});
});
});
});