@sprucelabs/spruce-cli
Version:
Command line interface for building Spruce skills.
289 lines (283 loc) • 12.3 kB
JavaScript
;
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 globby_1 = __importDefault(require("@sprucelabs/globby"));
const schema_1 = require("@sprucelabs/schema");
const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils");
const test_utils_1 = require("@sprucelabs/test-utils");
const CommandService_1 = __importDefault(require("../../../services/CommandService"));
const LintService_1 = __importDefault(require("../../../services/LintService"));
const SchemaTemplateItemBuilder_1 = __importDefault(require("../../../templateItemBuilders/SchemaTemplateItemBuilder"));
const AbstractSkillTest_1 = __importDefault(require("../../../tests/AbstractSkillTest"));
const test_utility_1 = __importDefault(require("../../../tests/utilities/test.utility"));
class SyncingSchemasInGoTest extends AbstractSkillTest_1.default {
static skillCacheKey = 'schemas';
static goDir;
static builder1Name = 'aSchemaIBuilt';
static builder2Name = 'anotherSchemaIBuilt';
static renderer;
static goModuleName = spruce_skill_utils_1.randomUtil.rand([
'my-skill',
'awesome-skill',
'super-skill',
]);
static version = spruce_skill_utils_1.versionUtil.generateVersion().constValue;
static skillNamespace = spruce_skill_utils_1.CORE_NAMESPACE;
static schemaTemplateItemBuilder;
static goFullModuleName;
static async beforeEach() {
await super.beforeEach();
if (!this.goDir) {
this.goDir = this.resolvePath(this.skillDir, 'go-schemas');
spruce_skill_utils_1.diskUtil.createDir(this.goDir);
}
CommandService_1.default.fakeCommand(/yarn.*?/, {
code: 1,
});
this.renderer = schema_1.SchemaTypesRenderer.Renderer();
this.schemaTemplateItemBuilder = new SchemaTemplateItemBuilder_1.default(spruce_skill_utils_1.CORE_NAMESPACE);
}
static async canSyncCoreSchemasWithoutError() {
this.moveToGoDir();
this.goFullModuleName = await this.go.initGoProject(this.goModuleName);
await this.sync();
const tsFiles = await (0, globby_1.default)('**/*.ts', {
cwd: this.cwd,
ignore: ['go/pkg/**'],
});
test_utils_1.assert.isLength(tsFiles, 0, 'Expected no .ts files to be generated.');
}
static async syncingGeneratesCoreGoFileIfSchemaDoesExist() {
await this.createSchema(this.builder1Name);
this.moveToGoDir();
const syncResults = await this.sync();
test_utility_1.default.assertFileByPathInGeneratedFiles(this.coreSchemaGoFilepath, syncResults.files);
test_utils_1.assert.isTrue(spruce_skill_utils_1.diskUtil.doesFileExist(this.coreSchemaGoFilepath), 'Expected core_schemas.go file to exist.');
}
static async coreSchemasFileHasStructBasedOnSchema() {
await this.assertCoreFileIncludesSchema(this.builder1Name);
}
static async coreShowsDifferentSchema() {
await this.createSchema(this.builder2Name);
this.moveToGoDir();
await this.sync();
await this.assertCoreFileIncludesSchema(this.builder2Name);
}
static async doesNotIncludeSchemaIfDeleted() {
spruce_skill_utils_1.diskUtil.deleteFile(this.getBuilderFilepath(this.builder1Name));
this.moveToGoDir();
await this.sync();
const contents = this.loadCoreSchemasFile();
test_utils_1.assert.doesNotInclude(contents, spruce_skill_utils_1.namesUtil.toPascal(this.builder1Name), 'Expected core_schemas.go to not include deleted schema.');
}
static async coreSchemasFileIncludesPackageDeclaration() {
this.assertCoreSchemaFileIncludes('package schemas');
}
static async goFileIsValid() {
this.moveToGoDir();
await this.go.exec('build', './...');
}
static async canRenderNestedSchemas() {
const schema2 = await this.importBuilder(this.builder2Name);
schema2.fields = {
...schema2.fields,
hasNestedSchema: {
type: 'schema',
options: {
schema: nestedSchema,
},
},
dateOfBirth: {
type: 'date',
},
};
spruce_skill_utils_1.diskUtil.writeFile(this.getBuilderFilepath(this.builder2Name), `import { buildSchema } from '@sprucelabs/schema'
export default buildSchema(${JSON.stringify(schema2, null, 4)})`);
await this.lintBuilders();
schema2.namespace = this.skillNamespace;
const expected = this.renderSchemaAsStruct(schema2);
this.moveToGoDir();
await this.sync();
this.assertCoreSchemaFileIncludes(expected);
}
static async generatedFileShouldPassVet() {
this.moveToGoDir();
await this.go.vet();
}
static async writesSchemaFileForEachSchemaFound() {
this.moveToGoDir();
const results = await this.sync();
const generated = ['nestedSchema', 'anotherSchemaIBuilt'];
for (const schema of generated) {
this.assertSchemaFileWrittenWithExpectedPackage(schema, results.files);
}
}
static async canActuallyUseGeneratedSchemasInGoTest() {
this.moveToGoDir();
const testSrc = buildGoTest({
pwd: this.goFullModuleName,
name: (0, test_utils_1.generateId)(),
age: Date.now() % 100,
version: this.version,
});
spruce_skill_utils_1.diskUtil.writeFile(this.resolvePath(this.cwd, 'test_schema.go'), testSrc);
await this.go.exec('test', './...');
}
static async creatingSchemaWithDifferentVersionAlsoWorks() {
this.version = spruce_skill_utils_1.versionUtil.generateVersion('2020_01_01').constValue;
await this.createSchema('versionedSchema');
this.moveToGoDir();
const results = await this.sync();
this.assertSchemaFileWrittenWithExpectedPackage('versionedSchema', results.files);
}
static assertSchemaFileWrittenWithExpectedPackage(schema, files = []) {
test_utils_1.assert.isAbove(files.length, 0, 'Expected at least one generated file.');
const path = test_utility_1.default.assertFileByPathInGeneratedFiles(`schemas/${this.skillNamespace.toLowerCase()}/${this.version}/${spruce_skill_utils_1.namesUtil.toSnake(schema)}.go`, files);
const contents = spruce_skill_utils_1.diskUtil.readFile(path);
test_utils_1.assert.doesInclude(contents, `package ${this.version}`, 'Did not include expected package declaration.');
}
static async lintBuilders() {
LintService_1.default.enableLinting();
await this.Service('lint').fix(`**/*.builder.ts`);
}
static async assertCoreFileIncludesSchema(name) {
const struct = await this.importStructForSchema(name);
this.assertCoreSchemaFileIncludes(struct);
}
static assertCoreSchemaFileIncludes(needle) {
const contents = this.loadCoreSchemasFile();
test_utils_1.assert.doesInclude(contents, needle, 'core_schemas.go missing expected content');
}
static async importStructForSchema(name) {
const imported = await this.importBuilder(name);
imported.namespace = this.skillNamespace;
const struct = this.renderSchemaAsStruct(imported);
return struct;
}
static loadCoreSchemasFile() {
return spruce_skill_utils_1.diskUtil.readFile(this.coreSchemaGoFilepath);
}
static renderSchemaAsStruct(imported) {
const templateItems = this.schemaTemplateItemBuilder.buildTemplateItems({
[spruce_skill_utils_1.CORE_NAMESPACE]: [imported],
});
return this.renderer.render(imported, {
language: 'go',
schemaTemplateItems: templateItems,
});
}
static async importBuilder(name) {
return (await this.Service('import').importDefault(this.getBuilderFilepath(name)));
}
static async createSchema(name) {
const results = await this.Action('schema', 'create').execute({
nameReadable: 'A schema i built!',
nameCamel: name,
version: this.version,
});
test_utils_1.assert.isFalsy(results.errors, 'Expected no errors when creating schema.');
}
static getBuilderFilepath(name) {
return this.resolvePath(this.skillDir, 'src', 'schemas', spruce_skill_utils_1.versionUtil.generateVersion().dirValue, `${name}.builder.ts`);
}
static get coreSchemaGoFilepath() {
return spruce_skill_utils_1.diskUtil.resolvePath(this.goDir, 'schemas/core_schemas.go');
}
static async sync() {
const results = await this.Action('schema', 'sync', {
shouldAutoHandleDependencies: true,
}).execute({
shouldGenerateCoreSchemaTypes: true,
schemaLookupDir: this.resolvePath(this.skillDir, 'src'),
});
test_utils_1.assert.isFalsy(results.errors, 'Expected no errors when syncing core schemas in a go project.');
test_utils_1.assert.isTruthy(results.files, 'Expected some generated files when syncing core schemas in a go project.');
return results;
}
static moveToGoDir() {
this.cwd = this.goDir;
this.setCwd(this.cwd);
}
}
exports.default = SyncingSchemasInGoTest;
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "canSyncCoreSchemasWithoutError", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "syncingGeneratesCoreGoFileIfSchemaDoesExist", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "coreSchemasFileHasStructBasedOnSchema", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "coreShowsDifferentSchema", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "doesNotIncludeSchemaIfDeleted", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "coreSchemasFileIncludesPackageDeclaration", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "goFileIsValid", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "canRenderNestedSchemas", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "generatedFileShouldPassVet", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "writesSchemaFileForEachSchemaFound", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "canActuallyUseGeneratedSchemasInGoTest", null);
__decorate([
(0, test_utils_1.test)()
], SyncingSchemasInGoTest, "creatingSchemaWithDifferentVersionAlsoWorks", null);
const nestedSchema = (0, schema_1.buildSchema)({
id: 'nestedSchema',
fields: {
name: {
type: 'text',
},
age: {
type: 'number',
},
},
});
const buildGoTest = (options) => `
package goschemas
import (
"testing"
spruce "${options.pwd}/schemas/spruce/${options.version}"
)
func TestMakeASchemaIBuilt(t *testing.T) {
data := map[string]interface{}{
"name": "${options.name}",
"age": ${options.age},
}
result, err := spruce.MakeNestedSchema(data)
if err != nil {
t.Fatalf("MakeNestedSchema failed: %v", err)
}
if result.Name != "${options.name}" {
t.Errorf("Expected Name to be '${options.name}', got '%s'",
result.Name)
}
if result.Age != ${options.age} {
t.Errorf("Expected Age to be ${options.age}, got %f",
result.Age)
}
}
`;
//# sourceMappingURL=SyncingCoreSchemasInGo.test.js.map