blob: f676c74f446d11c17971c4aa6f093631972f2c7d [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <utility>
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/tests/default_construct_unittest.test-mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo::test::default_construct {
class TestInterface : public mojom::TestInterface {
public:
explicit TestInterface(mojo::PendingReceiver<mojom::TestInterface> receiver)
: receiver_(this, std::move(receiver)) {}
void TestMethod(const TestStruct& in, TestMethodCallback callback) override {
std::move(callback).Run(in);
}
void TestMethodWithMap(const base::flat_map<uint8_t, TestStruct>& in,
uint8_t idx,
TestMethodWithMapCallback callback) override {
std::move(callback).Run(in.at(idx));
}
void TestMethodWithArray(const std::vector<TestStruct>& in,
uint8_t idx,
TestMethodWithArrayCallback callback) override {
std::move(callback).Run(in.at(idx));
}
void TestMethodWithFixedArray(
const std::vector<TestStruct>& in,
uint8_t idx,
TestMethodWithFixedArrayCallback callback) override {
std::move(callback).Run(in.at(idx));
}
private:
mojo::Receiver<mojom::TestInterface> receiver_;
};
class DefaultConstructTest : public ::testing::Test {
private:
base::test::SingleThreadTaskEnvironment task_environment_;
};
TEST_F(DefaultConstructTest, Echo) {
mojo::Remote<mojom::TestInterface> remote;
TestInterface instance(remote.BindNewPipeAndPassReceiver());
base::RunLoop run_loop;
remote->TestMethod(TestStruct(42),
base::BindLambdaForTesting([&](const TestStruct& out) {
EXPECT_EQ(out.value(), 42);
run_loop.Quit();
}));
run_loop.Run();
}
TEST_F(DefaultConstructTest, Map) {
mojo::Remote<mojom::TestInterface> remote;
TestInterface instance(remote.BindNewPipeAndPassReceiver());
base::RunLoop run_loop;
base::flat_map<uint8_t, TestStruct> test_map = {{1u, TestStruct(42)}};
remote->TestMethodWithMap(
std::move(test_map), 1u,
base::BindLambdaForTesting([&](const TestStruct& out) {
EXPECT_EQ(out.value(), 42);
run_loop.Quit();
}));
run_loop.Run();
}
TEST_F(DefaultConstructTest, Array) {
mojo::Remote<mojom::TestInterface> remote;
TestInterface instance(remote.BindNewPipeAndPassReceiver());
base::RunLoop run_loop;
std::vector<TestStruct> test_vec = {TestStruct(42), TestStruct(43)};
remote->TestMethodWithArray(
std::move(test_vec), 1u,
base::BindLambdaForTesting([&](const TestStruct& out) {
EXPECT_EQ(out.value(), 43);
run_loop.Quit();
}));
run_loop.Run();
}
TEST_F(DefaultConstructTest, FixedArray) {
mojo::Remote<mojom::TestInterface> remote;
TestInterface instance(remote.BindNewPipeAndPassReceiver());
base::RunLoop run_loop;
std::vector<TestStruct> test_vec = {TestStruct(42), TestStruct(43)};
remote->TestMethodWithFixedArray(
std::move(test_vec), 0u,
base::BindLambdaForTesting([&](const TestStruct& out) {
EXPECT_EQ(out.value(), 42);
run_loop.Quit();
}));
run_loop.Run();
}
// Ensures that a non-typemapped type with a field typemapped to a type without
// a public default constructor initializes that field using
// `mojo::internal::DefaultConstructTraits::Create()` (crbug.com/1385587). Note
// that the generated Mojo code wouldn't even compile without the accompanying
// fix, so this test just covers the runtime behavior.
TEST_F(DefaultConstructTest, TypeWithPrivatelyDefaultConstructibleField) {
mojom::TestStructContainer container;
EXPECT_EQ(container.test_struct.value(), 0);
}
TEST(DefaultConstructOptionalTest, InitializedToNullopt) {
auto container = mojom::OptionalTestStructContainer::New();
EXPECT_EQ(std::nullopt, container->test_struct);
}
} // namespace mojo::test::default_construct