Commit 45003c2a authored by Paul Slaughter's avatar Paul Slaughter

Move some IDE specs to Jest

- Also adds a shared WebWorkerMock
- Moves nav_dropdown_spec to VTU
parent 32093146
/* eslint-disable class-methods-use-this */
export default class WebWorkerMock {
addEventListener() {}
removeEventListener() {}
terminate() {}
postMessage() {}
}
......@@ -26,7 +26,7 @@ describe('IDE activity bar', () => {
describe('updateActivityBarView', () => {
beforeEach(() => {
spyOn(vm, 'updateActivityBarView');
jest.spyOn(vm, 'updateActivityBarView').mockImplementation(() => {});
vm.$mount();
});
......
import Vue from 'vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/ide/stores';
import Bar from '~/ide/components/file_templates/bar.vue';
import { resetStore, file } from '../../helpers';
......@@ -35,7 +35,7 @@ describe('IDE file templates bar component', () => {
});
it('calls setSelectedTemplateType when clicking item', () => {
spyOn(vm, 'setSelectedTemplateType').and.stub();
jest.spyOn(vm, 'setSelectedTemplateType').mockImplementation();
vm.$el.querySelector('.dropdown-content button').click();
......@@ -66,7 +66,7 @@ describe('IDE file templates bar component', () => {
});
it('calls fetchTemplate on click', () => {
spyOn(vm, 'fetchTemplate').and.stub();
jest.spyOn(vm, 'fetchTemplate').mockImplementation();
vm.$el
.querySelectorAll('.dropdown-content')[1]
......@@ -90,7 +90,7 @@ describe('IDE file templates bar component', () => {
});
it('calls undoFileTemplate when clicking undo button', () => {
spyOn(vm, 'undoFileTemplate').and.stub();
jest.spyOn(vm, 'undoFileTemplate').mockImplementation();
vm.$el.querySelector('.btn-default').click();
......@@ -100,7 +100,7 @@ describe('IDE file templates bar component', () => {
it('calls setSelectedTemplateType if activeFile name matches a template', done => {
const fileName = '.gitlab-ci.yml';
spyOn(vm, 'setSelectedTemplateType');
jest.spyOn(vm, 'setSelectedTemplateType').mockImplementation(() => {});
vm.$store.state.openFiles[0].name = fileName;
vm.setInitialType();
......
import Vue from 'vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import store from '~/ide/stores';
import ideSidebar from '~/ide/components/ide_side_bar.vue';
import { leftSidebarViews } from '~/ide/constants';
......
import Vue from 'vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import store from '~/ide/stores';
import ide from '~/ide/components/ide.vue';
import { file, resetStore } from '../helpers';
......
......@@ -35,7 +35,7 @@ describe('IDE tree list', () => {
beforeEach(() => {
bootstrapWithTree();
spyOn(vm, 'updateViewer').and.callThrough();
jest.spyOn(vm, 'updateViewer');
vm.$mount();
});
......@@ -64,7 +64,7 @@ describe('IDE tree list', () => {
beforeEach(() => {
bootstrapWithTree(emptyBranchTree);
spyOn(vm, 'updateViewer').and.callThrough();
jest.spyOn(vm, 'updateViewer');
vm.$mount();
});
......
import Vue from 'vue';
import { trimText } from 'spec/helpers/text_helper';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { trimText } from 'helpers/text_helper';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import NavDropdownButton from '~/ide/components/nav_dropdown_button.vue';
import { createStore } from '~/ide/stores';
......
import $ from 'jquery';
import { mount } from '@vue/test-utils';
import { createStore } from '~/ide/stores';
import NavDropdown from '~/ide/components/nav_dropdown.vue';
import { PERMISSION_READ_MR } from '~/ide/constants';
const TEST_PROJECT_ID = 'lorem-ipsum';
describe('IDE NavDropdown', () => {
let store;
let wrapper;
beforeEach(() => {
store = createStore();
Object.assign(store.state, {
currentProjectId: TEST_PROJECT_ID,
currentBranchId: 'master',
projects: {
[TEST_PROJECT_ID]: {
userPermissions: {
[PERMISSION_READ_MR]: true,
},
branches: {
master: { id: 'master' },
},
},
},
});
jest.spyOn(store, 'dispatch').mockImplementation(() => {});
});
afterEach(() => {
wrapper.destroy();
});
const createComponent = () => {
wrapper = mount(NavDropdown, {
store,
});
};
const findIcon = name => wrapper.find(`.ic-${name}`);
const findMRIcon = () => findIcon('merge-request');
const findNavForm = () => wrapper.find('.ide-nav-form');
const showDropdown = () => {
$(wrapper.vm.$el).trigger('show.bs.dropdown');
};
const hideDropdown = () => {
$(wrapper.vm.$el).trigger('hide.bs.dropdown');
};
describe('default', () => {
beforeEach(() => {
createComponent();
});
it('renders nothing initially', () => {
expect(findNavForm().exists()).toBe(false);
});
it('renders nav form when show.bs.dropdown', done => {
showDropdown();
wrapper.vm
.$nextTick()
.then(() => {
expect(findNavForm().exists()).toBe(true);
})
.then(done)
.catch(done.fail);
});
it('destroys nav form when closed', done => {
showDropdown();
hideDropdown();
wrapper.vm
.$nextTick()
.then(() => {
expect(findNavForm().exists()).toBe(false);
})
.then(done)
.catch(done.fail);
});
it('renders merge request icon', () => {
expect(findMRIcon().exists()).toBe(true);
});
});
describe('when user cannot read merge requests', () => {
beforeEach(() => {
store.state.projects[TEST_PROJECT_ID].userPermissions = {};
createComponent();
});
it('does not render merge requests', () => {
expect(findMRIcon().exists()).toBe(false);
});
});
});
import Vue from 'vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import mountComponent from 'helpers/vue_mount_component_helper';
import Button from '~/ide/components/new_dropdown/button.vue';
describe('IDE new entry dropdown button component', () => {
......@@ -16,7 +16,7 @@ describe('IDE new entry dropdown button component', () => {
icon: 'doc-new',
});
spyOn(vm, '$emit');
jest.spyOn(vm, '$emit').mockImplementation(() => {});
});
afterEach(() => {
......
import Vue from 'vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import store from '~/ide/stores';
import newDropdown from '~/ide/components/new_dropdown/index.vue';
import { resetStore } from '../../helpers';
......@@ -23,7 +23,7 @@ describe('new dropdown component', () => {
tree: [],
};
spyOn(vm, 'openNewEntryModal');
jest.spyOn(vm, 'openNewEntryModal').mockImplementation(() => {});
vm.$mount();
});
......@@ -58,11 +58,11 @@ describe('new dropdown component', () => {
describe('isOpen', () => {
it('scrolls dropdown into view', done => {
spyOn(vm.$refs.dropdownMenu, 'scrollIntoView');
jest.spyOn(vm.$refs.dropdownMenu, 'scrollIntoView').mockImplementation(() => {});
vm.isOpen = true;
setTimeout(() => {
setImmediate(() => {
expect(vm.$refs.dropdownMenu.scrollIntoView).toHaveBeenCalledWith({
block: 'nearest',
});
......@@ -74,7 +74,7 @@ describe('new dropdown component', () => {
describe('delete entry', () => {
it('calls delete action', () => {
spyOn(vm, 'deleteEntry');
jest.spyOn(vm, 'deleteEntry').mockImplementation(() => {});
vm.$el.querySelectorAll('.dropdown-menu button')[4].click();
......
import Vue from 'vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import { createStore } from '~/ide/stores';
import modal from '~/ide/components/new_dropdown/modal.vue';
import createFlash from '~/flash';
jest.mock('~/flash');
describe('new file modal component', () => {
const Component = Vue.extend(modal);
......@@ -11,47 +14,45 @@ describe('new file modal component', () => {
vm.$destroy();
});
['tree', 'blob'].forEach(type => {
describe(type, () => {
beforeEach(() => {
const store = createStore();
store.state.entryModal = {
type,
describe.each(['tree', 'blob'])('%s', type => {
beforeEach(() => {
const store = createStore();
store.state.entryModal = {
type,
path: '',
entry: {
path: '',
entry: {
path: '',
},
};
},
};
vm = createComponentWithStore(Component, store).$mount();
vm = createComponentWithStore(Component, store).$mount();
vm.name = 'testing';
});
vm.name = 'testing';
});
it(`sets modal title as ${type}`, () => {
const title = type === 'tree' ? 'directory' : 'file';
it(`sets modal title as ${type}`, () => {
const title = type === 'tree' ? 'directory' : 'file';
expect(vm.$el.querySelector('.modal-title').textContent.trim()).toBe(`Create new ${title}`);
});
expect(vm.$el.querySelector('.modal-title').textContent.trim()).toBe(`Create new ${title}`);
});
it(`sets button label as ${type}`, () => {
const title = type === 'tree' ? 'directory' : 'file';
it(`sets button label as ${type}`, () => {
const title = type === 'tree' ? 'directory' : 'file';
expect(vm.$el.querySelector('.btn-success').textContent.trim()).toBe(`Create ${title}`);
});
expect(vm.$el.querySelector('.btn-success').textContent.trim()).toBe(`Create ${title}`);
});
it(`sets form label as ${type}`, () => {
expect(vm.$el.querySelector('.label-bold').textContent.trim()).toBe('Name');
});
it(`sets form label as ${type}`, () => {
expect(vm.$el.querySelector('.label-bold').textContent.trim()).toBe('Name');
});
it(`${type === 'tree' ? 'does not show' : 'shows'} file templates`, () => {
const templateFilesEl = vm.$el.querySelector('.file-templates');
if (type === 'tree') {
expect(templateFilesEl).toBeNull();
} else {
expect(templateFilesEl instanceof Element).toBeTruthy();
}
});
it(`${type === 'tree' ? 'does not show' : 'shows'} file templates`, () => {
const templateFilesEl = vm.$el.querySelector('.file-templates');
if (type === 'tree') {
expect(templateFilesEl).toBeNull();
} else {
expect(templateFilesEl instanceof Element).toBeTruthy();
}
});
});
......@@ -131,16 +132,15 @@ describe('new file modal component', () => {
};
vm = createComponentWithStore(Component, store).$mount();
const flashSpy = spyOnDependency(modal, 'flash');
expect(flashSpy).not.toHaveBeenCalled();
expect(createFlash).not.toHaveBeenCalled();
vm.submitForm();
expect(flashSpy).toHaveBeenCalledWith(
expect(createFlash).toHaveBeenCalledWith(
'The name "test-path/test" is already taken in this directory.',
'alert',
jasmine.anything(),
expect.anything(),
null,
false,
true,
......
......@@ -17,7 +17,7 @@ describe('RepoTab', () => {
}
beforeEach(() => {
spyOn(router, 'push');
jest.spyOn(router, 'push').mockImplementation(() => {});
});
afterEach(() => {
......@@ -47,7 +47,7 @@ describe('RepoTab', () => {
},
});
spyOn(vm, 'openPendingTab');
jest.spyOn(vm, 'openPendingTab').mockImplementation(() => {});
vm.$el.click();
......@@ -63,7 +63,7 @@ describe('RepoTab', () => {
tab: file(),
});
spyOn(vm, 'clickFile');
jest.spyOn(vm, 'clickFile').mockImplementation(() => {});
vm.$el.click();
......@@ -75,7 +75,7 @@ describe('RepoTab', () => {
tab: file(),
});
spyOn(vm, 'closeFile');
jest.spyOn(vm, 'closeFile').mockImplementation(() => {});
vm.$el.querySelector('.multi-file-tab-close').click();
......
import Vue from 'vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import mountComponent from 'helpers/vue_mount_component_helper';
import TokenedInput from '~/ide/components/shared/tokened_input.vue';
const TEST_PLACEHOLDER = 'Searching in test';
......@@ -36,7 +36,7 @@ describe('IDE shared/TokenedInput', () => {
value: TEST_VALUE,
});
spyOn(vm, '$emit');
jest.spyOn(vm, '$emit').mockImplementation(() => {});
});
afterEach(() => {
......@@ -72,7 +72,7 @@ describe('IDE shared/TokenedInput', () => {
});
it('when input triggers backspace event, it calls "onBackspace"', () => {
spyOn(vm, 'onBackspace');
jest.spyOn(vm, 'onBackspace').mockImplementation(() => {});
vm.$refs.input.dispatchEvent(createBackspaceEvent());
vm.$refs.input.dispatchEvent(createBackspaceEvent());
......
......@@ -28,7 +28,7 @@ describe('Multi-file editor library model manager', () => {
});
it('adds model into disposable', () => {
spyOn(instance.disposable, 'add').and.callThrough();
jest.spyOn(instance.disposable, 'add');
instance.addModel(file());
......@@ -36,7 +36,7 @@ describe('Multi-file editor library model manager', () => {
});
it('returns cached model', () => {
spyOn(instance.models, 'get').and.callThrough();
jest.spyOn(instance.models, 'get');
instance.addModel(file());
instance.addModel(file());
......@@ -46,13 +46,13 @@ describe('Multi-file editor library model manager', () => {
it('adds eventHub listener', () => {
const f = file();
spyOn(eventHub, '$on').and.callThrough();
jest.spyOn(eventHub, '$on');
instance.addModel(f);
expect(eventHub.$on).toHaveBeenCalledWith(
`editor.update.model.dispose.${f.key}`,
jasmine.anything(),
expect.anything(),
);
});
});
......@@ -95,13 +95,13 @@ describe('Multi-file editor library model manager', () => {
});
it('removes eventHub listener', () => {
spyOn(eventHub, '$off').and.callThrough();
jest.spyOn(eventHub, '$off');
instance.removeCachedModel(f);
expect(eventHub.$off).toHaveBeenCalledWith(
`editor.update.model.dispose.${f.key}`,
jasmine.anything(),
expect.anything(),
);
});
});
......@@ -116,7 +116,7 @@ describe('Multi-file editor library model manager', () => {
});
it('calls disposable dispose', () => {
spyOn(instance.disposable, 'dispose').and.callThrough();
jest.spyOn(instance.disposable, 'dispose');
instance.dispose();
......
......@@ -6,7 +6,7 @@ describe('Multi-file editor library model', () => {
let model;
beforeEach(() => {
spyOn(eventHub, '$on').and.callThrough();
jest.spyOn(eventHub, '$on');
const f = file('path');
f.mrChange = { diff: 'ABC' };
......@@ -44,7 +44,7 @@ describe('Multi-file editor library model', () => {
it('adds eventHub listener', () => {
expect(eventHub.$on).toHaveBeenCalledWith(
`editor.update.model.dispose.${model.file.key}`,
jasmine.anything(),
expect.anything(),
);
});
......@@ -82,13 +82,13 @@ describe('Multi-file editor library model', () => {
describe('onChange', () => {
it('calls callback on change', done => {
const spy = jasmine.createSpy();
const spy = jest.fn();
model.onChange(spy);
model.getModel().setValue('123');
setTimeout(() => {
expect(spy).toHaveBeenCalledWith(model, jasmine.anything());
setImmediate(() => {
expect(spy).toHaveBeenCalledWith(model, expect.anything());
done();
});
});
......@@ -96,7 +96,7 @@ describe('Multi-file editor library model', () => {
describe('dispose', () => {
it('calls disposable dispose', () => {
spyOn(model.disposable, 'dispose').and.callThrough();
jest.spyOn(model.disposable, 'dispose');
model.dispose();
......@@ -114,18 +114,18 @@ describe('Multi-file editor library model', () => {
});
it('removes eventHub listener', () => {
spyOn(eventHub, '$off').and.callThrough();
jest.spyOn(eventHub, '$off');
model.dispose();
expect(eventHub.$off).toHaveBeenCalledWith(
`editor.update.model.dispose.${model.file.key}`,
jasmine.anything(),
expect.anything(),
);
});
it('calls onDispose callback', () => {
const disposeSpy = jasmine.createSpy();
const disposeSpy = jest.fn();
model.onDispose(disposeSpy);
......
......@@ -60,7 +60,7 @@ describe('Multi-file editor library decorations controller', () => {
});
it('calls decorate method', () => {
spyOn(controller, 'decorate');
jest.spyOn(controller, 'decorate').mockImplementation(() => {});
controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
......@@ -70,7 +70,7 @@ describe('Multi-file editor library decorations controller', () => {
describe('decorate', () => {
it('sets decorations on editor instance', () => {
spyOn(controller.editor.instance, 'deltaDecorations');
jest.spyOn(controller.editor.instance, 'deltaDecorations').mockImplementation(() => {});
controller.decorate(model);
......@@ -78,7 +78,7 @@ describe('Multi-file editor library decorations controller', () => {
});
it('caches decorations', () => {
spyOn(controller.editor.instance, 'deltaDecorations').and.returnValue([]);
jest.spyOn(controller.editor.instance, 'deltaDecorations').mockReturnValue([]);
controller.decorate(model);
......@@ -86,7 +86,7 @@ describe('Multi-file editor library decorations controller', () => {
});
it('caches decorations by model URL', () => {
spyOn(controller.editor.instance, 'deltaDecorations').and.returnValue([]);
jest.spyOn(controller.editor.instance, 'deltaDecorations').mockReturnValue([]);
controller.decorate(model);
......
......@@ -75,7 +75,7 @@ describe('Multi-file editor library dirty diff controller', () => {
describe('attachModel', () => {
it('adds change event callback', () => {
spyOn(model, 'onChange');
jest.spyOn(model, 'onChange').mockImplementation(() => {});
controller.attachModel(model);
......@@ -83,7 +83,7 @@ describe('Multi-file editor library dirty diff controller', () => {
});
it('adds dispose event callback', () => {
spyOn(model, 'onDispose');
jest.spyOn(model, 'onDispose').mockImplementation(() => {});
controller.attachModel(model);
......@@ -91,7 +91,7 @@ describe('Multi-file editor library dirty diff controller', () => {
});
it('calls throttledComputeDiff on change', () => {
spyOn(controller, 'throttledComputeDiff');
jest.spyOn(controller, 'throttledComputeDiff').mockImplementation(() => {});
controller.attachModel(model);
......@@ -109,7 +109,7 @@ describe('Multi-file editor library dirty diff controller', () => {
describe('computeDiff', () => {
it('posts to worker', () => {
spyOn(controller.dirtyDiffWorker, 'postMessage');
jest.spyOn(controller.dirtyDiffWorker, 'postMessage').mockImplementation(() => {});
controller.computeDiff(model);
......@@ -123,7 +123,7 @@ describe('Multi-file editor library dirty diff controller', () => {
describe('reDecorate', () => {
it('calls computeDiff when no decorations are cached', () => {
spyOn(controller, 'computeDiff');
jest.spyOn(controller, 'computeDiff').mockImplementation(() => {});
controller.reDecorate(model);
......@@ -131,7 +131,7 @@ describe('Multi-file editor library dirty diff controller', () => {
});
it('calls decorate when decorations are cached', () => {
spyOn(controller.decorationsController, 'decorate');
jest.spyOn(controller.decorationsController, 'decorate').mockImplementation(() => {});
controller.decorationsController.decorations.set(model.url, 'test');
......@@ -143,19 +143,19 @@ describe('Multi-file editor library dirty diff controller', () => {
describe('decorate', () => {
it('adds decorations into decorations controller', () => {
spyOn(controller.decorationsController, 'addDecorations');
jest.spyOn(controller.decorationsController, 'addDecorations').mockImplementation(() => {});
controller.decorate({ data: { changes: [], path: model.path } });
expect(controller.decorationsController.addDecorations).toHaveBeenCalledWith(
model,
'dirtyDiff',
jasmine.anything(),
expect.anything(),
);
});
it('adds decorations into editor', () => {
const spy = spyOn(controller.decorationsController.editor.instance, 'deltaDecorations');
const spy = jest.spyOn(controller.decorationsController.editor.instance, 'deltaDecorations');
controller.decorate({
data: { changes: computeDiff('123', '1234'), path: model.path },
......@@ -178,7 +178,7 @@ describe('Multi-file editor library dirty diff controller', () => {
describe('dispose', () => {
it('calls disposable dispose', () => {
spyOn(controller.disposable, 'dispose').and.callThrough();
jest.spyOn(controller.disposable, 'dispose');
controller.dispose();
......@@ -186,7 +186,7 @@ describe('Multi-file editor library dirty diff controller', () => {
});
it('terminates worker', () => {
spyOn(controller.dirtyDiffWorker, 'terminate').and.callThrough();
jest.spyOn(controller.dirtyDiffWorker, 'terminate');
controller.dispose();
......@@ -194,13 +194,13 @@ describe('Multi-file editor library dirty diff controller', () => {
});
it('removes worker event listener', () => {
spyOn(controller.dirtyDiffWorker, 'removeEventListener').and.callThrough();
jest.spyOn(controller.dirtyDiffWorker, 'removeEventListener');
controller.dispose();
expect(controller.dirtyDiffWorker.removeEventListener).toHaveBeenCalledWith(
'message',
jasmine.anything(),
expect.anything(),
);
});
......
import { editor as monacoEditor } from 'monaco-editor';
import Editor from '~/ide/lib/editor';
import { defaultEditorOptions } from '~/ide/lib/editor_options';
import { file } from '../helpers';
describe('Multi-file editor library', () => {
......@@ -7,6 +8,14 @@ describe('Multi-file editor library', () => {
let el;
let holder;
const setNodeOffsetWidth = val => {
Object.defineProperty(instance.instance.getDomNode(), 'offsetWidth', {
get() {
return val;
},
});
};
beforeEach(() => {
el = document.createElement('div');
holder = document.createElement('div');
......@@ -18,7 +27,9 @@ describe('Multi-file editor library', () => {
});
afterEach(() => {
instance.modelManager.dispose();
instance.dispose();
Editor.editorInstance = null;
el.remove();
});
......@@ -33,7 +44,7 @@ describe('Multi-file editor library', () => {
describe('createInstance', () => {
it('creates editor instance', () => {
spyOn(monacoEditor, 'create').and.callThrough();
jest.spyOn(monacoEditor, 'create');
instance.createInstance(holder);
......@@ -55,33 +66,25 @@ describe('Multi-file editor library', () => {
describe('createDiffInstance', () => {
it('creates editor instance', () => {
spyOn(monacoEditor, 'createDiffEditor').and.callThrough();
jest.spyOn(monacoEditor, 'createDiffEditor');
instance.createDiffInstance(holder);
expect(monacoEditor.createDiffEditor).toHaveBeenCalledWith(holder, {
model: null,
contextmenu: true,
minimap: {
enabled: false,
},
readOnly: true,
scrollBeyondLastLine: false,
renderWhitespace: 'none',
...defaultEditorOptions,
quickSuggestions: false,
occurrencesHighlight: false,
wordWrap: 'on',
renderSideBySide: true,
renderSideBySide: false,
readOnly: true,
renderLineHighlight: 'all',
hideCursorInOverviewRuler: false,
theme: 'vs white',
});
});
});
describe('createModel', () => {
it('calls model manager addModel', () => {
spyOn(instance.modelManager, 'addModel');
jest.spyOn(instance.modelManager, 'addModel').mockImplementation(() => {});
instance.createModel('FILE');
......@@ -105,7 +108,7 @@ describe('Multi-file editor library', () => {
});
it('attaches the model to the current instance', () => {
spyOn(instance.instance, 'setModel');
jest.spyOn(instance.instance, 'setModel').mockImplementation(() => {});
instance.attachModel(model);
......@@ -113,8 +116,8 @@ describe('Multi-file editor library', () => {
});
it('sets original & modified when diff editor', () => {
spyOn(instance.instance, 'getEditorType').and.returnValue('vs.editor.IDiffEditor');
spyOn(instance.instance, 'setModel');
jest.spyOn(instance.instance, 'getEditorType').mockReturnValue('vs.editor.IDiffEditor');
jest.spyOn(instance.instance, 'setModel').mockImplementation(() => {});
instance.attachModel(model);
......@@ -125,7 +128,7 @@ describe('Multi-file editor library', () => {
});
it('attaches the model to the dirty diff controller', () => {
spyOn(instance.dirtyDiffController, 'attachModel');
jest.spyOn(instance.dirtyDiffController, 'attachModel').mockImplementation(() => {});
instance.attachModel(model);
......@@ -133,7 +136,7 @@ describe('Multi-file editor library', () => {
});
it('re-decorates with the dirty diff controller', () => {
spyOn(instance.dirtyDiffController, 'reDecorate');
jest.spyOn(instance.dirtyDiffController, 'reDecorate').mockImplementation(() => {});
instance.attachModel(model);
......@@ -155,7 +158,7 @@ describe('Multi-file editor library', () => {
});
it('sets original & modified', () => {
spyOn(instance.instance, 'setModel');
jest.spyOn(instance.instance, 'setModel').mockImplementation(() => {});
instance.attachMergeRequestModel(model);
......@@ -170,7 +173,7 @@ describe('Multi-file editor library', () => {
it('resets the editor model', () => {
instance.createInstance(document.createElement('div'));
spyOn(instance.instance, 'setModel');
jest.spyOn(instance.instance, 'setModel').mockImplementation(() => {});
instance.clearEditor();
......@@ -180,7 +183,7 @@ describe('Multi-file editor library', () => {
describe('dispose', () => {
it('calls disposble dispose method', () => {
spyOn(instance.disposable, 'dispose').and.callThrough();
jest.spyOn(instance.disposable, 'dispose');
instance.dispose();
......@@ -198,7 +201,7 @@ describe('Multi-file editor library', () => {
});
it('does not dispose modelManager', () => {
spyOn(instance.modelManager, 'dispose');
jest.spyOn(instance.modelManager, 'dispose').mockImplementation(() => {});
instance.dispose();
......@@ -206,7 +209,7 @@ describe('Multi-file editor library', () => {
});
it('does not dispose decorationsController', () => {
spyOn(instance.decorationsController, 'dispose');
jest.spyOn(instance.decorationsController, 'dispose').mockImplementation(() => {});
instance.dispose();
......@@ -219,7 +222,7 @@ describe('Multi-file editor library', () => {
it('does not update options', () => {
instance.createInstance(holder);
spyOn(instance.instance, 'updateOptions');
jest.spyOn(instance.instance, 'updateOptions').mockImplementation(() => {});
instance.updateDiffView();
......@@ -231,11 +234,11 @@ describe('Multi-file editor library', () => {
beforeEach(() => {
instance.createDiffInstance(holder);
spyOn(instance.instance, 'updateOptions').and.callThrough();
jest.spyOn(instance.instance, 'updateOptions');
});
it('sets renderSideBySide to false if el is less than 700 pixels', () => {
spyOnProperty(instance.instance.getDomNode(), 'offsetWidth').and.returnValue(600);
setNodeOffsetWidth(600);
expect(instance.instance.updateOptions).not.toHaveBeenCalledWith({
renderSideBySide: false,
......@@ -243,7 +246,7 @@ describe('Multi-file editor library', () => {
});
it('sets renderSideBySide to false if el is more than 700 pixels', () => {
spyOnProperty(instance.instance.getDomNode(), 'offsetWidth').and.returnValue(800);
setNodeOffsetWidth(800);
expect(instance.instance.updateOptions).not.toHaveBeenCalledWith({
renderSideBySide: true,
......@@ -269,7 +272,7 @@ describe('Multi-file editor library', () => {
it('sets quickSuggestions to false when language is markdown', () => {
instance.createInstance(holder);
spyOn(instance.instance, 'updateOptions').and.callThrough();
jest.spyOn(instance.instance, 'updateOptions');
const model = instance.createModel({
...file(),
......
/* eslint-disable class-methods-use-this */
export default class TreeWorkerMock {
addEventListener() {}
terminate() {}
postMessage() {}
}
export { default } from 'helpers/web_worker_mock';
export { default } from 'helpers/web_worker_mock';
import $ from 'jquery';
import Vue from 'vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import store from '~/ide/stores';
import NavDropdown from '~/ide/components/nav_dropdown.vue';
import { PERMISSION_READ_MR } from '~/ide/constants';
const TEST_PROJECT_ID = 'lorem-ipsum';
describe('IDE NavDropdown', () => {
const Component = Vue.extend(NavDropdown);
let vm;
let $dropdown;
beforeEach(() => {
store.state.currentProjectId = TEST_PROJECT_ID;
Vue.set(store.state.projects, TEST_PROJECT_ID, {
userPermissions: {
[PERMISSION_READ_MR]: true,
},
});
vm = mountComponentWithStore(Component, { store });
$dropdown = $(vm.$el);
// block dispatch from doing anything
spyOn(vm.$store, 'dispatch');
});
afterEach(() => {
vm.$destroy();
});
const findIcon = name => vm.$el.querySelector(`.ic-${name}`);
const findMRIcon = () => findIcon('merge-request');
it('renders nothing initially', () => {
expect(vm.$el).not.toContainElement('.ide-nav-form');
});
it('renders nav form when show.bs.dropdown', done => {
$dropdown.trigger('show.bs.dropdown');
vm.$nextTick()
.then(() => {
expect(vm.$el).toContainElement('.ide-nav-form');
})
.then(done)
.catch(done.fail);
});
it('destroys nav form when closed', done => {
$dropdown.trigger('show.bs.dropdown');
$dropdown.trigger('hide.bs.dropdown');
vm.$nextTick()
.then(() => {
expect(vm.$el).not.toContainElement('.ide-nav-form');
})
.then(done)
.catch(done.fail);
});
it('renders merge request icon', () => {
expect(findMRIcon()).not.toBeNull();
});
describe('when user cannot read merge requests', () => {
beforeEach(done => {
store.state.projects[TEST_PROJECT_ID].userPermissions = {};
vm.$nextTick()
.then(done)
.catch(done.fail);
});
it('does not render merge requests', () => {
expect(findMRIcon()).toBeNull();
});
});
});
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