#include "rpc/ndjson.hpp" #include #include "check.hpp" using velox::daemon::rpc::FrameReader; using velox::daemon::rpc::frame; void run() { // One chunk, one frame. { FrameReader r; auto f = r.feed("{\"a\":1}\n"); CHECK_EQ(f.size(), 1u); CHECK_EQ(f.at(0), std::string("{\"a\":1}")); CHECK_EQ(r.buffered(), 0u); } // A frame split across two feeds is delivered only when the newline arrives. { FrameReader r; CHECK_EQ(r.feed("{\"a\":").size(), 0u); auto f = r.feed("1}\n"); CHECK_EQ(f.size(), 1u); CHECK_EQ(f.at(0), std::string("{\"a\":1}")); } // Several frames in one chunk, plus a partial tail held back. { FrameReader r; auto f = r.feed("1\n2\n3\n4"); CHECK_EQ(f.size(), 3u); CHECK_EQ(f.at(0), std::string("1")); CHECK_EQ(f.at(2), std::string("3")); CHECK_EQ(r.buffered(), 1u); auto g = r.feed("\n"); CHECK_EQ(g.size(), 1u); CHECK_EQ(g.at(0), std::string("4")); } // CRLF terminator is trimmed; blank lines are skipped. { FrameReader r; auto f = r.feed("x\r\n\r\n\ny\r\n"); CHECK_EQ(f.size(), 2u); CHECK_EQ(f.at(0), std::string("x")); CHECK_EQ(f.at(1), std::string("y")); } // Overflow latches once the unframed tail passes the cap. { FrameReader r; CHECK(!r.overflowed()); std::string big(9u * 1024 * 1024, 'a'); // no newline r.feed(big); CHECK(r.overflowed()); } // frame() appends exactly one newline. CHECK_EQ(frame("hello"), std::string("hello\n")); } TEST_MAIN()