Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /base /barrier_callback_unittest.cc
blob: 328919f6b0c72cfe4a37dc3971cd77b89579f25e [file] [log] [blame] [edit]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include"base/barrier_callback.h"
#include"base/functional/bind.h"
#include"base/functional/callback.h"
#include"base/memory/raw_ptr.h"
#include"base/test/bind.h"
#include"base/test/gtest_util.h"
#include"testing/gmock/include/gmock/gmock.h"
#include"testing/gtest/include/gtest/gtest.h"
namespace{
TEST(BarrierCallbackTest,RunsImmediatelyForZeroCallbacks){
bool done=false;
auto barrier_callback= base::BarrierCallback<int>(
0, base::BindLambdaForTesting([&done](std::vector<int> results){
EXPECT_THAT(results, testing::IsEmpty());
done=true;
}));
EXPECT_TRUE(done);
}
TEST(BarrierCallbackTest,ErrorToCallCallbackWithZeroCallbacks){
auto barrier_callback=
base::BarrierCallback<int>(0, base::BindOnce([](std::vector<int>){}));
EXPECT_FALSE(barrier_callback.is_null());
EXPECT_NOTREACHED_DEATH(barrier_callback.Run(3));
}
TEST(BarrierCallbackTest,RunAfterNumCallbacks){
bool done=false;
auto barrier_callback= base::BarrierCallback<int>(
3, base::BindLambdaForTesting([&done](std::vector<int> results){
EXPECT_THAT(results, testing::ElementsAre(1,3,2));
done=true;
}));
EXPECT_FALSE(done);
barrier_callback.Run(1);
EXPECT_FALSE(done);
barrier_callback.Run(3);
EXPECT_FALSE(done);
barrier_callback.Run(2);
EXPECT_TRUE(done);
}
TEST(BarrierCallbackTest,CopiesShareState){
bool done=false;
constauto barrier_callback= base::BarrierCallback<int>(
3, base::BindLambdaForTesting([&done](std::vector<int> results){
EXPECT_THAT(results, testing::ElementsAre(1,3,2));
done=true;
}));
EXPECT_FALSE(done);
constauto barrier_copy1= barrier_callback;
constauto barrier_copy2= barrier_callback;
constauto barrier_copy3= barrier_callback;
barrier_copy1.Run(1);
EXPECT_FALSE(done);
barrier_copy2.Run(3);
EXPECT_FALSE(done);
barrier_copy3.Run(2);
EXPECT_TRUE(done);
}
template<typename...Args>
classDestructionIndicator{
public:
// Sets `*destructed` to true in destructor.
explicitDestructionIndicator(bool* destructed): destructed_(destructed){
*destructed_=false;
}
~DestructionIndicator(){*destructed_=true;}
voidDoNothing(Args...){}
private:
raw_ptr<bool> destructed_;
};
TEST(BarrierCallbackTest,ReleasesDoneCallbackWhenDone){
bool done_destructed=false;
auto barrier_callback= base::BarrierCallback<bool>(
1,
base::BindOnce(&DestructionIndicator<std::vector<bool>>::DoNothing,
std::make_unique<DestructionIndicator<std::vector<bool>>>(
&done_destructed)));
EXPECT_FALSE(done_destructed);
barrier_callback.Run(true);
EXPECT_TRUE(done_destructed);
}
// Tests a case when `done_callback` resets the `barrier_callback`.
// `barrier_callback` is a RepeatingCallback holding the `done_callback`.
// `done_callback` holds a reference back to the `barrier_callback`. When
// `barrier_callback` is Run() it calls `done_callback` which erases the
// `barrier_callback` while still inside of its Run(). The Run() implementation
// (in base::BarrierCallback) must not try use itself after executing
// ResetBarrierCallback() or this test would crash inside Run().
TEST(BarrierCallbackTest,KeepingCallbackAliveUntilDone){
base::RepeatingCallback<void(bool)> barrier_callback;
barrier_callback= base::BarrierCallback<bool>(
1, base::BindLambdaForTesting(
[&barrier_callback](std::vector<bool> results){
barrier_callback= base::RepeatingCallback<void(bool)>();
EXPECT_THAT(results, testing::ElementsAre(true));
}));
barrier_callback.Run(true);
EXPECT_TRUE(barrier_callback.is_null());
}
TEST(BarrierCallbackTest,SupportsMoveonlyTypes){
classMoveOnly{
public:
MoveOnly()=default;
MoveOnly(MoveOnly&&)=default;
MoveOnly&operator=(MoveOnly&&)=default;
};
// No need to assert anything here, since if BarrierCallback didn't work with
// move-only types, this wouldn't compile.
auto barrier_callback= base::BarrierCallback<MoveOnly>(
1, base::BindOnce([](std::vector<MoveOnly>){}));
barrier_callback.Run(MoveOnly());
auto barrier_callback2= base::BarrierCallback<MoveOnly>(
1, base::BindOnce([](const std::vector<MoveOnly>&){}));
barrier_callback2.Run(MoveOnly());
}
TEST(BarrierCallbackTest,SupportsConstRefResults){
auto barrier_callback= base::BarrierCallback<int>(
1, base::BindOnce([](const std::vector<int>&){}));
barrier_callback.Run(1);
}
TEST(BarrierCallbackTest,SupportsReferenceTypes){
classReferenceable{
// Must be copyable.
};
Referenceable ref;
// No need to assert anything here, since if BarrierCallback didn't work with
// by-reference args, this wouldn't compile.
auto barrier_callback= base::BarrierCallback<constReferenceable&>(
1, base::BindOnce([](std::vector<Referenceable>){}));
barrier_callback.Run(ref);
auto barrier_callback2= base::BarrierCallback<constReferenceable&>(
1, base::BindOnce([](const std::vector<Referenceable>&){}));
barrier_callback2.Run(ref);
}
}// namespace

[8]ページ先頭

©2009-2025 Movatter.jp