@@ -13,7 +13,7 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
1313import { TestServiceAccessor , workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices' ;
1414import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' ;
1515import { basename } from 'vs/base/common/resources' ;
16- import { FileChangesEvent , FileChangeType , FileOperationError , FileOperationResult , NotModifiedSinceFileOperationError } from 'vs/platform/files/common/files' ;
16+ import { FileChangesEvent , FileChangeType , FileOperationError , FileOperationResult , IFileStatWithMetadata , IWriteFileOptions , NotModifiedSinceFileOperationError } from 'vs/platform/files/common/files' ;
1717import { SaveReason , SaveSourceRegistry } from 'vs/workbench/common/editor' ;
1818import { Promises , timeout } from 'vs/base/common/async' ;
1919import { consumeReadable , consumeStream , isReadableStream } from 'vs/base/common/stream' ;
@@ -82,13 +82,120 @@ export class TestStoredFileWorkingCopyModel extends Disposable implements IStore
8282 }
8383}
8484
85+ export class TestStoredFileWorkingCopyModelWithCustomSave extends TestStoredFileWorkingCopyModel {
86+
87+ saveCounter = 0 ;
88+ throwOnSave = false ;
89+
90+ async save ( options : IWriteFileOptions , token : CancellationToken ) : Promise < IFileStatWithMetadata > {
91+ if ( this . throwOnSave ) {
92+ throw new Error ( 'Fail' ) ;
93+ }
94+
95+ this . saveCounter ++ ;
96+
97+ return {
98+ resource : this . resource ,
99+ ctime : 0 ,
100+ etag : '' ,
101+ isDirectory : false ,
102+ isFile : true ,
103+ mtime : 0 ,
104+ name : 'resource2' ,
105+ size : 0 ,
106+ isSymbolicLink : false ,
107+ readonly : false ,
108+ locked : false ,
109+ children : undefined
110+ } ;
111+ }
112+ }
113+
85114export class TestStoredFileWorkingCopyModelFactory implements IStoredFileWorkingCopyModelFactory < TestStoredFileWorkingCopyModel > {
86115
87116 async createModel ( resource : URI , contents : VSBufferReadableStream , token : CancellationToken ) : Promise < TestStoredFileWorkingCopyModel > {
88117 return new TestStoredFileWorkingCopyModel ( resource , ( await streamToBuffer ( contents ) ) . toString ( ) ) ;
89118 }
90119}
91120
121+ export class TestStoredFileWorkingCopyModelWithCustomSaveFactory implements IStoredFileWorkingCopyModelFactory < TestStoredFileWorkingCopyModelWithCustomSave > {
122+
123+ async createModel ( resource : URI , contents : VSBufferReadableStream , token : CancellationToken ) : Promise < TestStoredFileWorkingCopyModelWithCustomSave > {
124+ return new TestStoredFileWorkingCopyModelWithCustomSave ( resource , ( await streamToBuffer ( contents ) ) . toString ( ) ) ;
125+ }
126+ }
127+
128+ suite ( 'StoredFileWorkingCopy (with custom save)' , function ( ) {
129+
130+ const factory = new TestStoredFileWorkingCopyModelWithCustomSaveFactory ( ) ;
131+
132+ let disposables : DisposableStore ;
133+ const resource = URI . file ( 'test/resource' ) ;
134+ let instantiationService : IInstantiationService ;
135+ let accessor : TestServiceAccessor ;
136+ let workingCopy : StoredFileWorkingCopy < TestStoredFileWorkingCopyModelWithCustomSave > ;
137+
138+ function createWorkingCopy ( uri : URI = resource ) {
139+ const workingCopy : StoredFileWorkingCopy < TestStoredFileWorkingCopyModelWithCustomSave > = new StoredFileWorkingCopy < TestStoredFileWorkingCopyModelWithCustomSave > ( 'testStoredFileWorkingCopyType' , uri , basename ( uri ) , factory , options => workingCopy . resolve ( options ) , accessor . fileService , accessor . logService , accessor . workingCopyFileService , accessor . filesConfigurationService , accessor . workingCopyBackupService , accessor . workingCopyService , accessor . notificationService , accessor . workingCopyEditorService , accessor . editorService , accessor . elevatedFileService ) ;
140+
141+ return workingCopy ;
142+ }
143+
144+ setup ( ( ) => {
145+ disposables = new DisposableStore ( ) ;
146+ instantiationService = workbenchInstantiationService ( undefined , disposables ) ;
147+ accessor = instantiationService . createInstance ( TestServiceAccessor ) ;
148+
149+ workingCopy = createWorkingCopy ( ) ;
150+ } ) ;
151+
152+ teardown ( ( ) => {
153+ workingCopy . dispose ( ) ;
154+ disposables . dispose ( ) ;
155+ } ) ;
156+
157+ test ( 'save (custom implemented)' , async ( ) => {
158+ let savedCounter = 0 ;
159+ let lastSaveEvent : IStoredFileWorkingCopySaveEvent | undefined = undefined ;
160+ workingCopy . onDidSave ( e => {
161+ savedCounter ++ ;
162+ lastSaveEvent = e ;
163+ } ) ;
164+
165+ let saveErrorCounter = 0 ;
166+ workingCopy . onDidSaveError ( ( ) => {
167+ saveErrorCounter ++ ;
168+ } ) ;
169+
170+ // unresolved
171+ await workingCopy . save ( ) ;
172+ assert . strictEqual ( savedCounter , 0 ) ;
173+ assert . strictEqual ( saveErrorCounter , 0 ) ;
174+
175+ // simple
176+ await workingCopy . resolve ( ) ;
177+ workingCopy . model ?. updateContents ( 'hello save' ) ;
178+ await workingCopy . save ( ) ;
179+
180+ assert . strictEqual ( savedCounter , 1 ) ;
181+ assert . strictEqual ( saveErrorCounter , 0 ) ;
182+ assert . strictEqual ( workingCopy . isDirty ( ) , false ) ;
183+ assert . strictEqual ( lastSaveEvent ! . reason , SaveReason . EXPLICIT ) ;
184+ assert . ok ( lastSaveEvent ! . stat ) ;
185+ assert . ok ( isStoredFileWorkingCopySaveEvent ( lastSaveEvent ! ) ) ;
186+ assert . strictEqual ( workingCopy . model ?. pushedStackElement , true ) ;
187+ assert . strictEqual ( ( workingCopy . model as TestStoredFileWorkingCopyModelWithCustomSave ) . saveCounter , 1 ) ;
188+
189+ // error
190+ workingCopy . model ?. updateContents ( 'hello save error' ) ;
191+ ( workingCopy . model as TestStoredFileWorkingCopyModelWithCustomSave ) . throwOnSave = true ;
192+ await workingCopy . save ( ) ;
193+
194+ assert . strictEqual ( saveErrorCounter , 1 ) ;
195+ assert . strictEqual ( workingCopy . hasState ( StoredFileWorkingCopyState . ERROR ) , true ) ;
196+ } ) ;
197+ } ) ;
198+
92199suite ( 'StoredFileWorkingCopy' , function ( ) {
93200
94201 const factory = new TestStoredFileWorkingCopyModelFactory ( ) ;
0 commit comments