Skip to content

Commit

Permalink
Merge 3e757e1 into 1869b96
Browse files Browse the repository at this point in the history
  • Loading branch information
papandreou committed Oct 26, 2019
2 parents 1869b96 + 3e757e1 commit 54dd36a
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 22 deletions.
2 changes: 1 addition & 1 deletion documentation/assertions/DOMElement/to-contain.md
Expand Up @@ -74,7 +74,7 @@ to contain <h1 class="heading">Assert on all content</h1>
class="title" // expected [ 'title' ] to contain 'heading'
data-test-id="title"
>
Assert on text content // should equal 'Assert on all content'
Assert on text content // should equal Assert on all content
//
// -Assert on text content
// +Assert on all content
Expand Down
2 changes: 1 addition & 1 deletion documentation/assertions/DOMElement/to-satisfy.md
Expand Up @@ -93,7 +93,7 @@ queried for first [data-test-id=title] to satisfy '<h1>Assert on all content</h1
to satisfy <h1>Assert on all content</h1>
<h1 class="title" data-test-id="title">
Assert on text content // should equal 'Assert on all content'
Assert on text content // should equal Assert on all content
//
// -Assert on text content
// +Assert on all content
Expand Down
57 changes: 48 additions & 9 deletions src/index.js
Expand Up @@ -808,9 +808,7 @@ module.exports = {
: node.attributes[i].value || '';
}
}
result.children = Array.prototype.map.call(node.childNodes, childNode =>
convertDOMNodeToSatisfySpec(childNode, isHtml)
);
result.children = Array.prototype.slice.call(node.childNodes);
return result;
} else if (node.nodeType === 3) {
// DOMTextNode
Expand Down Expand Up @@ -1519,7 +1517,23 @@ module.exports = {
}
);

