11#include < gtest/gtest.h>
22
3+ #include < limits>
4+ #include < stdexcept>
5+
36#include < storages/postgres/detail/connection.hpp>
47#include < storages/postgres/tests/test_buffers.hpp>
58#include < storages/postgres/tests/util_pgtest.hpp>
@@ -20,6 +23,23 @@ class PostgreIOIntegral : public ::testing::Test {};
2023
2124using IntTypes = ::testing::Types<pg::Smallint, pg::Integer, pg::Bigint, short , int , long , long long >;
2225
26+ template <typename TPgType, typename TValueType>
27+ struct NarrowingTypes {
28+ using PgType = TPgType;
29+ using ValueType = TValueType;
30+ };
31+
32+ template <typename NarrowingTypes>
33+ class PostgreIOIntegralNarrowing : public ::testing::Test {
34+ using PgType = typename NarrowingTypes::PgType;
35+ using ValueType = typename NarrowingTypes::ValueType;
36+ };
37+
38+ using NarrowingTestTypes = ::testing::Types<
39+ NarrowingTypes<pg::Integer, pg::Smallint>,
40+ NarrowingTypes<pg::Bigint, pg::Smallint>,
41+ NarrowingTypes<pg::Bigint, pg::Integer> >;
42+
2343} // namespace
2444
2545TEST (PostgreIOIntegral, ParserRegistry) {
@@ -48,14 +68,51 @@ TYPED_TEST(PostgreIOIntegral, Int) {
4868 static_assert (tt::kIsMappedToPg <TypeParam>, " missing mapping" );
4969 static_assert (tt::kHasFormatter <TypeParam>, " missing binary formatter" );
5070 static_assert (tt::kHasParser <TypeParam>, " missing binary parser" );
71+ using Limits = std::numeric_limits<TypeParam>;
5172
52- pg::test::Buffer buffer;
53- const TypeParam src{42 };
54- UEXPECT_NO_THROW (io::WriteBuffer (types, buffer, src));
55- auto fb = pg::test::MakeFieldBuffer (buffer, io::BufferCategory::kPlainBuffer );
56- TypeParam tgt{0 };
57- UEXPECT_NO_THROW (io::ReadBuffer (fb, tgt));
58- EXPECT_EQ (src, tgt);
73+ for (const TypeParam src :
74+ {Limits::lowest (), TypeParam (-42 ), TypeParam (-1 ), TypeParam (0 ), TypeParam (1 ), TypeParam (42 ), Limits::max ()})
75+ {
76+ pg::test::Buffer buffer;
77+ UEXPECT_NO_THROW (io::WriteBuffer (types, buffer, src));
78+ auto fb = pg::test::MakeFieldBuffer (buffer, io::BufferCategory::kPlainBuffer );
79+ TypeParam tgt{0 };
80+ UEXPECT_NO_THROW (io::ReadBuffer (fb, tgt));
81+ EXPECT_EQ (src, tgt);
82+ }
83+ }
84+
85+ TYPED_TEST_SUITE (PostgreIOIntegralNarrowing, NarrowingTestTypes);
86+
87+ TYPED_TEST (PostgreIOIntegralNarrowing, Success) {
88+ using ValueType = typename TypeParam::ValueType;
89+ using Limits = std::numeric_limits<ValueType>;
90+
91+ for (const ValueType src :
92+ {Limits::lowest (), ValueType (-42 ), ValueType (-1 ), ValueType (0 ), ValueType (1 ), ValueType (42 ), Limits::max ()})
93+ {
94+ pg::test::Buffer buffer;
95+ const typename TypeParam::PgType output = src;
96+ UEXPECT_NO_THROW (io::WriteBuffer (types, buffer, output));
97+ auto fb = pg::test::MakeFieldBuffer (buffer, io::BufferCategory::kPlainBuffer );
98+ ValueType tgt{0 };
99+ UEXPECT_NO_THROW (io::ReadBuffer (fb, tgt));
100+ EXPECT_EQ (src, tgt);
101+ }
102+ }
103+
104+ TYPED_TEST (PostgreIOIntegralNarrowing, Fail) {
105+ using ValueType = typename TypeParam::ValueType;
106+ using PgType = typename TypeParam::PgType;
107+ using Limits = std::numeric_limits<ValueType>;
108+
109+ for (const PgType src : {static_cast <PgType>(Limits::lowest ()) - 1 , static_cast <PgType>(Limits::max ()) + 1 }) {
110+ pg::test::Buffer buffer;
111+ UEXPECT_NO_THROW (io::WriteBuffer (types, buffer, src));
112+ auto fb = pg::test::MakeFieldBuffer (buffer, io::BufferCategory::kPlainBuffer );
113+ ValueType tgt{0 };
114+ UEXPECT_THROW (io::ReadBuffer (fb, tgt), std::runtime_error);
115+ }
59116}
60117
61118USERVER_NAMESPACE_END
0 commit comments