Skip to content

Commit

Permalink
test(e2e): add more test cases (#1074)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: authcall <authcall@proton.me>
Co-authored-by: Kevin Ingersoll <kingersoll@gmail.com>
  • Loading branch information
3 people committed Jul 4, 2023
1 parent 72b8069 commit 086be4e
Show file tree
Hide file tree
Showing 14 changed files with 412 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-candles-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@latticexyz/services": patch
---

fix a bug related to encoding negative bigints in MODE
16 changes: 16 additions & 0 deletions e2e/packages/client-vanilla/src/mud/contractComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,21 @@ export function defineContractComponents(world: World) {
}
);
})(),
Multi: (() => {
const tableId = new TableId("", "Multi");
return defineComponent(
world,
{
num: RecsType.BigInt,
value: RecsType.Boolean,
},
{
metadata: {
contractId: tableId.toHex(),
tableId: tableId.toString(),
},
}
);
})(),
};
}
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",
},
},
},
});
1 change: 1 addition & 0 deletions e2e/packages/contracts/src/codegen/Tables.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ pragma solidity >=0.8.0;
import { Number, NumberTableId } from "./tables/Number.sol";
import { Vector, VectorData, VectorTableId } from "./tables/Vector.sol";
import { NumberList, NumberListTableId } from "./tables/NumberList.sol";
import { Multi, MultiData, MultiTableId } from "./tables/Multi.sol";
284 changes: 284 additions & 0 deletions e2e/packages/contracts/src/codegen/tables/Multi.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/* Autogenerated file. Do not edit manually. */

// Import schema type
import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol";

// Import store internals
import { IStore } from "@latticexyz/store/src/IStore.sol";
import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol";
import { StoreCore } from "@latticexyz/store/src/StoreCore.sol";
import { Bytes } from "@latticexyz/store/src/Bytes.sol";
import { Memory } from "@latticexyz/store/src/Memory.sol";
import { SliceLib } from "@latticexyz/store/src/Slice.sol";
import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol";
import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol";
import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol";

bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Multi")));
bytes32 constant MultiTableId = _tableId;

struct MultiData {
int256 num;
bool value;
}

library Multi {
/** Get the table's schema */
function getSchema() internal pure returns (Schema) {
SchemaType[] memory _schema = new SchemaType[](2);
_schema[0] = SchemaType.INT256;
_schema[1] = SchemaType.BOOL;

return SchemaLib.encode(_schema);
}

function getKeySchema() internal pure returns (Schema) {
SchemaType[] memory _schema = new SchemaType[](4);
_schema[0] = SchemaType.UINT32;
_schema[1] = SchemaType.BOOL;
_schema[2] = SchemaType.UINT256;
_schema[3] = SchemaType.INT120;

return SchemaLib.encode(_schema);
}

/** Get the table's metadata */
function getMetadata() internal pure returns (string memory, string[] memory) {
string[] memory _fieldNames = new string[](2);
_fieldNames[0] = "num";
_fieldNames[1] = "value";
return ("Multi", _fieldNames);
}

/** Register the table's schema */
function registerSchema() internal {
StoreSwitch.registerSchema(_tableId, getSchema(), getKeySchema());
}

/** Register the table's schema (using the specified store) */
function registerSchema(IStore _store) internal {
_store.registerSchema(_tableId, getSchema(), getKeySchema());
}

/** Set the table's metadata */
function setMetadata() internal {
(string memory _tableName, string[] memory _fieldNames) = getMetadata();
StoreSwitch.setMetadata(_tableId, _tableName, _fieldNames);
}

/** Set the table's metadata (using the specified store) */
function setMetadata(IStore _store) internal {
(string memory _tableName, string[] memory _fieldNames) = getMetadata();
_store.setMetadata(_tableId, _tableName, _fieldNames);
}

/** Get num */
function getNum(uint32 a, bool b, uint256 c, int120 d) internal view returns (int256 num) {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 0);
return (int256(uint256(Bytes.slice32(_blob, 0))));
}

/** Get num (using the specified store) */
function getNum(IStore _store, uint32 a, bool b, uint256 c, int120 d) internal view returns (int256 num) {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

bytes memory _blob = _store.getField(_tableId, _keyTuple, 0);
return (int256(uint256(Bytes.slice32(_blob, 0))));
}

/** Set num */
function setNum(uint32 a, bool b, uint256 c, int120 d, int256 num) internal {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((num)));
}