function scoreElementAgainstSpec(element, spec) {
function memoize(fn) {
const map = new Map();
return node => {
let spec = map.get(node);
if (typeof spec === 'undefined') {
spec = fn(node);
map.set(node, spec);
}
return spec;
};
}

function scoreElementAgainstSpec(
element,
spec,
memoizedConvertDOMNodeToSatisfySpec
) {
const isTextSimilar = (value, valueSpec) => {
const actual = (value || '').trim().toLowerCase();
if (typeof valueSpec === 'string') {
Expand Down Expand Up @@ -1625,6 +1639,9 @@ module.exports = {
expectedChildren.forEach((childSpec, i) => {
const child = element.childNodes[i];
const childType = expect.findTypeOf(child);
if (expect.findTypeOf(childSpec).is('DOMNode')) {
childSpec = memoizedConvertDOMNodeToSatisfySpec(childSpec);
}

if (!child) {
return;
Expand All @@ -1636,7 +1653,8 @@ module.exports = {
// Element
score += scoreElementAgainstSpec(
element.childNodes[i],
convertDOMNodeToSatisfySpec(childSpec)
memoizedConvertDOMNodeToSatisfySpec(childSpec),
memoizedConvertDOMNodeToSatisfySpec
);
}

Expand All @@ -1648,7 +1666,11 @@ module.exports = {
childType.is('DOMElement') &&
typeof childSpec === 'object'
) {
score += scoreElementAgainstSpec(element.childNodes[i], childSpec);
score += scoreElementAgainstSpec(
element.childNodes[i],
childSpec,
memoizedConvertDOMNodeToSatisfySpec
);
} else if (
childType.is('DOMTextNode') &&
isTextSimilar(child.nodeValue, childSpec)
Expand All @@ -1660,7 +1682,14 @@ module.exports = {
return score;
}

function findMatchesWithGoodScore(data, spec) {
function findMatchesWithGoodScore(
data,
spec,
memoizedConvertDOMNodeToSatisfySpec
) {
memoizedConvertDOMNodeToSatisfySpec =
memoizedConvertDOMNodeToSatisfySpec ||
memoize(convertDOMNodeToSatisfySpec);
const elements =
typeof data.length === 'number'
? Array.prototype.slice.call(data)
Expand All @@ -1670,7 +1699,11 @@ module.exports = {
let bestScore = 0;

elements.forEach(element => {
const score = scoreElementAgainstSpec(element, spec);
const score = scoreElementAgainstSpec(
element,
spec,
memoizedConvertDOMNodeToSatisfySpec
);
bestScore = Math.max(score, bestScore);

if (score > 0 && score >= bestScore) {
Expand All @@ -1680,7 +1713,13 @@ module.exports = {
for (var i = 0; i < element.childNodes.length; i += 1) {
const child = element.childNodes[i];
if (child.nodeType === 1) {
result.push(...findMatchesWithGoodScore(child, spec));
result.push(
...findMatchesWithGoodScore(
child,
spec,
memoizedConvertDOMNodeToSatisfySpec
)
);
}
}
});
Expand Down
42 changes: 31 additions & 11 deletions test/index.spec.js
Expand Up @@ -1720,7 +1720,7 @@ describe('unexpected-dom', () => {
NodeList[
<div>
foo // should equal 'quux'
foo // should equal quux
//
// -foo
// +quux
Expand Down Expand Up @@ -1790,7 +1790,7 @@ describe('unexpected-dom', () => {
NodeList[
<div>
foo // should equal 'quux'
foo // should equal quux
//
// -foo
// +quux
Expand Down Expand Up @@ -1856,7 +1856,7 @@ describe('unexpected-dom', () => {
NodeList[
<div foo="bar">
foo // should equal 'foo!'
foo // should equal foo!
//
// -foo
// +foo!
Expand Down Expand Up @@ -2107,7 +2107,7 @@ describe('unexpected-dom', () => {
expected <div foo="bar" baz="quux">foobar</div> to satisfy <div foo="bar" baz="quux">hey</div>
<div foo="bar" baz="quux">
foobar // should equal 'hey'
foobar // should equal hey
//
// -foobar
// +hey
Expand Down Expand Up @@ -2222,7 +2222,7 @@ describe('unexpected-dom', () => {
<div
style="border-left-color: #FFF" // expected <div style="border-left-color: #FFF">hey</div>
// to satisfy { name: 'div', attributes: { style: 'border-left-color: #FFFF;' }, children: [ 'hey' ] }
// to satisfy { name: 'div', attributes: { style: 'border-left-color: #FFFF;' }, children: [ hey ] }
// Expectation contains invalid styles: 'border-left-color: #FFFF'
>hey</div>
`
Expand All @@ -2243,7 +2243,7 @@ describe('unexpected-dom', () => {
<div
style="width: 120px" // expected <div style="width: 120px">hey</div>
// to satisfy { name: 'div', attributes: { style: 'color;background;width: 120px' }, children: [ 'hey' ] }
// to satisfy { name: 'div', attributes: { style: 'color;background;width: 120px' }, children: [ hey ] }
// Expectation contains invalid styles: 'color;background'
>hey</div>
`
Expand Down Expand Up @@ -2493,6 +2493,26 @@ describe('unexpected-dom', () => {
`
);
});

// Regression test for https://github.com/unexpectedjs/unexpected-dom/issues/294
it('should produce a nice diff when satisfying a test node against an element with children', () => {
expect(
() =>
expect(
parseHtmlNode('<div>foo</div>'),
'to satisfy',
'<div><div><div>bar</div></div></div>'
),
'to throw an error satisfying to equal snapshot',
expect.unindent`
expected <div>foo</div> to satisfy <div><div><div>bar</div></div></div>
<div>
foo // should satisfy <div><div>bar</div></div>
</div>
`
);
});
});

describe('queried for', () => {
Expand Down Expand Up @@ -3578,7 +3598,7 @@ describe('unexpected-dom', () => {
to contain <span><span>Hello</span><!--ignore--></span>
<span>
// missing { name: 'span', attributes: {}, children: [ 'Hello' ] }
// missing <span>Hello</span>
Hello
</span>
`
Expand Down Expand Up @@ -3626,7 +3646,7 @@ describe('unexpected-dom', () => {
to contain <span class="name">John Doe</span>
<span class="name something-else">
Jane Doe // should equal 'John Doe'
Jane Doe // should equal John Doe
//
// -Jane Doe
// +John Doe
Expand Down Expand Up @@ -3722,7 +3742,7 @@ describe('unexpected-dom', () => {
to contain <span data-test-id="name">John Doe</span>
<span class="name something-else" data-test-id="name">
Jane Doe // should equal 'John Doe'
Jane Doe // should equal John Doe
//
// -Jane Doe
// +John Doe
Expand All @@ -3745,7 +3765,7 @@ describe('unexpected-dom', () => {
expected <div><span></span></div> to contain <span><i>Hello</i></span>
<span>
// missing { name: 'i', attributes: {}, children: [ 'Hello' ] }
// missing <i>Hello</i>
</span>
`
);
Expand Down Expand Up @@ -3790,7 +3810,7 @@ describe('unexpected-dom', () => {
<span>
<strong>Hello</strong>
<em>world</em>
// missing '!'
// missing !
</span>
`
);
Expand Down

0 comments on commit 54dd36a

Please sign in to comment.