codeActionModel.test.ts 5.7 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

import * as assert from 'assert';
import URI from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
A
Alex Dima 已提交
10
import { TextModel } from 'vs/editor/common/model/textModel';
A
Alex Dima 已提交
11
import { createTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
12
import { MarkerService } from 'vs/platform/markers/common/markerService';
13
import { CodeActionOracle } from 'vs/editor/contrib/codeAction/codeActionModel';
14
import { CodeActionProviderRegistry, LanguageIdentifier } from 'vs/editor/common/modes';
J
Johannes Rieken 已提交
15
import { IDisposable } from 'vs/base/common/lifecycle';
16
import { Range } from 'vs/editor/common/core/range';
17
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
18

M
Matt Bierner 已提交
19
suite('CodeAction', () => {
20

J
Johannes Rieken 已提交
21
	const languageIdentifier = new LanguageIdentifier('foo-lang', 3);
22
	let uri = URI.parse('untitled:path');
A
Alex Dima 已提交
23
	let model: TextModel;
24
	let markerService: MarkerService;
25
	let editor: ICodeEditor;
J
Johannes Rieken 已提交
26
	let reg: IDisposable;
27 28

	setup(() => {
J
Johannes Rieken 已提交
29 30
		reg = CodeActionProviderRegistry.register(languageIdentifier.language, {
			provideCodeActions() {
J
Johannes Rieken 已提交
31
				return [{ id: 'test-command', title: 'test', arguments: [] }];
J
Johannes Rieken 已提交
32 33
			}
		});
34
		markerService = new MarkerService();
A
Alex Dima 已提交
35
		model = TextModel.createFromString('foobar  foo bar\nfarboo far boo', undefined, languageIdentifier, uri);
A
Alex Dima 已提交
36
		editor = createTestCodeEditor(model);
37 38 39
		editor.setPosition({ lineNumber: 1, column: 1 });
	});

J
Johannes Rieken 已提交
40
	teardown(() => {
J
Johannes Rieken 已提交
41
		reg.dispose();
J
Johannes Rieken 已提交
42
		editor.dispose();
J
Johannes Rieken 已提交
43
		model.dispose();
J
Johannes Rieken 已提交
44
		markerService.dispose();
J
Johannes Rieken 已提交
45 46
	});

47 48
	test('Orcale -> marker added', done => {

49
		const oracle = new CodeActionOracle(editor, markerService, e => {
M
Matt Bierner 已提交
50
			assert.equal(e.trigger.type, 'auto');
51
			assert.ok(e.actions);
52

53
			e.actions.then(fixes => {
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
				oracle.dispose();
				assert.equal(fixes.length, 1);
				done();
			}, done);
		});

		// start here
		markerService.changeOne('fake', uri, [{
			startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 6,
			message: 'error',
			severity: 1,
			code: '',
			source: ''
		}]);

	});

71
	test('Orcale -> position changed', () => {
72 73 74 75 76 77 78 79 80 81 82

		markerService.changeOne('fake', uri, [{
			startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 6,
			message: 'error',
			severity: 1,
			code: '',
			source: ''
		}]);

		editor.setPosition({ lineNumber: 2, column: 1 });

J
Johannes Rieken 已提交
83
		return new Promise((resolve, reject) => {
84

85
			const oracle = new CodeActionOracle(editor, markerService, e => {
M
Matt Bierner 已提交
86
				assert.equal(e.trigger.type, 'auto');
87 88
				assert.ok(e.actions);
				e.actions.then(fixes => {
89 90 91 92 93 94 95
					oracle.dispose();
					assert.equal(fixes.length, 1);
					resolve(undefined);
				}, reject);
			});
			// start here
			editor.setPosition({ lineNumber: 1, column: 1 });
96
		});
J
Johannes Rieken 已提交
97
	});
98

99
	test('Oracle -> marker wins over selection', () => {
J
Johannes Rieken 已提交
100

A
Alex Dima 已提交
101
		let range: Range;
J
Johannes Rieken 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
		let reg = CodeActionProviderRegistry.register(languageIdentifier.language, {
			provideCodeActions(doc, _range) {
				range = _range;
				return [];
			}
		});

		markerService.changeOne('fake', uri, [{
			startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 6,
			message: 'error',
			severity: 1,
			code: '',
			source: ''
		}]);

		let fixes: TPromise<any>[] = [];
118 119
		let oracle = new CodeActionOracle(editor, markerService, e => {
			fixes.push(e.actions);
120
		}, 10);
J
Johannes Rieken 已提交
121 122 123

		editor.setSelection({ startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 13 });

124
		return TPromise.join<any>([TPromise.timeout(20)].concat(fixes)).then(_ => {
J
Johannes Rieken 已提交
125

126 127
			// -> marker wins
			assert.deepEqual(range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 6 });
J
Johannes Rieken 已提交
128

J
Johannes Rieken 已提交
129 130
			// 'auto' triggered, non-empty selection BUT within a marker
			editor.setSelection({ startLineNumber: 1, startColumn: 2, endLineNumber: 1, endColumn: 4 });
J
Johannes Rieken 已提交
131

132
			return TPromise.join([TPromise.timeout(20)].concat(fixes)).then(_ => {
J
Johannes Rieken 已提交
133 134 135 136 137 138 139 140 141
				reg.dispose();
				oracle.dispose();

				// assert marker
				assert.deepEqual(range, { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 6 });
			});
		});
	});

J
Johannes Rieken 已提交
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
	test('Lightbulb is in the wrong place, #29933', async function () {
		let reg = CodeActionProviderRegistry.register(languageIdentifier.language, {
			provideCodeActions(doc, _range) {
				return [];
			}
		});

		editor.getModel().setValue('// @ts-check\n2\ncon\n');

		markerService.changeOne('fake', uri, [{
			startLineNumber: 3, startColumn: 1, endLineNumber: 3, endColumn: 4,
			message: 'error',
			severity: 1,
			code: '',
			source: ''
		}]);

159
		// case 1 - drag selection over multiple lines -> range of enclosed marker, position or marker
J
Johannes Rieken 已提交
160
		await new Promise(resolve => {
J
Johannes Rieken 已提交
161

162
			let oracle = new CodeActionOracle(editor, markerService, e => {
M
Matt Bierner 已提交
163
				assert.equal(e.trigger.type, 'auto');
164 165
				assert.deepEqual(e.range, { startLineNumber: 3, startColumn: 1, endLineNumber: 3, endColumn: 4 });
				assert.deepEqual(e.position, { lineNumber: 3, column: 1 });
J
Johannes Rieken 已提交
166 167 168 169 170 171 172 173

				oracle.dispose();
				resolve(null);
			}, 5);

			editor.setSelection({ startLineNumber: 1, startColumn: 1, endLineNumber: 4, endColumn: 1 });
		});

174 175
		// // case 2 - selection over multiple lines & manual trigger -> lightbulb
		// await new TPromise(resolve => {
J
Johannes Rieken 已提交
176

177
		// 	editor.setSelection({ startLineNumber: 1, startColumn: 1, endLineNumber: 4, endColumn: 1 });
J
Johannes Rieken 已提交
178

179 180 181
		// 	let oracle = new QuickFixOracle(editor, markerService, e => {
		// 		assert.equal(e.type, 'manual');
		// 		assert.ok(e.range.equalsRange({ startLineNumber: 1, startColumn: 1, endLineNumber: 4, endColumn: 1 }));
J
Johannes Rieken 已提交
182

183 184 185
		// 		oracle.dispose();
		// 		resolve(null);
		// 	}, 5);
J
Johannes Rieken 已提交
186

187 188
		// 	oracle.trigger('manual');
		// });
J
Johannes Rieken 已提交
189 190 191 192 193


		reg.dispose();
	});

194
});