From ddc65b51ca82dc524c172bde6b89c31a7d98dc15 Mon Sep 17 00:00:00 2001 From: Matthias Osswald Date: Fri, 21 Dec 2018 15:54:37 +0100 Subject: [PATCH] [FIX] ComponentAnalyzer: Fully handle sap.ui5/routing --- lib/lbt/analyzer/ComponentAnalyzer.js | 24 +++++ test/lib/lbt/analyzer/ComponentAnalyzer.js | 111 +++++++++++++++++---- 2 files changed, 115 insertions(+), 20 deletions(-) diff --git a/lib/lbt/analyzer/ComponentAnalyzer.js b/lib/lbt/analyzer/ComponentAnalyzer.js index 73bb1d248..d796a8e19 100644 --- a/lib/lbt/analyzer/ComponentAnalyzer.js +++ b/lib/lbt/analyzer/ComponentAnalyzer.js @@ -133,6 +133,30 @@ class ComponentAnalyzer { const routing = ui5.routing; if ( routing ) { + const routingConfig = routing.config || {}; + + // See sap/ui/core/UIComponent#init + if (routing.routes) { + const routerClassName = routingConfig.routerClass || "sap.ui.core.routing.Router"; + const routerClassModule = ModuleName.fromUI5LegacyName(routerClassName); + log.verbose(`adding router dependency '${routerClassModule}'`); + info.addDependency(routerClassModule); + } else if (routing.targets) { + const targetsModule = routingConfig.targetsClass || "sap/ui/core/routing/Targets.js"; + log.verbose(`adding routing targets dependency '${targetsModule}'`); + info.addDependency(targetsModule); + + const viewsModule = "sap/ui/core/routing/Views.js"; + log.verbose(`adding routing views dependency '${viewsModule}'`); + info.addDependency(viewsModule); + } + + + // TODO: only loop over targets to pick up view dependencies + // routes only have a reference to a target + // this way we also support the "targets" only use case (without routes) + // but we would also include targets not referenced by any route + if (Array.isArray(routing.routes)) { routing.routes.forEach((route) => this._visitRoute(route, routing, info)); } else { diff --git a/test/lib/lbt/analyzer/ComponentAnalyzer.js b/test/lib/lbt/analyzer/ComponentAnalyzer.js index 660e82f8d..946081fe2 100644 --- a/test/lib/lbt/analyzer/ComponentAnalyzer.js +++ b/test/lib/lbt/analyzer/ComponentAnalyzer.js @@ -19,7 +19,63 @@ function createMockPool(relPath, manifest) { }; } -test("routing with routes as array", (t) => { +test("routing with empty config, routes, targets", async (t) => { + const mockManifest = { + "sap.ui5": { + routing: { + config: {}, + routes: [], + targets: {} + } + } + }; + + const mockPool = createMockPool("test/", mockManifest); + + const mockInfo = { + deps: [], + addDependency(name) { + this.deps.push(name); + } + }; + + const subject = new ComponentAnalyzer(mockPool); + await subject.analyze({name: path.join("test", "Component.js")}, mockInfo); + + t.deepEqual(mockInfo.deps, [ + "sap/ui/core/routing/Router.js" + ], "dependencies should be correct"); +}); + +test("routing with empty config, targets", async (t) => { + const mockManifest = { + "sap.ui5": { + routing: { + config: {}, + targets: {} + } + } + }; + + const mockPool = createMockPool("test/", mockManifest); + + const mockInfo = { + deps: [], + addDependency(name) { + this.deps.push(name); + } + }; + + const subject = new ComponentAnalyzer(mockPool); + await subject.analyze({name: path.join("test", "Component.js")}, mockInfo); + + t.deepEqual(mockInfo.deps, [ + "sap/ui/core/routing/Targets.js", + "sap/ui/core/routing/Views.js" + ], "dependencies should be correct"); +}); + +test("routing with routes as array", async (t) => { const mockManifest = { "sap.ui5": { routing: { @@ -43,17 +99,23 @@ test("routing with routes as array", (t) => { const mockPool = createMockPool("test/", mockManifest); const mockInfo = { + deps: [], addDependency(name) { - t.is(name, "test/view/App.view.xml"); + this.deps.push(name); } }; const subject = new ComponentAnalyzer(mockPool); - return subject.analyze({name: path.join("test", "Component.js")}, mockInfo); + await subject.analyze({name: path.join("test", "Component.js")}, mockInfo); + + t.deepEqual(mockInfo.deps, [ + "sap/ui/core/routing/Router.js", + "test/view/App.view.xml" + ], "dependencies should be correct"); }); -test("routing with routes as object", (t) => { +test("routing with routes as object", async (t) => { const mockManifest = { "sap.ui5": { routing: { @@ -76,16 +138,22 @@ test("routing with routes as object", (t) => { const mockPool = createMockPool("test/", mockManifest); const mockInfo = { + deps: [], addDependency(name) { - t.is(name, "test/view/App.view.xml"); + this.deps.push(name); } }; const subject = new ComponentAnalyzer(mockPool); - return subject.analyze({name: path.join("test", "Component.js")}, mockInfo); + await subject.analyze({name: path.join("test", "Component.js")}, mockInfo); + + t.deepEqual(mockInfo.deps, [ + "sap/ui/core/routing/Router.js", + "test/view/App.view.xml" + ], "dependencies should be correct"); }); -test("routing with route with multiple targets", (t) => { +test("routing with route with multiple targets", async (t) => { const mockManifest = { "sap.ui5": { routing: { @@ -116,15 +184,17 @@ test("routing with route with multiple targets", (t) => { }; const subject = new ComponentAnalyzer(mockPool); - return subject.analyze({name: path.join("test", "Component.js")}, mockInfo).then( () => { - t.deepEqual(mockInfo.deps, [ - "test/view/Master.view.xml", - "test/view/Detail.view.xml" - ], "dependencies should be correct"); - }); + await subject.analyze({name: path.join("test", "Component.js")}, mockInfo); + + t.deepEqual(mockInfo.deps, [ + "sap/ui/core/routing/Router.js", + "test/view/Master.view.xml", + "test/view/Detail.view.xml" + ], "dependencies should be correct"); + }); -test("routing with targets with local config", (t) => { +test("routing with targets with local config", async (t) => { const mockManifest = { "sap.ui5": { routing: { @@ -164,12 +234,13 @@ test("routing with targets with local config", (t) => { }; const subject = new ComponentAnalyzer(mockPool); - return subject.analyze({name: path.join("test", "Component.js")}, mockInfo).then( () => { - t.deepEqual(mockInfo.deps, [ - "test/view/Master.view.js", - "test/subview/Detail.view.xml" - ], "dependencies should be correct"); - }); + await subject.analyze({name: path.join("test", "Component.js")}, mockInfo); + + t.deepEqual(mockInfo.deps, [ + "sap/ui/core/routing/Router.js", + "test/view/Master.view.js", + "test/subview/Detail.view.xml" + ], "dependencies should be correct"); }); test("rootView with object", (t) => {