Skip to content

Commit 1b6cb93

Browse files
committed
test(project): Add case for dependency content changes
This test should cover a scenario with an application depending on a library. Specifically, we're directly modifying the contents of the library which should have effects on the application because a custom task will detect it and modify the application's resources. The application is expected to get rebuilt.
1 parent 5531cd9 commit 1b6cb93

File tree

4 files changed

+205
-0
lines changed

4 files changed

+205
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// This is a modified version of the compileLicenseSummary example of the UI5 CLI.
2+
// (https://github.com/UI5/cli/blob/b72919469d856508dd757ecf325a5fb45f15e56d/internal/documentation/docs/pages/extensibility/CustomTasks.md#example-libtaskscompilelicensesummaryjs)
3+
4+
module.exports = async function ({dependencies, log, taskUtil, workspace, options: {projectNamespace}}) {
5+
const {createResource} = taskUtil.resourceFactory;
6+
const projectsVisited = new Set();
7+
8+
async function processProject(project) {
9+
return Promise.all(taskUtil.getDependencies().map(async (projectName) => {
10+
if (projectName !== "library.d") {
11+
return;
12+
}
13+
if (projectsVisited.has(projectName)) {
14+
return;
15+
}
16+
projectsVisited.add(projectName);
17+
const project = taskUtil.getProject(projectName);
18+
const newLibraryFile = await project.getReader().byGlob("**/newLibraryFile.js");
19+
if (newLibraryFile.length > 0) {
20+
console.log('New Library file found. We are in #4 build.');
21+
// Change content of application.a:
22+
const applicationResource = await workspace.byPath("/resources/id1/controller/Base.controller.js");
23+
const content = (await applicationResource.getString()) + "\n console.log('something new');";
24+
await workspace.write(createResource({
25+
path: "/controller/Base.controller.js",
26+
string: content
27+
}));
28+
} else {
29+
console.log(`New Library file not found. We are still in an earlier build.`);
30+
}
31+
return processProject(project);
32+
}));
33+
}
34+
// Start processing dependencies of the root project
35+
await processProject(taskUtil.getProject());
36+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
specVersion: "2.3"
3+
type: application
4+
metadata:
5+
name: application.a
6+
builder:
7+
customTasks:
8+
- name: dependency-change
9+
afterTask: minify
10+
---
11+
specVersion: "5.0"
12+
kind: extension
13+
type: task
14+
metadata:
15+
name: dependency-change
16+
task:
17+
path: task.dependency-change.js
18+
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
sap.ui.define(["sap/ui/core/mvc/Controller", "sap/ui/core/UIComponent", "sap/ui/core/routing/History"], function (Controller, UIComponent, History) {
2+
"use strict";
3+
4+
return Controller.extend("com.myorg.myapp.controller.BaseController", {
5+
/**
6+
* Convenience method to get the components' router instance.
7+
* @returns {sap.m.routing.Router} The router instance
8+
*/
9+
getRouter: function () {
10+
return UIComponent.getRouterFor(this);
11+
},
12+
13+
/**
14+
* Convenience method for getting the i18n resource bundle of the component.
15+
* @returns {Promise<sap.base.i18n.ResourceBundle>} The i18n resource bundle of the component
16+
*/
17+
getResourceBundle: function () {
18+
const oModel = this.getOwnerComponent().getModel("i18n");
19+
return oModel.getResourceBundle();
20+
},
21+
22+
/**
23+
* Convenience method for getting the view model by name in every controller of the application.
24+
* @param {string} [sName] The model name
25+
* @returns {sap.ui.model.Model} The model instance
26+
*/
27+
getModel: function (sName) {
28+
return this.getView().getModel(sName);
29+
},
30+
31+
/**
32+
* Convenience method for setting the view model in every controller of the application.
33+
* @param {sap.ui.model.Model} oModel The model instance
34+
* @param {string} [sName] The model name
35+
* @returns {sap.ui.core.mvc.Controller} The current base controller instance
36+
*/
37+
setModel: function (oModel, sName) {
38+
this.getView().setModel(oModel, sName);
39+
return this;
40+
},
41+
42+
/**
43+
* Convenience method for triggering the navigation to a specific target.
44+
* @public
45+
* @param {string} sName Target name
46+
* @param {object} [oParameters] Navigation parameters
47+
* @param {boolean} [bReplace] Defines if the hash should be replaced (no browser history entry) or set (browser history entry)
48+
*/
49+
navTo: function (sName, oParameters, bReplace) {
50+
this.getRouter().navTo(sName, oParameters, undefined, bReplace);
51+
},
52+
53+
/**
54+
* Convenience event handler for navigating back.
55+
* It there is a history entry we go one step back in the browser history
56+
* If not, it will replace the current entry of the browser history with the main route.
57+
*/
58+
onNavBack: function () {
59+
const sPreviousHash = History.getInstance().getPreviousHash();
60+
if (sPreviousHash !== undefined) {
61+
window.history.go(-1);
62+
} else {
63+
this.getRouter().navTo("main", {}, undefined, true);
64+
}
65+
}
66+
});
67+
});

packages/project/test/lib/build/ProjectBuilder.integration.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,90 @@ test.serial.skip("Build application.a (multiple custom tasks 2)", async (t) => {
361361
await t.throwsAsync(fs.readFile(`${destPath}/test.js`, {encoding: "utf8"}));
362362
});
363363

364+
test.skip.serial("Build application.a (dependency content changes)", async (t) => {
365+
const fixtureTester = new FixtureTester(t, "application.a");
366+
const destPath = fixtureTester.destPath;
367+
368+
// This test should cover a scenario with an application depending on a library.
369+
// Specifically, we're directly modifying the contents of the library
370+
// which should have effects on the application because a custom task will detect it
371+
// and modify the application's resources. The application is expected to get rebuilt.
372+
373+
// #1 build (no cache, no changes, no dependencies)
374+
await fixtureTester.buildProject({
375+
graphConfig: {rootConfigPath: "ui5-customTask-dependency-change.yaml"},
376+
config: {destPath, cleanDest: true},
377+
assertions: {
378+
projects: {
379+
"application.a": {}
380+
}
381+
}
382+
});
383+
384+
385+
// #2 build (with cache, no changes, no dependencies)
386+
await fixtureTester.buildProject({
387+
graphConfig: {rootConfigPath: "ui5-customTask-dependency-change.yaml"},
388+
config: {destPath, cleanDest: true},
389+
assertions: {
390+
projects: {}
391+
}
392+
});
393+
394+
395+
// Change content of library.d (this will not affect application.a):
396+
const someJsOfLibrary = `${fixtureTester.fixturePath}/node_modules/library.d/main/src/library/d/some.js`;
397+
await fs.appendFile(someJsOfLibrary, `\ntest("line added");\n`);
398+
399+
// #3 build (with cache, with changes, with dependencies)
400+
await fixtureTester.buildProject({
401+
graphConfig: {rootConfigPath: "ui5-customTask-dependency-change.yaml"},
402+
config: {destPath, cleanDest: true, dependencyIncludes: {includeAllDependencies: true}},
403+
assertions: {
404+
projects: {
405+
"library.d": {},
406+
"library.a": {},
407+
"library.b": {},
408+
"library.c": {},
409+
}
410+
}
411+
});
412+
413+
// Check if library contains correct changed content:
414+
const builtFileContent = await fs.readFile(`${destPath}/resources/library/d/some.js`, {encoding: "utf8"});
415+
t.true(builtFileContent.includes(`test("line added");`), "Build dest contains changed file content");
416+
417+
418+
// Change content of library.d again (this time it affects application.a):
419+
await fs.writeFile(`${fixtureTester.fixturePath}/node_modules/library.d/main/src/library/d/newLibraryFile.js`,
420+
`console.log("SOME NEW CONTENT");`);
421+
422+
// #4 build (no cache, with changes, with dependencies)
423+
// This build should execute the custom task "task.dependency-change.js" again which now detects "newLibraryFile.js"
424+
// and modifies a resource of application.a (namely Base.controller.js).
425+
await fixtureTester.buildProject({
426+
graphConfig: {rootConfigPath: "ui5-customTask-dependency-change.yaml"},
427+
config: {destPath, cleanDest: true, dependencyIncludes: {includeAllDependencies: true}},
428+
assertions: {
429+
projects: {
430+
"library.d": {},
431+
"application.a": { // FIXME: currently failing (getting skipped entirely)
432+
skippedTasks: [
433+
"enhanceManifest",
434+
"escapeNonAsciiCharacters",
435+
"generateFlexChangesBundle",
436+
"replaceCopyright",
437+
]
438+
},
439+
}
440+
}
441+
});
442+
443+
// Check that application.a contains correct changed content (Base.controller.js):
444+
const builtFileContent2 = await fs.readFile(`${destPath}/controller/Base.controller.js`, {encoding: "utf8"});
445+
t.true(builtFileContent2.includes(`console.log('something new');`), "Build dest contains changed file content");
446+
});
447+
364448
test.serial("Build library.d project multiple times", async (t) => {
365449
const fixtureTester = new FixtureTester(t, "library.d");
366450
const destPath = fixtureTester.destPath;

0 commit comments

Comments
 (0)