Skip to content

Commit

Permalink
Initial tests for project management
Browse files Browse the repository at this point in the history
  • Loading branch information
khawkins committed Jun 15, 2023
1 parent 3f4b943 commit 164d3c1
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/commands/configureProjectCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export class ConfigureProjectCommand {
});
}

private async createNewProject(panel?: WebviewPanel): Promise<string> {
async createNewProject(panel?: WebviewPanel): Promise<string> {
return new Promise(async (resolve, reject) => {
const folderUri =
await this.projectConfigurationProcessor.getProjectFolderPath();
Expand All @@ -155,7 +155,7 @@ export class ConfigureProjectCommand {
});
}

private async openExistingProject(panel?: WebviewPanel): Promise<string> {
async openExistingProject(panel?: WebviewPanel): Promise<string> {
return new Promise(async (resolve) => {
const folderUri =
await this.projectConfigurationProcessor.getProjectFolderPath();
Expand Down Expand Up @@ -187,7 +187,7 @@ export class ConfigureProjectCommand {
});
}

private async executeProjectCreation(folderUri: Uri): Promise<string> {
async executeProjectCreation(folderUri: Uri): Promise<string> {
return new Promise(async (resolve) => {
const githubRepoUri: string =
'https://github.com/salesforce/offline-app-developer-starter-kit.git';
Expand All @@ -200,7 +200,7 @@ export class ConfigureProjectCommand {
});
}

private async validateProjectFolder(projectFolderUri: Uri): Promise<void> {
async validateProjectFolder(projectFolderUri: Uri): Promise<void> {
return new Promise(async (resolve, reject) => {
const origWorkingDir = process.cwd();
try {
Expand Down
41 changes: 41 additions & 0 deletions src/test/TestHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Stats } from 'fs';
import { mkdtemp, rm, stat } from 'fs/promises';
import * as os from 'os';
import * as path from 'path';
import * as process from 'process';

export async function createTempProjectDir(): Promise<string> {
return new Promise(async (resolve, reject) => {
try {
const projectDir = await mkdtemp(
path.join(os.tmpdir(), 'offlineWizard-')
);
return resolve(projectDir);
} catch (err) {
return reject(err);
}
});
}

export async function removeTempProjectDir(projectDir: string): Promise<void> {
return new Promise(async (resolve, reject) => {
let projectDirStats: Stats;
try {
projectDirStats = await stat(projectDir);
} catch (err) {
return reject(
`Project dir '${projectDir}' does not exist or is inaccessible.`
);
}
if (!projectDirStats.isDirectory()) {
return reject(`Project dir '${projectDir}' is not a directory.`);
}
return rm(projectDir, { recursive: true, force: true });
});
}

// Create a platform-agnostic absolute path to a non-existent folder.
export function createNonExistentAbsolutePath(): string {
const topLevel = path.parse(process.cwd()).root;
return path.join(topLevel, 'starter-kit-tests', 'path', 'to', 'nowhere');
}
152 changes: 149 additions & 3 deletions src/test/suite/commands/configureProjectCommand.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,20 @@
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/

import * as sinon from 'sinon';
import * as assert from 'assert';
import { writeFile } from 'fs/promises';
import { afterEach, beforeEach } from 'mocha';
import * as path from 'path';
import * as process from 'process';
import { CommonUtils } from '@salesforce/lwc-dev-mobile-core/lib/common/CommonUtils';
import * as sinon from 'sinon';
import { l10n, Uri } from 'vscode';
import { ConfigureProjectCommand } from '../../../commands/configureProjectCommand';
import {
createTempProjectDir,
createNonExistentAbsolutePath,
removeTempProjectDir
} from '../../TestHelper';

suite('Configure Project Command Test Suite', () => {
beforeEach(function () {});
Expand All @@ -15,7 +27,141 @@ suite('Configure Project Command Test Suite', () => {
sinon.restore();
});

test.skip('TODO', async () => {
// TODO
test('Open Project: Non-existent folder is an error', async () => {
const origCwd = process.cwd();
const extensionUri = Uri.file('whateva');
const nonExistentFolderUri = Uri.file(createNonExistentAbsolutePath());
try {
await new ConfigureProjectCommand(
extensionUri
).validateProjectFolder(nonExistentFolderUri);
assert.fail('Validation should fail on a non-existent folder.');
} catch (err) {
assert.equal(
(err as Error).message,
l10n.t(
"Could not access the project folder at '{0}'.",
nonExistentFolderUri.fsPath
)
);
} finally {
assert.equal(origCwd, process.cwd());
}
});

test('Open Project: No git installed is an error', async () => {
const origCwd = process.cwd();
const extensionUri = Uri.file('whateva');
const projectFolderUri = Uri.file(await createTempProjectDir());
const cmdStub = sinon.stub(CommonUtils, 'executeCommandAsync');
cmdStub.onCall(0).rejects();
try {
await new ConfigureProjectCommand(
extensionUri
).validateProjectFolder(projectFolderUri);
assert.fail('Validation should fail if git is not installed.');
} catch (err) {
assert.equal(
(err as Error).message,
l10n.t('git is not installed.')
);
} finally {
cmdStub.restore();
assert.equal(origCwd, process.cwd());
removeTempProjectDir(projectFolderUri.fsPath);
}
});

test('Open Project: Project is not a git repo', async () => {
const origCwd = process.cwd();
const extensionUri = Uri.file('whateva');
const projectFolderUri = Uri.file(await createTempProjectDir());

try {
await new ConfigureProjectCommand(
extensionUri
).validateProjectFolder(projectFolderUri);
assert.fail(
'Validation should fail if project dir is not a git repo.'
);
} catch (err) {
assert.equal(
(err as Error).message,
l10n.t(
"Folder '{0}' does not contain a git repository.",
projectFolderUri.fsPath
)
);
} finally {
assert.equal(origCwd, process.cwd());
removeTempProjectDir(projectFolderUri.fsPath);
}
});

test('Open Project: Project is not the Starter Kit git repo', async () => {
const origCwd = process.cwd();
const extensionUri = Uri.file('whateva');
const projectFolderUri = Uri.file(await createTempProjectDir());

// Create a skeleton git repo
process.chdir(projectFolderUri.fsPath);
await CommonUtils.executeCommandAsync('git init');
await writeFile(path.join(process.cwd(), 'README.txt'), 'Some content');
await CommonUtils.executeCommandAsync('git add README.txt');
await CommonUtils.executeCommandAsync(
'git commit --no-gpg-sign -m "Initial commit"'
);
process.chdir(origCwd);

try {
await new ConfigureProjectCommand(
extensionUri
).validateProjectFolder(projectFolderUri);
assert.fail(
'Validation should fail if project dir is not the Starter Kit repo.'
);
} catch (err) {
assert.equal(
(err as Error).message,
l10n.t(
"The git repository at '{0}' does not share history with the Offline Starter Kit.",
projectFolderUri.fsPath
)
);
} finally {
assert.equal(origCwd, process.cwd());
removeTempProjectDir(projectFolderUri.fsPath);
}
});

test('Open Project: Valid Starter Kit project', async () => {
const origCwd = process.cwd();
const extensionUri = Uri.file('whateva');
const projectFolderUri = Uri.file(await createTempProjectDir());

// Clone the Starter Kit repo, as shallowly as possible.
process.chdir(projectFolderUri.fsPath);
await CommonUtils.executeCommandAsync('git init');
await CommonUtils.executeCommandAsync(
'git remote add origin https://github.com/salesforce/offline-app-developer-starter-kit.git'
);
await CommonUtils.executeCommandAsync(
'git fetch origin 99b1fa9377694beb7918580aab445a2e9981f611'
);
await CommonUtils.executeCommandAsync(
'git checkout -b main FETCH_HEAD'
);
process.chdir(origCwd);

try {
await new ConfigureProjectCommand(
extensionUri
).validateProjectFolder(projectFolderUri);
} catch (err) {
assert.fail(`Project should have been valid, but wasn't: ${err}`);
} finally {
assert.equal(origCwd, process.cwd());
removeTempProjectDir(projectFolderUri.fsPath);
}
}).timeout(10000);
});

0 comments on commit 164d3c1

Please sign in to comment.