chai-kefir

用于断言 Kefir 可观察对象的 Chai 插件。

Build Status


如何使用

使用 npm 安装

npm i --save-dev chai-kefir

在测试文件顶部,导入 chai-kefirkefir 并注册 Kefir

import Kefir from 'kefir';
import { use } from 'chai';
import chaiKefir from 'chai-kefir';

如果您没有使用 ESModules,请确保获取 default 属性

const Kefir = require('kefir');
const { use } = require('chai');
const chaiKefir = require('chai-kefir').default;

在您的测试文件顶部,使用导出的工厂函数创建插件并将其注册到 chai

const { plugin, activate, send, stream, prop, pool } = chaiKefir(Kefir);
use(plugin);

所有导出的函数都允许您与 Kefir 可观察对象进行交互,而无需将它们直接连接到真实或模拟源。


API

Factory: (Kefir) => PluginHelpers

默认导出是一个工厂函数,它接受应用程序的 Kefir 实例,并返回一个包含插件助手对象的插件助手对象。这些助手将在下面介绍。

PluginHelpers

plugin: (chai, utils) => void

plugin 函数将 chai-kefir 的断言注册到 chai。此函数应传递给 chaiuse 函数。

activate: (obs: Kefir.Observable) => void

activate 是一个简单的辅助函数,用于打开流。

deactivate: (obs: Kefir.Observable) => void

deactivate 是一个简单的辅助函数,用于关闭流。它可以关闭使用 activate 激活的流。通过其他方式打开的流(直接调用 on{Value|Error|End|Any},使用 observe 等)需要通过其补充机制来停用。

send: (obs: Kefir.Observable, values: Array<Event<T>>) => obs

send 是一个辅助函数,用于将值发射到给定的可观察对象中。请注意,第二个参数是一个要从可观察对象中发射的值数组。该 Eventvalueerrorend 函数生成。对于这三个函数,可选的 options 对象不需要。

value: (value, options: ?{ current }) => Event<Value>

error: (error, options: ?{ current }) => Event<Error>

end: (options: ?{ current }) => Event<End>

valueerror 接受一个值或错误以及一个可选的 options 对象,并返回一个可以传递给 sendemitemitInTimeEvent 对象。 end 不接受此值,因为 Kefir 中的 end 事件不会与其一起发送值。

当传递给 send 时,options 对象将被忽略。 optionsemitemitInTime (两者将在下面描述)使用,以确定事件是否应该被视为 Kefir.Property 的当前事件、错误或结束。

stream: () => Kefir.Stream

prop: () => Kefir.Property

pool: () => Kefir.Pool

streamproppool 是创建空流、属性和池的辅助函数。这些可以用作模拟源来发送值。它们没有其他行为。

断言

observable

断言预期值是否为 Kefir.Observable。对于其他断言,我们建议从 observable 中进行链式调用。下面介绍的 property 需要它;其他断言应该为了保持一致性。

expect(obs).to.be.an.observable();

property

断言预期值是否为 Kefir.Property。必须与 observable 进行链式调用。

expect(obs).to.be.an.observable.property();

stream

断言预期值是否为 Kefir.Stream

expect(obs).to.be.an.observable.stream();

pool

断言预期值是否为 Kefir.Pool

expect(obs).to.be.an.observable.pool();

active

断言预期值是否是一个处于活动状态的可观察对象。

expect(obs).to.be.an.active.observable();

emit

断言提供的可观察对象是否同步发射预期值。 emit 接受一个要匹配的值数组,并期望它们按照正确的顺序深度等于值。

接受一个可选的回调函数,该函数在可观察对象激活后被调用。这是因为在将可观察对象传递给 chai 之前发射到可观察对象中的值不会发射到断言中,除非它是 Property。

expect(obs).to.emit([value(1), error(new Error('whoops!')), end()], () => {
    send(obs, [value(1), error(new Error('whoops!')), end()]);
});

如果 obs 是一个具有当前值的 Kefir.Property,则预期值应该获取包含 current: true 的 options 对象。请注意,鉴于 Properties 的工作方式,只有最后一个值是当前值。

send(obs, [value(1)]);
send(obs, [value(2)]);
expect(obs).to.emit([value(2, { current: true }), end()], () => {
    send(obs, [end()]);
});

这些规则也适用于 emitInTime

emitInTime

资产断言提供的资产是否随着时间的推移正确地发射了值。在幕后使用 lolex 接管 JavaScripts 定时器,允许您根据值发射的时间进行断言。预期值应该是一个元组数组,其中第一个值是时间,第二个值是发射的值。

const expected = [
    [0, value(1)],
    [10, error(new Error('whoops!'))],
    [20, end()]
]

接受一个回调函数,该函数传递一个简单的 tick 函数以及完整的 lolex clocktick 通过提供的毫秒数来推进内部计时器。 clock这里 有记录。

expect(obs).to.emit(expected, (tick, clock) => {
    send(obs, [value(1)]);
    tick(10);
    send(obs, [error(new Error('whoops!'))]);
    tick(10);
    send(obs, [end()]);
});

emitInTime 还接受一个可选的配置对象,该对象在回调函数之后。该对象接受以下选项

  • reverseSimultaneous: bool:指示是否应该以相反的顺序调用计划在同一时间执行的回调函数。这是一个高级用例,用于检查您的实现是否处理了常见的浏览器错误。有关详细信息,请参阅 此问题。Kefir 的内置方法正确地处理了这种情况,因此,除非您在实现中使用计时器,否则大多数情况下是不必要的。