ava: Adding Iterator to nested objects data type break Snapshots
Discussed in https://github.com/avajs/ava/discussions/2810
<div type='discussions-op-text'>Originally posted by jcubic August 17, 2021 I have a project that uses linked lists (class Pair that have car and cdr as part of my lisp interpreter). Those pairs create nested objects structures and I’m comparing that object structure with a snapshot.
Recently I’ve added this snippet of code that add iterator to my data type:
+ Pair.prototype[Symbol.iterator] = function() {
+ var node = this;
+ return {
+ next: function() {
+ var cur = node;
+ node = cur.cdr;
+ if (node === nil) {
+ return { value: undefined, done: true };
+ } else {
+ return { value: cur.car, done: false };
+ }
+ }
+ };
+ };
There is a bug in this code it should be cur === nil
but after fixing it, it also shows an error in tests when comparing Pair structure with a snapshot.
My question is how ava works with iterators vs objects with structure. Because the iterator is used only for lists and with Pairs, you can create any Trees. It should not break tests, but Ava thinks that the data has changed. Ava should not use iterator anywhere, it should compare my nested object structure instead.
Here is a link to the broken test:
https://travis-ci.com/github/jcubic/lips/builds/235460776
Here are the tests that are failing when reading snapshot:
https://github.com/jcubic/lips/blob/devel/tests/macroexpand.scm
The code is in Scheme (lisp dialect), but it compares JavaScript objects.
I was trying to reproduce the issue by calculating the hash used by ava. But it works as expected, the hash is the same before and after adding Iterator:
var cbor = require('cbor');
var crypto = require('crypto');
var zlib = require('zlib');
function Pair(car, cdr) {
this.car = car;
this.cdr = cdr;
}
function Nil() {}
var nil = new Nil();
var x = new Pair(
new Pair(
new Pair(
10,
new Pair(
20,
nil
)
),
nil
),
nil
);
function hash(data) {
const encoded = cbor.encodeOne(data, {
omitUndefinedProperties: true,
canonical: true
});
const compressed = zlib.gzipSync(encoded);
compressed[9] = 0x03; // Override the GZip header containing the OS to always be Linux
const sha256sum = crypto.createHash('sha256').update(compressed).digest();
return sha256sum;
}
var before = hash(x);
var ensure = hash(x);
Pair.prototype[Symbol.iterator] = function() {
var node = this;
return {
next: function() {
var cur = node;
node = cur.cdr;
if (cur === nil) {
return { value: undefined, done: true };
} else {
return { value: cur.car, done: false };
}
}
};
};
var after = hash(x);
console.log({before, ensure, match: Buffer.compare(before, ensure) === 0});
console.log({after, before, match: Buffer.compare(after, before) === 0})
Also when I’ve tried to update the snapshots to see the difference, I’ve got this error:
Could not update snapshots for the following test files:
⚠ tests/test.js
This is my only JavaScript test file.</div>
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 20 (7 by maintainers)
Per https://github.com/concordancejs/concordance/issues/76 I think this is by design.