diff --git a/BUILD.gn b/BUILD.gn index af3a690080..23e887a1bc 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -538,6 +538,7 @@ if (rtc_include_tests) { "call:fake_network_pipe_unittests", "p2p:libstunprober_unittests", "p2p:rtc_p2p_unittests", + "rtc_base:cancer_stick_castle_unittests", "rtc_base:function_unittest", "rtc_base:rtc_base_approved_unittests", "rtc_base:rtc_base_unittests", diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index 105bbc3c9f..137d7ca923 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -1070,6 +1070,19 @@ rtc_library("testclient") { ] } +rtc_library("cancer_stick_castle_unittests") { + testonly = true + + sources = [ "cancer_stick_castle_unittest.cc" ] + deps = [ + ":cancer_stick_castle", + ":gunit_helpers", + ":rtc_base", + "../api:function_view", + "../test:test_support", + ] +} + rtc_library("rtc_base_tests_utils") { testonly = true sources = [ diff --git a/rtc_base/cancer_stick_castle.h b/rtc_base/cancer_stick_castle.h index a0bdff9175..43e6a46a70 100644 --- a/rtc_base/cancer_stick_castle.h +++ b/rtc_base/cancer_stick_castle.h @@ -56,7 +56,7 @@ class CancerStickCastle { receivers_.AddReceiver( UntypedFunction::Create(std::forward(f))); } - void Send(ArgT... args) { + void Send(ArgT&&... args) { receivers_.Foreach([&](UntypedFunction& f) { f.Call(std::forward(args)...); }); diff --git a/rtc_base/cancer_stick_castle_unittest.cc b/rtc_base/cancer_stick_castle_unittest.cc new file mode 100644 index 0000000000..2c993b059a --- /dev/null +++ b/rtc_base/cancer_stick_castle_unittest.cc @@ -0,0 +1,162 @@ +/* + * Copyright 2020 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include +#include + +#include "api/function_view.h" +#include "rtc_base/bind.h" +#include "rtc_base/cancer_stick_castle.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { + +TEST(CancerStickCastle, NoRecieverSingleMessageTest) { + CancerStickCastle c; + + c.Send("message"); +} + +TEST(CancerStickCastle, MultipleParameterMessageTest) { + CancerStickCastle + c; + std::string str = "messege"; + int i = 10; + + c.Send(str, "message1", "message0", 123, &i, str); +} + +TEST(CancerStickCastle, NoParameterMessageTest) { + CancerStickCastle<> c; + + c.Send(); +} + +TEST(CancerStickCastle, ReferenceTest) { + CancerStickCastle c; + int index = 1; + + c.AddReceiver([](int& index) { index++; }); + c.Send(index); + + EXPECT_EQ(index, 2); +} + +TEST(CancerStickCastle, ConstReferenceTest) { + CancerStickCastle c; + int i = 0; + int index = 1; + + c.AddReceiver([&i](const int& index) { i = index; }); + c.Send(index); + + EXPECT_EQ(i, 1); +} + +TEST(CancerStickCastle, PointerTest) { + CancerStickCastle c; + int index = 1; + + c.AddReceiver([](int* index) { (*index)++; }); + c.Send(&index); + + EXPECT_EQ(index, 2); +} + +void PlusOne(int& a) { + a++; +} + +TEST(CancerStickCastle, FunctionPtrTest) { + CancerStickCastle c; + int index = 1; + + c.AddReceiver(PlusOne); + c.Send(index); + + EXPECT_EQ(index, 2); +} + +struct LargeNonTrivial { + int a[17]; + + LargeNonTrivial() = default; + LargeNonTrivial(LargeNonTrivial&& m) {} + ~LargeNonTrivial() = default; + + void operator()(int& a) { a = 1; } +}; + +TEST(CancerStickCastle, LargeNonTrivialTest) { + CancerStickCastle c; + int i = 0; + static_assert(sizeof(LargeNonTrivial) > 16, ""); + c.AddReceiver(LargeNonTrivial()); + c.Send(i); + + EXPECT_EQ(i, 1); +} + +/* sizeof(LargeTrivial) = 20bytes which is greater than + * the size check (16bytes) of the CSC library */ +struct LargeTrivial { + int a[17]; + void operator()(int& x) { x = 1; } +}; + +TEST(CancerStickCastle, LargeTrivial) { + CancerStickCastle c; + LargeTrivial lt; + int i = 0; + + static_assert(sizeof(lt) > 16, ""); + c.AddReceiver(lt); + c.Send(i); + + EXPECT_EQ(i, 1); +} + +struct OnlyNonTriviallyConstructible { + OnlyNonTriviallyConstructible() = default; + OnlyNonTriviallyConstructible(OnlyNonTriviallyConstructible&& m) {} + + void operator()(int& a) { a = 1; } +}; + +TEST(CancerStickCastle, OnlyNonTriviallyMoveConstructible) { + CancerStickCastle c; + int i = 0; + + c.AddReceiver(OnlyNonTriviallyConstructible()); + c.Send(i); + + EXPECT_EQ(i, 1); +} + +TEST(CancerStickCastle, MultipleReceiverSendTest) { + CancerStickCastle c; + std::function plus = PlusOne; + int index = 1; + + c.AddReceiver(plus); + c.AddReceiver([](int& i) { i--; }); + c.AddReceiver(plus); + c.AddReceiver(plus); + c.Send(index); + c.Send(index); + + EXPECT_EQ(index, 5); +} +// todo(glahiru): Add a test case to catch some error for Karl's first fix +// todo(glahiru): Add a test for rtc::Bind +// which used the following code in the Send +} // namespace +} // namespace webrtc