parent
347e0bb525
commit
74cbd3126f
3 changed files with 318 additions and 312 deletions
@ -1,17 +0,0 @@ |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file or at |
||||
// https://developers.google.com/open-source/licenses/bsd |
||||
#endregion |
||||
|
||||
namespace Google.Protobuf.Reflection; |
||||
|
||||
internal sealed partial class FeatureSetDescriptor |
||||
{ |
||||
// Canonical serialized form of the edition defaults, generated by embed_edition_defaults. |
||||
private const string DefaultsBase64 = |
||||
"ChMYhAciACoMCAEQAhgCIAMoATACChMY5wciACoMCAIQARgBIAIoATABChMY6AciDAgBEAEYASACKAEwASoAIOYHKOgH"; |
||||
} |
@ -0,0 +1,318 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2024 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#include <gmock/gmock.h> |
||||
#include <gtest/gtest.h> |
||||
#include "google/protobuf/compiler/hpb/tests/child_model.upb.proto.h" |
||||
#include "google/protobuf/compiler/hpb/tests/test_extension.upb.proto.h" |
||||
#include "google/protobuf/compiler/hpb/tests/test_model.upb.proto.h" |
||||
#include "google/protobuf/hpb/requires.h" |
||||
|
||||
namespace { |
||||
|
||||
using ::hpb::internal::Requires; |
||||
using ::hpb_unittest::protos::ChildModel1; |
||||
using ::hpb_unittest::protos::TestModel; |
||||
using ::testing::ElementsAre; |
||||
|
||||
const char kTestStr1[] = "abcdefg"; |
||||
const char kTestStr2[] = "just another test string"; |
||||
|
||||
TEST(CppGeneratedCode, RepeatedMessages) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
EXPECT_EQ(0, test_model.child_models_size()); |
||||
// Should be able to clear repeated field when empty.
|
||||
test_model.mutable_child_models()->clear(); |
||||
EXPECT_EQ(0, test_model.child_models_size()); |
||||
// Add 2 children.
|
||||
auto new_child = test_model.add_child_models(); |
||||
EXPECT_EQ(true, new_child.ok()); |
||||
new_child.value()->set_child_str1(kTestStr1); |
||||
new_child = test_model.add_child_models(); |
||||
EXPECT_EQ(true, new_child.ok()); |
||||
new_child.value()->set_child_str1(kTestStr2); |
||||
EXPECT_EQ(2, test_model.child_models_size()); |
||||
// Mutable access.
|
||||
auto mutable_first = test_model.mutable_child_models(0); |
||||
EXPECT_EQ(mutable_first->child_str1(), kTestStr1); |
||||
mutable_first->set_child_str1("change1"); |
||||
auto mutable_second = test_model.mutable_child_models(1); |
||||
EXPECT_EQ(mutable_second->child_str1(), kTestStr2); |
||||
mutable_second->set_child_str1("change2"); |
||||
// Check mutations using views.
|
||||
auto view_first = test_model.child_models(0); |
||||
EXPECT_EQ(view_first->child_str1(), "change1"); |
||||
auto view_second = test_model.child_models(1); |
||||
EXPECT_EQ(view_second->child_str1(), "change2"); |
||||
} |
||||
|
||||
TEST(CppGeneratedCode, RepeatedScalar) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
EXPECT_EQ(0, test_model.value_array_size()); |
||||
// Should be able to clear repeated field when empty.
|
||||
test_model.mutable_value_array()->clear(); |
||||
EXPECT_EQ(0, test_model.value_array_size()); |
||||
// Add 2 children.
|
||||
EXPECT_EQ(true, test_model.add_value_array(5)); |
||||
EXPECT_EQ(true, test_model.add_value_array(6)); |
||||
EXPECT_EQ(2, test_model.value_array_size()); |
||||
EXPECT_EQ(5, test_model.value_array(0)); |
||||
EXPECT_EQ(6, test_model.value_array(1)); |
||||
EXPECT_EQ(true, test_model.resize_value_array(3)); |
||||
EXPECT_EQ(3, test_model.value_array_size()); |
||||
test_model.set_value_array(2, 7); |
||||
EXPECT_EQ(5, test_model.value_array(0)); |
||||
EXPECT_EQ(6, test_model.value_array(1)); |
||||
EXPECT_EQ(7, test_model.value_array(2)); |
||||
} |
||||
|
||||
TEST(CppGeneratedCode, RepeatedFieldClear) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
test_model.mutable_value_array()->push_back(5); |
||||
test_model.mutable_value_array()->push_back(16); |
||||
test_model.mutable_value_array()->push_back(27); |
||||
ASSERT_EQ(test_model.mutable_value_array()->size(), 3); |
||||
test_model.mutable_value_array()->clear(); |
||||
EXPECT_EQ(test_model.mutable_value_array()->size(), 0); |
||||
} |
||||
|
||||
TEST(CppGeneratedCode, RepeatedFieldProxyForScalars) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
EXPECT_EQ(0, test_model.value_array().size()); |
||||
EXPECT_EQ(0, test_model.mutable_value_array()->size()); |
||||
|
||||
test_model.mutable_value_array()->push_back(5); |
||||
test_model.mutable_value_array()->push_back(16); |
||||
test_model.mutable_value_array()->push_back(27); |
||||
|
||||
ASSERT_EQ(test_model.mutable_value_array()->size(), 3); |
||||
EXPECT_EQ((*test_model.mutable_value_array())[0], 5); |
||||
EXPECT_EQ((*test_model.mutable_value_array())[1], 16); |
||||
EXPECT_EQ((*test_model.mutable_value_array())[2], 27); |
||||
|
||||
const auto value_array = test_model.value_array(); |
||||
ASSERT_EQ(value_array.size(), 3); |
||||
EXPECT_EQ(value_array[0], 5); |
||||
EXPECT_EQ(value_array[1], 16); |
||||
EXPECT_EQ(value_array[2], 27); |
||||
|
||||
EXPECT_THAT(value_array, ElementsAre(5, 16, 27)); |
||||
|
||||
EXPECT_THAT(std::vector(value_array.begin(), value_array.end()), |
||||
ElementsAre(5, 16, 27)); |
||||
EXPECT_THAT(std::vector(value_array.cbegin(), value_array.cend()), |
||||
ElementsAre(5, 16, 27)); |
||||
EXPECT_THAT(std::vector(value_array.rbegin(), value_array.rend()), |
||||
ElementsAre(27, 16, 5)); |
||||
EXPECT_THAT(std::vector(value_array.crbegin(), value_array.crend()), |
||||
ElementsAre(27, 16, 5)); |
||||
} |
||||
|
||||
TEST(CppGeneratedCode, RepeatedScalarIterator) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
test_model.mutable_value_array()->push_back(5); |
||||
test_model.mutable_value_array()->push_back(16); |
||||
test_model.mutable_value_array()->push_back(27); |
||||
int sum = 0; |
||||
// Access by value.
|
||||
const ::hpb::RepeatedField<int32_t>::CProxy rep1 = test_model.value_array(); |
||||
for (auto i : rep1) { |
||||
sum += i; |
||||
} |
||||
EXPECT_EQ(sum, 5 + 16 + 27); |
||||
// Access by const reference.
|
||||
sum = 0; |
||||
for (const auto& i : *test_model.mutable_value_array()) { |
||||
sum += i; |
||||
} |
||||
EXPECT_EQ(sum, 5 + 16 + 27); |
||||
// Access by forwarding reference.
|
||||
sum = 0; |
||||
for (auto&& i : *test_model.mutable_value_array()) { |
||||
sum += i; |
||||
} |
||||
EXPECT_EQ(sum, 5 + 16 + 27); |
||||
// Test iterator operators.
|
||||
auto begin = test_model.value_array().begin(); |
||||
auto end = test_model.value_array().end(); |
||||
sum = 0; |
||||
for (auto it = begin; it != end; ++it) { |
||||
sum += *it; |
||||
} |
||||
EXPECT_EQ(sum, 5 + 16 + 27); |
||||
auto it = begin; |
||||
++it; |
||||
EXPECT_TRUE(begin < it); |
||||
EXPECT_TRUE(begin <= it); |
||||
it = end; |
||||
EXPECT_TRUE(it == end); |
||||
EXPECT_TRUE(it > begin); |
||||
EXPECT_TRUE(it >= begin); |
||||
EXPECT_TRUE(it != begin); |
||||
// difference type
|
||||
it = end; |
||||
--it; |
||||
--it; |
||||
EXPECT_EQ(end - it, 2); |
||||
it = begin; |
||||
EXPECT_EQ(it[0], 5); |
||||
EXPECT_EQ(it[1], 16); |
||||
EXPECT_EQ(it[2], 27); |
||||
// ValueProxy.
|
||||
sum = 0; |
||||
for (::hpb::RepeatedField<int32_t>::ValueCProxy c : |
||||
test_model.value_array()) { |
||||
sum += c; |
||||
} |
||||
EXPECT_EQ(sum, 5 + 16 + 27); |
||||
sum = 0; |
||||
for (::hpb::RepeatedField<int32_t>::ValueProxy c : |
||||
*test_model.mutable_value_array()) { |
||||
sum += c; |
||||
} |
||||
EXPECT_EQ(sum, 5 + 16 + 27); |
||||
} |
||||
|
||||
TEST(CppGeneratedCode, RepeatedFieldProxyForStrings) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
EXPECT_EQ(0, test_model.repeated_string().size()); |
||||
EXPECT_EQ(0, test_model.mutable_repeated_string()->size()); |
||||
|
||||
test_model.mutable_repeated_string()->push_back("a"); |
||||
test_model.mutable_repeated_string()->push_back("b"); |
||||
test_model.mutable_repeated_string()->push_back("c"); |
||||
|
||||
ASSERT_EQ(test_model.repeated_string().size(), 3); |
||||
EXPECT_EQ(test_model.repeated_string()[0], "a"); |
||||
EXPECT_EQ(test_model.repeated_string()[1], "b"); |
||||
EXPECT_EQ(test_model.repeated_string()[2], "c"); |
||||
|
||||
EXPECT_THAT(test_model.repeated_string(), ElementsAre("a", "b", "c")); |
||||
EXPECT_THAT(*test_model.mutable_repeated_string(), |
||||
ElementsAre("a", "b", "c")); |
||||
|
||||
ASSERT_EQ(test_model.mutable_repeated_string()->size(), 3); |
||||
EXPECT_EQ((*test_model.mutable_repeated_string())[0], "a"); |
||||
EXPECT_EQ((*test_model.mutable_repeated_string())[1], "b"); |
||||
EXPECT_EQ((*test_model.mutable_repeated_string())[2], "c"); |
||||
|
||||
// The const accessor can't be used to modify the element
|
||||
EXPECT_FALSE((std::is_assignable<decltype(test_model.repeated_string()[1]), |
||||
absl::string_view>::value)); |
||||
// But the mutable one is fine.
|
||||
(*test_model.mutable_repeated_string())[1] = "other"; |
||||
EXPECT_THAT(test_model.repeated_string(), ElementsAre("a", "other", "c")); |
||||
|
||||
test_model.mutable_repeated_string()->clear(); |
||||
EXPECT_EQ(test_model.mutable_repeated_string()->size(), 0); |
||||
} |
||||
|
||||
TEST(CppGeneratedCode, RepeatedFieldProxyForMessages) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
EXPECT_EQ(0, test_model.child_models().size()); |
||||
ChildModel1 child1; |
||||
child1.set_child_str1(kTestStr1); |
||||
test_model.mutable_child_models()->push_back(child1); |
||||
ChildModel1 child2; |
||||
child2.set_child_str1(kTestStr2); |
||||
test_model.mutable_child_models()->push_back(std::move(child2)); |
||||
|
||||
int i = 0; |
||||
for (auto child : test_model.child_models()) { |
||||
EXPECT_FALSE(Requires<decltype(child)>( |
||||
[](auto&& x) -> decltype(x.set_child_str1("")) {})); |
||||
if (i++ == 0) { |
||||
EXPECT_EQ(child.child_str1(), kTestStr1); |
||||
} else { |
||||
EXPECT_EQ(child.child_str1(), kTestStr2); |
||||
} |
||||
} |
||||
|
||||
i = 0; |
||||
for (const auto& child : *test_model.mutable_child_models()) { |
||||
if (i++ == 0) { |
||||
EXPECT_EQ(child.child_str1(), kTestStr1); |
||||
} else { |
||||
EXPECT_EQ(child.child_str1(), kTestStr2); |
||||
} |
||||
} |
||||
|
||||
using testing::_; |
||||
EXPECT_THAT(test_model.child_models(), ElementsAre(_, _)); |
||||
|
||||
EXPECT_EQ(test_model.child_models().size(), 2); |
||||
EXPECT_EQ(test_model.child_models()[0].child_str1(), kTestStr1); |
||||
EXPECT_EQ(test_model.child_models()[1].child_str1(), kTestStr2); |
||||
EXPECT_EQ((*test_model.mutable_child_models())[0].child_str1(), kTestStr1); |
||||
EXPECT_EQ((*test_model.mutable_child_models())[1].child_str1(), kTestStr2); |
||||
(*test_model.mutable_child_models())[0].set_child_str1("change1"); |
||||
EXPECT_EQ((*test_model.mutable_child_models())[0].child_str1(), "change1"); |
||||
test_model.mutable_child_models()->clear(); |
||||
EXPECT_EQ(test_model.mutable_child_models()->size(), 0); |
||||
} |
||||
|
||||
TEST(CppGeneratedCode, EmptyRepeatedFieldProxyForMessages) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
EXPECT_EQ(0, test_model.child_models().size()); |
||||
ChildModel1 child1; |
||||
child1.set_child_str1(kTestStr1); |
||||
|
||||
EXPECT_EQ(test_model.child_models().size(), 0); |
||||
EXPECT_EQ(std::distance(test_model.child_models().begin(), |
||||
test_model.child_models().end()), |
||||
0); |
||||
} |
||||
|
||||
TEST(CppGeneratedCode, RepeatedFieldProxyForMessagesIndexOperator) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
EXPECT_EQ(0, test_model.child_models().size()); |
||||
ChildModel1 child1; |
||||
child1.set_child_str1(kTestStr1); |
||||
test_model.mutable_child_models()->push_back(child1); |
||||
ChildModel1 child2; |
||||
|
||||
child2.set_child_str1(kTestStr2); |
||||
test_model.mutable_child_models()->push_back(std::move(child2)); |
||||
ASSERT_EQ(test_model.child_models().size(), 2); |
||||
|
||||
// test_model.child_models()[0].set_child_str1("change1");
|
||||
(*test_model.mutable_child_models())[0].set_child_str1("change1"); |
||||
EXPECT_EQ((*test_model.mutable_child_models())[0].child_str1(), "change1"); |
||||
} |
||||
|
||||
TEST(CppGeneratedCode, RepeatedStrings) { |
||||
::hpb::Arena arena; |
||||
auto test_model = ::hpb::CreateMessage<TestModel>(arena); |
||||
EXPECT_EQ(0, test_model.repeated_string_size()); |
||||
// Should be able to clear repeated field when empty.
|
||||
test_model.mutable_repeated_string()->clear(); |
||||
EXPECT_EQ(0, test_model.repeated_string_size()); |
||||
// Add 2 children.
|
||||
EXPECT_EQ(true, test_model.add_repeated_string("Hello")); |
||||
EXPECT_EQ(true, test_model.add_repeated_string("World")); |
||||
EXPECT_EQ(2, test_model.repeated_string_size()); |
||||
EXPECT_EQ("Hello", test_model.repeated_string(0)); |
||||
EXPECT_EQ("World", test_model.repeated_string(1)); |
||||
EXPECT_EQ(true, test_model.resize_repeated_string(3)); |
||||
EXPECT_EQ(3, test_model.repeated_string_size()); |
||||
test_model.set_repeated_string(2, "Test"); |
||||
EXPECT_EQ("Hello", test_model.repeated_string(0)); |
||||
EXPECT_EQ("World", test_model.repeated_string(1)); |
||||
EXPECT_EQ("Test", test_model.repeated_string(2)); |
||||
} |
||||
|
||||
|
||||
} // namespace
|
Loading…
Reference in new issue