From 906f5a3eeb35b64b132ca62454611327a2e8e6bd Mon Sep 17 00:00:00 2001 From: yavorsk Date: Tue, 30 Jul 2024 18:26:27 +0300 Subject: [PATCH] merge angular.json as we do for package.json upon initialization; unit tests --- .../src/common/processes/transform.test.ts | 44 ++++++ .../src/common/processes/transform.ts | 7 + .../src/common/test-data/test.json | 9 ++ .../src/common/utils/helpers.test.ts | 33 +++++ .../src/common/utils/helpers.ts | 8 +- .../templates/angular-xmcloud/angular.json | 136 +----------------- 6 files changed, 101 insertions(+), 136 deletions(-) create mode 100644 packages/create-sitecore-jss/src/common/test-data/test.json diff --git a/packages/create-sitecore-jss/src/common/processes/transform.test.ts b/packages/create-sitecore-jss/src/common/processes/transform.test.ts index 6b91bef4f0..de9ef21856 100644 --- a/packages/create-sitecore-jss/src/common/processes/transform.test.ts +++ b/packages/create-sitecore-jss/src/common/processes/transform.test.ts @@ -477,6 +477,7 @@ describe('transform', () => { let writeFileToPathStub: SinonStub; let transformFilenameStub: SinonStub; let openPackageJsonStub: SinonStub; + let openJsonStub: SinonStub; let log: SinonStub; beforeEach(() => { @@ -496,6 +497,7 @@ describe('transform', () => { writeFileToPathStub?.restore(); transformFilenameStub?.restore(); openPackageJsonStub?.restore(); + openJsonStub?.restore(); log?.restore(); }); @@ -693,6 +695,48 @@ describe('transform', () => { }); }); + it('should merge json file', async () => { + const templatePath = path.resolve('templates/next'); + const destinationPath = path.resolve('samples/next'); + const file = 'test.json'; + const renderFileOutput = '{ "one": 1, "two": 2}'; + const currentJson = { three: 3, four: 4 }; + const templateJson = JSON.parse(renderFileOutput); + const mergedPkg = { merged: true }; + + globSyncStub = sinon.stub(glob, 'sync').returns([file]); + fsExistsSyncStub = sinon.stub(fs, 'existsSync').returns(true); + openJsonStub = sinon.stub(helpers, 'openJson').returns(currentJson); + ejsRenderFileStub = sinon.stub(ejs, 'renderFile').returns(Promise.resolve(renderFileOutput)); + mergeStub = sinon.stub(transform, 'merge').returns(mergedPkg); + diffAndWriteFilesStub = sinon.stub(transform, 'diffAndWriteFiles'); + + const answers = { + destination: destinationPath, + templates: [], + appPrefix: false, + force: false, + }; + + await transformFunc(templatePath, answers); + + expect(ejsRenderFileStub).to.have.been.calledOnceWith(path.join(templatePath, file), { + ...answers, + helper: { + isDev: false, + getPascalCaseName: helpers.getPascalCaseName, + getAppPrefix: helpers.getAppPrefix, + }, + }); + expect(mergeStub).to.have.been.calledOnceWith(currentJson, templateJson); + expect(openJsonStub).to.have.been.calledOnceWith(`${destinationPath}\\${file}`); + expect(diffAndWriteFilesStub).to.have.been.calledOnceWith({ + rendered: JSON.stringify(mergedPkg, null, 2), + pathToNewFile: path.join(destinationPath, file), + answers, + }); + }); + it('should concatenate .env file', async () => { const templatePath = path.resolve('templates/next'); const destinationPath = path.resolve('samples/next'); diff --git a/packages/create-sitecore-jss/src/common/processes/transform.ts b/packages/create-sitecore-jss/src/common/processes/transform.ts index f8034dc631..49fc368da9 100644 --- a/packages/create-sitecore-jss/src/common/processes/transform.ts +++ b/packages/create-sitecore-jss/src/common/processes/transform.ts @@ -9,6 +9,7 @@ import { getPascalCaseName, getAppPrefix, openPackageJson, + openJson, sortKeys, writeFileToPath, isDevEnvironment, @@ -290,6 +291,12 @@ export const transform = async ( // merge them and set the result to str which will then go through diff const merged = merge(currentPkg, templatePkg); str = JSON.stringify(merged, null, 2); + } else if (file.endsWith('.json') && fs.existsSync(pathToNewFile)) { + // we have other json file use simililar logic as for package.json to merge it + const currentJsonFile = openJson(pathToNewFile); + const templateJsonFile = JSON.parse(await renderFile(path.resolve(pathToTemplate), ejsData)); + const merged = merge(currentJsonFile, templateJsonFile); + str = JSON.stringify(merged, null, 2); } if (file.endsWith('.env') && fs.existsSync(pathToNewFile)) { diff --git a/packages/create-sitecore-jss/src/common/test-data/test.json b/packages/create-sitecore-jss/src/common/test-data/test.json new file mode 100644 index 0000000000..e0a534276f --- /dev/null +++ b/packages/create-sitecore-jss/src/common/test-data/test.json @@ -0,0 +1,9 @@ +{ + "first": "test first", + "second": "test second", + "description": "Test package.json", + "third": { + "thirdOne": "tests third one" + }, + "array": ["one", "two"] +} \ No newline at end of file diff --git a/packages/create-sitecore-jss/src/common/utils/helpers.test.ts b/packages/create-sitecore-jss/src/common/utils/helpers.test.ts index 5621f4c651..e7fef7a9cd 100644 --- a/packages/create-sitecore-jss/src/common/utils/helpers.test.ts +++ b/packages/create-sitecore-jss/src/common/utils/helpers.test.ts @@ -13,9 +13,11 @@ import { getBaseTemplates, getAppPrefix, saveConfiguration, + openJson, } from './helpers'; import { JsonObjectType } from '../processes/transform'; import testPackage from '../test-data/test.package.json'; +import testJson from '../test-data/test.json'; import rootPackage from '../../../package.json'; import { Initializer } from '../Initializer'; import { InitializerFactory } from '../../InitializerFactory'; @@ -80,6 +82,37 @@ describe('helpers', () => { }); }); + describe('openJson', () => { + let log: SinonStub; + + it('should return json data using provided path', () => { + const filePath = path.resolve('src', 'common', 'test-data', 'test.json'); + + const result = openJson(filePath); + + expect(result).to.deep.equal(testJson); + }); + + it('should throw an error when the path to the package does not exist', () => { + log = sinon.stub(console, 'log'); + + const filePath = path.resolve('not', 'existing', 'path', 'test.json'); + + const result = openJson(filePath); + + expect(result).to.equal(undefined); + expect(log.calledTwice).to.equal(true); + expect(log.getCall(0).args[0]).to.equal( + chalk.red(`The following error occurred while trying to read ${filePath}:`) + ); + expect(log.getCall(1).args[0]).to.equal( + chalk.red(`Error: ENOENT: no such file or directory, open '${filePath}'`) + ); + + log.restore(); + }); + }); + describe('writePackageJson', () => { let log: SinonStub; let writeFileSync: SinonStub; diff --git a/packages/create-sitecore-jss/src/common/utils/helpers.ts b/packages/create-sitecore-jss/src/common/utils/helpers.ts index f0521304e4..3b23709472 100644 --- a/packages/create-sitecore-jss/src/common/utils/helpers.ts +++ b/packages/create-sitecore-jss/src/common/utils/helpers.ts @@ -32,11 +32,15 @@ export const getPascalCaseName = (name: string): string => { */ export const openPackageJson = (pkgPath?: string) => { const filePath = path.resolve(pkgPath ?? `.${sep}package.json`); + return openJson(filePath); +}; + +export const openJson = (jsonPath: string) => { try { - const data = fs.readFileSync(filePath, 'utf8'); + const data = fs.readFileSync(jsonPath, 'utf8'); return data ? JSON.parse(data) : undefined; } catch (error) { - console.log(chalk.red(`The following error occurred while trying to read ${filePath}:`)); + console.log(chalk.red(`The following error occurred while trying to read ${jsonPath}:`)); console.log(chalk.red(error)); } }; diff --git a/packages/create-sitecore-jss/src/templates/angular-xmcloud/angular.json b/packages/create-sitecore-jss/src/templates/angular-xmcloud/angular.json index e270fbc220..353c7e6f2e 100644 --- a/packages/create-sitecore-jss/src/templates/angular-xmcloud/angular.json +++ b/packages/create-sitecore-jss/src/templates/angular-xmcloud/angular.json @@ -1,25 +1,9 @@ { - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "cli": { - "analytics": false - }, - "version": 1, - "newProjectRoot": "projects", "projects": { "<%- appName %>": { - "root": ".", - "sourceRoot": "src", - "projectType": "application", "architect": { "build": { - "builder": "@angular-builders/custom-webpack:browser", "options": { - "outputPath": "dist/browser/", - "index": "src/index.html", - "main": "src/main.ts", - "tsConfig": "src/tsconfig.app.json", - "polyfills": "src/polyfills.ts", - "assets": ["src/assets", "src/favicon.ico"], "styles": [ "node_modules/bootstrap/dist/css/bootstrap.min.css", "src/styles.css", @@ -27,128 +11,12 @@ ], "stylePreprocessorOptions": { "includePaths": ["src/assets/styles", "node_modules"] - }, - "scripts": [], - "allowedCommonJsDependencies": [ - "zen-observable", - "js-sha256", - "url-parse", - "graphql-request", - "debug" - ], - "customWebpackConfig": { - "path": "./webpack.config.js" - } - }, - "configurations": { - "production": { - "budgets": [ - { - "type": "anyComponentStyle", - "maximumWarning": "6kb" - } - ], - "baseHref": "/", - "aot": true, - "//": [ - "You might want to adjust the optimization entry to workaround a bug with bootstrap warnings caused by Angular", - "The warnings may occur during build and when running connected mode. Check below for possible fixes.", - "https://github.com/ng-bootstrap/ng-bootstrap/issues/4306" - ], - "optimization": "true", - "outputHashing": "all", - "sourceMap": false, - "namedChunks": false, - "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, - "fileReplacements": [ - { - "replace": "src/environments/environment.js", - "with": "src/environments/environment.prod.js" - } - ] - } - } - }, - "serve": { - "builder": "@angular-builders/custom-webpack:dev-server", - "options": { - "browserTarget": "<%- appName %>:build", - "port": 3000, - "proxyConfig": "proxy.conf.js" - }, - "configurations": { - "production": { - "browserTarget": "<%- appName %>:build:production" } } }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "<%- appName %>:build" - } - }, "test": { - "builder": "@angular-devkit/build-angular:karma", - "options": { - "main": "src/test.ts", - "karmaConfig": "./karma.conf.js", - "polyfills": "src/polyfills.ts", - "tsConfig": "src/tsconfig.spec.json", - "scripts": [], - "styles": ["src/styles.css", "src/assets/styles/main.scss"], - "assets": ["src/assets", "src/favicon.ico"] - } - }, - "lint": { - "builder": "@angular-eslint/builder:lint", - "options": { - "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"] - } - }, - "server": { - "builder": "@angular-devkit/build-angular:server", - "options": { - "main": "server.bundle.ts", - "tsConfig": "src/tsconfig.server.json", - "deleteOutputPath": false, - "outputHashing": "none" - }, - "configurations": { - "production": { - "outputHashing": "media", - "sourceMap": false, - "optimization": true, - "fileReplacements": [ - { - "replace": "src/environments/environment.js", - "with": "src/environments/environment.prod.js" - } - ] - } - } - } - } - }, - "angular-e2e": { - "root": "", - "sourceRoot": "", - "projectType": "application", - "architect": { - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", - "options": { - "protractorConfig": "./protractor.conf.js", - "devServerTarget": "<%- appName %>:serve" - } - }, - "lint": { - "builder": "@angular-eslint/angular-eslint", "options": { - "tsConfig": ["e2e/tsconfig.e2e.json"], - "exclude": ["**/node_modules/**"] + "styles": ["src/styles.css", "src/assets/styles/main.scss"] } } } @@ -157,7 +25,7 @@ "schematics": { "@schematics/angular:component": { "prefix": "app", - "style": "css" + "style": "scss" }, "@schematics/angular:directive": { "prefix": "app"