chai-kefir
用于断言 Kefir 可观察对象的 Chai 插件。
如何使用
使用 npm 安装
npm i --save-dev chai-kefir
在测试文件顶部,导入 chai-kefir 和 kefir 并注册 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。此函数应传递给 chai 的 use 函数。
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 是一个辅助函数,用于将值发射到给定的可观察对象中。请注意,第二个参数是一个要从可观察对象中发射的值数组。该 Event 由 value、error 和 end 函数生成。对于这三个函数,可选的 options 对象不需要。
value: (value, options: ?{ current }) => Event<Value>
error: (error, options: ?{ current }) => Event<Error>
end: (options: ?{ current }) => Event<End>
value 和 error 接受一个值或错误以及一个可选的 options 对象,并返回一个可以传递给 send、emit 或 emitInTime 的 Event 对象。 end 不接受此值,因为 Kefir 中的 end 事件不会与其一起发送值。
当传递给 send 时,options 对象将被忽略。 options 由 emit 和 emitInTime (两者将在下面描述)使用,以确定事件是否应该被视为 Kefir.Property 的当前事件、错误或结束。
stream: () => Kefir.Stream
prop: () => Kefir.Property
pool: () => Kefir.Pool
stream、prop 和 pool 是创建空流、属性和池的辅助函数。这些可以用作模拟源来发送值。它们没有其他行为。
断言
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 clock。 tick 通过提供的毫秒数来推进内部计时器。 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 的内置方法正确地处理了这种情况,因此,除非您在实现中使用计时器,否则大多数情况下是不必要的。