unexpected-htmllike
Advanced tools
Comparing version 2.0.2 to 2.1.0
@@ -58,1 +58,5 @@ | ||
* Fix outputting inspected attributes (e.g objects). Could previously result in incorrect indenting. | ||
### v2.1.0 | ||
* Add `findTargetAttrib` to the options to allow locating a nested element (see the [readme](https://github.com/bruderstein/unexpected-htmllike#findtargetattrib-string)!) | ||
@@ -50,3 +50,4 @@ 'use strict'; | ||
diff: diffResult.diff, | ||
weight: diffResult.weight.real | ||
weight: diffResult.weight.real, | ||
target: diffResult.target | ||
}; | ||
@@ -150,5 +151,9 @@ }); | ||
var target = undefined; | ||
var attributesResultPromise = diffAttributes(actualAdapter.getAttributes(actual), expectedAdapter.getAttributes(expected), expect, options).then(function (attribResult) { | ||
diffResult.attributes = attribResult.diff; | ||
weights.addWeight(attribResult.weight); | ||
if (attribResult.isTarget) { | ||
target = actual; | ||
} | ||
}); | ||
@@ -162,2 +167,5 @@ | ||
weights.addWeight(contentResult.weight); | ||
if (contentResult.target) { | ||
target = contentResult.target; | ||
} | ||
}); | ||
@@ -171,3 +179,4 @@ | ||
diff: diffResult, | ||
weight: weights | ||
weight: weights, | ||
target: target | ||
}; | ||
@@ -190,2 +199,3 @@ }); | ||
var bestDiff = null; | ||
var bestTarget = undefined; | ||
@@ -208,2 +218,3 @@ // Optimize the common case of being exactly one child, ie. an element wrapping something | ||
bestWeight = childrenResult.weight; | ||
bestTarget = childrenResult.target; | ||
} | ||
@@ -246,3 +257,4 @@ }).then(function () { | ||
diff: bestDiff, | ||
weight: bestWeight | ||
weight: bestWeight, | ||
target: bestTarget | ||
}; | ||
@@ -346,5 +358,14 @@ }); | ||
var target = undefined; | ||
changes.forEach(function (diffItem) { | ||
var itemResult = undefined; | ||
var testCached = undefined; | ||
if (typeof diffItem.actualIndex === 'number' && (typeof diffItem.expectedIndex === 'number' || diffItem.type === 'equal')) { | ||
var cacheIndex = diffItem.actualIndex * expectedChildrenLength + diffItem.expectedIndex; | ||
var cachedDiff = cachedDiffs[cacheIndex]; | ||
if (cachedDiff && cachedDiff.target) { | ||
target = cachedDiff.target; | ||
} | ||
} | ||
@@ -410,8 +431,8 @@ switch (diffItem.type) { | ||
return expect.promise.all(promises).then(function () { | ||
resolve(); | ||
resolve(target); | ||
}); | ||
} | ||
return resolve(); | ||
return resolve(target); | ||
}); | ||
}).then(function () { | ||
}).then(function (target) { | ||
@@ -427,3 +448,4 @@ if (actualChildren.length === 0 && expectedChildren.length !== 0 && options.diffMissingChildren) { | ||
removeCount: removeCount, | ||
changeCount: changeCount | ||
changeCount: changeCount, | ||
target: target | ||
}; | ||
@@ -430,0 +452,0 @@ }); |
@@ -78,3 +78,4 @@ 'use strict'; | ||
diff: (0, _convertToDiff2['default'])(actualAdapter, actual, { includeChildren: false }), | ||
weight: wrapperResult.weight.addTotal(options.weights.WRAPPER_REMOVED) | ||
weight: wrapperResult.weight.addTotal(options.weights.WRAPPER_REMOVED), | ||
target: wrapperResult.target | ||
}; | ||
@@ -272,17 +273,26 @@ if (options.diffWrappers) { | ||
var isTarget = false; | ||
Object.keys(expectedAttributes).forEach(function (attrib) { | ||
if (!actualAttributes.hasOwnProperty(attrib)) { | ||
if (options.diffRemovedAttributes) { | ||
diffWeights.addReal(options.weights.ATTRIBUTE_MISSING); | ||
var attribResult = { | ||
name: attrib, | ||
diff: { | ||
type: 'missing', | ||
expectedValue: expectedAttributes[attrib] | ||
} | ||
}; | ||
diffResult.push(attribResult); | ||
if (attrib === options.findTargetAttrib) { | ||
// If it's the findTargetAttrib attribute, but it's not true, we still want to ignore the attribute | ||
// This will allow dynamic testing: e.g. <SomeChild eventTarget={index === 3 ? true : false} /> | ||
if (expectedAttributes[attrib] === true) { | ||
isTarget = true; | ||
} | ||
} else { | ||
if (options.diffRemovedAttributes) { | ||
diffWeights.addReal(options.weights.ATTRIBUTE_MISSING); | ||
var attribResult = { | ||
name: attrib, | ||
diff: { | ||
type: 'missing', | ||
expectedValue: expectedAttributes[attrib] | ||
} | ||
}; | ||
diffResult.push(attribResult); | ||
} | ||
diffWeights.addTotal(options.weights.ATTRIBUTE_MISSING); | ||
} | ||
diffWeights.addTotal(options.weights.ATTRIBUTE_MISSING); | ||
} | ||
@@ -295,3 +305,4 @@ }); | ||
diff: diffResult, | ||
weight: diffWeights | ||
weight: diffWeights, | ||
isTarget: isTarget | ||
}; | ||
@@ -303,3 +314,4 @@ }); | ||
diff: diffResult, | ||
weight: diffWeights | ||
weight: diffWeights, | ||
isTarget: isTarget | ||
}; | ||
@@ -306,0 +318,0 @@ }; |
@@ -27,6 +27,2 @@ 'use strict'; | ||
var _lineBreaker = require('./lineBreaker'); | ||
var _lineBreaker2 = _interopRequireDefault(_lineBreaker); | ||
var _Weights = require('./Weights'); | ||
@@ -55,3 +51,4 @@ | ||
diff: diffResult.diff, | ||
weight: diffResult.weight.real | ||
weight: diffResult.weight.real, | ||
target: diffResult.target | ||
}; | ||
@@ -157,2 +154,7 @@ } | ||
var target = undefined; | ||
if (attributesResult.isTarget) { | ||
target = actual; | ||
} | ||
diffResult.attributes = attributesResult.diff; | ||
@@ -165,6 +167,8 @@ weights.addWeight(attributesResult.weight); | ||
weights.addWeight(contentResult.weight); | ||
target = target || contentResult.target; | ||
return { | ||
diff: diffResult, | ||
weight: weights | ||
weight: weights, | ||
target: target | ||
}; | ||
@@ -177,2 +181,3 @@ } | ||
var bestDiff = null; | ||
var bestTarget = undefined; | ||
@@ -195,2 +200,3 @@ // Optimize the common case of being exactly one child, ie. an element wrapping something | ||
bestWeight = childrenResult.weight; | ||
bestTarget = childrenResult.target; | ||
} | ||
@@ -229,3 +235,4 @@ | ||
diff: bestDiff, | ||
weight: bestWeight | ||
weight: bestWeight, | ||
target: bestTarget | ||
}; | ||
@@ -310,5 +317,14 @@ } | ||
var target = undefined; | ||
changes.forEach(function (diffItem) { | ||
var itemResult = undefined; | ||
var itemResult = undefined, | ||
cachedDiff = undefined; | ||
if (typeof diffItem.actualIndex === 'number' && typeof diffItem.expectedIndex === 'number') { | ||
var cacheIndex = diffItem.actualIndex * expectedChildrenLength + diffItem.expectedIndex; | ||
cachedDiff = cachedDiffs[cacheIndex]; | ||
if (cachedDiff && cachedDiff.target) { | ||
target = cachedDiff.target; | ||
} | ||
} | ||
@@ -354,10 +370,7 @@ switch (diffItem.type) { | ||
// fallthrough | ||
// (equal needs to be diffed, because it may contain wrappers, hence we need to work that out.. again) | ||
// It would be good to cache that, from the diff above. | ||
case 'equal': //eslint-disable-line no-fallthrough | ||
default: | ||
var result = diffElementOrWrapper(actualAdapter, expectedAdapter, diffItem.value, diffItem.expected, expect, options); | ||
diffResult.push(result.diff); | ||
diffWeights.addWeight(result.weight); | ||
diffResult.push(cachedDiff.diff); | ||
diffWeights.addWeight(cachedDiff.weight); | ||
break; | ||
@@ -374,2 +387,3 @@ } | ||
diff: diffResult, | ||
target: target, | ||
insertCount: insertCount, | ||
@@ -376,0 +390,0 @@ removeCount: removeCount, |
@@ -275,3 +275,35 @@ 'use strict'; | ||
}); | ||
describe('findTargetAttrib', function () { | ||
it('finds a target in a simple element', function () { | ||
var target = (0, _mockEntities.createActual)({ | ||
name: 'span', | ||
attribs: { id: '123' }, | ||
children: [] | ||
}); | ||
return expect((0, _mockEntities.createActual)({ | ||
name: 'div', attribs: {}, children: [{ | ||
name: 'span', | ||
attribs: { id: 'main' }, | ||
children: [target] | ||
}] | ||
}), 'when checked with options to contain', { findTargetAttrib: 'eventTarget', diffExtraAttributes: false }, (0, _mockEntities.createExpected)({ | ||
name: 'span', | ||
attribs: {}, | ||
children: [{ name: 'span', attribs: { eventTarget: true }, children: [] }] | ||
}), 'to satisfy', { | ||
found: true, | ||
bestMatch: { | ||
diff: { | ||
type: 'ELEMENT' | ||
}, | ||
weight: 0, | ||
target: target | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=contains.spec.js.map |
{ | ||
"name": "unexpected-htmllike", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "Helper library for unexpected plugins that perform assertions on XML like structures", | ||
@@ -31,3 +31,3 @@ "author": { | ||
"array-changes": "^1.2.1", | ||
"array-changes-async": "^2.1.0", | ||
"array-changes-async": "^2.2.0", | ||
"object-assign": "^4.0.1" | ||
@@ -34,0 +34,0 @@ }, |
@@ -177,2 +177,58 @@ # unexpected-htmllike | ||
### findTargetAttrib (string) | ||
This allows finding an actual child identified by an attribute on the expected. | ||
For instance, when `findTargetAttrib` is set to `'eventTarget'`, and presented with the following "actual" value (in some XML/HTML representation with an appropriate adapter) | ||
```xml | ||
<SomeComponent> | ||
<div className="wrapper"> | ||
<ChildComponent id="1">foo</ChildComponent> | ||
<ChildComponent id="2">bar</ChildComponent> | ||
<ChildComponent id="3">baz</ChildComponent> | ||
</div> | ||
</SomeComponent> | ||
``` | ||
The expected value is then (expressed in JSX syntax, the value of the attribute must be ` === true`): | ||
```xml | ||
<SomeComponent> | ||
<div className="wrapper"> | ||
<ChildComponent id="2" eventTarget={true} /> | ||
</div> | ||
</SomeComponent> | ||
``` | ||
In this case, (assuming `diffExtraElements` is false in the options) the resulting diff will contain a `target` property, which is the `<ChildComponent id="2">bar</ChildComponent>` element from the actual value (in whatever form that object takes). | ||
When set, the result of the diff contains a `target` property, which is the matching "actual" element that matched the "expected" element with the given attribute as true. | ||
It is anticipated to use this to identify a child component on which to trigger an event, or a child component to identify. | ||
e.g. (using unexpected-react as an example) | ||
```js | ||
// With `eventTarget` set as `findTargetAttrib` | ||
expect(todoList, 'with event click', 'on', <TodoItem id={2}><button className="completed" eventTarget /></TodoItem>, | ||
'to contain', <TodoItem id={2}><span>Completed!</span></TodoItem>); | ||
// With `queryTarget` set as `findTargetAttrib` | ||
expect(todoList, 'queried for', <TodoItem id={2}><span className="label" queryTarget /></TodoItem>, | ||
'to have rendered', <span>Label of item 2</span>); | ||
``` | ||
* For `diff()`, the target is a direct property of the result. | ||
* For `contains()`, the target is under the `bestMatch` property. i.e. | ||
```js | ||
var containsResult = htmlLikeInstance.contains(adapter, actual, expected, expect, options); | ||
if (containsResult.found) { | ||
const foundTarget = containsResult.bestMatch.target; | ||
// ... | ||
} | ||
``` | ||
### weights (object) | ||
@@ -179,0 +235,0 @@ This must be an object that represents the different weights for the various differences that can occur. |
@@ -22,3 +22,4 @@ import ArrayChangesAsync from 'array-changes-async'; | ||
diff: diffResult.diff, | ||
weight: diffResult.weight.real | ||
weight: diffResult.weight.real, | ||
target: diffResult.target | ||
}; | ||
@@ -125,2 +126,3 @@ }); | ||
let target; | ||
const attributesResultPromise = diffAttributes(actualAdapter.getAttributes(actual), expectedAdapter.getAttributes(expected), expect, options) | ||
@@ -130,2 +132,5 @@ .then(attribResult => { | ||
weights.addWeight(attribResult.weight); | ||
if (attribResult.isTarget) { | ||
target = actual; | ||
} | ||
}); | ||
@@ -141,2 +146,5 @@ | ||
weights.addWeight(contentResult.weight); | ||
if (contentResult.target) { | ||
target = contentResult.target; | ||
} | ||
}); | ||
@@ -151,3 +159,4 @@ | ||
diff: diffResult, | ||
weight: weights | ||
weight: weights, | ||
target | ||
}; | ||
@@ -175,2 +184,3 @@ }); | ||
let bestDiff = null; | ||
let bestTarget; | ||
@@ -193,2 +203,3 @@ // Optimize the common case of being exactly one child, ie. an element wrapping something | ||
bestWeight = childrenResult.weight; | ||
bestTarget = childrenResult.target; | ||
} | ||
@@ -235,3 +246,4 @@ }).then(() => { | ||
diff: bestDiff, | ||
weight: bestWeight | ||
weight: bestWeight, | ||
target: bestTarget | ||
}; | ||
@@ -338,5 +350,14 @@ }); | ||
let target; | ||
changes.forEach(diffItem => { | ||
let itemResult; | ||
let testCached; | ||
if (typeof diffItem.actualIndex === 'number' && (typeof diffItem.expectedIndex === 'number' || diffItem.type === 'equal')) { | ||
const cacheIndex = (diffItem.actualIndex * expectedChildrenLength) + diffItem.expectedIndex; | ||
const cachedDiff = cachedDiffs[cacheIndex]; | ||
if (cachedDiff && cachedDiff.target) { | ||
target = cachedDiff.target; | ||
} | ||
} | ||
@@ -404,9 +425,9 @@ switch(diffItem.type) { | ||
return expect.promise.all(promises).then(() => { | ||
resolve(); | ||
resolve(target); | ||
}); | ||
} | ||
return resolve(); | ||
return resolve(target); | ||
}); | ||
}).then(() => { | ||
}).then(target => { | ||
@@ -422,3 +443,4 @@ if (actualChildren.length === 0 && expectedChildren.length !== 0 && options.diffMissingChildren) { | ||
removeCount, | ||
changeCount | ||
changeCount, | ||
target | ||
}; | ||
@@ -425,0 +447,0 @@ }); |
@@ -59,3 +59,4 @@ | ||
diff: convertToDiff(actualAdapter, actual, { includeChildren: false }), | ||
weight: wrapperResult.weight.addTotal(options.weights.WRAPPER_REMOVED) | ||
weight: wrapperResult.weight.addTotal(options.weights.WRAPPER_REMOVED), | ||
target: wrapperResult.target | ||
}; | ||
@@ -252,17 +253,26 @@ if (options.diffWrappers) { | ||
let isTarget = false; | ||
Object.keys(expectedAttributes).forEach(attrib => { | ||
if (!actualAttributes.hasOwnProperty(attrib)) { | ||
if (options.diffRemovedAttributes) { | ||
diffWeights.addReal(options.weights.ATTRIBUTE_MISSING); | ||
const attribResult = { | ||
name: attrib, | ||
diff: { | ||
type: 'missing', | ||
expectedValue: expectedAttributes[attrib] | ||
} | ||
}; | ||
diffResult.push(attribResult); | ||
if (attrib === options.findTargetAttrib) { | ||
// If it's the findTargetAttrib attribute, but it's not true, we still want to ignore the attribute | ||
// This will allow dynamic testing: e.g. <SomeChild eventTarget={index === 3 ? true : false} /> | ||
if (expectedAttributes[attrib] === true) { | ||
isTarget = true; | ||
} | ||
} else { | ||
if (options.diffRemovedAttributes) { | ||
diffWeights.addReal(options.weights.ATTRIBUTE_MISSING); | ||
const attribResult = { | ||
name: attrib, | ||
diff: { | ||
type: 'missing', | ||
expectedValue: expectedAttributes[attrib] | ||
} | ||
}; | ||
diffResult.push(attribResult); | ||
} | ||
diffWeights.addTotal(options.weights.ATTRIBUTE_MISSING); | ||
} | ||
diffWeights.addTotal(options.weights.ATTRIBUTE_MISSING); | ||
} | ||
@@ -274,3 +284,4 @@ }); | ||
diff: diffResult, | ||
weight: diffWeights | ||
weight: diffWeights, | ||
isTarget: isTarget | ||
})); | ||
@@ -281,3 +292,4 @@ } | ||
diff: diffResult, | ||
weight: diffWeights | ||
weight: diffWeights, | ||
isTarget: isTarget | ||
}; | ||
@@ -284,0 +296,0 @@ }; |
@@ -5,3 +5,2 @@ import ArrayChanges from 'array-changes'; | ||
import convertToDiff from './convertToDiff'; | ||
import LineBreaker from './lineBreaker'; | ||
import Weights from './Weights'; | ||
@@ -23,3 +22,4 @@ import * as DiffCommon from './diffCommon'; | ||
diff: diffResult.diff, | ||
weight: diffResult.weight.real | ||
weight: diffResult.weight.real, | ||
target: diffResult.target | ||
}; | ||
@@ -125,3 +125,8 @@ } | ||
} | ||
let target; | ||
if (attributesResult.isTarget) { | ||
target = actual; | ||
} | ||
diffResult.attributes = attributesResult.diff; | ||
@@ -134,6 +139,8 @@ weights.addWeight(attributesResult.weight); | ||
weights.addWeight(contentResult.weight); | ||
target = target || contentResult.target; | ||
return { | ||
diff: diffResult, | ||
weight: weights | ||
weight: weights, | ||
target: target | ||
}; | ||
@@ -148,2 +155,3 @@ | ||
let bestDiff = null; | ||
let bestTarget; | ||
@@ -166,2 +174,3 @@ // Optimize the common case of being exactly one child, ie. an element wrapping something | ||
bestWeight = childrenResult.weight; | ||
bestTarget = childrenResult.target; | ||
} | ||
@@ -203,3 +212,4 @@ | ||
diff: bestDiff, | ||
weight: bestWeight | ||
weight: bestWeight, | ||
target: bestTarget | ||
}; | ||
@@ -252,2 +262,3 @@ } | ||
const changes = ArrayChanges(actualChildren, expectedChildren, | ||
@@ -295,5 +306,13 @@ function (a, b, aIndex, bIndex) { | ||
let target = undefined; | ||
changes.forEach(diffItem => { | ||
let itemResult; | ||
let itemResult, cachedDiff; | ||
if (typeof diffItem.actualIndex === 'number' && typeof diffItem.expectedIndex === 'number') { | ||
const cacheIndex = (diffItem.actualIndex * expectedChildrenLength) + diffItem.expectedIndex; | ||
cachedDiff = cachedDiffs[cacheIndex]; | ||
if (cachedDiff && cachedDiff.target) { | ||
target = cachedDiff.target; | ||
} | ||
} | ||
@@ -339,13 +358,9 @@ switch (diffItem.type) { | ||
// fallthrough | ||
// (equal needs to be diffed, because it may contain wrappers, hence we need to work that out.. again) | ||
// It would be good to cache that, from the diff above. | ||
case 'equal': //eslint-disable-line no-fallthrough | ||
default: | ||
const result = diffElementOrWrapper(actualAdapter, expectedAdapter, diffItem.value, diffItem.expected, expect, options); | ||
diffResult.push(result.diff); | ||
diffWeights.addWeight(result.weight); | ||
diffResult.push(cachedDiff.diff); | ||
diffWeights.addWeight(cachedDiff.weight); | ||
break; | ||
} | ||
}); | ||
@@ -361,2 +376,3 @@ | ||
diff: diffResult, | ||
target, | ||
insertCount, | ||
@@ -363,0 +379,0 @@ removeCount, |
@@ -341,2 +341,39 @@ import Unexpected from 'unexpected'; | ||
}); | ||
describe('findTargetAttrib', () => { | ||
it('finds a target in a simple element', () => { | ||
const target = createActual({ | ||
name: 'span', | ||
attribs: { id: '123' }, | ||
children: [] | ||
}); | ||
return expect(createActual({ | ||
name: 'div', attribs: {}, children: [ | ||
{ | ||
name: 'span', | ||
attribs: { id: 'main' }, | ||
children: [ target ] | ||
} | ||
] | ||
}), 'when checked with options to contain', { findTargetAttrib: 'eventTarget', diffExtraAttributes: false }, createExpected( | ||
{ | ||
name: 'span', | ||
attribs: {}, | ||
children: [ { name: 'span', attribs: { eventTarget: true }, children: [] } ] | ||
} | ||
), 'to satisfy', { | ||
found: true, | ||
bestMatch: { | ||
diff: { | ||
type: 'ELEMENT' | ||
}, | ||
weight: 0, | ||
target | ||
} | ||
}); | ||
}) | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1391959
13593
371
Updatedarray-changes-async@^2.2.0