Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
94bb5390
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
GitCode(gitcode.net)2024年7月9日维护升级公告
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
94bb5390
编写于
4月 30, 2019
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
hot exit - convert to async/await
上级
1b12c1e4
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
232 addition
and
258 deletion
+232
-258
src/vs/workbench/services/backup/node/backupFileService.ts
src/vs/workbench/services/backup/node/backupFileService.ts
+121
-114
src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts
...es/backup/test/electron-browser/backupFileService.test.ts
+111
-144
未找到文件。
src/vs/workbench/services/backup/node/backupFileService.ts
浏览文件 @
94bb5390
...
...
@@ -3,17 +3,18 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
*
as
path
from
'
vs/base/common/path
'
;
import
*
as
crypto
from
'
crypto
'
;
import
*
as
pfs
from
'
vs/base/node/pfs
'
;
import
{
URI
as
Uri
}
from
'
vs/base/common/uri
'
;
import
{
join
}
from
'
vs/base/common/path
'
;
import
{
createHash
}
from
'
crypto
'
;
import
{
readdir
,
readDirsInDir
,
rimraf
,
RimRafMode
}
from
'
vs/base/node/pfs
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
coalesce
}
from
'
vs/base/common/arrays
'
;
import
{
ResourceQueue
}
from
'
vs/base/common/async
'
;
import
{
IBackupFileService
}
from
'
vs/workbench/services/backup/common/backup
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
readToMatchingString
}
from
'
vs/base/node/stream
'
;
import
{
ITextBufferFactory
,
ITextSnapshot
}
from
'
vs/editor/common/model
'
;
import
{
createTextBufferFactoryFromStream
,
createTextBufferFactoryFromSnapshot
}
from
'
vs/editor/common/model/textModel
'
;
import
{
keys
}
from
'
vs/base/common/map
'
;
import
{
keys
,
ResourceMap
}
from
'
vs/base/common/map
'
;
import
{
Schemas
}
from
'
vs/base/common/network
'
;
import
{
IWorkbenchEnvironmentService
}
from
'
vs/workbench/services/environment/common/environmentService
'
;
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
...
...
@@ -23,47 +24,47 @@ import { TextSnapshotReadable } from 'vs/workbench/services/textfile/common/text
export
interface
IBackupFilesModel
{
resolve
(
backupRoot
:
string
):
Promise
<
IBackupFilesModel
>
;
add
(
resource
:
U
ri
,
versionId
?:
number
):
void
;
has
(
resource
:
U
ri
,
versionId
?:
number
):
boolean
;
get
():
U
ri
[];
remove
(
resource
:
U
ri
):
void
;
add
(
resource
:
U
RI
,
versionId
?:
number
):
void
;
has
(
resource
:
U
RI
,
versionId
?:
number
):
boolean
;
get
():
U
RI
[];
remove
(
resource
:
U
RI
):
void
;
count
():
number
;
clear
():
void
;
}
export
class
BackupFilesModel
implements
IBackupFilesModel
{
private
cache
:
{
[
resource
:
string
]:
number
/* version ID */
}
=
Object
.
create
(
null
);
private
cache
:
ResourceMap
<
number
/* version id */
>
=
new
ResourceMap
(
);
resolve
(
backupRoot
:
string
):
Promise
<
IBackupFilesModel
>
{
return
pfs
.
readDirsInDir
(
backupRoot
).
then
(
backupSchemas
=>
{
async
resolve
(
backupRoot
:
string
):
Promise
<
IBackupFilesModel
>
{
try
{
const
backupSchemas
=
await
readDirsInDir
(
backupRoot
);
// For all supported schemas
return
Promise
.
all
(
backupSchemas
.
map
(
backupSchema
=>
{
await
Promise
.
all
(
backupSchemas
.
map
(
async
backupSchema
=>
{
// Read backup directory for backups
const
backupSchemaPath
=
path
.
join
(
backupRoot
,
backupSchema
);
return
pfs
.
readdir
(
backupSchemaPath
).
then
(
backupHashes
=>
{
// Remember known backups in our caches
backupHashes
.
forEach
(
backupHash
=>
{
const
backupResource
=
Uri
.
file
(
path
.
join
(
backupSchemaPath
,
backupHash
));
this
.
add
(
backupResource
);
});
});
const
backupSchemaPath
=
join
(
backupRoot
,
backupSchema
);
const
backupHashes
=
await
readdir
(
backupSchemaPath
);
// Remember known backups in our caches
backupHashes
.
forEach
(
backupHash
=>
this
.
add
(
URI
.
file
(
join
(
backupSchemaPath
,
backupHash
))));
}));
}).
then
(()
=>
this
,
error
=>
this
);
}
catch
(
error
)
{
// ignore any errors
}
return
this
;
}
add
(
resource
:
U
ri
,
versionId
=
0
):
void
{
this
.
cache
[
resource
.
toString
()]
=
versionId
;
add
(
resource
:
U
RI
,
versionId
=
0
):
void
{
this
.
cache
.
set
(
resource
,
versionId
)
;
}
count
():
number
{
return
Object
.
keys
(
this
.
cache
).
length
;
return
this
.
cache
.
size
;
}
has
(
resource
:
U
ri
,
versionId
?:
number
):
boolean
{
const
cachedVersionId
=
this
.
cache
[
resource
.
toString
()]
;
has
(
resource
:
U
RI
,
versionId
?:
number
):
boolean
{
const
cachedVersionId
=
this
.
cache
.
get
(
resource
)
;
if
(
typeof
cachedVersionId
!==
'
number
'
)
{
return
false
;
// unknown resource
}
...
...
@@ -75,16 +76,16 @@ export class BackupFilesModel implements IBackupFilesModel {
return
true
;
}
get
():
U
ri
[]
{
return
Object
.
keys
(
this
.
cache
).
map
(
k
=>
Uri
.
parse
(
k
)
);
get
():
U
RI
[]
{
return
this
.
cache
.
keys
(
);
}
remove
(
resource
:
U
ri
):
void
{
delete
this
.
cache
[
resource
.
toString
()]
;
remove
(
resource
:
U
RI
):
void
{
this
.
cache
.
delete
(
resource
)
;
}
clear
():
void
{
this
.
cache
=
Object
.
create
(
null
);
this
.
cache
.
clear
(
);
}
}
...
...
@@ -116,15 +117,15 @@ export class BackupFileService implements IBackupFileService {
return
this
.
impl
.
hasBackups
();
}
loadBackupResource
(
resource
:
U
ri
):
Promise
<
Uri
|
undefined
>
{
loadBackupResource
(
resource
:
U
RI
):
Promise
<
URI
|
undefined
>
{
return
this
.
impl
.
loadBackupResource
(
resource
);
}
backupResource
(
resource
:
U
ri
,
content
:
ITextSnapshot
,
versionId
?:
number
):
Promise
<
void
>
{
backupResource
(
resource
:
U
RI
,
content
:
ITextSnapshot
,
versionId
?:
number
):
Promise
<
void
>
{
return
this
.
impl
.
backupResource
(
resource
,
content
,
versionId
);
}
discardResourceBackup
(
resource
:
U
ri
):
Promise
<
void
>
{
discardResourceBackup
(
resource
:
U
RI
):
Promise
<
void
>
{
return
this
.
impl
.
discardResourceBackup
(
resource
);
}
...
...
@@ -132,15 +133,15 @@ export class BackupFileService implements IBackupFileService {
return
this
.
impl
.
discardAllWorkspaceBackups
();
}
getWorkspaceFileBackups
():
Promise
<
U
ri
[]
>
{
getWorkspaceFileBackups
():
Promise
<
U
RI
[]
>
{
return
this
.
impl
.
getWorkspaceFileBackups
();
}
resolveBackupContent
(
backup
:
U
ri
):
Promise
<
ITextBufferFactory
>
{
resolveBackupContent
(
backup
:
U
RI
):
Promise
<
ITextBufferFactory
>
{
return
this
.
impl
.
resolveBackupContent
(
backup
);
}
toBackupResource
(
resource
:
U
ri
):
Uri
{
toBackupResource
(
resource
:
U
RI
):
URI
{
return
this
.
impl
.
toBackupResource
(
resource
);
}
}
...
...
@@ -179,104 +180,110 @@ class BackupFileServiceImpl implements IBackupFileService {
return
model
.
resolve
(
this
.
backupWorkspacePath
);
}
hasBackups
():
Promise
<
boolean
>
{
return
this
.
ready
.
then
(
model
=>
{
return
model
.
count
()
>
0
;
})
;
async
hasBackups
():
Promise
<
boolean
>
{
const
model
=
await
this
.
ready
;
return
model
.
count
()
>
0
;
}
loadBackupResource
(
resource
:
Uri
):
Promise
<
Uri
|
undefined
>
{
return
this
.
ready
.
then
(
model
=>
{
async
loadBackupResource
(
resource
:
URI
):
Promise
<
URI
|
undefined
>
{
const
model
=
await
this
.
ready
;
// Return directly if we have a known backup with that resource
const
backupResource
=
this
.
toBackupResource
(
resource
);
if
(
model
.
has
(
backupResource
))
{
return
backupResource
;
}
// Return directly if we have a known backup with that resource
const
backupResource
=
this
.
toBackupResource
(
resource
);
if
(
model
.
has
(
backupResource
))
{
return
backupResource
;
}
return
undefined
;
});
return
undefined
;
}
backupResource
(
resource
:
Uri
,
content
:
ITextSnapshot
,
versionId
?:
number
):
Promise
<
void
>
{
async
backupResource
(
resource
:
URI
,
content
:
ITextSnapshot
,
versionId
?:
number
):
Promise
<
void
>
{
if
(
this
.
isShuttingDown
)
{
return
Promise
.
resolve
();
}
return
this
.
ready
.
then
(
model
=>
{
const
backupResource
=
this
.
toBackupResource
(
resource
);
if
(
model
.
has
(
backupResource
,
versionId
))
{
return
undefined
;
// return early if backup version id matches requested one
}
const
model
=
await
this
.
ready
;
const
backupResource
=
this
.
toBackupResource
(
resource
);
if
(
model
.
has
(
backupResource
,
versionId
))
{
return
undefined
;
// return early if backup version id matches requested one
}
return
this
.
ioOperationQueues
.
queueFor
(
backupResource
).
queue
(
async
()
=>
{
const
preamble
=
`
${
resource
.
toString
()}${
BackupFileServiceImpl
.
META_MARKER
}
`
;
return
this
.
ioOperationQueues
.
queueFor
(
backupResource
).
queue
(()
=>
{
const
preamble
=
`
${
resource
.
toString
()}${
BackupFileServiceImpl
.
META_MARKER
}
`
;
// Update content with value
await
this
.
fileService
.
writeFile
(
backupResource
,
new
TextSnapshotReadable
(
content
,
preamble
))
;
// Update content with value
return
this
.
fileService
.
writeFile
(
backupResource
,
new
TextSnapshotReadable
(
content
,
preamble
)).
then
(()
=>
model
.
add
(
backupResource
,
versionId
));
});
// Update model
model
.
add
(
backupResource
,
versionId
);
});
}
discardResourceBackup
(
resource
:
Uri
):
Promise
<
void
>
{
return
this
.
ready
.
then
(
model
=>
{
const
backupResource
=
this
.
toBackupResource
(
resource
);
async
discardResourceBackup
(
resource
:
URI
):
Promise
<
void
>
{
const
model
=
await
this
.
ready
;
const
backupResource
=
this
.
toBackupResource
(
resource
);
return
this
.
ioOperationQueues
.
queueFor
(
backupResource
).
queue
(
async
()
=>
{
await
rimraf
(
backupResource
.
fsPath
,
RimRafMode
.
MOVE
);
return
this
.
ioOperationQueues
.
queueFor
(
backupResource
).
queue
(()
=>
{
return
pfs
.
rimraf
(
backupResource
.
fsPath
,
pfs
.
RimRafMode
.
MOVE
).
then
(()
=>
model
.
remove
(
backupResource
));
});
model
.
remove
(
backupResource
);
});
}
discardAllWorkspaceBackups
():
Promise
<
void
>
{
async
discardAllWorkspaceBackups
():
Promise
<
void
>
{
this
.
isShuttingDown
=
true
;
return
this
.
ready
.
then
(
model
=>
{
return
pfs
.
rimraf
(
this
.
backupWorkspacePath
,
pfs
.
RimRafMode
.
MOVE
).
then
(()
=>
model
.
clear
());
});
const
model
=
await
this
.
ready
;
await
rimraf
(
this
.
backupWorkspacePath
,
RimRafMode
.
MOVE
);
model
.
clear
();
}
getWorkspaceFileBackups
():
Promise
<
Uri
[]
>
{
return
this
.
ready
.
then
(
model
=>
{
const
readPromises
:
Promise
<
Uri
>
[]
=
[];
async
getWorkspaceFileBackups
():
Promise
<
URI
[]
>
{
const
model
=
await
this
.
ready
;
const
backups
=
await
Promise
.
all
(
model
.
get
().
map
(
async
fileBackup
=>
{
const
backup
=
await
readToMatchingString
(
fileBackup
.
fsPath
,
BackupFileServiceImpl
.
META_MARKER
,
2000
,
10000
);
if
(
!
backup
)
{
return
undefined
;
}
model
.
get
().
forEach
(
fileBackup
=>
{
readPromises
.
push
(
readToMatchingString
(
fileBackup
.
fsPath
,
BackupFileServiceImpl
.
META_MARKER
,
2000
,
10000
).
then
(
Uri
.
parse
)
);
});
return
URI
.
parse
(
backup
);
}));
return
Promise
.
all
(
readPromises
);
});
return
coalesce
(
backups
);
}
resolveBackupContent
(
backup
:
Uri
):
Promise
<
ITextBufferFactory
>
{
return
this
.
fileService
.
readFileStream
(
backup
).
then
(
content
=>
{
async
resolveBackupContent
(
backup
:
URI
):
Promise
<
ITextBufferFactory
>
{
const
content
=
await
this
.
fileService
.
readFileStream
(
backup
);
// Add a filter method to filter out everything until the meta marker
let
metaFound
=
false
;
const
metaPreambleFilter
=
(
chunk
:
VSBuffer
)
=>
{
const
chunkString
=
chunk
.
toString
();
// Add a filter method to filter out everything until the meta marker
let
metaFound
=
false
;
const
metaPreambleFilter
=
(
chunk
:
VSBuffer
)
=>
{
const
chunkString
=
chunk
.
toString
();
if
(
!
metaFound
&&
chunk
)
{
const
metaIndex
=
chunkString
.
indexOf
(
BackupFileServiceImpl
.
META_MARKER
);
if
(
metaIndex
===
-
1
)
{
return
VSBuffer
.
fromString
(
''
);
// meta not yet found, return empty string
}
metaFound
=
true
;
return
VSBuffer
.
fromString
(
chunkString
.
substr
(
metaIndex
+
1
));
// meta found, return everything after
if
(
!
metaFound
&&
chunk
)
{
const
metaIndex
=
chunkString
.
indexOf
(
BackupFileServiceImpl
.
META_MARKER
);
if
(
metaIndex
===
-
1
)
{
return
VSBuffer
.
fromString
(
''
);
// meta not yet found, return empty string
}
return
chunk
;
};
metaFound
=
true
;
return
createTextBufferFactoryFromStream
(
content
.
value
,
metaPreambleFilter
);
});
return
VSBuffer
.
fromString
(
chunkString
.
substr
(
metaIndex
+
1
));
// meta found, return everything after
}
return
chunk
;
};
return
createTextBufferFactoryFromStream
(
content
.
value
,
metaPreambleFilter
);
}
toBackupResource
(
resource
:
U
ri
):
Uri
{
return
U
ri
.
file
(
path
.
join
(
this
.
backupWorkspacePath
,
resource
.
scheme
,
hashPath
(
resource
)));
toBackupResource
(
resource
:
U
RI
):
URI
{
return
U
RI
.
file
(
join
(
this
.
backupWorkspacePath
,
resource
.
scheme
,
hashPath
(
resource
)));
}
}
...
...
@@ -290,7 +297,7 @@ export class InMemoryBackupFileService implements IBackupFileService {
return
Promise
.
resolve
(
this
.
backups
.
size
>
0
);
}
loadBackupResource
(
resource
:
U
ri
):
Promise
<
Uri
|
undefined
>
{
loadBackupResource
(
resource
:
U
RI
):
Promise
<
URI
|
undefined
>
{
const
backupResource
=
this
.
toBackupResource
(
resource
);
if
(
this
.
backups
.
has
(
backupResource
.
toString
()))
{
return
Promise
.
resolve
(
backupResource
);
...
...
@@ -299,14 +306,14 @@ export class InMemoryBackupFileService implements IBackupFileService {
return
Promise
.
resolve
(
undefined
);
}
backupResource
(
resource
:
U
ri
,
content
:
ITextSnapshot
,
versionId
?:
number
):
Promise
<
void
>
{
backupResource
(
resource
:
U
RI
,
content
:
ITextSnapshot
,
versionId
?:
number
):
Promise
<
void
>
{
const
backupResource
=
this
.
toBackupResource
(
resource
);
this
.
backups
.
set
(
backupResource
.
toString
(),
content
);
return
Promise
.
resolve
();
}
resolveBackupContent
(
backupResource
:
U
ri
):
Promise
<
ITextBufferFactory
>
{
resolveBackupContent
(
backupResource
:
U
RI
):
Promise
<
ITextBufferFactory
>
{
const
snapshot
=
this
.
backups
.
get
(
backupResource
.
toString
());
if
(
snapshot
)
{
return
Promise
.
resolve
(
createTextBufferFactoryFromSnapshot
(
snapshot
));
...
...
@@ -315,11 +322,11 @@ export class InMemoryBackupFileService implements IBackupFileService {
return
Promise
.
reject
(
'
Unexpected backup resource to resolve
'
);
}
getWorkspaceFileBackups
():
Promise
<
U
ri
[]
>
{
return
Promise
.
resolve
(
keys
(
this
.
backups
).
map
(
key
=>
U
ri
.
parse
(
key
)));
getWorkspaceFileBackups
():
Promise
<
U
RI
[]
>
{
return
Promise
.
resolve
(
keys
(
this
.
backups
).
map
(
key
=>
U
RI
.
parse
(
key
)));
}
discardResourceBackup
(
resource
:
U
ri
):
Promise
<
void
>
{
discardResourceBackup
(
resource
:
U
RI
):
Promise
<
void
>
{
this
.
backups
.
delete
(
this
.
toBackupResource
(
resource
).
toString
());
return
Promise
.
resolve
();
...
...
@@ -331,17 +338,17 @@ export class InMemoryBackupFileService implements IBackupFileService {
return
Promise
.
resolve
();
}
toBackupResource
(
resource
:
U
ri
):
Uri
{
return
U
ri
.
file
(
path
.
join
(
resource
.
scheme
,
hashPath
(
resource
)));
toBackupResource
(
resource
:
U
RI
):
URI
{
return
U
RI
.
file
(
join
(
resource
.
scheme
,
hashPath
(
resource
)));
}
}
/*
* Exported only for testing
*/
export
function
hashPath
(
resource
:
U
ri
):
string
{
export
function
hashPath
(
resource
:
U
RI
):
string
{
const
str
=
resource
.
scheme
===
Schemas
.
file
||
resource
.
scheme
===
Schemas
.
untitled
?
resource
.
fsPath
:
resource
.
toString
();
return
cr
ypto
.
cr
eateHash
(
'
md5
'
).
update
(
str
).
digest
(
'
hex
'
);
return
createHash
(
'
md5
'
).
update
(
str
).
digest
(
'
hex
'
);
}
registerSingleton
(
IBackupFileService
,
BackupFileService
);
\ No newline at end of file
src/vs/workbench/services/backup/test/electron-browser/backupFileService.test.ts
浏览文件 @
94bb5390
...
...
@@ -70,15 +70,14 @@ class TestBackupFileService extends BackupFileService {
suite
(
'
BackupFileService
'
,
()
=>
{
let
service
:
TestBackupFileService
;
setup
(()
=>
{
setup
(
async
()
=>
{
service
=
new
TestBackupFileService
(
workspaceResource
,
backupHome
,
workspacesJsonPath
);
// Delete any existing backups completely and then re-create it.
return
pfs
.
rimraf
(
backupHome
,
pfs
.
RimRafMode
.
MOVE
).
then
(()
=>
{
return
pfs
.
mkdirp
(
backupHome
).
then
(()
=>
{
return
pfs
.
writeFile
(
workspacesJsonPath
,
''
);
});
});
await
pfs
.
rimraf
(
backupHome
,
pfs
.
RimRafMode
.
MOVE
);
await
pfs
.
mkdirp
(
backupHome
);
return
pfs
.
writeFile
(
workspacesJsonPath
,
''
);
});
teardown
(()
=>
{
...
...
@@ -131,183 +130,155 @@ suite('BackupFileService', () => {
});
suite
(
'
loadBackupResource
'
,
()
=>
{
test
(
'
should return whether a backup resource exists
'
,
()
=>
{
return
pfs
.
mkdirp
(
path
.
dirname
(
fooBackupPath
)).
then
(()
=>
{
fs
.
writeFileSync
(
fooBackupPath
,
'
foo
'
);
service
=
new
TestBackupFileService
(
workspaceResource
,
backupHome
,
workspacesJsonPath
);
return
service
.
loadBackupResource
(
fooFile
).
then
(
resource
=>
{
assert
.
ok
(
resource
);
assert
.
equal
(
path
.
basename
(
resource
!
.
fsPath
),
path
.
basename
(
fooBackupPath
));
return
service
.
hasBackups
().
then
(
hasBackups
=>
{
assert
.
ok
(
hasBackups
);
});
});
});
test
(
'
should return whether a backup resource exists
'
,
async
()
=>
{
await
pfs
.
mkdirp
(
path
.
dirname
(
fooBackupPath
));
fs
.
writeFileSync
(
fooBackupPath
,
'
foo
'
);
service
=
new
TestBackupFileService
(
workspaceResource
,
backupHome
,
workspacesJsonPath
);
const
resource
=
await
service
.
loadBackupResource
(
fooFile
);
assert
.
ok
(
resource
);
assert
.
equal
(
path
.
basename
(
resource
!
.
fsPath
),
path
.
basename
(
fooBackupPath
));
const
hasBackups
=
await
service
.
hasBackups
();
assert
.
ok
(
hasBackups
);
});
});
suite
(
'
backupResource
'
,
()
=>
{
test
(
'
text file
'
,
function
()
{
return
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
fooBackupPath
),
`
${
fooFile
.
toString
()}
\ntest`
);
});
test
(
'
text file
'
,
async
()
=>
{
await
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
fooBackupPath
),
`
${
fooFile
.
toString
()}
\ntest`
);
});
test
(
'
untitled file
'
,
function
()
{
return
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
untitledBackupPath
),
`
${
untitledFile
.
toString
()}
\ntest`
);
});
test
(
'
untitled file
'
,
async
()
=>
{
await
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
untitledBackupPath
),
`
${
untitledFile
.
toString
()}
\ntest`
);
});
test
(
'
text file (ITextSnapshot)
'
,
function
()
{
test
(
'
text file (ITextSnapshot)
'
,
async
()
=>
{
const
model
=
TextModel
.
createFromString
(
'
test
'
);
return
service
.
backupResource
(
fooFile
,
model
.
createSnapshot
()).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
fooBackupPath
),
`
${
fooFile
.
toString
()}
\ntest`
);
model
.
dispose
();
});
await
service
.
backupResource
(
fooFile
,
model
.
createSnapshot
());
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
fooBackupPath
),
`
${
fooFile
.
toString
()}
\ntest`
);
model
.
dispose
();
});
test
(
'
untitled file (ITextSnapshot)
'
,
function
()
{
test
(
'
untitled file (ITextSnapshot)
'
,
async
()
=>
{
const
model
=
TextModel
.
createFromString
(
'
test
'
);
return
service
.
backupResource
(
untitledFile
,
model
.
createSnapshot
()).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
untitledBackupPath
),
`
${
untitledFile
.
toString
()}
\ntest`
);
model
.
dispose
();
});
await
service
.
backupResource
(
untitledFile
,
model
.
createSnapshot
());
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
untitledBackupPath
),
`
${
untitledFile
.
toString
()}
\ntest`
);
model
.
dispose
();
});
test
(
'
text file (large file, ITextSnapshot)
'
,
function
()
{
test
(
'
text file (large file, ITextSnapshot)
'
,
async
()
=>
{
const
largeString
=
(
new
Array
(
10
*
1024
)).
join
(
'
Large String
\n
'
);
const
model
=
TextModel
.
createFromString
(
largeString
);
return
service
.
backupResource
(
fooFile
,
model
.
createSnapshot
()).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
fooBackupPath
),
`
${
fooFile
.
toString
()}
\n
${
largeString
}
`
);
model
.
dispose
();
});
await
service
.
backupResource
(
fooFile
,
model
.
createSnapshot
());
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
fooBackupPath
),
`
${
fooFile
.
toString
()}
\n
${
largeString
}
`
);
model
.
dispose
();
});
test
(
'
untitled file (large file, ITextSnapshot)
'
,
function
()
{
test
(
'
untitled file (large file, ITextSnapshot)
'
,
async
()
=>
{
const
largeString
=
(
new
Array
(
10
*
1024
)).
join
(
'
Large String
\n
'
);
const
model
=
TextModel
.
createFromString
(
largeString
);
return
service
.
backupResource
(
untitledFile
,
model
.
createSnapshot
()).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
untitledBackupPath
),
`
${
untitledFile
.
toString
()}
\n
${
largeString
}
`
);
model
.
dispose
();
});
await
service
.
backupResource
(
untitledFile
,
model
.
createSnapshot
());
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
true
);
assert
.
equal
(
fs
.
readFileSync
(
untitledBackupPath
),
`
${
untitledFile
.
toString
()}
\n
${
largeString
}
`
);
model
.
dispose
();
});
});
suite
(
'
discardResourceBackup
'
,
()
=>
{
test
(
'
text file
'
,
function
()
{
return
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
return
service
.
discardResourceBackup
(
fooFile
).
then
(()
=>
{
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
false
);
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
0
);
});
});
test
(
'
text file
'
,
async
()
=>
{
await
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
await
service
.
discardResourceBackup
(
fooFile
);
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
false
);
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
0
);
});
test
(
'
untitled file
'
,
function
()
{
return
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
return
service
.
discardResourceBackup
(
untitledFile
).
then
(()
=>
{
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
false
);
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
0
);
});
});
test
(
'
untitled file
'
,
async
()
=>
{
await
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
await
service
.
discardResourceBackup
(
untitledFile
);
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
false
);
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
0
);
});
});
suite
(
'
discardAllWorkspaceBackups
'
,
()
=>
{
test
(
'
text file
'
,
function
()
{
return
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
return
service
.
backupResource
(
barFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
2
);
return
service
.
discardAllWorkspaceBackups
().
then
(()
=>
{
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
false
);
assert
.
equal
(
fs
.
existsSync
(
barBackupPath
),
false
);
assert
.
equal
(
fs
.
existsSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)),
false
);
});
});
});
test
(
'
text file
'
,
async
()
=>
{
await
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
1
);
await
service
.
backupResource
(
barFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)).
length
,
2
);
await
service
.
discardAllWorkspaceBackups
();
assert
.
equal
(
fs
.
existsSync
(
fooBackupPath
),
false
);
assert
.
equal
(
fs
.
existsSync
(
barBackupPath
),
false
);
assert
.
equal
(
fs
.
existsSync
(
path
.
join
(
workspaceBackupPath
,
'
file
'
)),
false
);
});
test
(
'
untitled file
'
,
function
()
{
return
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
return
service
.
discardAllWorkspaceBackups
().
then
(()
=>
{
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
false
);
assert
.
equal
(
fs
.
existsSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)),
false
);
});
});
test
(
'
untitled file
'
,
async
()
=>
{
await
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
assert
.
equal
(
fs
.
readdirSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)).
length
,
1
);
await
service
.
discardAllWorkspaceBackups
();
assert
.
equal
(
fs
.
existsSync
(
untitledBackupPath
),
false
);
assert
.
equal
(
fs
.
existsSync
(
path
.
join
(
workspaceBackupPath
,
'
untitled
'
)),
false
);
});
test
(
'
should disable further backups
'
,
function
()
{
return
service
.
discardAllWorkspaceBackups
().
then
(()
=>
{
return
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
assert
.
equal
(
fs
.
existsSync
(
workspaceBackupPath
),
false
);
});
});
test
(
'
should disable further backups
'
,
async
()
=>
{
await
service
.
discardAllWorkspaceBackups
();
await
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
assert
.
equal
(
fs
.
existsSync
(
workspaceBackupPath
),
false
);
});
});
suite
(
'
getWorkspaceFileBackups
'
,
()
=>
{
test
(
'
("file") - text file
'
,
()
=>
{
return
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
return
service
.
getWorkspaceFileBackups
().
then
(
textFiles
=>
{
assert
.
deepEqual
(
textFiles
.
map
(
f
=>
f
.
fsPath
),
[
fooFile
.
fsPath
]);
return
service
.
backupResource
(
barFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
return
service
.
getWorkspaceFileBackups
().
then
(
textFiles
=>
{
assert
.
deepEqual
(
textFiles
.
map
(
f
=>
f
.
fsPath
),
[
fooFile
.
fsPath
,
barFile
.
fsPath
]);
});
});
});
});
test
(
'
("file") - text file
'
,
async
()
=>
{
await
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
const
textFiles
=
await
service
.
getWorkspaceFileBackups
();
assert
.
deepEqual
(
textFiles
.
map
(
f
=>
f
.
fsPath
),
[
fooFile
.
fsPath
]);
await
service
.
backupResource
(
barFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
const
textFiles_1
=
await
service
.
getWorkspaceFileBackups
();
assert
.
deepEqual
(
textFiles_1
.
map
(
f
=>
f
.
fsPath
),
[
fooFile
.
fsPath
,
barFile
.
fsPath
]);
});
test
(
'
("file") - untitled file
'
,
()
=>
{
return
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
return
service
.
getWorkspaceFileBackups
().
then
(
textFiles
=>
{
assert
.
deepEqual
(
textFiles
.
map
(
f
=>
f
.
fsPath
),
[
untitledFile
.
fsPath
]);
});
});
test
(
'
("file") - untitled file
'
,
async
()
=>
{
await
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
const
textFiles
=
await
service
.
getWorkspaceFileBackups
();
assert
.
deepEqual
(
textFiles
.
map
(
f
=>
f
.
fsPath
),
[
untitledFile
.
fsPath
]);
});
test
(
'
("untitled") - untitled file
'
,
()
=>
{
return
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
return
service
.
getWorkspaceFileBackups
().
then
(
textFiles
=>
{
assert
.
deepEqual
(
textFiles
.
map
(
f
=>
f
.
fsPath
),
[
'
Untitled-1
'
]);
});
});
test
(
'
("untitled") - untitled file
'
,
async
()
=>
{
await
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
'
test
'
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
const
textFiles
=
await
service
.
getWorkspaceFileBackups
();
assert
.
deepEqual
(
textFiles
.
map
(
f
=>
f
.
fsPath
),
[
'
Untitled-1
'
]);
});
});
test
(
'
resolveBackupContent
'
,
()
=>
{
test
(
'
should restore the original contents (untitled file)
'
,
()
=>
{
test
(
'
should restore the original contents (untitled file)
'
,
async
()
=>
{
const
contents
=
'
test
\n
and more stuff
'
;
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
contents
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
service
.
resolveBackupContent
(
service
.
toBackupResource
(
untitledFile
)).
then
(
factory
=>
{
assert
.
equal
(
contents
,
snapshotToString
(
factory
.
create
(
platform
.
isWindows
?
DefaultEndOfLine
.
CRLF
:
DefaultEndOfLine
.
LF
).
createSnapshot
(
true
)));
}
);
}
);
await
service
.
backupResource
(
untitledFile
,
createTextBufferFactory
(
contents
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
const
factory
=
await
service
.
resolveBackupContent
(
service
.
toBackupResource
(
untitledFile
)
);
assert
.
equal
(
contents
,
snapshotToString
(
factory
.
create
(
platform
.
isWindows
?
DefaultEndOfLine
.
CRLF
:
DefaultEndOfLine
.
LF
).
createSnapshot
(
true
))
);
});
test
(
'
should restore the original contents (text file)
'
,
()
=>
{
test
(
'
should restore the original contents (text file)
'
,
async
()
=>
{
const
contents
=
[
'
Lorem ipsum
'
,
'
dolor öäü sit amet
'
,
...
...
@@ -315,11 +286,10 @@ suite('BackupFileService', () => {
'
adipiscing ßß elit
'
,
].
join
(
''
);
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
contents
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
)).
then
(()
=>
{
service
.
resolveBackupContent
(
service
.
toBackupResource
(
untitledFile
)).
then
(
factory
=>
{
assert
.
equal
(
contents
,
snapshotToString
(
factory
.
create
(
platform
.
isWindows
?
DefaultEndOfLine
.
CRLF
:
DefaultEndOfLine
.
LF
).
createSnapshot
(
true
)));
});
});
await
service
.
backupResource
(
fooFile
,
createTextBufferFactory
(
contents
).
create
(
DefaultEndOfLine
.
LF
).
createSnapshot
(
false
));
const
factory
=
await
service
.
resolveBackupContent
(
service
.
toBackupResource
(
untitledFile
));
assert
.
equal
(
contents
,
snapshotToString
(
factory
.
create
(
platform
.
isWindows
?
DefaultEndOfLine
.
CRLF
:
DefaultEndOfLine
.
LF
).
createSnapshot
(
true
)));
});
});
});
...
...
@@ -372,16 +342,13 @@ suite('BackupFilesModel', () => {
assert
.
equal
(
model
.
has
(
resource4
),
true
);
});
test
(
'
resolve
'
,
()
=>
{
return
pfs
.
mkdirp
(
path
.
dirname
(
fooBackupPath
)).
then
(()
=>
{
fs
.
writeFileSync
(
fooBackupPath
,
'
foo
'
);
const
model
=
new
BackupFilesModel
();
test
(
'
resolve
'
,
async
()
=>
{
await
pfs
.
mkdirp
(
path
.
dirname
(
fooBackupPath
));
fs
.
writeFileSync
(
fooBackupPath
,
'
foo
'
);
const
model
=
new
BackupFilesModel
();
return
model
.
resolve
(
workspaceBackupPath
).
then
(
model
=>
{
assert
.
equal
(
model
.
has
(
Uri
.
file
(
fooBackupPath
)),
true
);
});
});
const
resolvedModel
=
await
model
.
resolve
(
workspaceBackupPath
);
assert
.
equal
(
resolvedModel
.
has
(
Uri
.
file
(
fooBackupPath
)),
true
);
});
test
(
'
get
'
,
()
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录