node1-libxmljsmt-myh
Version:
multi-threaded libxml bindings for v8 javascript engine
418 lines (349 loc) • 13.3 kB
JavaScript
var libxml = require('../index');
module.exports.getDtd = function(assert) {
var doc = libxml.parseXmlString('<root></root>');
var dtd = doc.getDtd();
assert.equal(null, dtd);
doc = libxml.parseXmlString(' \n \n<root></root>');
assert.ok(doc);
dtd = doc.getDtd();
assert.equal('html', dtd.name);
assert.equal(null, dtd.externalId);
assert.equal(null, dtd.systemId);
doc = libxml.parseXmlString(' \n \n<root></root>');
dtd = doc.getDtd();
assert.equal('html', dtd.name);
assert.equal(null, dtd.externalId);
assert.equal('http://www.w3.org/TR/html4/strict.dtd', dtd.systemId);
doc = libxml.parseXmlString(' \n \n<root></root>');
dtd = doc.getDtd();
assert.equal('html', dtd.name);
assert.equal('-//W3C//DTD HTML 4.01//EN', dtd.externalId);
assert.equal('http://www.w3.org/TR/html4/strict.dtd', dtd.systemId);
assert.done();
};
module.exports.setDtd = function(assert) {
var doc = libxml.Document();
doc.setDtd("html");
assert.ok(doc);
assert.equal(' \n \n', doc.toString());
doc.setDtd("html", "bacon", "bacon");
assert.ok(doc);
assert.equal(' \n \n', doc.toString());
doc.setDtd("html", null);
assert.ok(doc);
assert.equal(' \n \n', doc.toString());
assert.throws(function() {
doc.setDtd(5);
});
assert.ok(doc);
assert.equal(' \n \n', doc.toString());
assert.throws(function() {
doc.setDtd();
});
assert.ok(doc);
assert.equal(' \n \n', doc.toString());
assert.done();
};
module.exports.blank = function(assert) {
var doc = libxml.Document();
assert.ok(doc);
assert.equal('1.0', doc.version());
assert.equal('utf8', doc.encoding());
assert.done();
};
module.exports.version = function(assert) {
var doc = libxml.Document('2.0');
assert.ok(doc);
assert.equal('2.0', doc.version());
assert.equal('utf8', doc.encoding());
assert.done();
};
module.exports.type = function(assert) {
var doc = libxml.Document('2.0');
assert.equal('document', doc.type());
assert.done();
};
module.exports.full = function(assert) {
var doc = libxml.Document('2.0', 'UTF-8');
assert.ok(doc);
assert.equal('2.0', doc.version());
assert.equal('UTF-8', doc.encoding());
assert.done();
};
module.exports.null_root = function(assert) {
var doc = libxml.Document();
assert.equal(null, doc.root());
assert.done();
};
module.exports.new_root = function(assert) {
var doc = libxml.Document();
var root = doc.node('root');
assert.equal('root', root.name());
assert.equal(root, doc.root());
root.node('child').parent().node('child');
assert.equal(doc.root().name(), doc.get('/root').name());
assert.done();
};
module.exports.one_child = function(assert) {
var doc = libxml.Document();
var root = doc.node('root').node('child-one').parent().node('child-two');
assert.equal('child-one', doc.child(0).name());
assert.equal('child-two', doc.child(1).name());
assert.done();
};
module.exports.root_children = function(assert) {
var doc = libxml.Document();
doc.node('root').node('child-one').parent().node('child-two');
assert.equal('child-one', doc.childNodes()[0].name());
assert.equal('child-two', doc.childNodes()[1].name());
assert.done();
};
module.exports.xpath = function(assert) {
var doc = libxml.Document();
doc.node('root').node('child').parent().node('child');
assert.equal(2, doc.find('child').length);
assert.done();
};
module.exports.xpath_child = function(assert) {
var doc = libxml.Document();
doc.node('root').node('child-one').parent().node('child-two');
assert.equal('child-one', doc.get('child-one').name());
assert.equal('child-two', doc.get('child-two').name());
assert.done();
};
module.exports.toString = function(assert) {
var control = [
' ',
'<root>',
' <child to="wongfoo">',
' <grandchild from="julie numar">with love</grandchild>',
' </child>',
' <sibling>with content!</sibling>',
'</root>',
''
].join("\n");
var doc = libxml.Document();
var root = doc.node('root');
root.node('child').attr({to: 'wongfoo'})
.node('grandchild', 'with love').attr({from: 'julie numar'})
root.node('sibling', 'with content!');
assert.equal(control, doc.toString());
assert.done();
};
module.exports.add_child_nodes = function(assert) {
var gchild = '';
var doc1_string = [
' ',
'<root><child to="wongfoo"><grandchild from="julie numar">with love</grandchild></child><sibling>with content!</sibling></root>',
].join("\n");
var doc2_string = [
' ',
'<root><child to="wongfoo"></child><sibling>with content!</sibling></root>',
].join("\n");
var doc1 = libxml.parseXml(doc1_string);
var doc2 = libxml.parseXml(doc2_string);
doc2.child(0).addChild(doc1.child(0).child(0));
assert.equal(doc1.toString(), doc2.toString());
assert.done();
};
module.exports.add_cdata_nodes = function(assert) {
var gchild = '';
var doc1_string = [
' ',
'<root><child to="wongfoo"/></root>',
].join("\n");
var expected_string = [
' ',
'<root>',
' <child to="wongfoo"><![CDATA[<p>Bacon</p>]]></child>',
'</root>',
'' /* Why?!? */
].join("\n");
var doc1 = libxml.parseXml(doc1_string);
doc1.child(0).cdata('<p>Bacon</p>');
assert.equal(doc1.toString(), expected_string);
assert.done();
};
module.exports.cloned_node = function(assert) {
var gchild_string = '<grandchild from="julie numar">with love</grandchild>';
var doc1_string = [
' ',
'<root><child to="wongfoo">'+gchild_string+'</child><sibling>with content!</sibling></root>',
''
].join("\n");
var doc2_string = [
' ',
'<root><child to="wongfoo"/><sibling>with content!</sibling></root>',
''
].join("\n");
var doc1 = libxml.parseXml(doc1_string);
var doc2 = libxml.parseXml(doc2_string);
var gchild = doc1.child(0).child(0); //the element to operate on
doc2.child(0).addChild(gchild); // add gchild clone to doc2, implicit clone
assert.equal(doc1.toString(), doc2.toString()); // both documents should be the same
assert. notEqual(gchild, doc2.child(0).child(0)); // these nodes should be different (cloned)
gchild.remove();
assert.equal(doc2_string, doc1.toString(false)); //doc1 should be the same as doc2 str (raw output)
assert.equal(doc1_string, doc2.toString(false)); //doc2 should be the same as doc1 str (raw output)
assert.done();
};
module.exports.validate = function(assert) {
var xsd = '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="comment" type="xs:string"/></xs:schema>';
var xml_valid = '<comment>A comment</comment>';
var xml_invalid = '<commentt>A comment</commentt>';
var xsdDoc = libxml.parseXml(xsd);
var xmlDocValid = libxml.parseXml(xml_valid);
var xmlDocInvalid = libxml.parseXml(xml_invalid);
assert.equal(xmlDocValid.validate(xsdDoc), true);
assert.equal(xmlDocValid.validationErrors.length, 0);
assert.equal(xmlDocInvalid.validate(xsdDoc), false);
assert.equal(xmlDocInvalid.validationErrors.length, 1);
assert.done();
};
module.exports.rngValidate = function(assert) {
// see http://relaxng.org/ for more infos about RELAX NG
var rng =
'<element name="addressBook" xmlns="http://relaxng.org/ns/structure/1.0">'+
'<zeroOrMore>'+
'<element name="card">'+
'<element name="name">'+
'<text/>'+
'</element>'+
'<element name="email">'+
'<text/>'+
'</element>'+
'</element>'+
'</zeroOrMore>'+
'</element>';
var xml_valid =
'<addressBook>'+
'<card>'+
'<name>John Smith</name>'+
'<email>js@example.com</email>'+
'</card>'+
'<card>'+
'<name>Fred Bloggs</name>'+
'<email>fb@example.net</email>'+
'</card>'+
'</addressBook>';
var xml_invalid =
'<addressBook>'+
'<card>'+
'<Name>John Smith</Name>'+
'<email>js@example.com</email>'+
'</card>'+
'<card>'+
'<name>Fred Bloggs</name>'+
'<email>fb@example.net</email>'+
'</card>'+
'</addressBook>';
var rngDoc = libxml.parseXml(rng);
var xmlDocValid = libxml.parseXml(xml_valid);
var xmlDocInvalid = libxml.parseXml(xml_invalid);
assert.equal(xmlDocValid.rngValidate(rngDoc), true);
assert.equal(xmlDocValid.validationErrors.length, 0);
assert.equal(xmlDocInvalid.rngValidate(rngDoc), false);
assert.equal(xmlDocInvalid.validationErrors.length, 1);
assert.done();
};
module.exports.errors = {
empty_html_doc: function(assert) {
function assertDocRootError(func, msg) {
assert.throws(func, /Document has no root element/, msg);
}
var xml_only_comments = '<!-- empty -->';
var doc = libxml.parseHtmlString(xml_only_comments);
assert.equal(null, doc.root());
assertDocRootError(function() {
doc.get('*');
}, 'get method throws correct error on empty doc');
assertDocRootError(function() {
doc.find('*');
}, 'find method throws correct error on empty doc');
assertDocRootError(function() {
doc.child(1);
}, 'child method throws correct error on empty doc');
assertDocRootError(function() {
doc.childNodes();
}, 'childNodes method throws correct error on empty doc');
assertDocRootError(function() {
doc.namespaces();
}, 'namespaces method throws correct error on empty doc');
assert.done();
}
};
module.exports.validate_memory_usage = function(assert) {
var xsd = '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="comment" type="xs:string"/></xs:schema>';
var xml = '<comment>A comment</comment>';
var xsdDoc = libxml.parseXml(xsd);
var xmlDoc = libxml.parseXml(xml);
var rssBefore = rssAfterGarbageCollection();
for (var i = 0; i < 10000; ++i) {
xmlDoc.validate(xsdDoc);
}
assert.ok((rssAfterGarbageCollection() - rssBefore) < VALIDATE_RSS_TOLERANCE);
assert.done();
};
module.exports.fromHtml = function(assert) {
var html = "<p>A paragraph with <span>inline tags</span></p>";
var header = ' \n<html><body>';
var footer = "</body></html>\n";
var parsedHtml = libxml.Document.fromHtml(html);
assert.equal(header + html + footer, parsedHtml.toString());
assert.done();
};
module.exports.fromHtmlFragment = function(assert) {
var html = "<p>A paragraph with <span>inline tags</span></p>";
var parsedHtml = libxml.Document.fromHtmlFragment(html);
assert.equal(html + "\n", parsedHtml.toString());
assert.done();
};
module.exports.validate_rng_memory_usage = function(assert) {
var rng =
'<element name="addressBook" xmlns="http://relaxng.org/ns/structure/1.0">'+
'<zeroOrMore>'+
'<element name="card">'+
'<element name="name">'+
'<text/>'+
'</element>'+
'<element name="email">'+
'<text/>'+
'</element>'+
'</element>'+
'</zeroOrMore>'+
'</element>';
var xml_valid =
'<addressBook>'+
'<card>'+
'<name>John Smith</name>'+
'<email>js@example.com</email>'+
'</card>'+
'<card>'+
'<name>Fred Bloggs</name>'+
'<email>fb@example.net</email>'+
'</card>'+
'</addressBook>';
var rngDoc = libxml.parseXml(rng);
var xmlDoc = libxml.parseXml(xml_valid);
var rssBefore = rssAfterGarbageCollection();
for (var i = 0; i < 10000; ++i) {
xmlDoc.rngValidate(rngDoc);
}
assert.ok((rssAfterGarbageCollection() - rssBefore) < VALIDATE_RSS_TOLERANCE);
assert.done();
};
var VALIDATE_RSS_TOLERANCE = 1;
function rssAfterGarbageCollection(maxCycles) {
maxCycles || (maxCycles = 10);
var rss = libxml.memoryUsage();
var freedMemory = 0;
do {
global.gc();
var rssAfterGc = libxml.memoryUsage();
freedMemory = rss - rssAfterGc;
rss = rssAfterGc;
maxCycles--;
}
while ((freedMemory !== 0) && (maxCycles > 0));
return rss;
}
\n