Skip to content

Commit

Permalink
[FIX] ComponentAnalyzer: Detect model types from dataSource
Browse files Browse the repository at this point in the history
  • Loading branch information
matz3 committed Feb 28, 2019
1 parent feb95e4 commit efc5cef
Show file tree
Hide file tree
Showing 2 changed files with 302 additions and 3 deletions.
38 changes: 35 additions & 3 deletions lib/lbt/analyzer/ComponentAnalyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class ComponentAnalyzer {
* @private
*/
_analyzeManifest( manifest, info ) {
const sapApp = (manifest && manifest["sap.app"]) || {};
const ui5 = (manifest && manifest["sap.ui5"]) || {};

if ( ui5.resources && ui5.resources.css ) {
Expand Down Expand Up @@ -116,12 +117,43 @@ class ComponentAnalyzer {

// TODO usages

// See sap/ui/core/Component._createManifestModelConfigurations
each( ui5.models, (options, model) => {
let modelType;
if ( options.type ) {
const module = ModuleName.fromUI5LegacyName( options.type );
log.verbose("derived model implementation dependency ", module);
info.addDependency(module);
modelType = options.type;
} else if ( options.dataSource && sapApp.dataSources ) {
const oDataSource = sapApp.dataSources[options.dataSource];
if (!oDataSource) {
return;
}
// default dataSource type is OData
const dataSourceType = oDataSource.type || "OData";
switch (dataSourceType) {
case "OData":
if (oDataSource.settings && oDataSource.settings.odataVersion === "4.0") {
modelType = "sap.ui.model.odata.v4.ODataModel";
} else {
modelType = "sap.ui.model.odata.v2.ODataModel";
}
break;
case "JSON":
modelType = "sap.ui.model.json.JSONModel";
break;
case "XML":
modelType = "sap.ui.model.xml.XMLModel";
break;
default:
// for custom dataSource types, the class should already be specified in the sap.ui5 models config
return;
}
} else {
// no type and no dataSource defined
return;
}
const module = ModuleName.fromUI5LegacyName( modelType );
log.verbose("derived model implementation dependency ", module);
info.addDependency(module);
});

const routing = ui5.routing;
Expand Down
267 changes: 267 additions & 0 deletions test/lib/lbt/analyzer/ComponentAnalyzer.js
Original file line number Diff line number Diff line change
Expand Up @@ -594,3 +594,270 @@ test("_analyzeManifest: Manifest with models", async (t) => {
t.deepEqual(stubAddDependency.getCall(0).args[0], "sap/ui/model/resource/ResourceModel.js",
"addDependency should be called with the dependency name");
});

test("_analyzeManifest: Manifest with V2 OData model via dataSources", async (t) => {
const manifest = {
"sap.app": {
"dataSources": {
"mainService": {
"uri": "/uri/to/odata/v2/service",
"type": "OData",
"settings": {
"odataVersion": "2.0"
}
}
}
},
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService"
}
}
}
};

const moduleInfo = {
addDependency: function() {}
};
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");

const analyzer = new ComponentAnalyzer();
await analyzer._analyzeManifest(manifest, moduleInfo);

t.true(stubAddDependency.calledOnce, "addDependency was called once");
t.deepEqual(stubAddDependency.getCall(0).args[0], "sap/ui/model/odata/v2/ODataModel.js",
"addDependency should be called with the dependency name");
});

test("_analyzeManifest: Manifest with V2 OData model via dataSources (default type)", async (t) => {
const manifest = {
"sap.app": {
"dataSources": {
"mainService": {
"uri": "/uri/to/odata/v2/service"
}
}
},
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService"
}
}
}
};

const moduleInfo = {
addDependency: function() {}
};
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");

const analyzer = new ComponentAnalyzer();
await analyzer._analyzeManifest(manifest, moduleInfo);

t.true(stubAddDependency.calledOnce, "addDependency was called once");
t.deepEqual(stubAddDependency.getCall(0).args[0], "sap/ui/model/odata/v2/ODataModel.js",
"addDependency should be called with the dependency name");
});


