Skip to content

Commit a6731b2

Browse files
committed
Add extensive diamond test coverage
Add 81 new tests across 3 test files covering diamond cut operations (add/replace/remove), all error conditions, ownership transfer and handover ceremonies, role management, MultiInit error paths, ETH handling, and ERC-165 compliance edge cases.
1 parent 10f0a78 commit a6731b2

7 files changed

Lines changed: 931 additions & 31 deletions

File tree

test/DiamondCutTester.t.sol

Lines changed: 508 additions & 0 deletions
Large diffs are not rendered by default.

test/DiamondTester.t.sol

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,36 @@ import {IDiamondLoupe} from "@diamond/interfaces/IDiamondLoupe.sol";
88
import {Facet} from "@diamond/libraries/DiamondLib.sol";
99

1010
/// @title DiamondTester
11-
/// @notice Contains test cases to validate the deployment and structure of the Diamond contract.
12-
/// @dev Inherits setup and state from DeployedDiamondState to interact with the deployed diamond.
11+
/// @notice Validates the structure and integrity of a freshly deployed Diamond
1312
contract DiamondTester is DeployedDiamondState {
14-
/// @notice Verifies that the diamond contract is successfully deployed.
15-
function testDiamondDeployed() public view {
13+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
14+
/* ROUGH — Post-Deployment Verification */
15+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
16+
17+
/// @notice The rough stone has been set — diamond is deployed
18+
function testRough_DiamondDeployed() public view {
1619
assertNotEq(address(diamond), address(0));
1720
}
1821

19-
/// @notice Verifies the diamond owner is set correctly.
20-
function testDiamondOwner() public view {
22+
/// @notice The crown holder is established at deployment
23+
function testRough_OwnerIsSet() public view {
2124
assertEq(ownableRoles.owner(), address(this));
2225
}
2326

24-
/// @notice Checks that the standard facets are deployed and have valid addresses.
25-
/// @dev Expects exactly 3 standard facets: DiamondCut, DiamondLoupe, and OwnableRoles.
26-
function testStandardFacetsDeployed() public view {
27+
/// @notice Exactly 3 standard facets are cut into the rough
28+
function testRough_StandardFacetsDeployed() public view {
2729
assertEq(facetAddresses.length, 3);
2830
for (uint256 i; i < facetAddresses.length; ++i) {
2931
assertNotEq(address(facetAddresses[i]), address(0));
3032
}
3133
}
3234

33-
/// @notice Ensures all function selectors are registered correctly for each facet.
34-
/// @dev Compares generated selectors with those registered in the diamond via facetAddress().
35-
function testSelectorsAreComplete() public {
35+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
36+
/* LOUPE — Inspecting the Cut */
37+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
38+
39+
/// @notice Every expected selector is registered under its facet
40+
function testLoupe_SelectorsAreComplete() public {
3641
for (uint256 i; i < facetAddresses.length; ++i) {
3742
bytes4[] memory fromGenSelectors = _getSelectors(facetNames[i]);
3843
for (uint256 j; j < fromGenSelectors.length; ++j) {
@@ -41,8 +46,8 @@ contract DiamondTester is DeployedDiamondState {
4146
}
4247
}
4348

44-
/// @notice Asserts that all function selectors across all facets are unique.
45-
function testSelectorsAreUnique() public view {
49+
/// @notice No two facets share a selector — every surface is unique
50+
function testLoupe_SelectorsAreUnique() public view {
4651
bytes4[] memory allSelectors = Utils.getAllSelectors(address(diamond));
4752
for (uint256 i; i < allSelectors.length; ++i) {
4853
for (uint256 j = i + 1; j < allSelectors.length; ++j) {
@@ -51,8 +56,8 @@ contract DiamondTester is DeployedDiamondState {
5156
}
5257
}
5358

54-
/// @notice Ensures each selector maps back to the correct facet.
55-
function testSelectorToFacetMappingIsCorrect() public view {
59+
/// @notice Forward mapping: selector → facet is consistent
60+
function testLoupe_SelectorToFacetMapping() public view {
5661
Facet[] memory facetsList = diamondLoupe.facets();
5762
for (uint256 i; i < facetsList.length; ++i) {
5863
for (uint256 j; j < facetsList[i].functionSelectors.length; ++j) {
@@ -63,8 +68,8 @@ contract DiamondTester is DeployedDiamondState {
6368
}
6469
}
6570

66-
/// @notice Ensures facet addresses return the correct function selectors.
67-
function testFacetAddressToSelectorsMappingIsCorrect() public view {
71+
/// @notice Reverse mapping: facet → selectors is consistent
72+
function testLoupe_FacetToSelectorsMapping() public view {
6873
for (uint256 i; i < facetAddresses.length; ++i) {
6974
bytes4[] memory selectors = diamondLoupe.facetFunctionSelectors(facetAddresses[i]);
7075
for (uint256 j; j < selectors.length; ++j) {
@@ -73,23 +78,44 @@ contract DiamondTester is DeployedDiamondState {
7378
}
7479
}
7580

76-
/// @notice Confirms ERC165 interface support.
77-
function testSupportsERC165() public view {
78-
assertTrue(diamondLoupe.supportsInterface(0x01ffc9a7)); // ERC165 interface ID
81+
/// @notice Unregistered facet returns empty selectors
82+
function testLoupe_UnknownFacetReturnsEmpty() public view {
83+
bytes4[] memory selectors = diamondLoupe.facetFunctionSelectors(address(0xDEAD));
84+
assertEq(selectors.length, 0);
85+
}
86+
87+
/// @notice Unregistered selector returns zero address
88+
function testLoupe_UnknownSelectorReturnsZero() public view {
89+
assertEq(diamondLoupe.facetAddress(bytes4(0xdeadbeef)), address(0));
90+
}
91+
92+
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
93+
/* CERTIFIED — ERC-165 Interface Compliance */
94+
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
95+
96+
/// @notice Certified: supports ERC-165 introspection
97+
function testCertified_SupportsERC165() public view {
98+
assertTrue(diamondLoupe.supportsInterface(0x01ffc9a7));
99+
}
100+
101+
/// @notice Certified: supports ERC-173 ownership
102+
function testCertified_SupportsERC173() public view {
103+
assertTrue(diamondLoupe.supportsInterface(0x7f5828d0));
79104
}
80105

81-
/// @notice Confirms ERC173 interface support.
82-
function testSupportsERC173() public view {
83-
assertTrue(diamondLoupe.supportsInterface(0x7f5828d0)); // ERC173 interface ID
106+
/// @notice Certified: supports IDiamondCut
107+
function testCertified_SupportsIDiamondCut() public view {
108+
assertTrue(diamondLoupe.supportsInterface(type(IDiamondCut).interfaceId));
84109
}
85110

86-
/// @notice Confirms IDiamondCut interface support.
87-
function testSupportsIDiamondCut() public view {
88-
assertTrue(diamondLoupe.supportsInterface(type(IDiamondCut).interfaceId)); // IDiamondCut interface ID
111+
/// @notice Certified: supports IDiamondLoupe
112+
function testCertified_SupportsIDiamondLoupe() public view {
113+
assertTrue(diamondLoupe.supportsInterface(type(IDiamondLoupe).interfaceId));
89114
}
90115

91-
/// @notice Confirms IDiamondLoupe interface support.
92-
function testSupportsIDiamondLoupe() public view {
93-
assertTrue(diamondLoupe.supportsInterface(type(IDiamondLoupe).interfaceId)); // IDiamondLoupe interface ID
116+
/// @notice Unregistered interface returns false
117+
function testCertified_UnsupportedInterfaceReturnsFalse() public view {
118+
assertFalse(diamondLoupe.supportsInterface(0xffffffff));
119+
assertFalse(diamondLoupe.supportsInterface(bytes4(0xdeadbeef)));
94120
}
95121
}

0 commit comments

Comments
 (0)