Commit 136d69d5 authored by Janis Altherr's avatar Janis Altherr Committed by Kushal Pandya

Add the source editor wrapper to be used by the Pipeline Wizard

Signed-off-by: default avatarJanis Altherr <jaltherr@gitlab.com>
parent 3d6de92f
<script>
import { debounce } from 'lodash';
import { isDocument } from 'yaml';
import { CONTENT_UPDATE_DEBOUNCE } from '~/editor/constants';
import SourceEditor from '~/editor/source_editor';
import { YamlEditorExtension } from '~/editor/extensions/source_editor_yaml_ext';
import { SourceEditorExtension } from '~/editor/extensions/source_editor_extension_base';
export default {
name: 'YamlEditor',
props: {
doc: {
type: Object,
required: true,
validator: (d) => isDocument(d),
},
highlight: {
type: [String, Array],
required: false,
default: null,
},
filename: {
type: String,
required: true,
},
},
data() {
return {
editor: null,
isUpdating: false,
yamlEditorExtension: null,
};
},
watch: {
doc: {
handler() {
this.updateEditorContent();
},
deep: true,
},
highlight(v) {
this.requestHighlight(v);
},
},
mounted() {
this.editor = new SourceEditor().createInstance({
el: this.$el,
blobPath: this.filename,
language: 'yaml',
});
[, this.yamlEditorExtension] = this.editor.use([
{ definition: SourceEditorExtension },
{
definition: YamlEditorExtension,
setupOptions: {
highlightPath: this.highlight,
},
},
]);
this.editor.onDidChangeModelContent(
debounce(() => this.handleChange(), CONTENT_UPDATE_DEBOUNCE),
);
this.updateEditorContent();
this.emitValue();
},
methods: {
async updateEditorContent() {
this.isUpdating = true;
this.editor.setDoc(this.doc);
this.isUpdating = false;
this.requestHighlight(this.highlight);
},
handleChange() {
this.emitValue();
if (!this.isUpdating) {
this.handleTouch();
}
},
emitValue() {
this.$emit('update:yaml', this.editor.getValue());
},
handleTouch() {
this.$emit('touch');
},
requestHighlight(path) {
this.editor.highlight(path, true);
},
},
};
</script>
<template>
<div id="source-editor-yaml-editor"></div>
</template>
import { mount } from '@vue/test-utils';
import { Document } from 'yaml';
import YamlEditor from '~/pipeline_wizard/components/editor.vue';
describe('Pages Yaml Editor wrapper', () => {
const defaultOptions = {
propsData: { doc: new Document({ foo: 'bar' }), filename: 'foo.yml' },
};
describe('mount hook', () => {
const wrapper = mount(YamlEditor, defaultOptions);
it('editor is mounted', () => {
expect(wrapper.vm.editor).not.toBeFalsy();
expect(wrapper.find('.gl-source-editor').exists()).toBe(true);
});
});
describe('watchers', () => {
describe('doc', () => {
const doc = new Document({ baz: ['bar'] });
let wrapper;
beforeEach(() => {
wrapper = mount(YamlEditor, defaultOptions);
});
afterEach(() => {
wrapper.destroy();
});
it("causes the editor's value to be set to the stringified document", async () => {
await wrapper.setProps({ doc });
expect(wrapper.vm.editor.getValue()).toEqual(doc.toString());
});
it('emits an update:yaml event with the yaml representation of doc', async () => {
await wrapper.setProps({ doc });
const changeEvents = wrapper.emitted('update:yaml');
expect(changeEvents[2]).toEqual([doc.toString()]);
});
it('does not cause the touch event to be emitted', () => {
wrapper.setProps({ doc });
expect(wrapper.emitted('touch')).not.toBeTruthy();
});
});
describe('highlight', () => {
const highlight = 'foo';
const wrapper = mount(YamlEditor, defaultOptions);
it('calls editor.highlight(path, keep=true)', async () => {
const highlightSpy = jest.spyOn(wrapper.vm.yamlEditorExtension.obj, 'highlight');
await wrapper.setProps({ highlight });
expect(highlightSpy).toHaveBeenCalledWith(expect.anything(), highlight, true);
});
});
});
describe('events', () => {
const wrapper = mount(YamlEditor, defaultOptions);
it('emits touch if content is changed in editor', async () => {
await wrapper.vm.editor.setValue('foo: boo');
expect(wrapper.emitted('touch')).toBeTruthy();
});
});
});
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