Skip to content

Commit

Permalink
add more test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
alvrs committed Jun 26, 2023
1 parent 96eb8e5 commit 4515913
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 10 deletions.
12 changes: 12 additions & 0 deletions e2e/packages/contracts/mud.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,17 @@ export default mudConfig({
value: "uint32[]",
},
},
Multi: {
keySchema: {
a: "uint32",
b: "bool",
c: "uint256",
d: "int120",
},
schema: {
num: "int256",
value: "bool",
},
},
},
});
6 changes: 5 additions & 1 deletion e2e/packages/sync-test/data/callWorld.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ type Args<Method extends keyof IWorld> = IWorld[Method] extends (...args: any) =
export function callWorld<Method extends keyof IWorld>(page: Page, method: Method, args: Args<Method>) {
return page.evaluate(
([_method, _args]) => {
return window["worldSend"](_method, _args).then((tx) => tx.wait());
return window["worldSend"](_method, _args)
.then((tx) => tx.wait())
.catch((e) => {
throw new Error([`Error executing ${_method} with args:`, JSON.stringify(_args), e].join("\n\n"));
});
},
[method, args]
);
Expand Down
2 changes: 1 addition & 1 deletion e2e/packages/sync-test/data/encodeTestData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
import { encodeTestData } from "./encodeTestData";

describe("encodeTestData", () => {
it("should encode test data", () => {
it("should encode numbers", () => {
expect(encodeTestData({ Number: [{ key: { key: 42 }, value: { value: 1337 } }] })).toStrictEqual({
Number: [{ key: ["0x000000000000000000000000000000000000000000000000000000000000002a"], value: "0x00000539" }],
});
Expand Down
12 changes: 8 additions & 4 deletions e2e/packages/sync-test/data/encodeTestData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { mapObject } from "@latticexyz/utils";
import { Data, EncodedData } from "./types";
import { encodeAbiParameters, toHex, encodePacked } from "viem";
import { encodeAbiParameters, toHex, encodePacked, numberToHex } from "viem";
import config from "../../contracts/mud.config";

/**
Expand All @@ -10,9 +10,13 @@ export function encodeTestData(testData: Data) {
return mapObject(testData, (records, table) =>
records
? records.map((record) => ({
key: Object.values(record.key).map((key) =>
encodeAbiParameters([{ type: "bytes32" }], [toHex(key as any, { size: 32 })])
),
key: Object.entries(record.key).map(([keyName, keyValue]) => {
const signed = config.tables[table].keySchema[keyName]?.startsWith("int");
return encodeAbiParameters(
[{ type: "bytes32" }],
[signed ? numberToHex(keyValue as any, { size: 32, signed }) : toHex(keyValue as any, { size: 32 })]
);
}),
value: encodePacked(Object.values(config.tables[table].schema), Object.values(record.value)),
}))
: undefined
Expand Down
3 changes: 2 additions & 1 deletion e2e/packages/sync-test/data/mergeTestData.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { mapObject } from "@latticexyz/utils";
import { Data, Datum } from "./types";
import { serialize } from "./utils";

/**
* Merges an array of test data by merging and filtering the records for each table,
Expand All @@ -12,7 +13,7 @@ export function mergeTestData(...testDatas: Data[]) {
for (const [table, records] of Object.entries(testData)) {
recordsByTableByKeys[table] ??= {};
for (const record of records) {
recordsByTableByKeys[table][JSON.stringify(record.key)] = record;
recordsByTableByKeys[table][serialize(record.key)] = record;
}
}
}
Expand Down
44 changes: 41 additions & 3 deletions e2e/packages/sync-test/data/readClientStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,53 @@ import { Page } from "@playwright/test";

// Extract the storeCache type directly from the client
import { setup } from "../../client-vanilla/src/mud/setup";
import { deserialize, serialize } from "./utils";
type StoreCache = Awaited<ReturnType<typeof setup>>["network"]["storeCache"];

/**
* Read an individual record from the client's data store.
* This is necessary because `page.evaluate` can only transmit serialisable data,
* so we can't just return the entire client store (which includes functions to read data)
*/
export async function readClientStore(page: Page, selector: Parameters<StoreCache["get"]>): Promise<StoreCache> {
return page.evaluate((_selector) => {
return window["storeCache"].get(..._selector);
export async function readClientStore(
page: Page,
[namespace, table, key]: Parameters<StoreCache["get"]>
): Promise<Record<string, unknown> | undefined> {
const selector = [namespace, table, serialize(key)];
const serializedValue = await page.evaluate((_selector) => {
const [_namespace, _table, _key] = _selector;
const result = window["storeCache"].get(_namespace, _table, deserialize(_key));
return result ? serialize(result) : undefined;

/**
* Helper to serialize values that are not natively serializable and therefore not transferrable to the page
* For now only `bigint` needs serialization.
*/
function serialize(obj: unknown): string {
return JSON.stringify(obj, (_, v) => (typeof v === "bigint" ? `bigint(${v.toString()})` : v));
}

/**
* Helper to deserialize values that were serialized by `serialize` (because they are not natively serializable).
* For now only `bigint` is serialized and need to be deserialized here.
*/
function deserialize(blob: string): Record<string, unknown> {
const obj = JSON.parse(blob);

// Check whether the value matches the mattern `${number}n`
// (serialization of bigint in `serialize`)
// and turn it back into a bigint
const regex = /^bigint\((.*)\)$/; // Regular expression pattern.
for (const [key, value] of Object.entries(obj)) {
const match = typeof value === "string" && value.match(regex); // Attempt to match the pattern.
if (match) {
obj[key] = BigInt(match[1]);
}
}

return obj;
}
}, selector);

return serializedValue ? deserialize(serializedValue) : undefined;
}
16 changes: 16 additions & 0 deletions e2e/packages/sync-test/data/testData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import { Data } from "./types";
export const testData1 = {
Number: [{ key: { key: 1 }, value: { value: 42 } }],
Vector: [{ key: { key: 1 }, value: { x: 1, y: 2 } }],
Multi: [
{
key: { a: 9999, b: true, c: BigInt(42), d: BigInt(-999) },
value: { num: BigInt(1337), value: true },
},
],
} satisfies Data;

export const testData2 = {
Expand All @@ -18,4 +24,14 @@ export const testData2 = {
{ key: { key: 1 }, value: { x: 1, y: 42 } },
{ key: { key: 32 }, value: { x: 1, y: -42 } },
],
Multi: [
{
key: { a: 9999, b: true, c: BigInt(42), d: BigInt(-999) },
value: { num: BigInt(31337), value: false },
},
{
key: { a: 9998, b: true, c: BigInt(42), d: BigInt(-999) },
value: { num: BigInt(0), value: true },
},
],
} satisfies Data;
28 changes: 28 additions & 0 deletions e2e/packages/sync-test/data/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* Helper to serialize values that are not natively serializable and therefore not transferrable to the page
* For now only `bigint` needs serialization.
*/
export function serialize(obj: unknown): string {
return JSON.stringify(obj, (_, v) => (typeof v === "bigint" ? `bigint(${v.toString()})` : v));
}

/**
* Helper to deserialize values that were serialized by `serialize` (because they are not natively serializable).
* For now only `bigint` is serialized and need to be deserialized here.
*/
export function deserialize(blob: string): Record<string, unknown> {
const obj = JSON.parse(blob);

// Check whether the value matches the mattern `${number}n`
// (serialization of bigint in `serialize`)
// and turn it back into a bigint
const regex = /^bigint\((.*)\)$/; // Regular expression pattern.
for (const [key, value] of Object.entries(obj)) {
const match = typeof value === "string" && value.match(regex); // Attempt to match the pattern.
if (match) {
obj[key] = BigInt(match[1]);
}
}

return obj;
}

0 comments on commit 4515913

Please sign in to comment.