/** Set num (using the specified store) */
function setNum(IStore _store, uint32 a, bool b, uint256 c, int120 d, int256 num) internal {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

_store.setField(_tableId, _keyTuple, 0, abi.encodePacked((num)));
}

/** Get value */
function getValue(uint32 a, bool b, uint256 c, int120 d) internal view returns (bool value) {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 1);
return (_toBool(uint8(Bytes.slice1(_blob, 0))));
}

/** Get value (using the specified store) */
function getValue(IStore _store, uint32 a, bool b, uint256 c, int120 d) internal view returns (bool value) {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

bytes memory _blob = _store.getField(_tableId, _keyTuple, 1);
return (_toBool(uint8(Bytes.slice1(_blob, 0))));
}

/** Set value */
function setValue(uint32 a, bool b, uint256 c, int120 d, bool value) internal {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

StoreSwitch.setField(_tableId, _keyTuple, 1, abi.encodePacked((value)));
}

/** Set value (using the specified store) */
function setValue(IStore _store, uint32 a, bool b, uint256 c, int120 d, bool value) internal {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

_store.setField(_tableId, _keyTuple, 1, abi.encodePacked((value)));
}

/** Get the full data */
function get(uint32 a, bool b, uint256 c, int120 d) internal view returns (MultiData memory _table) {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

bytes memory _blob = StoreSwitch.getRecord(_tableId, _keyTuple, getSchema());
return decode(_blob);
}

/** Get the full data (using the specified store) */
function get(IStore _store, uint32 a, bool b, uint256 c, int120 d) internal view returns (MultiData memory _table) {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

bytes memory _blob = _store.getRecord(_tableId, _keyTuple, getSchema());
return decode(_blob);
}

/** Set the full data using individual values */
function set(uint32 a, bool b, uint256 c, int120 d, int256 num, bool value) internal {
bytes memory _data = encode(num, value);

bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

StoreSwitch.setRecord(_tableId, _keyTuple, _data);
}

/** Set the full data using individual values (using the specified store) */
function set(IStore _store, uint32 a, bool b, uint256 c, int120 d, int256 num, bool value) internal {
bytes memory _data = encode(num, value);

bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

_store.setRecord(_tableId, _keyTuple, _data);
}

/** Set the full data using the data struct */
function set(uint32 a, bool b, uint256 c, int120 d, MultiData memory _table) internal {
set(a, b, c, d, _table.num, _table.value);
}

/** Set the full data using the data struct (using the specified store) */
function set(IStore _store, uint32 a, bool b, uint256 c, int120 d, MultiData memory _table) internal {
set(_store, a, b, c, d, _table.num, _table.value);
}

/** Decode the tightly packed blob using this table's schema */
function decode(bytes memory _blob) internal pure returns (MultiData memory _table) {
_table.num = (int256(uint256(Bytes.slice32(_blob, 0))));

_table.value = (_toBool(uint8(Bytes.slice1(_blob, 32))));
}

/** Tightly pack full data using this table's schema */
function encode(int256 num, bool value) internal view returns (bytes memory) {
return abi.encodePacked(num, value);
}

/** Encode keys as a bytes32 array using this table's schema */
function encodeKeyTuple(uint32 a, bool b, uint256 c, int120 d) internal pure returns (bytes32[] memory _keyTuple) {
_keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));
}

/* Delete all data for given keys */
function deleteRecord(uint32 a, bool b, uint256 c, int120 d) internal {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

StoreSwitch.deleteRecord(_tableId, _keyTuple);
}

/* Delete all data for given keys (using the specified store) */
function deleteRecord(IStore _store, uint32 a, bool b, uint256 c, int120 d) internal {
bytes32[] memory _keyTuple = new bytes32[](4);
_keyTuple[0] = bytes32(uint256(a));
_keyTuple[1] = _boolToBytes32(b);
_keyTuple[2] = bytes32(uint256(c));
_keyTuple[3] = bytes32(uint256(int256(d)));

_store.deleteRecord(_tableId, _keyTuple);
}
}

function _toBool(uint8 value) pure returns (bool result) {
assembly {
result := value
}
}

function _boolToBytes32(bool value) pure returns (bytes32 result) {
assembly {
result := value
}
}
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
8 changes: 4 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, encodePacked } from "viem";
import config from "../../contracts/mud.config";

/**
Expand All @@ -10,9 +10,9 @@ 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]) => {
return encodeAbiParameters([{ type: config.tables[table].keySchema[keyName] }], [keyValue]);
}),
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
Loading

0 comments on commit 086be4e

Please sign in to comment.