blob: 4c35dcbbd9257c4cd50a8bb76cd76f996ae86f70 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "blimp/common/mandatory_callback.h"
#include <memory>
#include "base/bind.h"
#include "base/test/gtest_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blimp {
namespace {
class MandatoryCallbackTest : public testing::Test {
public:
class ResultCollector {
public:
MOCK_METHOD2(MarkInvokedTwoArgs, void(int, float));
MOCK_METHOD1(MarkInvoked, void(int));
};
MandatoryCallbackTest() {}
~MandatoryCallbackTest() override {}
protected:
testing::StrictMock<ResultCollector> result_;
private:
DISALLOW_COPY_AND_ASSIGN(MandatoryCallbackTest);
};
#if !DCHECK_IS_ON()
TEST_F(MandatoryCallbackTest, NoEffectForReleaseBuilds) {
auto mandatory_cb = CreateMandatoryCallback(base::Bind(&base::DoNothing));
// Test should not crash when |mandatory_cb| is leaked.
}
#else
TEST_F(MandatoryCallbackTest, PassesWhenDestroyedAfterRun) {
EXPECT_CALL(result_, MarkInvoked(3));
base::Callback<void(int)> cb =
base::Bind(&MandatoryCallbackTest::ResultCollector::MarkInvoked,
base::Unretained(&result_));
MandatoryCallback<void(int)> mandatory_cb = CreateMandatoryCallback(cb);
mandatory_cb.Run(3);
}
TEST_F(MandatoryCallbackTest, FailsWhenDestroyedBeforeRun) {
base::Callback<void(int)> cb =
base::Bind(&MandatoryCallbackTest::ResultCollector::MarkInvoked,
base::Unretained(&result_));
ASSERT_DCHECK_DEATH(auto mandatory_cb = CreateMandatoryCallback(cb));
}
TEST_F(MandatoryCallbackTest, FailsOnMultipleInvocations) {
EXPECT_CALL(result_, MarkInvoked(3));
base::Callback<void(int)> cb =
base::Bind(&MandatoryCallbackTest::ResultCollector::MarkInvoked,
base::Unretained(&result_));
auto mandatory_cb = CreateMandatoryCallback(cb);
mandatory_cb.Run(3);
EXPECT_DCHECK_DEATH(mandatory_cb.Run(3));
}
TEST_F(MandatoryCallbackTest, FailsOnMoveThenMultipleCall) {
EXPECT_CALL(result_, MarkInvoked(3));
base::Callback<void(int)> cb =
base::Bind(&MandatoryCallbackTest::ResultCollector::MarkInvoked,
base::Unretained(&result_));
auto mandatory_cb = CreateMandatoryCallback(cb);
auto moved = std::move(mandatory_cb);
moved.Run(3);
EXPECT_DCHECK_DEATH(mandatory_cb.Run(3));
}
// Allows death checks to copy-and-discard as a one-liner statement,
// which is necessary for isolating the moved variable inside the forked death
// check process.
template <typename CallbackType>
void MoveAndToss(CallbackType&& cb) {
auto copy = std::move(cb);
}
TEST_F(MandatoryCallbackTest, FailsOnMoveThenDrop) {
base::Callback<void(int)> cb =
base::Bind(&MandatoryCallbackTest::ResultCollector::MarkInvoked,
base::Unretained(&result_));
ASSERT_DCHECK_DEATH(MoveAndToss(CreateMandatoryCallback(cb)));
}
#endif
} // namespace
} // namespace blimp