From 3938b639ecd726e90eee2dd49c6507e43a07a8bd Mon Sep 17 00:00:00 2001 From: Andrew Bulat Date: Tue, 19 Nov 2024 04:31:36 +0000 Subject: [PATCH] Add tests for user-provided LiveObjects types to the LiveObjects package test --- .../browser/template/src/ably.config.d.ts | 21 ++++++++++ .../browser/template/src/index-liveobjects.ts | 42 ++++++++++++++----- .../browser/template/src/tsconfig.json | 1 + 3 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 test/package/browser/template/src/ably.config.d.ts diff --git a/test/package/browser/template/src/ably.config.d.ts b/test/package/browser/template/src/ably.config.d.ts new file mode 100644 index 000000000..e5bca7718 --- /dev/null +++ b/test/package/browser/template/src/ably.config.d.ts @@ -0,0 +1,21 @@ +import { LiveCounter, LiveMap } from 'ably'; + +type CustomRoot = { + numberKey: number; + stringKey: string; + booleanKey: boolean; + couldBeUndefined?: string; + mapKey?: LiveMap<{ + foo: 'bar'; + nestedMap?: LiveMap<{ + baz: 'qux'; + }>; + }>; + counterKey?: LiveCounter; +}; + +declare global { + export interface LiveObjectsTypes { + root: CustomRoot; + } +} diff --git a/test/package/browser/template/src/index-liveobjects.ts b/test/package/browser/template/src/index-liveobjects.ts index 9334aadf4..1cd27b021 100644 --- a/test/package/browser/template/src/index-liveobjects.ts +++ b/test/package/browser/template/src/index-liveobjects.ts @@ -1,7 +1,12 @@ import * as Ably from 'ably'; import LiveObjects from 'ably/liveobjects'; +import { CustomRoot } from './ably.config'; import { createSandboxAblyAPIKey } from './sandbox'; +type ExplicitRootType = { + someOtherKey: string; +}; + globalThis.testAblyPackage = async function () { const key = await createSandboxAblyAPIKey({ featureFlags: ['enableChannelState'] }); @@ -11,12 +16,27 @@ globalThis.testAblyPackage = async function () { // check liveObjects can be accessed const liveObjects = channel.liveObjects; await channel.attach(); - // root should be a LiveMap object - const root: Ably.LiveMap = await liveObjects.getRoot(); + // expect root to be a LiveMap instance with LiveObjects types defined via the global LiveObjectsTypes interface + // also checks that we can refer to the LiveObjects types exported from 'ably' by referencing a LiveMap interface + const root: Ably.LiveMap = await liveObjects.getRoot(); + + // check root has expected LiveMap TypeScript type methods + const size: number = root.size(); - // check root is recognized as LiveMap TypeScript type - root.get('someKey'); - root.size(); + // check custom user provided typings via LiveObjectsTypes are working: + // keys on a root: + const aNumber: number = root.get('numberKey'); + const aString: string = root.get('stringKey'); + const aBoolean: boolean = root.get('booleanKey'); + const couldBeUndefined: string | undefined = root.get('couldBeUndefined'); + // live objects on a root: + const counter: Ably.LiveCounter | undefined = root.get('counterKey'); + const map: LiveObjectsTypes['root']['mapKey'] = root.get('mapKey'); + // check string literal types works + // need to use nullish coalescing as we didn't actually create any data on the root, + // so the next calls would fail. we only need to check that TypeScript types work + const foo: 'bar' = map?.get('foo')!; + const baz: 'qux' = map?.get('nestedMap')?.get('baz')!; // check LiveMap subscription callback has correct TypeScript types const { unsubscribe } = root.subscribe(({ update }) => { @@ -31,13 +51,15 @@ globalThis.testAblyPackage = async function () { }); unsubscribe(); - // check LiveCounter types also behave as expected - const counter = root.get('randomKey') as Ably.LiveCounter | undefined; - // use nullish coalescing as we didn't actually create a counter object on the root, - // so the next calls would fail. we only need to check that TypeScript types work - const value: number = counter?.value(); + // check LiveCounter type also behaves as expected + // same deal with nullish coalescing + const value: number = counter?.value()!; const counterSubscribeResponse = counter?.subscribe(({ update }) => { const shouldBeANumber: number = update.inc; }); counterSubscribeResponse?.unsubscribe(); + + // check can provide custom types for the getRoot method, ignoring global LiveObjectsTypes interface + const explicitRoot: Ably.LiveMap = await liveObjects.getRoot(); + const someOtherKey: string = explicitRoot.get('someOtherKey'); }; diff --git a/test/package/browser/template/src/tsconfig.json b/test/package/browser/template/src/tsconfig.json index b206a6399..3230e8697 100644 --- a/test/package/browser/template/src/tsconfig.json +++ b/test/package/browser/template/src/tsconfig.json @@ -1,6 +1,7 @@ { "include": ["**/*.ts", "**/*.tsx"], "compilerOptions": { + "strictNullChecks": true, "resolveJsonModule": true, "esModuleInterop": true, "module": "esnext",