断言流

Asserting streams

你会如何处理流断言?也就是说,您关心输入的顺序但不关心它们是否互斥(可能介于两者之间)。

监听每个阶段的事件当然是可行的,但它变得非常冗长,寻找更务实的解决方案。

粗暴的方法类似于下面的磁带测试

t.plan(3);

var exe = child.spawn(...);
exe.stdout.once('data', first function(data) {
  // first expected output is always 1
  t.equal(data.toString(), '1\n');

    // next, 2, 3, 4 is coming but in unknown order.
    // the test only tests for 2
    exe.stdout.on('data', function second(data) {
      if (data.toString() !== '2\n') {
        // skip, don't care about this entry
        return;
      }

      exe.stdout.removeListener('data', second);
      t.equal(data.toString(), '2\n');

      // next is 5, 6, 7, again in unknown order but they are
      // AFTER the previous sequence
      exe.stdout.on('data', function third(data) {
        if (data.toString() !== '7\n') {
          // skip, don't care about this entry
          return;
        }

        exe.stdout.removeListener('data', third);        
        t.equal(data.toString(), '7\n');
      });
    });
  });
});

这是一个可能的解决方案。我们添加了一个数据侦听器,每次我们收到一个事件时,我们都会检查它是否与我们期望的下一个事件匹配,如果是,则将其从期望值数组中删除。最后,当我们清空数组时,我们调用回调。我假设您在获得预期响应后可以调用回调。您可能希望确保此测试有超时;否则它将永远等待并且永远不会失败。

assertStreamWithGaps = function(stream, strs, next) {
  stream.on('data', function(data) {
    if(data.toString() === strs[0]) {
      strs.shift();
      if(strs.length === 0) {
        next();
      }
    }
  });
}

你可以在你的例子中这样称呼它:

assertStreamWithGaps(exe.stdout, ['1\n', '2\n', '7\n']);

这与您的示例完全不匹配,因为您希望没有领先差距。我不清楚这是否是故意的,所以我跳过了它。添加该功能可能很容易。

此外,我不确定 t 是什么或如何使用它,所以我没有。