blob: 140f583c50fd551d41643cf2cd925917be01d07e [file] [edit]
// Protocol Buffers - Google's data interchange format
// Copyright 2026 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
// Text-format conformance tests for integer fields: the extreme values of
// each integer type in decimal, hex and octal, and rejection of values just
// past them. This replaces the integer blocks of the legacy
// TextFormatConformanceTestSuiteImpl<M>::RunAllTests(); the test names and
// the requests sent to the testee are identical to the legacy ones.
//
// The legacy suite ran RunAllTests() only for TestAllTypesProto3, which its
// RunSuiteImpl() instantiated in its proto3 and editions flavours, so these
// run over Proto3TestMessageTypes() (like HelloWorld).
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "conformance/binary_test_util.h"
#include "conformance/matchers.h"
#include "conformance/message_type_fixtures.h"
#include "conformance/testee.h"
namespace google {
namespace protobuf {
namespace conformance {
namespace {
using ::testing::ValuesIn;
using TextIntegerTest = MessageTypeConformanceTest;
// Extreme values in decimal.
TEST_P(TextIntegerTest, Int32FieldMaxValue) {
EXPECT_THAT(
Testee("Int32FieldMaxValue")
.ParseText(message(), R"pb(optional_int32: 2147483647)pb")
.SerializeBinary(),
Yields(WhenParsed(EqualsTextProto(R"pb(optional_int32: 2147483647)pb"))));
EXPECT_THAT(
Testee("Int32FieldMaxValue")
.ParseText(message(), R"pb(optional_int32: 2147483647)pb")
.SerializeText(),
Yields(WhenParsed(EqualsTextProto(R"pb(optional_int32: 2147483647)pb"))));
}
TEST_P(TextIntegerTest, Int32FieldMinValue) {
EXPECT_THAT(Testee("Int32FieldMinValue")
.ParseText(message(), R"pb(optional_int32: -2147483648)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int32: -2147483648)pb"))));
EXPECT_THAT(Testee("Int32FieldMinValue")
.ParseText(message(), R"pb(optional_int32: -2147483648)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int32: -2147483648)pb"))));
}
TEST_P(TextIntegerTest, Uint32FieldMaxValue) {
EXPECT_THAT(Testee("Uint32FieldMaxValue")
.ParseText(message(), R"pb(optional_uint32: 4294967295)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_uint32: 4294967295)pb"))));
EXPECT_THAT(Testee("Uint32FieldMaxValue")
.ParseText(message(), R"pb(optional_uint32: 4294967295)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_uint32: 4294967295)pb"))));
}
TEST_P(TextIntegerTest, Int64FieldMaxValue) {
EXPECT_THAT(
Testee("Int64FieldMaxValue")
.ParseText(message(), R"pb(optional_int64: 9223372036854775807)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int64: 9223372036854775807)pb"))));
EXPECT_THAT(
Testee("Int64FieldMaxValue")
.ParseText(message(), R"pb(optional_int64: 9223372036854775807)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int64: 9223372036854775807)pb"))));
}
// TODO: Write the plain-string inputs below as R"pb(...)pb" raw
// strings once the migration's request goldens are gone. The goldens pin the
// exact request bytes, and clang-format would reformat the whitespace of these
// inputs inside a pb raw string.
TEST_P(TextIntegerTest, Int64FieldMinValue) {
EXPECT_THAT(Testee("Int64FieldMinValue")
.ParseText(message(), "optional_int64: -9223372036854775808")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto("optional_int64: -9223372036854775808"))));
EXPECT_THAT(Testee("Int64FieldMinValue")
.ParseText(message(), "optional_int64: -9223372036854775808")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto("optional_int64: -9223372036854775808"))));
}
TEST_P(TextIntegerTest, Uint64FieldMaxValue) {
EXPECT_THAT(Testee("Uint64FieldMaxValue")
.ParseText(message(), "optional_uint64: 18446744073709551615")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto("optional_uint64: 18446744073709551615"))));
EXPECT_THAT(Testee("Uint64FieldMaxValue")
.ParseText(message(), "optional_uint64: 18446744073709551615")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto("optional_uint64: 18446744073709551615"))));
}
// Extreme values in hex; the responses are compared to the decimal form.
TEST_P(TextIntegerTest, Int32FieldMaxValueHex) {
EXPECT_THAT(
Testee("Int32FieldMaxValueHex")
.ParseText(message(), R"pb(optional_int32: 0x7FFFFFFF)pb")
.SerializeBinary(),
Yields(WhenParsed(EqualsTextProto(R"pb(optional_int32: 2147483647)pb"))));
EXPECT_THAT(
Testee("Int32FieldMaxValueHex")
.ParseText(message(), R"pb(optional_int32: 0x7FFFFFFF)pb")
.SerializeText(),
Yields(WhenParsed(EqualsTextProto(R"pb(optional_int32: 2147483647)pb"))));
}
TEST_P(TextIntegerTest, Int32FieldMinValueHex) {
EXPECT_THAT(Testee("Int32FieldMinValueHex")
.ParseText(message(), R"pb(optional_int32: -0x80000000)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int32: -2147483648)pb"))));
EXPECT_THAT(Testee("Int32FieldMinValueHex")
.ParseText(message(), R"pb(optional_int32: -0x80000000)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int32: -2147483648)pb"))));
}
TEST_P(TextIntegerTest, Uint32FieldMaxValueHex) {
EXPECT_THAT(Testee("Uint32FieldMaxValueHex")
.ParseText(message(), R"pb(optional_uint32: 0xFFFFFFFF)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_uint32: 4294967295)pb"))));
EXPECT_THAT(Testee("Uint32FieldMaxValueHex")
.ParseText(message(), R"pb(optional_uint32: 0xFFFFFFFF)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_uint32: 4294967295)pb"))));
}
TEST_P(TextIntegerTest, Int64FieldMaxValueHex) {
EXPECT_THAT(
Testee("Int64FieldMaxValueHex")
.ParseText(message(), R"pb(optional_int64: 0x7FFFFFFFFFFFFFFF)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int64: 9223372036854775807)pb"))));
EXPECT_THAT(
Testee("Int64FieldMaxValueHex")
.ParseText(message(), R"pb(optional_int64: 0x7FFFFFFFFFFFFFFF)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int64: 9223372036854775807)pb"))));
}
TEST_P(TextIntegerTest, Int64FieldMinValueHex) {
EXPECT_THAT(
Testee("Int64FieldMinValueHex")
.ParseText(message(), R"pb(optional_int64: -0x8000000000000000)pb")
.SerializeBinary(),
Yields(
WhenParsed(EqualsTextProto("optional_int64: -9223372036854775808"))));
EXPECT_THAT(
Testee("Int64FieldMinValueHex")
.ParseText(message(), R"pb(optional_int64: -0x8000000000000000)pb")
.SerializeText(),
Yields(
WhenParsed(EqualsTextProto("optional_int64: -9223372036854775808"))));
}
TEST_P(TextIntegerTest, Uint64FieldMaxValueHex) {
EXPECT_THAT(
Testee("Uint64FieldMaxValueHex")
.ParseText(message(), R"pb(optional_uint64: 0xFFFFFFFFFFFFFFFF)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto("optional_uint64: 18446744073709551615"))));
EXPECT_THAT(
Testee("Uint64FieldMaxValueHex")
.ParseText(message(), R"pb(optional_uint64: 0xFFFFFFFFFFFFFFFF)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto("optional_uint64: 18446744073709551615"))));
}
// Extreme values in octal.
TEST_P(TextIntegerTest, Int32FieldMaxValueOctal) {
EXPECT_THAT(
Testee("Int32FieldMaxValueOctal")
.ParseText(message(), R"pb(optional_int32: 017777777777)pb")
.SerializeBinary(),
Yields(WhenParsed(EqualsTextProto(R"pb(optional_int32: 2147483647)pb"))));
EXPECT_THAT(
Testee("Int32FieldMaxValueOctal")
.ParseText(message(), R"pb(optional_int32: 017777777777)pb")
.SerializeText(),
Yields(WhenParsed(EqualsTextProto(R"pb(optional_int32: 2147483647)pb"))));
}
TEST_P(TextIntegerTest, Int32FieldMinValueOctal) {
EXPECT_THAT(Testee("Int32FieldMinValueOctal")
.ParseText(message(), R"pb(optional_int32: -020000000000)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int32: -2147483648)pb"))));
EXPECT_THAT(Testee("Int32FieldMinValueOctal")
.ParseText(message(), R"pb(optional_int32: -020000000000)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int32: -2147483648)pb"))));
}
TEST_P(TextIntegerTest, Uint32FieldMaxValueOctal) {
EXPECT_THAT(Testee("Uint32FieldMaxValueOctal")
.ParseText(message(), R"pb(optional_uint32: 037777777777)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_uint32: 4294967295)pb"))));
EXPECT_THAT(Testee("Uint32FieldMaxValueOctal")
.ParseText(message(), R"pb(optional_uint32: 037777777777)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_uint32: 4294967295)pb"))));
}
TEST_P(TextIntegerTest, Int64FieldMaxValueOctal) {
EXPECT_THAT(
Testee("Int64FieldMaxValueOctal")
.ParseText(message(), R"pb(optional_int64: 0777777777777777777777)pb")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int64: 9223372036854775807)pb"))));
EXPECT_THAT(
Testee("Int64FieldMaxValueOctal")
.ParseText(message(), R"pb(optional_int64: 0777777777777777777777)pb")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto(R"pb(optional_int64: 9223372036854775807)pb"))));
}
TEST_P(TextIntegerTest, Int64FieldMinValueOctal) {
EXPECT_THAT(
Testee("Int64FieldMinValueOctal")
.ParseText(message(), "optional_int64: -01000000000000000000000")
.SerializeBinary(),
Yields(
WhenParsed(EqualsTextProto("optional_int64: -9223372036854775808"))));
EXPECT_THAT(
Testee("Int64FieldMinValueOctal")
.ParseText(message(), "optional_int64: -01000000000000000000000")
.SerializeText(),
Yields(
WhenParsed(EqualsTextProto("optional_int64: -9223372036854775808"))));
}
TEST_P(TextIntegerTest, Uint64FieldMaxValueOctal) {
EXPECT_THAT(
Testee("Uint64FieldMaxValueOctal")
.ParseText(message(), "optional_uint64: 01777777777777777777777")
.SerializeBinary(),
Yields(WhenParsed(
EqualsTextProto("optional_uint64: 18446744073709551615"))));
EXPECT_THAT(
Testee("Uint64FieldMaxValueOctal")
.ParseText(message(), "optional_uint64: 01777777777777777777777")
.SerializeText(),
Yields(WhenParsed(
EqualsTextProto("optional_uint64: 18446744073709551615"))));
}
// Parsers reject out-of-bound integer values.
TEST_P(TextIntegerTest, Int32FieldTooLarge) {
EXPECT_THAT(Testee("Int32FieldTooLarge")
.ParseText(message(), R"pb(optional_int32: 2147483648)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Int32FieldTooSmall) {
EXPECT_THAT(Testee("Int32FieldTooSmall")
.ParseText(message(), R"pb(optional_int32: -2147483649)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Uint32FieldTooLarge) {
EXPECT_THAT(Testee("Uint32FieldTooLarge")
.ParseText(message(), R"pb(optional_uint32: 4294967296)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Int64FieldTooLarge) {
EXPECT_THAT(
Testee("Int64FieldTooLarge")
.ParseText(message(), R"pb(optional_int64: 9223372036854775808)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Int64FieldTooSmall) {
EXPECT_THAT(Testee("Int64FieldTooSmall")
.ParseText(message(), "optional_int64: -9223372036854775809")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Uint64FieldTooLarge) {
EXPECT_THAT(Testee("Uint64FieldTooLarge")
.ParseText(message(), "optional_uint64: 18446744073709551616")
.ParseOnly(),
Yields(IsParseError()));
}
// ... in hex
TEST_P(TextIntegerTest, Int32FieldTooLargeHex) {
EXPECT_THAT(Testee("Int32FieldTooLargeHex")
.ParseText(message(), R"pb(optional_int32: 0x80000000)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Int32FieldTooSmallHex) {
EXPECT_THAT(Testee("Int32FieldTooSmallHex")
.ParseText(message(), R"pb(optional_int32: -0x80000001)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Uint32FieldTooLargeHex) {
EXPECT_THAT(Testee("Uint32FieldTooLargeHex")
.ParseText(message(), R"pb(optional_uint32: 0x100000000)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Int64FieldTooLargeHex) {
EXPECT_THAT(
Testee("Int64FieldTooLargeHex")
.ParseText(message(), R"pb(optional_int64: 0x8000000000000000)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Int64FieldTooSmallHex) {
EXPECT_THAT(
Testee("Int64FieldTooSmallHex")
.ParseText(message(), R"pb(optional_int64: -0x8000000000000001)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Uint64FieldTooLargeHex) {
EXPECT_THAT(Testee("Uint64FieldTooLargeHex")
.ParseText(message(), "optional_uint64: 0x10000000000000000")
.ParseOnly(),
Yields(IsParseError()));
}
// ... and in octal.
TEST_P(TextIntegerTest, Int32FieldTooLargeOctal) {
EXPECT_THAT(Testee("Int32FieldTooLargeOctal")
.ParseText(message(), R"pb(optional_int32: 020000000000)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Int32FieldTooSmallOctal) {
EXPECT_THAT(Testee("Int32FieldTooSmallOctal")
.ParseText(message(), R"pb(optional_int32: -020000000001)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Uint32FieldTooLargeOctal) {
EXPECT_THAT(Testee("Uint32FieldTooLargeOctal")
.ParseText(message(), R"pb(optional_uint32: 040000000000)pb")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Int64FieldTooLargeOctal) {
EXPECT_THAT(
Testee("Int64FieldTooLargeOctal")
.ParseText(message(), "optional_int64: 01000000000000000000000")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Int64FieldTooSmallOctal) {
EXPECT_THAT(
Testee("Int64FieldTooSmallOctal")
.ParseText(message(), "optional_int64: -01000000000000000000001")
.ParseOnly(),
Yields(IsParseError()));
}
TEST_P(TextIntegerTest, Uint64FieldTooLargeOctal) {
EXPECT_THAT(
Testee("Uint64FieldTooLargeOctal")
.ParseText(message(), "optional_uint64: 02000000000000000000000")
.ParseOnly(),
Yields(IsParseError()));
}
INSTANTIATE_TEST_SUITE_P(All, TextIntegerTest,
ValuesIn(Proto3TestMessageTypes()),
MessageTypeParamName);
} // namespace
} // namespace conformance
} // namespace protobuf
} // namespace google