Skip to content

Commit

Permalink
Merge pull request #33 from papandreou/fix/nodeNameCaseSensitivity
Browse files Browse the repository at this point in the history
Fixed detection of HTML/XML in Safari and IE.
  • Loading branch information
Munter committed Oct 2, 2015
2 parents 73f9332 + 5a0a733 commit 9d9ae8c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 6 deletions.
27 changes: 21 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,17 @@ function getClassNamesFromAttributeValue(attributeValue) {
return classNames;
}

function isInsideHtmlDocument(node) {
var ownerDocument = node.ownerDocument;
if (ownerDocument.contentType) {
return ownerDocument.contentType === 'text/html';
} else {
return ownerDocument.toString() === '[object HTMLDocument]';
}
}

function getAttributes(element) {
var isHtml = element.ownerDocument.contentType === 'text/html';
var isHtml = isInsideHtmlDocument(element);
var attrs = element.attributes;
var result = {};

Expand Down Expand Up @@ -175,7 +184,7 @@ function stringifyStartTag(element) {
}

function stringifyEndTag(element) {
var isHtml = element.ownerDocument.contentType === 'text/html';
var isHtml = isInsideHtmlDocument(element);
var elementName = isHtml ? element.nodeName.toLowerCase() : element.nodeName;
if (isHtml && isVoidElement(elementName) && element.childNodes.length === 0) {
return '';
Expand Down Expand Up @@ -399,7 +408,13 @@ module.exports = {
return obj && typeof obj.nodeType === 'number' && obj.nodeType === 1 && obj.nodeName && obj.attributes;
},
equal: function (a, b, equal) {
return a.nodeName.toLowerCase() === b.nodeName.toLowerCase() && equal(getAttributes(a), getAttributes(b)) && equal(a.childNodes, b.childNodes);
var aIsHtml = isInsideHtmlDocument(a);
var bIsHtml = isInsideHtmlDocument(b);
return (
aIsHtml === bIsHtml &&
(aIsHtml ? a.nodeName.toLowerCase() === b.nodeName.toLowerCase() : a.nodeName === b.nodeName) &&
equal(getAttributes(a), getAttributes(b)) && equal(a.childNodes, b.childNodes)
);
},
inspect: function (element, depth, output, inspect) {
var elementName = element.nodeName.toLowerCase();
Expand Down Expand Up @@ -453,7 +468,7 @@ module.exports = {
},
diffLimit: 512,
diff: function (actual, expected, output, diff, inspect, equal) {
var isHtml = actual.ownerDocument.contentType === 'text/html';
var isHtml = isInsideHtmlDocument(actual);
var result = {
diff: output,
inline: true
Expand Down Expand Up @@ -572,7 +587,7 @@ module.exports = {
}

expect.addAssertion('DOMDocumentFragment', 'to [exhaustively] satisfy', function (expect, subject, value) {
var isHtml = subject.ownerDocument.contentType === 'text/html';
var isHtml = isInsideHtmlDocument(subject);
var valueType = expect.findTypeOf(value);
if (valueType.name === 'string') {
var originalValue = value;
Expand All @@ -592,7 +607,7 @@ module.exports = {
});

expect.addAssertion('DOMElement', 'to [exhaustively] satisfy', function (expect, subject, value) {
var isHtml = subject.ownerDocument.contentType === 'text/html';
var isHtml = isInsideHtmlDocument(subject);
if (typeof value === 'string') {
var documentFragment = isHtml ? parseHtml(value, true, this.testDescription) : parseXml(value, this.testDescription);
if (documentFragment.childNodes.length !== 1) {
Expand Down
51 changes: 51 additions & 0 deletions test/unexpected-dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ function parseHtmlFragment(str) {
return documentFragment;
}

function parseXml(str) {
if (typeof DOMParser !== 'undefined') {
return new DOMParser().parseFromString(str, 'text/xml');
} else {
return require('jsdom').jsdom(str, { parsingMode: 'xml' });
}
}

describe('unexpected-dom', function () {
expect.output.preferredWidth = 100;

Expand Down Expand Up @@ -1675,4 +1683,47 @@ describe('unexpected-dom', function () {
'</ul>'
);
});

it('should compare XML element names case sensitively', function () {
expect(function () {
expect(parseXml('<foO></foO>').firstChild, 'to satisfy', {
name: 'foo'
});
}, 'to throw',
'expected <foO></foO> to satisfy { name: \'foo\' }\n' +
'\n' +
'<foO // should equal \'foo\'\n' +
'></foO>'
);
});

it('should compare XML element names case sensitively, even when the owner document lacks a contentType attribute', function () {
expect(function () {
var document = parseXml('<foO></foO>');
document.firstChild._ownerDocument = { toString: function () { return '[object XMLDocument]'; } };
expect(document.firstChild, 'to satisfy', {
name: 'foo'
});
}, 'to throw',
'expected <foO></foO> to satisfy { name: \'foo\' }\n' +
'\n' +
'<foO // should equal \'foo\'\n' +
'></foO>'
);
});

it('should compare XML element names case sensitively, even when the owner document lacks a contentType attribute', function () {
expect(function () {
var document = parseXml('<foO></foO>');
document.firstChild._ownerDocument = { toString: function () { return '[object XMLDocument]'; } };
expect(document.firstChild, 'to satisfy', {
name: 'foo'
});
}, 'to throw',
'expected <foO></foO> to satisfy { name: \'foo\' }\n' +
'\n' +
'<foO // should equal \'foo\'\n' +
'></foO>'
);
});
});

0 comments on commit 9d9ae8c

Please sign in to comment.