diff --git a/.travis.yml b/.travis.yml index aec1545..a578e5d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,5 @@ --- language: node_js -env: - - CXX=g++-4.8 -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.8 sudo: false node_js: - "stable" diff --git a/lib/Action.js b/lib/Action.js index 41b6bdd..05c262f 100644 --- a/lib/Action.js +++ b/lib/Action.js @@ -1,24 +1,24 @@ const ParserCommon = require('./ParserCommon'); -function Action(xml) { - this.Annotations = {}; - this.Parameters = {}; - this.ReturnType = null; +class Action extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; + this.Parameters = {}; + this.ReturnType = null; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Parameter': {parent: this.Parameters, nameProp: 'Name'}, - 'ReturnType': {name: 'ReturnType'} - }; - this.validAttributes = { - 'IsBound': {bool: true}, - 'Name': {alreadyHandeled: true} - }; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, + 'Parameter': {parent: this.Parameters, nameProp: 'Name'}, + 'ReturnType': {name: 'ReturnType'} + }; + this.validAttributes = { + 'IsBound': {bool: true}, + 'Name': {alreadyHandeled: true} + }; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Action', 'Name'); - - return this; + this.init(element, 'Name'); + } } module.exports = Action; diff --git a/lib/ActionImport.js b/lib/ActionImport.js index c46759d..e6234e2 100644 --- a/lib/ActionImport.js +++ b/lib/ActionImport.js @@ -1,22 +1,20 @@ const ParserCommon = require('./ParserCommon'); -const Annotation = require('./Annotation'); +class ActionImport extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; -function ActionImport(xml) { - this.Annotations = {}; - - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Action': {}, - 'EntitySet': {}, - 'Name': {alreadyHandeled: true} - }; - - var init = ParserCommon.initEntity.bind(this); - init(xml, 'ActionImport', 'Name'); - return this; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'} + }; + this.validAttributes = { + 'Action': {}, + 'EntitySet': {}, + 'Name': {alreadyHandeled: true} + }; + this.init(element, 'Name'); + } } module.exports = ActionImport; diff --git a/lib/Annotation.js b/lib/Annotation.js index adfe708..36d0a95 100644 --- a/lib/Annotation.js +++ b/lib/Annotation.js @@ -1,23 +1,23 @@ const ParserCommon = require('./ParserCommon'); -function Annotation(xml) { - this.validElements = { - 'Collection': {parent: this, name: 'Collection'}, - 'Record': {parent: this, name: 'Record'}, - 'String': {parent: this, name: 'String', getText: true} - }; - this.validAttributes = { - 'Term': {alreadyHandeled: true}, - 'Qualifier': {}, - 'String': {}, - 'EnumMember': {}, - 'Bool': {bool: true}, - 'Int': {integer: true} - }; - - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Action', 'Term'); - return this; +class Annotation extends ParserCommon { + constructor(element) { + super(); + this.validElements = { + 'Collection': {parent: this, name: 'Collection'}, + 'Record': {parent: this, name: 'Record'}, + 'String': {parent: this, name: 'String', getText: true} + }; + this.validAttributes = { + 'Term': {alreadyHandeled: true}, + 'Qualifier': {}, + 'String': {}, + 'EnumMember': {}, + 'Bool': {bool: true}, + 'Int': {integer: true} + }; + this.init(element, 'Term'); + } } module.exports = Annotation; diff --git a/lib/CSDLSearch.js b/lib/CSDLSearch.js index 2c4e904..99d4729 100644 --- a/lib/CSDLSearch.js +++ b/lib/CSDLSearch.js @@ -94,9 +94,9 @@ function findByType(metadata, typeName) { var namespace = typeName.substring(0, index); var justType = typeName.substring(index+1); var schema = metadata[namespace]; - if(schema === undefined) { - schema = metadata._options.cache.getSchema(namespace); - if(schema === undefined) { + if(schema === undefined) { + let schemas = metadata._options.cache.getSchemas(namespace); + if(schemas.length === 0) { if(metadata.References === undefined) { return null; } @@ -108,6 +108,17 @@ function findByType(metadata, typeName) { return null; } } + else if(schemas.length === 1) { + schema = schemas[0]; + } + else { + for(let i = 0; i < schemas.length; i++) { + if(schemas[i][justType] !== undefined) { + return schemas[i][justType]; + } + } + return null; + } } return schema[justType]; } diff --git a/lib/Collection.js b/lib/Collection.js index 515e6bd..fff460f 100644 --- a/lib/Collection.js +++ b/lib/Collection.js @@ -1,28 +1,27 @@ const ParserCommon = require('./ParserCommon'); -function Collection(xml) { - this.PropertyPaths = []; - this.Records = []; - this.Strings = []; +class Collection extends ParserCommon { + constructor(element) { + super(); + this.PropertyPaths = []; + this.Records = []; + this.Strings = []; - this.validElements = { - 'PropertyPath': {parent: this.PropertyPaths, getText: true}, - 'Record': {parent: this.Records}, - 'String': {parent: this.Strings, passthru: true} - }; - this.validAttributes = { - }; + this.validElements = { + 'PropertyPath': {parent: this.PropertyPaths, getText: true}, + 'Record': {parent: this.Records}, + 'String': {parent: this.Strings, passthru: true} + }; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Collection'); - - if(this.PropertyPaths.length === 0) { - delete this.PropertyPaths; - } - if(this.Records.length === 0) { - delete this.Records; + this.init(element); + + if(this.PropertyPaths.length === 0) { + delete this.PropertyPaths; + } + if(this.Records.length === 0) { + delete this.Records; + } } - return this; } module.exports = Collection; diff --git a/lib/ComplexType.js b/lib/ComplexType.js index f64d275..7b00d9e 100644 --- a/lib/ComplexType.js +++ b/lib/ComplexType.js @@ -1,24 +1,26 @@ const ParserCommon = require('./ParserCommon'); -function ComplexType(xml) { - this.Properties = {}; - this.Annotations = {}; +class ComplexType extends ParserCommon { + constructor(element) { + super(); - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Property': {parent: this.Properties, nameProp: 'Name'}, - 'NavigationProperty': {parent: this.Properties, nameProp: 'Name'} - }; - this.validAttributes = { - 'Abstract': {bool: true}, - 'OpenType': {bool: true}, - 'BaseType': {}, - 'Name': {alreadyHandeled: true} - }; + this.Properties = {}; + this.Annotations = {}; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'ComplexType', 'Name'); - return this; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, + 'Property': {parent: this.Properties, nameProp: 'Name'}, + 'NavigationProperty': {parent: this.Properties, nameProp: 'Name'} + }; + this.validAttributes = { + 'Abstract': {bool: true}, + 'OpenType': {bool: true}, + 'BaseType': {}, + 'Name': {alreadyHandeled: true} + }; + + this.init(element, 'Name'); + } } module.exports = ComplexType; diff --git a/lib/EntityContainer.js b/lib/EntityContainer.js index 0dd3269..312501f 100644 --- a/lib/EntityContainer.js +++ b/lib/EntityContainer.js @@ -1,20 +1,22 @@ const ParserCommon = require('./ParserCommon'); -function EntityContainer(xml) { - this.validElements = { - 'EntitySet': {parent: this, nameProp: 'Name'}, - 'Singleton': {parent: this, nameProp: 'Name'}, - 'ActionImport': {parent: this, nameProp: 'Name'}, - 'FunctionImport': {parent: this, nameProp: 'Name'} - }; - this.validAttributes = { - 'Extends': {}, - 'Name': {alreadyHandeled: true} - }; +class EntityContainer extends ParserCommon { + constructor(element) { + super(); - var init = ParserCommon.initEntity.bind(this); - init(xml, 'EntityContainer', 'Name'); - return this; + this.validElements = { + 'EntitySet': {parent: this, nameProp: 'Name'}, + 'Singleton': {parent: this, nameProp: 'Name'}, + 'ActionImport': {parent: this, nameProp: 'Name'}, + 'FunctionImport': {parent: this, nameProp: 'Name'} + }; + this.validAttributes = { + 'Extends': {}, + 'Name': {alreadyHandeled: true} + }; + + this.init(element, 'Name'); + } } module.exports = EntityContainer; diff --git a/lib/EntitySet.js b/lib/EntitySet.js index 85c0bf0..f71eb38 100644 --- a/lib/EntitySet.js +++ b/lib/EntitySet.js @@ -1,22 +1,22 @@ const ParserCommon = require('./ParserCommon'); -function EntitySet(xml) { - this.Annotations = {}; - this.NaviagtionPropertyBindings = {}; +class EntitySet extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; + this.NaviagtionPropertyBindings = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'NavigationPropertyBinding': {parent: this.NaviagtionPropertyBindings, nameProp: 'Path'} - }; - this.validAttributes = { - 'EntityType': {}, - 'Name': {alreadyHandeled: true} - }; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, + 'NavigationPropertyBinding': {parent: this.NaviagtionPropertyBindings, nameProp: 'Path'} + }; + this.validAttributes = { + 'EntityType': {}, + 'Name': {alreadyHandeled: true} + }; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'EntitySet', 'Name'); - - return this; + this.init(element, 'Name'); + } } module.exports = EntitySet; diff --git a/lib/EntityType.js b/lib/EntityType.js index ea66d89..b565c8a 100644 --- a/lib/EntityType.js +++ b/lib/EntityType.js @@ -1,38 +1,38 @@ const ParserCommon = require('./ParserCommon'); -function EntityType(xml) { - this._key = null; - this.Annotations = {}; - this.Properties = {}; +class EntityType extends ParserCommon { + constructor(element) { + super(); - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Property': {parent: this.Properties, nameProp: 'Name'}, - 'NavigationProperty': {parent: this.Properties, nameProp: 'Name'}, - 'Key': {parent: this, name: '_key', passthru: true} - }; - this.validAttributes = { - 'Abstract': {bool: true}, - 'BaseType': {}, - 'Name': {alreadyHandeled: true} - }; + this._key = null; + this.Annotations = {}; + this.Properties = {}; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'EntityType', 'Name'); + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, + 'Property': {parent: this.Properties, nameProp: 'Name'}, + 'NavigationProperty': {parent: this.Properties, nameProp: 'Name'}, + 'Key': {parent: this, name: '_key', passthru: true} + }; + this.validAttributes = { + 'Abstract': {bool: true}, + 'BaseType': {}, + 'Name': {alreadyHandeled: true} + }; - if(this._key !== null) - { - var propNames = this._key.find('.//*[local-name()="PropertyRef"]/@Name'); - for(var i = 0; i < propNames.length; i++) - { - var name = propNames[i].value(); - if(this.Properties[name] !== undefined) { - this.Properties[name].IsKey = true; - } + this.init(element, 'Name'); + + if(this._key !== null) { + let propRefs = this._key.childrenNamed('PropertyRef'); + for(let i = 0; i < propRefs.length; i++) { + let name = propRefs[i].attr['Name']; + if(this.Properties[name] !== undefined) { + this.Properties[name].IsKey = true; + } + } } + delete this._key; } - delete this._key; - return this; } module.exports = EntityType; diff --git a/lib/EnumType.js b/lib/EnumType.js index 8222b1e..1e460b7 100644 --- a/lib/EnumType.js +++ b/lib/EnumType.js @@ -1,48 +1,47 @@ const ParserCommon = require('./ParserCommon'); +const Annotation = require('./Annotation'); -function EnumType(xml) { - this._index = 0; - this.Members = {}; - this.Annotations = {}; +class EnumType extends ParserCommon { + constructor(element) { + super(); + this._index = 0; + this.Members = {}; + this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Member': {parent: this.Parameters, helperFunc: this.memberHelper.bind(this)} - }; - this.validAttributes = { - 'IsFlags': {bool: true}, - 'Name': {alreadyHandeled: true} - }; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, + 'Member': {parent: this.Parameters, helperFunc: this.memberHelper.bind(this)} + }; + this.validAttributes = { + 'IsFlags': {bool: true}, + 'Name': {alreadyHandeled: true} + }; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'EnumType', 'Name'); - delete this._index; - return this; -} - -EnumType.prototype.memberHelper = function(element) { - var name = element.attr('Name').value(); - var value = element.attr('Value'); - this.Members[name] = {}; - if(value === null) - { - this.Members[name].value = this._index++; + this.init(element, 'Name'); + delete this._index; } - else - { - this.Members[name].value = value.value()*1; - this._index = value.value()*1; - } - var children = element.childNodes(); - for(var i = 0; i < children.length; i++) { - if(children[i].type() === 'element' && children[i].name() === 'Annotation') { - if(this.Members[name].Annotations === undefined) { - this.Members[name].Annotations = {}; - } - var type = require('./Annotation'); - var annotation = new type(children[i]); - this.Members[name].Annotations[annotation.Name] = annotation; + + memberHelper(element) { + let name = element.attr['Name']; + let value = element.attr['Value']; + this.Members[name] = {}; + if(value) { + this.Members[name].value = value*1; + this._index = value*1; + } + else { + this.Members[name].value = this._index++; } + let me = this; + element.eachChild(function(child, index, array) { + if(child.name === 'Annotation') { + let annotation = new Annotation(child); + if(me.Members[name].Annotations === undefined) { + me.Members[name].Annotations = {}; + } + me.Members[name].Annotations[annotation.Name] = annotation; + } + }); } } diff --git a/lib/Function.js b/lib/Function.js index 9d862d2..35766ca 100644 --- a/lib/Function.js +++ b/lib/Function.js @@ -1,25 +1,26 @@ const ParserCommon = require('./ParserCommon'); -function Function(xml) { - this.Annotations = {}; - this.Parameters = {}; - this.ReturnType = null; +class Function extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; + this.Parameters = {}; + this.ReturnType = null; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Parameter': {parent: this.Parameters, nameProp: 'Name'}, - 'ReturnType': {name: 'ReturnType'} - }; - this.validAttributes = { - 'IsBound': {bool: true}, - 'IsComposable': {bool: true}, - 'EntitySetPath': {}, - 'Name': {alreadyHandeled: true} - }; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, + 'Parameter': {parent: this.Parameters, nameProp: 'Name'}, + 'ReturnType': {name: 'ReturnType'} + }; + this.validAttributes = { + 'IsBound': {bool: true}, + 'IsComposable': {bool: true}, + 'EntitySetPath': {}, + 'Name': {alreadyHandeled: true} + }; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Function', 'Name'); - return this; + this.init(element, 'Name'); + } } module.exports = Function; diff --git a/lib/FunctionImport.js b/lib/FunctionImport.js index 8ff6ed6..a3491b1 100644 --- a/lib/FunctionImport.js +++ b/lib/FunctionImport.js @@ -1,21 +1,21 @@ const ParserCommon = require('./ParserCommon'); -function FunctionImport(xml) { - this.Annotations = {}; +class FunctionImport extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'IncludeInServiceDocument': {bool: true}, - 'EntitySet': {}, - 'Function': {}, - 'Name': {alreadyHandeled: true} - }; - - var init = ParserCommon.initEntity.bind(this); - init(xml, 'FunctionImport', 'Name'); - return this; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'} + }; + this.validAttributes = { + 'IncludeInServiceDocument': {bool: true}, + 'EntitySet': {}, + 'Function': {}, + 'Name': {alreadyHandeled: true} + }; + this.init(element, 'Name'); + } } module.exports = FunctionImport; diff --git a/lib/Metadata.js b/lib/Metadata.js index a3494d0..baa9992 100644 --- a/lib/Metadata.js +++ b/lib/Metadata.js @@ -1,22 +1,22 @@ -//const xmljs = require('libxmljs-mt'); -const xmljs = require('libxmljs'); +const xmldoc = require('xmldoc'); const fs = require('fs'); const request = require('request'); const ParserCommon = require('./ParserCommon'); +const Reference = require('./Reference'); +const Schema = require('./Schema'); const CSDLCache = require('./cache/csdlCache'); -function Metadata(options) { - this._options = {useLocal: null, useNetwork: true}; - this.References = []; - if(options !== undefined) { - this.setOptions(options); +class Metadata { + constructor(options) { + this._options = {useLocal: null, useNetwork: true}; + this.References = []; + if(options) { + this.setOptions(options); + } } - return this; -} -Metadata.prototype.setOptions = function(options) { - if(options !== undefined && options !== null) { + setOptions(options) { this._options = Object.assign(this._options, options); if(this._options.cache === undefined) { this._options.cache = new CSDLCache(this._options.useLocal, this._options.useNetwork); @@ -26,110 +26,62 @@ Metadata.prototype.setOptions = function(options) { this._options.cache.useNetwork = this._options.useNetwork; } } -}; - -Metadata.prototype.done = function(error) { - if(this.reallyDone !== undefined) { - var callback = this.reallyDone; - delete this.reallyDone; - if(this.context !== undefined) { - callback = callback.bind(this.context); - delete this.context; - } - if(this._options.cache) { - this._options.cache.addMetadata(this); - } - callback(error, this); - } -} - -Metadata.prototype.parse = function(string, callback, context) { - this.reallyDone = callback; - this.context = context; - try { - var doc = xmljs.parseXml(string); - } catch(e) { - this.done(e); - return; - } - var root = doc.root(); - var parseElement = this.parseElement.bind(this); - try { - ParserCommon.parseEntity(root, 'Metadata', parseElement); - } - catch(e) { - this.done(e); - } - this.done(null); -} - -Metadata.prototype.resolve = function(callback) { - var prom = this.resolvePromise(); - prom.then(function(data) { - callback(null, data); - }).catch(function(error) { - callback(error, null); - }); -} -Metadata.prototype.resolvePromise = function() { - var self = this; - if(this.References === undefined || this.References.length === 0) { - delete this.context; - return new Promise(function(resolve, reject) { - resolve(self); + parse(string, callback, context) { + let arr = []; + let doc = new xmldoc.XmlDocument(string); + let me = this; + doc.eachChild(function(child, index, array) { + let elemName = child.name; + switch(elemName) { + case 'Reference': + case 'edmx:Reference': + let ref = new Reference(child); + arr.push(ref.bind(me._options.cache)); + me.References.push(ref); + break; + case 'DataServices': + case 'edmx:DataServices': + arr.push(me.parseDataServices(child)); + break; + default: + arr.push(Promise.reject(new Error('Unknown element name '+elemName))); + break; + } }); - } - else { - return new Promise(function(resolve, reject) { - self._options.cache.waitForCoherent(function(error) { - if(error) { - reject(error); - } - else { - resolve(self); - } - }); + Promise.all(arr).then((values) => { + callback(null, me); + if(me._options.cache) { + me._options.cache.addMetadata(me); + } + }).catch((e) => { + callback(e, null); }); } -} -Metadata.prototype.parseElement = function(element) { - var elemName = element.name(); - switch(elemName) { - case 'Reference': - var Reference = require('./Reference'); - var errorCallback = this.done.bind(this); - this.References.push(new Reference(element, this._options.cache, errorCallback)); - break; - case 'DataServices': - this.parseDataServices(element); - break; - default: - throw new Error('Unknown element name '+element.name()); - } -} - -Metadata.prototype.parseDataServices = function(dataServices) { - var parseElement = this.parseDataServiceElement.bind(this); - try { - ParserCommon.parseEntity(dataServices, 'DataService', parseElement); - } - catch(e) { - this.done(e); + parseDataServices(element) { + let me = this; + element.eachChild(function(child, index, array) { + let elemName = child.name; + switch(elemName) { + case 'Schema': + let namespace = child.attr['Namespace']; + me[namespace] = new Schema(child); + break; + default: + arr.push(Promise.reject(new Error('Unknown element name '+elemName))); + break; + } + }); + //Just resolve this with null as we have no new references to add + return Promise.resolve(null); } -} -Metadata.prototype.parseDataServiceElement = function(element) { - var elemName = element.name(); - switch(elemName) { - case 'Schema': - var namespace = element.attr('Namespace').value(); - var Schema = require('./Schema'); - this[namespace] = new Schema(element); - break; - default: - throw new Error('Unknown element name '+element.name()); + resolve() { + if(this.References === undefined || this.References.length === 0) { + return Promise.resolve(null); + } + return this._options.cache.waitForCoherent(); } } @@ -138,13 +90,17 @@ module.exports.construct = Metadata; module.exports.parseMetadata = function(string, options, callback) { try { var meta = new Metadata(options); - meta.parse(string, function(error, metadata) { - if(error) { - callback(error, metadata); - } - else { - metadata.resolve(callback); + meta.parse(string, (err, data) => { + if(err) { + callback(err, data); + return; } + let promise = data.resolve(); + promise.then(() => { + callback(null, data); + }).catch((e) => { + callback(e, data); + }); }); } catch(e) { @@ -171,5 +127,4 @@ module.exports.parseMetadataUri = function(uri, options, callback) { module.exports.parseMetadata(body, options, callback); }); } - /* vim: set tabstop=2 shiftwidth=2 expandtab: */ diff --git a/lib/NavigationProperty.js b/lib/NavigationProperty.js index 0699760..669fa60 100644 --- a/lib/NavigationProperty.js +++ b/lib/NavigationProperty.js @@ -1,27 +1,25 @@ const ParserCommon = require('./ParserCommon'); -const Annotation = require('./Annotation'); +class NavigationProperty extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; -function NavigationProperty(xml) { - this.Annotations = {}; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'} + //TODO ReferentialConstraint handling + //TODO OnDelete Handling + }; + this.validAttributes = { + 'Name': {alreadyHandeled: true}, + 'Type': {}, + 'Nullable': {bool: true}, + 'Partner': {}, + 'ContainsTarget': {bool: true} + }; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - //TODO ReferentialConstraint handling - //TODO OnDelete Handling - }; - this.validAttributes = { - 'Name': {alreadyHandeled: true}, - 'Type': {}, - 'Nullable': {bool: true}, - 'Partner': {}, - 'ContainsTarget': {bool: true} - }; - - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Property', 'Name'); - - return this; + this.init(element, 'Name'); + } } module.exports = NavigationProperty; diff --git a/lib/NavigationPropertyBinding.js b/lib/NavigationPropertyBinding.js index 7cba1c5..6ab583d 100644 --- a/lib/NavigationPropertyBinding.js +++ b/lib/NavigationPropertyBinding.js @@ -1,16 +1,14 @@ const ParserCommon = require('./ParserCommon'); -function NavigationPropertyBinding(xml) { - this.validElements = { - }; - this.validAttributes = { - 'Target': {}, - 'Path': {alreadyHandeled: true} - }; - - var init = ParserCommon.initEntity.bind(this); - init(xml, 'NavigationPropertyBinding', 'Path'); - return this; +class NavigationPropertyBinding extends ParserCommon { + constructor(element) { + super(); + this.validAttributes = { + 'Target': {}, + 'Path': {alreadyHandeled: true} + }; + this.init(element, 'Path'); + } } module.exports = NavigationPropertyBinding; diff --git a/lib/Parameter.js b/lib/Parameter.js index 423bb8e..823693c 100644 --- a/lib/Parameter.js +++ b/lib/Parameter.js @@ -1,25 +1,27 @@ const ParserCommon = require('./ParserCommon'); -function Parameter(xml) { - this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Name': {alreadyHandeled: true}, - 'Type': {}, - 'Nullable': {bool: true}, - 'MaxLength': {integer: true}, - 'Precision': {integer: true}, - 'Scale': {}, - 'Unicode': {bool: true}, - 'SRID': {} - }; +class Parameter extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Parameter', 'Name'); - return this; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'} + }; + this.validAttributes = { + 'Name': {alreadyHandeled: true}, + 'Type': {}, + 'Nullable': {bool: true}, + 'MaxLength': {integer: true}, + 'Precision': {integer: true}, + 'Scale': {}, + 'Unicode': {bool: true}, + 'SRID': {} + }; + + this.init(element, 'Name'); + } } module.exports = Parameter; diff --git a/lib/ParserCommon.js b/lib/ParserCommon.js index ba6789d..bfb0ce3 100644 --- a/lib/ParserCommon.js +++ b/lib/ParserCommon.js @@ -1,55 +1,42 @@ 'use strict' -/** Initialize an entity. Bind this function to the object before you call it!*/ -function initEntity(element, entityTypeName, nameAttr, nameAttrLocation) { - if(this.parseEntity !== undefined) { - throw new Error('Function not bound before call!'); - } - if(nameAttr !== undefined) { - if(nameAttrLocation === undefined) { - nameAttrLocation = 'Name'; - } - this[nameAttrLocation] = element.attr(nameAttr).value(); - } - if(this.validElements !== undefined || this.validAttributes !== undefined) { - parseEntity(element, entityTypeName, defaultElementParse.bind(this), defaultAttributeParse.bind(this)); - delete this.validElements; - delete this.validAttributes; - } -} -function parseEntity(element, entityName, elementCallback, attributeCallback) { - if(elementCallback !== undefined) { - var children = element.childNodes(); - for(var i = 0; i < children.length; i++) { - switch(children[i].type()) { - case 'element': - elementCallback(children[i]); - break; - case 'text': - var text = children[i].toString().trim(); - if(text.length !== 0) { - throw new Error('Unknown text element in '+entityName+'! Text = "'+text+'"'); - } - break; - case 'comment': - //Ignore comments - break; +class ParserCommon { + init(element, nameAttr, nameAttrLocation) { + let entityTypeName = this.constructor.name; + if(nameAttr !== undefined) { + if(nameAttrLocation === undefined) { + nameAttrLocation = 'Name'; } + this[nameAttrLocation] = element.attr[nameAttr]; + } + + if(this.validElements !== undefined || this.validAttributes !== undefined) { + this.parseEntity(element, entityTypeName); + delete this.validElements; + delete this.validAttributes; } } - if(attributeCallback !== undefined) { - var attributes = element.attrs(); - for(var i = 0; i < attributes.length; i++) - { - attributeCallback(attributes[i]); - } + + parseEntity(element, entityName) { + let me = this; + if(element.val.trim().length !== 0) { + throw new Error('Unknown text element in '+entityName+'! Text = "'+element.val+'"'); + } + element.eachChild(function(child, index, array) { + me.parseChildElement(child); + }); + + for(let name in element.attr) { + this.parseAttribute(name, element.attr[name]); + } } -} -function defaultElementParse(element) { - var elemName = element.name(); - if(this.validElements !== undefined && this.validElements[elemName] !== undefined) { - var options = this.validElements[elemName]; + parseChildElement(element) { + let elemName = element.name; + if(this.validElements === undefined || this.validElements[elemName] === undefined) { + throw new Error('Unknown element name '+elemName+' in Parent '+this.constructor.name); + } + let options = this.validElements[elemName]; if(options.parent === undefined) { options.parent = this; } @@ -57,12 +44,12 @@ function defaultElementParse(element) { options.helperFunc(element); return; } - var name = false; + let name = false; if(options.name !== undefined) { name = options.name; } else if(options.nameProp !== undefined) { - name = element.attr(options.nameProp).value(); + name = element.attr[options.nameProp]; } if(options.passthru === true) { options.parent[name] = element; @@ -70,28 +57,26 @@ function defaultElementParse(element) { } if(name === false) { if(options.getText === true) { - options.parent.push(element.text()); + options.parent.push(element.val); return; } - var type = require('./'+elemName); + let type = require('./'+elemName); options.parent.push(new type(element)); + return; } if(options.getText === true) { - options.parent[name] = element.text(); + options.parent[name] = element.val; return; } var type = require('./'+elemName); options.parent[name] = new type(element); } - else { - throw new Error('Unknown element name '+elemName); - } -} -function defaultAttributeParse(attribute) { - var attrName = attribute.name(); - if(this.validAttributes !== undefined && this.validAttributes[attrName] !== undefined) { - var options = this.validAttributes[attrName]; + parseAttribute(name, value) { + if(this.validAttributes === undefined || this.validAttributes[name] === undefined) { + throw new Error('Unknown attribute name '+name); + } + let options = this.validAttributes[name]; if(options.alreadyHandeled === true) { return; } @@ -99,40 +84,34 @@ function defaultAttributeParse(attribute) { options.parent = this; } if(options.name === undefined) { - options.name = attrName; + options.name = name; } if(options.bool === true) { - parseBooleanAttribute(options.parent, attribute, options.name); + this.parseBooleanAttribute(options.parent, value, options.name); } else if(options.integer === true) { - options.parent[options.name] = attribute.value()*1; + options.parent[options.name] = value*1; } else { - options.parent[options.name] = attribute.value(); + options.parent[options.name] = value; if(options.helperFunc !== undefined) { options.parent[options.name] = options.helperFunc(options.parent[options.name]); } } } - else { - throw new Error('Unknown attribute name '+attrName); - } -} -function parseBooleanAttribute(entity, attr, name) { - var value = attr.value(); - if(value === 'true') { - entity[name] = true; - } - else if(value === 'false') { - entity[name] = false; - } - else { - throw new Error('Unknown value '+value+' for attribute named '+name); + parseBooleanAttribute(entity, value, name) { + if(value === 'true') { + entity[name] = true; + } + else if(value === 'false') { + entity[name] = false; + } + else { + throw new Error('Unknown value '+value+' for attribute named '+name); + } } } -module.exports.initEntity = initEntity; -module.exports.parseEntity = parseEntity; -module.exports.parseBooleanAttribute = parseBooleanAttribute; +module.exports = ParserCommon; /* vim: set tabstop=2 shiftwidth=2 expandtab: */ diff --git a/lib/Property.js b/lib/Property.js index 2829f7e..5016fdc 100644 --- a/lib/Property.js +++ b/lib/Property.js @@ -1,25 +1,28 @@ const ParserCommon = require('./ParserCommon'); -function Property(xml) { - this.Annotations = {}; +class Property extends ParserCommon { + constructor(element) { + super(); - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Type': {}, - 'Nullable': {bool: true}, - 'MaxLength': {integer: true}, - 'Precision': {integer: true}, - 'Scale': {}, - 'Unicode': {bool: true}, - 'SRID': {}, - 'DefaultValue': {}, - 'Name': {alreadyHandeled: true} - }; + this.Annotations = {}; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Property', 'Name'); + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'} + }; + this.validAttributes = { + 'Type': {}, + 'Nullable': {bool: true}, + 'MaxLength': {integer: true}, + 'Precision': {integer: true}, + 'Scale': {}, + 'Unicode': {bool: true}, + 'SRID': {}, + 'DefaultValue': {}, + 'Name': {alreadyHandeled: true} + }; + + this.init(element, 'Name'); + } } module.exports = Property; diff --git a/lib/PropertyValue.js b/lib/PropertyValue.js index 6535be3..83a2ae0 100644 --- a/lib/PropertyValue.js +++ b/lib/PropertyValue.js @@ -1,24 +1,24 @@ const ParserCommon = require('./ParserCommon'); -function PropertyValue(xml) { - this.Annotations = {}; - this.Records = []; +class PropertyValue extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; + this.Records = []; - this.validElements = { - 'Record': {parent: this.Records} - }; - this.validAttributes = { - 'Bool': {bool: true}, - 'String': {}, - 'Path': {}, - 'Property': {alreadyHandeled: true}, - 'EnumMember': {} - }; - - var init = ParserCommon.initEntity.bind(this); - init(xml, 'PropertyValue', 'Property'); - - return this; + this.validElements = { + 'Record': {parent: this.Records}, + 'Collection': {parent: this, name: 'Collection'} + }; + this.validAttributes = { + 'Bool': {bool: true}, + 'String': {}, + 'Path': {}, + 'Property': {alreadyHandeled: true}, + 'EnumMember': {} + }; + this.init(element, 'Property'); + } } module.exports = PropertyValue; diff --git a/lib/Record.js b/lib/Record.js index 028090b..3a8ac9f 100644 --- a/lib/Record.js +++ b/lib/Record.js @@ -1,20 +1,20 @@ const ParserCommon = require('./ParserCommon'); -function Record(xml) { - this.Annotations = {}; - this.PropertyValues = {}; +class Record extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; + this.PropertyValues = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'PropertyValue': {parent: this.PropertyValues, nameProp: 'Property'} - }; - this.validAttributes = { - 'Type': {} - }; - - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Record'); - return this; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, + 'PropertyValue': {parent: this.PropertyValues, nameProp: 'Property'} + }; + this.validAttributes = { + 'Type': {} + }; + this.init(element); + } } module.exports = Record; diff --git a/lib/Reference.js b/lib/Reference.js index a7d84e0..83fccb1 100644 --- a/lib/Reference.js +++ b/lib/Reference.js @@ -1,35 +1,48 @@ const ParserCommon = require('./ParserCommon'); -function Reference(xml, cache, errorCallback) { - this.Uri = null; - this.Includes = {}; - this.Annotations = {}; +class Reference extends ParserCommon { + constructor(element) { + super(); + this.Uri = null; + this.Includes = {}; + this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'Include': {parent: this.Includes, helperFunc: this.processInclude.bind(this)} - }; - this.validAttributes = { - 'Uri': {} - }; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Reference'); + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, + 'Include': {parent: this.Includes, helperFunc: this.processInclude.bind(this)}, + 'edmx:Include': {parent: this.Includes, helperFunc: this.processInclude.bind(this)} + }; + this.validAttributes = { + 'Uri': {} + }; - if(!cache.hasMetadata(this.Uri)) { - this.MetaPromise = cache.getMetadata(this.Uri); - var self = this; - this.MetaPromise.then(function(data) {self.Metadata = data;}).catch(errorCallback); + this.init(element); } -} -Reference.prototype.processInclude = function(element) { - var namespace = element.attr('Namespace').value(); - var aliasAttr = element.attr('Alias'); - if(aliasAttr === null) { - this.Includes[namespace] = namespace; + processInclude(element) { + let namespace = element.attr['Namespace']; + let aliasAttr = element.attr['Alias']; + if(aliasAttr) { + this.Includes[aliasAttr] = namespace; + } + else { + this.Includes[namespace] = namespace; + } } - else { - this.Includes[aliasAttr.value()] = namespace; + + bind(cache) { + let me = this; + if(cache.hasMetadata(this.Uri)) { + //Someone else is already doing this... + return Promise.resolve(null); + } + let promise = cache.getMetadata(this.Uri); + return new Promise((resolve, reject) => { + promise.then((data) => { + this.Metadata = data; + resolve(null); + }).catch(reject); + }); } } diff --git a/lib/ReturnType.js b/lib/ReturnType.js index 59dc7e8..da2dc9b 100644 --- a/lib/ReturnType.js +++ b/lib/ReturnType.js @@ -1,17 +1,18 @@ const ParserCommon = require('./ParserCommon'); -function ReturnType(xml) { - this.validElements = { - }; - this.validAttributes = { - 'Nullable': {bool: true}, - 'Type': {}, - 'Name': {alreadyHandeled: true} - }; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'ReturnType'); - return this; +class ReturnType extends ParserCommon { + constructor(element) { + super(); + + this.validAttributes = { + 'Nullable': {bool: true}, + 'Type': {}, + 'Name': {alreadyHandeled: true} + }; + + this.init(element); + } } module.exports = ReturnType; diff --git a/lib/Schema.js b/lib/Schema.js index 6ff752d..5828c79 100644 --- a/lib/Schema.js +++ b/lib/Schema.js @@ -1,26 +1,30 @@ +'use strict' const ParserCommon = require('./ParserCommon'); -function Schema(xml) { - this.Annotations = {}; +class Schema extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; - this.validElements = { - 'Action': {parent: this, nameProp: 'Name'}, - 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, - 'ComplexType': {parent: this, nameProp: 'Name'}, - 'EntityContainer': {parent: this, nameProp: 'Name'}, - 'EntityType': {parent: this, nameProp: 'Name'}, - 'EnumType': {parent: this, nameProp: 'Name'}, - 'Function': {parent: this, nameProp: 'Name'}, - 'Term': {parent: this, nameProp: 'Name'}, - 'TypeDefinition': {parent: this, nameProp: 'Name'} - }; - this.validAttributes = { - 'Namespace': {alreadyHandeled: true}, - 'Alias': {name: '_Alias'} - }; + this.validElements = { + 'Action': {parent: this, nameProp: 'Name'}, + 'Annotation': {parent: this.Annotations, nameProp: 'Term'}, + 'ComplexType': {parent: this, nameProp: 'Name'}, + 'EntityContainer': {parent: this, nameProp: 'Name'}, + 'EntityType': {parent: this, nameProp: 'Name'}, + 'EnumType': {parent: this, nameProp: 'Name'}, + 'Function': {parent: this, nameProp: 'Name'}, + 'Term': {parent: this, nameProp: 'Name'}, + 'TypeDefinition': {parent: this, nameProp: 'Name'} + }; + this.validAttributes = { + 'Namespace': {alreadyHandeled: true}, + 'Alias': {name: '_Alias'}, + 'xmlns': {alreadyHandeled: true} + }; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Action', 'Namespace', '_Name'); + this.init(element, 'Namespace', '_Name'); + } } module.exports = Schema; diff --git a/lib/Singleton.js b/lib/Singleton.js index 83f258c..58ea741 100644 --- a/lib/Singleton.js +++ b/lib/Singleton.js @@ -1,19 +1,19 @@ const ParserCommon = require('./ParserCommon'); -function Singleton(xml) { - this.Annotations = {}; +class Singleton extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Type': {}, - 'Name': {alreadyHandeled: true} - }; - - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Singleton', 'Name'); - return this; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'} + }; + this.validAttributes = { + 'Type': {}, + 'Name': {alreadyHandeled: true} + }; + this.init(element, 'Name'); + } } module.exports = Singleton; diff --git a/lib/Term.js b/lib/Term.js index 5f75fed..fcbc194 100644 --- a/lib/Term.js +++ b/lib/Term.js @@ -1,30 +1,31 @@ const ParserCommon = require('./ParserCommon'); -function Term(xml) { - this.Annotations = {}; +class Term extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'Name': {alreadyHandeled: true}, - 'Type': {}, - 'BaseTerm': {}, - 'DefaultValue': {}, - 'AppliesTo': {helperFunc: this.splitAppliesTo}, - 'Nullable': {bool: true}, - 'MaxLength': {integer: true}, - 'Precision': {integer: true}, - 'Scale': {}, - 'SRID': {} - }; - var init = ParserCommon.initEntity.bind(this); - init(xml, 'Term', 'Name'); - return this; -} + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'} + }; + this.validAttributes = { + 'Name': {alreadyHandeled: true}, + 'Type': {}, + 'BaseTerm': {}, + 'DefaultValue': {}, + 'AppliesTo': {helperFunc: this.splitAppliesTo.bind(this)}, + 'Nullable': {bool: true}, + 'MaxLength': {integer: true}, + 'Precision': {integer: true}, + 'Scale': {}, + 'SRID': {} + }; + this.init(element, 'Name'); + } -Term.prototype.splitAppliesTo = function(value) { - return value.split(' '); + splitAppliesTo(value) { + return value.split(' '); + } } module.exports = Term; diff --git a/lib/TypeDefinition.js b/lib/TypeDefinition.js index ec7c7d1..19324e2 100644 --- a/lib/TypeDefinition.js +++ b/lib/TypeDefinition.js @@ -1,24 +1,24 @@ const ParserCommon = require('./ParserCommon'); -function TypeDefinition(xml) { - this.Annotations = {}; +class TypeDefinition extends ParserCommon { + constructor(element) { + super(); + this.Annotations = {}; - this.validElements = { - 'Annotation': {parent: this.Annotations, nameProp: 'Term'} - }; - this.validAttributes = { - 'UnderlyingType': {}, - 'Name': {alreadyHandeled: true}, - 'MaxLength': {integer: true}, - 'Precision': {integer: true}, - 'Scale': {}, - 'Unicode': {bool: true}, - 'SRID': {} - }; - - var init = ParserCommon.initEntity.bind(this); - init(xml, 'TypeDefinition', 'Name'); - return this; + this.validElements = { + 'Annotation': {parent: this.Annotations, nameProp: 'Term'} + }; + this.validAttributes = { + 'UnderlyingType': {}, + 'Name': {alreadyHandeled: true}, + 'MaxLength': {integer: true}, + 'Precision': {integer: true}, + 'Scale': {}, + 'Unicode': {bool: true}, + 'SRID': {} + }; + this.init(element, 'Name'); + } } module.exports = TypeDefinition; diff --git a/lib/cache/csdlCache.js b/lib/cache/csdlCache.js index 4a17c89..30a3baf 100644 --- a/lib/cache/csdlCache.js +++ b/lib/cache/csdlCache.js @@ -31,7 +31,7 @@ CSDLCache.prototype.getMetadata = function(uri) { reject(error); } else { - self.metadataCache.push(metadata); + //self.metadataCache.push(metadata); resolve(metadata); } }); @@ -61,15 +61,15 @@ CSDLCache.prototype.clear = function() { this.metadataCache = []; } -CSDLCache.prototype.waitForCoherent = function(callback) { +CSDLCache.prototype.waitForCoherent = function() { var promises = []; for(var key in this.csdlCache) { promises.push(this.csdlCache[key]); } - Promise.all(promises).then(function() {callback(null);}).catch(function(err) {callback(err);}); + return Promise.all(promises); } -CSDLCache.prototype.getSchema = function(namespace) { +CSDLCache.prototype.getSchema = function(namespace) { for(var i = 0; i < this.metadataCache.length; i++) { var metadata = this.metadataCache[i]; if(metadata[namespace] !== undefined) { @@ -79,6 +79,31 @@ CSDLCache.prototype.getSchema = function(namespace) { return undefined; } +//There can be multiple in some cases this returns all... +CSDLCache.prototype.getSchemas = function(namespace) { + let arr = []; + for(var i = 0; i < this.metadataCache.length; i++) { + var metadata = this.metadataCache[i]; + if(metadata[namespace] !== undefined) { + arr.push(metadata[namespace]); + } + } + return arr; +} + +CSDLCache.prototype.getSchemasThatStartWith = function(namespace) { + let arr = []; + for(var i = 0; i < this.metadataCache.length; i++) { + var metadata = this.metadataCache[i]; + for(var name in metadata) { + if(name.startsWith(namespace)) { + arr.push(metadata[name]); + } + } + } + return arr; +} + CSDLCache.prototype.addMetadata = function(metadata) { this.metadataCache.push(metadata); } diff --git a/package.json b/package.json index 0b38983..8289492 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "main": "./index.js", "scripts": { "test": "nyc mocha", + "nocov": "mocha", "coveralls": "nyc report --reporter=text-lcov | coveralls" }, "engines": { @@ -17,8 +18,8 @@ "url": "https://github.com/pboyd04/CSDLParser.git" }, "dependencies": { - "libxmljs": ">=0.19.0", - "request": "^2.81.0" + "request": "^2.81.0", + "xmldoc": "^1.1.2" }, "devDependencies": { "chai": "^4.2.0", diff --git a/test/corner.js b/test/corner.js index 000bfe9..e0951e4 100644 --- a/test/corner.js +++ b/test/corner.js @@ -1,7 +1,7 @@ var csdl = require('../index'); var assert = require('assert'); var ParserCommon = require('../lib/ParserCommon'); -var XML = require('libxmljs'); +var xmldoc = require('xmldoc'); describe('Corner Cases', function() { describe('Key Attribute', function() { @@ -32,23 +32,16 @@ describe('Corner Cases', function() { }); describe('ParserCommon', function() { it('No attribute or element case', function() { - let myobj = {}; - let init = ParserCommon.initEntity.bind(myobj); - init(null, 'Test'); - assert.ok('Passed'); - }); - it('No element callback case', function() { - ParserCommon.parseEntity(null, 'Test', undefined, undefined); + let myobj = new ParserCommon(); + myobj.init(null); assert.ok('Passed'); }); it('Attribute parent case', function() { let test = {}; - let myobj = {validAttributes: {'x': {'parent': test}}}; - let doc = new XML.Document(); - let node = doc.node('Test'); - let attr = node.attr('x', 'value'); - let init = ParserCommon.initEntity.bind(myobj); - init(node, 'Test'); + let myobj = new ParserCommon(); + myobj.validAttributes = {'x': {'parent': test}}; + let doc = new xmldoc.XmlDocument(''); + myobj.init(doc, 'Test'); assert.equal(test.x, 'value'); assert.equal(myobj.x, undefined); }); diff --git a/test/fixtures/Redfish/Message_v1.xml b/test/fixtures/Redfish/Message_v1.xml new file mode 100644 index 0000000..7d25e1d --- /dev/null +++ b/test/fixtures/Redfish/Message_v1.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/fixtures/Redfish/Org.OData.Measures.V1.xml b/test/fixtures/Redfish/Org.OData.Measures.V1.xml new file mode 100644 index 0000000..2a99636 --- /dev/null +++ b/test/fixtures/Redfish/Org.OData.Measures.V1.xml @@ -0,0 +1,88 @@ + + + + + + + + + + Terms describing monetary amounts and measured quantities + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/fixtures/Redfish/Settings_v1.xml b/test/fixtures/Redfish/Settings_v1.xml new file mode 100644 index 0000000..81d8ab2 --- /dev/null +++ b/test/fixtures/Redfish/Settings_v1.xml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/negative.js b/test/negative.js index 8a56a3b..71a4dbd 100644 --- a/test/negative.js +++ b/test/negative.js @@ -1,6 +1,6 @@ const ParserCommon = require('../lib/ParserCommon'); const Annotation = require('../lib/Annotation'); -const XML = require('libxmljs'); +const xmldoc = require('xmldoc'); const assert = require('chai').assert; const csdl = require('../index'); @@ -13,28 +13,22 @@ const noDataService = ''; describe('Negative', function(){ - it('Unbound Function', function() { - assert.throws(function(){ParserCommon.initEntity(null, 'test');}, Error, 'Function not bound before call!'); - }); it('Unknown Text', function(){ - let doc = XML.parseXml(simpleWithText); - let root = doc.root(); - assert.throws(function(){ParserCommon.parseEntity(root, 'test', null, null);}, Error, 'Unknown text element in test! Text = "Text"'); + let doc = new xmldoc.XmlDocument(simpleWithText); + let parser = new ParserCommon(); + assert.throws(function(){parser.parseEntity(doc, 'test');}, Error, 'Unknown text element in test! Text = "Text"'); }); it('Unknown Element', function(){ - let doc = XML.parseXml(invalidAnnotationElement); - let root = doc.root(); - assert.throws(function(){new Annotation(root);}, Error, 'Unknown element name BadElement'); + let doc = new xmldoc.XmlDocument(invalidAnnotationElement); + assert.throws(function(){new Annotation(doc);}, Error, 'Unknown element name BadElement'); }); it('Unknown Attribute', function(){ - let doc = XML.parseXml(invalidAnnotationAttribute); - let root = doc.root(); - assert.throws(function(){new Annotation(root);}, Error, 'Unknown attribute name BadAttr'); + let doc = new xmldoc.XmlDocument(invalidAnnotationAttribute); + assert.throws(function(){new Annotation(doc);}, Error, 'Unknown attribute name BadAttr'); }); it('Unknown Attribute Value', function(){ - let doc = XML.parseXml(invalidAnnotationBadBool); - let root = doc.root(); - assert.throws(function(){new Annotation(root);}, Error, 'Unknown value Bad for attribute named Bool'); + let doc = new xmldoc.XmlDocument(invalidAnnotationBadBool); + assert.throws(function(){new Annotation(doc);}, Error, 'Unknown value Bad for attribute named Bool'); }); it('Non CSDL', function(done) { csdl.parseMetadata(simpleWithText, {}, function(error, data){ diff --git a/test/uriParser.js b/test/uriParser.js index 519d48b..84750f9 100644 --- a/test/uriParser.js +++ b/test/uriParser.js @@ -3,13 +3,14 @@ var assert = require('assert'); describe('Uri Parsing', function() { it('Bad URI', function(done) { - csdl.parseMetadataUri('http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Core.V1.xml', {}, function(error, metadata) { + csdl.parseMetadataUri('http://example.com/404', {}, function(error, metadata) { assert.notEqual(error, null); assert.equal(metadata, null); done(); }); }); it('OData Core Parsing', function(done) { + this.timeout(10000); csdl.parseMetadataUri('http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Core.V1.xml', {}, function(error, metadata) { assert.equal(error, null); assert.equal(Object.keys(metadata).length, 3);