concordancejs / concordance

Compare, format, diff and serialize any JavaScript value
ISC License
207 stars 15 forks source link

Infinite iterables cause infinite loops #73

Closed ninevra closed 3 years ago

ninevra commented 3 years ago

concordance attempts to traverse iterables to completion, so that it can compare and/or describe their elements. This means that compare, diff, format, and serialize loop infinitely when called with infinite iterables.

This can cause AVA tests to time out, even on comparisons that can be completed in finite time, such as

const test = require('ava');

test('Comparing infinite iterables', t => {
  t.deepEqual(
    (function * () { while (true) yield; })(),
    undefined
  );
});

I'm not sure whether this is the intended behavior or not.

novemberborn commented 3 years ago

I'm not sure whether this is the intended behavior or not.

Retroactively… yes? I'm not sure what else to do with this, it's hard to set an arbitrary cap on iteration steps. What do you think?

ninevra commented 3 years ago

I'm not sure? It wouldn't make sense to consider only a finite number of elements, but I suppose one could throw after a configurable number of steps.

Traversing iterables at all seems odd to me, since stateful iterables could produce strange results and async iterables aren't (and can't be) treated similarly, but that's a done design decision. (Looking at other libraries, chai and jest likewise traverse iterables, lodash just declares them equal for some reason, and node assert compares them by reference / identity.)

describe() and compare() seem to work fine with infinite iterables (unless compare receives two equal infinite iterables, of course). It might be possible to improve on this slightly by setting a configurable maximum iterations cap for at least diff() and format(), so that AVA could produce sensible output in slightly more cases. Doesn't seem worth the work, though, since assertions on infinite iterables will never pass.

I'll close this issue.