// ***************************************************************************** // Copyright (C) 2018 Red Hat, Inc. and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** import * as assert from 'assert'; import * as Converter from './type-converters'; import * as theia from '@theia/plugin'; import * as types from './types-impl'; import * as model from '../common/plugin-api-rpc-model'; import { MarkdownString } from './markdown-string'; import { MarkdownString as MarkdownStringInterface } from '@theia/core/lib/common/markdown-rendering'; import { TaskDto } from '../common/plugin-api-rpc'; describe('Type converters:', () => { describe('convert ranges:', () => { // given const modelRange: model.Range = { startLineNumber: 5, startColumn: 5, endLineNumber: 10, endColumn: 20 }; const pluginRange: theia.Range = new types.Range(4, 4, 9, 19); it('should convert to theia range', () => { // when const result: types.Range = Converter.toRange(modelRange); // then assert.deepStrictEqual(result, pluginRange); }); it('should convert to model range', () => { // when const result: model.Range | undefined = Converter.fromRange(pluginRange); // then assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, modelRange); }); }); describe('markdown:', () => { describe('type guard:', () => { it('should recognize markdown string', () => { // given const markdownString = new MarkdownString('**test**'); // when const result = MarkdownStringInterface.is(markdownString); // then assert.deepStrictEqual(result !== false, true); }); it('should recognize markdown object', () => { // given const markdownObject = { value: '*test*' }; // when const result = MarkdownStringInterface.is(markdownObject); // then assert.deepStrictEqual(result !== false, true); }); it('should recognize markdown object with redundant fields', () => { // given const markdownObject = { field1: 5, value: '*test*', field2: 'test' }; // when const result = MarkdownStringInterface.is(markdownObject); // then assert.deepStrictEqual(result !== false, true); }); it('should reject non markdown object', () => { // given const nonMarkdownObject = { field1: 5, field2: 'test' }; // when const result = MarkdownStringInterface.is(nonMarkdownObject); // then assert.deepStrictEqual(result === false, true); }); it('should reject non markdown object if it contains isTrusted field', () => { // given const nonMarkdownObject = { isTrusted: true, field1: 5, field2: 'test' }; // when const result = MarkdownStringInterface.is(nonMarkdownObject); // then assert.deepStrictEqual(result === false, true); }); }); describe('converter: ', () => { const aStringWithMarkdown: string = '**test**'; const pluginMarkdown: theia.MarkdownString = new MarkdownString(aStringWithMarkdown); const aLanguage = 'typescript'; const aValue = 'const x=5;'; const codeblock = { language: aLanguage, value: aValue }; const modelMarkdownWithCode: model.MarkdownString = { value: '```' + aLanguage + '\n' + aValue + '\n```\n' }; const modelMarkdown: model.MarkdownString = { value: aStringWithMarkdown }; it('should convert plugin markdown to model markdown', () => { // when const result = Converter.fromMarkdown(pluginMarkdown); // then assert.deepStrictEqual(result, { ...modelMarkdown, supportThemeIcons: false, supportHtml: false }, 'The implementation includes an explicit default `false` for `supportThemeIcons` and `supportHtml`'); }); it('should convert string to model markdown', () => { // when const result = Converter.fromMarkdown(aStringWithMarkdown); // then assert.deepStrictEqual(result, modelMarkdown); }); it('should convert codeblock to model markdown', () => { // when const result = Converter.fromMarkdown(codeblock); // then assert.deepStrictEqual(result, modelMarkdownWithCode); }); it('should convert array of markups to model markdown', () => { // given // eslint-disable-next-line deprecation/deprecation const markups: (theia.MarkdownString | theia.MarkedString)[] = [ pluginMarkdown, aStringWithMarkdown, codeblock, new MarkdownString('hello', true), ]; // when const result: model.MarkdownString[] = Converter.fromManyMarkdown(markups); // then assert.deepStrictEqual(Array.isArray(result), true); assert.deepStrictEqual(result.length, 4); assert.deepStrictEqual(result[0], { ...modelMarkdown, supportThemeIcons: false, supportHtml: false, }, 'MarkdownString implementation includes default value for `supportThemeIcons` and `supportHtml`'); assert.deepStrictEqual(result[1], modelMarkdown, 'Strings should be converted to Markdown.'); assert.deepStrictEqual(result[2], modelMarkdownWithCode, 'Objects matching the interface should be unchanged'); assert.deepStrictEqual(result[3], { value: 'hello', supportThemeIcons: true, supportHtml: false }, 'The constructor argument to MarkdownString for theme icons is respected.'); }); }); }); describe('convert tasks:', () => { const customType = 'custom'; const shellType = 'shell'; const label = 'npm run build'; const source = 'source'; const command = 'npm'; const commandLine = 'npm run build'; const args = ['run', 'build']; const cwd = '/projects/theia'; const additionalProperty = 'some property'; const group = new types.TaskGroup('build', 'Build'); const shellTaskDto: TaskDto = { type: shellType, executionType: shellType, label, source, scope: 1, command, args, options: { cwd }, additionalProperty, presentation: { reveal: 3, focus: true }, group: { kind: 'build', isDefault: false }, runOptions: { reevaluateOnRerun: false } }; const shellTaskDtoWithCommandLine: TaskDto = { type: shellType, executionType: shellType, label, source, scope: 2, command: commandLine, options: { cwd }, additionalProperty, runOptions: { reevaluateOnRerun: false } }; const shellPluginTask: theia.Task = { name: label, source, scope: 1, definition: { type: shellType, additionalProperty }, presentationOptions: { reveal: types.TaskRevealKind.Never, focus: true }, group, execution: { command, args, options: { cwd } }, runOptions: { reevaluateOnRerun: false } }; const shellPluginTaskWithQuotedCommand: theia.Task = { ...shellPluginTask, execution: { command: { quoting: types.ShellQuoting.Strong, value: 'npm' }, args, options: { cwd } } }; const pluginTaskWithCommandLine: theia.Task = { name: label, source, scope: 2, definition: { type: shellType, additionalProperty }, execution: { commandLine, options: { cwd } }, runOptions: { reevaluateOnRerun: false } }; const customTaskDto: TaskDto = { ...shellTaskDto, type: customType }; const customTaskDtoWithCommandLine: TaskDto = { ...shellTaskDtoWithCommandLine, type: customType }; const customPluginTask: theia.Task = { ...shellPluginTask, definition: { type: customType, additionalProperty } }; const customPluginTaskWithCommandLine: theia.Task = { name: label, source, scope: 2, definition: { type: customType, additionalProperty }, execution: { commandLine, options: { cwd } }, runOptions: { reevaluateOnRerun: false } }; it('should convert to task dto with string command', () => { // when const result: TaskDto | undefined = Converter.fromTask(shellPluginTask); // then assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, shellTaskDto); }); it('should convert to task dto with ShellStringQuoted', () => { const result: TaskDto | undefined = Converter.fromTask(shellPluginTaskWithQuotedCommand); assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, shellTaskDto); }); it('should convert from task dto', () => { // when const result: theia.Task = Converter.toTask(shellTaskDto); assert.strictEqual(result.execution instanceof types.ShellExecution, true); if (result.execution instanceof types.ShellExecution) { assert.strictEqual(result.execution.commandLine, undefined); result.execution = { args: result.execution.args, options: result.execution.options, command: result.execution.command }; } // then assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, shellPluginTask); }); it('should convert to task dto from task with commandline', () => { // when const result: TaskDto | undefined = Converter.fromTask(pluginTaskWithCommandLine); // then assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, shellTaskDtoWithCommandLine); }); it('should convert task with custom type to dto', () => { // when const result: TaskDto | undefined = Converter.fromTask(customPluginTask); // then assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, customTaskDto); }); it('should convert task with custom type from dto', () => { // when const result: theia.Task = Converter.toTask(customTaskDto); assert.strictEqual(result.execution instanceof types.ShellExecution, true); if (result.execution instanceof types.ShellExecution) { assert.strictEqual(result.execution.commandLine, undefined); result.execution = { args: result.execution.args, options: result.execution.options, command: result.execution.command }; } // then assert.deepStrictEqual(result, customPluginTask); }); it('should convert to task dto from custom task with commandline', () => { // when const result: TaskDto | undefined = Converter.fromTask(customPluginTaskWithCommandLine); // then assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, customTaskDtoWithCommandLine); }); }); describe('Webview Panel Show Options:', () => { it('should create options from view column ', () => { const viewColumn = types.ViewColumn.Five; const showOptions: theia.WebviewPanelShowOptions = { area: types.WebviewPanelTargetArea.Main, viewColumn: types.ViewColumn.Four, preserveFocus: false }; // when const result: theia.WebviewPanelShowOptions = Converter.toWebviewPanelShowOptions(viewColumn); // then assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, showOptions); }); it('should create options from given "WebviewPanelShowOptions" object ', () => { const incomingObject: theia.WebviewPanelShowOptions = { area: types.WebviewPanelTargetArea.Main, viewColumn: types.ViewColumn.Five, preserveFocus: true }; const showOptions: theia.WebviewPanelShowOptions = { area: types.WebviewPanelTargetArea.Main, viewColumn: types.ViewColumn.Four, preserveFocus: true }; // when const result: theia.WebviewPanelShowOptions = Converter.toWebviewPanelShowOptions(incomingObject); // then assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, showOptions); }); it('should set default "main" area', () => { const incomingObject: theia.WebviewPanelShowOptions = { viewColumn: types.ViewColumn.Five, preserveFocus: false }; const showOptions: theia.WebviewPanelShowOptions = { area: types.WebviewPanelTargetArea.Main, viewColumn: types.ViewColumn.Four, preserveFocus: false }; // when const result: theia.WebviewPanelShowOptions = Converter.toWebviewPanelShowOptions(incomingObject); // then assert.notStrictEqual(result, undefined); assert.deepStrictEqual(result, showOptions); }); }); describe('#convertCode', () => { it('should convert a "code" of type "string"', () => { assert.strictEqual(Converter.convertCode('string'), 'string'); }); it('should convert a "code" of type "number"', () => { assert.strictEqual(Converter.convertCode(4), '4'); }); it('should convert an undefined "code"', () => { assert.strictEqual(Converter.convertCode(undefined), undefined); }); it('should convert a "code" of type "{ value: number, target: Uri }"', () => { const uri = types.URI.parse('foo://example.com:8042/over/there?name=ferret#nose'); assert.strictEqual(Converter.convertCode({ value: 4, target: uri }), '4'); }); it('should convert a "code" of type "{ value: number, target: Uri }"', () => { const uri = types.URI.parse('foo://example.com:8042/over/there?name=ferret#nose'); assert.strictEqual(Converter.convertCode({ value: 'string', target: uri }), 'string'); }); }); });