Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/test/node/snapshot.test.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as fs from 'fs';
7
import { tmpdir } from 'os';
8
import { getRandomTestPath } from './testUtils.js';
9
import { Promises } from '../../node/pfs.js';
10
import { SnapshotContext, assertSnapshot } from '../common/snapshot.js';
11
import { URI } from '../../common/uri.js';
12
import { join } from '../../common/path.js';
13
import { assertThrowsAsync, ensureNoDisposablesAreLeakedInTestSuite } from '../common/utils.js';
14
15
// tests for snapshot are in Node so that we can use native FS operations to
16
// set up and validate things.
17
//
18
// Uses snapshots for testing snapshots. It's snapception!
19
20
suite('snapshot', () => {
21
let testDir: string;
22
23
ensureNoDisposablesAreLeakedInTestSuite();
24
25
setup(function () {
26
testDir = getRandomTestPath(tmpdir(), 'vsctests', 'snapshot');
27
return fs.promises.mkdir(testDir, { recursive: true });
28
});
29
30
teardown(function () {
31
return Promises.rm(testDir);
32
});
33
34
const makeContext = (test: Partial<Mocha.Test> | undefined) => {
35
return new class extends SnapshotContext {
36
constructor() {
37
super(test as Mocha.Test);
38
this.snapshotsDir = URI.file(testDir);
39
}
40
};
41
};
42
43
const snapshotFileTree = async () => {
44
let str = '';
45
46
const printDir = async (dir: string, indent: number) => {
47
const children = await Promises.readdir(dir);
48
for (const child of children) {
49
const p = join(dir, child);
50
if ((await fs.promises.stat(p)).isFile()) {
51
const content = await fs.promises.readFile(p, 'utf-8');
52
str += `${' '.repeat(indent)}${child}:\n`;
53
for (const line of content.split('\n')) {
54
str += `${' '.repeat(indent + 2)}${line}\n`;
55
}
56
} else {
57
str += `${' '.repeat(indent)}${child}/\n`;
58
await printDir(p, indent + 2);
59
}
60
}
61
};
62
63
await printDir(testDir, 0);
64
await assertSnapshot(str);
65
};
66
67
test('creates a snapshot', async () => {
68
const ctx = makeContext({
69
file: 'foo/bar',
70
fullTitle: () => 'hello world!'
71
});
72
73
await ctx.assert({ cool: true });
74
await snapshotFileTree();
75
});
76
77
test('validates a snapshot', async () => {
78
const ctx1 = makeContext({
79
file: 'foo/bar',
80
fullTitle: () => 'hello world!'
81
});
82
83
await ctx1.assert({ cool: true });
84
85
const ctx2 = makeContext({
86
file: 'foo/bar',
87
fullTitle: () => 'hello world!'
88
});
89
90
// should pass:
91
await ctx2.assert({ cool: true });
92
93
const ctx3 = makeContext({
94
file: 'foo/bar',
95
fullTitle: () => 'hello world!'
96
});
97
98
// should fail:
99
await assertThrowsAsync(() => ctx3.assert({ cool: false }));
100
});
101
102
test('cleans up old snapshots', async () => {
103
const ctx1 = makeContext({
104
file: 'foo/bar',
105
fullTitle: () => 'hello world!'
106
});
107
108
await ctx1.assert({ cool: true });
109
await ctx1.assert({ nifty: true });
110
await ctx1.assert({ customName: 1 }, { name: 'thirdTest', extension: 'txt' });
111
await ctx1.assert({ customName: 2 }, { name: 'fourthTest' });
112
113
await snapshotFileTree();
114
115
const ctx2 = makeContext({
116
file: 'foo/bar',
117
fullTitle: () => 'hello world!'
118
});
119
120
await ctx2.assert({ cool: true });
121
await ctx2.assert({ customName: 1 }, { name: 'thirdTest' });
122
await ctx2.removeOldSnapshots();
123
124
await snapshotFileTree();
125
});
126
127
test('formats object nicely', async () => {
128
const circular: any = {};
129
circular.a = circular;
130
131
await assertSnapshot([
132
1,
133
true,
134
undefined,
135
null,
136
123n,
137
Symbol('heyo'),
138
'hello',
139
{ hello: 'world' },
140
circular,
141
new Map([['hello', 1], ['goodbye', 2]]),
142
new Set([1, 2, 3]),
143
function helloWorld() { },
144
/hello/g,
145
new Array(10).fill('long string'.repeat(10)),
146
{ [Symbol.for('debug.description')]() { return `Range [1 -> 5]`; } },
147
]);
148
});
149
});
150
151