From b58e71293ce937d11cf6f7789a6c5082c0d461cc Mon Sep 17 00:00:00 2001 From: Lars Kissel Date: Tue, 12 Oct 2021 16:29:55 +0200 Subject: [PATCH] [INTERNAL] Improve manifest creation, add unit test --- lib/middleware/versionInfo.js | 23 ++--- test/lib/server/main.js | 42 ++++----- test/lib/server/middleware/versionInfo.js | 102 +++++++++++++++++++++- 3 files changed, 129 insertions(+), 38 deletions(-) diff --git a/lib/middleware/versionInfo.js b/lib/middleware/versionInfo.js index e8b7e9fa..fc49e6c7 100644 --- a/lib/middleware/versionInfo.js +++ b/lib/middleware/versionInfo.js @@ -1,6 +1,5 @@ -const log = require("@ui5/logger").getLogger("server:middleware:versionInfo"); const createVersionInfoProcessor = require("@ui5/builder").processors.versionInfoGenerator; -const manifestCreator = require("@ui5/builder").processors.manifestCreator; +const createManifestProcessor = require("@ui5/builder").processors.manifestCreator; const MANIFEST_JSON = "manifest.json"; @@ -35,18 +34,14 @@ function createMiddleware({resources, tree: project}) { const extensions = "js,json,library,less,css,theming,theme,properties"; const libResources = await dependencies.byGlob(`/resources/${namespace}/**/*.{${extensions}}`); - try { - libraryManifest = await manifestCreator({ - libraryResource: dotLibResource, - namespace, - resources: libResources, - options: {} - }); - } catch (err) { - // if the manifest creation fails (e.g. because of a missing project dependency), - // the processing of the version info shouldn't be interrupted - log.warn(err.message); - } + libraryManifest = await createManifestProcessor({ + libraryResource: dotLibResource, + namespace, + resources: libResources, + options: { + omitMinVersions: true + } + }); } return { libraryManifest, diff --git a/test/lib/server/main.js b/test/lib/server/main.js index 4dd54dc8..9648a568 100644 --- a/test/lib/server/main.js +++ b/test/lib/server/main.js @@ -1,23 +1,14 @@ const test = require("ava"); -const sinon = require("sinon"); const supertest = require("supertest"); const ui5Server = require("../../../"); const server = ui5Server.server; const normalizer = require("@ui5/project").normalizer; -const logger = require("@ui5/logger"); let request; let serve; // Start server before running tests test.before((t) => { - t.context.versionInfoLogger = { - warn: sinon.stub() - }; - sinon.stub(logger, "getLogger") - .callThrough() - .withArgs("server:middleware:versionInfo").returns(t.context.versionInfoLogger); - return normalizer.generateProjectTree({ cwd: "./test/fixtures/application.a" }).then((tree) => { @@ -31,7 +22,6 @@ test.before((t) => { }); test.after.always(() => { - sinon.restore(); return new Promise((resolve, reject) => { serve.close((error) => { if (error) { @@ -222,17 +212,6 @@ test("Get sap-ui-version.json from versionInfo middleware (/resources/sap-ui-ver } t.deepEqual(res.statusCode, 200, "Correct HTTP status code"); - const {versionInfoLogger} = t.context; - t.is(versionInfoLogger.warn.callCount, 4); - t.is(versionInfoLogger.warn.getCall(0).args[0], - "Couldn't find version for library 'sap.ui.core', project dependency missing?"); - t.is(versionInfoLogger.warn.getCall(1).args[0], - "Couldn't find version for library 'sap.ui.core', project dependency missing?"); - t.is(versionInfoLogger.warn.getCall(2).args[0], - "Couldn't find version for library 'sap.ui.core', project dependency missing?"); - t.is(versionInfoLogger.warn.getCall(3).args[0], - "Couldn't find version for library 'sap.ui.core', project dependency missing?"); - const buildTimestamp = res.body.buildTimestamp; t.deepEqual(res.body, { "name": "application.a", @@ -242,18 +221,39 @@ test("Get sap-ui-version.json from versionInfo middleware (/resources/sap-ui-ver "libraries": [ { name: "library.a", + manifestHints: { + dependencies: { + libs: { + "library.d": {} + } + } + }, version: "1.0.0", buildTimestamp, scmRevision: "" }, { name: "library.b", + manifestHints: { + dependencies: { + libs: { + "library.d": {} + } + } + }, version: "1.0.0", buildTimestamp, scmRevision: "" }, { name: "library.c", + manifestHints: { + dependencies: { + libs: { + "library.d": {} + } + } + }, version: "1.0.0", buildTimestamp, scmRevision: "" diff --git a/test/lib/server/middleware/versionInfo.js b/test/lib/server/middleware/versionInfo.js index 2be07965..99909608 100644 --- a/test/lib/server/middleware/versionInfo.js +++ b/test/lib/server/middleware/versionInfo.js @@ -1,7 +1,8 @@ const test = require("ava"); -const ui5Fs = require("@ui5/fs"); -const resourceFactory = ui5Fs.resourceFactory; -const versionInfoMiddleware = require("../../../../lib/middleware/versionInfo"); +const sinon = require("sinon"); +const mock = require("mock-require"); +const resourceFactory = require("@ui5/fs").resourceFactory; +let versionInfoMiddleware = require("../../../../lib/middleware/versionInfo"); function createWorkspace() { return resourceFactory.createAdapter({ @@ -152,6 +153,101 @@ async function assertCreatedVersionInfo(t, expectedVersionInfo, versionInfoConte t.deepEqual(currentVersionInfo, expectedVersionInfo, "Correct content"); } +test.beforeEach((t) => { + versionInfoMiddleware = mock.reRequire("../../../../lib/middleware/versionInfo"); +}); + +test.afterEach.always((t) => { + sinon.restore(); + mock.stopAll(); +}); + +test.serial("todo", async (t) => { + let stubCount = 0; + const manifestCreatorStub = sinon.stub().callsFake(() => `stubbed manifest ${stubCount++}`); + const dummyVersionInfo = resourceFactory.createResource({ + path: "/dummy/path", + string: "stubbed version info" + }); + const versionInfoGeneratorStub = sinon.stub().returns([dummyVersionInfo]); + mock("@ui5/builder", { + processors: { + manifestCreator: manifestCreatorStub, + versionInfoGenerator: versionInfoGeneratorStub + } + }); + versionInfoMiddleware = mock.reRequire("../../../../lib/middleware/versionInfo"); + + const dependencies = createDependencies({virBasePath: "/"}); + // create lib.a without manifest + await createDotLibrary(dependencies, resourceFactory, ["lib", "a"], [{name: "lib.b"}, {name: "lib.c"}]); + // create lib.b with manifest: no manifestCreator call expected + await createResources(dependencies, resourceFactory, ["lib", "b"], []); + // create lib.c without manifest but with dummy files + await createDotLibrary(dependencies, resourceFactory, ["lib", "c"]); + [ + // relevant file extensions for manifest creation + "js", "json", "less", "css", "theming", "theme", "properties", + // other file extensions are irrelevant + "html", "txt", "ts" + ].forEach(async (extension) => { + await dependencies.write(resourceFactory.createResource({path: `/resources/lib/c/foo.${extension}`})); + }); + + const resources = {dependencies}; + const tree = { + metadata: { + name: "myname" + }, + version: "1.33.7" + }; + const middleware = versionInfoMiddleware({resources, tree}); + + const endStub = sinon.stub(); + await middleware( + /* req */ undefined, + /* res */ {writeHead: function() {}, end: endStub}, + /* next */ function() {}); + + t.is(manifestCreatorStub.callCount, 2); + t.is(manifestCreatorStub.getCall(0).args[0].libraryResource.getPath(), "/resources/lib/a/.library"); + t.is(manifestCreatorStub.getCall(1).args[0].libraryResource.getPath(), "/resources/lib/c/.library"); + t.is(manifestCreatorStub.getCall(0).args[0].namespace, "lib/a"); + t.is(manifestCreatorStub.getCall(1).args[0].namespace, "lib/c"); + t.deepEqual( + manifestCreatorStub.getCall(0).args[0].resources.map((resource) => resource.getPath()), + ["/resources/lib/a/.library"]); + t.deepEqual( + manifestCreatorStub.getCall(1).args[0].resources.map((resource) => resource.getPath()).sort(), + [ + "/resources/lib/c/.library", + "/resources/lib/c/foo.css", + "/resources/lib/c/foo.js", + "/resources/lib/c/foo.json", + "/resources/lib/c/foo.less", + "/resources/lib/c/foo.properties", + "/resources/lib/c/foo.theme", + "/resources/lib/c/foo.theming" + ]); + t.deepEqual(manifestCreatorStub.getCall(0).args[0].options, {omitMinVersions: true}); + t.deepEqual(manifestCreatorStub.getCall(1).args[0].options, {omitMinVersions: true}); + + t.is(versionInfoGeneratorStub.callCount, 1); + const versionInfoGeneratorOptions = versionInfoGeneratorStub.getCall(0).args[0].options; + t.is(versionInfoGeneratorOptions.rootProjectName, "myname"); + t.is(versionInfoGeneratorOptions.rootProjectVersion, "1.33.7"); + t.is(versionInfoGeneratorOptions.libraryInfos.length, 3); + t.is(versionInfoGeneratorOptions.libraryInfos[0].name, "lib.a"); + t.is(versionInfoGeneratorOptions.libraryInfos[0].libraryManifest, "stubbed manifest 0"); + t.is(versionInfoGeneratorOptions.libraryInfos[1].name, "lib.b"); + t.is(versionInfoGeneratorOptions.libraryInfos[1].libraryManifest.getPath(), "/resources/lib/b/manifest.json"); + t.is(versionInfoGeneratorOptions.libraryInfos[2].name, "lib.c"); + t.is(versionInfoGeneratorOptions.libraryInfos[2].libraryManifest, "stubbed manifest 1"); + + t.is(endStub.callCount, 1); + t.deepEqual(endStub.getCall(0).args[0], "stubbed version info"); +}); + // test case taken from: ui5-builder/test/lib/tasks/generateVersionInfo.js test.serial("integration: Library with dependencies and subcomponent complex scenario", async (t) => { const workspace = createWorkspace();