#include #include #include #include namespace xrpl { class StringUtilities_test : public beast::unit_test::suite { public: void testUnHexSuccess(std::string const& strIn, std::string const& strExpected) { auto rv = strUnHex(strIn); BEAST_EXPECT(rv); BEAST_EXPECT(makeSlice(*rv) == makeSlice(strExpected)); } void testUnHexFailure(std::string const& strIn) { auto rv = strUnHex(strIn); BEAST_EXPECT(!rv); } void testUnHex() { testcase("strUnHex"); testUnHexSuccess("526970706c6544", "RippleD"); testUnHexSuccess("A", "\n"); testUnHexSuccess("0A", "\n"); testUnHexSuccess("D0A", "\r\n"); testUnHexSuccess("0D0A", "\r\n"); testUnHexSuccess("200D0A", " \r\n"); testUnHexSuccess("282A2B2C2D2E2F29", "(*+,-./)"); // Check for things which contain some or only invalid characters testUnHexFailure("123X"); testUnHexFailure("V"); testUnHexFailure("XRP"); } void testParseUrl() { testcase("parseUrl"); // Expected passes. { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain.empty()); BEAST_EXPECT(!pUrl.port); // RFC 3986: // > In general, a URI that uses the generic syntax for authority // with an empty path should be normalized to a path of "/". // Do we want to normalize paths? BEAST_EXPECT(pUrl.path.empty()); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme:///")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain.empty()); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "lower://domain")); BEAST_EXPECT(pUrl.scheme == "lower"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path.empty()); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "UPPER://domain:234/")); BEAST_EXPECT(pUrl.scheme == "upper"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(*pUrl.port == 234); BEAST_EXPECT(pUrl.path == "/"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "Mixed://domain/path")); BEAST_EXPECT(pUrl.scheme == "mixed"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/path"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://[::1]:123/path")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "::1"); BEAST_EXPECT(*pUrl.port == 123); BEAST_EXPECT(pUrl.path == "/path"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://user:pass@domain:123/abc:321")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username == "user"); BEAST_EXPECT(pUrl.password == "pass"); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(*pUrl.port == 123); BEAST_EXPECT(pUrl.path == "/abc:321"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://user@domain:123/abc:321")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username == "user"); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(*pUrl.port == 123); BEAST_EXPECT(pUrl.path == "/abc:321"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://:pass@domain:123/abc:321")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password == "pass"); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(*pUrl.port == 123); BEAST_EXPECT(pUrl.path == "/abc:321"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://domain:123/abc:321")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(*pUrl.port == 123); BEAST_EXPECT(pUrl.path == "/abc:321"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://user:pass@domain/abc:321")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username == "user"); BEAST_EXPECT(pUrl.password == "pass"); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/abc:321"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://user@domain/abc:321")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username == "user"); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/abc:321"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://:pass@domain/abc:321")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password == "pass"); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/abc:321"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://domain/abc:321")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/abc:321"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme:///path/to/file")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain.empty()); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/path/to/file"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://user:pass@domain/path/with/an@sign")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username == "user"); BEAST_EXPECT(pUrl.password == "pass"); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/path/with/an@sign"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://domain/path/with/an@sign")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "domain"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/path/with/an@sign"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "scheme://:999/")); BEAST_EXPECT(pUrl.scheme == "scheme"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == ":999"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/"); } { parsedURL pUrl; BEAST_EXPECT(parseUrl(pUrl, "http://::1:1234/validators")); BEAST_EXPECT(pUrl.scheme == "http"); BEAST_EXPECT(pUrl.username.empty()); BEAST_EXPECT(pUrl.password.empty()); BEAST_EXPECT(pUrl.domain == "::0.1.18.52"); BEAST_EXPECT(!pUrl.port); BEAST_EXPECT(pUrl.path == "/validators"); } // Expected fails. { parsedURL pUrl; BEAST_EXPECT(!parseUrl(pUrl, "")); BEAST_EXPECT(!parseUrl(pUrl, "nonsense")); BEAST_EXPECT(!parseUrl(pUrl, "://")); BEAST_EXPECT(!parseUrl(pUrl, ":///")); BEAST_EXPECT(!parseUrl(pUrl, "scheme://user:pass@domain:65536/abc:321")); BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:23498765/")); BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:0/")); BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:+7/")); BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:-7234/")); BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:@#$56!/")); } { std::string strUrl("s://" + std::string(8192, ':')); parsedURL pUrl; BEAST_EXPECT(!parseUrl(pUrl, strUrl)); } } void testToString() { testcase("toString"); auto result = to_string("hello"); BEAST_EXPECT(result == "hello"); } void run() override { testParseUrl(); testUnHex(); testToString(); } }; BEAST_DEFINE_TESTSUITE(StringUtilities, basics, xrpl); } // namespace xrpl