Skip to content

Commit

Permalink
Model <!--ignore--> as its own type and implement the ignoring via an…
Browse files Browse the repository at this point in the history
… assertion

Fixes <!--ignore--> as the top-level to satisfy RHS.
  • Loading branch information
papandreou committed Sep 30, 2018
1 parent 25bd2b4 commit fe9ce65
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 18 deletions.
47 changes: 30 additions & 17 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,17 @@ module.exports = {
}
});

// Recognize <!-- ignore --> as a special subtype of DOMComment so it can be targeted by assertions:
expect.exportType({
name: 'DOMIgnoreComment',
base: 'DOMComment',
identify: function(obj) {
return (
this.baseType.identify(obj) && /^\s*ignore\s*$/.test(obj.nodeValue)
);
}
});

expect.exportType({
name: 'DOMTextNode',
base: 'DOMNode',
Expand Down Expand Up @@ -719,6 +730,13 @@ module.exports = {
}
);

expect.exportAssertion(
'<DOMComment> to [exhaustively] satisfy <DOMComment>',
function(expect, subject, value) {
return expect(subject.nodeValue, 'to equal', value.nodeValue);
}
);

// Avoid rendering a huge object diff when a text node is matched against a different node type:
expect.exportAssertion(
'<DOMTextNode> to [exhaustively] satisfy <object>',
Expand All @@ -727,6 +745,13 @@ module.exports = {
}
);

// Always passes:
expect.exportAssertion(
// Name each subject type to increase the specificity of the assertion
'<DOMComment|DOMElement|DOMTextNode|DOMDocument|HTMLDocType> to [exhaustively] satisfy <DOMIgnoreComment>',
function(expect, subject, value) {}
);

// Necessary because this case would otherwise be handled by the above catch-all for <object>:
expect.exportAssertion(
'<DOMTextNode> to [exhaustively] satisfy <regexp>',
Expand All @@ -742,21 +767,8 @@ module.exports = {
}
);

function convertChildrenToSatisfySpec(children, isHtml) {
return children.map(function(child) {
if (expect.findTypeOf(child).is('DOMNode')) {
return convertDOMNodeToSatisfySpec(child, isHtml);
} else {
return child;
}
});
}

function convertDOMNodeToSatisfySpec(node, isHtml) {
if (node.nodeType === 8 && node.nodeValue.trim() === 'ignore') {
// Ignore subtree
return expect.it('to be an', 'DOMNode');
} else if (node.nodeType === 10) {
if (node.nodeType === 10) {
// HTMLDocType
return { name: node.nodeName };
} else if (node.nodeType === 1) {
Expand Down Expand Up @@ -788,6 +800,9 @@ module.exports = {
} else if (node.nodeType === 3) {
// DOMTextNode
return node.nodeValue;
} else if (node.nodeType === 8) {
// DOMComment
return node;
} else {
throw new Error(
'to satisfy: Node type ' +
Expand Down Expand Up @@ -1001,9 +1016,7 @@ module.exports = {
subject.ownerDocument.contentType
),
'to satisfy',
Array.isArray(value.children)
? convertChildrenToSatisfySpec(value.children, isHtml)
: value.children
value.children
);
});
} else if (typeof value.textContent !== 'undefined') {
Expand Down
42 changes: 41 additions & 1 deletion test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ function parseHtml(str) {
.window.document.body.firstChild;
}

function parseHtmlDocument(str) {
return new jsdom.JSDOM(str).window.document;
}

function parseHtmlFragment(str) {
str = '<html><head></head><body>' + str + '</body></html>';
var htmlDocument = new jsdom.JSDOM(str).window.document;
Expand All @@ -76,6 +80,10 @@ function parseHtmlFragment(str) {
return documentFragment;
}

function parseHtmlNode(str) {
return parseHtmlFragment(str).childNodes[0];
}

function parseXml(str) {
if (typeof DOMParser !== 'undefined') {
// eslint-disable-next-line no-undef
Expand Down Expand Up @@ -1468,7 +1476,7 @@ describe('unexpected-dom', function() {
);
});

describe('and it contain an ignore comment', function() {
describe('and it contains an ignore comment', function() {
it('ignores the corresponding subtree', () => {
expect(
[
Expand Down Expand Up @@ -2078,6 +2086,38 @@ describe('unexpected-dom', function() {
});
});

describe('when matching against <!-- ignore -->', function() {
var ignoreComment = parseHtmlNode('<!--ignore-->');

it('should match a text node', function() {
expect(parseHtmlNode('foo'), 'to satisfy', ignoreComment);
});

it('should match an element', function() {
expect(parseHtmlNode('<div>foo</div>'), 'to satisfy', ignoreComment);
});

it('should match a comment', function() {
expect(parseHtmlNode('<!-- foo -->'), 'to satisfy', ignoreComment);
});

it('should match a doctype', function() {
expect(
parseHtmlDocument('<!DOCTYPE html>').firstChild,
'to satisfy',
ignoreComment
);
});

it('should match a document', function() {
expect(
'<?xml version="1.0"?><fooBar>abc<source></source></fooBar>',
'when parsed as xml to satisfy',
ignoreComment
);
});
});

it('should fail with a diff', function() {
body.innerHTML =
'<div foo="bar" id="quux">foobar</div><div foo="quux">hey</div>';
Expand Down

0 comments on commit fe9ce65

Please sign in to comment.