test("_analyzeManifest: Manifest with V4 OData model via dataSources", async (t) => {
const manifest = {
"sap.app": {
"dataSources": {
"mainService": {
"uri": "/uri/to/odata/v4/service",
"type": "OData",
"settings": {
"odataVersion": "4.0",
}
}
}
},
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService"
}
}
}
};

const moduleInfo = {
addDependency: function() {}
};
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");

const analyzer = new ComponentAnalyzer();
await analyzer._analyzeManifest(manifest, moduleInfo);

t.true(stubAddDependency.calledOnce, "addDependency was called once");
t.deepEqual(stubAddDependency.getCall(0).args[0], "sap/ui/model/odata/v4/ODataModel.js",
"addDependency should be called with the dependency name");
});

test("_analyzeManifest: Manifest with JSON model via dataSources", async (t) => {
const manifest = {
"sap.app": {
"dataSources": {
"mainService": {
"uri": "/uri/to/json/service",
"type": "JSON"
}
}
},
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService"
}
}
}
};

const moduleInfo = {
addDependency: function() {}
};
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");

const analyzer = new ComponentAnalyzer();
await analyzer._analyzeManifest(manifest, moduleInfo);

t.true(stubAddDependency.calledOnce, "addDependency was called once");
t.deepEqual(stubAddDependency.getCall(0).args[0], "sap/ui/model/json/JSONModel.js",
"addDependency should be called with the dependency name");
});

test("_analyzeManifest: Manifest with V4 OData model via dataSources", async (t) => {
const manifest = {
"sap.app": {
"dataSources": {
"mainService": {
"uri": "/uri/to/xml/service",
"type": "XML"
}
}
},
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService"
}
}
}
};

const moduleInfo = {
addDependency: function() {}
};
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");

const analyzer = new ComponentAnalyzer();
await analyzer._analyzeManifest(manifest, moduleInfo);

t.true(stubAddDependency.calledOnce, "addDependency was called once");
t.deepEqual(stubAddDependency.getCall(0).args[0], "sap/ui/model/xml/XMLModel.js",
"addDependency should be called with the dependency name");
});

test("_analyzeManifest: Manifest with model via dataSources (custom type)", async (t) => {
const manifest = {
"sap.app": {
"dataSources": {
"mainService": {
"uri": "/uri/to/some/service",
"type": "MyType"
}
}
},
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService"
}
}
}
};

const moduleInfo = {
addDependency: function() {}
};
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");

const analyzer = new ComponentAnalyzer();
await analyzer._analyzeManifest(manifest, moduleInfo);

t.true(stubAddDependency.notCalled, "addDependency was not called");
});

test("_analyzeManifest: Manifest with model (non existing dataSource)", async (t) => {
const manifest = {
"sap.app": {
"dataSources": {
"mainService": {
"uri": "/uri/to/some/service"
}
}
},
"sap.ui5": {
"models": {
"": {
"dataSource": "someOtherService"
}
}
}
};

const moduleInfo = {
addDependency: function() {}
};
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");

const analyzer = new ComponentAnalyzer();
await analyzer._analyzeManifest(manifest, moduleInfo);

t.true(stubAddDependency.notCalled, "addDependency was not called");
});

test("_analyzeManifest: Manifest with model (non existing dataSource)", async (t) => {
const manifest = {
"sap.ui5": {
"models": {
"": {
"dataSource": "mainService"
}
}
}
};

const moduleInfo = {
addDependency: function() {}
};
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");

const analyzer = new ComponentAnalyzer();
await analyzer._analyzeManifest(manifest, moduleInfo);

t.true(stubAddDependency.notCalled, "addDependency was not called");
});

test("_analyzeManifest: Manifest with model (no type / no dataSource)", async (t) => {
const manifest = {
"sap.ui5": {
"models": {
"": {}
}
}
};

const moduleInfo = {
addDependency: function() {}
};
const stubAddDependency = sinon.spy(moduleInfo, "addDependency");

const analyzer = new ComponentAnalyzer();
await analyzer._analyzeManifest(manifest, moduleInfo);

t.true(stubAddDependency.notCalled, "addDependency was not called");
});

0 comments on commit efc5cef

Please sign in to comment.