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

test(e2e): add more test cases #1074

Merged
merged 12 commits into from
Jul 4, 2023
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
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]);
}),
alvrs marked this conversation as resolved.
Show resolved Hide resolved
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