Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-29 00:09:35 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-29 00:09:35 +0300
commitabe11a6a2c04112d0b7d6d4facfd0c8370f51831 (patch)
treeb0c9e9e019417e7b438bf24c6a4a28acfc0fd95b /spec/javascripts
parent95e18e32833de71b46d73ead66c8f13e261af3f4 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/javascripts')
-rw-r--r--spec/javascripts/ide/components/activity_bar_spec.js72
-rw-r--r--spec/javascripts/ide/components/file_templates/bar_spec.js117
-rw-r--r--spec/javascripts/ide/components/ide_side_bar_spec.js57
-rw-r--r--spec/javascripts/ide/components/ide_spec.js125
-rw-r--r--spec/javascripts/ide/components/ide_tree_list_spec.js77
-rw-r--r--spec/javascripts/ide/components/ide_tree_spec.js34
-rw-r--r--spec/javascripts/ide/components/jobs/detail/description_spec.js28
-rw-r--r--spec/javascripts/ide/components/jobs/item_spec.js39
-rw-r--r--spec/javascripts/ide/components/nav_dropdown_button_spec.js93
-rw-r--r--spec/javascripts/ide/components/nav_dropdown_spec.js80
-rw-r--r--spec/javascripts/ide/components/new_dropdown/button_spec.js65
-rw-r--r--spec/javascripts/ide/components/new_dropdown/index_spec.js84
-rw-r--r--spec/javascripts/ide/components/new_dropdown/modal_spec.js150
-rw-r--r--spec/javascripts/ide/components/repo_tab_spec.js185
-rw-r--r--spec/javascripts/ide/components/repo_tabs_spec.js35
-rw-r--r--spec/javascripts/ide/components/shared/tokened_input_spec.js133
-rw-r--r--spec/javascripts/ide/lib/common/model_manager_spec.js126
-rw-r--r--spec/javascripts/ide/lib/common/model_spec.js137
-rw-r--r--spec/javascripts/ide/lib/decorations/controller_spec.js143
-rw-r--r--spec/javascripts/ide/lib/diff/controller_spec.js215
-rw-r--r--spec/javascripts/ide/lib/editor_spec.js287
21 files changed, 0 insertions, 2282 deletions
diff --git a/spec/javascripts/ide/components/activity_bar_spec.js b/spec/javascripts/ide/components/activity_bar_spec.js
deleted file mode 100644
index 823ca29dab9..00000000000
--- a/spec/javascripts/ide/components/activity_bar_spec.js
+++ /dev/null
@@ -1,72 +0,0 @@
-import Vue from 'vue';
-import store from '~/ide/stores';
-import { leftSidebarViews } from '~/ide/constants';
-import ActivityBar from '~/ide/components/activity_bar.vue';
-import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
-import { resetStore } from '../helpers';
-
-describe('IDE activity bar', () => {
- const Component = Vue.extend(ActivityBar);
- let vm;
-
- beforeEach(() => {
- Vue.set(store.state.projects, 'abcproject', {
- web_url: 'testing',
- });
- Vue.set(store.state, 'currentProjectId', 'abcproject');
-
- vm = createComponentWithStore(Component, store);
- });
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
- });
-
- describe('updateActivityBarView', () => {
- beforeEach(() => {
- spyOn(vm, 'updateActivityBarView');
-
- vm.$mount();
- });
-
- it('calls updateActivityBarView with edit value on click', () => {
- vm.$el.querySelector('.js-ide-edit-mode').click();
-
- expect(vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.edit.name);
- });
-
- it('calls updateActivityBarView with commit value on click', () => {
- vm.$el.querySelector('.js-ide-commit-mode').click();
-
- expect(vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.commit.name);
- });
-
- it('calls updateActivityBarView with review value on click', () => {
- vm.$el.querySelector('.js-ide-review-mode').click();
-
- expect(vm.updateActivityBarView).toHaveBeenCalledWith(leftSidebarViews.review.name);
- });
- });
-
- describe('active item', () => {
- beforeEach(() => {
- vm.$mount();
- });
-
- it('sets edit item active', () => {
- expect(vm.$el.querySelector('.js-ide-edit-mode').classList).toContain('active');
- });
-
- it('sets commit item active', done => {
- vm.$store.state.currentActivityView = leftSidebarViews.commit.name;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.js-ide-commit-mode').classList).toContain('active');
-
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/ide/components/file_templates/bar_spec.js b/spec/javascripts/ide/components/file_templates/bar_spec.js
deleted file mode 100644
index 5399ada94ae..00000000000
--- a/spec/javascripts/ide/components/file_templates/bar_spec.js
+++ /dev/null
@@ -1,117 +0,0 @@
-import Vue from 'vue';
-import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import { createStore } from '~/ide/stores';
-import Bar from '~/ide/components/file_templates/bar.vue';
-import { resetStore, file } from '../../helpers';
-
-describe('IDE file templates bar component', () => {
- let Component;
- let vm;
-
- beforeAll(() => {
- Component = Vue.extend(Bar);
- });
-
- beforeEach(() => {
- const store = createStore();
-
- store.state.openFiles.push({
- ...file('file'),
- opened: true,
- active: true,
- });
-
- vm = mountComponentWithStore(Component, { store });
- });
-
- afterEach(() => {
- vm.$destroy();
- resetStore(vm.$store);
- });
-
- describe('template type dropdown', () => {
- it('renders dropdown component', () => {
- expect(vm.$el.querySelector('.dropdown').textContent).toContain('Choose a type');
- });
-
- it('calls setSelectedTemplateType when clicking item', () => {
- spyOn(vm, 'setSelectedTemplateType').and.stub();
-
- vm.$el.querySelector('.dropdown-content button').click();
-
- expect(vm.setSelectedTemplateType).toHaveBeenCalledWith({
- name: '.gitlab-ci.yml',
- key: 'gitlab_ci_ymls',
- });
- });
- });
-
- describe('template dropdown', () => {
- beforeEach(done => {
- vm.$store.state.fileTemplates.templates = [
- {
- name: 'test',
- },
- ];
- vm.$store.state.fileTemplates.selectedTemplateType = {
- name: '.gitlab-ci.yml',
- key: 'gitlab_ci_ymls',
- };
-
- vm.$nextTick(done);
- });
-
- it('renders dropdown component', () => {
- expect(vm.$el.querySelectorAll('.dropdown')[1].textContent).toContain('Choose a template');
- });
-
- it('calls fetchTemplate on click', () => {
- spyOn(vm, 'fetchTemplate').and.stub();
-
- vm.$el
- .querySelectorAll('.dropdown-content')[1]
- .querySelector('button')
- .click();
-
- expect(vm.fetchTemplate).toHaveBeenCalledWith({
- name: 'test',
- });
- });
- });
-
- it('shows undo button if updateSuccess is true', done => {
- vm.$store.state.fileTemplates.updateSuccess = true;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.btn-default').style.display).not.toBe('none');
-
- done();
- });
- });
-
- it('calls undoFileTemplate when clicking undo button', () => {
- spyOn(vm, 'undoFileTemplate').and.stub();
-
- vm.$el.querySelector('.btn-default').click();
-
- expect(vm.undoFileTemplate).toHaveBeenCalled();
- });
-
- it('calls setSelectedTemplateType if activeFile name matches a template', done => {
- const fileName = '.gitlab-ci.yml';
-
- spyOn(vm, 'setSelectedTemplateType');
- vm.$store.state.openFiles[0].name = fileName;
-
- vm.setInitialType();
-
- vm.$nextTick(() => {
- expect(vm.setSelectedTemplateType).toHaveBeenCalledWith({
- name: fileName,
- key: 'gitlab_ci_ymls',
- });
-
- done();
- });
- });
-});
diff --git a/spec/javascripts/ide/components/ide_side_bar_spec.js b/spec/javascripts/ide/components/ide_side_bar_spec.js
deleted file mode 100644
index 28f127a61c0..00000000000
--- a/spec/javascripts/ide/components/ide_side_bar_spec.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import Vue from 'vue';
-import { createComponentWithStore } from 'spec/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 { resetStore } from '../helpers';
-import { projectData } from '../mock_data';
-
-describe('IdeSidebar', () => {
- let vm;
-
- beforeEach(() => {
- const Component = Vue.extend(ideSidebar);
-
- store.state.currentProjectId = 'abcproject';
- store.state.projects.abcproject = projectData;
-
- vm = createComponentWithStore(Component, store).$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
- });
-
- it('renders a sidebar', () => {
- expect(vm.$el.querySelector('.multi-file-commit-panel-inner')).not.toBeNull();
- });
-
- it('renders loading icon component', done => {
- vm.$store.state.loading = true;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.multi-file-loading-container')).not.toBeNull();
- expect(vm.$el.querySelectorAll('.multi-file-loading-container').length).toBe(3);
-
- done();
- });
- });
-
- describe('activityBarComponent', () => {
- it('renders tree component', () => {
- expect(vm.$el.querySelector('.ide-file-list')).not.toBeNull();
- });
-
- it('renders commit component', done => {
- vm.$store.state.currentActivityView = leftSidebarViews.commit.name;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.multi-file-commit-panel-section')).not.toBeNull();
-
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/ide/components/ide_spec.js b/spec/javascripts/ide/components/ide_spec.js
deleted file mode 100644
index 4241b994cba..00000000000
--- a/spec/javascripts/ide/components/ide_spec.js
+++ /dev/null
@@ -1,125 +0,0 @@
-import Vue from 'vue';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import store from '~/ide/stores';
-import ide from '~/ide/components/ide.vue';
-import { file, resetStore } from '../helpers';
-import { projectData } from '../mock_data';
-
-function bootstrap(projData) {
- const Component = Vue.extend(ide);
-
- store.state.currentProjectId = 'abcproject';
- store.state.currentBranchId = 'master';
- store.state.projects.abcproject = Object.assign({}, projData);
- Vue.set(store.state.trees, 'abcproject/master', {
- tree: [],
- loading: false,
- });
-
- return createComponentWithStore(Component, store, {
- emptyStateSvgPath: 'svg',
- noChangesStateSvgPath: 'svg',
- committedStateSvgPath: 'svg',
- });
-}
-
-describe('ide component, empty repo', () => {
- let vm;
-
- beforeEach(() => {
- const emptyProjData = Object.assign({}, projectData, { empty_repo: true, branches: {} });
- vm = bootstrap(emptyProjData);
- vm.$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
- });
-
- it('renders "New file" button in empty repo', done => {
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.ide-empty-state button[title="New file"]')).not.toBeNull();
- done();
- });
- });
-});
-
-describe('ide component, non-empty repo', () => {
- let vm;
-
- beforeEach(() => {
- vm = bootstrap(projectData);
- vm.$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
- });
-
- it('shows error message when set', done => {
- expect(vm.$el.querySelector('.gl-alert')).toBe(null);
-
- vm.$store.state.errorMessage = {
- text: 'error',
- };
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.gl-alert')).not.toBe(null);
-
- done();
- });
- });
-
- describe('onBeforeUnload', () => {
- it('returns undefined when no staged files or changed files', () => {
- expect(vm.onBeforeUnload()).toBe(undefined);
- });
-
- it('returns warning text when their are changed files', () => {
- vm.$store.state.changedFiles.push(file());
-
- expect(vm.onBeforeUnload()).toBe('Are you sure you want to lose unsaved changes?');
- });
-
- it('returns warning text when their are staged files', () => {
- vm.$store.state.stagedFiles.push(file());
-
- expect(vm.onBeforeUnload()).toBe('Are you sure you want to lose unsaved changes?');
- });
-
- it('updates event object', () => {
- const event = {};
- vm.$store.state.stagedFiles.push(file());
-
- vm.onBeforeUnload(event);
-
- expect(event.returnValue).toBe('Are you sure you want to lose unsaved changes?');
- });
- });
-
- describe('non-existent branch', () => {
- it('does not render "New file" button for non-existent branch when repo is not empty', done => {
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.ide-empty-state button[title="New file"]')).toBeNull();
- done();
- });
- });
- });
-
- describe('branch with files', () => {
- beforeEach(() => {
- store.state.trees['abcproject/master'].tree = [file()];
- });
-
- it('does not render "New file" button', done => {
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.ide-empty-state button[title="New file"]')).toBeNull();
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/ide/components/ide_tree_list_spec.js b/spec/javascripts/ide/components/ide_tree_list_spec.js
deleted file mode 100644
index f63007c7dd2..00000000000
--- a/spec/javascripts/ide/components/ide_tree_list_spec.js
+++ /dev/null
@@ -1,77 +0,0 @@
-import Vue from 'vue';
-import IdeTreeList from '~/ide/components/ide_tree_list.vue';
-import store from '~/ide/stores';
-import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
-import { resetStore, file } from '../helpers';
-import { projectData } from '../mock_data';
-
-describe('IDE tree list', () => {
- const Component = Vue.extend(IdeTreeList);
- const normalBranchTree = [file('fileName')];
- const emptyBranchTree = [];
- let vm;
-
- const bootstrapWithTree = (tree = normalBranchTree) => {
- store.state.currentProjectId = 'abcproject';
- store.state.currentBranchId = 'master';
- store.state.projects.abcproject = Object.assign({}, projectData);
- Vue.set(store.state.trees, 'abcproject/master', {
- tree,
- loading: false,
- });
-
- vm = createComponentWithStore(Component, store, {
- viewerType: 'edit',
- });
- };
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
- });
-
- describe('normal branch', () => {
- beforeEach(() => {
- bootstrapWithTree();
-
- spyOn(vm, 'updateViewer').and.callThrough();
-
- vm.$mount();
- });
-
- it('updates viewer on mount', () => {
- expect(vm.updateViewer).toHaveBeenCalledWith('edit');
- });
-
- it('renders loading indicator', done => {
- store.state.trees['abcproject/master'].loading = true;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.multi-file-loading-container')).not.toBeNull();
- expect(vm.$el.querySelectorAll('.multi-file-loading-container').length).toBe(3);
-
- done();
- });
- });
-
- it('renders list of files', () => {
- expect(vm.$el.textContent).toContain('fileName');
- });
- });
-
- describe('empty-branch state', () => {
- beforeEach(() => {
- bootstrapWithTree(emptyBranchTree);
-
- spyOn(vm, 'updateViewer').and.callThrough();
-
- vm.$mount();
- });
-
- it('does not load files if the branch is empty', () => {
- expect(vm.$el.textContent).not.toContain('fileName');
- expect(vm.$el.textContent).toContain('No files');
- });
- });
-});
diff --git a/spec/javascripts/ide/components/ide_tree_spec.js b/spec/javascripts/ide/components/ide_tree_spec.js
deleted file mode 100644
index 97a0a2432f1..00000000000
--- a/spec/javascripts/ide/components/ide_tree_spec.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import Vue from 'vue';
-import IdeTree from '~/ide/components/ide_tree.vue';
-import store from '~/ide/stores';
-import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
-import { resetStore, file } from '../helpers';
-import { projectData } from '../mock_data';
-
-describe('IdeRepoTree', () => {
- let vm;
-
- beforeEach(() => {
- const IdeRepoTree = Vue.extend(IdeTree);
-
- store.state.currentProjectId = 'abcproject';
- store.state.currentBranchId = 'master';
- store.state.projects.abcproject = Object.assign({}, projectData);
- Vue.set(store.state.trees, 'abcproject/master', {
- tree: [file('fileName')],
- loading: false,
- });
-
- vm = createComponentWithStore(IdeRepoTree, store).$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
- });
-
- it('renders list of files', () => {
- expect(vm.$el.textContent).toContain('fileName');
- });
-});
diff --git a/spec/javascripts/ide/components/jobs/detail/description_spec.js b/spec/javascripts/ide/components/jobs/detail/description_spec.js
deleted file mode 100644
index babae00d2f7..00000000000
--- a/spec/javascripts/ide/components/jobs/detail/description_spec.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import Vue from 'vue';
-import Description from '~/ide/components/jobs/detail/description.vue';
-import mountComponent from '../../../../helpers/vue_mount_component_helper';
-import { jobs } from '../../../mock_data';
-
-describe('IDE job description', () => {
- const Component = Vue.extend(Description);
- let vm;
-
- beforeEach(() => {
- vm = mountComponent(Component, {
- job: jobs[0],
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders job details', () => {
- expect(vm.$el.textContent).toContain('#1');
- expect(vm.$el.textContent).toContain('test');
- });
-
- it('renders CI icon', () => {
- expect(vm.$el.querySelector('.ci-status-icon .ic-status_success_borderless')).not.toBe(null);
- });
-});
diff --git a/spec/javascripts/ide/components/jobs/item_spec.js b/spec/javascripts/ide/components/jobs/item_spec.js
deleted file mode 100644
index 2f97d39e98e..00000000000
--- a/spec/javascripts/ide/components/jobs/item_spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import Vue from 'vue';
-import JobItem from '~/ide/components/jobs/item.vue';
-import mountComponent from '../../../helpers/vue_mount_component_helper';
-import { jobs } from '../../mock_data';
-
-describe('IDE jobs item', () => {
- const Component = Vue.extend(JobItem);
- const job = jobs[0];
- let vm;
-
- beforeEach(() => {
- vm = mountComponent(Component, {
- job,
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders job details', () => {
- expect(vm.$el.textContent).toContain(job.name);
- expect(vm.$el.textContent).toContain(`#${job.id}`);
- });
-
- it('renders CI icon', () => {
- expect(vm.$el.querySelector('.ic-status_success_borderless')).not.toBe(null);
- });
-
- it('does not render view logs button if not started', done => {
- vm.job.started = false;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.btn')).toBe(null);
-
- done();
- });
- });
-});
diff --git a/spec/javascripts/ide/components/nav_dropdown_button_spec.js b/spec/javascripts/ide/components/nav_dropdown_button_spec.js
deleted file mode 100644
index bbaf97164ea..00000000000
--- a/spec/javascripts/ide/components/nav_dropdown_button_spec.js
+++ /dev/null
@@ -1,93 +0,0 @@
-import Vue from 'vue';
-import { trimText } from 'spec/helpers/text_helper';
-import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import NavDropdownButton from '~/ide/components/nav_dropdown_button.vue';
-import { createStore } from '~/ide/stores';
-
-describe('NavDropdown', () => {
- const TEST_BRANCH_ID = 'lorem-ipsum-dolar';
- const TEST_MR_ID = '12345';
- let store;
- let vm;
-
- beforeEach(() => {
- store = createStore();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- const createComponent = (props = {}) => {
- vm = mountComponentWithStore(Vue.extend(NavDropdownButton), { props, store });
- vm.$mount();
- };
-
- const findIcon = name => vm.$el.querySelector(`.ic-${name}`);
- const findMRIcon = () => findIcon('merge-request');
- const findBranchIcon = () => findIcon('branch');
-
- describe('normal', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('renders empty placeholders, if state is falsey', () => {
- expect(trimText(vm.$el.textContent)).toEqual('- -');
- });
-
- it('renders branch name, if state has currentBranchId', done => {
- vm.$store.state.currentBranchId = TEST_BRANCH_ID;
-
- vm.$nextTick()
- .then(() => {
- expect(trimText(vm.$el.textContent)).toEqual(`${TEST_BRANCH_ID} -`);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('renders mr id, if state has currentMergeRequestId', done => {
- vm.$store.state.currentMergeRequestId = TEST_MR_ID;
-
- vm.$nextTick()
- .then(() => {
- expect(trimText(vm.$el.textContent)).toEqual(`- !${TEST_MR_ID}`);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('renders branch and mr, if state has both', done => {
- vm.$store.state.currentBranchId = TEST_BRANCH_ID;
- vm.$store.state.currentMergeRequestId = TEST_MR_ID;
-
- vm.$nextTick()
- .then(() => {
- expect(trimText(vm.$el.textContent)).toEqual(`${TEST_BRANCH_ID} !${TEST_MR_ID}`);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('shows icons', () => {
- expect(findBranchIcon()).toBeTruthy();
- expect(findMRIcon()).toBeTruthy();
- });
- });
-
- describe('with showMergeRequests false', () => {
- beforeEach(() => {
- createComponent({ showMergeRequests: false });
- });
-
- it('shows single empty placeholder, if state is falsey', () => {
- expect(trimText(vm.$el.textContent)).toEqual('-');
- });
-
- it('shows only branch icon', () => {
- expect(findBranchIcon()).toBeTruthy();
- expect(findMRIcon()).toBe(null);
- });
- });
-});
diff --git a/spec/javascripts/ide/components/nav_dropdown_spec.js b/spec/javascripts/ide/components/nav_dropdown_spec.js
deleted file mode 100644
index dfb4d03540f..00000000000
--- a/spec/javascripts/ide/components/nav_dropdown_spec.js
+++ /dev/null
@@ -1,80 +0,0 @@
-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();
- });
- });
-});
diff --git a/spec/javascripts/ide/components/new_dropdown/button_spec.js b/spec/javascripts/ide/components/new_dropdown/button_spec.js
deleted file mode 100644
index 6a326b5bd92..00000000000
--- a/spec/javascripts/ide/components/new_dropdown/button_spec.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import Button from '~/ide/components/new_dropdown/button.vue';
-
-describe('IDE new entry dropdown button component', () => {
- let Component;
- let vm;
-
- beforeAll(() => {
- Component = Vue.extend(Button);
- });
-
- beforeEach(() => {
- vm = mountComponent(Component, {
- label: 'Testing',
- icon: 'doc-new',
- });
-
- spyOn(vm, '$emit');
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders button with label', () => {
- expect(vm.$el.textContent).toContain('Testing');
- });
-
- it('renders icon', () => {
- expect(vm.$el.querySelector('.ic-doc-new')).not.toBe(null);
- });
-
- it('emits click event', () => {
- vm.$el.click();
-
- expect(vm.$emit).toHaveBeenCalledWith('click');
- });
-
- it('hides label if showLabel is false', done => {
- vm.showLabel = false;
-
- vm.$nextTick(() => {
- expect(vm.$el.textContent).not.toContain('Testing');
-
- done();
- });
- });
-
- describe('tooltipTitle', () => {
- it('returns empty string when showLabel is true', () => {
- expect(vm.tooltipTitle).toBe('');
- });
-
- it('returns label', done => {
- vm.showLabel = false;
-
- vm.$nextTick(() => {
- expect(vm.tooltipTitle).toBe('Testing');
-
- done();
- });
- });
- });
-});
diff --git a/spec/javascripts/ide/components/new_dropdown/index_spec.js b/spec/javascripts/ide/components/new_dropdown/index_spec.js
deleted file mode 100644
index 03afe997fed..00000000000
--- a/spec/javascripts/ide/components/new_dropdown/index_spec.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import Vue from 'vue';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import store from '~/ide/stores';
-import newDropdown from '~/ide/components/new_dropdown/index.vue';
-import { resetStore } from '../../helpers';
-
-describe('new dropdown component', () => {
- let vm;
-
- beforeEach(() => {
- const component = Vue.extend(newDropdown);
-
- vm = createComponentWithStore(component, store, {
- branch: 'master',
- path: '',
- mouseOver: false,
- type: 'tree',
- });
-
- vm.$store.state.currentProjectId = 'abcproject';
- vm.$store.state.path = '';
- vm.$store.state.trees['abcproject/mybranch'] = {
- tree: [],
- };
-
- spyOn(vm, 'openNewEntryModal');
-
- vm.$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
- });
-
- it('renders new file, upload and new directory links', () => {
- const buttons = vm.$el.querySelectorAll('.dropdown-menu button');
-
- expect(buttons[0].textContent.trim()).toBe('New file');
- expect(buttons[1].textContent.trim()).toBe('Upload file');
- expect(buttons[2].textContent.trim()).toBe('New directory');
- });
-
- describe('createNewItem', () => {
- it('sets modalType to blob when new file is clicked', () => {
- vm.$el.querySelectorAll('.dropdown-menu button')[0].click();
-
- expect(vm.openNewEntryModal).toHaveBeenCalledWith({ type: 'blob', path: '' });
- });
-
- it('sets modalType to tree when new directory is clicked', () => {
- vm.$el.querySelectorAll('.dropdown-menu button')[2].click();
-
- expect(vm.openNewEntryModal).toHaveBeenCalledWith({ type: 'tree', path: '' });
- });
- });
-
- describe('isOpen', () => {
- it('scrolls dropdown into view', done => {
- spyOn(vm.$refs.dropdownMenu, 'scrollIntoView');
-
- vm.isOpen = true;
-
- setTimeout(() => {
- expect(vm.$refs.dropdownMenu.scrollIntoView).toHaveBeenCalledWith({
- block: 'nearest',
- });
-
- done();
- });
- });
- });
-
- describe('delete entry', () => {
- it('calls delete action', () => {
- spyOn(vm, 'deleteEntry');
-
- vm.$el.querySelectorAll('.dropdown-menu button')[4].click();
-
- expect(vm.deleteEntry).toHaveBeenCalledWith('');
- });
- });
-});
diff --git a/spec/javascripts/ide/components/new_dropdown/modal_spec.js b/spec/javascripts/ide/components/new_dropdown/modal_spec.js
deleted file mode 100644
index 0ea767e087d..00000000000
--- a/spec/javascripts/ide/components/new_dropdown/modal_spec.js
+++ /dev/null
@@ -1,150 +0,0 @@
-import Vue from 'vue';
-import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
-import { createStore } from '~/ide/stores';
-import modal from '~/ide/components/new_dropdown/modal.vue';
-
-describe('new file modal component', () => {
- const Component = Vue.extend(modal);
- let vm;
-
- afterEach(() => {
- vm.$destroy();
- });
-
- ['tree', 'blob'].forEach(type => {
- describe(type, () => {
- beforeEach(() => {
- const store = createStore();
- store.state.entryModal = {
- type,
- path: '',
- entry: {
- path: '',
- },
- };
-
- vm = createComponentWithStore(Component, store).$mount();
-
- vm.name = 'testing';
- });
-
- it(`sets modal title as ${type}`, () => {
- const title = type === 'tree' ? 'directory' : 'file';
-
- expect(vm.$el.querySelector('.modal-title').textContent.trim()).toBe(`Create new ${title}`);
- });
-
- it(`sets button label as ${type}`, () => {
- const title = type === 'tree' ? 'directory' : 'file';
-
- 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(`${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();
- }
- });
- });
- });
-
- describe('rename entry', () => {
- beforeEach(() => {
- const store = createStore();
- store.state.entryModal = {
- type: 'rename',
- path: '',
- entry: {
- name: 'test',
- type: 'blob',
- path: 'test-path',
- },
- };
-
- vm = createComponentWithStore(Component, store).$mount();
- });
-
- ['tree', 'blob'].forEach(type => {
- it(`renders title and button for renaming ${type}`, done => {
- const text = type === 'tree' ? 'folder' : 'file';
-
- vm.$store.state.entryModal.entry.type = type;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.modal-title').textContent.trim()).toBe(`Rename ${text}`);
- expect(vm.$el.querySelector('.btn-success').textContent.trim()).toBe(`Rename ${text}`);
-
- done();
- });
- });
- });
-
- describe('entryName', () => {
- it('returns entries name', () => {
- expect(vm.entryName).toBe('test-path');
- });
-
- it('updated name', () => {
- vm.name = 'index.js';
-
- expect(vm.entryName).toBe('index.js');
- });
-
- it('removes leading/trailing spaces when found in the new name', () => {
- vm.entryName = ' index.js ';
-
- expect(vm.entryName).toBe('index.js');
- });
-
- it('does not remove internal spaces in the file name', () => {
- vm.entryName = ' In Praise of Idleness.txt ';
-
- expect(vm.entryName).toBe('In Praise of Idleness.txt');
- });
- });
- });
-
- describe('submitForm', () => {
- it('throws an error when target entry exists', () => {
- const store = createStore();
- store.state.entryModal = {
- type: 'rename',
- path: 'test-path/test',
- entry: {
- name: 'test',
- type: 'blob',
- path: 'test-path/test',
- },
- };
- store.state.entries = {
- 'test-path/test': {
- name: 'test',
- deleted: false,
- },
- };
-
- vm = createComponentWithStore(Component, store).$mount();
- const flashSpy = spyOnDependency(modal, 'flash');
-
- expect(flashSpy).not.toHaveBeenCalled();
-
- vm.submitForm();
-
- expect(flashSpy).toHaveBeenCalledWith(
- 'The name "test-path/test" is already taken in this directory.',
- 'alert',
- jasmine.anything(),
- null,
- false,
- true,
- );
- });
- });
-});
diff --git a/spec/javascripts/ide/components/repo_tab_spec.js b/spec/javascripts/ide/components/repo_tab_spec.js
deleted file mode 100644
index 3b52f279bf2..00000000000
--- a/spec/javascripts/ide/components/repo_tab_spec.js
+++ /dev/null
@@ -1,185 +0,0 @@
-import Vue from 'vue';
-import store from '~/ide/stores';
-import repoTab from '~/ide/components/repo_tab.vue';
-import router from '~/ide/ide_router';
-import { file, resetStore } from '../helpers';
-
-describe('RepoTab', () => {
- let vm;
-
- function createComponent(propsData) {
- const RepoTab = Vue.extend(repoTab);
-
- return new RepoTab({
- store,
- propsData,
- }).$mount();
- }
-
- beforeEach(() => {
- spyOn(router, 'push');
- });
-
- afterEach(() => {
- vm.$destroy();
-
- resetStore(vm.$store);
- });
-
- it('renders a close link and a name link', () => {
- vm = createComponent({
- tab: file(),
- });
- vm.$store.state.openFiles.push(vm.tab);
- const close = vm.$el.querySelector('.multi-file-tab-close');
- const name = vm.$el.querySelector(`[title="${vm.tab.url}"]`);
-
- expect(close.innerHTML).toContain('#close');
- expect(name.textContent.trim()).toEqual(vm.tab.name);
- });
-
- it('does not call openPendingTab when tab is active', done => {
- vm = createComponent({
- tab: {
- ...file(),
- pending: true,
- active: true,
- },
- });
-
- spyOn(vm, 'openPendingTab');
-
- vm.$el.click();
-
- vm.$nextTick(() => {
- expect(vm.openPendingTab).not.toHaveBeenCalled();
-
- done();
- });
- });
-
- it('fires clickFile when the link is clicked', () => {
- vm = createComponent({
- tab: file(),
- });
-
- spyOn(vm, 'clickFile');
-
- vm.$el.click();
-
- expect(vm.clickFile).toHaveBeenCalledWith(vm.tab);
- });
-
- it('calls closeFile when clicking close button', () => {
- vm = createComponent({
- tab: file(),
- });
-
- spyOn(vm, 'closeFile');
-
- vm.$el.querySelector('.multi-file-tab-close').click();
-
- expect(vm.closeFile).toHaveBeenCalledWith(vm.tab);
- });
-
- it('changes icon on hover', done => {
- const tab = file();
- tab.changed = true;
- vm = createComponent({
- tab,
- });
-
- vm.$el.dispatchEvent(new Event('mouseover'));
-
- Vue.nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.file-modified')).toBeNull();
-
- vm.$el.dispatchEvent(new Event('mouseout'));
- })
- .then(Vue.nextTick)
- .then(() => {
- expect(vm.$el.querySelector('.file-modified')).not.toBeNull();
-
- done();
- })
- .catch(done.fail);
- });
-
- describe('locked file', () => {
- let f;
-
- beforeEach(() => {
- f = file('locked file');
- f.file_lock = {
- user: {
- name: 'testuser',
- updated_at: new Date(),
- },
- };
-
- vm = createComponent({
- tab: f,
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders lock icon', () => {
- expect(vm.$el.querySelector('.file-status-icon')).not.toBeNull();
- });
-
- it('renders a tooltip', () => {
- expect(vm.$el.querySelector('span:nth-child(2)').dataset.originalTitle).toContain(
- 'Locked by testuser',
- );
- });
- });
-
- describe('methods', () => {
- describe('closeTab', () => {
- it('closes tab if file has changed', done => {
- const tab = file();
- tab.changed = true;
- tab.opened = true;
- vm = createComponent({
- tab,
- });
- vm.$store.state.openFiles.push(tab);
- vm.$store.state.changedFiles.push(tab);
- vm.$store.state.entries[tab.path] = tab;
- vm.$store.dispatch('setFileActive', tab.path);
-
- vm.$el.querySelector('.multi-file-tab-close').click();
-
- vm.$nextTick(() => {
- expect(tab.opened).toBeFalsy();
- expect(vm.$store.state.changedFiles.length).toBe(1);
-
- done();
- });
- });
-
- it('closes tab when clicking close btn', done => {
- const tab = file('lose');
- tab.opened = true;
- vm = createComponent({
- tab,
- });
- vm.$store.state.openFiles.push(tab);
- vm.$store.state.entries[tab.path] = tab;
- vm.$store.dispatch('setFileActive', tab.path);
-
- vm.$el.querySelector('.multi-file-tab-close').click();
-
- vm.$nextTick(() => {
- expect(tab.opened).toBeFalsy();
-
- done();
- });
- });
- });
- });
-});
diff --git a/spec/javascripts/ide/components/repo_tabs_spec.js b/spec/javascripts/ide/components/repo_tabs_spec.js
deleted file mode 100644
index 583f71e6121..00000000000
--- a/spec/javascripts/ide/components/repo_tabs_spec.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import Vue from 'vue';
-import repoTabs from '~/ide/components/repo_tabs.vue';
-import createComponent from '../../helpers/vue_mount_component_helper';
-import { file } from '../helpers';
-
-describe('RepoTabs', () => {
- const openedFiles = [file('open1'), file('open2')];
- const RepoTabs = Vue.extend(repoTabs);
- let vm;
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders a list of tabs', done => {
- vm = createComponent(RepoTabs, {
- files: openedFiles,
- viewer: 'editor',
- hasChanges: false,
- activeFile: file('activeFile'),
- hasMergeRequest: false,
- });
- openedFiles[0].active = true;
-
- vm.$nextTick(() => {
- const tabs = [...vm.$el.querySelectorAll('.multi-file-tab')];
-
- expect(tabs.length).toEqual(2);
- expect(tabs[0].parentNode.classList.contains('active')).toEqual(true);
- expect(tabs[1].parentNode.classList.contains('active')).toEqual(false);
-
- done();
- });
- });
-});
diff --git a/spec/javascripts/ide/components/shared/tokened_input_spec.js b/spec/javascripts/ide/components/shared/tokened_input_spec.js
deleted file mode 100644
index 885fd976655..00000000000
--- a/spec/javascripts/ide/components/shared/tokened_input_spec.js
+++ /dev/null
@@ -1,133 +0,0 @@
-import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import TokenedInput from '~/ide/components/shared/tokened_input.vue';
-
-const TEST_PLACEHOLDER = 'Searching in test';
-const TEST_TOKENS = [
- { label: 'lorem', id: 1 },
- { label: 'ipsum', id: 2 },
- { label: 'dolar', id: 3 },
-];
-const TEST_VALUE = 'lorem';
-
-function getTokenElements(vm) {
- return Array.from(vm.$el.querySelectorAll('.filtered-search-token button'));
-}
-
-function createBackspaceEvent() {
- const e = new Event('keyup');
- e.keyCode = 8;
- e.which = e.keyCode;
- e.altKey = false;
- e.ctrlKey = true;
- e.shiftKey = false;
- e.metaKey = false;
- return e;
-}
-
-describe('IDE shared/TokenedInput', () => {
- const Component = Vue.extend(TokenedInput);
- let vm;
-
- beforeEach(() => {
- vm = mountComponent(Component, {
- tokens: TEST_TOKENS,
- placeholder: TEST_PLACEHOLDER,
- value: TEST_VALUE,
- });
-
- spyOn(vm, '$emit');
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('renders tokens', () => {
- const renderedTokens = getTokenElements(vm).map(x => x.textContent.trim());
-
- expect(renderedTokens).toEqual(TEST_TOKENS.map(x => x.label));
- });
-
- it('renders input', () => {
- expect(vm.$refs.input).toBeTruthy();
- expect(vm.$refs.input).toHaveValue(TEST_VALUE);
- });
-
- it('renders placeholder, when tokens are empty', done => {
- vm.tokens = [];
-
- vm.$nextTick()
- .then(() => {
- expect(vm.$refs.input).toHaveAttr('placeholder', TEST_PLACEHOLDER);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('triggers "removeToken" on token click', () => {
- getTokenElements(vm)[0].click();
-
- expect(vm.$emit).toHaveBeenCalledWith('removeToken', TEST_TOKENS[0]);
- });
-
- it('when input triggers backspace event, it calls "onBackspace"', () => {
- spyOn(vm, 'onBackspace');
-
- vm.$refs.input.dispatchEvent(createBackspaceEvent());
- vm.$refs.input.dispatchEvent(createBackspaceEvent());
-
- expect(vm.onBackspace).toHaveBeenCalledTimes(2);
- });
-
- it('triggers "removeToken" on backspaces when value is empty', () => {
- vm.value = '';
-
- vm.onBackspace();
-
- expect(vm.$emit).not.toHaveBeenCalled();
- expect(vm.backspaceCount).toEqual(1);
-
- vm.onBackspace();
-
- expect(vm.$emit).toHaveBeenCalledWith('removeToken', TEST_TOKENS[TEST_TOKENS.length - 1]);
- expect(vm.backspaceCount).toEqual(0);
- });
-
- it('does not trigger "removeToken" on backspaces when value is not empty', () => {
- vm.onBackspace();
- vm.onBackspace();
-
- expect(vm.backspaceCount).toEqual(0);
- expect(vm.$emit).not.toHaveBeenCalled();
- });
-
- it('does not trigger "removeToken" on backspaces when tokens are empty', () => {
- vm.tokens = [];
-
- vm.onBackspace();
- vm.onBackspace();
-
- expect(vm.backspaceCount).toEqual(0);
- expect(vm.$emit).not.toHaveBeenCalled();
- });
-
- it('triggers "focus" on input focus', () => {
- vm.$refs.input.dispatchEvent(new Event('focus'));
-
- expect(vm.$emit).toHaveBeenCalledWith('focus');
- });
-
- it('triggers "blur" on input blur', () => {
- vm.$refs.input.dispatchEvent(new Event('blur'));
-
- expect(vm.$emit).toHaveBeenCalledWith('blur');
- });
-
- it('triggers "input" with value on input change', () => {
- vm.$refs.input.value = 'something-else';
- vm.$refs.input.dispatchEvent(new Event('input'));
-
- expect(vm.$emit).toHaveBeenCalledWith('input', 'something-else');
- });
-});
diff --git a/spec/javascripts/ide/lib/common/model_manager_spec.js b/spec/javascripts/ide/lib/common/model_manager_spec.js
deleted file mode 100644
index 38ffa317e8e..00000000000
--- a/spec/javascripts/ide/lib/common/model_manager_spec.js
+++ /dev/null
@@ -1,126 +0,0 @@
-import eventHub from '~/ide/eventhub';
-import ModelManager from '~/ide/lib/common/model_manager';
-import { file } from '../../helpers';
-
-describe('Multi-file editor library model manager', () => {
- let instance;
-
- beforeEach(() => {
- instance = new ModelManager();
- });
-
- afterEach(() => {
- instance.dispose();
- });
-
- describe('addModel', () => {
- it('caches model', () => {
- instance.addModel(file());
-
- expect(instance.models.size).toBe(1);
- });
-
- it('caches model by file path', () => {
- const f = file('path-name');
- instance.addModel(f);
-
- expect(instance.models.keys().next().value).toBe(f.key);
- });
-
- it('adds model into disposable', () => {
- spyOn(instance.disposable, 'add').and.callThrough();
-
- instance.addModel(file());
-
- expect(instance.disposable.add).toHaveBeenCalled();
- });
-
- it('returns cached model', () => {
- spyOn(instance.models, 'get').and.callThrough();
-
- instance.addModel(file());
- instance.addModel(file());
-
- expect(instance.models.get).toHaveBeenCalled();
- });
-
- it('adds eventHub listener', () => {
- const f = file();
- spyOn(eventHub, '$on').and.callThrough();
-
- instance.addModel(f);
-
- expect(eventHub.$on).toHaveBeenCalledWith(
- `editor.update.model.dispose.${f.key}`,
- jasmine.anything(),
- );
- });
- });
-
- describe('hasCachedModel', () => {
- it('returns false when no models exist', () => {
- expect(instance.hasCachedModel('path')).toBeFalsy();
- });
-
- it('returns true when model exists', () => {
- const f = file('path-name');
-
- instance.addModel(f);
-
- expect(instance.hasCachedModel(f.key)).toBeTruthy();
- });
- });
-
- describe('getModel', () => {
- it('returns cached model', () => {
- instance.addModel(file('path-name'));
-
- expect(instance.getModel('path-name')).not.toBeNull();
- });
- });
-
- describe('removeCachedModel', () => {
- let f;
-
- beforeEach(() => {
- f = file();
-
- instance.addModel(f);
- });
-
- it('clears cached model', () => {
- instance.removeCachedModel(f);
-
- expect(instance.models.size).toBe(0);
- });
-
- it('removes eventHub listener', () => {
- spyOn(eventHub, '$off').and.callThrough();
-
- instance.removeCachedModel(f);
-
- expect(eventHub.$off).toHaveBeenCalledWith(
- `editor.update.model.dispose.${f.key}`,
- jasmine.anything(),
- );
- });
- });
-
- describe('dispose', () => {
- it('clears cached models', () => {
- instance.addModel(file());
-
- instance.dispose();
-
- expect(instance.models.size).toBe(0);
- });
-
- it('calls disposable dispose', () => {
- spyOn(instance.disposable, 'dispose').and.callThrough();
-
- instance.dispose();
-
- expect(instance.disposable.dispose).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/javascripts/ide/lib/common/model_spec.js b/spec/javascripts/ide/lib/common/model_spec.js
deleted file mode 100644
index f096e06f43c..00000000000
--- a/spec/javascripts/ide/lib/common/model_spec.js
+++ /dev/null
@@ -1,137 +0,0 @@
-import eventHub from '~/ide/eventhub';
-import Model from '~/ide/lib/common/model';
-import { file } from '../../helpers';
-
-describe('Multi-file editor library model', () => {
- let model;
-
- beforeEach(() => {
- spyOn(eventHub, '$on').and.callThrough();
-
- const f = file('path');
- f.mrChange = { diff: 'ABC' };
- f.baseRaw = 'test';
- model = new Model(f);
- });
-
- afterEach(() => {
- model.dispose();
- });
-
- it('creates original model & base model & new model', () => {
- expect(model.originalModel).not.toBeNull();
- expect(model.model).not.toBeNull();
- expect(model.baseModel).not.toBeNull();
-
- expect(model.originalModel.uri.path).toBe('original/path--path');
- expect(model.model.uri.path).toBe('path--path');
- expect(model.baseModel.uri.path).toBe('target/path--path');
- });
-
- it('creates model with head file to compare against', () => {
- const f = file('path');
- model.dispose();
-
- model = new Model(f, {
- ...f,
- content: '123 testing',
- });
-
- expect(model.head).not.toBeNull();
- expect(model.getOriginalModel().getValue()).toBe('123 testing');
- });
-
- it('adds eventHub listener', () => {
- expect(eventHub.$on).toHaveBeenCalledWith(
- `editor.update.model.dispose.${model.file.key}`,
- jasmine.anything(),
- );
- });
-
- describe('path', () => {
- it('returns file path', () => {
- expect(model.path).toBe(model.file.key);
- });
- });
-
- describe('getModel', () => {
- it('returns model', () => {
- expect(model.getModel()).toBe(model.model);
- });
- });
-
- describe('getOriginalModel', () => {
- it('returns original model', () => {
- expect(model.getOriginalModel()).toBe(model.originalModel);
- });
- });
-
- describe('getBaseModel', () => {
- it('returns base model', () => {
- expect(model.getBaseModel()).toBe(model.baseModel);
- });
- });
-
- describe('setValue', () => {
- it('updates models value', () => {
- model.setValue('testing 123');
-
- expect(model.getModel().getValue()).toBe('testing 123');
- });
- });
-
- describe('onChange', () => {
- it('calls callback on change', done => {
- const spy = jasmine.createSpy();
- model.onChange(spy);
-
- model.getModel().setValue('123');
-
- setTimeout(() => {
- expect(spy).toHaveBeenCalledWith(model, jasmine.anything());
- done();
- });
- });
- });
-
- describe('dispose', () => {
- it('calls disposable dispose', () => {
- spyOn(model.disposable, 'dispose').and.callThrough();
-
- model.dispose();
-
- expect(model.disposable.dispose).toHaveBeenCalled();
- });
-
- it('clears events', () => {
- model.onChange(() => {});
-
- expect(model.events.size).toBe(1);
-
- model.dispose();
-
- expect(model.events.size).toBe(0);
- });
-
- it('removes eventHub listener', () => {
- spyOn(eventHub, '$off').and.callThrough();
-
- model.dispose();
-
- expect(eventHub.$off).toHaveBeenCalledWith(
- `editor.update.model.dispose.${model.file.key}`,
- jasmine.anything(),
- );
- });
-
- it('calls onDispose callback', () => {
- const disposeSpy = jasmine.createSpy();
-
- model.onDispose(disposeSpy);
-
- model.dispose();
-
- expect(disposeSpy).toHaveBeenCalled();
- });
- });
-});
diff --git a/spec/javascripts/ide/lib/decorations/controller_spec.js b/spec/javascripts/ide/lib/decorations/controller_spec.js
deleted file mode 100644
index 4118774cca3..00000000000
--- a/spec/javascripts/ide/lib/decorations/controller_spec.js
+++ /dev/null
@@ -1,143 +0,0 @@
-import Editor from '~/ide/lib/editor';
-import DecorationsController from '~/ide/lib/decorations/controller';
-import Model from '~/ide/lib/common/model';
-import { file } from '../../helpers';
-
-describe('Multi-file editor library decorations controller', () => {
- let editorInstance;
- let controller;
- let model;
-
- beforeEach(() => {
- editorInstance = Editor.create();
- editorInstance.createInstance(document.createElement('div'));
-
- controller = new DecorationsController(editorInstance);
- model = new Model(file('path'));
- });
-
- afterEach(() => {
- model.dispose();
- editorInstance.dispose();
- controller.dispose();
- });
-
- describe('getAllDecorationsForModel', () => {
- it('returns empty array when no decorations exist for model', () => {
- const decorations = controller.getAllDecorationsForModel(model);
-
- expect(decorations).toEqual([]);
- });
-
- it('returns decorations by model URL', () => {
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
-
- const decorations = controller.getAllDecorationsForModel(model);
-
- expect(decorations[0]).toEqual({ decoration: 'decorationValue' });
- });
- });
-
- describe('addDecorations', () => {
- it('caches decorations in a new map', () => {
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
-
- expect(controller.decorations.size).toBe(1);
- });
-
- it('does not create new cache model', () => {
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue2' }]);
-
- expect(controller.decorations.size).toBe(1);
- });
-
- it('caches decorations by model URL', () => {
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
-
- expect(controller.decorations.size).toBe(1);
- expect(controller.decorations.keys().next().value).toBe('gitlab:path--path');
- });
-
- it('calls decorate method', () => {
- spyOn(controller, 'decorate');
-
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
-
- expect(controller.decorate).toHaveBeenCalled();
- });
- });
-
- describe('decorate', () => {
- it('sets decorations on editor instance', () => {
- spyOn(controller.editor.instance, 'deltaDecorations');
-
- controller.decorate(model);
-
- expect(controller.editor.instance.deltaDecorations).toHaveBeenCalledWith([], []);
- });
-
- it('caches decorations', () => {
- spyOn(controller.editor.instance, 'deltaDecorations').and.returnValue([]);
-
- controller.decorate(model);
-
- expect(controller.editorDecorations.size).toBe(1);
- });
-
- it('caches decorations by model URL', () => {
- spyOn(controller.editor.instance, 'deltaDecorations').and.returnValue([]);
-
- controller.decorate(model);
-
- expect(controller.editorDecorations.keys().next().value).toBe('gitlab:path--path');
- });
- });
-
- describe('dispose', () => {
- it('clears cached decorations', () => {
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
-
- controller.dispose();
-
- expect(controller.decorations.size).toBe(0);
- });
-
- it('clears cached editorDecorations', () => {
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
-
- controller.dispose();
-
- expect(controller.editorDecorations.size).toBe(0);
- });
- });
-
- describe('hasDecorations', () => {
- it('returns true when decorations are cached', () => {
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
-
- expect(controller.hasDecorations(model)).toBe(true);
- });
-
- it('returns false when no model decorations exist', () => {
- expect(controller.hasDecorations(model)).toBe(false);
- });
- });
-
- describe('removeDecorations', () => {
- beforeEach(() => {
- controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]);
- controller.decorate(model);
- });
-
- it('removes cached decorations', () => {
- expect(controller.decorations.size).not.toBe(0);
- expect(controller.editorDecorations.size).not.toBe(0);
-
- controller.removeDecorations(model);
-
- expect(controller.decorations.size).toBe(0);
- expect(controller.editorDecorations.size).toBe(0);
- });
- });
-});
diff --git a/spec/javascripts/ide/lib/diff/controller_spec.js b/spec/javascripts/ide/lib/diff/controller_spec.js
deleted file mode 100644
index 90ebb95b687..00000000000
--- a/spec/javascripts/ide/lib/diff/controller_spec.js
+++ /dev/null
@@ -1,215 +0,0 @@
-import { Range } from 'monaco-editor';
-import Editor from '~/ide/lib/editor';
-import ModelManager from '~/ide/lib/common/model_manager';
-import DecorationsController from '~/ide/lib/decorations/controller';
-import DirtyDiffController, { getDiffChangeType, getDecorator } from '~/ide/lib/diff/controller';
-import { computeDiff } from '~/ide/lib/diff/diff';
-import { file } from '../../helpers';
-
-describe('Multi-file editor library dirty diff controller', () => {
- let editorInstance;
- let controller;
- let modelManager;
- let decorationsController;
- let model;
-
- beforeEach(() => {
- editorInstance = Editor.create();
- editorInstance.createInstance(document.createElement('div'));
-
- modelManager = new ModelManager();
- decorationsController = new DecorationsController(editorInstance);
-
- model = modelManager.addModel(file('path'));
-
- controller = new DirtyDiffController(modelManager, decorationsController);
- });
-
- afterEach(() => {
- controller.dispose();
- model.dispose();
- decorationsController.dispose();
- editorInstance.dispose();
- });
-
- describe('getDiffChangeType', () => {
- ['added', 'removed', 'modified'].forEach(type => {
- it(`returns ${type}`, () => {
- const change = {
- [type]: true,
- };
-
- expect(getDiffChangeType(change)).toBe(type);
- });
- });
- });
-
- describe('getDecorator', () => {
- ['added', 'removed', 'modified'].forEach(type => {
- it(`returns with linesDecorationsClassName for ${type}`, () => {
- const change = {
- [type]: true,
- };
-
- expect(getDecorator(change).options.linesDecorationsClassName).toBe(
- `dirty-diff dirty-diff-${type}`,
- );
- });
-
- it('returns with line numbers', () => {
- const change = {
- lineNumber: 1,
- endLineNumber: 2,
- [type]: true,
- };
-
- const { range } = getDecorator(change);
-
- expect(range.startLineNumber).toBe(1);
- expect(range.endLineNumber).toBe(2);
- expect(range.startColumn).toBe(1);
- expect(range.endColumn).toBe(1);
- });
- });
- });
-
- describe('attachModel', () => {
- it('adds change event callback', () => {
- spyOn(model, 'onChange');
-
- controller.attachModel(model);
-
- expect(model.onChange).toHaveBeenCalled();
- });
-
- it('adds dispose event callback', () => {
- spyOn(model, 'onDispose');
-
- controller.attachModel(model);
-
- expect(model.onDispose).toHaveBeenCalled();
- });
-
- it('calls throttledComputeDiff on change', () => {
- spyOn(controller, 'throttledComputeDiff');
-
- controller.attachModel(model);
-
- model.getModel().setValue('123');
-
- expect(controller.throttledComputeDiff).toHaveBeenCalled();
- });
-
- it('caches model', () => {
- controller.attachModel(model);
-
- expect(controller.models.has(model.url)).toBe(true);
- });
- });
-
- describe('computeDiff', () => {
- it('posts to worker', () => {
- spyOn(controller.dirtyDiffWorker, 'postMessage');
-
- controller.computeDiff(model);
-
- expect(controller.dirtyDiffWorker.postMessage).toHaveBeenCalledWith({
- path: model.path,
- originalContent: '',
- newContent: '',
- });
- });
- });
-
- describe('reDecorate', () => {
- it('calls computeDiff when no decorations are cached', () => {
- spyOn(controller, 'computeDiff');
-
- controller.reDecorate(model);
-
- expect(controller.computeDiff).toHaveBeenCalledWith(model);
- });
-
- it('calls decorate when decorations are cached', () => {
- spyOn(controller.decorationsController, 'decorate');
-
- controller.decorationsController.decorations.set(model.url, 'test');
-
- controller.reDecorate(model);
-
- expect(controller.decorationsController.decorate).toHaveBeenCalledWith(model);
- });
- });
-
- describe('decorate', () => {
- it('adds decorations into decorations controller', () => {
- spyOn(controller.decorationsController, 'addDecorations');
-
- controller.decorate({ data: { changes: [], path: model.path } });
-
- expect(controller.decorationsController.addDecorations).toHaveBeenCalledWith(
- model,
- 'dirtyDiff',
- jasmine.anything(),
- );
- });
-
- it('adds decorations into editor', () => {
- const spy = spyOn(controller.decorationsController.editor.instance, 'deltaDecorations');
-
- controller.decorate({
- data: { changes: computeDiff('123', '1234'), path: model.path },
- });
-
- expect(spy).toHaveBeenCalledWith(
- [],
- [
- {
- range: new Range(1, 1, 1, 1),
- options: {
- isWholeLine: true,
- linesDecorationsClassName: 'dirty-diff dirty-diff-modified',
- },
- },
- ],
- );
- });
- });
-
- describe('dispose', () => {
- it('calls disposable dispose', () => {
- spyOn(controller.disposable, 'dispose').and.callThrough();
-
- controller.dispose();
-
- expect(controller.disposable.dispose).toHaveBeenCalled();
- });
-
- it('terminates worker', () => {
- spyOn(controller.dirtyDiffWorker, 'terminate').and.callThrough();
-
- controller.dispose();
-
- expect(controller.dirtyDiffWorker.terminate).toHaveBeenCalled();
- });
-
- it('removes worker event listener', () => {
- spyOn(controller.dirtyDiffWorker, 'removeEventListener').and.callThrough();
-
- controller.dispose();
-
- expect(controller.dirtyDiffWorker.removeEventListener).toHaveBeenCalledWith(
- 'message',
- jasmine.anything(),
- );
- });
-
- it('clears cached models', () => {
- controller.attachModel(model);
-
- model.dispose();
-
- expect(controller.models.size).toBe(0);
- });
- });
-});
diff --git a/spec/javascripts/ide/lib/editor_spec.js b/spec/javascripts/ide/lib/editor_spec.js
deleted file mode 100644
index 556bd45d3a5..00000000000
--- a/spec/javascripts/ide/lib/editor_spec.js
+++ /dev/null
@@ -1,287 +0,0 @@
-import { editor as monacoEditor } from 'monaco-editor';
-import Editor from '~/ide/lib/editor';
-import { file } from '../helpers';
-
-describe('Multi-file editor library', () => {
- let instance;
- let el;
- let holder;
-
- beforeEach(() => {
- el = document.createElement('div');
- holder = document.createElement('div');
- el.appendChild(holder);
-
- document.body.appendChild(el);
-
- instance = Editor.create();
- });
-
- afterEach(() => {
- instance.dispose();
-
- el.remove();
- });
-
- it('creates instance of editor', () => {
- expect(Editor.editorInstance).not.toBeNull();
- });
-
- it('creates instance returns cached instance', () => {
- expect(Editor.create()).toEqual(instance);
- });
-
- describe('createInstance', () => {
- it('creates editor instance', () => {
- spyOn(monacoEditor, 'create').and.callThrough();
-
- instance.createInstance(holder);
-
- expect(monacoEditor.create).toHaveBeenCalled();
- });
-
- it('creates dirty diff controller', () => {
- instance.createInstance(holder);
-
- expect(instance.dirtyDiffController).not.toBeNull();
- });
-
- it('creates model manager', () => {
- instance.createInstance(holder);
-
- expect(instance.modelManager).not.toBeNull();
- });
- });
-
- describe('createDiffInstance', () => {
- it('creates editor instance', () => {
- spyOn(monacoEditor, 'createDiffEditor').and.callThrough();
-
- instance.createDiffInstance(holder);
-
- expect(monacoEditor.createDiffEditor).toHaveBeenCalledWith(holder, {
- model: null,
- contextmenu: true,
- minimap: {
- enabled: false,
- },
- readOnly: true,
- scrollBeyondLastLine: false,
- renderWhitespace: 'none',
- quickSuggestions: false,
- occurrencesHighlight: false,
- wordWrap: 'on',
- renderSideBySide: true,
- renderLineHighlight: 'all',
- hideCursorInOverviewRuler: false,
- theme: 'vs white',
- });
- });
- });
-
- describe('createModel', () => {
- it('calls model manager addModel', () => {
- spyOn(instance.modelManager, 'addModel');
-
- instance.createModel('FILE');
-
- expect(instance.modelManager.addModel).toHaveBeenCalledWith('FILE', null);
- });
- });
-
- describe('attachModel', () => {
- let model;
-
- beforeEach(() => {
- instance.createInstance(document.createElement('div'));
-
- model = instance.createModel(file());
- });
-
- it('sets the current model on the instance', () => {
- instance.attachModel(model);
-
- expect(instance.currentModel).toBe(model);
- });
-
- it('attaches the model to the current instance', () => {
- spyOn(instance.instance, 'setModel');
-
- instance.attachModel(model);
-
- expect(instance.instance.setModel).toHaveBeenCalledWith(model.getModel());
- });
-
- it('sets original & modified when diff editor', () => {
- spyOn(instance.instance, 'getEditorType').and.returnValue('vs.editor.IDiffEditor');
- spyOn(instance.instance, 'setModel');
-
- instance.attachModel(model);
-
- expect(instance.instance.setModel).toHaveBeenCalledWith({
- original: model.getOriginalModel(),
- modified: model.getModel(),
- });
- });
-
- it('attaches the model to the dirty diff controller', () => {
- spyOn(instance.dirtyDiffController, 'attachModel');
-
- instance.attachModel(model);
-
- expect(instance.dirtyDiffController.attachModel).toHaveBeenCalledWith(model);
- });
-
- it('re-decorates with the dirty diff controller', () => {
- spyOn(instance.dirtyDiffController, 'reDecorate');
-
- instance.attachModel(model);
-
- expect(instance.dirtyDiffController.reDecorate).toHaveBeenCalledWith(model);
- });
- });
-
- describe('attachMergeRequestModel', () => {
- let model;
-
- beforeEach(() => {
- instance.createDiffInstance(document.createElement('div'));
-
- const f = file();
- f.mrChanges = { diff: 'ABC' };
- f.baseRaw = 'testing';
-
- model = instance.createModel(f);
- });
-
- it('sets original & modified', () => {
- spyOn(instance.instance, 'setModel');
-
- instance.attachMergeRequestModel(model);
-
- expect(instance.instance.setModel).toHaveBeenCalledWith({
- original: model.getBaseModel(),
- modified: model.getModel(),
- });
- });
- });
-
- describe('clearEditor', () => {
- it('resets the editor model', () => {
- instance.createInstance(document.createElement('div'));
-
- spyOn(instance.instance, 'setModel');
-
- instance.clearEditor();
-
- expect(instance.instance.setModel).toHaveBeenCalledWith(null);
- });
- });
-
- describe('dispose', () => {
- it('calls disposble dispose method', () => {
- spyOn(instance.disposable, 'dispose').and.callThrough();
-
- instance.dispose();
-
- expect(instance.disposable.dispose).toHaveBeenCalled();
- });
-
- it('resets instance', () => {
- instance.createInstance(document.createElement('div'));
-
- expect(instance.instance).not.toBeNull();
-
- instance.dispose();
-
- expect(instance.instance).toBeNull();
- });
-
- it('does not dispose modelManager', () => {
- spyOn(instance.modelManager, 'dispose');
-
- instance.dispose();
-
- expect(instance.modelManager.dispose).not.toHaveBeenCalled();
- });
-
- it('does not dispose decorationsController', () => {
- spyOn(instance.decorationsController, 'dispose');
-
- instance.dispose();
-
- expect(instance.decorationsController.dispose).not.toHaveBeenCalled();
- });
- });
-
- describe('updateDiffView', () => {
- describe('edit mode', () => {
- it('does not update options', () => {
- instance.createInstance(holder);
-
- spyOn(instance.instance, 'updateOptions');
-
- instance.updateDiffView();
-
- expect(instance.instance.updateOptions).not.toHaveBeenCalled();
- });
- });
-
- describe('diff mode', () => {
- beforeEach(() => {
- instance.createDiffInstance(holder);
-
- spyOn(instance.instance, 'updateOptions').and.callThrough();
- });
-
- it('sets renderSideBySide to false if el is less than 700 pixels', () => {
- spyOnProperty(instance.instance.getDomNode(), 'offsetWidth').and.returnValue(600);
-
- expect(instance.instance.updateOptions).not.toHaveBeenCalledWith({
- renderSideBySide: false,
- });
- });
-
- it('sets renderSideBySide to false if el is more than 700 pixels', () => {
- spyOnProperty(instance.instance.getDomNode(), 'offsetWidth').and.returnValue(800);
-
- expect(instance.instance.updateOptions).not.toHaveBeenCalledWith({
- renderSideBySide: true,
- });
- });
- });
- });
-
- describe('isDiffEditorType', () => {
- it('returns true when diff editor', () => {
- instance.createDiffInstance(holder);
-
- expect(instance.isDiffEditorType).toBe(true);
- });
-
- it('returns false when not diff editor', () => {
- instance.createInstance(holder);
-
- expect(instance.isDiffEditorType).toBe(false);
- });
- });
-
- it('sets quickSuggestions to false when language is markdown', () => {
- instance.createInstance(holder);
-
- spyOn(instance.instance, 'updateOptions').and.callThrough();
-
- const model = instance.createModel({
- ...file(),
- key: 'index.md',
- path: 'index.md',
- });
-
- instance.attachModel(model);
-
- expect(instance.instance.updateOptions).toHaveBeenCalledWith({
- readOnly: false,
- quickSuggestions: false,
- });
- });
-});