Skip to content

Commit

Permalink
test(integration): Update test + framework code
Browse files Browse the repository at this point in the history
Getting close enough on the core framework and unit test code to want
to start working on the CirlceCI side of things.  This commit forms a
solid baseline to use while working on .circleci/config.yml

Related to: #133
  • Loading branch information
VivekMChawla committed Mar 15, 2019
1 parent 0c5d2d0 commit 7eaf7a2
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 83 deletions.
52 changes: 28 additions & 24 deletions test/helpers/cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {ChildProcess} from "child_process";
const {existsSync} = require('fs');
const {constants} = require('os');
const {ChildProcess, spawn} = require('cross-spawn');
const util = require('util'); // Provides access to the "inspect" function to help output objects via console.log.


//─────────────────────────────────────────────────────────────────────────────────────────────────┐
Expand All @@ -29,10 +30,11 @@ const {ChildProcess, spawn} = require('cross-spawn');
//─────────────────────────────────────────────────────────────────────────────────────────────────┘
export interface CommandOutput {
exitCode?: number;
output?: string[];
signal?: string;
stderr?: string;
stdout?: string;
signal?: string;
stderr?: string;
stderrLines?: string[];
stdout?: string;
stdoutLines?: string[];
}

//─────────────────────────────────────────────────────────────────────────────────────────────────┐
Expand Down Expand Up @@ -150,14 +152,14 @@ export function createProcess(processPath:string, args:string[]=[], envVars:AnyJ

//─────────────────────────────────────────────────────────────────────────────────────────────────┐
/**
* @function createProcess
* @function executeWithInput
* @param {string} processPath Path of the process to execute
* @param {string[]} args Arguments to the command
* @param {MockInput[]} [mockInputs] (Optional) Array of MockInput objects (user responses)
* @param {ExecOptions} [opts] (optional) Environment variables
* @returns {Promise<CommandOutput>} Returns a promise that resolves when all inputs are sent.
* Rejects the promise if any error.
* @description Creates a command and executes inputs (user responses) to the stdin
* @description Executes a CLI Plugin command and is capable of sending mock stdin inputs.
* @public
*/
//─────────────────────────────────────────────────────────────────────────────────────────────────┘
Expand All @@ -176,10 +178,11 @@ export async function executeWithInput(processPath:string, args:string[]=[], moc

// Initialize an object to store output from this function.
const commandOutput:CommandOutput = {
exitCode: null,
output: [],
stderr: '',
stdout: ''
exitCode: null,
stderrLines: [],
stdoutLines: [],
stderr: '',
stdout: ''
};

// DEVTEST: Echo a variety of path related info so we can see differences between local and CircleCI.
Expand Down Expand Up @@ -235,13 +238,14 @@ export async function executeWithInput(processPath:string, args:string[]=[], moc
clearAllTimeouts(trackedTimeouts);

// Prep the Command Output variable for return.
commandOutput.output = commandOutput.stdout.trim().split('\n');
commandOutput.exitCode = code;
commandOutput.signal = signal;
commandOutput.stdoutLines = commandOutput.stdout.trim().split('\n');
commandOutput.stderrLines = commandOutput.stderr.trim().split('\n');
commandOutput.exitCode = code;
commandOutput.signal = signal;

// Show the contents of the Command Output if the showResults option was set.
if (opts && opts.showResult) {
console.log('Command Output:\n%O', commandOutput);
console.log(`Command Output:\n${util.inspect(commandOutput, {depth:10, maxArrayLength:1000, colors:true})}`);
}

// Resolve the promise, returning the Command Output we've collected.
Expand All @@ -252,20 +256,20 @@ export async function executeWithInput(processPath:string, args:string[]=[], moc

//─────────────────────────────────────────────────────────────────────────────────────────────────┐
/**
* @function getOutputLines
* @param {CommandOutput} commandOutput Contains the output results of a call to executeWithInput().
* @param {number[]} linesToGet Index values of individual line numbers to retrieve.
* @function getLines
* @param {string[]} stringArray Contains the output results of a call to executeWithInput().
* @param {number[]} linesToGet Index values of individual line numbers to retrieve.
* Negative numbers will fetch lines offset from the end of the output array.
* @returns {string} Single concatenated string of all requested lines.
* @description Given a CommandOutput object and an array of index values, returns a single string
* concatenation of the requested line numbers.
* @public
*/
//─────────────────────────────────────────────────────────────────────────────────────────────────┘
export function getOutputLines(commandOutput:CommandOutput, linesToGet:number[]):string {
export function getLines(stringArray:string[], linesToGet:number[]):string {

// Return an empty string if we didn't get a populated string array in commandOutput.
if (Array.isArray(commandOutput.output) === false || commandOutput.output.length === 0) {
// Return an empty string if we didn't get a populated string array.
if (Array.isArray(stringArray) === false || stringArray.length === 0) {
return '';
}

Expand All @@ -285,14 +289,14 @@ export function getOutputLines(commandOutput:CommandOutput, linesToGet:number[])
}

// Fetch lines from the END of the array if the requested line is a negative number.
if (line < 0 && (commandOutput.output.length - line >= 0)) {
returnString += commandOutput.output[commandOutput.output.length - Math.abs(line)];
if (line < 0 && (stringArray.length - line >= 0)) {
returnString += stringArray[stringArray.length - Math.abs(line)];
continue;
}

// Fetch lines by the normal array index if the requested line is a positive number.
if (line >= 0 && (line <= commandOutput.output.length - 1)) {
returnString += commandOutput.output[line];
if (line >= 0 && (line <= stringArray.length - 1)) {
returnString += stringArray[line];
continue;
}
}
Expand Down
21 changes: 21 additions & 0 deletions test/helpers/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ process.env.FALCON_COMMAND_RUNNER = path.resolve('bin/run'); // Pat
process.env.FALCON_TEST_TEMPDIR = path.resolve('test/temp'); // Path to the temp directory used during tests.
process.env.FALCON_TEST_PROJECTDIR = path.resolve('test/projects'); // Path to the directory that holds sample ADK projects.

// Check environment for cues about handling debug. Allows CI environment to flip debug on/off.
process.env.FALCON_TEST_SHOW_STDOUT = process.env.FALCON_TEST_SHOW_STDOUT || ''; // stdout from spawned process is piped to the main process.
process.env.FALCON_TEST_SHOW_STDERR = process.env.FALCON_TEST_SHOW_STDERR || ''; // stderr from spawned process is piped to the main process.
process.env.FALCON_TEST_SHOW_RESULT = process.env.FALCON_TEST_SHOW_RESULT || ''; // Prints internal commandResult object at the conclusion of executeWithInput().

// DEVTEST: Echo the various "debug" env vars.
console.log(`FALCON_TEST_SHOW_STDOUT: ${process.env.FALCON_TEST_SHOW_STDOUT}`);
console.log(`FALCON_TEST_SHOW_STDERR: ${process.env.FALCON_TEST_SHOW_STDERR}`);
console.log(`FALCON_TEST_SHOW_RESULT: ${process.env.FALCON_TEST_SHOW_RESULT}`);

// DEVTEST: Demonstrate how boolean checks of env vars goes.
if (process.env.FALCON_TEST_SHOW_STDOUT) {
console.log('-->FALCON_TEST_SHOW_STDOUT environment var deemed TRUE<--');
}
if (process.env.FALCON_TEST_SHOW_STDERR) {
console.log('-->FALCON_TEST_SHOW_STDERR environment var deemed TRUE<--');
}
if (process.env.FALCON_TEST_SHOW_RESULT) {
console.log('-->FALCON_TEST_SHOW_RESULT environment var deemed TRUE<--');
}

// Delete everything inside of the Falcon Test Temp Directory EXCEPT .gitignore
del.sync(
[
Expand Down
57 changes: 31 additions & 26 deletions test/integration-tests/commands/falcon/adk/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
* @license MIT
*/
//─────────────────────────────────────────────────────────────────────────────────────────────────┘
// Import Modules=
import { expect } from 'chai';
import { executeWithInput } from '../../../../helpers/cmd';
import { getOutputLines } from '../../../../helpers/cmd';
import { KEY } from '../../../../helpers/cmd';
// Import Modules
import {expect} from 'chai';
import {executeWithInput} from '../../../../helpers/cmd';
import {KEY} from '../../../../helpers/cmd';


//─────────────────────────────────────────────────────────────────────────────────────────────────┐
Expand All @@ -23,34 +22,36 @@ import { KEY } from '../../../../helpers/cmd';
//─────────────────────────────────────────────────────────────────────────────────────────────────┘
describe.skip('falcon:adk:create', () => {

//───────────────────────────────────────────────────────────────────────────┐
// Test One
//───────────────────────────────────────────────────────────────────────────┘
it('should successfully create an ADK project', async () => {
const commandResponse = await executeWithInput(
process.env.FALCON_COMMAND_RUNNER, // Path to the process that will be run.
[
'falcon:adk:create' // First member of the array must be the CLI command we want to run.
],
[
{input: KEY.ENTER, delay: 20000},
{input: KEY.ENTER, delay: 200},
{input: KEY.ENTER, delay: 200},
{input: 'N' + KEY.ENTER, delay: 200},
{input: 'Y' + KEY.ENTER, delay: 200},
{input: KEY.ENTER, delay: 200},
{input: KEY.ENTER, delay: 200},
{input: KEY.ENTER, delay: 200},
{input: KEY.ENTER, delay: 200},
{input: 'Y' + KEY.ENTER, delay: 200}
{input: KEY.ENTER, delay: 20000}, // Choose first DevHub listed
{input: KEY.ENTER, delay: 200}, // ???
{input: KEY.ENTER, delay: 200}, // ???
{input: 'N' + KEY.ENTER, delay: 200}, // ???
{input: 'Y' + KEY.ENTER, delay: 200}, // ???
{input: KEY.ENTER, delay: 200}, // ???
{input: KEY.ENTER, delay: 200}, // ???
{input: KEY.ENTER, delay: 200}, // ???
{input: KEY.ENTER, delay: 200}, // ???
{input: 'Y' + KEY.ENTER, delay: 200} // ???
],
{
envVars: {
SFDX_JSON_TO_STDOUT: true, // Sends all JSON output to STDOUT
SFDX_AUTOUPDATE_DISABLE: true // Disables the Salesforce CLI AutoUpdate feature
SFDX_JSON_TO_STDOUT: true, // Sends all JSON output to STDOUT
SFDX_AUTOUPDATE_DISABLE: true // Disables the Salesforce CLI AutoUpdate feature
},
workingDir: process.env.FALCON_TEST_TEMPDIR,
showStdout: true,
showStderr: true,
showResult: true,
showStdout: process.env.FALCON_TEST_SHOW_STDOUT ? true : false,
showStderr: process.env.FALCON_TEST_SHOW_STDERR ? true : false,
showResult: process.env.FALCON_TEST_SHOW_RESULT ? true : false,
minTimeout: 100,
maxTimeout: 300000
}
Expand All @@ -59,13 +60,17 @@ describe.skip('falcon:adk:create', () => {
// Check exit code.
expect(commandResponse.exitCode)
.to
.equal(0, 'Non-zero Exit Code');
// Check final output.
expect(getOutputLines(commandResponse, [-1]))
.equal(0, 'FAILURE! Non-zero exit code');

// Check final output for success indicators.
expect(commandResponse.stdoutLines)
.to
.equal('Command Succeded : falcon:adk:create completed successfully', 'Incorrect Final Output');
}).timeout(120000);
.include('Command Succeded : falcon:adk:create completed successfully',
'FAILURE! Final output missing success message');
}).timeout(120000);

// Test Two...
//───────────────────────────────────────────────────────────────────────────┐
// Test Two
//───────────────────────────────────────────────────────────────────────────┘

});
Loading

0 comments on commit 7eaf7a2

Please sign in to comment.