diff --git a/lib/tasks/bundlers/generateManifestBundle.js b/lib/tasks/bundlers/generateManifestBundle.js index fa5b19192..4f740e139 100644 --- a/lib/tasks/bundlers/generateManifestBundle.js +++ b/lib/tasks/bundlers/generateManifestBundle.js @@ -16,25 +16,29 @@ const BUNDLE_NAME = "manifest-bundle.zip"; * @param {string} parameters.options.namespace Namespace of the application/library * @returns {Promise} Promise resolving with undefined once data has been written */ -module.exports = function({workspace, options}) { - return workspace.byGlob(`/**/{${DESCRIPTOR},*${PROPERTIES_EXT}}`) - .then((allResources) => { - if (allResources.length > 0) { - return manifestBundler({ - resources: allResources, - options: { - descriptor: DESCRIPTOR, - propertiesExtension: PROPERTIES_EXT, - bundleName: BUNDLE_NAME, - namespace: options.namespace - } - }).then((processedResources) => { - return Promise.all(processedResources.map((resource) => { - return workspace.write(resource); - })); - }); - } else { - log.verbose(`Could not find a "${DESCRIPTOR}" file for project ${options.projectName}, creation of "${BUNDLE_NAME}" is skipped!`); - } - }); +module.exports = async function({workspace, options}) { + if (!options || !options.projectName || !options.namespace) { + throw new Error("[generateManifestBundle]: One or more mandatory options not provided"); + } + + const allResources = await workspace.byGlob(`/resources/${options.namespace}/**/{${DESCRIPTOR},*${PROPERTIES_EXT}}`); + if (allResources.length === 0) { + log.verbose(`Could not find a "${DESCRIPTOR}" file for project ${options.projectName}, ` + + `creation of "${BUNDLE_NAME}" is skipped!`); + return; + } + + const processedResources = await manifestBundler({ + resources: allResources, + options: { + descriptor: DESCRIPTOR, + propertiesExtension: PROPERTIES_EXT, + bundleName: BUNDLE_NAME, + namespace: options.namespace + } + }); + + await Promise.all(processedResources.map((resource) => { + return workspace.write(resource); + })); }; diff --git a/lib/types/library/LibraryBuilder.js b/lib/types/library/LibraryBuilder.js index af3cb5d65..806278ee8 100644 --- a/lib/types/library/LibraryBuilder.js +++ b/lib/types/library/LibraryBuilder.js @@ -123,7 +123,7 @@ class LibraryBuilder extends AbstractBuilder { return generateManifestBundle({ workspace: resourceCollections.workspace, options: { - projectType: project.type, + projectName: project.metadata.name, namespace: project.metadata.namespace } }); diff --git a/test/lib/tasks/bundlers/generateManifestBundle.js b/test/lib/tasks/bundlers/generateManifestBundle.js index 401924204..3cb5e9b5b 100644 --- a/test/lib/tasks/bundlers/generateManifestBundle.js +++ b/test/lib/tasks/bundlers/generateManifestBundle.js @@ -1,19 +1,105 @@ const test = require("ava"); const path = require("path"); +const sinon = require("sinon"); +const mock = require("mock-require"); + const chai = require("chai"); chai.use(require("chai-fs")); const assert = chai.assert; - +const {promisify} = require("util"); +const extractZip = promisify(require("extract-zip")); +const recursive = require("recursive-readdir"); const ui5Builder = require("../../../../"); const builder = ui5Builder.builder; +const generateManifestBundle = require("../../../../lib/tasks/bundlers/generateManifestBundle"); + +test.serial("generateManifestBundle", async (t) => { + const byGlobStub = sinon.stub().resolves(["some resource", "some other resource"]); + const writeStub = sinon.stub().resolves(); + const workspace = { + byGlob: byGlobStub, + write: writeStub + }; + + const manifestBundlerStub = sinon.stub().resolves(["some new resource", "some other new resource"]); + mock("../../../../lib/processors/bundlers/manifestBundler", manifestBundlerStub); + const generateManifestBundle = mock.reRequire("../../../../lib/tasks/bundlers/generateManifestBundle"); + + + await generateManifestBundle({ + workspace, + options: { + projectName: "some project", + namespace: "some/project" + } + }); + t.deepEqual(byGlobStub.callCount, 1, "workspace.byGlob got called once"); + t.deepEqual(byGlobStub.getCall(0).args[0], "/resources/some/project/**/{manifest.json,*.properties}", + "workspace.byGlob got called with the correct arguments"); + + t.deepEqual(manifestBundlerStub.callCount, 1, "manifestBundler got called once"); + t.deepEqual(manifestBundlerStub.getCall(0).args[0], { + resources: ["some resource", "some other resource"], + options: { + descriptor: "manifest.json", + propertiesExtension: ".properties", + bundleName: "manifest-bundle.zip", + namespace: "some/project" + } + }, "manifestBundler got called with the correct arguments"); + + t.deepEqual(writeStub.callCount, 2, "workspace.write got called twice"); + t.deepEqual(writeStub.getCall(0).args[0], "some new resource", + "workspace.write got called with the correct arguments"); + t.deepEqual(writeStub.getCall(1).args[0], "some other new resource", + "workspace.write got called with the correct arguments"); + + mock.stop("../../../../lib/processors/bundlers/manifestBundler"); +}); + +test.serial("generateManifestBundle with no resources", async (t) => { + const byGlobStub = sinon.stub().resolves([]); + const workspace = { + byGlob: byGlobStub + }; + + const manifestBundlerStub = sinon.stub().resolves([]); + mock("../../../../lib/processors/bundlers/manifestBundler", manifestBundlerStub); + const generateManifestBundle = mock.reRequire("../../../../lib/tasks/bundlers/generateManifestBundle"); + + + await generateManifestBundle({ + workspace, + options: { + projectName: "some project", + namespace: "some/project" + } + }); + t.deepEqual(byGlobStub.callCount, 1, "workspace.byGlob got called once"); + t.deepEqual(byGlobStub.getCall(0).args[0], "/resources/some/project/**/{manifest.json,*.properties}", + "workspace.byGlob got called with the correct arguments"); + + t.deepEqual(manifestBundlerStub.callCount, 0, "manifestBundler not called"); + + mock.stop("../../../../lib/processors/bundlers/manifestBundler"); +}); + +test("generateManifestBundle with missing parameters", async (t) => { + const error = await t.throwsAsync(generateManifestBundle({})); + t.deepEqual(error.message, "[generateManifestBundle]: One or more mandatory options not provided", + "Rejected with correct error message"); +}); + + +/* =================== + Integration Tests +*/ + const applicationBPath = path.join(__dirname, "..", "..", "..", "fixtures", "application.b"); const libraryCore = path.join(__dirname, "..", "..", "..", "fixtures", "sap.ui.core-evo"); const libraryKPath = path.join(__dirname, "..", "..", "..", "fixtures", "library.k"); -const {promisify} = require("util"); -const extractZip = promisify(require("extract-zip")); -const recursive = require("recursive-readdir"); const findFiles = (folder) => { return new Promise((resolve, reject) => { @@ -91,113 +177,7 @@ const applicationBTree = { "id": "application.b", "version": "1.0.0", "path": applicationBPath, - "dependencies": [ - { - "id": "library.d", - "version": "1.0.0", - "path": path.join(applicationBPath, "..", "library.d"), - "dependencies": [], - "_level": 1, - "specVersion": "0.1", - "type": "library", - "metadata": { - "name": "library.d", - "namespace": "library/d", - "copyright": "Some fancy copyright" - }, - "resources": { - "configuration": { - "paths": { - "src": "main/src", - "test": "main/test" - } - }, - "pathMappings": { - "/resources/": "main/src", - "/test-resources/": "main/test" - } - } - }, - { - "id": "library.a", - "version": "1.0.0", - "path": path.join(applicationBPath, "..", "collection", "library.a"), - "dependencies": [], - "_level": 1, - "specVersion": "0.1", - "type": "library", - "metadata": { - "name": "library.a", - "namespace": "library/a", - "copyright": "${copyright}" - }, - "resources": { - "configuration": { - "paths": { - "src": "src", - "test": "test" - } - }, - "pathMappings": { - "/resources/": "src", - "/test-resources/": "test" - } - } - }, - { - "id": "library.b", - "version": "1.0.0", - "path": path.join(applicationBPath, "..", "collection", "library.b"), - "dependencies": [], - "_level": 1, - "specVersion": "0.1", - "type": "library", - "metadata": { - "name": "library.b", - "namespace": "library/b", - "copyright": "${copyright}" - }, - "resources": { - "configuration": { - "paths": { - "src": "src", - "test": "test" - } - }, - "pathMappings": { - "/resources/": "src", - "/test-resources/": "test" - } - } - }, - { - "id": "library.c", - "version": "1.0.0", - "path": path.join(applicationBPath, "..", "collection", "library.c"), - "dependencies": [], - "_level": 1, - "specVersion": "0.1", - "type": "library", - "metadata": { - "name": "library.c", - "namespace": "library/c", - "copyright": "${copyright}" - }, - "resources": { - "configuration": { - "paths": { - "src": "src", - "test": "test" - } - }, - "pathMappings": { - "/resources/": "src", - "/test-resources/": "test" - } - } - } - ], - "builder": {}, + "dependencies": [], "_level": 0, "specVersion": "0.1", "type": "application", @@ -232,8 +212,7 @@ const libraryKTree = { "type": "library", "metadata": { "name": "sap.ui.core", - "namespace": "sap/ui/core", - "copyright": "Some fancy copyright" + "namespace": "sap/ui/core" }, "resources": { "configuration": { @@ -252,8 +231,7 @@ const libraryKTree = { "type": "library", "metadata": { "name": "library.k", - "namespace": "library/k", - "copyright": "UI development toolkit for HTML5 (OpenUI5)\n * (c) Copyright 2009-xxx SAP SE or an SAP affiliate company.\n * Licensed under the Apache License, Version 2.0 - see LICENSE.txt." + "namespace": "library/k" }, "resources": { "configuration": {