@sprucelabs/spruce-cli
Version:
Command line interface for building Spruce skills.
242 lines (240 loc) • 10.8 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 test_utils_2 = require("@sprucelabs/test-utils");
const AbstractSkillTest_1 = __importDefault(require("../../../tests/AbstractSkillTest"));
const test_utility_1 = __importDefault(require("../../../tests/utilities/test.utility"));
class CreatingASkillViewTest extends AbstractSkillTest_1.default {
static skillCacheKey = 'views';
static action;
static rootSvc;
static appointmentsCard;
static dashboardVc;
static async beforeEach() {
await super.beforeEach();
this.action = this.Action('view', 'create');
}
static hasCreateAction() {
test_utils_1.assert.isFunction(this.action.execute);
}
static async viewFeatureHasExpectedDependencies() {
const features = await this.featureInstaller;
const view = features.getFeature('view');
test_utils_1.assert.isEqualDeep(view.dependencies, [
{
code: 'node',
isRequired: true,
},
{
code: 'schema',
isRequired: true,
},
{
code: 'event',
isRequired: true,
},
]);
}
static async asksIfRootSkillViewIfNotYetCreated() {
void this.action.execute({
viewType: 'skillView',
});
await this.waitForInput();
const last = this.ui.getLastInvocation();
test_utils_1.assert.isEqual(last.command, 'confirm');
this.ui.reset();
}
static async canCreateRootSkillView() {
const results = await this.action.execute({
viewType: 'skillView',
isRoot: true,
});
test_utils_1.assert.isFalsy(results.errors);
this.rootSvc = test_utility_1.default.assertFileByNameInGeneratedFiles('Root.svc.ts', results.files);
test_utils_1.assert.doesInclude(this.rootSvc, 'skillViewControllers');
}
static async generatesValidRootSkillView() {
await this.Service('typeChecker').check(this.rootSvc);
}
static async rootSkillViewExtendsAbstractSkillViewController() {
const contents = spruce_skill_utils_1.diskUtil.readFile(this.rootSvc);
test_utils_1.assert.doesInclude(contents, 'export default class RootSkillViewController extends AbstractSkillViewController');
}
static async cantCreateTwoRootSvcs() {
const results = await this.action.execute({
viewType: 'skillView',
isRoot: true,
});
test_utils_1.assert.isTruthy(results.errors);
test_utils_2.errorAssert.assertError(results.errors?.[0], 'SKILL_VIEW_EXISTS', {
name: 'Root',
});
}
static async doesNotAskForRootAgainEvenIfRootIsMoved() {
const destinationDir = this.resolvePath('src', 'root');
spruce_skill_utils_1.diskUtil.createDir(destinationDir);
spruce_skill_utils_1.diskUtil.moveFile(this.rootSvc, this.resolvePath(destinationDir, 'Root.svc.ts'));
await this.createSkillViewAndWaitForPrompt();
this.ui.reset();
}
static async asksForNamesIfCreatingSkillViewNotRoot() {
const { promise } = await this.createSkillViewAndWaitForPrompt();
await this.ui.sendInput('Dashboard');
await this.ui.sendInput('\n');
const results = await promise;
test_utils_1.assert.isFalsy(results.errors);
this.dashboardVc = test_utility_1.default.assertFileByNameInGeneratedFiles('Dashboard.svc.ts', results.files);
test_utils_1.assert.doesInclude(this.dashboardVc, 'skillViewControllers');
this.ui.reset();
}
static async asksForViewModelWhenCreatingSkillView() {
const promise = this.action.execute({
viewType: 'view',
nameReadable: 'Appointments card',
});
await this.waitForInput();
const last = this.ui.getLastInvocation();
test_utils_1.assert.isEqual(last.command, 'prompt');
test_utils_1.assert.doesInclude(last.options.options.choices, {
value: 'Card',
});
await this.ui.sendInput('Card');
const results = await promise;
test_utils_1.assert.isFalsy(results.errors);
this.appointmentsCard = test_utility_1.default.assertFileByNameInGeneratedFiles('AppointmentsCard.vc.ts', results.files);
}
static skillViewExtendsAbstractViewControllerWithProperView() {
const contents = spruce_skill_utils_1.diskUtil.readFile(this.appointmentsCard);
test_utils_1.assert.doesInclude(contents, 'export default class AppointmentsCardViewController extends AbstractViewController<Card>');
}
static async nicelyTypesRootSkillViewController() {
const contents = this.buildTestfile({
idInterfaceName: 'SkillViewControllerId',
code: `
const root = vcFactory.Controller('testing-views.root', {})
export const svcModel = root.render()
export const svcId: SkillViewControllerId = 'testing-views.root'`,
});
const testFile = this.resolvePath('src', 'test.ts');
spruce_skill_utils_1.diskUtil.writeFile(testFile, contents);
const imported = await this.Service('import').importAll(testFile);
test_utils_1.assert.isTruthy(imported.svcModel);
test_utils_1.assert.isTruthy(imported.svcId);
}
static async nicelyTypesViewController() {
const contents = this.buildTestfile({
idInterfaceName: 'ViewControllerId',
code: `
const apptCard = vcFactory.Controller('testing-views.appointments-card', {})
export const vcModel = apptCard.render()
export const vcId: ViewControllerId = 'testing-views.appointments-card'`,
});
const testFile = this.resolvePath('src', 'test.ts');
spruce_skill_utils_1.diskUtil.writeFile(testFile, contents);
const imported = await this.Service('import').importAll(testFile);
test_utils_1.assert.isTruthy(imported.vcModel);
test_utils_1.assert.isTruthy(imported.vcId);
}
static async typesViewControllerOptions() {
const viewsFile = this.resolveHashSprucePath('views', 'views.ts');
const viewContents = spruce_skill_utils_1.diskUtil.readFile(viewsFile);
test_utils_1.assert.doesInclude(viewContents, `interface ViewControllerOptionsMap`);
test_utils_1.assert.doesInclude(viewContents, `'testing-views.appointments-card': ConstructorParameters<typeof AppointmentsCardViewController>[0]`);
}
static async typesSkillViewControllerLoadOptionsOptions() {
const viewsFile = this.resolveHashSprucePath('views', 'views.ts');
const viewContents = spruce_skill_utils_1.diskUtil.readFile(viewsFile);
test_utils_1.assert.doesInclude(viewContents, `interface SkillViewControllerArgsMap`);
test_utils_1.assert.doesInclude(viewContents, `type LoadOptions<Args extends Record<string,any>[]> = Args[0]['args'] extends Record<string, any> ? Args[0]['args'] : Record<never, any>`);
test_utils_1.assert.doesInclude(viewContents, `'testing-views.root': LoadOptions<Parameters<RootSkillViewController['load']>>`);
}
static async createSkillViewAndWaitForPrompt() {
const promise = this.action.execute({
viewType: 'skillView',
});
await this.waitForInput();
let last = this.ui.getLastInvocation();
test_utils_1.assert.isEqual(last.command, 'prompt');
return { promise };
}
static buildTestfile(options) {
const { code, idInterfaceName } = options;
return (`
import ` +
`'#spruce/views/views'
import {
ViewControllerFactory,
AuthenticatorImpl,
StubStorage,
${idInterfaceName},
} from '@sprucelabs/heartwood-view-controllers'
import { vcDiskUtil } from '@sprucelabs/spruce-test-fixtures'
AuthenticatorImpl.setStorage(new StubStorage())
const vcFactory = ViewControllerFactory.Factory({
controllerMap: vcDiskUtil.loadViewControllersAndBuildMap('testing-views', __dirname).map,
device: {} as any,
connectToApi: async () => {
return 'yes' as any
},
})
${code}
`.trim());
}
}
exports.default = CreatingASkillViewTest;
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "hasCreateAction", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "viewFeatureHasExpectedDependencies", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "asksIfRootSkillViewIfNotYetCreated", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "canCreateRootSkillView", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "generatesValidRootSkillView", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "rootSkillViewExtendsAbstractSkillViewController", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "cantCreateTwoRootSvcs", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "doesNotAskForRootAgainEvenIfRootIsMoved", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "asksForNamesIfCreatingSkillViewNotRoot", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "asksForViewModelWhenCreatingSkillView", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "skillViewExtendsAbstractViewControllerWithProperView", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "nicelyTypesRootSkillViewController", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "nicelyTypesViewController", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "typesViewControllerOptions", null);
__decorate([
(0, test_utils_1.test)()
], CreatingASkillViewTest, "typesSkillViewControllerLoadOptionsOptions", null);
//# sourceMappingURL=CreatingASkillView.test.js.map