From 4f5fb4bfa6b3699a012b45f5361e2899e6d337df Mon Sep 17 00:00:00 2001 From: damyanpetev Date: Thu, 19 Mar 2026 18:57:51 +0200 Subject: [PATCH] refactor: remove leftover wrappers AngularTemplate and related tests --- packages/cli/lib/templates/AngularTemplate.ts | 166 ------------- spec/unit/add-spec.ts | 72 +----- .../base-templates/AngularTemplate-spec.ts | 220 ------------------ 3 files changed, 1 insertion(+), 457 deletions(-) delete mode 100644 packages/cli/lib/templates/AngularTemplate.ts delete mode 100644 spec/unit/base-templates/AngularTemplate-spec.ts diff --git a/packages/cli/lib/templates/AngularTemplate.ts b/packages/cli/lib/templates/AngularTemplate.ts deleted file mode 100644 index 916fb6c4e..000000000 --- a/packages/cli/lib/templates/AngularTemplate.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { - AddTemplateArgs, App, Config, ControlExtraConfiguration, defaultDelimiters, - FS_TOKEN, FsFileSystem, IFileSystem, ProjectConfig, Template, TypeScriptUtils, Util -} from "@igniteui/cli-core"; -import { AngularTypeScriptFileUpdate } from "@igniteui/angular-templates"; - -import * as path from "path"; - -export class AngularTemplate implements Template { - public components: string[]; - public controlGroup: string; - public listInComponentTemplates: boolean = true; - public listInCustomTemplates: boolean = false; - public id: string; - public name: string; - public description: string; - public dependencies: Array = []; - public framework: string = "angular"; - public projectType: string; - public hasExtraConfiguration: boolean = false; - public packages = []; - public delimiters = defaultDelimiters; - - protected widget: string; - protected fileSystem = new FsFileSystem(); - - /** - * Creates a new AngularTemplate for a root path (pass in __dirname) - */ - constructor(private rootPath: string) { } - - public get templatePaths(): string[] { - return [path.join(this.rootPath, "files")]; - } - - public generateConfig(name: string, options: {}): { [key: string]: any } { - if (options["modulePath"] && !Util.fileExists(path.join(process.cwd(), `src\\app`, options["modulePath"]))) { - Util.error(`Wrong module path provided: ${options["modulePath"]}. No components were added!`); - return Promise.resolve(false); - } - - const config = Object.assign({}, options["extraConfig"], this.getBaseVariables(name)); - - return config; - } - - public registerInProject(projectPath: string, name: string, options?: AddTemplateArgs) { - let modulePath = "app-module.ts"; - if (options && options.modulePath) { - modulePath = options.modulePath; - } - // D.P. Don't use the top-level import as that chains import of typescript - // which slows down execution of the entire component noticeably (template loading) - // https://www.typescriptlang.org/docs/handbook/modules.html#dynamic-module-loading-in-nodejs - // tslint:disable-next-line:variable-name - const TsUpdate: typeof AngularTypeScriptFileUpdate = - // tslint:disable-next-line:no-submodule-imports - require("@igniteui/angular-templates").AngularTypeScriptFileUpdate; - - const componentPath = path.join(projectPath, `src/app/components/${this.folderName(name)}/${this.fileName(name)}.component.ts`); - const className = `${Util.className(Util.nameFromPath(name))}Component`; - if (!(options && options.skipRoute)) { - //1) import the component class name, - //2) and populate the Routes array with the path and component - //for example: { path: "combo", component: ComboComponent } - const routingModulePath = path.join(projectPath, "src/app/app-routing-module.ts"); - const routingModule = new TsUpdate(routingModulePath, false, { singleQuotes: false }); - - routingModule.addRoute({ - path: this.folderName(name), - identifierName: className, - modulePath: Util.relativePath(routingModulePath, componentPath, true, true), - data: { text: Util.nameFromPath(name) } - }); - - routingModule.finalize(); - } - - //3) add an import of the component class from its file location. - //4) populate the declarations portion of the @NgModule with the component class name. - const mainModulePath = path.join(projectPath, `src/app/${modulePath}`); - const relativePath = Util.relativePath(mainModulePath, componentPath, true, true); - const mainModule = new TsUpdate(mainModulePath, false, { singleQuotes: false }); - mainModule.addNgModuleMeta({ - declare: [className], - from: relativePath, - export: modulePath !== "app-module.ts" ? [className] : [] - }); - mainModule.finalize(); - - this.ensureSourceFiles(projectPath); - } - public getExtraConfiguration(): ControlExtraConfiguration[] { - return []; - } - public setExtraConfiguration(extraConfigKeys: {}) { } - - protected getBaseVariables(name: string) { - const config = {}; - config["name"] = Util.nameFromPath(name); - config["ClassName"] = Util.className(Util.nameFromPath(name)); - config["path"] = this.folderName(name); - config["filePrefix"] = this.fileName(name); - config["description"] = this.description; - config["cliVersion"] = Util.version(); - config["camelCaseName"] = Util.camelCase(name); - - if (this.widget) { - config["widget"] = this.widget; - } - if (this.name) { - config["nameMerged"] = this.name.replace(/ /g, ""); - } - return config; - } - - protected ensureSourceFiles(projectPath: string) { - // tslint:disable-next-line:no-submodule-imports - const components = require("@igniteui/cli-core/packages/components"); - const config = ProjectConfig.getConfig(); - const files: string[] = config.project.sourceFiles; - const dvDependencies = this.dependencies.filter(x => components.dv.indexOf(x) !== -1); - - if (dvDependencies.length && files.indexOf("infragistics.dv.js") === -1) { - files.push("infragistics.dv.js"); - ProjectConfig.setConfig(config); - } - - if (this.dependencies.indexOf("igExcel") !== -1 && files.indexOf("infragistics.excel-bundled.js") === -1) { - files.push("infragistics.excel-bundled.js"); - ProjectConfig.setConfig(config); - } - - if (this.dependencies.indexOf("igGridExcelExporter") !== -1 - && files.indexOf("modules/infragistics.gridexcelexporter.js") === -1) { - files.push("modules/infragistics.gridexcelexporter.js"); - ProjectConfig.setConfig(config); - } - } - - protected folderName(pathName: string): string { - //TODO: should remove the spaces - const parts = path.parse(pathName); - let folderName = pathName; - if (parts.dir) { - folderName = path.join(parts.dir, parts.name); - folderName = folderName.replace(/\\/g, "/"); - // TODO: config-based "src/app"? - const relative = path.join(process.cwd(), "src/app", folderName); - // path.join will also resolve any ".." segments - // so if relative result doesn't start with CWD it's out of project root - if (!relative.startsWith(process.cwd())) { - Util.error(`Path ${"src/app/" + folderName} is not valid!`, "red"); - process.exit(1); - } - //clean up potential leading spaces in folder names (`path/ name`): - folderName = folderName.replace(/\/\s+/g, "/"); - } - return Util.lowerDashed(folderName); - } - - protected fileName(pathName: string): string { - const name = Util.nameFromPath(pathName); - return Util.lowerDashed(name); - } -} diff --git a/spec/unit/add-spec.ts b/spec/unit/add-spec.ts index dab603d60..9bf01b9bf 100644 --- a/spec/unit/add-spec.ts +++ b/spec/unit/add-spec.ts @@ -6,7 +6,6 @@ import * as path from "path"; import * as ts from "typescript"; import { default as addCmd } from "../../packages/cli/lib/commands/add"; import { PromptSession } from "../../packages/cli/lib/PromptSession"; -import { AngularTemplate } from "../../packages/cli/lib/templates/AngularTemplate"; import { resetSpy } from "../helpers/utils"; function createMockBaseTemplate(): BaseTemplate { @@ -312,75 +311,6 @@ describe("Unit - Add command", () => { expect(addCmd.templateManager.updateProjectConfiguration).toHaveBeenCalledTimes(1); }); - it("Should properly accept module args when passed - Angular Wrappers", async () => { - const mockProjectConfig = { - project: { - framework: "angular", - theme: "infragistics" - } - } as unknown as Config; - spyOn(TypeScriptUtils, "getFileSource").and.returnValue( - ts.createSourceFile("test-file-name", ``, ts.ScriptTarget.Latest, true) - ); - const routeSpy = spyOn(AngularTypeScriptFileUpdate.prototype, "addRoute"); - // const declarationSpy = spyOn(AngularTypeScriptFileUpdate.prototype, "addDeclaration").and.callThrough(); - const ngMetaSpy = spyOn(AngularTypeScriptFileUpdate.prototype, "addNgModuleMeta"); - const finalizeSpy = spyOn(AngularTypeScriptFileUpdate.prototype, "finalize"); - const mockTemplate = new AngularTemplate("test"); - mockTemplate.packages = []; - mockTemplate.dependencies = []; - - const directoryPath = path.join("My/Example/Path"); - spyOn(process, "cwd").and.returnValue(directoryPath); - spyOn(mockTemplate, "generateConfig"); - spyOn(Util, "processTemplates").and.returnValue(Promise.resolve(true)); - spyOn(mockTemplate, "registerInProject").and.callThrough(); - spyOn(Util, "directoryExists").and.returnValue(true); - // const sourceFilesSpy = spyOn(mockTemplate, "ensureSourceFiles"); - const mockLibrary = jasmine.createSpyObj("frameworkLibrary", ["hasTemplate", "getTemplateById"]); - mockLibrary.hasTemplate.and.returnValue(true); - mockLibrary.getTemplateById.and.returnValue(mockTemplate); - addCmd.templateManager = jasmine.createSpyObj("TemplateManager", { - getFrameworkById: {}, - getProjectLibrary: mockLibrary, - updateProjectConfiguration: () => {} - }); - spyOn(ProjectConfig, "getConfig").and.returnValue(mockProjectConfig); - spyOn(ProjectConfig, "hasLocalConfig").and.returnValue(true); - spyOn(addCmd, "addTemplate").and.callThrough(); - spyOn(PackageManager, "flushQueue").and.returnValue(Promise.resolve()); - spyOn(PackageManager, "ensureIgniteUISource"); - await addCmd.handler({ - name: "test-file-name", template: "CustomTemplate", - module: "myCustomModule/my-custom-module.module.ts", - _: ["add"], - $0: "add" - }); - expect(addCmd.addTemplate).toHaveBeenCalledWith( - "test-file-name", mockTemplate, - jasmine.objectContaining({ modulePath: "myCustomModule/my-custom-module.module.ts" }) - ); - expect(PackageManager.flushQueue).toHaveBeenCalled(); - expect(mockTemplate.generateConfig).toHaveBeenCalledTimes(1); - expect(mockTemplate.generateConfig).toHaveBeenCalledWith( - "test-file-name", - jasmine.objectContaining({ modulePath: "myCustomModule/my-custom-module.module.ts" }) - ); - expect(mockTemplate.registerInProject).toHaveBeenCalledTimes(1); - expect(mockTemplate.registerInProject).toHaveBeenCalledWith( - directoryPath, "test-file-name", - jasmine.objectContaining({ modulePath: "myCustomModule/my-custom-module.module.ts" }));; - expect(routeSpy).toHaveBeenCalledTimes(1); - expect(ngMetaSpy).toHaveBeenCalledTimes(1); - expect(ngMetaSpy).toHaveBeenCalledWith({ - declare: ["TestFileNameComponent"], - from: "../components/test-file-name/test-file-name.component", - export: [ 'TestFileNameComponent' ] - }); - expect(finalizeSpy).toHaveBeenCalledTimes(2); - expect(addCmd.templateManager.updateProjectConfiguration).toHaveBeenCalledTimes(1); - }); - it("Should properly accept skip-route args when passed", async () => { const mockProjectConfig = { project: { @@ -442,7 +372,7 @@ describe("Unit - Add command", () => { spyOn(Util, "fileExists").and.returnValue(false); spyOn(Util, "error"); const wrongPath = "myCustomModule/my-custom-module.module.ts"; - addCmd.addTemplate("test-file-name", new AngularTemplate(__dirname), { modulePath: wrongPath }); + addCmd.addTemplate("test-file-name", new IgniteUIForAngularTemplate(__dirname), { modulePath: wrongPath }); expect(Util.fileExists).toHaveBeenCalledTimes(1); expect(Util.error).toHaveBeenCalledTimes(1); expect(Util.error).toHaveBeenCalledWith(`Wrong module path provided: ${wrongPath}. No components were added!`); diff --git a/spec/unit/base-templates/AngularTemplate-spec.ts b/spec/unit/base-templates/AngularTemplate-spec.ts deleted file mode 100644 index fdde8136d..000000000 --- a/spec/unit/base-templates/AngularTemplate-spec.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { App, Config, ProjectConfig, Util } from "@igniteui/cli-core"; -import * as path from "path"; -import { AngularTemplate } from "../../../packages/cli/lib/templates/AngularTemplate"; -import { AngularTypeScriptFileUpdate } from "@igniteui/angular-templates"; - -describe("Unit - AngularTemplate Base", () => { - class TestTemplate extends AngularTemplate { - constructor() { - super("root/path"); - this.name = "Test Template"; - this.description = "test description"; - } - } - class TestWidgetTemplate extends AngularTemplate { - public widget = "widget no-process"; - } - - it("generateConfig call processTemplates with correct path and variables", async () => { - const expected = { - name: "my component", - ClassName: "MyComponent", - path: "my-component", - filePrefix: "my-component", - description: "test description", - cliVersion: Util.version(), - camelCaseName: "myComponent", - nameMerged: "TestTemplate" - }; - spyOn(Util, "processTemplates"); - // const validateSpy = spyOn(Util, "validateTemplate").and.returnValue(true); - - const templ = new TestTemplate(); - const actual = templ.generateConfig("my component", {}); - expect(actual).toEqual(expected); - // expect(validateSpy).toHaveBeenCalledWith( - // path.join("root/path" , "files"), - // "/target/path", - // expected, {}); - // expect(Util.processTemplates).toHaveBeenCalledWith( - // path.join("root/path" , "files"), - // "/target/path", - // expected, {}); - }); - - it("generateConfig merge passed variables under extraConfig (only)", async () => { - const expected = { - name: "page", - ClassName: "Page", - path: "page", - filePrefix: "page", - description: undefined, - // widget - widget: "widget no-process", - // extra - extraConfig1 : "extraConfig1", - camelCaseName: "page", - gridFeatures : "{ features }", - cliVersion: Util.version() - }; - spyOn(Util, "processTemplates"); - // const validateSpy = spyOn(Util, "validateTemplate").and.returnValue(true); - - const templ = new TestWidgetTemplate("root"); - let actual = templ.generateConfig("page", { extraConfig : { - extraConfig1 : "extraConfig1", - gridFeatures : "{ features }" - } }); - expect(actual).toEqual(expected); - // expect(validateSpy).toHaveBeenCalledWith( - // path.join("root" , "files"), - // "/target/path", - // expected, {}); - // expect(Util.processTemplates).toHaveBeenCalledWith( - // path.join("root" , "files"), - // "/target/path", - // expected, {}); - actual = templ.generateConfig("page", { - extraConfig : { - extraConfig1 : "extraConfig1", - gridFeatures : "{ features }" - }, - someOtherVar: "some/some.module.ts", - someThirdVar: false - }); - expect(actual).toEqual(expected); - }); - - describe("registerInProject", () => { - let helpers; - beforeEach(() => { - const tsUpdateMock = jasmine.createSpyObj( - "AngularTypeScriptFileUpdate", ["addRoute", "addNgModuleMeta", "finalize"]) as AngularTypeScriptFileUpdate; - function AngularTypeScriptFileUpdate() { - this.addRoute = tsUpdateMock.addRoute; - this.addNgModuleMeta = tsUpdateMock.addNgModuleMeta; - this.finalize = tsUpdateMock.finalize; - } - - helpers = { - tsUpdateMock, - AngularTypeScriptFileUpdate, - requireMock: require - } - - // spy on require: - spyOn(require("module"), "_load").and.callFake((modulePath: string) => { - if (modulePath.endsWith("@igniteui/angular-templates")) { - return helpers; - } else if (modulePath.endsWith("@igniteui/cli-core/packages/components")) { - return { dv: ["igDvWidget"] }; - } - }); - spyOn(helpers, "AngularTypeScriptFileUpdate").and.callThrough(); - - const mockFileSystem = { - fileExists: jasmine.createSpy().and.returnValue(false), - readFile: jasmine.createSpy().and.returnValue(JSON.stringify({ key: "value" })), - writeFile: jasmine.createSpy().and.callThrough() - }; - spyOn(App.container, 'get').and.returnValue(mockFileSystem); - - const mockProjectConfig = { - project: { - sourceFiles: ["existing"] - } - } as unknown as Config; - // return through function to get new obj ref each time - spyOn(ProjectConfig, "getConfig").and.callFake(() => (mockProjectConfig)); - spyOn(ProjectConfig, "setConfig"); - }); - - it("registers route and declare component", async () => { - const templ = new TestTemplate(); - templ.registerInProject("target/path", "view name"); - expect(helpers.AngularTypeScriptFileUpdate) - .toHaveBeenCalledWith(path.join("target/path", "src/app/app-routing-module.ts"), false, { singleQuotes: false }); - expect(helpers.tsUpdateMock.addRoute).toHaveBeenCalledWith( - { - path: 'view-name', - identifierName: 'ViewNameComponent', - modulePath: './components/view-name/view-name.component', - data: { text: 'view name' } - } - ); - - expect(helpers.AngularTypeScriptFileUpdate) - .toHaveBeenCalledWith(path.join("target/path", "src/app/app-module.ts"), false, { singleQuotes: false }); - expect(helpers.tsUpdateMock.addNgModuleMeta).toHaveBeenCalledWith( - { - declare: [ - "ViewNameComponent", - ], - from: "./components/view-name/view-name.component", - export: [], - } - ); - expect(helpers.tsUpdateMock.finalize).toHaveBeenCalled(); - - //config update: - expect(ProjectConfig.setConfig).toHaveBeenCalledTimes(0); - }); - it("should skip route if skipRoute is passed", async () => { - const templ = new TestTemplate(); - templ.registerInProject("target/path", "view name", { skipRoute: true }); - expect(helpers.tsUpdateMock.addRoute).toHaveBeenCalledTimes(0); - - // just declare - expect(helpers.AngularTypeScriptFileUpdate).toHaveBeenCalledTimes(1); - expect(helpers.AngularTypeScriptFileUpdate).toHaveBeenCalledWith(path.join("target/path", "src/app/app-module.ts"), - false, { singleQuotes: false }); - expect(helpers.tsUpdateMock.addNgModuleMeta).toHaveBeenCalledWith( - { - declare: [ - "ViewNameComponent", - ], - from: "./components/view-name/view-name.component", - export: [], - } - ); - expect(helpers.tsUpdateMock.finalize).toHaveBeenCalled(); - - //config update: - expect(ProjectConfig.setConfig).toHaveBeenCalledTimes(0); - }); - it("updates project config", async () => { - const templ = new TestTemplate(); - templ.dependencies.push("igDvWidget"); - templ.registerInProject("", ""); - const firstMockProjectConfig = { - project: { - sourceFiles: ["existing", "infragistics.dv.js"] - } - } as unknown as Config; - expect(ProjectConfig.setConfig).toHaveBeenCalledWith(firstMockProjectConfig); - - templ.dependencies.push("igExcel"); - templ.registerInProject("", ""); - const secondMockProjectConfig = { - project: { - sourceFiles: ["existing", "infragistics.dv.js", "infragistics.excel-bundled.js"] - } - } as unknown as Config; - expect(ProjectConfig.setConfig).toHaveBeenCalledWith(secondMockProjectConfig); - - templ.dependencies.push("igGridExcelExporter"); - templ.registerInProject("", ""); - const thirdMockProjectConfig = { - project: { - sourceFiles: [ - "existing", - "infragistics.dv.js", - "infragistics.excel-bundled.js", - "modules/infragistics.gridexcelexporter.js" - ] - } - } as unknown as Config; - expect(ProjectConfig.setConfig).toHaveBeenCalledWith(thirdMockProjectConfig); - }); - }); -});