2018-03-20 10:16:38 -04:00
|
|
|
import eventHub from '~/ide/eventhub';
|
|
|
|
import Model from '~/ide/lib/common/model';
|
2018-03-20 10:12:48 -04:00
|
|
|
import { file } from '../../helpers';
|
|
|
|
|
|
|
|
describe('Multi-file editor library model', () => {
|
|
|
|
let model;
|
|
|
|
|
2018-06-07 17:34:50 -04:00
|
|
|
beforeEach(() => {
|
2020-04-28 17:09:35 -04:00
|
|
|
jest.spyOn(eventHub, '$on');
|
2018-03-20 10:12:48 -04:00
|
|
|
|
2018-06-07 17:34:50 -04:00
|
|
|
const f = file('path');
|
|
|
|
f.mrChange = { diff: 'ABC' };
|
|
|
|
f.baseRaw = 'test';
|
2018-06-08 00:53:45 -04:00
|
|
|
model = new Model(f);
|
2018-03-20 10:12:48 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
model.dispose();
|
|
|
|
});
|
|
|
|
|
2018-03-26 08:18:24 -04:00
|
|
|
it('creates original model & base model & new model', () => {
|
2018-03-20 10:12:48 -04:00
|
|
|
expect(model.originalModel).not.toBeNull();
|
|
|
|
expect(model.model).not.toBeNull();
|
2018-03-26 08:18:24 -04:00
|
|
|
expect(model.baseModel).not.toBeNull();
|
2018-05-09 06:09:26 -04:00
|
|
|
|
|
|
|
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');
|
2018-03-20 10:12:48 -04:00
|
|
|
});
|
|
|
|
|
2018-04-07 05:08:34 -04:00
|
|
|
it('creates model with head file to compare against', () => {
|
|
|
|
const f = file('path');
|
|
|
|
model.dispose();
|
|
|
|
|
2018-06-08 00:53:45 -04:00
|
|
|
model = new Model(f, {
|
2018-04-07 05:08:34 -04:00
|
|
|
...f,
|
|
|
|
content: '123 testing',
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(model.head).not.toBeNull();
|
|
|
|
expect(model.getOriginalModel().getValue()).toBe('123 testing');
|
|
|
|
});
|
|
|
|
|
2018-03-20 10:12:48 -04:00
|
|
|
it('adds eventHub listener', () => {
|
2018-03-20 10:16:38 -04:00
|
|
|
expect(eventHub.$on).toHaveBeenCalledWith(
|
2018-03-23 11:59:09 -04:00
|
|
|
`editor.update.model.dispose.${model.file.key}`,
|
2020-04-28 17:09:35 -04:00
|
|
|
expect.anything(),
|
2018-03-20 10:16:38 -04:00
|
|
|
);
|
2018-03-20 10:12:48 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('path', () => {
|
|
|
|
it('returns file path', () => {
|
2018-03-23 11:59:09 -04:00
|
|
|
expect(model.path).toBe(model.file.key);
|
2018-03-20 10:12:48 -04:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('getModel', () => {
|
|
|
|
it('returns model', () => {
|
|
|
|
expect(model.getModel()).toBe(model.model);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('getOriginalModel', () => {
|
|
|
|
it('returns original model', () => {
|
|
|
|
expect(model.getOriginalModel()).toBe(model.originalModel);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-03-26 08:18:24 -04:00
|
|
|
describe('getBaseModel', () => {
|
|
|
|
it('returns base model', () => {
|
|
|
|
expect(model.getBaseModel()).toBe(model.baseModel);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-03-20 10:12:48 -04:00
|
|
|
describe('setValue', () => {
|
|
|
|
it('updates models value', () => {
|
|
|
|
model.setValue('testing 123');
|
|
|
|
|
|
|
|
expect(model.getModel().getValue()).toBe('testing 123');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('onChange', () => {
|
2020-12-23 16:10:24 -05:00
|
|
|
it('calls callback on change', (done) => {
|
2020-04-28 17:09:35 -04:00
|
|
|
const spy = jest.fn();
|
2018-03-20 10:12:48 -04:00
|
|
|
model.onChange(spy);
|
|
|
|
|
|
|
|
model.getModel().setValue('123');
|
|
|
|
|
2020-04-28 17:09:35 -04:00
|
|
|
setImmediate(() => {
|
|
|
|
expect(spy).toHaveBeenCalledWith(model, expect.anything());
|
2018-03-20 10:12:48 -04:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('dispose', () => {
|
|
|
|
it('calls disposable dispose', () => {
|
2020-04-28 17:09:35 -04:00
|
|
|
jest.spyOn(model.disposable, 'dispose');
|
2018-03-20 10:12:48 -04:00
|
|
|
|
|
|
|
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', () => {
|
2020-04-28 17:09:35 -04:00
|
|
|
jest.spyOn(eventHub, '$off');
|
2018-03-20 10:12:48 -04:00
|
|
|
|
|
|
|
model.dispose();
|
|
|
|
|
2018-03-20 10:16:38 -04:00
|
|
|
expect(eventHub.$off).toHaveBeenCalledWith(
|
2018-03-23 11:59:09 -04:00
|
|
|
`editor.update.model.dispose.${model.file.key}`,
|
2020-04-28 17:09:35 -04:00
|
|
|
expect.anything(),
|
2018-03-20 10:16:38 -04:00
|
|
|
);
|
2018-03-20 10:12:48 -04:00
|
|
|
});
|
2018-04-11 07:29:16 -04:00
|
|
|
|
|
|
|
it('calls onDispose callback', () => {
|
2020-04-28 17:09:35 -04:00
|
|
|
const disposeSpy = jest.fn();
|
2018-04-11 07:29:16 -04:00
|
|
|
|
|
|
|
model.onDispose(disposeSpy);
|
|
|
|
|
|
|
|
model.dispose();
|
|
|
|
|
|
|
|
expect(disposeSpy).toHaveBeenCalled();
|
|
|
|
});
|
2020-05-25 08:08:23 -04:00
|
|
|
|
|
|
|
it('applies custom options and triggers onChange callback', () => {
|
|
|
|
const changeSpy = jest.fn();
|
|
|
|
jest.spyOn(model, 'applyCustomOptions');
|
|
|
|
|
|
|
|
model.onChange(changeSpy);
|
|
|
|
|
|
|
|
model.dispose();
|
|
|
|
|
|
|
|
expect(model.applyCustomOptions).toHaveBeenCalled();
|
|
|
|
expect(changeSpy).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('updateOptions', () => {
|
|
|
|
it('sets the options on the options object', () => {
|
|
|
|
model.updateOptions({ insertSpaces: true, someOption: 'some value' });
|
|
|
|
|
|
|
|
expect(model.options).toEqual({
|
|
|
|
endOfLine: 0,
|
|
|
|
insertFinalNewline: true,
|
|
|
|
insertSpaces: true,
|
|
|
|
someOption: 'some value',
|
|
|
|
trimTrailingWhitespace: false,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it.each`
|
|
|
|
option | value
|
|
|
|
${'insertSpaces'} | ${true}
|
|
|
|
${'insertSpaces'} | ${false}
|
|
|
|
${'indentSize'} | ${4}
|
|
|
|
${'tabSize'} | ${3}
|
|
|
|
`("correctly sets option: $option=$value to Monaco's TextModel", ({ option, value }) => {
|
|
|
|
model.updateOptions({ [option]: value });
|
|
|
|
|
|
|
|
expect(model.getModel().getOptions()).toMatchObject({ [option]: value });
|
|
|
|
});
|
|
|
|
|
|
|
|
it('applies custom options immediately', () => {
|
|
|
|
jest.spyOn(model, 'applyCustomOptions');
|
|
|
|
|
|
|
|
model.updateOptions({ trimTrailingWhitespace: true, someOption: 'some value' });
|
|
|
|
|
|
|
|
expect(model.applyCustomOptions).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('applyCustomOptions', () => {
|
|
|
|
it.each`
|
|
|
|
option | value | contentBefore | contentAfter
|
|
|
|
${'endOfLine'} | ${0} | ${'hello\nworld\n'} | ${'hello\nworld\n'}
|
|
|
|
${'endOfLine'} | ${0} | ${'hello\r\nworld\r\n'} | ${'hello\nworld\n'}
|
|
|
|
${'endOfLine'} | ${1} | ${'hello\nworld\n'} | ${'hello\r\nworld\r\n'}
|
|
|
|
${'endOfLine'} | ${1} | ${'hello\r\nworld\r\n'} | ${'hello\r\nworld\r\n'}
|
|
|
|
${'insertFinalNewline'} | ${true} | ${'hello\nworld'} | ${'hello\nworld\n'}
|
|
|
|
${'insertFinalNewline'} | ${true} | ${'hello\nworld\n'} | ${'hello\nworld\n'}
|
|
|
|
${'insertFinalNewline'} | ${false} | ${'hello\nworld'} | ${'hello\nworld'}
|
|
|
|
${'trimTrailingWhitespace'} | ${true} | ${'hello \t\nworld \t\n'} | ${'hello\nworld\n'}
|
|
|
|
${'trimTrailingWhitespace'} | ${true} | ${'hello \t\r\nworld \t\r\n'} | ${'hello\nworld\n'}
|
|
|
|
${'trimTrailingWhitespace'} | ${false} | ${'hello \t\r\nworld \t\r\n'} | ${'hello \t\nworld \t\n'}
|
|
|
|
`(
|
|
|
|
'correctly applies custom option $option=$value to content',
|
|
|
|
({ option, value, contentBefore, contentAfter }) => {
|
|
|
|
model.options[option] = value;
|
|
|
|
|
|
|
|
model.updateNewContent(contentBefore);
|
|
|
|
model.applyCustomOptions();
|
|
|
|
|
|
|
|
expect(model.getModel().getValue()).toEqual(contentAfter);
|
|
|
|
},
|
|
|
|
);
|
2018-03-20 10:12:48 -04:00
|
|
|
});
|
|
|
|
});
|