From de02a36a77fb41ca78a7861fb9a8eba213b4844d Mon Sep 17 00:00:00 2001 From: Xie Yuheng Date: Mon, 24 Jun 2024 21:27:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=BD=E5=87=BA=20`Support`=20=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=20`assertSupported`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 2 +- src/dependency/Supported.ts | 41 ++++++++++++++++++++++++++++++++-- src/examples/barometer.test.ts | 28 +++++++++-------------- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/TODO.md b/TODO.md index 601e718..407baed 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,7 @@ > - https://github.com/cicada-lang/propagator/issues/2 -抽出来一个叫 `Support` 的 type +抽出 `SupportLike` 以及 `toSupport` improve interface for `put` -- second argument should be list of optional promises diff --git a/src/dependency/Supported.ts b/src/dependency/Supported.ts index 1398740..148f68b 100644 --- a/src/dependency/Supported.ts +++ b/src/dependency/Supported.ts @@ -1,12 +1,23 @@ +import assert from "node:assert" import { isNonNullObject } from "../utils/isNonNullObject.js" +import { log } from "../utils/log.js" + +export type Support = Set export type Supported = { "@type": "Supported" value: T - support: Set + support: Support } -export function Supported(value: T, support: Set): Supported { +export function Supported( + value: T, + support: Support | Array, +): Supported { + if (support instanceof Array) { + support = new Set(support) + } + return { "@type": "Supported", value, @@ -22,3 +33,29 @@ export function toSupported(x: any): Supported { if (isSupported(x)) return x return Supported(x, new Set()) } + +export function assertSupported( + target: any, + support?: Support | Array, +): asserts target is Supported { + if (!isSupported(target)) { + const message = `Assertion fails.` + log({ + kind: "Error", + who: "assertSupported", + message, + target, + support, + }) + + throw new Error(`[assertSupported] ${message}`) + } + + if (support !== undefined) { + if (support instanceof Array) { + support = new Set(support) + } + + assert.deepStrictEqual(target.support, support) + } +} diff --git a/src/examples/barometer.test.ts b/src/examples/barometer.test.ts index 211c5d7..9d6e8b5 100644 --- a/src/examples/barometer.test.ts +++ b/src/examples/barometer.test.ts @@ -1,7 +1,7 @@ import assert from "node:assert" import { test } from "node:test" import { Cell, put } from "../cell/index.js" -import { Supported } from "../dependency/index.js" +import { Supported, assertSupported } from "../dependency/index.js" import { Interval, intervalAlmostEqual } from "../interval/index.js" import { run } from "../scheduler/index.js" import { log } from "../utils/log.js" @@ -78,13 +78,13 @@ test("examples / barometer / similarTriangles & fallDuration", async () => { test("examples / barometer / with supported value", async () => { const [barometerShadow, barometerHeight, buildingShadow, buildingHeight] = similarTriangles() - put(buildingShadow, Supported(Interval(54.9, 55.1), new Set(["shadows"]))) - put(barometerHeight, Supported(Interval(0.3, 0.32), new Set(["shadows"]))) - put(barometerShadow, Supported(Interval(0.36, 0.37), new Set(["shadows"]))) + put(buildingShadow, Supported(Interval(54.9, 55.1), ["shadows"])) + put(barometerHeight, Supported(Interval(0.3, 0.32), ["shadows"])) + put(barometerShadow, Supported(Interval(0.36, 0.37), ["shadows"])) await run() - assert.deepStrictEqual(buildingHeight.content.support, new Set(["shadows"])) + assertSupported(buildingHeight.content, ["shadows"]) assert( intervalAlmostEqual( buildingHeight.content.value, @@ -95,11 +95,11 @@ test("examples / barometer / with supported value", async () => { const fallTime = Cell() fallDuration(fallTime, buildingHeight) - put(fallTime, Supported(Interval(2.9, 3.3), new Set(["lousy-fall-time"]))) + put(fallTime, Supported(Interval(2.9, 3.3), ["lousy-fall-time"])) await run() - assert.deepStrictEqual(buildingHeight.content.support, new Set(["shadows"])) + assertSupported(buildingHeight.content, ["shadows"]) assert( intervalAlmostEqual( buildingHeight.content.value, @@ -108,14 +108,11 @@ test("examples / barometer / with supported value", async () => { ), ) - put(fallTime, Supported(Interval(2.9, 3.1), new Set(["better-fall-time"]))) + put(fallTime, Supported(Interval(2.9, 3.1), ["better-fall-time"])) await run() - assert.deepStrictEqual( - buildingHeight.content.support, - new Set(["shadows", "better-fall-time"]), - ) + assertSupported(buildingHeight.content, ["shadows", "better-fall-time"]) assert( intervalAlmostEqual( buildingHeight.content.value, @@ -124,14 +121,11 @@ test("examples / barometer / with supported value", async () => { ), ) - put(buildingHeight, Supported(45, new Set(["superintendent"]))) + put(buildingHeight, Supported(45, ["superintendent"])) await run() - assert.deepStrictEqual( - buildingHeight.content.support, - new Set(["superintendent"]), - ) + assertSupported(buildingHeight.content, ["superintendent"]) assert.deepStrictEqual(buildingHeight.content.value, 45) // (content barometer-height)