2021-03-11 19:13:27 +05:30
|
|
|
import { GlLoadingIcon } from '@gitlab/ui';
|
2021-03-08 18:12:59 +05:30
|
|
|
import { shallowMount } from '@vue/test-utils';
|
2021-03-11 19:13:27 +05:30
|
|
|
import Vue, { nextTick } from 'vue';
|
2020-06-23 00:09:42 +05:30
|
|
|
import Vuex from 'vuex';
|
|
|
|
import Terminal from '~/ide/components/terminal/terminal.vue';
|
|
|
|
import TerminalControls from '~/ide/components/terminal/terminal_controls.vue';
|
|
|
|
import {
|
|
|
|
STARTING,
|
|
|
|
PENDING,
|
|
|
|
RUNNING,
|
|
|
|
STOPPING,
|
|
|
|
STOPPED,
|
|
|
|
} from '~/ide/stores/modules/terminal/constants';
|
|
|
|
import GLTerminal from '~/terminal/terminal';
|
|
|
|
|
|
|
|
const TEST_TERMINAL_PATH = 'terminal/path';
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
Vue.use(Vuex);
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
jest.mock('~/terminal/terminal', () =>
|
2021-03-08 18:12:59 +05:30
|
|
|
jest.fn().mockImplementation(function FakeTerminal() {
|
|
|
|
Object.assign(this, {
|
|
|
|
dispose: jest.fn(),
|
|
|
|
disable: jest.fn(),
|
|
|
|
addScrollListener: jest.fn(),
|
|
|
|
scrollToTop: jest.fn(),
|
|
|
|
scrollToBottom: jest.fn(),
|
|
|
|
});
|
|
|
|
}),
|
2020-06-23 00:09:42 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
describe('IDE Terminal', () => {
|
|
|
|
let wrapper;
|
|
|
|
let state;
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
const factory = (propsData) => {
|
2020-06-23 00:09:42 +05:30
|
|
|
const store = new Vuex.Store({
|
|
|
|
state,
|
|
|
|
mutations: {
|
|
|
|
set(prevState, newState) {
|
|
|
|
Object.assign(prevState, newState);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
wrapper = shallowMount(Terminal, {
|
2020-06-23 00:09:42 +05:30
|
|
|
propsData: {
|
|
|
|
status: RUNNING,
|
|
|
|
terminalPath: TEST_TERMINAL_PATH,
|
|
|
|
...propsData,
|
|
|
|
},
|
|
|
|
store,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
state = {
|
|
|
|
panelResizing: false,
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('loading text', () => {
|
2021-03-08 18:12:59 +05:30
|
|
|
[STARTING, PENDING].forEach((status) => {
|
2020-06-23 00:09:42 +05:30
|
|
|
it(`shows when starting (${status})`, () => {
|
|
|
|
factory({ status });
|
|
|
|
|
2022-08-27 11:52:29 +05:30
|
|
|
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
|
2020-06-23 00:09:42 +05:30
|
|
|
expect(wrapper.find('.top-bar').text()).toBe('Starting...');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it(`shows when stopping`, () => {
|
|
|
|
factory({ status: STOPPING });
|
|
|
|
|
2022-08-27 11:52:29 +05:30
|
|
|
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
|
2020-06-23 00:09:42 +05:30
|
|
|
expect(wrapper.find('.top-bar').text()).toBe('Stopping...');
|
|
|
|
});
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
[RUNNING, STOPPED].forEach((status) => {
|
2020-06-23 00:09:42 +05:30
|
|
|
it('hides when not loading', () => {
|
|
|
|
factory({ status });
|
|
|
|
|
2022-08-27 11:52:29 +05:30
|
|
|
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false);
|
2020-06-23 00:09:42 +05:30
|
|
|
expect(wrapper.find('.top-bar').text()).toBe('');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('refs.terminal', () => {
|
|
|
|
it('has terminal path in data', () => {
|
|
|
|
factory();
|
|
|
|
|
|
|
|
expect(wrapper.vm.$refs.terminal.dataset.projectPath).toBe(TEST_TERMINAL_PATH);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('terminal controls', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
factory();
|
|
|
|
wrapper.vm.createTerminal();
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
return nextTick();
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
it('is visible if terminal is created', () => {
|
2022-08-27 11:52:29 +05:30
|
|
|
expect(wrapper.findComponent(TerminalControls).exists()).toBe(true);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
it('scrolls glterminal on scroll-up', () => {
|
2022-08-27 11:52:29 +05:30
|
|
|
wrapper.findComponent(TerminalControls).vm.$emit('scroll-up');
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
expect(wrapper.vm.glterminal.scrollToTop).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('scrolls glterminal on scroll-down', () => {
|
2022-08-27 11:52:29 +05:30
|
|
|
wrapper.findComponent(TerminalControls).vm.$emit('scroll-down');
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
expect(wrapper.vm.glterminal.scrollToBottom).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('has props set', () => {
|
2022-08-27 11:52:29 +05:30
|
|
|
expect(wrapper.findComponent(TerminalControls).props()).toEqual({
|
2020-06-23 00:09:42 +05:30
|
|
|
canScrollUp: false,
|
|
|
|
canScrollDown: false,
|
|
|
|
});
|
|
|
|
|
2022-03-02 08:16:31 +05:30
|
|
|
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
|
|
|
|
// eslint-disable-next-line no-restricted-syntax
|
2020-06-23 00:09:42 +05:30
|
|
|
wrapper.setData({ canScrollUp: true, canScrollDown: true });
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
return nextTick().then(() => {
|
2022-08-27 11:52:29 +05:30
|
|
|
expect(wrapper.findComponent(TerminalControls).props()).toEqual({
|
2020-06-23 00:09:42 +05:30
|
|
|
canScrollUp: true,
|
|
|
|
canScrollDown: true,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('refresh', () => {
|
|
|
|
it('creates the terminal if running', () => {
|
|
|
|
factory({ status: RUNNING, terminalPath: TEST_TERMINAL_PATH });
|
|
|
|
|
|
|
|
wrapper.vm.refresh();
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
expect(GLTerminal.mock.instances).toHaveLength(1);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
it('stops the terminal if stopping', async () => {
|
|
|
|
factory({ status: RUNNING, terminalPath: TEST_TERMINAL_PATH });
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
wrapper.vm.refresh();
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
const terminal = GLTerminal.mock.instances[0];
|
|
|
|
wrapper.setProps({ status: STOPPING });
|
|
|
|
await nextTick();
|
|
|
|
|
|
|
|
expect(terminal.disable).toHaveBeenCalled();
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('createTerminal', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
factory();
|
|
|
|
wrapper.vm.createTerminal();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('creates the terminal', () => {
|
|
|
|
expect(GLTerminal).toHaveBeenCalledWith(wrapper.vm.$refs.terminal);
|
2022-11-25 23:54:43 +05:30
|
|
|
expect(wrapper.vm.glterminal).toBeInstanceOf(GLTerminal);
|
2020-06-23 00:09:42 +05:30
|
|
|
});
|
|
|
|
|
|
|
|
describe('scroll listener', () => {
|
|
|
|
it('has been called', () => {
|
|
|
|
expect(wrapper.vm.glterminal.addScrollListener).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('updates scroll data when called', () => {
|
|
|
|
expect(wrapper.vm.canScrollUp).toBe(false);
|
|
|
|
expect(wrapper.vm.canScrollDown).toBe(false);
|
|
|
|
|
|
|
|
const listener = wrapper.vm.glterminal.addScrollListener.mock.calls[0][0];
|
|
|
|
listener({ canScrollUp: true, canScrollDown: true });
|
|
|
|
|
|
|
|
expect(wrapper.vm.canScrollUp).toBe(true);
|
|
|
|
expect(wrapper.vm.canScrollDown).toBe(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('destroyTerminal', () => {
|
|
|
|
it('calls dispose', () => {
|
|
|
|
factory();
|
|
|
|
wrapper.vm.createTerminal();
|
|
|
|
const disposeSpy = wrapper.vm.glterminal.dispose;
|
|
|
|
|
|
|
|
expect(disposeSpy).not.toHaveBeenCalled();
|
|
|
|
|
|
|
|
wrapper.vm.destroyTerminal();
|
|
|
|
|
|
|
|
expect(disposeSpy).toHaveBeenCalled();
|
|
|
|
expect(wrapper.vm.glterminal).toBe(null);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('stopTerminal', () => {
|
|
|
|
it('calls disable', () => {
|
|
|
|
factory();
|
|
|
|
wrapper.vm.createTerminal();
|
|
|
|
|
|
|
|
expect(wrapper.vm.glterminal.disable).not.toHaveBeenCalled();
|
|
|
|
|
|
|
|
wrapper.vm.stopTerminal();
|
|
|
|
|
|
|
|
expect(wrapper.vm.glterminal.disable).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|