#include #include #include #include #include #include namespace { class THeadersExistence { public: THeadersExistence() = default; THeadersExistence(const THttpHeaders& headers) { for (THttpHeaders::TConstIterator it = headers.Begin(); it != headers.End(); ++it) { Add(it->Name(), it->Value()); } } public: void Add(TStringBuf name, TStringBuf value) { Impl.emplace(TString(name), TString(value)); } bool operator==(const THeadersExistence& rhs) const { return Impl == rhs.Impl; } private: typedef TMultiSet> TImpl; TImpl Impl; }; } bool operator==(const THeadersExistence& lhs, const THttpHeaders& rhs) { return lhs == THeadersExistence(rhs); } bool operator==(const THttpHeaders& lhs, const THeadersExistence& rhs) { return THeadersExistence(lhs) == rhs; } class THttpHeadersTest: public TTestBase { UNIT_TEST_SUITE(THttpHeadersTest); UNIT_TEST(TestConstructorFromArrayRef); UNIT_TEST(TestAddOperation1Arg); UNIT_TEST(TestAddOperation2Args); UNIT_TEST(TestAddOrReplaceOperation1Arg); UNIT_TEST(TestAddOrReplaceOperation2Args); UNIT_TEST(TestAddHeaderTemplateness); UNIT_TEST(TestFindHeader); UNIT_TEST_SUITE_END(); private: typedef void (*TAddHeaderFunction)(THttpHeaders&, TStringBuf name, TStringBuf value); typedef void (*TAddOrReplaceHeaderFunction)(THttpHeaders&, TStringBuf name, TStringBuf value); public: void TestConstructorFromArrayRef(); void TestAddOperation1Arg(); void TestAddOperation2Args(); void TestAddOrReplaceOperation1Arg(); void TestAddOrReplaceOperation2Args(); void TestAddHeaderTemplateness(); void TestFindHeader(); private: static void AddHeaderImpl1Arg(THttpHeaders& headers, TStringBuf name, TStringBuf value) { headers.AddHeader(THttpInputHeader(TString(name), TString(value))); } static void AddHeaderImpl2Args(THttpHeaders& headers, TStringBuf name, TStringBuf value) { headers.AddHeader(TString(name), TString(value)); } static void AddOrReplaceHeaderImpl1Arg(THttpHeaders& headers, TStringBuf name, TStringBuf value) { headers.AddOrReplaceHeader(THttpInputHeader(TString(name), TString(value))); } static void AddOrReplaceHeaderImpl2Args(THttpHeaders& headers, TStringBuf name, TStringBuf value) { headers.AddOrReplaceHeader(TString(name), TString(value)); } void DoTestAddOperation(TAddHeaderFunction); void DoTestAddOrReplaceOperation(TAddHeaderFunction, TAddOrReplaceHeaderFunction); }; UNIT_TEST_SUITE_REGISTRATION(THttpHeadersTest); void THttpHeadersTest::TestConstructorFromArrayRef() { THeadersExistence expected; expected.Add("h1", "v1"); expected.Add("h2", "v2"); // Construct from vector TVector headerVec{ {"h1", "v1"}, {"h2", "v2"} }; THttpHeaders h1(headerVec); UNIT_ASSERT(expected == h1); // Construct from initializer list THttpHeaders h2({ {"h1", "v1"}, {"h2", "v2"} }); UNIT_ASSERT(expected == h2); } void THttpHeadersTest::TestAddOperation1Arg() { DoTestAddOperation(AddHeaderImpl1Arg); } void THttpHeadersTest::TestAddOperation2Args() { DoTestAddOperation(AddHeaderImpl2Args); } void THttpHeadersTest::TestAddOrReplaceOperation1Arg() { DoTestAddOrReplaceOperation(AddHeaderImpl1Arg, AddOrReplaceHeaderImpl1Arg); } void THttpHeadersTest::TestAddOrReplaceOperation2Args() { DoTestAddOrReplaceOperation(AddHeaderImpl2Args, AddOrReplaceHeaderImpl2Args); } void THttpHeadersTest::DoTestAddOperation(TAddHeaderFunction addHeader) { THttpHeaders h1; addHeader(h1, "h1", "v1"); addHeader(h1, "h2", "v1"); addHeader(h1, "h3", "v1"); addHeader(h1, "h3", "v2"); addHeader(h1, "h3", "v2"); THeadersExistence h2; h2.Add("h1", "v1"); h2.Add("h2", "v1"); h2.Add("h3", "v1"); h2.Add("h3", "v2"); h2.Add("h3", "v2"); UNIT_ASSERT(h2 == h1); } // Sorry, but AddOrReplaceHeader replaces only first occurence void THttpHeadersTest::DoTestAddOrReplaceOperation(TAddHeaderFunction addHeader, TAddOrReplaceHeaderFunction addOrReplaceHeader) { THttpHeaders h1; addHeader(h1, "h1", "v1"); addOrReplaceHeader(h1, "h2", "v1"); addOrReplaceHeader(h1, "h2", "v2"); addOrReplaceHeader(h1, "h2", "v3"); addHeader(h1, "h2", "v4"); addHeader(h1, "h3", "v1"); addHeader(h1, "h3", "v2"); addOrReplaceHeader(h1, "h3", "v3"); THeadersExistence h2; h2.Add("h1", "v1"); h2.Add("h2", "v3"); h2.Add("h2", "v4"); h2.Add("h3", "v2"); h2.Add("h3", "v3"); UNIT_ASSERT(h2 == h1); } void THttpHeadersTest::TestAddHeaderTemplateness() { THttpHeaders h1; h1.AddHeader("h1", "v1"); h1.AddHeader("h2", TString("v2")); h1.AddHeader("h3", TStringBuf("v3")); h1.AddHeader("h4", TStringBuf("v4")); THeadersExistence h2; h2.Add("h1", "v1"); h2.Add("h2", "v2"); h2.Add("h3", "v3"); h2.Add("h4", "v4"); UNIT_ASSERT(h1 == h2); } void THttpHeadersTest::TestFindHeader() { THttpHeaders sut; sut.AddHeader("NaMe", "Value"); UNIT_ASSERT(sut.FindHeader("name")); UNIT_ASSERT(sut.FindHeader("name")->Value() == "Value"); }