Skip to content

Commit d9d3d2a

Browse files
committed
[INTERNAL] log warning when asynchronous factory function is used for XMLComposite, SmartTemplate and FioriElements
1 parent 62a8e5b commit d9d3d2a

File tree

7 files changed

+311
-132
lines changed

7 files changed

+311
-132
lines changed

lib/lbt/analyzer/FioriElementsAnalyzer.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ class FioriElementsAnalyzer {
181181
}
182182
});
183183
}
184+
if (defineCall.factory.async) {
185+
log.warn("Using 'sap.ui.define' with an asynchronous function callback " +
186+
"is currently not supported by the UI5 runtime.");
187+
}
184188
}
185189
}
186190
return templateName;

lib/lbt/analyzer/SmartTemplateAnalyzer.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ class TemplateComponentAnalyzer {
150150
}
151151
});
152152
}
153+
if (defineCall.factory.async) {
154+
log.warn("Using 'sap.ui.define' with an asynchronous function callback " +
155+
"is currently not supported by the UI5 runtime.");
156+
}
153157
}
154158
}
155159
return templateName;

lib/lbt/analyzer/XMLCompositeAnalyzer.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class XMLCompositeAnalyzer {
4646
log.verbose("fragment control: add dependency to template fragment %s", fragmentModule);
4747
info.addDependency(fragmentModule);
4848
}
49+
if (defineCall.factory.async) {
50+
log.warn("Using 'sap.ui.define' with an asynchronous function callback " +
51+
"is currently not supported by the UI5 runtime.");
52+
}
4953
}
5054
}
5155
}

test/lib/lbt/analyzer/FioriElementsAnalyzer.js

Lines changed: 80 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
11
const test = require("ava");
22
const FioriElementsAnalyzer = require("../../../../lib/lbt/analyzer/FioriElementsAnalyzer");
3-
const sinon = require("sinon");
43
const parseUtils = require("../../../../lib/lbt/utils/parseUtils");
4+
const sinonGlobal = require("sinon");
5+
const logger = require("@ui5/logger");
6+
const loggerInstance = logger.getLogger();
7+
const mock = require("mock-require");
8+
9+
test.before((t) => {
10+
const sinon = t.context.sinon = sinonGlobal.createSandbox();
11+
t.context.warningLogSpy = sinon.spy(loggerInstance, "warn");
12+
sinon.stub(logger, "getLogger").returns(loggerInstance);
13+
t.context.FioriElementsAnalyzerWithStubbedLogger =
14+
mock.reRequire("../../../../lib/lbt/analyzer/FioriElementsAnalyzer");
15+
});
16+
17+
test.after((t) => {
18+
mock.stopAll();
19+
t.context.sinon.restore();
20+
});
21+
22+
test.beforeEach((t) => {
23+
t.context.warningLogSpy.resetHistory();
24+
});
525

