This commit is contained in:
parent
33c68c2f44
commit
749f525f83
44 changed files with 5380 additions and 3532 deletions
93
tests/ShouldParseEurcChains/main.cpp
Normal file
93
tests/ShouldParseEurcChains/main.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
catcrafts.net
|
||||
Copyright (C) 2026 Catcrafts
|
||||
|
||||
The source code of this website is made available for viewing purposes only.
|
||||
No permission is granted to copy, modify, distribute, or create derivative works.
|
||||
*/
|
||||
|
||||
// The EURC rail's two parsers.
|
||||
//
|
||||
// The balance decoder is the line between "the buyer paid" and "the node
|
||||
// errored", and the chains parser is the line between "watching a chain"
|
||||
// and "silently not watching it". Both refuse rather than guess.
|
||||
|
||||
import std;
|
||||
import Catcrafts.Shared;
|
||||
import Catcrafts.Server;
|
||||
|
||||
using namespace Catcrafts;
|
||||
|
||||
namespace {
|
||||
|
||||
int failures = 0;
|
||||
|
||||
void Check(bool ok, std::string_view what, std::string_view got = {}) {
|
||||
if (ok) return;
|
||||
++failures;
|
||||
std::println(std::cerr, "FAIL: {}{}{}", what,
|
||||
got.empty() ? "" : " got: ", got);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
using Server::ParseEthCallUint;
|
||||
Check(ParseEthCallUint(R"({"jsonrpc":"2.0","id":1,"result":"0x0"})") == 0,
|
||||
"eurc: zero balance");
|
||||
Check(ParseEthCallUint(
|
||||
R"({"jsonrpc":"2.0","id":1,"result":"0x0000000000000000000000000000000000000000000000000000000022001230"})")
|
||||
== 570430000,
|
||||
"eurc: €570.43 as 6-decimal base units, full 32-byte word");
|
||||
Check(ParseEthCallUint(R"({"result":"0xFF"})") == 255,
|
||||
"eurc: uppercase hex accepted");
|
||||
// 2^63 does not fit; the decoder must saturate, never wrap to negative.
|
||||
Check(ParseEthCallUint(R"({"result":"0x8000000000000000"})")
|
||||
== std::numeric_limits<std::int64_t>::max(),
|
||||
"eurc: overflow saturates");
|
||||
Check(!ParseEthCallUint(
|
||||
R"({"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"x"}})")
|
||||
.has_value(),
|
||||
"eurc: an RPC error is not a zero balance");
|
||||
Check(!ParseEthCallUint(R"({"result":"21ff361c"})").has_value(),
|
||||
"eurc: missing 0x rejected");
|
||||
Check(!ParseEthCallUint(R"({"result":"0x"})").has_value(),
|
||||
"eurc: empty word rejected");
|
||||
Check(!ParseEthCallUint(R"({"result":42})").has_value(),
|
||||
"eurc: numeric result rejected — the wire type is a hex string");
|
||||
Check(!ParseEthCallUint("garbage").has_value(), "eurc: malformed payload");
|
||||
|
||||
const auto chains = Server::ParseEurcChains(R"({"chains":[
|
||||
{"name":"base","rpc":"https://mainnet.base.org",
|
||||
"contract":"0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42",
|
||||
"chain_id":8453,"note":"lowest fees"},
|
||||
{"name":"ethereum","rpc":"https://ethereum-rpc.publicnode.com",
|
||||
"contract":"0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c","chain_id":1}]})");
|
||||
Check(chains.has_value() && chains->size() == 2, "eurc: chains file parses");
|
||||
if (chains && chains->size() == 2) {
|
||||
Check((*chains)[0].name == "base" && (*chains)[0].chainId == 8453,
|
||||
"eurc: file order preserved — first entry is the recommendation");
|
||||
Check((*chains)[0].contract == "0x60a3e35cc302bfa44cb288bc5a4f316fdb1adb42",
|
||||
"eurc: contract lowercased for comparison");
|
||||
Check((*chains)[0].note == "lowest fees", "eurc: note carried");
|
||||
Check((*chains)[1].blockTag == "finalized" && (*chains)[1].decimals == 6,
|
||||
"eurc: defaults");
|
||||
}
|
||||
Check(!Server::ParseEurcChains(R"({"chains":[
|
||||
{"name":"base","rpc":"https://x.org","contract":"0xdeadbeef"}]})").has_value(),
|
||||
"eurc: short contract rejects the whole file");
|
||||
Check(!Server::ParseEurcChains(R"({"chains":[
|
||||
{"name":"base","rpc":"ftp://x.org",
|
||||
"contract":"0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42"}]})").has_value(),
|
||||
"eurc: non-http rpc rejects the whole file");
|
||||
Check(!Server::ParseEurcChains(R"({"chains":[]})").has_value(),
|
||||
"eurc: empty chain list rejected");
|
||||
Check(!Server::ParseEurcChains("garbage").has_value(),
|
||||
"eurc: malformed chains file rejected");
|
||||
|
||||
if (failures != 0) {
|
||||
std::println(std::cerr, "{} check(s) failed", failures);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue