Skip to content

Commit

Permalink
[FIX] generateResourcesJson: Include dependencies of XML resources
Browse files Browse the repository at this point in the history
The XML analysis requires dependency resources to be able to list them
as "required" in the resources.json.

JIRA: CPOUI5FOUNDATION-294
  • Loading branch information
matz3 committed Feb 23, 2021
1 parent fce35a5 commit 0fc364d
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 8 deletions.
4 changes: 3 additions & 1 deletion lib/processors/resourceListCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,11 @@ function makeResourcesJSON(list, prefix) {
* @private
* @param {object} parameters Parameters
* @param {module:@ui5/fs.Resource[]} parameters.resources List of resources
* @param {module:@ui5/fs.Resource[]} [parameters.dependencyResources=[]] List of dependency resources
* @param {object} [parameters.options] Options
* @returns {Promise<module:@ui5/fs.Resource[]>} Promise resolving with the resources.json resources
*/
module.exports = async function({resources, options}) {
module.exports = async function({resources, dependencyResources = [], options}) {
options = Object.assign({
failOnOrphans: false,
externalResources: undefined,
Expand All @@ -143,6 +144,7 @@ module.exports = async function({resources, options}) {

const pool = new LocatorResourcePool();
await pool.prepare( resources );
await pool.prepare( dependencyResources );

const collector = new ResourceCollector(pool);
const visitPromises = resources.map((resource) => collector.visitResource(resource));
Expand Down
13 changes: 11 additions & 2 deletions lib/tasks/generateResourcesJson.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,25 @@ function getCreatorOptions(projectName) {
* @alias module:@ui5/builder.tasks.generateResourcesJson
* @param {object} parameters Parameters
* @param {module:@ui5/fs.DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {module:@ui5/fs.AbstractReader} [parameters.dependencies] Reader or Collection to read dependency files
* @param {object} parameters.options Options
* @param {string} parameters.options.projectName Project name
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
*/
module.exports = async function({workspace, options: {projectName}}) {
module.exports = async function({workspace, dependencies, options: {projectName}}) {
const resources = await workspace.byGlob(["/resources/**/*.*"].concat(DEFAULT_EXCLUDES));

// TODO 3.0: Make dependencies parameter mandatory
let dependencyResources;
if (dependencies) {
dependencyResources =
await dependencies.byGlob("/resources/**/*.{js,json,xml,html,properties,library}");
}

const resourceLists = await resourceListCreator({
resources,
options: getCreatorOptions(projectName)
dependencyResources,
options: getCreatorOptions(projectName),
});
await Promise.all(
resourceLists.map((resourceList) => workspace.write(resourceList))
Expand Down
77 changes: 77 additions & 0 deletions test/lib/processors/resourceListCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,80 @@ test.serial("components and themes", async (t) => {
]
}`);
});

test.serial("XML View with control resource as dependency", async (t) => {
const myAppManifestJsonResource = resourceFactory.createResource({
path: "/resources/my/app/manifest.json",
string: JSON.stringify({"sap.app": {"id": "my.app"}})
});
const myAppXmlViewResource = resourceFactory.createResource({
path: "/resources/my/app/view/Main.view.xml",
string: `<mvc:View
controllerName="my.app.controller.Main"
xmlns="my.lib"
xmlns:myapp="my.app.controls"
xmlns:mvc="sap.ui.core.mvc">
<!-- Existing control, should be listed as "required" -->
<Button></Button>
<!-- Nonexistent control, should not be listed -->
<NonexistentControl></NonexistentControl>
<!-- Existing control within same project (app), should be listed as "required" -->
<myapp:Button></myapp:Button>
<!-- Nonexistent control within same project (app), should not be listed -->
<myapp:NonexistentControl></myapp:NonexistentControl>
</mvc:View>`
});
const myAppButtonResource = resourceFactory.createResource({
path: "/resources/my/app/controls/Button.js",
string: ""
});
const myLibButtonResource = resourceFactory.createResource({
path: "/resources/my/lib/Button.js",
string: ""
});

const resourcesJson = await resourceListCreator({
resources: [myAppManifestJsonResource, myAppXmlViewResource, myAppButtonResource],
dependencyResources: [myLibButtonResource]
});

t.is(resourcesJson.length, 1, "One resources.json should be returned");
const myAppResourcesJson = resourcesJson[0];
t.is(myAppResourcesJson.getPath(), "/resources/my/app/resources.json");
const myAppResourcesJsonContent = await myAppResourcesJson.getString();
t.is(myAppResourcesJsonContent, `{
"_version": "1.1.0",
"resources": [
{
"name": "controls/Button.js",
"module": "my/app/controls/Button.js",
"size": 0,
"format": "raw"
},
{
"name": "manifest.json",
"module": "my/app/manifest.json",
"size": 27
},
{
"name": "resources.json",
"size": 523
},
{
"name": "view/Main.view.xml",
"module": "my/app/view/Main.view.xml",
"size": 592,
"required": [
"my/app/controller/Main.controller.js",
"my/app/controls/Button.js",
"my/lib/Button.js"
]
}
]
}`);
});
51 changes: 46 additions & 5 deletions test/lib/tasks/generateResourcesJson.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ test.beforeEach((t) => {
t.context.resourceListCreatorStub = sinon.stub();
t.context.resourceListCreatorStub.returns(Promise.resolve([]));
mock("../../../lib/processors/resourceListCreator", t.context.resourceListCreatorStub);
mock.reRequire("../../../lib/processors/resourceListCreator");

t.context.generateResourcesJson = mock.reRequire("../../../lib/tasks/generateResourcesJson");
});

test.afterEach.always((t) => {
mock.stop("../../../lib/processors/resourceListCreator");
sinon.restore();
mock.stopAll();
});

test("empty resources", async (t) => {
const generateResourcesJson = require("../../../lib/tasks/generateResourcesJson");
test.serial("empty resources (sap.ui.core)", async (t) => {
const {generateResourcesJson, resourceListCreatorStub} = t.context;

const result = await generateResourcesJson({
workspace: createWorkspace(),
Expand All @@ -48,7 +50,7 @@ test("empty resources", async (t) => {
}
});
t.deepEqual(result, undefined, "no resources returned");
t.is(t.context.resourceListCreatorStub.callCount, 1);
t.is(resourceListCreatorStub.callCount, 1);
const expectedOptions = {
externalResources: {
"sap/ui/core": [
Expand All @@ -70,5 +72,44 @@ test("empty resources", async (t) => {
"**/library-preload.support.js"
]
};
t.deepEqual(resourceListCreatorStub.getCall(0).args[0].options, expectedOptions, "options match");
});

test.serial("empty resources (my.lib)", async (t) => {
const generateResourcesJson = require("../../../lib/tasks/generateResourcesJson");

const result = await generateResourcesJson({
workspace: createWorkspace(),
dependencies: undefined,
options: {
projectName: "my.lib"
}
});
t.deepEqual(result, undefined, "no resources returned");
t.is(t.context.resourceListCreatorStub.callCount, 1);
const expectedOptions = {};
t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].options, expectedOptions, "options match");
});

test.serial("empty resources (my.lib with dependencies)", async (t) => {
const generateResourcesJson = require("../../../lib/tasks/generateResourcesJson");

const dependencyResources = [{"dependency": "resources"}];
const dependencies = {
byGlob: sinon.stub().resolves(dependencyResources)
};

const result = await generateResourcesJson({
workspace: createWorkspace(),
dependencies,
options: {
projectName: "my.lib"
}
});
t.deepEqual(result, undefined, "no resources returned");
t.is(t.context.resourceListCreatorStub.callCount, 1);
const expectedOptions = {};
t.deepEqual(t.context.resourceListCreatorStub.getCall(0).args[0].options, expectedOptions, "options match");
t.is(t.context.resourceListCreatorStub.getCall(0).args[0].dependencyResources, dependencyResources,
"dependencyResources reference should be passed to resourceListCreator");
});

0 comments on commit 0fc364d

Please sign in to comment.