Commit 2c96b5e7 authored by Phil Hughes's avatar Phil Hughes

Merge branch 'himkp-jest-ide' into 'master'

Migrate all app/javascripts/ide specs to Jest

Closes #194238

See merge request gitlab-org/gitlab!32408
parents 6e59f81b 3e6878a6
......@@ -297,6 +297,3 @@ export * from './actions/tree';
export * from './actions/file';
export * from './actions/project';
export * from './actions/merge_request';
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -161,6 +161,3 @@ export const canCreateMergeRequests = (state, getters) =>
export const canPushCode = (state, getters) =>
Boolean(getters.findProjectPermissions(state.currentProjectId)[PERMISSION_PUSH_CODE]);
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -8,5 +8,4 @@ export const pingUsage = ({ rootGetters }) => {
return axios.post(url);
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
export default pingUsage;
......@@ -234,6 +234,3 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
window.dispatchEvent(new Event('resize'));
});
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -59,6 +59,3 @@ export const shouldDisableNewMrOption = (state, getters, rootState, rootGetters)
export const shouldCreateMR = (state, getters) =>
state.shouldCreateMR && !getters.shouldDisableNewMrOption;
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -117,6 +117,3 @@ export const undoFileTemplate = ({ dispatch, commit, rootGetters }) => {
dispatch('discardFileChanges', file.path, { root: true });
}
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
......@@ -25,6 +25,3 @@ export const open = ({ state, commit }, view) => {
export const close = ({ commit }) => {
commit(types.SET_OPEN, false);
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {};
// Similar to `lodash/debounce`, `lodash/throttle` also causes flaky specs.
// See `./debounce.js` for more details.
export default fn => fn;
Element.prototype.scrollTo = jest.fn().mockImplementation(function scrollTo(x, y) {
this.scrollLeft = x;
this.scrollTop = y;
this.dispatchEvent(new Event('scroll'));
});
import './element_scroll_into_view';
import './element_scroll_by';
import './element_scroll_to';
import './form_element';
import './get_client_rects';
import './inner_text';
......
import Vue from 'vue';
import createComponent from 'spec/helpers/vue_mount_component_helper';
import createComponent from 'helpers/vue_mount_component_helper';
import CommitMessageField from '~/ide/components/commit_sidebar/message_field.vue';
describe('IDE commit message field', () => {
......@@ -54,7 +54,7 @@ describe('IDE commit message field', () => {
});
it('emits input event on input', () => {
spyOn(vm, '$emit');
jest.spyOn(vm, '$emit').mockImplementation();
const textarea = vm.$el.querySelector('textarea');
textarea.value = 'testing';
......@@ -160,7 +160,7 @@ describe('IDE commit message field', () => {
.then(() => {
expect(vm.scrollTop).toBe(50);
expect(vm.$el.querySelector('.highlights').style.transform).toBe(
'translate3d(0px, -50px, 0px)',
'translate3d(0, -50px, 0)',
);
})
.then(done)
......
......@@ -3,44 +3,45 @@ import JobDetail from '~/ide/components/jobs/detail.vue';
import { createStore } from '~/ide/stores';
import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
import { jobs } from '../../mock_data';
import { TEST_HOST } from 'helpers/test_constants';
describe('IDE jobs detail view', () => {
const Component = Vue.extend(JobDetail);
let vm;
beforeEach(() => {
const createComponent = () => {
const store = createStore();
store.state.pipelines.detailJob = {
...jobs[0],
isLoading: true,
output: 'testing',
rawPath: `${gl.TEST_HOST}/raw`,
rawPath: `${TEST_HOST}/raw`,
};
vm = createComponentWithStore(Component, store);
spyOn(vm, 'fetchJobTrace').and.returnValue(Promise.resolve());
return createComponentWithStore(Vue.extend(JobDetail), store);
};
vm = vm.$mount();
beforeEach(() => {
vm = createComponent();
spyOn(vm.$refs.buildTrace, 'scrollTo');
jest.spyOn(vm, 'fetchJobTrace').mockResolvedValue();
});
afterEach(() => {
vm.$destroy();
});
it('calls fetchJobTrace on mount', () => {
describe('mounted', () => {
beforeEach(() => {
vm = vm.$mount();
});
it('calls fetchJobTrace', () => {
expect(vm.fetchJobTrace).toHaveBeenCalled();
});
it('scrolls to bottom on mount', done => {
setTimeout(() => {
it('scrolls to bottom', () => {
expect(vm.$refs.buildTrace.scrollTo).toHaveBeenCalled();
done();
});
});
it('renders job output', () => {
......@@ -78,7 +79,7 @@ describe('IDE jobs detail view', () => {
});
it('resets detailJob when clicking header button', () => {
spyOn(vm, 'setDetailJob');
jest.spyOn(vm, 'setDetailJob').mockImplementation();
vm.$el.querySelector('.btn').click();
......@@ -87,42 +88,48 @@ describe('IDE jobs detail view', () => {
it('renders raw path link', () => {
expect(vm.$el.querySelector('.controllers-buttons').getAttribute('href')).toBe(
`${gl.TEST_HOST}/raw`,
`${TEST_HOST}/raw`,
);
});
});
describe('scroll buttons', () => {
it('triggers scrollDown when clicking down button', done => {
spyOn(vm, 'scrollDown');
vm.$el.querySelectorAll('.btn-scroll')[1].click();
vm.$nextTick(() => {
expect(vm.scrollDown).toHaveBeenCalled();
done();
beforeEach(() => {
vm = createComponent();
jest.spyOn(vm, 'fetchJobTrace').mockResolvedValue();
});
afterEach(() => {
vm.$destroy();
});
it('triggers scrollUp when clicking up button', done => {
spyOn(vm, 'scrollUp');
it.each`
fnName | btnName | scrollPos
${'scrollDown'} | ${'down'} | ${0}
${'scrollUp'} | ${'up'} | ${1}
`('triggers $fnName when clicking $btnName button', ({ fnName, scrollPos }) => {
jest.spyOn(vm, fnName).mockImplementation();
vm.scrollPos = 1;
vm = vm.$mount();
vm.scrollPos = scrollPos;
vm.$nextTick()
.then(() => vm.$el.querySelector('.btn-scroll').click())
.then(() => vm.$nextTick())
.then(() => {
expect(vm.scrollUp).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
return vm.$nextTick().then(() => {
vm.$el.querySelector('.btn-scroll:not([disabled])').click();
expect(vm[fnName]).toHaveBeenCalled();
});
});
});
describe('scrollDown', () => {
beforeEach(() => {
vm = vm.$mount();
jest.spyOn(vm.$refs.buildTrace, 'scrollTo').mockImplementation();
});
it('scrolls build trace to bottom', () => {
spyOnProperty(vm.$refs.buildTrace, 'scrollHeight').and.returnValue(1000);
jest.spyOn(vm.$refs.buildTrace, 'scrollHeight', 'get').mockReturnValue(1000);
vm.scrollDown();
......@@ -131,6 +138,12 @@ describe('IDE jobs detail view', () => {
});
describe('scrollUp', () => {
beforeEach(() => {
vm = vm.$mount();
jest.spyOn(vm.$refs.buildTrace, 'scrollTo').mockImplementation();
});
it('scrolls build trace to top', () => {
vm.scrollUp();
......@@ -140,45 +153,35 @@ describe('IDE jobs detail view', () => {
describe('scrollBuildLog', () => {
beforeEach(() => {
spyOnProperty(vm.$refs.buildTrace, 'offsetHeight').and.returnValue(100);
spyOnProperty(vm.$refs.buildTrace, 'scrollHeight').and.returnValue(200);
vm = vm.$mount();
jest.spyOn(vm.$refs.buildTrace, 'scrollTo').mockImplementation();
jest.spyOn(vm.$refs.buildTrace, 'offsetHeight', 'get').mockReturnValue(100);
jest.spyOn(vm.$refs.buildTrace, 'scrollHeight', 'get').mockReturnValue(200);
});
it('sets scrollPos to bottom when at the bottom', done => {
spyOnProperty(vm.$refs.buildTrace, 'scrollTop').and.returnValue(100);
it('sets scrollPos to bottom when at the bottom', () => {
jest.spyOn(vm.$refs.buildTrace, 'scrollTop', 'get').mockReturnValue(100);
vm.scrollBuildLog();
setTimeout(() => {
expect(vm.scrollPos).toBe(1);
done();
});
});
it('sets scrollPos to top when at the top', done => {
spyOnProperty(vm.$refs.buildTrace, 'scrollTop').and.returnValue(0);
it('sets scrollPos to top when at the top', () => {
jest.spyOn(vm.$refs.buildTrace, 'scrollTop', 'get').mockReturnValue(0);
vm.scrollPos = 1;
vm.scrollBuildLog();
setTimeout(() => {
expect(vm.scrollPos).toBe(0);
done();
});
});
it('resets scrollPos when not at top or bottom', done => {
spyOnProperty(vm.$refs.buildTrace, 'scrollTop').and.returnValue(10);
it('resets scrollPos when not at top or bottom', () => {
jest.spyOn(vm.$refs.buildTrace, 'scrollTop', 'get').mockReturnValue(10);
vm.scrollBuildLog();
setTimeout(() => {
expect(vm.scrollPos).toBe('');
done();
});
});
});
});
......@@ -6,7 +6,7 @@ import List from '~/ide/components/pipelines/list.vue';
import JobsList from '~/ide/components/jobs/list.vue';
import Tab from '~/vue_shared/components/tabs/tab.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import { pipelines } from '../../../../javascripts/ide/mock_data';
import { pipelines } from 'jest/ide/mock_data';
import IDEServices from '~/ide/services';
const localVue = createLocalVue();
......
......@@ -7,13 +7,13 @@ import repoEditor from '~/ide/components/repo_editor.vue';
import Editor from '~/ide/lib/editor';
import { leftSidebarViews, FILE_VIEW_MODE_EDITOR, FILE_VIEW_MODE_PREVIEW } from '~/ide/constants';
import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
import setTimeoutPromise from '../../helpers/set_timeout_promise_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { file, resetStore } from '../helpers';
describe('RepoEditor', () => {
let vm;
beforeEach(done => {
beforeEach(() => {
const f = {
...file(),
viewMode: FILE_VIEW_MODE_EDITOR,
......@@ -45,12 +45,12 @@ describe('RepoEditor', () => {
Vue.set(vm.$store.state.entries, f.path, f);
spyOn(vm, 'getFileData').and.returnValue(Promise.resolve());
spyOn(vm, 'getRawFileData').and.returnValue(Promise.resolve());
jest.spyOn(vm, 'getFileData').mockResolvedValue();
jest.spyOn(vm, 'getRawFileData').mockResolvedValue();
vm.$mount();
Vue.nextTick(() => setTimeout(done));
return vm.$nextTick();
});
afterEach(() => {
......@@ -161,7 +161,7 @@ describe('RepoEditor', () => {
.then(() => {
vm.$el.querySelectorAll('.ide-mode-tabs .nav-links a')[1].click();
})
.then(setTimeoutPromise)
.then(waitForPromises)
.then(() => {
expect(vm.$el.querySelector('.preview-container').innerHTML).toContain(
'<p>testing 123</p>',
......@@ -186,7 +186,7 @@ describe('RepoEditor', () => {
describe('createEditorInstance', () => {
it('calls createInstance when viewer is editor', done => {
spyOn(vm.editor, 'createInstance');
jest.spyOn(vm.editor, 'createInstance').mockImplementation();
vm.createEditorInstance();
......@@ -200,7 +200,7 @@ describe('RepoEditor', () => {
it('calls createDiffInstance when viewer is diff', done => {
vm.$store.state.viewer = 'diff';
spyOn(vm.editor, 'createDiffInstance');
jest.spyOn(vm.editor, 'createDiffInstance').mockImplementation();
vm.createEditorInstance();
......@@ -214,7 +214,7 @@ describe('RepoEditor', () => {
it('calls createDiffInstance when viewer is a merge request diff', done => {
vm.$store.state.viewer = 'mrdiff';
spyOn(vm.editor, 'createDiffInstance');
jest.spyOn(vm.editor, 'createDiffInstance').mockImplementation();
vm.createEditorInstance();
......@@ -228,7 +228,7 @@ describe('RepoEditor', () => {
describe('setupEditor', () => {
it('creates new model', () => {
spyOn(vm.editor, 'createModel').and.callThrough();
jest.spyOn(vm.editor, 'createModel');
Editor.editorInstance.modelManager.dispose();
......@@ -239,7 +239,7 @@ describe('RepoEditor', () => {
});
it('attaches model to editor', () => {
spyOn(vm.editor, 'attachModel').and.callThrough();
jest.spyOn(vm.editor, 'attachModel');
Editor.editorInstance.modelManager.dispose();
......@@ -251,7 +251,7 @@ describe('RepoEditor', () => {
it('attaches model to merge request editor', () => {
vm.$store.state.viewer = 'mrdiff';
vm.file.mrChange = true;
spyOn(vm.editor, 'attachMergeRequestModel');
jest.spyOn(vm.editor, 'attachMergeRequestModel').mockImplementation();
Editor.editorInstance.modelManager.dispose();
......@@ -263,7 +263,7 @@ describe('RepoEditor', () => {
it('does not attach model to merge request editor when not a MR change', () => {
vm.$store.state.viewer = 'mrdiff';
vm.file.mrChange = false;
spyOn(vm.editor, 'attachMergeRequestModel');
jest.spyOn(vm.editor, 'attachMergeRequestModel').mockImplementation();
Editor.editorInstance.modelManager.dispose();
......@@ -273,7 +273,7 @@ describe('RepoEditor', () => {
});
it('adds callback methods', () => {
spyOn(vm.editor, 'onPositionChange').and.callThrough();
jest.spyOn(vm.editor, 'onPositionChange');
Editor.editorInstance.modelManager.dispose();
......@@ -286,7 +286,7 @@ describe('RepoEditor', () => {
it('updates state when model content changed', done => {
vm.model.setValue('testing 123\n');
setTimeout(() => {
setImmediate(() => {
expect(vm.file.content).toBe('testing 123\n');
done();
......@@ -294,7 +294,7 @@ describe('RepoEditor', () => {
});
it('sets head model as staged file', () => {
spyOn(vm.editor, 'createModel').and.callThrough();
jest.spyOn(vm.editor, 'createModel');
Editor.editorInstance.modelManager.dispose();
......@@ -310,8 +310,8 @@ describe('RepoEditor', () => {
describe('editor updateDimensions', () => {
beforeEach(() => {
spyOn(vm.editor, 'updateDimensions').and.callThrough();
spyOn(vm.editor, 'updateDiffView');
jest.spyOn(vm.editor, 'updateDimensions');
jest.spyOn(vm.editor, 'updateDiffView').mockImplementation();
});
it('calls updateDimensions when panelResizing is false', done => {
......@@ -381,7 +381,7 @@ describe('RepoEditor', () => {
describe('when files view mode is preview', () => {
beforeEach(done => {
spyOn(vm.editor, 'updateDimensions');
jest.spyOn(vm.editor, 'updateDimensions').mockImplementation();
vm.file.viewMode = FILE_VIEW_MODE_PREVIEW;
vm.$nextTick(done);
});
......@@ -392,28 +392,21 @@ describe('RepoEditor', () => {
});
describe('when file view mode changes to editor', () => {
beforeEach(done => {
it('should update dimensions', () => {
vm.file.viewMode = FILE_VIEW_MODE_EDITOR;
// one tick to trigger watch
vm.$nextTick()
// another tick needed until we can update dimensions
.then(() => vm.$nextTick())
.then(done)
.catch(done.fail);
});
it('should update dimensions', () => {
return vm.$nextTick().then(() => {
expect(vm.editor.updateDimensions).toHaveBeenCalled();
});
});
});
});
describe('initEditor', () => {
beforeEach(() => {
vm.file.tempFile = false;
spyOn(vm.editor, 'createInstance');
spyOnProperty(vm, 'shouldHideEditor').and.returnValue(true);
jest.spyOn(vm.editor, 'createInstance').mockImplementation();
jest.spyOn(vm, 'shouldHideEditor', 'get').mockReturnValue(true);
});
it('does not fetch file information for temp entries', done => {
......@@ -459,12 +452,12 @@ describe('RepoEditor', () => {
describe('updates on file changes', () => {
beforeEach(() => {
spyOn(vm, 'initEditor');
jest.spyOn(vm, 'initEditor').mockImplementation();
});
it('calls removePendingTab when old file is pending', done => {
spyOnProperty(vm, 'shouldHideEditor').and.returnValue(true);
spyOn(vm, 'removePendingTab');
jest.spyOn(vm, 'shouldHideEditor', 'get').mockReturnValue(true);
jest.spyOn(vm, 'removePendingTab').mockImplementation();
vm.file.pending = true;
......
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import store from '~/ide/stores';
import actions, {
import createFlash from '~/flash';
import {
getMergeRequestData,
getMergeRequestChanges,
getMergeRequestVersions,
......@@ -14,6 +15,8 @@ import { resetStore } from '../../helpers';
const TEST_PROJECT = 'abcproject';
const TEST_PROJECT_ID = 17;
jest.mock('~/flash');
describe('IDE store merge request actions', () => {
let mock;
......@@ -41,7 +44,7 @@ describe('IDE store merge request actions', () => {
describe('base case', () => {
beforeEach(() => {
spyOn(service, 'getProjectMergeRequests').and.callThrough();
jest.spyOn(service, 'getProjectMergeRequests');
mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests/).reply(200, mockData);
});
......@@ -66,7 +69,7 @@ describe('IDE store merge request actions', () => {
.dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
.then(() => {
expect(store.state.projects.abcproject.mergeRequests).toEqual({
'2': jasmine.objectContaining(mrData),
'2': expect.objectContaining(mrData),
});
done();
})
......@@ -99,7 +102,7 @@ describe('IDE store merge request actions', () => {
describe('no merge requests for branch available case', () => {
beforeEach(() => {
spyOn(service, 'getProjectMergeRequests').and.callThrough();
jest.spyOn(service, 'getProjectMergeRequests');
mock.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests/).reply(200, []);
});
......@@ -122,16 +125,11 @@ describe('IDE store merge request actions', () => {
});
it('flashes message, if error', done => {
const flashSpy = spyOnDependency(actions, 'flash');
store
.dispatch('getMergeRequestsForBranch', { projectId: TEST_PROJECT, branchId: 'bar' })
.then(() => {
fail('Expected getMergeRequestsForBranch to throw an error');
})
.catch(() => {
expect(flashSpy).toHaveBeenCalled();
expect(flashSpy.calls.argsFor(0)[0]).toEqual('Error fetching merge requests for bar');
expect(createFlash).toHaveBeenCalled();
expect(createFlash.mock.calls[0][0]).toBe('Error fetching merge requests for bar');
})
.then(done)
.catch(done.fail);
......@@ -142,7 +140,7 @@ describe('IDE store merge request actions', () => {
describe('getMergeRequestData', () => {
describe('success', () => {
beforeEach(() => {
spyOn(service, 'getProjectMergeRequestData').and.callThrough();
jest.spyOn(service, 'getProjectMergeRequestData');
mock
.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1/)
......@@ -181,7 +179,7 @@ describe('IDE store merge request actions', () => {
});
it('dispatches error action', done => {
const dispatch = jasmine.createSpy('dispatch');
const dispatch = jest.fn();
getMergeRequestData(
{
......@@ -195,7 +193,7 @@ describe('IDE store merge request actions', () => {
.catch(() => {
expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
text: 'An error occurred while loading the merge request.',
action: jasmine.any(Function),
action: expect.any(Function),
actionText: 'Please try again',
actionPayload: {
projectId: TEST_PROJECT,
......@@ -217,7 +215,7 @@ describe('IDE store merge request actions', () => {
describe('success', () => {
beforeEach(() => {
spyOn(service, 'getProjectMergeRequestChanges').and.callThrough();
jest.spyOn(service, 'getProjectMergeRequestChanges');
mock
.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/changes/)
......@@ -254,7 +252,7 @@ describe('IDE store merge request actions', () => {
});
it('dispatches error action', done => {
const dispatch = jasmine.createSpy('dispatch');
const dispatch = jest.fn();
getMergeRequestChanges(
{
......@@ -268,7 +266,7 @@ describe('IDE store merge request actions', () => {
.catch(() => {
expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
text: 'An error occurred while loading the merge request changes.',
action: jasmine.any(Function),
action: expect.any(Function),
actionText: 'Please try again',
actionPayload: {
projectId: TEST_PROJECT,
......@@ -293,7 +291,7 @@ describe('IDE store merge request actions', () => {
mock
.onGet(/api\/(.*)\/projects\/abcproject\/merge_requests\/1\/versions/)
.reply(200, [{ id: 789 }]);
spyOn(service, 'getProjectMergeRequestVersions').and.callThrough();
jest.spyOn(service, 'getProjectMergeRequestVersions');
});
it('calls getProjectMergeRequestVersions service method', done => {
......@@ -324,7 +322,7 @@ describe('IDE store merge request actions', () => {
});
it('dispatches error action', done => {
const dispatch = jasmine.createSpy('dispatch');
const dispatch = jest.fn();
getMergeRequestVersions(
{
......@@ -338,7 +336,7 @@ describe('IDE store merge request actions', () => {
.catch(() => {
expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
text: 'An error occurred while loading the merge request version data.',
action: jasmine.any(Function),
action: expect.any(Function),
actionText: 'Please try again',
actionPayload: {
projectId: TEST_PROJECT,
......@@ -400,7 +398,7 @@ describe('IDE store merge request actions', () => {
const originalDispatch = store.dispatch;
spyOn(store, 'dispatch').and.callFake((type, payload) => {
jest.spyOn(store, 'dispatch').mockImplementation((type, payload) => {
switch (type) {
case 'getMergeRequestData':
return Promise.resolve(testMergeRequest);
......@@ -415,7 +413,7 @@ describe('IDE store merge request actions', () => {
return originalDispatch(type, payload);
}
});
spyOn(service, 'getFileData').and.callFake(() =>
jest.spyOn(service, 'getFileData').mockImplementation(() =>
Promise.resolve({
headers: {},
}),
......@@ -425,7 +423,7 @@ describe('IDE store merge request actions', () => {
it('dispatches actions for merge request data', done => {
openMergeRequest({ state: store.state, dispatch: store.dispatch, getters: mockGetters }, mr)
.then(() => {
expect(store.dispatch.calls.allArgs()).toEqual([
expect(store.dispatch.mock.calls).toEqual([
['getMergeRequestData', mr],
['setCurrentBranchId', testMergeRequest.source_branch],
[
......@@ -493,15 +491,11 @@ describe('IDE store merge request actions', () => {
});
it('flashes message, if error', done => {
const flashSpy = spyOnDependency(actions, 'flash');
store.dispatch.and.returnValue(Promise.reject());
store.dispatch.mockRejectedValue();
openMergeRequest(store, mr)
.then(() => {
fail('Expected openMergeRequest to throw an error');
})
.catch(() => {
expect(flashSpy).toHaveBeenCalledWith(jasmine.any(String));
expect(createFlash).toHaveBeenCalledWith(expect.any(String));
})
.then(done)
.catch(done.fail);
......
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import { createStore } from '~/ide/stores';
import router from '~/ide/ide_router';
import {
refreshLastCommitData,
showBranchNotFoundError,
......@@ -9,10 +11,8 @@ import {
loadFile,
loadBranch,
} from '~/ide/stores/actions';
import { createStore } from '~/ide/stores';
import service from '~/ide/services';
import api from '~/api';
import router from '~/ide/ide_router';
import { resetStore } from '../../helpers';
import testAction from '../../../helpers/vuex_action_helper';
......@@ -49,13 +49,11 @@ describe('IDE store project actions', () => {
},
},
};
spyOn(service, 'getBranchData').and.returnValue(
Promise.resolve({
jest.spyOn(service, 'getBranchData').mockResolvedValue({
data: {
commit: { id: '123' },
},
}),
);
});
});
it('calls the service', done => {
......@@ -110,7 +108,7 @@ describe('IDE store project actions', () => {
type: 'setErrorMessage',
payload: {
text: "Branch <strong>master</strong> was not found in this project's repository.",
action: jasmine.any(Function),
action: expect.any(Function),
actionText: 'Create branch',
actionPayload: 'master',
},
......@@ -122,10 +120,12 @@ describe('IDE store project actions', () => {
});
describe('createNewBranchFromDefault', () => {
it('calls API', done => {
spyOn(api, 'createBranch').and.returnValue(Promise.resolve());
spyOn(router, 'push');
beforeEach(() => {
jest.spyOn(api, 'createBranch').mockResolvedValue();
jest.spyOn(router, 'push').mockImplementation();
});
it('calls API', done => {
createNewBranchFromDefault(
{
state: {
......@@ -151,9 +151,7 @@ describe('IDE store project actions', () => {
});
it('clears error message', done => {
const dispatchSpy = jasmine.createSpy('dispatch');
spyOn(api, 'createBranch').and.returnValue(Promise.resolve());
spyOn(router, 'push');
const dispatchSpy = jest.fn().mockName('dispatch');
createNewBranchFromDefault(
{
......@@ -177,9 +175,6 @@ describe('IDE store project actions', () => {
});
it('reloads window', done => {
spyOn(api, 'createBranch').and.returnValue(Promise.resolve());
spyOn(router, 'push');
createNewBranchFromDefault(
{
state: {
......@@ -215,7 +210,7 @@ describe('IDE store project actions', () => {
payload: { entry: store.state.trees[`${TEST_PROJECT_ID}/master`], forceValue: false },
},
],
jasmine.any(Object),
expect.any(Object),
done,
);
});
......@@ -243,7 +238,7 @@ describe('IDE store project actions', () => {
'foo/bar': { pending: false },
},
});
spyOn(store, 'dispatch');
jest.spyOn(store, 'dispatch').mockImplementation();
});
it('does nothing, if basePath is not given', () => {
......@@ -264,15 +259,15 @@ describe('IDE store project actions', () => {
it('does not handle tree entry action, if entry is pending', () => {
loadFile(store, { basePath: 'foo/bar-pending/' });
expect(store.dispatch).not.toHaveBeenCalledWith('handleTreeEntryAction', jasmine.anything());
expect(store.dispatch).not.toHaveBeenCalledWith('handleTreeEntryAction', expect.anything());
});
it('creates a new temp file supplied via URL if the file does not exist yet', () => {
loadFile(store, { basePath: 'not-existent.md' });
expect(store.dispatch.calls.count()).toBe(1);
expect(store.dispatch.mock.calls).toHaveLength(1);
expect(store.dispatch).not.toHaveBeenCalledWith('handleTreeEntryAction', jasmine.anything());
expect(store.dispatch).not.toHaveBeenCalledWith('handleTreeEntryAction', expect.anything());
expect(store.dispatch).toHaveBeenCalledWith('createTempEntry', {
name: 'not-existent.md',
......@@ -307,14 +302,14 @@ describe('IDE store project actions', () => {
it('fetches branch data', done => {
const mockGetters = { findBranch: () => ({ commit: { id: ref } }) };
spyOn(store, 'dispatch').and.returnValue(Promise.resolve());
jest.spyOn(store, 'dispatch').mockResolvedValue();
loadBranch(
{ getters: mockGetters, state: store.state, dispatch: store.dispatch },
{ projectId, branchId },
)
.then(() => {
expect(store.dispatch.calls.allArgs()).toEqual([
expect(store.dispatch.mock.calls).toEqual([
['getBranchData', { projectId, branchId }],
['getMergeRequestsForBranch', { projectId, branchId }],
['getFiles', { projectId, branchId, ref }],
......@@ -325,12 +320,12 @@ describe('IDE store project actions', () => {
});
it('shows an error if branch can not be fetched', done => {
spyOn(store, 'dispatch').and.returnValue(Promise.reject());
jest.spyOn(store, 'dispatch').mockReturnValue(Promise.reject());
loadBranch(store, { projectId, branchId })
.then(done.fail)
.catch(() => {
expect(store.dispatch.calls.allArgs()).toEqual([
expect(store.dispatch.mock.calls).toEqual([
['getBranchData', { projectId, branchId }],
['showBranchNotFoundError', branchId],
]);
......@@ -360,13 +355,13 @@ describe('IDE store project actions', () => {
describe('existing branch', () => {
beforeEach(() => {
spyOn(store, 'dispatch').and.returnValue(Promise.resolve());
jest.spyOn(store, 'dispatch').mockResolvedValue();
});
it('dispatches branch actions', done => {
openBranch(store, branch)
.then(() => {
expect(store.dispatch.calls.allArgs()).toEqual([
expect(store.dispatch.mock.calls).toEqual([
['setCurrentBranchId', branchId],
['loadBranch', { projectId, branchId }],
['loadFile', { basePath: undefined }],
......@@ -379,13 +374,13 @@ describe('IDE store project actions', () => {
describe('non-existent branch', () => {
beforeEach(() => {
spyOn(store, 'dispatch').and.returnValue(Promise.reject());
jest.spyOn(store, 'dispatch').mockReturnValue(Promise.reject());
});
it('dispatches correct branch actions', done => {
openBranch(store, branch)
.then(val => {
expect(store.dispatch.calls.allArgs()).toEqual([
expect(store.dispatch.mock.calls).toEqual([
['setCurrentBranchId', branchId],
['loadBranch', { projectId, branchId }],
]);
......
import MockAdapter from 'axios-mock-adapter';
import testAction from 'spec/helpers/vuex_action_helper';
import testAction from 'helpers/vuex_action_helper';
import { showTreeEntry, getFiles, setDirectoryData } from '~/ide/stores/actions/tree';
import * as types from '~/ide/stores/mutation_types';
import axios from '~/lib/utils/axios_utils';
......@@ -21,8 +21,7 @@ describe('Multi-file store tree actions', () => {
};
beforeEach(() => {
jasmine.clock().install();
spyOn(router, 'push');
jest.spyOn(router, 'push').mockImplementation();
mock = new MockAdapter(axios);
......@@ -35,7 +34,6 @@ describe('Multi-file store tree actions', () => {
});
afterEach(() => {
jasmine.clock().uninstall();
mock.restore();
resetStore(store);
});
......@@ -43,7 +41,7 @@ describe('Multi-file store tree actions', () => {
describe('getFiles', () => {
describe('success', () => {
beforeEach(() => {
spyOn(service, 'getFiles').and.callThrough();
jest.spyOn(service, 'getFiles');
mock
.onGet(/(.*)/)
......@@ -54,15 +52,16 @@ describe('Multi-file store tree actions', () => {
]);
});
it('calls service getFiles', done => {
it('calls service getFiles', () => {
return (
store
.dispatch('getFiles', basicCallParameters)
// getFiles actions calls lodash.defer
.then(() => jest.runOnlyPendingTimers())
.then(() => {
expect(service.getFiles).toHaveBeenCalledWith('foo/abcproject', '12345678');
done();
})
.catch(done.fail);
);
});
it('adds data into tree', done => {
......@@ -71,7 +70,7 @@ describe('Multi-file store tree actions', () => {
.then(() => {
// The populating of the tree is deferred for performance reasons.
// See this merge request for details: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/25700
jasmine.clock().tick(1);
jest.advanceTimersByTime(1);
})
.then(() => {
projectTree = store.state.trees['abcproject/master'];
......@@ -91,7 +90,7 @@ describe('Multi-file store tree actions', () => {
describe('error', () => {
it('dispatches error action', done => {
const dispatch = jasmine.createSpy('dispatchSpy');
const dispatch = jest.fn();
store.state.projects = {
'abc/def': {
......@@ -127,7 +126,7 @@ describe('Multi-file store tree actions', () => {
.catch(() => {
expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
text: 'An error occurred while loading all the files.',
action: jasmine.any(Function),
action: expect.any(Function),
actionText: 'Please try again',
actionPayload: { projectId: 'abc/def', branchId: 'master-testing' },
});
......
import MockAdapter from 'axios-mock-adapter';
import actions, {
import { visitUrl } from '~/lib/utils/url_utility';
import { createStore } from '~/ide/stores';
import router from '~/ide/ide_router';
import {
stageAllChanges,
unstageAllChanges,
toggleFileFinder,
......@@ -15,28 +18,29 @@ import actions, {
discardAllChanges,
} from '~/ide/stores/actions';
import axios from '~/lib/utils/axios_utils';
import { createStore } from '~/ide/stores';
import * as types from '~/ide/stores/mutation_types';
import router from '~/ide/ide_router';
import { file } from '../helpers';
import testAction from '../../helpers/vuex_action_helper';
import eventHub from '~/ide/eventhub';
jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn(),
joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths,
}));
describe('Multi-file store actions', () => {
let store;
beforeEach(() => {
store = createStore();
spyOn(store, 'commit').and.callThrough();
spyOn(store, 'dispatch').and.callThrough();
spyOn(router, 'push');
jest.spyOn(store, 'commit');
jest.spyOn(store, 'dispatch');
jest.spyOn(router, 'push').mockImplementation();
});
describe('redirectToUrl', () => {
it('calls visitUrl', done => {
const visitUrl = spyOnDependency(actions, 'visitUrl');
store
.dispatch('redirectToUrl', 'test')
.then(() => {
......@@ -79,7 +83,7 @@ describe('Multi-file store actions', () => {
discardAllChanges(store);
expect(store.dispatch.calls.allArgs()).toEqual(jasmine.arrayContaining(expectedCalls));
expect(store.dispatch.mock.calls).toEqual(expect.arrayContaining(expectedCalls));
});
it('removes all files from changedFiles state', done => {
......@@ -255,7 +259,7 @@ describe('Multi-file store actions', () => {
type: 'blob',
})
.then(() => {
expect(store.state.stagedFiles).toEqual([jasmine.objectContaining({ name })]);
expect(store.state.stagedFiles).toEqual([expect.objectContaining({ name })]);
done();
})
......@@ -311,12 +315,12 @@ describe('Multi-file store actions', () => {
document.body.innerHTML +=
'<div id="tabs"><div class="active"><div class="repo-tab"></div></div></div>';
const el = document.querySelector('.repo-tab');
spyOn(el, 'focus');
jest.spyOn(el, 'focus').mockImplementation();
store
.dispatch('scrollToTab')
.then(() => {
setTimeout(() => {
setImmediate(() => {
expect(el.focus).toHaveBeenCalled();
document.getElementById('tabs').remove();
......@@ -350,16 +354,16 @@ describe('Multi-file store actions', () => {
it('adds all files from changedFiles to stagedFiles', () => {
stageAllChanges(store);
expect(store.commit.calls.allArgs()).toEqual([
expect(store.commit.mock.calls).toEqual([
[types.SET_LAST_COMMIT_MSG, ''],
[types.STAGE_CHANGE, jasmine.objectContaining({ path: file1.path })],
[types.STAGE_CHANGE, expect.objectContaining({ path: file1.path })],
]);
});
it('opens pending tab if a change exists in that file', () => {
stageAllChanges(store);
expect(store.dispatch.calls.allArgs()).toEqual([
expect(store.dispatch.mock.calls).toEqual([
[
'openPendingTab',
{ file: { ...file1, staged: true, changed: true }, keyPrefix: 'staged' },
......@@ -382,15 +386,15 @@ describe('Multi-file store actions', () => {
it('removes all files from stagedFiles after unstaging', () => {
unstageAllChanges(store);
expect(store.commit.calls.allArgs()).toEqual([
[types.UNSTAGE_CHANGE, jasmine.objectContaining({ path: file2.path })],
expect(store.commit.mock.calls).toEqual([
[types.UNSTAGE_CHANGE, expect.objectContaining({ path: file2.path })],
]);
});
it('opens pending tab if a change exists in that file', () => {
unstageAllChanges(store);
expect(store.dispatch.calls.allArgs()).toEqual([
expect(store.dispatch.mock.calls).toEqual([
['openPendingTab', { file: file1, keyPrefix: 'unstaged' }],
]);
});
......@@ -696,7 +700,7 @@ describe('Multi-file store actions', () => {
describe('renameEntry', () => {
describe('purging of file model cache', () => {
beforeEach(() => {
spyOn(eventHub, '$emit');
jest.spyOn(eventHub, '$emit').mockImplementation();
});
it('does not purge model cache for temporary entries that got renamed', done => {
......@@ -715,9 +719,7 @@ describe('Multi-file store actions', () => {
name: 'new',
})
.then(() => {
expect(eventHub.$emit.calls.allArgs()).not.toContain(
'editor.update.model.dispose.foo-bar',
);
expect(eventHub.$emit.mock.calls).not.toContain('editor.update.model.dispose.foo-bar');
})
.then(done)
.catch(done.fail);
......@@ -768,17 +770,17 @@ describe('Multi-file store actions', () => {
});
it('by default renames an entry and stages it', () => {
const dispatch = jasmine.createSpy();
const commit = jasmine.createSpy();
const dispatch = jest.fn();
const commit = jest.fn();
renameEntry(
{ dispatch, commit, state: store.state, getters: store.getters },
{ path: 'orig', name: 'renamed' },
);
expect(commit.calls.allArgs()).toEqual([
expect(commit.mock.calls).toEqual([
[types.RENAME_ENTRY, { path: 'orig', name: 'renamed', parentPath: undefined }],
[types.STAGE_CHANGE, jasmine.objectContaining({ path: 'renamed' })],
[types.STAGE_CHANGE, expect.objectContaining({ path: 'renamed' })],
]);
});
......@@ -813,7 +815,7 @@ describe('Multi-file store actions', () => {
renameEntry,
{ path: 'orig', name: 'renamed' },
store.state,
[jasmine.objectContaining({ type: types.RENAME_ENTRY })],
[expect.objectContaining({ type: types.RENAME_ENTRY })],
[{ type: 'triggerFilesChange' }],
done,
);
......@@ -831,7 +833,7 @@ describe('Multi-file store actions', () => {
name: 'renamed',
})
.then(() => {
expect(router.push.calls.count()).toBe(1);
expect(router.push.mock.calls).toHaveLength(1);
expect(router.push).toHaveBeenCalledWith(`/project/foo-bar.md`);
})
.then(done)
......@@ -918,7 +920,7 @@ describe('Multi-file store actions', () => {
expect(entries['new-folder']).toBeDefined();
expect(entries['new-folder/test']).toEqual(
jasmine.objectContaining({
expect.objectContaining({
path: 'new-folder/test',
name: 'test',
prevPath: 'old-folder/test',
......@@ -941,7 +943,7 @@ describe('Multi-file store actions', () => {
expect(entries['old-folder']).toBeDefined();
expect(entries['old-folder/test']).toEqual(
jasmine.objectContaining({
expect.objectContaining({
path: 'old-folder/test',
name: 'test',
prevPath: undefined,
......@@ -989,10 +991,10 @@ describe('Multi-file store actions', () => {
.dispatch('renameEntry', { path: filePath, name: fileName, parentPath: newParentPath })
.then(() => {
expect(store.state.entries[newParentPath]).toEqual(
jasmine.objectContaining({
expect.objectContaining({
path: newParentPath,
type: 'tree',
tree: jasmine.arrayContaining([
tree: expect.arrayContaining([
store.state.entries[`${newParentPath}/${fileName}`],
]),
}),
......@@ -1078,7 +1080,7 @@ describe('Multi-file store actions', () => {
branchId: 'master-testing',
},
];
dispatch = jasmine.createSpy('dispatchSpy');
dispatch = jest.fn();
document.body.innerHTML += '<div class="flash-container"></div>';
});
......@@ -1092,7 +1094,7 @@ describe('Multi-file store actions', () => {
getBranchData(...callParams)
.then(done.fail)
.catch(e => {
expect(dispatch.calls.count()).toEqual(0);
expect(dispatch.mock.calls).toHaveLength(0);
expect(e.response.status).toEqual(404);
expect(document.querySelector('.flash-alert')).toBeNull();
done();
......@@ -1105,7 +1107,7 @@ describe('Multi-file store actions', () => {
getBranchData(...callParams)
.then(done.fail)
.catch(e => {
expect(dispatch.calls.count()).toEqual(0);
expect(dispatch.mock.calls).toHaveLength(0);
expect(e.response).toBeUndefined();
expect(document.querySelector('.flash-alert')).not.toBeNull();
done();
......
import { resetStore, file } from 'spec/ide/helpers';
import rootActions from '~/ide/stores/actions';
import { resetStore, file } from 'jest/ide/helpers';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { visitUrl } from '~/lib/utils/url_utility';
import { createStore } from '~/ide/stores';
import service from '~/ide/services';
import router from '~/ide/ide_router';
......@@ -10,15 +12,28 @@ import * as actions from '~/ide/stores/modules/commit/actions';
import { commitActionTypes, PERMISSION_CREATE_MR } from '~/ide/constants';
import testAction from '../../../../helpers/vuex_action_helper';
jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn(),
joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths,
}));
const TEST_COMMIT_SHA = '123456789';
const store = createStore();
describe('IDE commit module actions', () => {
let mock;
beforeEach(() => {
spyOn(router, 'push');
gon.api_version = 'v1';
mock = new MockAdapter(axios);
jest.spyOn(router, 'push').mockImplementation();
mock.onGet('/api/v1/projects/abcproject/repository/branches/master').reply(200);
});
afterEach(() => {
delete gon.api_version;
mock.restore();
resetStore(store);
});
......@@ -71,7 +86,7 @@ describe('IDE commit module actions', () => {
[
{
type: mutationTypes.UPDATE_COMMIT_ACTION,
payload: { commitAction: jasmine.anything() },
payload: { commitAction: expect.anything() },
},
{ type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: true },
],
......@@ -92,7 +107,7 @@ describe('IDE commit module actions', () => {
[
{
type: mutationTypes.UPDATE_COMMIT_ACTION,
payload: { commitAction: jasmine.anything() },
payload: { commitAction: expect.anything() },
},
{ type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: false },
],
......@@ -168,7 +183,7 @@ describe('IDE commit module actions', () => {
let f;
beforeEach(() => {
spyOn(eventHub, '$emit');
jest.spyOn(eventHub, '$emit').mockImplementation();
f = file('changedFile');
Object.assign(f, {
......@@ -200,9 +215,9 @@ describe('IDE commit module actions', () => {
changed: true,
},
],
openFiles: store.state.stagedFiles,
});
store.state.openFiles = store.state.stagedFiles;
store.state.stagedFiles.forEach(stagedFile => {
store.state.entries[stagedFile.path] = stagedFile;
});
......@@ -280,11 +295,7 @@ describe('IDE commit module actions', () => {
});
describe('commitChanges', () => {
let visitUrl;
beforeEach(() => {
visitUrl = spyOnDependency(rootActions, 'visitUrl');
document.body.innerHTML += '<div class="flash-container"></div>';
const f = {
......@@ -346,11 +357,7 @@ describe('IDE commit module actions', () => {
};
beforeEach(() => {
spyOn(service, 'commit').and.returnValue(
Promise.resolve({
data: COMMIT_RESPONSE,
}),
);
jest.spyOn(service, 'commit').mockResolvedValue({ data: COMMIT_RESPONSE });
});
it('calls service', done => {
......@@ -358,14 +365,14 @@ describe('IDE commit module actions', () => {
.dispatch('commit/commitChanges')
.then(() => {
expect(service.commit).toHaveBeenCalledWith('abcproject', {
branch: jasmine.anything(),
branch: expect.anything(),
commit_message: 'testing 123',
actions: [
{
action: commitActionTypes.update,
file_path: jasmine.anything(),
file_path: expect.anything(),
content: '\n',
encoding: jasmine.anything(),
encoding: expect.anything(),
last_commit_id: undefined,
previous_path: undefined,
},
......@@ -385,14 +392,14 @@ describe('IDE commit module actions', () => {
.dispatch('commit/commitChanges')
.then(() => {
expect(service.commit).toHaveBeenCalledWith('abcproject', {
branch: jasmine.anything(),
branch: expect.anything(),
commit_message: 'testing 123',
actions: [
{
action: commitActionTypes.update,
file_path: jasmine.anything(),
file_path: expect.anything(),
content: '\n',
encoding: jasmine.anything(),
encoding: expect.anything(),
last_commit_id: TEST_COMMIT_SHA,
previous_path: undefined,
},
......@@ -455,7 +462,7 @@ describe('IDE commit module actions', () => {
describe('merge request', () => {
it('redirects to new merge request page', done => {
spyOn(eventHub, '$on');
jest.spyOn(eventHub, '$on').mockImplementation();
store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
store.state.commit.shouldCreateMR = true;
......@@ -475,7 +482,7 @@ describe('IDE commit module actions', () => {
});
it('does not redirect to new merge request page when shouldCreateMR is not checked', done => {
spyOn(eventHub, '$on');
jest.spyOn(eventHub, '$on').mockImplementation();
store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
store.state.commit.shouldCreateMR = false;
......@@ -489,30 +496,25 @@ describe('IDE commit module actions', () => {
.catch(done.fail);
});
it('resets changed files before redirecting', done => {
visitUrl = visitUrl.and.callFake(() => {
expect(store.state.stagedFiles.length).toBe(0);
done();
});
spyOn(eventHub, '$on');
it('resets changed files before redirecting', () => {
jest.spyOn(eventHub, '$on').mockImplementation();
store.state.commit.commitAction = '3';
store.dispatch('commit/commitChanges').catch(done.fail);
return store.dispatch('commit/commitChanges').then(() => {
expect(store.state.stagedFiles.length).toBe(0);
});
});
});
});
describe('failed', () => {
beforeEach(() => {
spyOn(service, 'commit').and.returnValue(
Promise.resolve({
jest.spyOn(service, 'commit').mockResolvedValue({
data: {
message: 'failed message',
},
}),
);
});
});
it('shows failed message', done => {
......@@ -543,20 +545,15 @@ describe('IDE commit module actions', () => {
};
it('commits TOGGLE_EMPTY_STATE mutation on empty repo', done => {
spyOn(service, 'commit').and.returnValue(
Promise.resolve({
data: COMMIT_RESPONSE,
}),
);
spyOn(store, 'commit').and.callThrough();
jest.spyOn(service, 'commit').mockResolvedValue({ data: COMMIT_RESPONSE });
jest.spyOn(store, 'commit');
store
.dispatch('commit/commitChanges')
.then(() => {
expect(store.commit.calls.allArgs()).toEqual(
jasmine.arrayContaining([
['TOGGLE_EMPTY_STATE', jasmine.any(Object), jasmine.any(Object)],
expect(store.commit.mock.calls).toEqual(
expect.arrayContaining([
['TOGGLE_EMPTY_STATE', expect.any(Object), expect.any(Object)],
]),
);
done();
......@@ -566,19 +563,15 @@ describe('IDE commit module actions', () => {
it('does not commmit TOGGLE_EMPTY_STATE mutation on existing project', done => {
COMMIT_RESPONSE.parent_ids.push('1234');
spyOn(service, 'commit').and.returnValue(
Promise.resolve({
data: COMMIT_RESPONSE,
}),
);
spyOn(store, 'commit').and.callThrough();
jest.spyOn(service, 'commit').mockResolvedValue({ data: COMMIT_RESPONSE });
jest.spyOn(store, 'commit');
store
.dispatch('commit/commitChanges')
.then(() => {
expect(store.commit.calls.allArgs()).not.toEqual(
jasmine.arrayContaining([
['TOGGLE_EMPTY_STATE', jasmine.any(Object), jasmine.any(Object)],
expect(store.commit.mock.calls).not.toEqual(
expect.arrayContaining([
['TOGGLE_EMPTY_STATE', expect.any(Object), expect.any(Object)],
]),
);
done();
......
export * from '../../frontend/ide/helpers';
export * from '../../frontend/ide/mock_data';
import Vue from 'vue';
import Mousetrap from 'mousetrap';
import { file } from 'spec/ide/helpers';
import { file } from 'jest/ide/helpers';
import timeoutPromise from 'spec/helpers/set_timeout_promise_helper';
import FindFileComponent from '~/vue_shared/components/file_finder/index.vue';
import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment