Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LiveObjects package test #1921

Merged
merged 2 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion test/package/browser/template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This directory is intended to be used for testing the following aspects of the a
It contains three files, each of which import ably-js in different manners, and provide a way to briefly exercise its functionality:

- `src/index-default.ts` imports the default ably-js package (`import { Realtime } from 'ably'`).
- `src/index-liveobjects.ts` imports the LiveObjects ably-js plugin (`import LiveObjects from 'ably/liveobjects'`).
- `src/index-modular.ts` imports the tree-shakable ably-js package (`import { BaseRealtime, WebSocketTransport, FetchRequest } from 'ably/modular'`).
- `src/ReactApp.tsx` imports React hooks from the ably-js package (`import { useChannel } from 'ably/react'`).

Expand All @@ -25,6 +26,7 @@ This directory exposes three package scripts that are to be used for testing:

- `build`: Uses esbuild to create:
1. a bundle containing `src/index-default.ts` and ably-js;
2. a bundle containing `src/index-modular.ts` and ably-js.
2. a bundle containing `src/index-liveobjects.ts` and ably-js.
3. a bundle containing `src/index-modular.ts` and ably-js.
- `test`: Using the bundles created by `build` and playwright components setup, tests that the code that exercises ably-js’s functionality is working correctly in a browser.
- `typecheck`: Type-checks the code that imports ably-js.
2 changes: 1 addition & 1 deletion test/package/browser/template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "",
"main": "index.js",
"scripts": {
"build": "esbuild --bundle src/index-default.ts --outdir=dist && esbuild --bundle src/index-modular.ts --outdir=dist",
"build": "esbuild --bundle src/index-default.ts --outdir=dist && esbuild --bundle src/index-liveobjects.ts --outdir=dist && esbuild --bundle src/index-modular.ts --outdir=dist",
"typecheck": "tsc --project src -noEmit",
"test-support:server": "ts-node server/server.ts",
"test": "npm run test:lib && npm run test:hooks",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Ably NPM package test (LiveObjects plugin export)</title>
</head>
<body>
<script type="text/javascript" src="index-liveobjects.js"></script>
<script type="text/javascript" src="runTest.js"></script>
</body>
</html>
2 changes: 1 addition & 1 deletion test/package/browser/template/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ async function startWebServer(listenPort: number) {
const server = express();
server.get('/', (req, res) => res.send('OK'));
server.use(express.static(path.join(__dirname, '/resources')));
for (const filename of ['index-default.js', 'index-modular.js']) {
for (const filename of ['index-default.js', 'index-liveobjects.js', 'index-modular.js']) {
server.use(`/${filename}`, express.static(path.join(__dirname, '..', 'dist', filename)));
}

Expand Down
43 changes: 43 additions & 0 deletions test/package/browser/template/src/index-liveobjects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as Ably from 'ably';
import LiveObjects from 'ably/liveobjects';
import { createSandboxAblyAPIKey } from './sandbox';

globalThis.testAblyPackage = async function () {
const key = await createSandboxAblyAPIKey({ featureFlags: ['enableChannelState'] });

const realtime = new Ably.Realtime({ key, environment: 'sandbox', plugins: { LiveObjects } });
VeskeR marked this conversation as resolved.
Show resolved Hide resolved

const channel = realtime.channels.get('channel', { modes: ['STATE_SUBSCRIBE', 'STATE_PUBLISH'] });
// 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();

// check root is recognized as LiveMap TypeScript type
root.get('someKey');
root.size();
VeskeR marked this conversation as resolved.
Show resolved Hide resolved

// check LiveMap subscription callback has correct TypeScript types
const { unsubscribe } = root.subscribe(({ update }) => {
switch (update.someKey) {
case 'removed':
case 'updated':
break;
default:
// check all possible types are exhausted
const shouldExhaustAllTypes: never = update.someKey;
}
});
unsubscribe();

VeskeR marked this conversation as resolved.
Show resolved Hide resolved
// 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();
const counterSubscribeResponse = counter?.subscribe(({ update }) => {
const shouldBeANumber: number = update.inc;
});
counterSubscribeResponse?.unsubscribe();
};
8 changes: 6 additions & 2 deletions test/package/browser/template/src/sandbox.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import testAppSetup from '../../../../common/ably-common/test-resources/test-app-setup.json';

export async function createSandboxAblyAPIKey() {
export async function createSandboxAblyAPIKey(withOptions?: object) {
const postData = {
...testAppSetup.post_apps,
...(withOptions ?? {}),
};
const response = await fetch('https://sandbox-rest.ably.io/apps', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(testAppSetup.post_apps),
body: JSON.stringify(postData),
});

if (!response.ok) {
Expand Down
2 changes: 1 addition & 1 deletion test/package/browser/template/src/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"resolveJsonModule": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"moduleResolution": "node",
"jsx": "react-jsx"
}
}
1 change: 1 addition & 0 deletions test/package/browser/template/test/lib/package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { test, expect } from '@playwright/test';
test.describe('NPM package', () => {
for (const scenario of [
{ name: 'default export', path: '/index-default.html' },
{ name: 'LiveObjects plugin export', path: '/index-liveobjects.html' },
VeskeR marked this conversation as resolved.
Show resolved Hide resolved
{ name: 'modular export', path: '/index-modular.html' },
]) {
test.describe(scenario.name, () => {
Expand Down
Loading