From 050b2bb5e87cb22b7bf30820c6032d1aacf501cc Mon Sep 17 00:00:00 2001 From: Mike Donnalley Date: Fri, 21 Jun 2024 13:13:42 -0600 Subject: [PATCH] chore: code review --- src/generators/analyticsTemplateGenerator.ts | 4 +- src/generators/apexClassGenerator.ts | 4 +- src/generators/apexTriggerGenerator.ts | 4 +- .../{sfGenerator.ts => baseGenerator.ts} | 16 +- src/generators/lightningAppGenerator.ts | 4 +- src/generators/lightningComponentGenerator.ts | 4 +- src/generators/lightningEventGenerator.ts | 4 +- src/generators/lightningInterfaceGenerator.ts | 4 +- src/generators/lightningTestGenerator.ts | 4 +- src/generators/projectGenerator.ts | 27 +- src/generators/staticResourceGenerator.ts | 4 +- .../visualforceComponentGenerator.ts | 4 +- src/generators/visualforcePageGenerator.ts | 4 +- src/service/templateService.ts | 8 +- ...enerator.test.ts => baseGenerator.test.ts} | 23 +- test/service/templateService.test.ts | 448 +++++++++++++++++- 16 files changed, 490 insertions(+), 76 deletions(-) rename src/generators/{sfGenerator.ts => baseGenerator.ts} (95%) rename test/generators/{sfGenerator.test.ts => baseGenerator.test.ts} (77%) diff --git a/src/generators/analyticsTemplateGenerator.ts b/src/generators/analyticsTemplateGenerator.ts index 2e5c7531..7b7da2f2 100644 --- a/src/generators/analyticsTemplateGenerator.ts +++ b/src/generators/analyticsTemplateGenerator.ts @@ -8,9 +8,9 @@ import * as path from 'path'; import { nls } from '../i18n'; import { CreateUtil } from '../utils'; import { AnalyticsTemplateOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class AnalyticsTemplateGenerator extends SfGenerator { +export default class AnalyticsTemplateGenerator extends BaseGenerator { constructor(options: AnalyticsTemplateOptions) { super(options); } diff --git a/src/generators/apexClassGenerator.ts b/src/generators/apexClassGenerator.ts index 14cf8440..c3e5f082 100644 --- a/src/generators/apexClassGenerator.ts +++ b/src/generators/apexClassGenerator.ts @@ -7,9 +7,9 @@ import * as path from 'path'; import { CreateUtil } from '../utils'; import { ApexClassOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class ApexClassGenerator extends SfGenerator { +export default class ApexClassGenerator extends BaseGenerator { constructor(options: ApexClassOptions) { super(options); } diff --git a/src/generators/apexTriggerGenerator.ts b/src/generators/apexTriggerGenerator.ts index b6fe3681..dfbaafb5 100644 --- a/src/generators/apexTriggerGenerator.ts +++ b/src/generators/apexTriggerGenerator.ts @@ -7,9 +7,9 @@ import * as path from 'path'; import { CreateUtil } from '../utils'; import { ApexTriggerOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class ApexTriggerGenerator extends SfGenerator { +export default class ApexTriggerGenerator extends BaseGenerator { constructor(options: ApexTriggerOptions) { super(options); } diff --git a/src/generators/sfGenerator.ts b/src/generators/baseGenerator.ts similarity index 95% rename from src/generators/sfGenerator.ts rename to src/generators/baseGenerator.ts index 8376a65e..3200f102 100644 --- a/src/generators/sfGenerator.ts +++ b/src/generators/baseGenerator.ts @@ -6,25 +6,17 @@ */ import * as fs from 'fs'; -import { access, mkdir, writeFile, readFile } from 'node:fs/promises'; +import { mkdir, writeFile, readFile } from 'node:fs/promises'; import * as path from 'path'; import { CreateOutput, TemplateOptions } from '../utils/types'; import { renderFile } from 'ejs'; import { nls } from '../i18n'; import { loadCustomTemplatesGitRepo } from '../service/gitRepoUtils'; -async function pathExists(path: string): Promise { - return access(path) - .then(() => true) - .catch(() => false); -} - async function outputFile(file: string, data: string): Promise { const dir = path.dirname(file); - if (!(await pathExists(dir))) { - await mkdir(dir, { recursive: true }); - } + await mkdir(dir, { recursive: true }); return writeFile(file, data); } @@ -74,7 +66,7 @@ export async function setCustomTemplatesRootPathOrGitRepo( /** * Look up package version of @salesforce/templates package to supply a default API version */ -function getDefaultApiVersion(): string { +export function getDefaultApiVersion(): string { const packageJsonPath = path.join('..', '..', 'package.json'); const versionTrimmed = require(packageJsonPath).salesforceApiVersion.trim(); return `${versionTrimmed.split('.')[0]}.0`; @@ -173,7 +165,7 @@ abstract class NotYeoman { } } -export abstract class SfGenerator< +export abstract class BaseGenerator< TOptions extends TemplateOptions > extends NotYeoman { /** diff --git a/src/generators/lightningAppGenerator.ts b/src/generators/lightningAppGenerator.ts index 04a115cc..913dc9b1 100644 --- a/src/generators/lightningAppGenerator.ts +++ b/src/generators/lightningAppGenerator.ts @@ -8,9 +8,9 @@ import * as path from 'path'; import { nls } from '../i18n'; import { CreateUtil } from '../utils'; import { LightningAppOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class LightningAppGenerator extends SfGenerator { +export default class LightningAppGenerator extends BaseGenerator { constructor(options: LightningAppOptions) { super(options); } diff --git a/src/generators/lightningComponentGenerator.ts b/src/generators/lightningComponentGenerator.ts index c4613e31..f284e960 100644 --- a/src/generators/lightningComponentGenerator.ts +++ b/src/generators/lightningComponentGenerator.ts @@ -10,9 +10,9 @@ import * as path from 'path'; import { nls } from '../i18n'; import { CreateUtil } from '../utils'; import { LightningComponentOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class LightningComponentGenerator extends SfGenerator { +export default class LightningComponentGenerator extends BaseGenerator { constructor(options: LightningComponentOptions) { super(options); } diff --git a/src/generators/lightningEventGenerator.ts b/src/generators/lightningEventGenerator.ts index d2e97674..320dec1b 100644 --- a/src/generators/lightningEventGenerator.ts +++ b/src/generators/lightningEventGenerator.ts @@ -8,9 +8,9 @@ import * as path from 'path'; import { nls } from '../i18n'; import { CreateUtil } from '../utils'; import { LightningEventOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class LightningEventGenerator extends SfGenerator { +export default class LightningEventGenerator extends BaseGenerator { constructor(options: LightningEventOptions) { super(options); } diff --git a/src/generators/lightningInterfaceGenerator.ts b/src/generators/lightningInterfaceGenerator.ts index f2da1b14..1ac4610f 100644 --- a/src/generators/lightningInterfaceGenerator.ts +++ b/src/generators/lightningInterfaceGenerator.ts @@ -8,9 +8,9 @@ import * as path from 'path'; import { nls } from '../i18n'; import { CreateUtil } from '../utils'; import { LightningInterfaceOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class LightningInterfaceGenerator extends SfGenerator { +export default class LightningInterfaceGenerator extends BaseGenerator { constructor(options: LightningInterfaceOptions) { super(options); } diff --git a/src/generators/lightningTestGenerator.ts b/src/generators/lightningTestGenerator.ts index ced3d158..b6e78b8d 100644 --- a/src/generators/lightningTestGenerator.ts +++ b/src/generators/lightningTestGenerator.ts @@ -8,9 +8,9 @@ import * as path from 'path'; import { nls } from '../i18n'; import { CreateUtil } from '../utils'; import { LightningTestOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class LightningTestGenerator extends SfGenerator { +export default class LightningTestGenerator extends BaseGenerator { constructor(options: LightningTestOptions) { super(options); } diff --git a/src/generators/projectGenerator.ts b/src/generators/projectGenerator.ts index 8f54a93d..0139b013 100644 --- a/src/generators/projectGenerator.ts +++ b/src/generators/projectGenerator.ts @@ -5,11 +5,11 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import * as fs from 'fs'; -import { readFile, writeFile } from 'node:fs/promises'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; import * as path from 'path'; import { CreateUtil } from '../utils'; import { ProjectOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; const GITIGNORE = 'gitignore'; const HUSKY_FOLDER = '.husky'; @@ -53,7 +53,7 @@ async function extendJSON( await writeFile(filepath, newContent); } -export default class ProjectGenerator extends SfGenerator { +export default class ProjectGenerator extends BaseGenerator { constructor(options: ProjectOptions) { super(options); this.sourceRootWithPartialPath('project'); @@ -121,7 +121,7 @@ export default class ProjectGenerator extends SfGenerator { } if (template === 'standard') { - makeEmptyFolders(folderlayout, standardfolderarray); + await makeEmptyFolders(folderlayout, standardfolderarray); // Add Husky directory and hooks this._createHuskyConfig(path.join(this.outputdir, projectname)); @@ -186,7 +186,7 @@ export default class ProjectGenerator extends SfGenerator { } if (template === 'empty') { - makeEmptyFolders(folderlayout, emptyfolderarray); + await makeEmptyFolders(folderlayout, emptyfolderarray); await this.render( this.templatePath('.forceignore'), this.destinationPath( @@ -197,7 +197,7 @@ export default class ProjectGenerator extends SfGenerator { } if (template === 'analytics') { - makeEmptyFolders(folderlayout, analyticsfolderarray); + await makeEmptyFolders(folderlayout, analyticsfolderarray); // Add Husky directory and hooks this._createHuskyConfig(path.join(this.outputdir, projectname)); @@ -265,20 +265,11 @@ export default class ProjectGenerator extends SfGenerator { } } -function makeEmptyFolders( +async function makeEmptyFolders( toplevelfolders: string[], metadatafolders: string[] ) { - let oldfolder = ''; - for (const folder of toplevelfolders) { - if (!fs.existsSync(path.join(oldfolder, folder))) { - fs.mkdirSync(path.join(oldfolder, folder)); - } - oldfolder = path.join(oldfolder, folder); - } - for (const newfolder of metadatafolders) { - if (!fs.existsSync(path.join(oldfolder, newfolder))) { - fs.mkdirSync(path.join(oldfolder, newfolder)); - } + for (const folder of metadatafolders) { + await mkdir(path.join(...toplevelfolders, folder), { recursive: true }); } } diff --git a/src/generators/staticResourceGenerator.ts b/src/generators/staticResourceGenerator.ts index 8797a5f6..7429bce0 100644 --- a/src/generators/staticResourceGenerator.ts +++ b/src/generators/staticResourceGenerator.ts @@ -9,11 +9,11 @@ import * as path from 'path'; import { nls } from '../i18n'; import { CreateUtil } from '../utils'; import { StaticResourceOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; const EXTENSION_TEMPLATES = ['js', 'css', 'json', 'txt']; -export default class StaticResourceGenerator extends SfGenerator { +export default class StaticResourceGenerator extends BaseGenerator { constructor(options: StaticResourceOptions) { super(options); } diff --git a/src/generators/visualforceComponentGenerator.ts b/src/generators/visualforceComponentGenerator.ts index a8bd0d18..0ad1fa53 100644 --- a/src/generators/visualforceComponentGenerator.ts +++ b/src/generators/visualforceComponentGenerator.ts @@ -7,9 +7,9 @@ import * as path from 'path'; import { CreateUtil } from '../utils'; import { VisualforceComponentOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class VisualforceComponentGenerator extends SfGenerator { +export default class VisualforceComponentGenerator extends BaseGenerator { constructor(options: VisualforceComponentOptions) { super(options); } diff --git a/src/generators/visualforcePageGenerator.ts b/src/generators/visualforcePageGenerator.ts index f6e9a785..aacfe864 100644 --- a/src/generators/visualforcePageGenerator.ts +++ b/src/generators/visualforcePageGenerator.ts @@ -7,9 +7,9 @@ import * as path from 'path'; import { CreateUtil } from '../utils'; import { VisualforcePageOptions } from '../utils/types'; -import { SfGenerator } from './sfGenerator'; +import { BaseGenerator } from './baseGenerator'; -export default class VisualforcePageGenerator extends SfGenerator { +export default class VisualforcePageGenerator extends BaseGenerator { constructor(options: VisualforcePageOptions) { super(options); } diff --git a/src/service/templateService.ts b/src/service/templateService.ts index 0cecd4bc..0705a02a 100644 --- a/src/service/templateService.ts +++ b/src/service/templateService.ts @@ -11,7 +11,7 @@ import { TemplateType, } from '../utils/types'; -async function importGenerator(templateType: TemplateType) { +export async function importGenerator(templateType: TemplateType) { const generatorClass = TemplateType[templateType].toString().charAt(0).toLowerCase() + TemplateType[templateType].toString().slice(1) + @@ -32,7 +32,7 @@ export class TemplateService { /** * Get an instance of TemplateService - * @param cwd cwd of current yeoman environment. CLI: don't need to set explicitly. VS Code: it's typically the root workspace path + * @param cwd cwd of current environment. CLI: don't need to set explicitly. VS Code: it's typically the root workspace path */ public static getInstance(cwd?: string): TemplateService { if (!TemplateService.instance) { @@ -44,14 +44,14 @@ export class TemplateService { } /** - * Getting cwd of current yeoman environment + * Getting cwd of current environment */ public get cwd(): string { return this._cwd; } /** - * Setting cwd of current yeoman environment + * Setting cwd of current environment * In VS Code, it's typically the root workspace path */ public set cwd(cwd: string) { diff --git a/test/generators/sfGenerator.test.ts b/test/generators/baseGenerator.test.ts similarity index 77% rename from test/generators/sfGenerator.test.ts rename to test/generators/baseGenerator.test.ts index 80b09179..93ae99a2 100644 --- a/test/generators/sfGenerator.test.ts +++ b/test/generators/baseGenerator.test.ts @@ -5,24 +5,20 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -import * as path from 'path'; import * as sinon from 'sinon'; import { expect } from 'chai'; import { TemplateOptions } from '../../src'; -import { SfGenerator } from '../../src/generators/sfGenerator'; +import { + BaseGenerator, + getDefaultApiVersion, +} from '../../src/generators/baseGenerator'; -function getDefaultApiVersion(): string { - const packageJsonPath = path.join('..', '..', 'package.json'); - const versionTrimmed = require(packageJsonPath).salesforceApiVersion.trim(); - return `${versionTrimmed.split('.')[0]}.0`; -} - -describe('SfGenerator', () => { +describe('BaseGenerator', () => { const API_VERSION = getDefaultApiVersion(); interface MyTemplateOptions extends TemplateOptions { customProp: boolean; } - class MyGenerator extends SfGenerator { + class MyGenerator extends BaseGenerator { public validateOptions() {} public async generate() { this.doWriting({ @@ -64,3 +60,10 @@ describe('SfGenerator', () => { expect(validateOptionsStub.calledOnce).to.be.true; }); }); + +describe('getDefaultApiVersion', () => { + it('should return the default api version', async () => { + const pjson = await import('../../package.json'); + expect(getDefaultApiVersion()).to.equal(`${pjson.salesforceApiVersion}.0`); + }); +}); diff --git a/test/service/templateService.test.ts b/test/service/templateService.test.ts index 473469fc..ef16a5c5 100644 --- a/test/service/templateService.test.ts +++ b/test/service/templateService.test.ts @@ -17,20 +17,16 @@ import { nls } from '../../src/i18n'; import { getStoragePathForCustomTemplates } from '../../src/service/gitRepoUtils'; import { getProxyForUrl } from 'proxy-from-env'; import { - SfGenerator, + BaseGenerator, setCustomTemplatesRootPathOrGitRepo, -} from '../../src/generators/sfGenerator'; + getDefaultApiVersion, +} from '../../src/generators/baseGenerator'; +import { importGenerator } from '../../src/service/templateService'; chai.use(chaiAsPromised); chai.config.truncateThreshold = 100000; chai.should(); -function getDefaultApiVersion(): string { - const packageJsonPath = path.join('..', '..', 'package.json'); - const versionTrimmed = require(packageJsonPath).salesforceApiVersion.trim(); - return `${versionTrimmed.split('.')[0]}.0`; -} - function assertFileContent(file: string, regex: string | RegExp) { const exists = fs.existsSync(file); chai.expect(exists).to.be.true; @@ -361,7 +357,7 @@ describe('TemplateService', () => { await setCustomTemplatesRootPathOrGitRepo(customTemplates); - assert.calledOnce(streamStub); + assert.callCount(streamStub, 1); streamStub.restore(); existsSyncStub.restore(); }); @@ -462,7 +458,7 @@ describe('TemplateService', () => { }); it('should reject if create template fails', async () => { - const generatorStub = stub(SfGenerator.prototype, 'run').throws( + const generatorStub = stub(BaseGenerator.prototype, 'run').throws( new Error('error') ); const templateService = TemplateService.getInstance(process.cwd()); @@ -481,4 +477,436 @@ describe('TemplateService', () => { } }); }); + + describe('Generators', () => { + it('should have a generator for each TemplateType', async () => { + const templateTypes = Object.values(TemplateType).filter( + (v) => !isNaN(Number(v)) + ); + + for (const templateType of templateTypes) { + try { + // @ts-expect-error because we loose type safety when iterating over the values of an enum + const generator = await importGenerator(templateType); + chai.expect(generator).to.not.be.undefined; + } catch { + throw new Error( + `No generator found for template type: ${ + TemplateType[templateType as number] + }` + ); + } + } + }); + + it('should create AnalyticsTemplate', async () => { + await fs.remove( + path.join('testsoutput', 'libraryCreate', 'waveTemplates') + ); + const templateService = TemplateService.getInstance(); + const result = await templateService.create( + TemplateType.AnalyticsTemplate, + { + templatename: 'analytics', + outputdir: path.join('testsoutput', 'libraryCreate', 'waveTemplates'), + } + ); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/waveTemplates/analytics/dashboards/analyticsDashboard.json', + 'testsoutput/libraryCreate/waveTemplates/analytics/app-to-template-rules.json', + 'testsoutput/libraryCreate/waveTemplates/analytics/folder.json', + 'testsoutput/libraryCreate/waveTemplates/analytics/releaseNotes.html', + 'testsoutput/libraryCreate/waveTemplates/analytics/template-info.json', + 'testsoutput/libraryCreate/waveTemplates/analytics/template-to-app-rules.json', + 'testsoutput/libraryCreate/waveTemplates/analytics/ui.json', + 'testsoutput/libraryCreate/waveTemplates/analytics/variables.json', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create ApexClass', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'apexClass')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create(TemplateType.ApexClass, { + template: 'DefaultApexClass', + classname: 'LibraryCreateClass', + outputdir: path.join('testsoutput', 'libraryCreate', 'apexClass'), + }); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/apexClass/LibraryCreateClass.cls', + 'testsoutput/libraryCreate/apexClass/LibraryCreateClass.cls-meta.xml', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create ApexTrigger', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'apexTrigger')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create(TemplateType.ApexTrigger, { + triggername: 'LibraryCreateTrigger', + sobject: 'Account', + event: 'before insert', + outputdir: path.join('testsoutput', 'libraryCreate', 'apexTrigger'), + template: 'ApexTrigger', + }); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/apexTrigger/LibraryCreateTrigger.trigger', + 'testsoutput/libraryCreate/apexTrigger/LibraryCreateTrigger.trigger-meta.xml', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create LightningApp', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'aura')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create(TemplateType.LightningApp, { + appname: 'LibraryCreateApp', + internal: false, + outputdir: path.join('testsoutput', 'libraryCreate', 'aura'), + template: 'DefaultLightningApp', + }); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/aura/LibraryCreateApp/LibraryCreateApp.app-meta.xml', + 'testsoutput/libraryCreate/aura/LibraryCreateApp/LibraryCreateApp.app', + 'testsoutput/libraryCreate/aura/LibraryCreateApp/LibraryCreateApp.auradoc', + 'testsoutput/libraryCreate/aura/LibraryCreateApp/LibraryCreateAppController.js', + 'testsoutput/libraryCreate/aura/LibraryCreateApp/LibraryCreateApp.css', + 'testsoutput/libraryCreate/aura/LibraryCreateApp/LibraryCreateAppHelper.js', + 'testsoutput/libraryCreate/aura/LibraryCreateApp/LibraryCreateAppRenderer.js', + 'testsoutput/libraryCreate/aura/LibraryCreateApp/LibraryCreateApp.svg', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create LightningComponent (aura)', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'aura')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create( + TemplateType.LightningComponent, + { + componentname: 'LibraryCreateComponent', + outputdir: path.join('testsoutput', 'libraryCreate', 'aura'), + template: 'default', + type: 'aura', + } + ); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/aura/LibraryCreateComponent/LibraryCreateComponent.cmp-meta.xml', + 'testsoutput/libraryCreate/aura/LibraryCreateComponent/LibraryCreateComponent.auradoc', + 'testsoutput/libraryCreate/aura/LibraryCreateComponent/LibraryCreateComponent.cmp', + 'testsoutput/libraryCreate/aura/LibraryCreateComponent/LibraryCreateComponent.css', + 'testsoutput/libraryCreate/aura/LibraryCreateComponent/LibraryCreateComponent.design', + 'testsoutput/libraryCreate/aura/LibraryCreateComponent/LibraryCreateComponent.svg', + 'testsoutput/libraryCreate/aura/LibraryCreateComponent/LibraryCreateComponentController.js', + 'testsoutput/libraryCreate/aura/LibraryCreateComponent/LibraryCreateComponentHelper.js', + 'testsoutput/libraryCreate/aura/LibraryCreateComponent/LibraryCreateComponentRenderer.js', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create LightningComponent (lwc)', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'lwc')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create( + TemplateType.LightningComponent, + { + componentname: 'LibraryCreateComponent', + outputdir: path.join('testsoutput', 'libraryCreate', 'lwc'), + template: 'default', + type: 'lwc', + } + ); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/lwc/libraryCreateComponent/libraryCreateComponent.js', + 'testsoutput/libraryCreate/lwc/libraryCreateComponent/libraryCreateComponent.html', + 'testsoutput/libraryCreate/lwc/libraryCreateComponent/__tests__/libraryCreateComponent.test.js', + 'testsoutput/libraryCreate/lwc/libraryCreateComponent/libraryCreateComponent.js-meta.xml', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create LightningEvent', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'aura')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create(TemplateType.LightningEvent, { + eventname: 'LibraryCreateEvent', + outputdir: path.join('testsoutput', 'libraryCreate', 'aura'), + template: 'DefaultLightningEvt', + }); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/aura/LibraryCreateEvent/LibraryCreateEvent.evt-meta.xml', + 'testsoutput/libraryCreate/aura/LibraryCreateEvent/LibraryCreateEvent.evt', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create LightningInterface', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'aura')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create( + TemplateType.LightningInterface, + { + interfacename: 'LibraryCreateInterface', + outputdir: path.join('testsoutput', 'libraryCreate', 'aura'), + template: 'DefaultLightningIntf', + } + ); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/aura/LibraryCreateInterface/LibraryCreateInterface.intf-meta.xml', + 'testsoutput/libraryCreate/aura/LibraryCreateInterface/LibraryCreateInterface.intf', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create LightningTest', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'aura')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create(TemplateType.LightningTest, { + testname: 'LibraryCreateTest', + outputdir: path.join('testsoutput', 'libraryCreate', 'aura'), + template: 'DefaultLightningTest', + }); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/aura/LibraryCreateTest.resource-meta.xml', + 'testsoutput/libraryCreate/aura/LibraryCreateTest.resource', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create Project (standard)', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'project')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create(TemplateType.Project, { + outputdir: path.join('testsoutput', 'libraryCreate', 'project'), + projectname: 'LibraryCreateProject', + template: 'standard', + defaultpackagedir: 'force-app', + }); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/project/LibraryCreateProject/.forceignore', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.gitignore', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.husky/pre-commit', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.prettierignore', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.prettierrc', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.vscode/extensions.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.vscode/launch.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.vscode/settings.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/README.md', + 'testsoutput/libraryCreate/project/LibraryCreateProject/config/project-scratch-def.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/force-app/main/default/aura/.eslintrc.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/force-app/main/default/lwc/.eslintrc.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/jest.config.js', + 'testsoutput/libraryCreate/project/LibraryCreateProject/package.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/scripts/apex/hello.apex', + 'testsoutput/libraryCreate/project/LibraryCreateProject/scripts/soql/account.soql', + 'testsoutput/libraryCreate/project/LibraryCreateProject/sfdx-project.json', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create Project (empty)', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'project')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create(TemplateType.Project, { + outputdir: path.join('testsoutput', 'libraryCreate', 'project'), + projectname: 'LibraryCreateProject', + template: 'empty', + defaultpackagedir: 'force-app', + }); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/project/LibraryCreateProject/config/project-scratch-def.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/README.md', + 'testsoutput/libraryCreate/project/LibraryCreateProject/sfdx-project.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.forceignore', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create Project (analytics)', async () => { + await fs.remove(path.join('testsoutput', 'libraryCreate', 'project')); + const templateService = TemplateService.getInstance(); + const result = await templateService.create(TemplateType.Project, { + outputdir: path.join('testsoutput', 'libraryCreate', 'project'), + projectname: 'LibraryCreateProject', + template: 'analytics', + defaultpackagedir: 'force-app', + }); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/project/LibraryCreateProject/config/project-scratch-def.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/README.md', + 'testsoutput/libraryCreate/project/LibraryCreateProject/sfdx-project.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.husky/pre-commit', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.vscode/extensions.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.vscode/launch.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.vscode/settings.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/force-app/main/default/lwc/.eslintrc.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/force-app/main/default/aura/.eslintrc.json', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.forceignore', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.gitignore', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.prettierignore', + 'testsoutput/libraryCreate/project/LibraryCreateProject/.prettierrc', + 'testsoutput/libraryCreate/project/LibraryCreateProject/jest.config.js', + 'testsoutput/libraryCreate/project/LibraryCreateProject/package.json', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create StaticResource', async () => { + await fs.remove( + path.join('testsoutput', 'libraryCreate', 'staticResource') + ); + const templateService = TemplateService.getInstance(); + const result = await templateService.create(TemplateType.StaticResource, { + resourcename: 'LibraryCreateResource', + outputdir: path.join('testsoutput', 'libraryCreate', 'staticResource'), + template: 'empty', + contenttype: 'application/zip', + }); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/staticResource/LibraryCreateResource/.gitkeep', + 'testsoutput/libraryCreate/staticResource/LibraryCreateResource.resource-meta.xml', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create VisualforceComponent', async () => { + await fs.remove( + path.join('testsoutput', 'libraryCreate', 'visualforceComponent') + ); + const templateService = TemplateService.getInstance(); + const result = await templateService.create( + TemplateType.VisualforceComponent, + { + componentname: 'LibraryCreateComponent', + label: 'LibraryCreateComponent', + outputdir: path.join( + 'testsoutput', + 'libraryCreate', + 'visualforceComponent' + ), + template: 'DefaultVFComponent', + } + ); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/visualforceComponent/LibraryCreateComponent.component', + 'testsoutput/libraryCreate/visualforceComponent/LibraryCreateComponent.component-meta.xml', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + + it('should create VisualforcePage', async () => { + await fs.remove( + path.join('testsoutput', 'libraryCreate', 'visualforcePage') + ); + const templateService = TemplateService.getInstance(); + const result = await templateService.create( + TemplateType.VisualforcePage, + { + pagename: 'LibraryCreatePage', + label: 'LibraryCreatePage', + outputdir: path.join( + 'testsoutput', + 'libraryCreate', + 'visualforcePage' + ), + template: 'DefaultVFPage', + } + ); + + chai + .expect(result.created.sort()) + .to.deep.equal( + [ + 'testsoutput/libraryCreate/visualforcePage/LibraryCreatePage.page', + 'testsoutput/libraryCreate/visualforcePage/LibraryCreatePage.page-meta.xml', + ] + .map((p) => path.normalize(p)) + .sort() + ); + }); + }); });