@@ -900,3 +900,352 @@ func TestForkMode_AutodetectFailureRequiresExplicitNetwork(t *testing.T) {
900900 require .Error (t , err )
901901 assert .ErrorContains (t , err , "failed to get chain ID from fork host" )
902902}
903+
904+ func TestNetworkForkResolution_Success (t * testing.T ) {
905+ t .Parallel ()
906+
907+ _ , state , _ := util .TestMocks (t )
908+
909+ // Add mainnet network with a host
910+ state .Networks ().AddOrUpdate (config.Network {
911+ Name : "mainnet" ,
912+ Host : "access.mainnet.nodes.onflow.org:9000" ,
913+ })
914+
915+ // Add mainnet-fork that references mainnet via Fork field (no host)
916+ state .Networks ().AddOrUpdate (config.Network {
917+ Name : "mainnet-fork" ,
918+ Fork : "mainnet" ,
919+ })
920+
921+ // Create a simple test that uses the test_fork pragma
922+ testScript := []byte (`
923+ #test_fork(network: "mainnet-fork", height: nil)
924+
925+ import Test
926+
927+ access(all) fun testSimple() {
928+ Test.assert(true)
929+ }
930+ ` )
931+
932+ testFiles := map [string ][]byte {
933+ "test_fork_resolution.cdc" : testScript ,
934+ }
935+
936+ result , err := testCode (testFiles , state , flagsTests {})
937+
938+ require .NoError (t , err )
939+ require .Len (t , result .Results , 1 )
940+ assert .NoError (t , result .Results ["test_fork_resolution.cdc" ][0 ].Error )
941+ }
942+
943+ func TestNetworkForkResolution_ForkNetworkNotFound (t * testing.T ) {
944+ t .Parallel ()
945+
946+ _ , state , _ := util .TestMocks (t )
947+
948+ // Add mainnet-fork that references non-existent network
949+ state .Networks ().AddOrUpdate (config.Network {
950+ Name : "mainnet-fork" ,
951+ Fork : "nonexistent" ,
952+ })
953+
954+ // Create a simple test that uses the fork network
955+ testScript := []byte (`
956+ #test_fork(network: "mainnet-fork", height: nil)
957+
958+ import Test
959+
960+ access(all) fun testSimple() {
961+ Test.assert(true)
962+ }
963+ ` )
964+
965+ testFiles := map [string ][]byte {
966+ "test_fork_missing.cdc" : testScript ,
967+ }
968+
969+ _ , err := testCode (testFiles , state , flagsTests {})
970+
971+ require .Error (t , err )
972+ assert .ErrorContains (t , err , "could not resolve network" )
973+ }
974+
975+ func TestNetworkForkResolution_ForkNetworkHasNoHost (t * testing.T ) {
976+ t .Parallel ()
977+
978+ _ , state , _ := util .TestMocks (t )
979+
980+ // Add mainnet network with no host
981+ state .Networks ().AddOrUpdate (config.Network {
982+ Name : "mainnet" ,
983+ })
984+
985+ // Add mainnet-fork that references mainnet with no host
986+ state .Networks ().AddOrUpdate (config.Network {
987+ Name : "mainnet-fork" ,
988+ Fork : "mainnet" ,
989+ })
990+
991+ // Create a simple test that uses the fork network
992+ testScript := []byte (`
993+ #test_fork(network: "mainnet-fork", height: nil)
994+
995+ import Test
996+
997+ access(all) fun testSimple() {
998+ Test.assert(true)
999+ }
1000+ ` )
1001+
1002+ testFiles := map [string ][]byte {
1003+ "test_fork_no_host.cdc" : testScript ,
1004+ }
1005+
1006+ _ , err := testCode (testFiles , state , flagsTests {})
1007+
1008+ // Should fail with network resolution error
1009+ require .Error (t , err )
1010+ assert .ErrorContains (t , err , "network resolver could not resolve network" )
1011+ }
1012+
1013+ func TestNetworkForkResolution_WithOwnHost (t * testing.T ) {
1014+ t .Parallel ()
1015+
1016+ _ , state , _ := util .TestMocks (t )
1017+
1018+ // Add mainnet network
1019+ state .Networks ().AddOrUpdate (config.Network {
1020+ Name : "mainnet" ,
1021+ Host : "access.mainnet.nodes.onflow.org:9000" ,
1022+ })
1023+
1024+ // Add mainnet-fork with its own host AND fork field
1025+ // Should use mainnet's host (from Fork) not its own
1026+ state .Networks ().AddOrUpdate (config.Network {
1027+ Name : "mainnet-fork" ,
1028+ Host : "127.0.0.1:3569" ,
1029+ Fork : "mainnet" ,
1030+ })
1031+
1032+ // Create a simple test that uses the fork network
1033+ testScript := []byte (`
1034+ #test_fork(network: "mainnet-fork", height: nil)
1035+
1036+ import Test
1037+
1038+ access(all) fun testSimple() {
1039+ Test.assert(true)
1040+ }
1041+ ` )
1042+
1043+ testFiles := map [string ][]byte {
1044+ "test_fork_with_host.cdc" : testScript ,
1045+ }
1046+
1047+ result , err := testCode (testFiles , state , flagsTests {})
1048+
1049+ require .NoError (t , err )
1050+ require .Len (t , result .Results , 1 )
1051+ assert .NoError (t , result .Results ["test_fork_with_host.cdc" ][0 ].Error )
1052+ }
1053+
1054+ func TestContractAddressForkResolution_UsesMainnetForkFirst (t * testing.T ) {
1055+ t .Parallel ()
1056+
1057+ _ , state , _ := util .TestMocks (t )
1058+
1059+ // Add mainnet network
1060+ state .Networks ().AddOrUpdate (config.Network {
1061+ Name : "mainnet" ,
1062+ Host : "access.mainnet.nodes.onflow.org:9000" ,
1063+ })
1064+
1065+ // Add mainnet-fork network
1066+ state .Networks ().AddOrUpdate (config.Network {
1067+ Name : "mainnet-fork" ,
1068+ Host : "127.0.0.1:3569" ,
1069+ Fork : "mainnet" ,
1070+ })
1071+
1072+ // Contract with mainnet-fork specific alias (using proper mainnet-style address)
1073+ mainnetForkAddr := flowsdk .HexToAddress ("0x1654653399040a61" )
1074+ contractSource := []byte (`
1075+ access(all) contract TestContract {
1076+ access(all) var value: Int
1077+ init() { self.value = 42 }
1078+ }
1079+ ` )
1080+ _ = state .ReaderWriter ().WriteFile ("TestContract.cdc" , contractSource , 0644 )
1081+
1082+ c := config.Contract {
1083+ Name : "TestContract" ,
1084+ Location : "TestContract.cdc" ,
1085+ Aliases : config.Aliases {
1086+ {
1087+ Network : "mainnet-fork" ,
1088+ Address : mainnetForkAddr ,
1089+ },
1090+ },
1091+ }
1092+ state .Contracts ().AddOrUpdate (c )
1093+
1094+ testScript := []byte (`
1095+ #test_fork(network: "mainnet-fork", height: nil)
1096+
1097+ import Test
1098+ import "TestContract"
1099+
1100+ access(all) fun testUsesMainnetForkAddress() {
1101+ // Verify TestContract resolves to the mainnet-fork address
1102+ let addr = Type<TestContract>().address!
1103+ Test.assertEqual(0x1654653399040a61 as Address, addr)
1104+ }
1105+ ` )
1106+
1107+ testFiles := map [string ][]byte {
1108+ "test_mainnet_fork_addr.cdc" : testScript ,
1109+ }
1110+
1111+ result , err := testCode (testFiles , state , flagsTests {})
1112+
1113+ require .NoError (t , err )
1114+ require .Len (t , result .Results , 1 )
1115+ assert .NoError (t , result .Results ["test_mainnet_fork_addr.cdc" ][0 ].Error )
1116+ }
1117+
1118+ func TestContractAddressForkResolution_FallbackToMainnet (t * testing.T ) {
1119+ t .Parallel ()
1120+
1121+ _ , state , _ := util .TestMocks (t )
1122+
1123+ // Add mainnet network
1124+ state .Networks ().AddOrUpdate (config.Network {
1125+ Name : "mainnet" ,
1126+ Host : "access.mainnet.nodes.onflow.org:9000" ,
1127+ })
1128+
1129+ // Add mainnet-fork network
1130+ state .Networks ().AddOrUpdate (config.Network {
1131+ Name : "mainnet-fork" ,
1132+ Host : "127.0.0.1:3569" ,
1133+ Fork : "mainnet" ,
1134+ })
1135+
1136+ // Contract with ONLY mainnet alias (no mainnet-fork alias)
1137+ mainnetAddr := flowsdk .HexToAddress ("0xf233dcee88fe0abe" )
1138+ contractSource := []byte (`
1139+ access(all) contract TestContract {
1140+ access(all) var value: Int
1141+ init() { self.value = 99 }
1142+ }
1143+ ` )
1144+ _ = state .ReaderWriter ().WriteFile ("TestContract.cdc" , contractSource , 0644 )
1145+
1146+ c := config.Contract {
1147+ Name : "TestContract" ,
1148+ Location : "TestContract.cdc" ,
1149+ Aliases : config.Aliases {
1150+ {
1151+ Network : "mainnet" ,
1152+ Address : mainnetAddr ,
1153+ },
1154+ },
1155+ }
1156+ state .Contracts ().AddOrUpdate (c )
1157+
1158+ testScript := []byte (`
1159+ #test_fork(network: "mainnet-fork", height: nil)
1160+
1161+ import Test
1162+ import "TestContract"
1163+
1164+ access(all) fun testFallbackToMainnetAddress() {
1165+ // Verify TestContract falls back to mainnet address since mainnet-fork has no alias
1166+ let addr = Type<TestContract>().address!
1167+ Test.assertEqual(0xf233dcee88fe0abe as Address, addr)
1168+ }
1169+ ` )
1170+
1171+ testFiles := map [string ][]byte {
1172+ "test_fallback_mainnet.cdc" : testScript ,
1173+ }
1174+
1175+ result , err := testCode (testFiles , state , flagsTests {})
1176+
1177+ require .NoError (t , err )
1178+ require .Len (t , result .Results , 1 )
1179+ assert .NoError (t , result .Results ["test_fallback_mainnet.cdc" ][0 ].Error )
1180+ }
1181+
1182+ func TestContractAddressForkResolution_PrioritizesForkOverParent (t * testing.T ) {
1183+ t .Parallel ()
1184+
1185+ _ , state , _ := util .TestMocks (t )
1186+
1187+ // Add mainnet network
1188+ state .Networks ().AddOrUpdate (config.Network {
1189+ Name : "mainnet" ,
1190+ Host : "access.mainnet.nodes.onflow.org:9000" ,
1191+ })
1192+
1193+ // Add mainnet-fork network
1194+ state .Networks ().AddOrUpdate (config.Network {
1195+ Name : "mainnet-fork" ,
1196+ Host : "127.0.0.1:3569" ,
1197+ Fork : "mainnet" ,
1198+ })
1199+
1200+ // Contract with BOTH mainnet and mainnet-fork aliases - should use mainnet-fork first
1201+ mainnetAddr := flowsdk .HexToAddress ("0x1654653399040a61" )
1202+ mainnetForkAddr := flowsdk .HexToAddress ("0xf233dcee88fe0abe" )
1203+
1204+ contractSource := []byte (`
1205+ access(all) contract TestContract {
1206+ access(all) var value: Int
1207+ init() { self.value = 123 }
1208+ }
1209+ ` )
1210+ _ = state .ReaderWriter ().WriteFile ("TestContract.cdc" , contractSource , 0644 )
1211+
1212+ c := config.Contract {
1213+ Name : "TestContract" ,
1214+ Location : "TestContract.cdc" ,
1215+ Aliases : config.Aliases {
1216+ {
1217+ Network : "mainnet" ,
1218+ Address : mainnetAddr ,
1219+ },
1220+ {
1221+ Network : "mainnet-fork" ,
1222+ Address : mainnetForkAddr ,
1223+ },
1224+ },
1225+ }
1226+ state .Contracts ().AddOrUpdate (c )
1227+
1228+ // Should use the mainnet-fork address (0xf233dcee88fe0abe), not mainnet (0x1654653399040a61)
1229+ testScript := []byte (`
1230+ #test_fork(network: "mainnet-fork", height: nil)
1231+
1232+ import Test
1233+ import "TestContract"
1234+
1235+ access(all) fun testPrioritizesFork() {
1236+ // Verify TestContract uses mainnet-fork address (0xf233dcee88fe0abe), NOT mainnet (0x1654653399040a61)
1237+ let addr = Type<TestContract>().address!
1238+ Test.assertEqual(0xf233dcee88fe0abe as Address, addr)
1239+ }
1240+ ` )
1241+
1242+ testFiles := map [string ][]byte {
1243+ "test_priority.cdc" : testScript ,
1244+ }
1245+
1246+ result , err := testCode (testFiles , state , flagsTests {})
1247+
1248+ require .NoError (t , err )
1249+ require .Len (t , result .Results , 1 )
1250+ assert .NoError (t , result .Results ["test_priority.cdc" ][0 ].Error )
1251+ }
0 commit comments