Ability to show only changes and deletions in diffs, not additions
See original GitHub issueI use chai
assertion library and chai-like
library for the partial comparing of objects: I am interested in existence and compliance only of those properties that are listed in an expected
object. Existence of additional properties in an actual
object permissibly. Unfortunately, when diff is created it is not considered in any way and those properties, existence which for the test it is indifferent get to diff. It would be desirable to have a way to suppress their generation in a diff. Example (runned with mocha):
'use strict';
let chai = require('chai');
let expect = chai.expect;
chai.use(require('chai-like'));
describe("diff test", function() {
let AST = {
type: 'grammar',
rules: [
{ type: 'rule', name: 'rule1' },
{ type: 'rule', name: 'rule2' },
],
// it is a lot more other properties
};
it("chai-like", function() {
expect(AST).like({
rules: [
{ name: 'rule' },
{ name: 'rule2' }
]
});
});
});
This is current actual output of mocha which is too large in some cases and contains unnecessary details
1) diff test
chai-like:
AssertionError: expected { Object (type, rules) } to be like { Object (rules) }
+ expected - actual
{
"rules": [
{
- "name": "rule1"
- "type": "rule"
+ "name": "rule"
}
{
"name": "rule2"
- "type": "rule"
}
]
- "type": "grammar"
}
at Context.<anonymous> (test\test.js:24:17)
But I want that diff looked here so:
{
"rules": [
{
- "name": "rule1"
+ "name": "rule"
}
]
}
Now there is no opportunity to show diff in that look in what it is required as AssertionError
has no signs that it is required. Mocha developers advised to create at first the task here before they are able to support this functionality (https://github.com/mochajs/mocha/issues/3193).
I suppose add to an AssertionError
object new property which could control such behavior of diff.
If the idea is supported, I can make PRs for its implementation in all necessary libraries.
Issue Analytics
- State:
- Created 6 years ago
- Comments:27 (21 by maintainers)
Top GitHub Comments
FWIW here is an (incomplete) list of issues we have relating to diffs and Mocha: https://github.com/chaijs/chai/issues/246, https://github.com/chaijs/chai/issues/249, https://github.com/chaijs/chai/issues/270, https://github.com/chaijs/chai/issues/304, https://github.com/chaijs/chai/issues/363, https://github.com/chaijs/chai/issues/469, https://github.com/chaijs/chai/issues/654, https://github.com/chaijs/chai/issues/678, https://github.com/chaijs/chai/issues/703, https://github.com/chaijs/chai/issues/1055, https://github.com/chaijs/chai/issues/1060, https://github.com/chaijs/chai/issues/1103
You can see these issues have been surfaced with a fairly regular cadence since 2014 which is somewhat shortly after when mocha started supporting
expected
andactual
.We can see the same thing in Mocha’s issue tracker: https://github.com/mochajs/mocha/issues/1832, https://github.com/mochajs/mocha/issues/1348, https://github.com/mochajs/mocha/issues/1071 … I won’t go on, you know enough about mocha’s issues.
All of these issues are roughly duplicates of eachother - the general theme is that the error output isn’t sufficient.
FWIW @Mingun is looking for the same answer all the above issues are. I’m derailing this issue with my own agenda, which is something I’ve been perculating on for a long time. I’ve been hoping to add
diff
for a long time, not just because of this recently filed issue.That is exactly what I’m after. Given mocha+chai is the most used combo, like you say, we could easily throw a bit of weight around and end up with everyone happy. IMO this is where the
diff
property would help. It would not break backward compat, and libraries could simply opt into it where they want to. But maybe I’m just flogging a dead horse now, so let’s restart.Problem
Both mocha and chai need to improve diff output, to stop the influx off issues we both receive. How do we do this in an interoperable way?
Requirements (chai)
.message
property (we call this libloupe
, it is going through a huge rewrite currently)loupe
will use object-diffing as a heuristic for providing concise and effective.message
strings.loupe
s algorithms can be used to represent the differences between two objects, in some format, object or string.What are Mocha’s requirements for this interop here?
brain dump follows
Where Do I File A Bug?
What sucks for users, I’ve noticed, is that they don’t know which lib is responsible for the diff. Is it Chai? Is it Mocha? Sometimes we don’t even know!
I’m open to suggestions on how to attack that.
Baseline Value Representation
What also sucks–and could suck more, if we don’t do this right–is inconsistent diffs from one lib to the next.
How to represent a numeric primitive is not especially controversial. But …
Number
instance? What aboutString
?undefined
orvoid 0
?null
?Date
objects?Buffer
objects?ArrayBuffer
objects?SharedArrayBuffer
objects (j/k)?Promise
objects? Non-nativePromise
objects?Array
s vs array-like objects? What’s considered an array-like object?Map
, andSet
?WeakMap
andWeakSet
, both of which cannot be enumerated?{foo: 'bar'}
is not the same object as{foo: 'bar'}
, but it’s equivalent)?Mocha has its own ideas about many of these, but not necessarily the “best” or “most correct” ones. Some of these may be best left out of the “core”–and/or we can choose to delay decisions until they become necessary.
Extensibility
…but there’s likely more than one way to represent any of the given types I’ve mentioned above. Different kinds of diffs–not just object comparison–may (?) need support, such as a standard unified or inline output from
diff
.A lib or plugin author should be able to write their own custom implementation to diff objects of a certain “type”. This can be defined by
instanceof
, ortype
, or a custom comparison function.Going a step further, end users should be able to leverage a
valueOf()
-like-function to tailor the diffs to their liking, so you don’t need to do a Magic Plugin Dance to get that diff for yourMonkeyButt
class looking the way you want.Metadata, Statistics
One thing Mocha can’t do, because of a lack of a built-in assertion library, is set an expectation about how many assertions were expected to be made. Mocha doesn’t know what an “assertion” is. Some may find this capability more useful than others, but it is another tool to avoid false positives.
But I don’t know if the user should touch the assertion lib API or Mocha’s API to use it.
(This is also not currently possible from within a standalone assertion framework, because it doesn’t know when a “test” or “suite” finishes. Or what a “test” or “suite” is.)
Open to ideas. First thing that comes to mind is some sort of
EventEmitter
bus.If there are numbers that Chai keeps that may be useful to Mocha, let’s expose those.
Backwards Compat
Mocha must continue to work fine with other assertion libraries. That said, Mocha’s diff output will necessarily change, since I don’t want to maintain two separate algorithms for this.
Modules
Given that currently an assertion library can create and display the entire diff without any assistance from Mocha short of a
console.log(message)
, I’m not sure what Chai expects Mocha to implement. @keithamus mentioned “colors”, etc., but this is not something Mocha must do because Chai cannot. What I’m looking for is to understand:As mentioned earlier, Mocha & Chai could consume the same module to generate diffs.
Justification
If we’re going to disrupt users by screwing with their diffs, the new diffs should be better than the old ones.
They should be so freaking awesome that users of other frameworks & libs create issues demanding adoption. 😉