diff --git a/packages/general/src/transaction/Tx.ts b/packages/general/src/transaction/Tx.ts index 6b7049fd90..c71e28a268 100644 --- a/packages/general/src/transaction/Tx.ts +++ b/packages/general/src/transaction/Tx.ts @@ -688,6 +688,7 @@ class Tx implements Transaction, Transaction.Finalization { const promise = participant.postCommit?.(); if (MaybePromise.is(promise)) { + i++; return Promise.resolve(promise).then(executePostCommit, e => { reportParticipantError(e); executePostCommit(); diff --git a/packages/general/test/util/ObservableTest.ts b/packages/general/test/util/ObservableTest.ts index 3b89d69955..0480e66535 100644 --- a/packages/general/test/util/ObservableTest.ts +++ b/packages/general/test/util/ObservableTest.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Observable, ObserverGroup } from "#util/Observable.js"; +import { AsyncObservable, Observable, ObserverGroup } from "#util/Observable.js"; // Observable deserves proper unit tests but is tested heavily via other modules. Currently this file just tests a // few spot cases @@ -52,3 +52,39 @@ describe("ObservableGroup", () => { expect(observable.isObserved).false; }); }); + +describe("AsyncObservable", () => { + it("emits", async () => { + const observable = AsyncObservable<[foo: string]>(); + + let observedFoo; + + observable.on(async foo => { + observedFoo = foo; + }); + + await observable.emit("what I expect"); + + expect(observedFoo).equals("what I expect"); + }); + + it("emits with mix of observers", async () => { + const observable = AsyncObservable<[foo: string]>(); + + const observedFoos = Array(); + + for (let i = 0; i < 3; i++) { + observable.on(async foo => { + observedFoos.push(foo); + }); + + observable.on(foo => { + observedFoos.push(foo); + }); + } + + await observable.emit("asdf"); + + expect(observedFoos).deep.equals(["asdf", "asdf", "asdf", "asdf", "asdf", "asdf"]); + }); +}); diff --git a/packages/node/test/behaviors/on-off/OnOffServerTest.ts b/packages/node/test/behaviors/on-off/OnOffServerTest.ts index 5f8ea141ac..38780126a1 100644 --- a/packages/node/test/behaviors/on-off/OnOffServerTest.ts +++ b/packages/node/test/behaviors/on-off/OnOffServerTest.ts @@ -6,6 +6,7 @@ import { OnOffServer } from "#behaviors/on-off"; import { MaybePromise } from "#general"; +import { MockServerNode } from "../../node/mock-server-node.js"; describe("OnOffServer", () => { it("accepts extensions of off-only commands", () => { @@ -18,4 +19,28 @@ describe("OnOffServer", () => { x satisfies { on(): MaybePromise }; }); + + it("properly supports async observers", async () => { + const server = await MockServerNode.createOnline(); + const part = server.parts.get(1); + + const observedValues = Array(); + + part!.eventsOf(OnOffServer).onOff$Changed.on(async value => { + observedValues.push(value); + }); + + for (let i = 0; i < 2; i++) { + await part!.act(async agent => { + const onOff = agent.get(OnOffServer); + await onOff.toggle(); + }); + } + + await server.close(); + + await MockTime.yield3(); + + expect(observedValues).deep.equals([true, false]); + }); }); diff --git a/packages/types/src/tlv/TlvString.ts b/packages/types/src/tlv/TlvString.ts index a595786254..476f33571a 100644 --- a/packages/types/src/tlv/TlvString.ts +++ b/packages/types/src/tlv/TlvString.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { InternalError, maxValue, minValue, serialize, UnexpectedDataError } from "#general"; +import { InternalError, serialize, UnexpectedDataError } from "#general"; import { ValidationDatatypeMismatchError, ValidationOutOfBoundsError } from "../common/ValidationError.js"; import { TlvCodec, TlvTag, TlvToPrimitive, TlvType, TlvTypeLength } from "./TlvCodec.js"; import { TlvReader, TlvSchema, TlvWriter } from "./TlvSchema.js"; @@ -29,6 +29,8 @@ export class StringSchema ext super(); if (minLength < 0) throw new InternalError("Minimum length should be a positive number."); + if (maxLength < 0) throw new InternalError("Maximum length should be a positive number."); + if (minLength > maxLength) throw new InternalError("Minimum length should be smaller than maximum length."); } override encodeTlvInternal(writer: TlvWriter, value: TlvToPrimitive[T], tag?: TlvTag): void { @@ -60,8 +62,8 @@ export class StringSchema ext bound({ minLength, maxLength, length }: LengthConstraints) { return new StringSchema( this.type, - length ?? maxValue(this.minLength, minLength), - length ?? minValue(this.maxLength, maxLength), + length ?? minLength ?? this.minLength, + length ?? maxLength ?? this.maxLength, ); } }