Skip to content

Commit 8cf483a

Browse files
committed
Added tests for repository
1 parent 469ce60 commit 8cf483a

File tree

4 files changed

+203
-28
lines changed

4 files changed

+203
-28
lines changed

src/svnRepository.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ export class Repository {
1818
return await parseStatusXml(result.stdout);
1919
}
2020

21+
resetInfo() {
22+
this._info = undefined;
23+
}
24+
2125
async getInfo(): Promise<ISvnInfo> {
2226
if (this._info) {
2327
return this._info;
@@ -28,7 +32,7 @@ export class Repository {
2832

2933
//Cache for 30 seconds
3034
setTimeout(() => {
31-
this._info = undefined;
35+
this.resetInfo();
3236
}, 30000);
3337

3438
return this._info;
@@ -210,6 +214,8 @@ export class Repository {
210214
throw new Error(switchBranch.stderr);
211215
}
212216

217+
this.resetInfo();
218+
213219
return true;
214220
}
215221

@@ -227,6 +233,8 @@ export class Repository {
227233
throw new Error(switchBranch.stderr);
228234
}
229235

236+
this.resetInfo();
237+
230238
return true;
231239
}
232240

src/test/extension.test.ts

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,40 @@ import { SvnFinder } from "../svnFinder";
1717

1818
// Defines a Mocha test suite to group tests of similar kind together
1919
suite("Extension Tests", () => {
20-
2120
//Before Each
22-
setup(async () => {
23-
});
21+
setup(async () => {});
2422

2523
teardown(() => {
2624
testUtil.destroyAllTempPaths();
2725
});
2826

29-
test("Find Repository", async () => {
30-
const svnFinder = new SvnFinder();
31-
const info = await svnFinder.findSvn();
27+
test("should be present", () => {
28+
assert.ok(vscode.extensions.getExtension("johnstoncode.svn-scm"));
3229
});
3330

34-
test("Try Open Repository", async () => {
35-
const repoUrl = await testUtil.createRepoServer();
36-
await testUtil.createStandardLayout(repoUrl);
37-
const checkoutDir = await testUtil.createRepoCheckout(repoUrl + "/trunk");
38-
39-
const svnFinder = new SvnFinder();
40-
const info = await svnFinder.findSvn();
41-
const svn = new Svn({ svnPath: info.path, version: info.version });
42-
const model = new Model(svn);
43-
await model.tryOpenRepository(checkoutDir);
44-
model.dispose();
31+
// The extension is already activated by vscode before running mocha test framework.
32+
// No need to test activate any more. So commenting this case.
33+
// tslint:disable-next-line: only-arrow-functions
34+
test("should be able to activate the extension", function(done) {
35+
this.timeout(60 * 1000);
36+
const extension = vscode.extensions.getExtension("johnstoncode.svn-scm");
37+
38+
if (!extension) {
39+
done("Extension not found");
40+
return;
41+
}
42+
43+
if (!extension.isActive) {
44+
extension.activate().then(
45+
api => {
46+
done();
47+
},
48+
() => {
49+
done("Failed to activate extension");
50+
}
51+
);
52+
} else {
53+
done();
54+
}
4555
});
4656
});

src/test/repository.test.ts

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
//
2+
// Note: This example test is leveraging the Mocha test framework.
3+
// Please refer to their documentation on https://mochajs.org/ for help.
4+
//
5+
6+
// The module 'assert' provides assertion methods from node
7+
import * as assert from "assert";
8+
9+
// You can import and use all API from the 'vscode' module
10+
// as well as import your extension to test it
11+
import * as fs from "fs";
12+
import * as path from "path";
13+
import * as vscode from "vscode";
14+
import * as testUtil from "./testUtil";
15+
import { Uri } from "vscode";
16+
import { Svn } from "../svn";
17+
import { Model } from "../model";
18+
import { SvnFinder, ISvn } from "../svnFinder";
19+
import { Repository } from "../repository";
20+
21+
// Defines a Mocha test suite to group tests of similar kind together
22+
suite("Repository Tests", () => {
23+
let repoUri: Uri;
24+
let checkoutDir: Uri;
25+
let svnFinder: SvnFinder;
26+
let info: ISvn;
27+
let svn: Svn;
28+
let model: Model;
29+
30+
suiteSetup(async () => {
31+
repoUri = await testUtil.createRepoServer();
32+
await testUtil.createStandardLayout(testUtil.getSvnUrl(repoUri));
33+
checkoutDir = await testUtil.createRepoCheckout(
34+
testUtil.getSvnUrl(repoUri) + "/trunk"
35+
);
36+
37+
svnFinder = new SvnFinder();
38+
info = await svnFinder.findSvn();
39+
svn = new Svn({ svnPath: info.path, version: info.version });
40+
model = new Model(svn);
41+
await model.tryOpenRepository(checkoutDir.fsPath);
42+
});
43+
44+
suiteTeardown(() => {
45+
testUtil.destroyAllTempPaths();
46+
});
47+
48+
test("Find Repository", async () => {
49+
assert.ok(info);
50+
assert.ok(info.path);
51+
assert.ok(info.version);
52+
});
53+
54+
test("Try Open Repository", async function() {
55+
assert.equal(model.repositories.length, 1);
56+
});
57+
58+
test("Try Open Repository Again", async () => {
59+
await model.tryOpenRepository(checkoutDir.fsPath);
60+
assert.equal(model.repositories.length, 1);
61+
});
62+
63+
test("Try get repository from Uri", () => {
64+
const repository = model.getRepository(checkoutDir);
65+
assert.ok(repository);
66+
});
67+
68+
test("Try get repository from string", () => {
69+
const repository = model.getRepository(checkoutDir.fsPath);
70+
assert.ok(repository);
71+
});
72+
73+
test("Try get repository from repository", () => {
74+
const repository = model.getRepository(checkoutDir.fsPath);
75+
const repository2 = model.getRepository(repository);
76+
assert.ok(repository2);
77+
assert.equal(repository, repository2);
78+
});
79+
80+
test("Try get current branch name", async () => {
81+
const repository: Repository | undefined = model.getRepository(
82+
checkoutDir.fsPath
83+
);
84+
if (!repository) return;
85+
86+
const name = await repository.getCurrentBranch();
87+
assert.equal(name, "trunk");
88+
});
89+
90+
test("Try commit file", async function() {
91+
this.timeout(60000);
92+
const repository: Repository | undefined = model.getRepository(
93+
checkoutDir.fsPath
94+
);
95+
if (!repository) return;
96+
97+
assert.equal(repository.changes.resourceStates.length, 0);
98+
99+
const file = path.join(checkoutDir.fsPath, "new.txt");
100+
101+
await repository.update();
102+
fs.writeFileSync(file, "test");
103+
104+
await repository.addFile(file);
105+
106+
await repository.update();
107+
await testUtil.delay(1500); //Wait the debounce time
108+
assert.equal(repository.changes.resourceStates.length, 1);
109+
110+
const message = await repository.repository.commitFiles("First Commit", [
111+
file
112+
]);
113+
assert.ok(/Committed revision (.*)\./i.test(message));
114+
115+
await repository.update();
116+
await testUtil.delay(1500); //Wait the debounce time
117+
assert.equal(repository.changes.resourceStates.length, 0);
118+
119+
const remoteContent = await repository.show(file, "HEAD");
120+
assert.equal(remoteContent, "test");
121+
});
122+
123+
test("Try switch branch", async function() {
124+
this.timeout(60000);
125+
const newCheckoutDir = await testUtil.createRepoCheckout(
126+
testUtil.getSvnUrl(repoUri) + "/trunk"
127+
);
128+
129+
await model.tryOpenRepository(newCheckoutDir.fsPath);
130+
131+
const newRepository: Repository | undefined = model.getRepository(
132+
newCheckoutDir.fsPath
133+
);
134+
if (!newRepository) return;
135+
assert.ok(newRepository);
136+
137+
const isSwitched = await newRepository.branch("test");
138+
assert.ok(isSwitched);
139+
140+
const currentBranch = await newRepository.getCurrentBranch();
141+
142+
assert.equal(currentBranch, "test");
143+
});
144+
});

src/test/testUtil.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ import { SpawnOptions, ChildProcess } from "child_process";
88
const tempDir = os.tmpdir();
99
var tempDirList: string[] = [];
1010

11+
export function getSvnUrl(uri: Uri) {
12+
const url = uri.toString();
13+
14+
return url.replace(/%3A/g, ":");
15+
}
16+
17+
export function delay(ms: number) {
18+
return new Promise(resolve => setTimeout(resolve, ms));
19+
}
20+
1121
export function spawn(
1222
command: string,
1323
args?: string[],
@@ -46,7 +56,7 @@ export function newTempDir(prefix: string) {
4656
}
4757

4858
export function createRepoServer() {
49-
return new Promise<string>((resolve, reject) => {
59+
return new Promise<Uri>((resolve, reject) => {
5060
const fullpath = newTempDir("svn_server_");
5161
const dirname = path.basename(fullpath);
5262

@@ -58,8 +68,7 @@ export function createRepoServer() {
5868

5969
proc.once("exit", exitCode => {
6070
if (exitCode === 0) {
61-
const url = "file:///" + fullpath.replace(/\\/g, "/");
62-
resolve(url);
71+
resolve(Uri.file(fullpath));
6372
}
6473
reject();
6574
});
@@ -105,21 +114,21 @@ export async function createStandardLayout(
105114
}
106115

107116
export function createRepoCheckout(url: string) {
108-
return new Promise<string>((resolve, reject) => {
117+
return new Promise<Uri>((resolve, reject) => {
109118
const fullpath = newTempDir("svn_checkout_");
110119

111120
let proc = spawn("svn", ["checkout", url, fullpath], { cwd: tempDir });
112121

113122
proc.once("exit", exitCode => {
114123
if (exitCode === 0) {
115-
resolve(fullpath);
124+
resolve(Uri.file(fullpath));
116125
}
117126
reject();
118127
});
119128
});
120129
}
121130

122-
export function destroyPath(fullPath: string) {
131+
export async function destroyPath(fullPath: string) {
123132
fullPath = fullPath.replace(/^file\:\/\/\//, "");
124133

125134
if (!fs.existsSync(fullPath)) {
@@ -137,10 +146,14 @@ export function destroyPath(fullPath: string) {
137146
}
138147

139148
//Error in windows with anti-malware
140-
try {
141-
fs.rmdirSync(fullPath);
142-
} catch (error) {
143-
console.error(error);
149+
for (let i = 0; i < 3; i++) {
150+
try {
151+
fs.rmdirSync(fullPath);
152+
break;
153+
} catch (error) {
154+
await delay(3000);
155+
console.error(error);
156+
}
144157
}
145158
return true;
146159
}

0 commit comments

Comments
 (0)