Skip to content

Commit

Permalink
test(world): add test to ensure all store/world tables are registered (
Browse files Browse the repository at this point in the history
  • Loading branch information
tash-2s authored Jan 2, 2024
1 parent 5905420 commit de05c33
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/world/foundry.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[profile.default]
solc = "0.8.21"
ffi = false
ffi = true
fuzz_runs = 256
optimizer = true
optimizer_runs = 3000
Expand Down
70 changes: 70 additions & 0 deletions packages/world/test/CoreModule.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.21;

import { Test } from "forge-std/Test.sol";

import { StoreRead } from "@latticexyz/store/src/StoreRead.sol";
import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol";
import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";
import { Tables } from "@latticexyz/store/src/codegen/index.sol";

import { WorldContextProviderLib } from "../src/WorldContext.sol";
import { CoreModule } from "../src/modules/core/CoreModule.sol";

contract WorldMock is StoreRead {
constructor() {
StoreSwitch.setStoreAddress(address(this));
}

function delegatecallFromWorld(address target, bytes memory callData) public {
WorldContextProviderLib.delegatecallWithContextOrRevert({
msgSender: msg.sender,
msgValue: 0,
target: target,
callData: callData
});
}
}

contract CoreModuleTest is Test {
CoreModule coreModule;
WorldMock worldMock;

function setUp() public {
coreModule = new CoreModule();
worldMock = new WorldMock();
StoreSwitch.setStoreAddress(address(worldMock));
}

function testInstallRoot() public {
// Prepare tableIds for registration validation
bytes32[] memory tableIds = getTableIdsFromStoreAndWorldConfigs();

// Invoke installRoot
worldMock.delegatecallFromWorld(address(coreModule), abi.encodeCall(CoreModule.installRoot, (new bytes(0))));

// Confirm that each tableId is registered
for (uint256 i; i < tableIds.length; i++) {
bytes32 tableId = tableIds[i];
assertFalse(
Tables.getFieldLayout(ResourceId.wrap(tableId)).isEmpty(),
string.concat("table should be registered: ", string(abi.encodePacked(tableId)))
);
}
}

function getTableIdsFromStoreAndWorldConfigs() private returns (bytes32[] memory) {
string[] memory ffiInputs = new string[](3);
ffiInputs[0] = "pnpm";
ffiInputs[1] = "tsx";
ffiInputs[2] = "ts/scripts/list-tables-from-store-and-world-configs.ts";

bytes memory ffiOutput = vm.ffi(ffiInputs);

// The JSONPath `$[*].id` selects the `id` of all elements in the root array
bytes memory encoded = vm.parseJson(string(ffiOutput), "$[*].id");
bytes32[] memory tableIds = abi.decode(encoded, (bytes32[]));

return tableIds;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { type Hex } from "viem";

import { type ExpandMUDUserConfig } from "@latticexyz/store/register";
import { type MUDCoreUserConfig } from "@latticexyz/config";

import { resourceToHex } from "@latticexyz/common";

import storeConfig from "@latticexyz/store/mud.config";
import worldConfig from "../../mud.config";

function configToTables<T extends MUDCoreUserConfig>(config: ExpandMUDUserConfig<T>): { name: string; id: Hex }[] {
return Object.entries(config.tables)
.filter(([_, table]) => !table.tableIdArgument) // Skip generic tables
.map(([name, table]) => ({
name: name,
id: resourceToHex({
type: table.offchainOnly ? "offchainTable" : "table",
namespace: config.namespace,
name: table.name,
}),
}));
}

console.log(JSON.stringify([...configToTables(storeConfig), ...configToTables(worldConfig)]));

0 comments on commit de05c33

Please sign in to comment.