UNPKG

generator-begcode

Version:

Spring Boot + Angular/React/Vue in one handy generator

306 lines (305 loc) 13.5 kB
import { YeomanTest, RunContext, result } from 'yeoman-test'; import { merge, set } from 'lodash-es'; import { globSync } from 'glob'; import { basename, dirname, join } from 'path'; import { fileURLToPath } from 'url'; import EnvironmentBuilder from '../cli/environment-builder.mjs'; import { JHIPSTER_CONFIG_DIR } from '../generators/generator-constants.js'; import { GENERATOR_WORKSPACES } from '../generators/generator-list.js'; import getGenerator from './get-generator.js'; import { createJHipsterLogger, normalizePathEnd, parseCreationTimestamp } from '../generators/base/support/index.js'; import BaseGenerator from '../generators/base/index.js'; import { getPackageRoot, isDistFolder } from '../lib/index.js'; const runResult = result; export { runResult, runResult as result }; const DEFAULT_TEST_SETTINGS = { forwardCwd: true }; const DEFAULT_TEST_OPTIONS = { skipInstall: true }; const DEFAULT_TEST_ENV_OPTIONS = { skipInstall: true, dryRun: false }; const generatorsDir = join(fileURLToPath(import.meta.url), '../../generators'); const mockedGenerators = [ ...globSync('*/index.{j,t}s', { cwd: generatorsDir, posix: true }).map(file => dirname(file)), ...globSync('*/generators/*/index.{j,t}s', { cwd: generatorsDir, posix: true }).map(file => dirname(file).replace('/generators/', ':')), ] .filter(gen => !gen.startsWith('bootstrap-')) .map(gen => `begcode:${gen}`) .sort(); const defaultSharedApplication = Object.fromEntries(['CLIENT_WEBPACK_DIR'].map(key => [key, undefined])); let defaultMockFactory; export const defineDefaults = async ({ mockFactory } = {}) => { if (mockFactory) { defaultMockFactory = mockFactory; } else if (!defaultMockFactory) { try { const { esmocha } = await import('esmocha'); defaultMockFactory = esmocha.fn; } catch { throw new Error('loadMockFactory should be called before using mock'); } } }; const createFiles = (workspaceFolder, configuration, entities) => { if (!configuration.baseName) { throw new Error('baseName is required'); } workspaceFolder = workspaceFolder ? normalizePathEnd(workspaceFolder) : workspaceFolder; const entityFiles = entities ? Object.fromEntries(entities?.map(entity => [`${workspaceFolder}${JHIPSTER_CONFIG_DIR}/${entity.name}.json`, entity])) : {}; configuration = { entities: entities?.map(e => e.name), ...configuration }; return { [`${workspaceFolder}.yo-rc.json`]: { 'generator-jhipster': configuration }, ...entityFiles, }; }; export const createJHipsterConfigFiles = (configuration, entities) => createFiles('', configuration, entities); export const createBlueprintFiles = (blueprintPackage, { packageJson, generator = 'test-blueprint', generatorContent, files = {} } = {}) => { generatorContent = generatorContent ?? `export const createGenerator = async env => { const BaseGenerator = await env.requireGenerator('begcode:base'); return class extends BaseGenerator { get [BaseGenerator.INITIALIZING]() { return {}; } }; }; `; const generators = Array.isArray(generator) ? generator : [generator]; return { [`node_modules/${blueprintPackage}/package.json`]: { name: blueprintPackage, version: '9.9.9', type: 'module', ...packageJson, }, ...Object.fromEntries(generators.map(generator => [`node_modules/${blueprintPackage}/generators/${generator}/index.js`, generatorContent])), ...Object.fromEntries(Object.entries(files).map(([file, content]) => [`node_modules/${blueprintPackage}/${file}`, content])), }; }; class JHipsterRunContext extends RunContext { sharedSource; sharedData; sharedApplication; sharedControl; workspaceApplications = []; commonWorkspacesConfig; generateApplicationsSet = false; withOptions(options) { return super.withOptions(options); } withJHipsterConfig(configuration, entities) { return this.withFiles(createFiles('', { baseName: 'jhipster', creationTimestamp: parseCreationTimestamp('2020-01-01'), ...configuration }, entities)); } withSkipWritingPriorities() { return this.withOptions({ skipPriorities: ['writing', 'postWriting', 'writingEntities', 'postWritingEntities'] }); } withWorkspacesCommonConfig(commonWorkspacesConfig) { if (this.workspaceApplications.length > 0) { throw new Error('Cannot be called after withWorkspaceApplication'); } this.commonWorkspacesConfig = { ...this.commonWorkspacesConfig, ...commonWorkspacesConfig }; return this; } withWorkspaceApplicationAtFolder(workspaceFolder, configuration, entities) { if (this.generateApplicationsSet) { throw new Error('Cannot be called after withWorkspaceApplication'); } this.workspaceApplications.push(workspaceFolder); return this.withFiles(createFiles(workspaceFolder, { ...configuration, ...this.commonWorkspacesConfig }, entities)); } withWorkspaceApplication(configuration, entities) { return this.withWorkspaceApplicationAtFolder(configuration.baseName, configuration, entities); } withWorkspacesSamples(...appNames) { return this.onBeforePrepare(async () => { try { const { default: deploymentTestSamples } = await import('./support/deployment-samples.js'); for (const appName of appNames) { const application = deploymentTestSamples[appName]; if (!application) { throw new Error(`Application ${appName} not found`); } this.withWorkspaceApplicationAtFolder(appName, deploymentTestSamples[appName]); } } catch { throw new Error('Samples are currently not available to blueprint testing.'); } }); } withGenerateWorkspaceApplications(generateWorkspaces = false) { return this.onBeforePrepare(() => { this.generateApplicationsSet = true; this.withOptions({ generateApplications: true, workspacesFolders: this.workspaceApplications, workspaces: generateWorkspaces }); }); } withJHipsterLookup() { return this.withLookups([{ packagePaths: [getPackageRoot()], lookups: [`${isDistFolder() ? 'dist/' : ''}generators`] }]); } withParentBlueprintLookup(lookups = ['generators']) { const packageRootParent = join(getPackageRoot(), '..'); if (basename(packageRootParent) === 'node_modules') { this.withLookups([{ packagePaths: [join(packageRootParent, '..')], lookups }]); } else { this.withLookups([{ packagePaths: [process.cwd()], lookups }]); } return this; } withFakeTestBlueprint(blueprintPackage, { packageJson, generator = 'test-blueprint' } = {}) { return this.withFiles(createBlueprintFiles(blueprintPackage, { packageJson, generator })) .withLookups({ localOnly: true }) .commitFiles(); } withMockedSource() { this.sharedSource = new Proxy({}, { get(target, name) { if (!target[name]) { target[name] = defaultMockFactory(); } return target[name]; }, set() { return true; }, }); return this.onBeforePrepare(() => defineDefaults()).withSharedData({ sharedSource: this.sharedSource }); } withControl(sharedControl) { this.sharedControl = this.sharedControl ?? {}; Object.assign(this.sharedControl, sharedControl); return this.withSharedData({ control: this.sharedControl }); } withSharedApplication(sharedApplication) { this.sharedApplication = this.sharedApplication ?? { ...defaultSharedApplication }; merge(this.sharedApplication, sharedApplication); return this.withSharedData({ sharedApplication: this.sharedApplication }); } withMockedJHipsterGenerators(exceptList = []) { exceptList = exceptList.map(gen => (gen.startsWith('jhipster:') ? gen : `jhipster:${gen}`)); return this.withMockedGenerators(mockedGenerators.filter(gen => !exceptList.includes(gen) && this.Generator !== gen)); } withGradleBuildTool() { return this.withFiles({ 'build.gradle': ` dependencies { // jhipster-needle-gradle-dependency } plugins { // jhipster-needle-gradle-plugins } `, }).withJHipsterConfig({ buildTool: 'gradle' }); } withSharedData(sharedData) { if (!this.sharedData) { const applicationId = 'test-application'; this.sharedData = { ...sharedData }; set(this.envOptions, `sharedOptions.sharedData.applications.${applicationId}`, this.sharedData); return this.withOptions({ applicationId, }); } Object.assign(this.sharedData, sharedData); return this; } async run() { const runResult = (await super.run()); if (this.sharedSource) { const sourceCallsArg = Object.fromEntries(Object.entries(this.sharedSource).map(([name, fn]) => [name, fn.mock.calls.map(args => args[0])])); if (sourceCallsArg.addEntitiesToClient) { sourceCallsArg.addEntitiesToClient = sourceCallsArg.addEntitiesToClient.map(({ application, entities }) => ({ application: `Application[${application.baseName}]`, entities: entities.map(entity => `Entity[${entity.name}]`), })); } if (sourceCallsArg.addEntityToCache) { sourceCallsArg.addEntityToCache = sourceCallsArg.addEntityToCache.map(({ relationships, ...fields }) => ({ ...fields, relationships: relationships.map(rel => `Relationship[${rel.relationshipName}]`), })); } runResult.sourceCallsArg = sourceCallsArg; } runResult.composedMockedGenerators = mockedGenerators.filter(gen => runResult.mockedGenerators[gen]?.called && !['begcode:bootstrap', 'begcode:project-name'].includes(gen)); return runResult; } } class JHipsterTest extends YeomanTest { constructor() { super(); this.adapterOptions = { log: createJHipsterLogger() }; } run(GeneratorOrNamespace, settings, envOptions) { return super.run(GeneratorOrNamespace, settings, envOptions).withAdapterOptions({ log: createJHipsterLogger() }); } runJHipster(jhipsterGenerator, settings, envOptions) { return this.run(getGenerator(jhipsterGenerator), settings, envOptions); } runTestBlueprintGenerator() { const blueprintNS = 'begcode:test-blueprint'; class BlueprintedGenerator extends BaseGenerator { async beforeQueue() { if (!this.fromBlueprint) { await this.composeWithBlueprints(); } } rootGeneratorName() { return 'generator-begcode'; } get [BaseGenerator.INITIALIZING]() { return {}; } } return this.run(blueprintNS).withGenerators([[BlueprintedGenerator, { namespace: blueprintNS }]]); } create(GeneratorOrNamespace, settings, envOptions) { return super.create(GeneratorOrNamespace, settings, envOptions); } createJHipster(jhipsterGenerator, settings, envOptions) { return this.create(getGenerator(jhipsterGenerator), settings, envOptions); } generateDeploymentWorkspaces(commonConfig) { return this.runJHipster(GENERATOR_WORKSPACES) .withWorkspacesCommonConfig(commonConfig ?? {}) .withOptions({ generateWorkspaces: true, generateWith: 'docker', skipPriorities: ['prompting'], }); } } export function createTestHelpers(options = {}) { const { environmentOptions = {} } = options; const sharedOptions = { ...DEFAULT_TEST_OPTIONS, ...environmentOptions.sharedOptions, }; const helper = new JHipsterTest(); helper.settings = { ...DEFAULT_TEST_SETTINGS, ...options.settings }; helper.environmentOptions = { ...DEFAULT_TEST_ENV_OPTIONS, ...environmentOptions, sharedOptions }; helper.generatorOptions = { ...DEFAULT_TEST_OPTIONS, ...options.generatorOptions }; helper.createEnv = (...args) => EnvironmentBuilder.createEnv(...args); helper.getRunContextType = () => JHipsterRunContext; return helper; } const commonTestOptions = { reproducible: true, skipChecks: true, reproducibleTests: true, noInsight: true, useVersionPlaceholders: true, fakeKeytool: true, }; export const basicHelpers = createTestHelpers({ generatorOptions: { ...commonTestOptions } }); export const defaultHelpers = createTestHelpers({ generatorOptions: { skipPrettier: true, ...commonTestOptions }, environmentOptions: { dryRun: true }, }); export const skipPrettierHelpers = createTestHelpers({ generatorOptions: { skipPrettier: true, ...commonTestOptions } }); export const dryRunHelpers = createTestHelpers({ generatorOptions: { ...commonTestOptions }, environmentOptions: { dryRun: true }, });