626
test("analyze: with Component.js", async (t) => {
727
const emptyPool = {};
@@ -27,7 +47,7 @@ test("analyze: without manifest", async (t) => {
2747

2848
const analyzer = new FioriElementsAnalyzer(mockPool);
2949

30-
const stubAnalyzeManifest = sinon.stub(analyzer, "_analyzeManifest").resolves();
50+
const stubAnalyzeManifest = t.context.sinon.stub(analyzer, "_analyzeManifest").resolves();
3151

3252
const name = "MyComponent.js";
3353
const result = await analyzer.analyze({name}, moduleInfo);
@@ -60,7 +80,7 @@ test("analyze: with manifest", async (t) => {
6080

6181
const analyzer = new FioriElementsAnalyzer(mockPool);
6282

63-
const stubAnalyzeManifest = sinon.stub(analyzer, "_analyzeManifest").resolves();
83+
const stubAnalyzeManifest = t.context.sinon.stub(analyzer, "_analyzeManifest").resolves();
6484

6585
const name = "MyComponent.js";
6686
await analyzer.analyze({name}, moduleInfo);
@@ -86,11 +106,11 @@ test("_analyzeManifest: Manifest with TemplateAssembler code", async (t) => {
86106
const moduleInfo = {
87107
addDependency: function() {}
88108
};
89-
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");
109+
const stubAddDependency = t.context.sinon.spy(moduleInfo, "addDependency");
90110

91111
const analyzer = new FioriElementsAnalyzer();
92112

93-
const stubAnalyzeTemplateComponent = sinon.stub(analyzer, "_analyzeTemplateComponent").resolves();
113+
const stubAnalyzeTemplateComponent = t.context.sinon.stub(analyzer, "_analyzeTemplateComponent").resolves();
94114

95115
await analyzer._analyzeManifest(manifest, moduleInfo);
96116

@@ -130,7 +150,7 @@ test.serial("_analyzeTemplateComponent: Manifest with TemplateAssembler code", a
130150
const moduleInfo = {
131151
addDependency: function() {}
132152
};
133-
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");
153+
const stubAddDependency = t.context.sinon.spy(moduleInfo, "addDependency");
134154

135155
const mockPool = {
136156
async findResource() {
@@ -142,8 +162,8 @@ test.serial("_analyzeTemplateComponent: Manifest with TemplateAssembler code", a
142162

143163
const analyzer = new FioriElementsAnalyzer(mockPool);
144164

145-
const stubAnalyzeAST = sinon.stub(analyzer, "_analyzeAST").returns("mytpl");
146-
const stubParse = sinon.stub(parseUtils, "parseJS").returns("");
165+
const stubAnalyzeAST = t.context.sinon.stub(analyzer, "_analyzeAST").returns("mytpl");
166+
const stubParse = t.context.sinon.stub(parseUtils, "parseJS").returns("");
147167

148168
await analyzer._analyzeTemplateComponent("pony",
149169
{}, moduleInfo);
@@ -164,7 +184,7 @@ test.serial("_analyzeTemplateComponent: no default template name", async (t) =>
164184
const moduleInfo = {
165185
addDependency: function() {}
166186
};
167-
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");
187+
const stubAddDependency = t.context.sinon.spy(moduleInfo, "addDependency");
168188

169189
const mockPool = {
170190
async findResource() {
@@ -176,8 +196,8 @@ test.serial("_analyzeTemplateComponent: no default template name", async (t) =>
176196

177197
const analyzer = new FioriElementsAnalyzer(mockPool);
178198

179-
const stubAnalyzeAST = sinon.stub(analyzer, "_analyzeAST").returns("");
180-
const stubParse = sinon.stub(parseUtils, "parseJS").returns("");
199+
const stubAnalyzeAST = t.context.sinon.stub(analyzer, "_analyzeAST").returns("");
200+
const stubParse = t.context.sinon.stub(parseUtils, "parseJS").returns("");
181201

182202
await analyzer._analyzeTemplateComponent("pony",
183203
{}, moduleInfo);
@@ -193,7 +213,7 @@ test.serial("_analyzeTemplateComponent: with template name from pageConfig", asy
193213
const moduleInfo = {
194214
addDependency: function() {}
195215
};
196-
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");
216+
const stubAddDependency = t.context.sinon.spy(moduleInfo, "addDependency");
197217

198218
const mockPool = {
199219
async findResource() {
@@ -205,8 +225,8 @@ test.serial("_analyzeTemplateComponent: with template name from pageConfig", asy
205225

206226
const analyzer = new FioriElementsAnalyzer(mockPool);
207227

208-
const stubAnalyzeAST = sinon.stub(analyzer, "_analyzeAST").returns("");
209-
const stubParse = sinon.stub(parseUtils, "parseJS").returns("");
228+
const stubAnalyzeAST = t.context.sinon.stub(analyzer, "_analyzeAST").returns("");
229+
const stubParse = t.context.sinon.stub(parseUtils, "parseJS").returns("");
210230

211231
await analyzer._analyzeTemplateComponent("pony", {
212232
component: {
@@ -225,7 +245,7 @@ test.serial("_analyzeTemplateComponent: with template name from pageConfig", asy
225245
stubParse.restore();
226246
});
227247

228-
test("_analyzeAST: get template name from ast", async (t) => {
248+
test("_analyzeAST: get template name from ast", (t) => {
229249
const code = `sap.ui.define(["a", "sap/fe/core/TemplateAssembler"], function(a, TemplateAssembler){
230250
return TemplateAssembler.getTemplateComponent(getMethods,
231251
"sap.fe.templates.Page.Component", {
@@ -241,11 +261,11 @@ test("_analyzeAST: get template name from ast", async (t) => {
241261
});});`;
242262
const ast = parseUtils.parseJS(code);
243263
const analyzer = new FioriElementsAnalyzer();
244-
const templateName = await analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
264+
const templateName = analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
245265
t.is(templateName, "sap.fe.templates.Page.view.Page");
246266
});
247267

248-
test("_analyzeAST: get template name from ast (async function)", async (t) => {
268+
test.serial("_analyzeAST: get template name from ast (async function)", (t) => {
249269
const code = `sap.ui.define(["a", "sap/fe/core/TemplateAssembler"], async function(a, TemplateAssembler){
250270
return TemplateAssembler.getTemplateComponent(getMethods,
251271
"sap.fe.templates.Page.Component", {
@@ -259,14 +279,16 @@ test("_analyzeAST: get template name from ast (async function)", async (t) => {
259279
"manifest": "json"
260280
}
261281
});});`;
282+
const {FioriElementsAnalyzerWithStubbedLogger, warningLogSpy} = t.context;
262283
const ast = parseUtils.parseJS(code);
263-
const analyzer = new FioriElementsAnalyzer();
264-
const templateName = await analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
284+
const analyzer = new FioriElementsAnalyzerWithStubbedLogger();
285+
const templateName = analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
265286
t.is(templateName, "sap.fe.templates.Page.view.Page");
287+
t.is(warningLogSpy.callCount, 1, "Warning log is called once");
266288
});
267289

268-
test("_analyzeAST: get template name from ast (ArrowFunction)", async (t) => {
269-
const code = `sap.ui.define(["a", "sap/fe/core/TemplateAssembler"], (a, TemplateAssembler) => {
290+
test.serial("_analyzeAST: get template name from ast (async ArrowFunction)", (t) => {
291+
const code = `sap.ui.define(["a", "sap/fe/core/TemplateAssembler"], async (a, TemplateAssembler) => {
270292
return TemplateAssembler.getTemplateComponent(getMethods,
271293
"sap.fe.templates.Page.Component", {
272294
metadata: {
@@ -279,15 +301,17 @@ test("_analyzeAST: get template name from ast (ArrowFunction)", async (t) => {
279301
"manifest": "json"
280302
}
281303
});});`;
304+
const {FioriElementsAnalyzerWithStubbedLogger, warningLogSpy} = t.context;
282305
const ast = parseUtils.parseJS(code);
283-
const analyzer = new FioriElementsAnalyzer();
284-
const templateName = await analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
306+
const analyzer = new FioriElementsAnalyzerWithStubbedLogger();
307+
const templateName = analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
285308
t.is(templateName, "sap.fe.templates.Page.view.Page");
309+
t.is(warningLogSpy.callCount, 1, "Warning log is called once");
286310
});
287311

288-
test("_analyzeAST: get template name from ast (ArrowFunction with implicit return)", async (t) => {
312+
test.serial("_analyzeAST: get template name from ast (async ArrowFunction with implicit return)", (t) => {
289313
const code = `sap.ui.define(["a", "sap/fe/core/TemplateAssembler"],
290-
(a, TemplateAssembler) => TemplateAssembler.getTemplateComponent(getMethods,
314+
async (a, TemplateAssembler) => TemplateAssembler.getTemplateComponent(getMethods,
291315
"sap.fe.templates.Page.Component", {
292316
metadata: {
293317
properties: {
@@ -299,15 +323,37 @@ test("_analyzeAST: get template name from ast (ArrowFunction with implicit retur
299323
"manifest": "json"
300324
}
301325
}));`;
326+
const {FioriElementsAnalyzerWithStubbedLogger, warningLogSpy} = t.context;
327+
const ast = parseUtils.parseJS(code);
328+
const analyzer = new FioriElementsAnalyzerWithStubbedLogger();
329+
const templateName = analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
330+
t.is(templateName, "sap.fe.templates.Page.view.Page");
331+
t.is(warningLogSpy.callCount, 1, "Warning log is called once");
332+
});
333+
334+
test("_analyzeAST: get template name from ast (ArrowFunction)", (t) => {
335+
const code = `sap.ui.define(["a", "sap/fe/core/TemplateAssembler"], (a, TemplateAssembler) => {
336+
return TemplateAssembler.getTemplateComponent(getMethods,
337+
"sap.fe.templates.Page.Component", {
338+
metadata: {
339+
properties: {
340+
"templateName": {
341+
"type": "string",
342+
"defaultValue": "sap.fe.templates.Page.view.Page"
343+
}
344+
},
345+
"manifest": "json"
346+
}
347+
});});`;
302348
const ast = parseUtils.parseJS(code);
303349
const analyzer = new FioriElementsAnalyzer();
304-
const templateName = await analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
350+
const templateName = analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
305351
t.is(templateName, "sap.fe.templates.Page.view.Page");
306352
});
307353

308-
test("_analyzeAST: get template name from ast (async factory function)", async (t) => {
354+
test("_analyzeAST: get template name from ast (ArrowFunction with implicit return)", (t) => {
309355
const code = `sap.ui.define(["a", "sap/fe/core/TemplateAssembler"],
310-
async (a, TemplateAssembler) => TemplateAssembler.getTemplateComponent(getMethods,
356+
(a, TemplateAssembler) => TemplateAssembler.getTemplateComponent(getMethods,
311357
"sap.fe.templates.Page.Component", {
312358
metadata: {
313359
properties: {
@@ -321,11 +367,11 @@ test("_analyzeAST: get template name from ast (async factory function)", async (
321367
}));`;
322368
const ast = parseUtils.parseJS(code);
323369
const analyzer = new FioriElementsAnalyzer();
324-
const templateName = await analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
370+
const templateName = analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
325371
t.is(templateName, "sap.fe.templates.Page.view.Page");
326372
});
327373

328-
test("_analyzeAST: get template name from ast (with SpreadElement)", async (t) => {
374+
test("_analyzeAST: get template name from ast (with SpreadElement)", (t) => {
329375
const code = `sap.ui.define(["a", "sap/fe/core/TemplateAssembler"], (a, TemplateAssembler) => {
330376
const myTemplate = {
331377
templateName: {
@@ -344,14 +390,14 @@ test("_analyzeAST: get template name from ast (with SpreadElement)", async (t) =
344390
});});`;
345391
const ast = parseUtils.parseJS(code);
346392
const analyzer = new FioriElementsAnalyzer();
347-
const templateName = await analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
393+
const templateName = analyzer._analyzeAST("sap.fe.templates.Page.Component", ast);
348394

349395
t.is(templateName, "", "The TemplateName is correctly empty");
350396
// TODO: Support SpreadElement
351397
// t.is(templateName, "sap.fe.templates.Page.view.Page", "The TemplateName is correctly determined");
352398
});
353399

354-
test("_analyzeAST: no template name from ast", async (t) => {
400+
test("_analyzeAST: no template name from ast", (t) => {
355401
const code = `sap.ui.define(["a", "sap/fe/core/TemplateAssembler"], function(a, TemplateAssembler){
356402
return TemplateAssembler.getTemplateComponent(getMethods,
357403
"sap.fe.templates.Page.Component", {
@@ -369,11 +415,10 @@ test("_analyzeAST: no template name from ast", async (t) => {
369415

370416
const analyzer = new FioriElementsAnalyzer();
371417

372-
const stubAnalyzeTemplateClassDefinition = sinon.stub(analyzer,
418+
const stubAnalyzeTemplateClassDefinition = t.context.sinon.stub(analyzer,
373419
"_analyzeTemplateClassDefinition").returns(false);
374420

375-
const result = await analyzer._analyzeAST("pony", ast);
376-
421+
const result = analyzer._analyzeAST("pony", ast);
377422

378423
t.true(stubAnalyzeTemplateClassDefinition.calledOnce, "_analyzeTemplateClassDefinition was called once");
379424

0 commit comments

Comments
 (0)