@ effectionx/ converg
承认理想状态,并在该状态实现后同步.
此软件包为 @ bigtest/汇合 适应 效果 结构货币.
何以相会?
假设你想写一个断言来验证一个简单的原因 效果: 当单击某个按钮时, 对话框会显示包含 一些从网络中加载的文本 .
为了做到这一点,你必须保证你的主张 之后 你测试的效果已经实现.

如果不是的话,那么你可能会变成假阴性,或者"阴性测试" 因为你的断言太早了 如果你只是等待一点点 再长一点,你的测试就会通过 真遗憾!

事实上,测试片是大多数人逃避的原因 首先用 JavaScript 编写大测试 。 看来差不多了 无法写出强健的测试,但不能在 运行时间的内部,以便手动同步 比如渲染和数据加载 不幸的是,这些可能是 移动目标,更糟糕的是, 他们与你结合到你的框架.
但是,如果不是试图 运行我们的说法在正确的 时间,我们运行它们 数量 直到他们通过 或者我们决定 放弃?

这就是什么的本质 @effectionx/converge 规定:
重复测试一个条件,然后允许代码运行
条件已经满足了.
这不仅仅是为了断言。 因为那是个将军 在任何观测到的状态上同步的机制,可用于 适当的时间测试 设置和撕裂也.
安装
npm install @effectionx/converge
使用量
when(assertion, options?)
主张通过时的汇合 在内部 暂停期。 这个
重复运行(默认情况下每10 ms)并被考虑
当它不抛出或返回的时候 false如果它从未通过
在超时时,操作会随最后一个出错而抛出.
import { when } from "@effectionx/converge";
// Wait for a condition to become true
let { value } = yield* when(function* () {
if (total !== 100) throw new Error("not ready");
return total;
});
// With custom timeout
yield* when(
function* () {
if (!element.isVisible) throw new Error("not visible");
},
{ timeout: 5000 },
);
always(assertion, options?)
主张通过时的汇合 整个 暂停期.
喜欢 when()但必须经过
整个期间始终如一。 如果在任何时刻失败
操作立即投出.
import { always } from "@effectionx/converge";
// Verify a condition remains true
yield* always(function* () {
if (counter >= 100) throw new Error("counter exceeded limit");
});
// With custom timeout
yield* always(
function* () {
if (!connection.isAlive) throw new Error("connection lost");
},
{ timeout: 5000 },
);
选项
两者 when 财务报告和审定财务报表 always 接受选项对象 :
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
timeout | number | 2000 (何时)/ 200 (总是) | 最多等待时间( 毫秒) |
interval | number | 10 | 以毫秒表示的断言重试间隔时间 |
Stats 对象
两个函数返回 a ConvergeStats 有时间和执行信息的对象:
interface ConvergeStats<T> {
start: number; // Timestamp when convergence started
end: number; // Timestamp when convergence ended
elapsed: number; // Milliseconds the convergence took
runs: number; // Number of times the assertion was executed
timeout: number; // The timeout that was configured
interval: number; // The interval that was configured
value: T; // The return value from the assertion
}
示例
let stats = yield* when(
function* () {
return yield* fetchData();
},
{ timeout: 5000 },
);
console.log(`Converged in ${stats.elapsed}ms after ${stats.runs} attempts`);
console.log(stats.value); // the fetched data
实例
等待元素出现
yield* when(function* () {
let element = document.querySelector('[data-test-id="dialog"]');
if (!element) throw new Error("dialog not found");
return element;
});
验证一个值保持稳定
yield* always(
function* () {
if (connection.status !== "connected") {
throw new Error("connection dropped");
}
},
{ timeout: 1000 },
);
使用文件系统操作
import { when } from "@effectionx/converge";
import { access } from "node:fs/promises";
import { until } from "effection";
// Wait for a file to exist
yield* when(
function* () {
let exists = yield* until(
access(filePath).then(
() => true,
() => false,
),
);
if (!exists) throw new Error("file not found");
return true;
},
{ timeout: 10000 },
);