From a4c9fed946440ba40ddd00f79d7718c37e5a7a4b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 21 Sep 2016 10:45:41 +0200 Subject: [PATCH] test for bad concurrent edits, test for subsequent good edits --- .../node/extHostDocumentSaveParticipant.ts | 6 +- .../extHostDocumentSaveParticipant.test.ts | 78 +++++++++++++++++++ 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts index fcda092983a..ada1b48de41 100644 --- a/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts +++ b/src/vs/workbench/api/node/extHostDocumentSaveParticipant.ts @@ -47,7 +47,7 @@ export class ExtHostDocumentSaveParticipant { }; } - $participateInSave(resource: URI): TPromise { + $participateInSave(resource: URI): TPromise { const entries = this._callbacks.entries(); return sequence(entries.map(([fn, thisArg]) => { @@ -106,8 +106,8 @@ export class ExtHostDocumentSaveParticipant { return this._workspace.$applyWorkspaceEdit(edits); } - // TODO@joh - fail? - console.warn('IGNORING changes because document has changed while computing changes'); + // TODO@joh bubble this to listener? + return new Error('ignoring change because of concurrent edits'); }, err => { // ignore error diff --git a/src/vs/workbench/test/node/api/extHostDocumentSaveParticipant.test.ts b/src/vs/workbench/test/node/api/extHostDocumentSaveParticipant.test.ts index a0ec404c9f6..60f6d16f688 100644 --- a/src/vs/workbench/test/node/api/extHostDocumentSaveParticipant.test.ts +++ b/src/vs/workbench/test/node/api/extHostDocumentSaveParticipant.test.ts @@ -177,4 +177,82 @@ suite('ExtHostDocumentSaveParticipant', () => { assert.equal(edits.length, 1); }); }); + + test('event delivery, concurrent change', () => { + + let edits: IResourceEdit[]; + const participant = new ExtHostDocumentSaveParticipant(documents, new class extends MainThreadWorkspaceShape { + $applyWorkspaceEdit(_edits) { + edits = _edits; + return TPromise.as(true); + } + }); + + let sub = participant.onWillSaveTextDocumentEvent(function (e) { + + // concurrent change from somewhere + documents.$acceptModelChanged(resource.toString(), [{ + versionId: 2, + range: { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: 1 }, + text: 'bar', + rangeLength: undefined, eol: undefined, isRedoing: undefined, isUndoing: undefined, + }]); + + e.waitUntil(TPromise.as([TextEdit.insert(new Position(0, 0), 'bar')])); + }); + + return participant.$participateInSave(resource).then(values => { + sub.dispose(); + + assert.equal(edits, undefined); + assert.ok((values[0]).message); + }); + + }); + + test('event delivery, two listeners -> two document states', () => { + + const participant = new ExtHostDocumentSaveParticipant(documents, new class extends MainThreadWorkspaceShape { + $applyWorkspaceEdit(_edits: IResourceEdit[]) { + + for (const {resource, newText, range} of _edits) { + documents.$acceptModelChanged(resource.toString(), [{ + range, + text: newText, + versionId: documents.getDocumentData(resource).version + 1, + rangeLength: undefined, eol: undefined, isRedoing: undefined, isUndoing: undefined, + }]); + } + return TPromise.as(true); + } + }); + + const document = documents.getDocumentData(resource).document; + + let sub1 = participant.onWillSaveTextDocumentEvent(function (e) { + // the document state we started with + assert.equal(document.version, 1); + assert.equal(document.getText(), 'foo'); + + e.waitUntil(TPromise.as([TextEdit.insert(new Position(0, 0), 'bar')])); + }); + + let sub2 = participant.onWillSaveTextDocumentEvent(function (e) { + // the document state AFTER the first listener kicked in + assert.equal(document.version, 2); + assert.equal(document.getText(), 'barfoo'); + + e.waitUntil(TPromise.as([TextEdit.insert(new Position(0, 0), 'bar')])); + }); + + return participant.$participateInSave(resource).then(values => { + sub1.dispose(); + sub2.dispose(); + + // the document state AFTER eventing is done + assert.equal(document.version, 3); + assert.equal(document.getText(), 'barbarfoo'); + }); + + }); }); -- GitLab