diff --git a/packages/builder/lib/processors/versionInfoGenerator.js b/packages/builder/lib/processors/versionInfoGenerator.js
index 21ff0d36c88..64f8b2a68ca 100644
--- a/packages/builder/lib/processors/versionInfoGenerator.js
+++ b/packages/builder/lib/processors/versionInfoGenerator.js
@@ -350,12 +350,57 @@ const processLibraryInfo = async (libraryInfo) => {
* @typedef {object} LibraryInfo
* @property {string} name The library name, e.g. "lib.x"
* @property {string} version The library version, e.g. "1.0.0"
+ * @property {string} [id] The npm package id of the library project, e.g. "@openui5/sap.ui.core".
+ * Used by {@link resolveFramework} to detect the UI5 framework via npm-scope scanning.
* @property {@ui5/fs/Resource} libraryManifest library manifest resource,
* e.g. resource with path "lib/x/manifest.json"
* @property {@ui5/fs/Resource[]} embeddedManifests list of embedded manifest resources,
* e.g. resource with path "lib/x/sub/manifest.json"
*/
+/**
+ * Resolves the UI5 framework name and version from raw project inputs.
+ *
+ * Resolution order:
+ * 1. Explicit config: frameworkName is "OpenUI5" or "SAPUI5"
+ * → returns it with frameworkVersion coalesced to "".
+ * 2. Dependency scan: examines libraryInfos[].id for @sapui5/ or
+ * @openui5/ npm scopes; version comes from the sap.ui.core entry.
+ * 3. Fallback: {name: "", version: ""}.
+ *
+ * The returned object always has both name and version as strings.
+ *
+ * @public
+ * @param {string} [frameworkName] Framework name from the root project's ui5.yaml
+ * @param {string} [frameworkVersion] Framework version from the root project's ui5.yaml
+ * @param {module:@ui5/builder/processors/versionInfoGenerator~LibraryInfo[]} libraryInfos
+ * Library infos; each entry's optional id field is used for the npm-scope scan
+ * @returns {{name: string, version: string}} Resolved framework object
+ */
+export function resolveFramework(frameworkName, frameworkVersion, libraryInfos) {
+ if (frameworkName === "OpenUI5" || frameworkName === "SAPUI5") {
+ return {name: frameworkName, version: frameworkVersion || ""};
+ }
+ let openui5Detected = false;
+ let openui5CoreVersion = "";
+ for (const libraryInfo of libraryInfos) {
+ const {id} = libraryInfo;
+ if (id?.startsWith("@sapui5/")) {
+ return {name: "SAPUI5", version: ""};
+ }
+ if (id?.startsWith("@openui5/")) {
+ openui5Detected = true;
+ if (libraryInfo.name === "sap.ui.core") {
+ openui5CoreVersion = libraryInfo.version;
+ }
+ }
+ }
+ if (openui5Detected) {
+ return {name: "OpenUI5", version: openui5CoreVersion};
+ }
+ return {name: "", version: ""};
+}
+
/**
* Creates sap-ui-version.json.
*
@@ -379,6 +424,11 @@ const processLibraryInfo = async (libraryInfo) => {
* }
* ```
*
+ * @param {string} [parameters.options.frameworkName] Framework name from the root project's ui5.yaml,
+ * e.g. "OpenUI5" or "SAPUI5". Used for framework resolution.
+ * @param {string} [parameters.options.frameworkVersion] Framework version from the root project's ui5.yaml,
+ * e.g. "1.136.0". Used only when frameworkName is recognized;
+ * defaults to "" when omitted.
* @returns {Promise<@ui5/fs/Resource[]>} Promise resolving with an array containing the versionInfo resource
*/
@@ -463,6 +513,7 @@ export default async function({options}) {
buildTimestamp: buildTimestamp,
scmRevision: "", // TODO: insert current application scm revision here
// gav: "", // TODO: insert current application id + version here
+ framework: resolveFramework(options.frameworkName, options.frameworkVersion, options.libraryInfos),
libraries,
components
};
diff --git a/packages/builder/lib/tasks/generateVersionInfo.js b/packages/builder/lib/tasks/generateVersionInfo.js
index 8cb2f8f6cfb..076f7408c46 100644
--- a/packages/builder/lib/tasks/generateVersionInfo.js
+++ b/packages/builder/lib/tasks/generateVersionInfo.js
@@ -41,7 +41,8 @@ export default async ({workspace, dependencies, options: {rootProject, pattern}}
libraryManifest,
embeddedManifests,
name: dotLibResource.getProject().getName(),
- version: dotLibResource.getProject().getVersion()
+ version: dotLibResource.getProject().getVersion(),
+ id: dotLibResource.getProject().getId?.()
};
});
});
@@ -51,6 +52,8 @@ export default async ({workspace, dependencies, options: {rootProject, pattern}}
options: {
rootProjectName: rootProject.getName(),
rootProjectVersion: rootProject.getVersion(),
+ frameworkName: rootProject.getFrameworkName?.(),
+ frameworkVersion: rootProject.getFrameworkVersion?.(),
libraryInfos
}
});
diff --git a/packages/builder/test/expected/build/application.j/dest-resources-json/resources/sap-ui-version.json b/packages/builder/test/expected/build/application.j/dest-resources-json/resources/sap-ui-version.json
index 551fc7d927c..151d6d5be04 100644
--- a/packages/builder/test/expected/build/application.j/dest-resources-json/resources/sap-ui-version.json
+++ b/packages/builder/test/expected/build/application.j/dest-resources-json/resources/sap-ui-version.json
@@ -3,5 +3,9 @@
"version": "1.0.0",
"buildTimestamp": "202008120917",
"scmRevision": "",
+ "framework": {
+ "name": "",
+ "version": ""
+ },
"libraries": []
}
\ No newline at end of file
diff --git a/packages/builder/test/expected/build/application.m/dest/resources/sap-ui-version.json b/packages/builder/test/expected/build/application.m/dest/resources/sap-ui-version.json
index a109feea58d..a965e2b6034 100644
--- a/packages/builder/test/expected/build/application.m/dest/resources/sap-ui-version.json
+++ b/packages/builder/test/expected/build/application.m/dest/resources/sap-ui-version.json
@@ -3,5 +3,9 @@
"version": "1.0.0",
"buildTimestamp": "WILL_BE_IGNORED_BY_TESTS",
"scmRevision": "",
+ "framework": {
+ "name": "",
+ "version": ""
+ },
"libraries": []
}
diff --git a/packages/builder/test/expected/build/application.o/dest/resources/sap-ui-version.json b/packages/builder/test/expected/build/application.o/dest/resources/sap-ui-version.json
index b6212fb25e3..38949352ec3 100644
--- a/packages/builder/test/expected/build/application.o/dest/resources/sap-ui-version.json
+++ b/packages/builder/test/expected/build/application.o/dest/resources/sap-ui-version.json
@@ -3,5 +3,9 @@
"version": "1.0.0",
"buildTimestamp": "WILL_BE_IGNORED_BY_TESTS",
"scmRevision": "",
+ "framework": {
+ "name": "",
+ "version": ""
+ },
"libraries": []
}
diff --git a/packages/builder/test/lib/processors/versionInfoGenerator.js b/packages/builder/test/lib/processors/versionInfoGenerator.js
index 5a69ac6c72d..3b0b541ec1b 100644
--- a/packages/builder/test/lib/processors/versionInfoGenerator.js
+++ b/packages/builder/test/lib/processors/versionInfoGenerator.js
@@ -1,6 +1,7 @@
import test from "ava";
import sinon from "sinon";
import esmock from "esmock";
+import {resolveFramework} from "../../../lib/processors/versionInfoGenerator.js";
test.beforeEach(async (t) => {
t.context.warnLogStub = sinon.stub();
@@ -37,6 +38,13 @@ const assertVersionInfoContent = (t, oExpectedVersionInfo, sActualContent) => {
delete lib.buildTimestamp; // removing to allow deep comparison
});
+ // The "framework" object is always emitted. When the expectation does not assert it
+ // explicitly, verify it defaults to empty strings and remove it to allow deep comparison.
+ if (!("framework" in oExpectedVersionInfo)) {
+ t.deepEqual(currentVersionInfo.framework, {name: "", version: ""},
+ "framework defaults to empty strings when no framework option is passed");
+ delete currentVersionInfo.framework;
+ }
t.deepEqual(currentVersionInfo, oExpectedVersionInfo, "Correct content");
};
@@ -59,6 +67,79 @@ test.serial("versionInfoGenerator empty libraryInfos parameter", async (t) => {
});
+test.serial("versionInfoGenerator resolves framework from explicit frameworkName/frameworkVersion", async (t) => {
+ const {versionInfoGenerator} = t.context;
+ const versionInfos = await versionInfoGenerator({options: {
+ rootProjectName: "myname", rootProjectVersion: "1.33.7", libraryInfos: [],
+ frameworkName: "OpenUI5", frameworkVersion: "1.136.0"}});
+
+ const result = JSON.parse(await versionInfos[0].getString());
+ t.deepEqual(result.framework, {name: "OpenUI5", version: "1.136.0"});
+});
+
+// --- resolveFramework unit tests (pure function, no esmock needed) ---
+
+test("resolveFramework: explicit OpenUI5 returns name and version", (t) => {
+ t.deepEqual(resolveFramework("OpenUI5", "1.136.0", []), {name: "OpenUI5", version: "1.136.0"});
+});
+
+test("resolveFramework: explicit SAPUI5 returns name and version", (t) => {
+ t.deepEqual(resolveFramework("SAPUI5", "1.136.0", []), {name: "SAPUI5", version: "1.136.0"});
+});
+
+test("resolveFramework: name-only config coalesces missing version to empty string (fixes #3)", (t) => {
+ t.deepEqual(resolveFramework("SAPUI5", undefined, []), {name: "SAPUI5", version: ""});
+ t.deepEqual(resolveFramework("OpenUI5", undefined, []), {name: "OpenUI5", version: ""});
+});
+
+test("resolveFramework: explicit config wins over dependency scan", (t) => {
+ const libs = [{id: "@sapui5/sap.m", name: "sap.m", version: "1.136.0"}];
+ t.deepEqual(resolveFramework("OpenUI5", "1.138.0", libs), {name: "OpenUI5", version: "1.138.0"});
+});
+
+test("resolveFramework: unrecognized frameworkName falls through to scan and then fallback", (t) => {
+ t.deepEqual(resolveFramework("CustomFramework", "1.0.0", []), {name: "", version: ""});
+});
+
+test("resolveFramework: scans @openui5/ dep and resolves OpenUI5 with sap.ui.core version", (t) => {
+ const libs = [
+ {id: "@openui5/sap.m", name: "sap.m", version: "1.136.0"},
+ {id: "@openui5/sap.ui.core", name: "sap.ui.core", version: "1.136.0"}
+ ];
+ t.deepEqual(resolveFramework(undefined, undefined, libs), {name: "OpenUI5", version: "1.136.0"});
+});
+
+test("resolveFramework: scans @openui5/ dep without sap.ui.core yields empty version", (t) => {
+ const libs = [{id: "@openui5/sap.m", name: "sap.m", version: "1.136.0"}];
+ t.deepEqual(resolveFramework(undefined, undefined, libs), {name: "OpenUI5", version: ""});
+});
+
+test("resolveFramework: scans @sapui5/ dep and resolves SAPUI5 with empty version", (t) => {
+ const libs = [{id: "@sapui5/sap.m", name: "sap.m", version: "1.136.0"}];
+ t.deepEqual(resolveFramework(undefined, undefined, libs), {name: "SAPUI5", version: ""});
+});
+
+test("resolveFramework: @sapui5/ dep short-circuits before @openui5/ accumulation", (t) => {
+ const libs = [
+ {id: "@openui5/sap.ui.core", name: "sap.ui.core", version: "1.136.0"},
+ {id: "@sapui5/sap.m", name: "sap.m", version: "1.136.0"}
+ ];
+ t.deepEqual(resolveFramework(undefined, undefined, libs), {name: "SAPUI5", version: ""});
+});
+
+test("resolveFramework: libs without id are ignored in scan (no-id fallback)", (t) => {
+ const libs = [
+ {name: "sap.m", version: "1.136.0"},
+ {id: undefined, name: "sap.ui.core", version: "1.136.0"}
+ ];
+ t.deepEqual(resolveFramework(undefined, undefined, libs), {name: "", version: ""});
+});
+
+test("resolveFramework: empty libraryInfos returns fallback", (t) => {
+ t.deepEqual(resolveFramework(undefined, undefined, []), {name: "", version: ""});
+});
+
+
test.serial("versionInfoGenerator simple library infos", async (t) => {
const {versionInfoGenerator} = t.context;
const options = {
diff --git a/packages/builder/test/lib/tasks/generateVersionInfo.js b/packages/builder/test/lib/tasks/generateVersionInfo.js
index bedb63baf19..2c2adcfcd82 100644
--- a/packages/builder/test/lib/tasks/generateVersionInfo.js
+++ b/packages/builder/test/lib/tasks/generateVersionInfo.js
@@ -28,7 +28,10 @@ const createProjectMetadata = (names, version, type) => {
getName: () => key,
getNamespace: () => names.join("/"),
getVersion: () => version || "3.0.0-" + key,
- getType: () => type || "library"
+ getType: () => type || "library",
+ getId: () => key,
+ getFrameworkName: () => undefined,
+ getFrameworkVersion: () => undefined
};
};
@@ -91,6 +94,14 @@ async function assertCreatedVersionInfo(t, oExpectedVersionInfo, oOptions) {
return libraryA.name.localeCompare(libraryB.name);
});
+ // The "framework" object is always emitted. When the expectation does not assert it
+ // explicitly, verify it defaults to empty strings and remove it to allow deep comparison.
+ if (!("framework" in oExpectedVersionInfo)) {
+ t.deepEqual(currentVersionInfo.framework, {name: "", version: ""},
+ "framework defaults to empty strings when no framework is resolved");
+ delete currentVersionInfo.framework;
+ }
+
t.deepEqual(currentVersionInfo, oExpectedVersionInfo, "Correct content");
}
@@ -1184,3 +1195,175 @@ test.serial("integration: Library of type 'module'", async (t) => {
t.is(infoLogStub.callCount, 0);
});
+
+test.serial("task: explicit OpenUI5 framework config is forwarded", async (t) => {
+ const workspace = createWorkspace();
+ const rootProject = {
+ getName: () => "myname",
+ getVersion: () => "1.33.7",
+ getFrameworkName: () => "OpenUI5",
+ getFrameworkVersion: () => "1.136.0"
+ };
+ const oOptions = {
+ workspace,
+ dependencies: resourceFactory.createAdapter({virBasePath: "/resources/"}),
+ options: {
+ pattern: "/resources/**/.library",
+ rootProject
+ }
+ };
+ await assertCreatedVersionInfo(t, {
+ "name": "myname",
+ "scmRevision": "",
+ "version": "1.33.7",
+ "framework": {"name": "OpenUI5", "version": "1.136.0"},
+ "libraries": []
+ }, oOptions);
+});
+
+test.serial("task: explicit SAPUI5 framework config is forwarded", async (t) => {
+ const workspace = createWorkspace();
+ const rootProject = {
+ getName: () => "myname",
+ getVersion: () => "1.33.7",
+ getFrameworkName: () => "SAPUI5",
+ getFrameworkVersion: () => "1.136.0"
+ };
+ const oOptions = {
+ workspace,
+ dependencies: resourceFactory.createAdapter({virBasePath: "/resources/"}),
+ options: {
+ pattern: "/resources/**/.library",
+ rootProject
+ }
+ };
+ await assertCreatedVersionInfo(t, {
+ "name": "myname",
+ "scmRevision": "",
+ "version": "1.33.7",
+ "framework": {"name": "SAPUI5", "version": "1.136.0"},
+ "libraries": []
+ }, oOptions);
+});
+
+test.serial("task: unrecognized framework name yields empty framework", async (t) => {
+ const workspace = createWorkspace();
+ const rootProject = {
+ getName: () => "myname",
+ getVersion: () => "1.33.7",
+ getFrameworkName: () => "CustomFramework",
+ getFrameworkVersion: () => "1.0.0"
+ };
+ const oOptions = {
+ workspace,
+ dependencies: resourceFactory.createAdapter({virBasePath: "/resources/"}),
+ options: {
+ pattern: "/resources/**/.library",
+ rootProject
+ }
+ };
+ // framework not in expected → assertCreatedVersionInfo verifies it defaults to {name:"",version:""}
+ await assertCreatedVersionInfo(t, {
+ "name": "myname",
+ "scmRevision": "",
+ "version": "1.33.7",
+ "libraries": []
+ }, oOptions);
+});
+
+function createScopedDepProject(names, {id, version = "1.136.0"} = {}) {
+ const key = names.join(".");
+ return {
+ getName: () => key,
+ getNamespace: () => names.join("/"),
+ getVersion: () => version,
+ getType: () => "library",
+ getId: () => id ?? key,
+ getFrameworkName: () => undefined,
+ getFrameworkVersion: () => undefined
+ };
+}
+
+test.serial("task: scans @openui5/sap.ui.core dep and resolves OpenUI5 with core version", async (t) => {
+ const workspace = createWorkspace();
+ const dep = resourceFactory.createAdapter({
+ virBasePath: "/",
+ project: createScopedDepProject(["sap", "ui", "core"], {id: "@openui5/sap.ui.core", version: "1.136.0"})
+ });
+ await dep.write(resourceFactory.createResource({
+ path: "/resources/sap/ui/core/.library",
+ string: `sap.ui.core`
+ }));
+ const rootProject = {
+ getName: () => "myapp", getVersion: () => "1.0.0",
+ getFrameworkName: () => undefined, getFrameworkVersion: () => undefined
+ };
+ const oOptions = {
+ workspace,
+ dependencies: dep,
+ options: {pattern: "/resources/**/.library", rootProject}
+ };
+ await assertCreatedVersionInfo(t, {
+ "name": "myapp",
+ "scmRevision": "",
+ "version": "1.0.0",
+ "framework": {"name": "OpenUI5", "version": "1.136.0"},
+ "libraries": [{"name": "sap.ui.core", "scmRevision": "", "version": "1.136.0"}]
+ }, oOptions);
+});
+
+test.serial("task: scans @sapui5/ dep and resolves SAPUI5 with empty version", async (t) => {
+ const workspace = createWorkspace();
+ const dep = resourceFactory.createAdapter({
+ virBasePath: "/",
+ project: createScopedDepProject(["sap", "m"], {id: "@sapui5/sap.m", version: "1.136.0"})
+ });
+ await dep.write(resourceFactory.createResource({
+ path: "/resources/sap/m/.library",
+ string: `sap.m`
+ }));
+ const rootProject = {
+ getName: () => "myapp", getVersion: () => "1.0.0",
+ getFrameworkName: () => undefined, getFrameworkVersion: () => undefined
+ };
+ const oOptions = {
+ workspace,
+ dependencies: dep,
+ options: {pattern: "/resources/**/.library", rootProject}
+ };
+ await assertCreatedVersionInfo(t, {
+ "name": "myapp",
+ "scmRevision": "",
+ "version": "1.0.0",
+ "framework": {"name": "SAPUI5", "version": ""},
+ "libraries": [{"name": "sap.m", "scmRevision": "", "version": "1.136.0"}]
+ }, oOptions);
+});
+
+test.serial("task: explicit ui5.yaml config wins over @sapui5/ scan result", async (t) => {
+ const workspace = createWorkspace();
+ const dep = resourceFactory.createAdapter({
+ virBasePath: "/",
+ project: createScopedDepProject(["sap", "m"], {id: "@sapui5/sap.m", version: "1.136.0"})
+ });
+ await dep.write(resourceFactory.createResource({
+ path: "/resources/sap/m/.library",
+ string: `sap.m`
+ }));
+ const rootProject = {
+ getName: () => "myapp", getVersion: () => "1.0.0",
+ getFrameworkName: () => "OpenUI5", getFrameworkVersion: () => "1.138.0"
+ };
+ const oOptions = {
+ workspace,
+ dependencies: dep,
+ options: {pattern: "/resources/**/.library", rootProject}
+ };
+ await assertCreatedVersionInfo(t, {
+ "name": "myapp",
+ "scmRevision": "",
+ "version": "1.0.0",
+ "framework": {"name": "OpenUI5", "version": "1.138.0"},
+ "libraries": [{"name": "sap.m", "scmRevision": "", "version": "1.136.0"}]
+ }, oOptions);
+});
diff --git a/packages/server/lib/middleware/versionInfo.js b/packages/server/lib/middleware/versionInfo.js
index ac48ae70755..4fc12d94d1e 100644
--- a/packages/server/lib/middleware/versionInfo.js
+++ b/packages/server/lib/middleware/versionInfo.js
@@ -40,7 +40,8 @@ function createMiddleware({resources, middlewareUtil}) {
libraryManifest,
embeddedManifests,
name: dotLibResource.getProject().getName(),
- version: dotLibResource.getProject().getVersion()
+ version: dotLibResource.getProject().getVersion(),
+ id: dotLibResource.getProject().getId?.()
};
});
const rootProject = middlewareUtil.getProject();
@@ -49,6 +50,8 @@ function createMiddleware({resources, middlewareUtil}) {
options: {
rootProjectName: rootProject.getName(),
rootProjectVersion: rootProject.getVersion(),
+ frameworkName: rootProject.getFrameworkName?.(),
+ frameworkVersion: rootProject.getFrameworkVersion?.(),
libraryInfos
}
});
diff --git a/packages/server/test/lib/server/main.js b/packages/server/test/lib/server/main.js
index 54c9049be62..0633d6e2d0d 100644
--- a/packages/server/test/lib/server/main.js
+++ b/packages/server/test/lib/server/main.js
@@ -208,6 +208,7 @@ test("Get sap-ui-version.json from versionInfo middleware (/resources/sap-ui-ver
"version": "1.0.0",
"buildTimestamp": buildTimestamp,
"scmRevision": "",
+ "framework": {"name": "", "version": ""},
"libraries": [
{
name: "library.a",
diff --git a/packages/server/test/lib/server/middleware/versionInfo.js b/packages/server/test/lib/server/middleware/versionInfo.js
index e3ca031ee95..80e2d4b776c 100644
--- a/packages/server/test/lib/server/middleware/versionInfo.js
+++ b/packages/server/test/lib/server/middleware/versionInfo.js
@@ -32,7 +32,9 @@ const createProjectMetadata = (names, version, type) => {
getName: () => key,
getNamespace: () => names.join("/"),
getVersion: () => version || "3.0.0-" + key,
- getType: () => type || "library"
+ getType: () => type || "library",
+ getFrameworkName: () => undefined,
+ getFrameworkVersion: () => undefined
};
};
@@ -272,6 +274,10 @@ test.serial("test all inner API calls within middleware", async (t) => {
const versionInfoGeneratorOptions = versionInfoGeneratorStub.getCall(0).args[0].options;
t.is(versionInfoGeneratorOptions.rootProjectName, "myname");
t.is(versionInfoGeneratorOptions.rootProjectVersion, "1.33.7");
+ t.is(versionInfoGeneratorOptions.frameworkName, undefined,
+ "frameworkName forwarded from root project (undefined when not configured)");
+ t.is(versionInfoGeneratorOptions.frameworkVersion, undefined,
+ "frameworkVersion forwarded from root project (undefined when not configured)");
t.is(versionInfoGeneratorOptions.libraryInfos.length, 3);
t.is(versionInfoGeneratorOptions.libraryInfos[0].name, "lib.a");
t.is(await versionInfoGeneratorOptions.libraryInfos[0].libraryManifest.getString(), "mocked manifest.json 1");
@@ -349,6 +355,7 @@ test.serial("integration: Library with dependencies and subcomponent complex sce
"name": "myname",
"scmRevision": "",
"version": "1.33.7",
+ "framework": {"name": "", "version": ""},
"libraries": [{
"name": "lib.a",
"scmRevision": "",
@@ -443,3 +450,98 @@ test.serial("integration: Library with dependencies and subcomponent complex sce
await middleware(undefined, res, next);
});
+
+test.serial("integration: middleware resolves framework for configured OpenUI5 project", async (t) => {
+ const workspace = createWorkspace();
+ await createDotLibrary(workspace, resourceFactory, ["test", "lib"]);
+
+ const coreProject = {
+ getName: () => "sap.ui.core",
+ getNamespace: () => "sap/ui/core",
+ getVersion: () => "1.136.0",
+ getType: () => "library",
+ getFrameworkName: () => undefined,
+ getFrameworkVersion: () => undefined,
+ getId: () => "@openui5/sap.ui.core"
+ };
+ const dep = resourceFactory.createAdapter({virBasePath: "/", project: coreProject});
+ coreProject.getSourceReader = () => dep;
+ await createDotLibrary(dep, resourceFactory, ["sap", "ui", "core"], "1.136.0");
+ await createManifestResource(dep, resourceFactory, ["sap", "ui", "core"], []);
+
+ const resources = {
+ dependencies: resourceFactory.createReaderCollection({
+ name: "dependencies",
+ readers: [dep]
+ })
+ };
+
+ const middlewareUtil = {
+ getProject: () => ({
+ getName: () => "myapp",
+ getVersion: () => "1.0.0",
+ getFrameworkName: () => "OpenUI5",
+ getFrameworkVersion: () => "1.136.0"
+ })
+ };
+
+ const versionInfoMiddleware = await t.context.createVersionInfoMiddleware();
+ const middleware = versionInfoMiddleware({resources, middlewareUtil});
+
+ const expectedVersionInfo = {
+ "name": "myapp",
+ "scmRevision": "",
+ "version": "1.0.0",
+ "framework": {"name": "OpenUI5", "version": "1.136.0"},
+ "libraries": [{"name": "sap.ui.core", "scmRevision": "", "version": "1.136.0"}]
+ };
+
+ const res = {
+ writeHead: function() {},
+ end: async function(versionInfoContent) {
+ await assertCreatedVersionInfo(t, expectedVersionInfo, versionInfoContent);
+ }
+ };
+ await middleware(undefined, res, function(err) {
+ throw err;
+ });
+});
+
+test.serial("integration: middleware emits empty string version for name-only framework config", async (t) => {
+ const workspace = createWorkspace();
+ await createDotLibrary(workspace, resourceFactory, ["test", "lib"]);
+
+ const resources = {
+ dependencies: resourceFactory.createReaderCollection({name: "dependencies", readers: []})
+ };
+
+ const middlewareUtil = {
+ getProject: () => ({
+ getName: () => "myapp",
+ getVersion: () => "1.0.0",
+ getFrameworkName: () => "SAPUI5",
+ getFrameworkVersion: () => undefined
+ })
+ };
+
+ const versionInfoMiddleware = await t.context.createVersionInfoMiddleware();
+ const middleware = versionInfoMiddleware({resources, middlewareUtil});
+
+ const expectedVersionInfo = {
+ "name": "myapp",
+ "scmRevision": "",
+ "version": "1.0.0",
+ "framework": {"name": "SAPUI5", "version": ""},
+ "libraries": []
+ };
+
+ const res = {
+ writeHead: function() {},
+ end: async function(versionInfoContent) {
+ await assertCreatedVersionInfo(t, expectedVersionInfo, versionInfoContent);
+ }
+ };
+ await middleware(undefined, res, function(err) {
+ throw err;
+ });
+});