Skip to content

Commit 9cb323e

Browse files
Move web tests into lib (which is what they test) (#145)
* Fold tests/ into lib/, which is what it tests * Update cache key to invalidate cache * Remove branch restriction for GH workflow This allows for stacking of PRs
1 parent 5461369 commit 9cb323e

File tree

12 files changed

+247
-1240
lines changed

12 files changed

+247
-1240
lines changed

.github/workflows/web_build_and_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ jobs:
2727

2828
- name: Run all tests
2929
working-directory: ./web
30-
run: npm run test --workspace=tests
30+
run: npm run test --workspace=lib

web/lib/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"service": true
4848
},
4949
"test": {
50-
"command": "node --test --enable-source-maps --test-reporter spec dist/src/0.8/tests/**/*.test.js",
50+
"command": "node --test --enable-source-maps --test-reporter spec dist/src/0.8/*.test.js",
5151
"dependencies": [
5252
"build"
5353
]
@@ -94,6 +94,7 @@
9494
"homepage": "https://github.com/google/A2UI/tree/main/web#readme",
9595
"devDependencies": {
9696
"@types/markdown-it": "^14.1.2",
97+
"@types/node": "^24.10.1",
9798
"typescript": "^5.8.3",
9899
"wireit": "^0.15.0-pre.2"
99100
},

web/lib/src/0.8/data/guards.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,13 @@ import {
3737
ResolvedText,
3838
ResolvedTextField,
3939
ResolvedVideo,
40+
ValueMap,
4041
} from "../types/types";
4142

43+
export function isValueMap(value: unknown): value is ValueMap {
44+
return isObject(value) && "key" in value;
45+
}
46+
4247
export function isPath(key: string, value: unknown): value is string {
4348
return key === "path" && typeof value === "string";
4449
}

web/lib/src/0.8/data/model-processor.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import {
2929
SurfaceID,
3030
SurfaceUpdateMessage,
3131
ModelProcessor,
32+
ValueMap,
33+
DataObject,
3234
} from "../types/types";
3335
import {
3436
isComponentArrayReference,
@@ -52,6 +54,7 @@ import {
5254
isResolvedText,
5355
isResolvedTextField,
5456
isResolvedVideo,
57+
isValueMap,
5558
} from "./guards.js";
5659

5760
/**
@@ -423,7 +426,11 @@ export class A2UIModelProcessor implements ModelProcessor {
423426
#handleDataModelUpdate(message: DataModelUpdate, surfaceId: SurfaceID): void {
424427
const surface = this.#getOrCreateSurface(surfaceId);
425428
const path = message.path ?? "/";
426-
this.#setDataByPath(surface.dataModel, path, message.contents);
429+
this.#setDataByPath(
430+
surface.dataModel,
431+
path,
432+
message.contents
433+
);
427434
this.#rebuildComponentTree(surface);
428435
}
429436

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import assert from "node:assert";
1818
import { describe, it, beforeEach } from "node:test";
1919
import { v0_8 } from "@a2ui/web-lib";
20+
import {DataMap, DataValue} from "./types/types";
2021

2122
// Helper function to strip reactivity for clean comparisons.
2223
const toPlainObject = (value: unknown): ReturnType<typeof JSON.parse> => {
@@ -87,8 +88,8 @@ describe("A2UIModelProcessor", () => {
8788

8889
const defaultSurface = surfaces.get("@default");
8990
assert.ok(defaultSurface, "Default surface should exist");
90-
assert.strictEqual(defaultSurface.rootComponentId, "comp-a");
91-
assert.deepStrictEqual(defaultSurface.styles, { color: "blue" });
91+
assert.strictEqual(defaultSurface!.rootComponentId, "comp-a");
92+
assert.deepStrictEqual(defaultSurface!.styles, { color: "blue" });
9293
});
9394

9495
it("should handle `surfaceUpdate` by adding components", () => {
@@ -112,8 +113,8 @@ describe("A2UIModelProcessor", () => {
112113
if (!surface) {
113114
assert.fail("No default surface");
114115
}
115-
assert.strictEqual(surface.components.size, 1);
116-
assert.ok(surface.components.has("comp-a"));
116+
assert.strictEqual(surface!.components.size, 1);
117+
assert.ok(surface!.components.has("comp-a"));
117118
});
118119

119120
it("should handle `deleteSurface`", () => {
@@ -290,10 +291,7 @@ describe("A2UIModelProcessor", () => {
290291
);
291292

292293
// Check that it's a Map and has the first item.
293-
assert.ok(
294-
messagesData instanceof Map,
295-
"Data at /messages should be a Map"
296-
);
294+
assertIsDataMap(messagesData);
297295
assert.strictEqual(messagesData.size, 1);
298296
assert.strictEqual(messagesData.get(key1), message1);
299297

@@ -322,13 +320,10 @@ describe("A2UIModelProcessor", () => {
322320
);
323321

324322
// 4. Check that the Map was additively updated and now has both items.
325-
assert.ok(
326-
messagesData instanceof Map,
327-
"Data at /messages should still be a Map"
328-
);
323+
assertIsDataMap(messagesData);
329324
assert.strictEqual(messagesData.size, 2, "Map should have 2 items total");
330325
assert.strictEqual(
331-
messagesData.get(key1),
326+
(messagesData as DataMap).get(key1),
332327
message1,
333328
"First item correct"
334329
);
@@ -1311,26 +1306,32 @@ describe("A2UIModelProcessor", () => {
13111306
assert.ok(surfaceA && surfaceB, "Both surfaces should exist");
13121307

13131308
// Check Surface A
1314-
assert.strictEqual(surfaceA.components.size, 1);
1315-
assert.ok(surfaceA.components.has("comp-a"));
1316-
assert.deepStrictEqual(toPlainObject(surfaceA.dataModel), {
1309+
assert.ok(surfaceA, "Surface A exists.");
1310+
assert.strictEqual(surfaceA!.components.size, 1);
1311+
assert.ok(surfaceA!.components.has("comp-a"));
1312+
assert.deepStrictEqual(toPlainObject(surfaceA!.dataModel), {
13171313
name: "Surface A Data",
13181314
});
13191315
assert.deepStrictEqual(
1320-
toPlainObject(surfaceA.componentTree).properties.text,
1316+
toPlainObject(surfaceA!.componentTree).properties.text,
13211317
{ path: "/name" }
13221318
);
13231319

13241320
// Check Surface B
1325-
assert.strictEqual(surfaceB.components.size, 1);
1326-
assert.ok(surfaceB.components.has("comp-b"));
1327-
assert.deepStrictEqual(toPlainObject(surfaceB.dataModel), {
1321+
assert.ok(surfaceB, "Surface B exists.");
1322+
assert.strictEqual(surfaceB!.components.size, 1);
1323+
assert.ok(surfaceB!.components.has("comp-b"));
1324+
assert.deepStrictEqual(toPlainObject(surfaceB!.dataModel), {
13281325
name: "Surface B Data",
13291326
});
13301327
assert.deepStrictEqual(
1331-
toPlainObject(surfaceB.componentTree).properties.text,
1328+
toPlainObject(surfaceB!.componentTree).properties.text,
13321329
{ path: "/name" }
13331330
);
13341331
});
13351332
});
13361333
});
1334+
1335+
function assertIsDataMap(obj: DataValue): asserts obj is DataMap {
1336+
assert.ok(obj instanceof Map, `Data should be a DataMap`);
1337+
}

web/lib/src/0.8/types/types.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -263,19 +263,17 @@ export interface SurfaceUpdateMessage {
263263
export interface DataModelUpdate {
264264
surfaceId: string;
265265
path?: string;
266-
contents: {
267-
key: string;
268-
valueString?: string /** May be JSON */;
269-
valueNumber?: number;
270-
valueBoolean?: boolean;
271-
272-
valueMap?: {
273-
key: string;
274-
valueString?: string /** May be JSON */;
275-
valueNumber?: number;
276-
valueBoolean?: boolean;
277-
}[];
278-
}[];
266+
contents: ValueMap[];
267+
}
268+
269+
// ValueMap is a type of DataObject for passing to the data model.
270+
export type ValueMap = DataObject & {
271+
key: string;
272+
/** May be JSON */
273+
valueString?: string;
274+
valueNumber?: number;
275+
valueBoolean?: boolean;
276+
valueMap?: ValueMap[];
279277
}
280278

281279
export interface DeleteSurfaceMessage {

web/lib/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"noUnusedLocals": false,
3131
"noUnusedParameters": true,
3232
"noFallthroughCasesInSwitch": true,
33-
"types": []
33+
"types": ["node"]
3434
},
3535
"include": ["src/**/*.ts"]
3636
}

0 commit comments

Comments
 (0)