mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-10 00:35:30 +01:00
Strict null work on mainThreadSaveParticpants test
This commit is contained in:
@@ -34,7 +34,7 @@ import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IProgressService2, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { extHostCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
|
||||
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
|
||||
import { ISaveParticipant, SaveReason, IActiveTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ISaveParticipant, SaveReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ExtHostContext, ExtHostDocumentSaveParticipantShape, IExtHostContext } from '../node/extHost.protocol';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
@@ -51,7 +51,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
|
||||
this.doTrimTrailingWhitespace(model.textEditorModel, env.reason === SaveReason.AUTO);
|
||||
}
|
||||
@@ -113,7 +113,7 @@ export class FinalNewLineParticipant implements ISaveParticipantParticipant {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
|
||||
this.doInsertFinalNewLine(model.textEditorModel);
|
||||
}
|
||||
@@ -151,7 +151,7 @@ export class TrimFinalNewLinesParticipant implements ISaveParticipantParticipant
|
||||
// Nothing
|
||||
}
|
||||
|
||||
async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
|
||||
this.doTrimFinalNewLines(model.textEditorModel, env.reason === SaveReason.AUTO);
|
||||
}
|
||||
@@ -222,7 +222,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
|
||||
const model = editorModel.textEditorModel;
|
||||
if (env.reason === SaveReason.AUTO
|
||||
@@ -293,7 +293,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService
|
||||
) { }
|
||||
|
||||
async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
if (env.reason === SaveReason.AUTO) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -373,7 +373,7 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant {
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentSaveParticipant);
|
||||
}
|
||||
|
||||
async participate(editorModel: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
async participate(editorModel: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
|
||||
if (!shouldSynchronizeModel(editorModel.textEditorModel)) {
|
||||
// the model never made it to the extension
|
||||
@@ -424,7 +424,7 @@ export class SaveParticipant implements ISaveParticipant {
|
||||
this._saveParticipants.dispose();
|
||||
}
|
||||
|
||||
async participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void> {
|
||||
return this._progressService.withProgress({ location: ProgressLocation.Window }, progress => {
|
||||
progress.report({ message: localize('saveParticipants', "Running Save Participants...") });
|
||||
const promiseFactory = this._saveParticipants.getValue().map(p => () => {
|
||||
|
||||
@@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, IRawTextContent, ILoadOptions, LoadReason, IActiveTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, IRawTextContent, ILoadOptions, LoadReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { EncodingMode } from 'vs/workbench/common/editor';
|
||||
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
|
||||
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
|
||||
@@ -661,7 +661,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
|
||||
};
|
||||
|
||||
this.blockModelContentChange = true;
|
||||
saveParticipantPromise = TextFileEditorModel.saveParticipant.participate(this as IActiveTextFileEditorModel, { reason: options.reason }).then(onCompleteOrError, onCompleteOrError);
|
||||
saveParticipantPromise = TextFileEditorModel.saveParticipant.participate(this as IResolvedTextFileEditorModel, { reason: options.reason }).then(onCompleteOrError, onCompleteOrError);
|
||||
}
|
||||
|
||||
// mark the save participant as current pending save operation
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface ISaveParticipant {
|
||||
/**
|
||||
* Participate in a save of a model. Allows to change the model before it is being saved to disk.
|
||||
*/
|
||||
participate(model: IActiveTextFileEditorModel, env: { reason: SaveReason }): Promise<void>;
|
||||
participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason }): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,7 +255,7 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport
|
||||
isDisposed(): boolean;
|
||||
}
|
||||
|
||||
export interface IActiveTextFileEditorModel extends ITextFileEditorModel {
|
||||
export interface IResolvedTextFileEditorModel extends ITextFileEditorModel {
|
||||
readonly textEditorModel: ITextModel;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
|
||||
import { ITextFileService, SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ITextFileService, SaveReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager';
|
||||
import { snapshotToString } from 'vs/platform/files/common/files';
|
||||
|
||||
@@ -38,7 +38,7 @@ suite('MainThreadSaveParticipant', function () {
|
||||
});
|
||||
|
||||
test('insert final new line', async function () {
|
||||
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/final_new_line.txt'), 'utf8');
|
||||
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel;
|
||||
|
||||
await model.load();
|
||||
const configService = new TestConfigurationService();
|
||||
@@ -47,66 +47,66 @@ suite('MainThreadSaveParticipant', function () {
|
||||
|
||||
// No new line for empty lines
|
||||
let lineContent = '';
|
||||
model.textEditorModel!.setValue(lineContent);
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
await participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), lineContent);
|
||||
|
||||
// No new line if last line already empty
|
||||
lineContent = `Hello New Line${model.textEditorModel!.getEOL()}`;
|
||||
model.textEditorModel!.setValue(lineContent);
|
||||
lineContent = `Hello New Line${model.textEditorModel.getEOL()}`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
await participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), lineContent);
|
||||
|
||||
// New empty line added (single line)
|
||||
lineContent = 'Hello New Line';
|
||||
model.textEditorModel!.setValue(lineContent);
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
await participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel!.getEOL()}`);
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel.getEOL()}`);
|
||||
|
||||
// New empty line added (multi line)
|
||||
lineContent = `Hello New Line${model.textEditorModel!.getEOL()}Hello New Line${model.textEditorModel!.getEOL()}Hello New Line`;
|
||||
model.textEditorModel!.setValue(lineContent);
|
||||
lineContent = `Hello New Line${model.textEditorModel.getEOL()}Hello New Line${model.textEditorModel.getEOL()}Hello New Line`;
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
await participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel!.getEOL()}`);
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${lineContent}${model.textEditorModel.getEOL()}`);
|
||||
});
|
||||
|
||||
test('trim final new lines', async function () {
|
||||
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8');
|
||||
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel;
|
||||
|
||||
await model.load();
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
|
||||
const participant = new TrimFinalNewLinesParticipant(configService, undefined!);
|
||||
const textContent = 'Trim New Line';
|
||||
const eol = `${model.textEditorModel!.getEOL()}`;
|
||||
const eol = `${model.textEditorModel.getEOL()}`;
|
||||
|
||||
// No new line removal if last line is not new line
|
||||
let lineContent = `${textContent}`;
|
||||
model.textEditorModel!.setValue(lineContent);
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
await participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), lineContent);
|
||||
|
||||
// No new line removal if last line is single new line
|
||||
lineContent = `${textContent}${eol}`;
|
||||
model.textEditorModel!.setValue(lineContent);
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
await participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), lineContent);
|
||||
|
||||
// Remove new line (single line with two new lines)
|
||||
lineContent = `${textContent}${eol}${eol}`;
|
||||
model.textEditorModel!.setValue(lineContent);
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
await participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`);
|
||||
|
||||
// Remove new lines (multiple lines with multiple new lines)
|
||||
lineContent = `${textContent}${eol}${textContent}${eol}${eol}${eol}`;
|
||||
model.textEditorModel!.setValue(lineContent);
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
await participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}${textContent}${eol}`);
|
||||
});
|
||||
|
||||
test('trim final new lines bug#39750', async function () {
|
||||
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8');
|
||||
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel;
|
||||
|
||||
await model.load();
|
||||
const configService = new TestConfigurationService();
|
||||
@@ -116,33 +116,33 @@ suite('MainThreadSaveParticipant', function () {
|
||||
|
||||
// single line
|
||||
let lineContent = `${textContent}`;
|
||||
model.textEditorModel!.setValue(lineContent);
|
||||
model.textEditorModel.setValue(lineContent);
|
||||
|
||||
// apply edits and push to undo stack.
|
||||
let textEdits = [{ range: new Range(1, 14, 1, 14), text: '.', forceMoveMarkers: false }];
|
||||
model.textEditorModel!.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; });
|
||||
model.textEditorModel.pushEditOperations([new Selection(1, 14, 1, 14)], textEdits, () => { return [new Selection(1, 15, 1, 15)]; });
|
||||
|
||||
// undo
|
||||
model.textEditorModel!.undo();
|
||||
model.textEditorModel.undo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}`);
|
||||
|
||||
// trim final new lines should not mess the undo stack
|
||||
await participant.participate(model, { reason: SaveReason.EXPLICIT });
|
||||
model.textEditorModel!.redo();
|
||||
model.textEditorModel.redo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}.`);
|
||||
});
|
||||
|
||||
test('trim final new lines bug#46075', async function () {
|
||||
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8');
|
||||
const model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/trim_final_new_line.txt'), 'utf8') as IResolvedTextFileEditorModel;
|
||||
|
||||
await model.load();
|
||||
const configService = new TestConfigurationService();
|
||||
configService.setUserConfiguration('files', { 'trimFinalNewlines': true });
|
||||
const participant = new TrimFinalNewLinesParticipant(configService, undefined!);
|
||||
const textContent = 'Test';
|
||||
const eol = `${model.textEditorModel!.getEOL()}`;
|
||||
const eol = `${model.textEditorModel.getEOL()}`;
|
||||
let content = `${textContent}${eol}${eol}`;
|
||||
model.textEditorModel!.setValue(content);
|
||||
model.textEditorModel.setValue(content);
|
||||
|
||||
// save many times
|
||||
for (let i = 0; i < 10; i++) {
|
||||
@@ -153,9 +153,9 @@ suite('MainThreadSaveParticipant', function () {
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`);
|
||||
|
||||
// undo should go back to previous content immediately
|
||||
model.textEditorModel!.undo();
|
||||
model.textEditorModel.undo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}${eol}`);
|
||||
model.textEditorModel!.redo();
|
||||
model.textEditorModel.redo();
|
||||
assert.equal(snapshotToString(model.createSnapshot()!), `${textContent}${eol}`);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user