Skip to content
This repository has been archived by the owner on Sep 9, 2021. It is now read-only.

Commit

Permalink
Add init command unit tests (#97)
Browse files Browse the repository at this point in the history
* Refactor init module for improved testability
* Add unit tests for parts of the init command module

Co-authored-by: Erik Marks <[email protected]>
  • Loading branch information
astarinmymind and rekmarks authored Mar 24, 2021
1 parent 0af6a4f commit bfdc42d
Show file tree
Hide file tree
Showing 6 changed files with 596 additions and 79 deletions.
6 changes: 3 additions & 3 deletions src/cmds/init/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import yargs from 'yargs';
import builders from '../../builders';
import { build } from '../build';
import { YargsArgs } from '../../types/yargs';
import { initHandler } from './initialize';
import { build } from '../build';
import { initHandler } from './initHandler';

module.exports.command = ['init', 'i'];
module.exports.desc = 'Initialize Snap package';
Expand All @@ -16,9 +16,9 @@ module.exports.builder = (yarg: yargs.Argv) => {
module.exports.handler = (argv: YargsArgs) => init(argv);

async function init(argv: YargsArgs): Promise<void> {
const newArgs = await initHandler(argv);

console.log();
const newArgs = await initHandler(argv);

await build({
...newArgs,
Expand Down
64 changes: 64 additions & 0 deletions src/cmds/init/initHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { promises as fs } from 'fs';
import { CONFIG_PATHS, logError, closePrompt } from '../../utils';
import { YargsArgs } from '../../types/yargs';
import template from './initTemplate.json';
import { asyncPackageInit, validateEmptyDir, buildWeb3Wallet } from './initUtils';

const CONFIG_PATH = CONFIG_PATHS[0];

export async function initHandler(argv: YargsArgs) {
console.log(`Init: Begin building 'package.json'\n`);

const pkg = await asyncPackageInit();

await validateEmptyDir();

console.log(`\nInit: Set 'package.json' web3Wallet properties\n`);

const [web3Wallet, _newArgs] = await buildWeb3Wallet(argv);
const newArgs = _newArgs as YargsArgs;
pkg.web3Wallet = web3Wallet;

try {
await fs.writeFile('package.json', `${JSON.stringify(pkg, null, 2)}\n`);
} catch (err) {
logError(`Init Error: Fatal: Failed to write package.json`, err);
process.exit(1);
}

console.log(`\nInit: 'package.json' web3Wallet properties set successfully!`);

// write main js entry file
const { main } = pkg;
if (main !== undefined) {
newArgs.src = main;
try {
await fs.writeFile(main, template.js);
console.log(`Init: Wrote main entry file '${main}'`);
} catch (err) {
logError(`Init Error: Fatal: Failed to write main .js file '${main}'`, err);
process.exit(1);
}
}

// write index.html
try {
await fs.writeFile('index.html', template.html.toString()
.replace(/_PORT_/gu, newArgs.port.toString() || argv.port.toString()));
console.log(`Init: Wrote 'index.html' file`);
} catch (err) {
logError(`Init Error: Fatal: Failed to write index.html file`, err);
process.exit(1);
}

// write config file
try {
await fs.writeFile(CONFIG_PATH, JSON.stringify(newArgs, null, 2));
console.log(`Init: Wrote '${CONFIG_PATH}' config file`);
} catch (err) {
logError(`Init Error: Failed to write '${CONFIG_PATH}' file`, err);
}

closePrompt();
return { ...argv, ...newArgs };
}
83 changes: 7 additions & 76 deletions src/cmds/init/initialize.ts → src/cmds/init/initUtils.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,13 @@
import { promises as fs, existsSync } from 'fs';
import pathUtils from 'path';
import initPackageJson from 'init-package-json';
import {
CONFIG_PATHS, logError, logWarning, prompt, closePrompt, trimPathString,
} from '../../utils';
import { CONFIG_PATHS, logError, logWarning, prompt, trimPathString } from '../../utils';
import { YargsArgs } from '../../types/yargs';
import { ManifestWalletProperty, NodePackageManifest } from '../../types/package';
import template from './initTemplate.json';

const CONFIG_PATH = CONFIG_PATHS[0];

interface InitOutput {
port: number;
dist: string;
outfileName: string;
sourceMaps: boolean;
stripComments: boolean;
src: string;
}

export async function initHandler(argv: YargsArgs): Promise<InitOutput> {
console.log(`Init: Begin building 'package.json'\n`);

const pkg = await asyncPackageInit();

await validateEmptyDir();

console.log(`\nInit: Set 'package.json' web3Wallet properties\n`);

const [web3Wallet, _newArgs] = await buildWeb3Wallet(argv);
const newArgs = _newArgs as YargsArgs;
pkg.web3Wallet = web3Wallet;

try {
await fs.writeFile('package.json', `${JSON.stringify(pkg, null, 2)}\n`);
} catch (err) {
logError(`Init Error: Fatal: Failed to write package.json`, err);
process.exit(1);
}

console.log(`\nInit: 'package.json' web3Wallet properties set successfully!`);

// write main js entry file
const { main } = pkg;
if (main !== undefined) {
newArgs.src = main;
try {
await fs.writeFile(main, template.js);
console.log(`Init: Wrote main entry file '${main}'`);
} catch (err) {
logError(`Init Error: Fatal: Failed to write main .js file '${main}'`, err);
process.exit(1);
}
}

// write index.html
try {
await fs.writeFile('index.html', template.html.toString()
.replace(/_PORT_/gu, newArgs.port.toString() || argv.port.toString()));
console.log(`Init: Wrote 'index.html' file`);
} catch (err) {
logError(`Init Error: Fatal: Failed to write index.html file`, err);
process.exit(1);
}

// write config file
try {
await fs.writeFile(CONFIG_PATH, JSON.stringify(newArgs, null, 2));
console.log(`Init: Wrote '${CONFIG_PATH}' config file`);
} catch (err) {
logError(`Init Error: Failed to write '${CONFIG_PATH}' file`, err);
}

closePrompt();
return { ...argv, ...newArgs } as InitOutput;
}

async function asyncPackageInit(): Promise<NodePackageManifest> {
export async function asyncPackageInit(): Promise<NodePackageManifest> {

// use existing package.json if found
const hasPackage = existsSync('package.json');
Expand Down Expand Up @@ -120,7 +51,7 @@ async function asyncPackageInit(): Promise<NodePackageManifest> {
});
}

async function buildWeb3Wallet(argv: YargsArgs): Promise<[
export async function buildWeb3Wallet(argv: YargsArgs): Promise<[
ManifestWalletProperty,
{ port: number; dist: string; outfileName: string },
]> {
Expand All @@ -131,8 +62,8 @@ async function buildWeb3Wallet(argv: YargsArgs): Promise<[
let initialPermissions: Record<string, unknown> = defaultPerms;

try {
const c = await prompt({ question: `Use all default Snap manifest values?`, defaultValue: 'yes', shouldClose: false });
if (c && ['y', 'yes'].includes(c.toLowerCase())) {
const userInput = await prompt({ question: `Use all default Snap manifest values?`, defaultValue: 'yes', shouldClose: false });
if (userInput && ['y', 'yes'].includes(userInput.toLowerCase())) {
console.log('Using default values...');
try {
await fs.mkdir(dist);
Expand All @@ -159,7 +90,7 @@ async function buildWeb3Wallet(argv: YargsArgs): Promise<[
port = parsedPort;
noValidPort = false;
} else {
logError(`Invalid port '${port}, please retry.`);
logError(`Invalid port '${parsedPort}', please retry.`);
}
}

Expand Down Expand Up @@ -228,7 +159,7 @@ async function buildWeb3Wallet(argv: YargsArgs): Promise<[
}
}

async function validateEmptyDir(): Promise<void> {
export async function validateEmptyDir(): Promise<void> {
const existing = (await fs.readdir(process.cwd())).filter((item) => [
'index.js', 'index.html', CONFIG_PATH, 'dist',
].includes(item.toString()));
Expand Down
17 changes: 17 additions & 0 deletions test/cmds/init/init.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const init = require('../../../dist/src/cmds/init');
const initializeModule = require('../../../dist/src/cmds/init/initHandler');
const buildModule = require('../../../dist/src/cmds/build');

describe('init module', () => {
it('console logs if successful', async () => {
const mockArgv = { foo: 'bar' };
const initHandlerMock = jest.spyOn(initializeModule, 'initHandler').mockImplementation(() => mockArgv);
const buildMock = jest.spyOn(buildModule, 'build').mockImplementation();
jest.spyOn(console, 'log').mockImplementation();

await init.handler({ ...mockArgv });
expect(initHandlerMock).toHaveBeenCalledWith(mockArgv);
expect(buildMock).toHaveBeenCalledWith({ foo: 'bar', manifest: false, eval: true });
expect(global.console.log).toHaveBeenCalledTimes(2);
});
});
Loading

0 comments on commit bfdc42d

Please sign in to comment.