From 391eb84e8f0edc7ffc7e321d01a0d92b1ea07f0a Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 2 May 2018 14:10:35 +0300 Subject: [PATCH] fix(assets-generation): Do not fail in case some App_Resources are missing In case you delete `App_Resources/iOS` directory, the `getAssetsStructure` method fails as it tries to read `Content.json` files from the deleted directory. Instead of failing, just return empty arrays for the images. This is already working this way for Android. Add test for the case --- lib/services/project-data-service.ts | 2 +- test/services/project-data-service.ts | 61 +++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index c4c38e17f2..a807cc18fe 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -125,7 +125,7 @@ export class ProjectDataService implements IProjectDataService { private async getIOSAssetSubGroup(dirPath: string): Promise { const pathToContentJson = path.join(dirPath, AssetConstants.iOSResourcesFileName); - const content = this.$fs.readJson(pathToContentJson); + const content = this.$fs.exists(pathToContentJson) && this.$fs.readJson(pathToContentJson) || { images: [] }; const imageDefinitions = this.getImageDefinitions().ios; diff --git a/test/services/project-data-service.ts b/test/services/project-data-service.ts index 32e08d6dc9..e1f68149fb 100644 --- a/test/services/project-data-service.ts +++ b/test/services/project-data-service.ts @@ -2,8 +2,9 @@ import { Yok } from "../../lib/common/yok"; import { assert } from "chai"; import { ProjectDataService } from "../../lib/services/project-data-service"; import { LoggerStub } from "../stubs"; -import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER } from '../../lib/constants'; +import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER, PACKAGE_JSON_FILE_NAME, AssetConstants } from '../../lib/constants'; import { DevicePlatformsConstants } from "../../lib/common/mobile/device-platforms-constants"; +import { basename } from "path"; const CLIENT_NAME_KEY_IN_PROJECT_FILE = "nativescript"; @@ -53,19 +54,38 @@ const createTestInjector = (readTextData?: string): IInjector => { readText: (filename: string, encoding?: IReadFileOptions | string): string => { return readTextData; - } + }, + + exists: (filePath: string): boolean => basename(filePath) === PACKAGE_JSON_FILE_NAME, + + readJson: (filePath: string): any => null, + + enumerateFilesInDirectorySync: (directoryPath: string, + filterCallback?: (_file: string, _stat: IFsStats) => boolean, + opts?: { enumerateDirectories?: boolean, includeEmptyDirectories?: boolean }, + foundFiles?: string[]): string[] => [] }); testInjector.register("logger", LoggerStub); testInjector.register("projectDataService", ProjectDataService); - testInjector.register("androidResourcesMigrationService", {}); + testInjector.register("androidResourcesMigrationService", { + hasMigrated: (appResourcesDir: string): boolean => true + }); testInjector.register("devicePlatformsConstants", DevicePlatformsConstants); testInjector.register("injector", testInjector); + testInjector.register("errors", {}); + + testInjector.register("projectHelper", { + sanitizeName: (appName: string): string => appName + }); + + testInjector.register("options", {}); + return testInjector; }; @@ -244,4 +264,39 @@ describe("projectDataService", () => { assert.deepEqual(dataPassedToWriteJson, { dependencies: {} }); }); }); + + describe("getAssetsStructure", () => { + it("does not fail when App_Resources/Android and App_Resources/iOS do not exist", async () => { + const defaultEmptyData: any = {}; + defaultEmptyData[CLIENT_NAME_KEY_IN_PROJECT_FILE] = {}; + const testInjector = createTestInjector(JSON.stringify(defaultEmptyData)); + const fs = testInjector.resolve("fs"); + fs.readJson = (filePath: string): any => { + if (basename(filePath) === AssetConstants.imageDefinitionsFileName) { + return { android: {}, ios: {} }; + } + + throw new Error(`Unable to read file ${filePath}`); + }; + + const projectDataService = testInjector.resolve("projectDataService"); + const assetStructure = await projectDataService.getAssetsStructure({ projectDir: "." }); + const emptyAssetStructure: IAssetGroup = { + icons: { + images: [] + }, + splashBackgrounds: { + images: [] + }, + splashCenterImages: { + images: [] + }, + splashImages: { + images: [] + } + }; + + assert.deepEqual(assetStructure, { ios: emptyAssetStructure, android: _.merge(_.cloneDeep(emptyAssetStructure), { splashImages: null }) }); + }); + }); });