Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/svnRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export class Repository {
return await parseStatusXml(result.stdout);
}

resetInfo() {
this._info = undefined;
}

async getInfo(): Promise<ISvnInfo> {
if (this._info) {
return this._info;
Expand All @@ -28,7 +32,7 @@ export class Repository {

//Cache for 30 seconds
setTimeout(() => {
this._info = undefined;
this.resetInfo();
}, 30000);

return this._info;
Expand Down Expand Up @@ -210,6 +214,8 @@ export class Repository {
throw new Error(switchBranch.stderr);
}

this.resetInfo();

return true;
}

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

this.resetInfo();

return true;
}

Expand Down
44 changes: 27 additions & 17 deletions src/test/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,40 @@ import { SvnFinder } from "../svnFinder";

// Defines a Mocha test suite to group tests of similar kind together
suite("Extension Tests", () => {

//Before Each
setup(async () => {
});
setup(async () => {});

teardown(() => {
testUtil.destroyAllTempPaths();
});

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

test("Try Open Repository", async () => {
const repoUrl = await testUtil.createRepoServer();
await testUtil.createStandardLayout(repoUrl);
const checkoutDir = await testUtil.createRepoCheckout(repoUrl + "/trunk");

const svnFinder = new SvnFinder();
const info = await svnFinder.findSvn();
const svn = new Svn({ svnPath: info.path, version: info.version });
const model = new Model(svn);
await model.tryOpenRepository(checkoutDir);
model.dispose();
// The extension is already activated by vscode before running mocha test framework.
// No need to test activate any more. So commenting this case.
// tslint:disable-next-line: only-arrow-functions
test("should be able to activate the extension", function(done) {
this.timeout(60 * 1000);
const extension = vscode.extensions.getExtension("johnstoncode.svn-scm");

if (!extension) {
done("Extension not found");
return;
}

if (!extension.isActive) {
extension.activate().then(
api => {
done();
},
() => {
done("Failed to activate extension");
}
);
} else {
done();
}
});
});
144 changes: 144 additions & 0 deletions src/test/repository.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
//
// Note: This example test is leveraging the Mocha test framework.
// Please refer to their documentation on https://mochajs.org/ for help.
//

// The module 'assert' provides assertion methods from node
import * as assert from "assert";

// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
import * as fs from "fs";
import * as path from "path";
import * as vscode from "vscode";
import * as testUtil from "./testUtil";
import { Uri } from "vscode";
import { Svn } from "../svn";
import { Model } from "../model";
import { SvnFinder, ISvn } from "../svnFinder";
import { Repository } from "../repository";

// Defines a Mocha test suite to group tests of similar kind together
suite("Repository Tests", () => {
let repoUri: Uri;
let checkoutDir: Uri;
let svnFinder: SvnFinder;
let info: ISvn;
let svn: Svn;
let model: Model;

suiteSetup(async () => {
repoUri = await testUtil.createRepoServer();
await testUtil.createStandardLayout(testUtil.getSvnUrl(repoUri));
checkoutDir = await testUtil.createRepoCheckout(
testUtil.getSvnUrl(repoUri) + "/trunk"
);

svnFinder = new SvnFinder();
info = await svnFinder.findSvn();
svn = new Svn({ svnPath: info.path, version: info.version });
model = new Model(svn);
await model.tryOpenRepository(checkoutDir.fsPath);
});

suiteTeardown(() => {
testUtil.destroyAllTempPaths();
});

test("Find Repository", async () => {
assert.ok(info);
assert.ok(info.path);
assert.ok(info.version);
});

test("Try Open Repository", async function() {
assert.equal(model.repositories.length, 1);
});

test("Try Open Repository Again", async () => {
await model.tryOpenRepository(checkoutDir.fsPath);
assert.equal(model.repositories.length, 1);
});

test("Try get repository from Uri", () => {
const repository = model.getRepository(checkoutDir);
assert.ok(repository);
});

test("Try get repository from string", () => {
const repository = model.getRepository(checkoutDir.fsPath);
assert.ok(repository);
});

test("Try get repository from repository", () => {
const repository = model.getRepository(checkoutDir.fsPath);
const repository2 = model.getRepository(repository);
assert.ok(repository2);
assert.equal(repository, repository2);
});

test("Try get current branch name", async () => {
const repository: Repository | undefined = model.getRepository(
checkoutDir.fsPath
);
if (!repository) return;

const name = await repository.getCurrentBranch();
assert.equal(name, "trunk");
});

test("Try commit file", async function() {
this.timeout(60000);
const repository: Repository | undefined = model.getRepository(
checkoutDir.fsPath
);
if (!repository) return;

assert.equal(repository.changes.resourceStates.length, 0);

const file = path.join(checkoutDir.fsPath, "new.txt");

await repository.update();
fs.writeFileSync(file, "test");

await repository.addFile(file);

await repository.update();
await testUtil.delay(1500); //Wait the debounce time
assert.equal(repository.changes.resourceStates.length, 1);

const message = await repository.repository.commitFiles("First Commit", [
file
]);
assert.ok(/Committed revision (.*)\./i.test(message));

await repository.update();
await testUtil.delay(1500); //Wait the debounce time
assert.equal(repository.changes.resourceStates.length, 0);

const remoteContent = await repository.show(file, "HEAD");
assert.equal(remoteContent, "test");
});

test("Try switch branch", async function() {
this.timeout(60000);
const newCheckoutDir = await testUtil.createRepoCheckout(
testUtil.getSvnUrl(repoUri) + "/trunk"
);

await model.tryOpenRepository(newCheckoutDir.fsPath);

const newRepository: Repository | undefined = model.getRepository(
newCheckoutDir.fsPath
);
if (!newRepository) return;
assert.ok(newRepository);

const isSwitched = await newRepository.branch("test");
assert.ok(isSwitched);

const currentBranch = await newRepository.getCurrentBranch();

assert.equal(currentBranch, "test");
});
});
33 changes: 23 additions & 10 deletions src/test/testUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ import { SpawnOptions, ChildProcess } from "child_process";
const tempDir = os.tmpdir();
var tempDirList: string[] = [];

export function getSvnUrl(uri: Uri) {
const url = uri.toString();

return url.replace(/%3A/g, ":");
}

export function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

export function spawn(
command: string,
args?: string[],
Expand Down Expand Up @@ -46,7 +56,7 @@ export function newTempDir(prefix: string) {
}

export function createRepoServer() {
return new Promise<string>((resolve, reject) => {
return new Promise<Uri>((resolve, reject) => {
const fullpath = newTempDir("svn_server_");
const dirname = path.basename(fullpath);

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

proc.once("exit", exitCode => {
if (exitCode === 0) {
const url = "file:///" + fullpath.replace(/\\/g, "/");
resolve(url);
resolve(Uri.file(fullpath));
}
reject();
});
Expand Down Expand Up @@ -105,21 +114,21 @@ export async function createStandardLayout(
}

export function createRepoCheckout(url: string) {
return new Promise<string>((resolve, reject) => {
return new Promise<Uri>((resolve, reject) => {
const fullpath = newTempDir("svn_checkout_");

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

proc.once("exit", exitCode => {
if (exitCode === 0) {
resolve(fullpath);
resolve(Uri.file(fullpath));
}
reject();
});
});
}

export function destroyPath(fullPath: string) {
export async function destroyPath(fullPath: string) {
fullPath = fullPath.replace(/^file\:\/\/\//, "");

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

//Error in windows with anti-malware
try {
fs.rmdirSync(fullPath);
} catch (error) {
console.error(error);
for (let i = 0; i < 3; i++) {
try {
fs.rmdirSync(fullPath);
break;
} catch (error) {
await delay(3000);
console.error(error);
}
}
return true;
}
Expand Down