@sprucelabs/spruce-cli
Version:
Command line interface for building Spruce skills.
210 lines • 9.7 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils");
const test_utils_1 = require("@sprucelabs/test-utils");
const feature_utilities_1 = __importDefault(require("../../features/feature.utilities"));
const CommandService_1 = __importDefault(require("../../services/CommandService"));
const AbstractSchemaTest_1 = __importDefault(require("../../tests/AbstractSchemaTest"));
const test_utility_1 = __importDefault(require("../../tests/utilities/test.utility"));
class FeatureCommandExecuterContTest extends AbstractSchemaTest_1.default {
static async canSkipOptionalDependencies() {
const { promise: actionPromise } = await this.startBuildingNewErrorUntilOptionalDependencies('skip');
const results = await this.finishBuildingUpToNamingNewError(actionPromise);
test_utils_1.assert.isTruthy(results.files);
test_utils_1.assert.isFalsy(results.errors);
const pluginsDir = this.resolveHashSprucePath('features');
test_utils_1.assert.isFalse(spruce_skill_utils_1.diskUtil.doesDirExist(pluginsDir));
test_utility_1.default.assertFileByNameInGeneratedFiles('myNewError.schema.ts', results.files);
}
static async shouldEmitExecutionEvents() {
this.fakeInstallCommands();
const executer = this.Action('skill', 'create', {
shouldAutoHandleDependencies: true,
});
let emittedWillEvent = false;
let willEventCommand = '';
let emittedDidEvent = false;
let didEventCommand = '';
let willExecuteHitCount = 0;
let didExecuteHitCount = 0;
const emitter = this.emitter;
void emitter.on('feature.will-execute', (payload) => {
emittedWillEvent = true;
willExecuteHitCount++;
willEventCommand = feature_utilities_1.default.generateCommand(payload.featureCode, payload.actionCode);
return {};
});
void emitter.on('feature.did-execute', (payload) => {
emittedDidEvent = true;
didExecuteHitCount++;
didEventCommand = feature_utilities_1.default.generateCommand(payload.featureCode, payload.actionCode);
return {
meta: {
taco: 'bell',
},
};
});
test_utils_1.assert.isFalse(emittedWillEvent);
test_utils_1.assert.isFalse(emittedDidEvent);
test_utils_1.assert.isEqual(willExecuteHitCount, 0);
test_utils_1.assert.isEqual(didExecuteHitCount, 0);
const promise = executer.execute({});
await this.waitForInput();
await this.ui.sendInput('My new skill');
await this.ui.sendInput('So great!');
const results = await promise;
test_utils_1.assert.isEqual(results.meta?.taco, 'bell');
test_utils_1.assert.isEqual(willEventCommand, 'create.skill');
test_utils_1.assert.isEqual(didEventCommand, 'create.skill');
test_utils_1.assert.isEqual(willExecuteHitCount, 1);
test_utils_1.assert.isEqual(didExecuteHitCount, 1);
}
static async canPermanentlySkipOptionalDependencies() {
const { promise: actionPromise } = await this.startBuildingNewErrorUntilOptionalDependencies('alwaysSkip');
await this.finishBuildingUpToNamingNewError(actionPromise);
const executer = this.Action('error', 'create', {
shouldAutoHandleDependencies: true,
});
const promise = executer.execute({});
await this.waitForInput();
test_utils_1.assert.doesNotInclude(this.ui.getLastInvocation(), {
command: 'prompt',
options: {
type: 'select',
},
});
await this.ui.sendInput('My second error');
await this.ui.sendInput('');
const secondTimeResults = await promise;
test_utils_1.assert.isTruthy(secondTimeResults.files);
test_utility_1.default.assertFileByNameInGeneratedFiles('myNewError.schema.ts', secondTimeResults.files);
}
static async shouldReturnProperSummary() {
this.fakeInstallCommands();
const executer = this.Action('skill', 'create', {
shouldAutoHandleDependencies: true,
});
const results = await executer.execute({
name: 'install summary test skill',
description: 'go team!',
});
test_utils_1.assert.isTruthy(results.files);
test_utils_1.assert.isTruthy(results.packagesInstalled);
test_utils_1.assert.isAbove(results.files.length, 0);
test_utils_1.assert.isAbove(results.packagesInstalled.length, 0);
}
static async shouldAskInstallDependentFeatures() {
this.fakeInstallCommands();
const executer = this.Action('schema', 'create', {
shouldAutoHandleDependencies: true,
});
void executer.execute({});
await this.waitForInput();
this.ui.reset();
const lastQuestion = this.ui.getLastInvocation();
test_utils_1.assert.isEqual(lastQuestion.command, 'prompt');
test_utils_1.assert.doesInclude(lastQuestion.options.label, /install the skill feature/gi);
}
static async shouldAddListenerWithoutBreakingOnSkill() {
this.fakeInstallCommands();
await this.FeatureFixture().installCachedFeatures('schemas');
const executer = this.Action('event', 'listen', {
shouldAutoHandleDependencies: true,
});
const promise = executer.execute({});
await this.waitForInput();
await this.ui.sendInput('Y');
await this.waitForInput();
await this.ui.sendInput('\n');
await this.waitForInput();
await this.ui.sendInput('skill');
await this.ui.sendInput('will-boot');
const results = await promise;
const version = spruce_skill_utils_1.versionUtil.generateVersion().dirValue;
test_utility_1.default.assertFileByNameInGeneratedFiles(`will-boot.${version}.listener.ts`, results.files);
}
static async finishBuildingUpToNamingNewError(actionPromise) {
await this.ui.sendInput('');
await this.waitForInput();
await this.ui.sendInput('');
await this.waitForInput();
await this.ui.sendInput('My new error');
await this.ui.sendInput('');
const results = await actionPromise;
return results;
}
static async startBuildingNewErrorUntilOptionalDependencies(skillFeatureAnswer) {
const executer = this.Action('error', 'create', {
shouldAutoHandleDependencies: true,
});
const promise = executer.execute({});
await this.waitForInput();
const message = this.ui.invocations[this.ui.invocations.length - 2].options.message;
test_utils_1.assert.isTruthy(message);
test_utils_1.assert.doesInclude(message, /2 required/gi);
test_utils_1.assert.doesInclude(message, /1 optional/gi);
test_utils_1.assert.doesInclude(this.ui.getLastInvocation(), {
command: 'prompt',
options: {
type: 'select',
options: {
choices: [
{
value: 'yes',
label: 'Yes',
},
{
value: 'skip',
label: 'Skip',
},
{
value: 'alwaysSkip',
label: 'Always skip',
},
],
},
},
});
await this.ui.sendInput(skillFeatureAnswer);
await this.ui.sendInput('y');
await this.waitForInput();
await this.ui.sendInput('My new module');
await this.ui.sendInput('it is for testing');
await this.waitForInput();
return { promise };
}
static fakeInstallCommands() {
CommandService_1.default.fakeCommand(new RegExp(/yarn|npm/gis), {
code: 0,
});
}
}
exports.default = FeatureCommandExecuterContTest;
__decorate([
(0, test_utils_1.test)()
], FeatureCommandExecuterContTest, "canSkipOptionalDependencies", null);
__decorate([
(0, test_utils_1.test)()
], FeatureCommandExecuterContTest, "shouldEmitExecutionEvents", null);
__decorate([
(0, test_utils_1.test)()
], FeatureCommandExecuterContTest, "canPermanentlySkipOptionalDependencies", null);
__decorate([
(0, test_utils_1.test)()
], FeatureCommandExecuterContTest, "shouldReturnProperSummary", null);
__decorate([
(0, test_utils_1.test)()
], FeatureCommandExecuterContTest, "shouldAskInstallDependentFeatures", null);
__decorate([
(0, test_utils_1.test)()
], FeatureCommandExecuterContTest, "shouldAddListenerWithoutBreakingOnSkill", null);
//# sourceMappingURL=ActionExecuter2.test.js.map