LCOV - code coverage report
Current view: top level - engine/semantic - value_parameters_test.cc (source / functions) Coverage Total Hit
Test: _coverage_report.dat Lines: 100.0 % 89 89
Test Date: 2026-08-08 08:38:15 Functions: 100.0 % 9 9

            Line data    Source code
       1              : // Matrix coverage for ParseParameterValue wire forms (query-parameter
       2              : // wire-form matrix).
       3              : #include "absl/time/time.h"
       4              : #include "backend/engine/semantic/value.h"
       5              : #include "googlesql/public/numeric_value.h"
       6              : #include "googlesql/public/type.h"
       7              : #include "googlesql/public/value.h"
       8              : #include "gtest/gtest.h"
       9              : 
      10              : namespace bigquery_emulator {
      11              : namespace backend {
      12              : namespace engine {
      13              : namespace semantic {
      14              : namespace {
      15              : 
      16              : struct ParameterMatrixCase {
      17              :   const char* type_kind;
      18              :   const char* type_json;
      19              :   const char* value_json;
      20              :   bool should_succeed;
      21              :   const char* label;
      22              : };
      23              : 
      24            1 : std::vector<ParameterMatrixCase> AcceptedMatrixCases() {
      25            1 :   return {
      26            1 :       {"TIMESTAMP",
      27            1 :        nullptr,
      28            1 :        "2026-06-22T10:00:00",
      29            1 :        true,
      30            1 :        "timestamp_naive_iso_t"},
      31            1 :       {"TIMESTAMP", nullptr, "2026-06-22 10:00:00", true, "timestamp_space"},
      32            1 :       {"TIMESTAMP", nullptr, "2026-06-22T10:00:00Z", true, "timestamp_z"},
      33            1 :       {"TIMESTAMP",
      34            1 :        nullptr,
      35            1 :        "2026-06-22T10:00:00+00:00",
      36            1 :        true,
      37            1 :        "timestamp_offset"},
      38            1 :       {"TIMESTAMP",
      39            1 :        nullptr,
      40            1 :        "2026-06-22T10:00:00.123456",
      41            1 :        true,
      42            1 :        "timestamp_fractional"},
      43            1 :       {"TIMESTAMP", nullptr, "2026-06-22", true, "timestamp_date_only"},
      44            1 :       {"DATE", nullptr, "2020-06-15", true, "date_iso"},
      45            1 :       {"DATETIME", nullptr, "2020-06-15 12:30:45", true, "datetime_space"},
      46            1 :       {"DATETIME", nullptr, "2020-06-15T12:30:45", true, "datetime_iso_t"},
      47            1 :       {"TIME", nullptr, "12:30:45", true, "time_hms"},
      48            1 :       {"TIME", nullptr, "12:30:45.123456", true, "time_fractional"},
      49            1 :       {"NUMERIC", nullptr, "3.14159", true, "numeric"},
      50            1 :       {"BIGNUMERIC",
      51            1 :        nullptr,
      52            1 :        "99999999999999999999999999999.999999999",
      53            1 :        true,
      54            1 :        "bignumeric"},
      55            1 :       {"BOOL", nullptr, "true", true, "bool_true"},
      56            1 :       {"BOOL", nullptr, "false", true, "bool_false"},
      57            1 :       {"BYTES", nullptr, "\"SGVsbG8=\"", true, "bytes_base64"},
      58            1 :       {"ARRAY", "STRING", R"(["a","b"])", true, "array_string"},
      59            1 :       {"STRUCT", "x:INT64,y:STRING", R"(["1","foo"])", true, "struct_mixed"},
      60            1 :   };
      61            1 : }
      62              : 
      63            1 : std::vector<ParameterMatrixCase> RejectedMatrixCases() {
      64            1 :   return {
      65            1 :       {"TIMESTAMP", nullptr, "not-a-timestamp", false, "timestamp_garbage"},
      66            1 :       {"DATE", nullptr, "2020-13-45", false, "date_invalid"},
      67            1 :       {"BOOL", nullptr, "yes", false, "bool_garbage"},
      68            1 :       {"BYTES", nullptr, "\"!!!\"", false, "bytes_invalid_base64"},
      69            1 :   };
      70            1 : }
      71              : 
      72              : class ParameterMatrixTest : public testing::TestWithParam<ParameterMatrixCase> {
      73              : };
      74              : 
      75           22 : TEST_P(ParameterMatrixTest, ParseParameterValue) {
      76           22 :   const ParameterMatrixCase& c = GetParam();
      77           22 :   absl::string_view type_json = c.type_json != nullptr ? c.type_json : "";
      78           22 :   auto result = ParseParameterValue(c.value_json, c.type_kind, type_json);
      79           22 :   if (c.should_succeed) {
      80           36 :     ASSERT_TRUE(result.ok()) << c.label << ": " << result.status();
      81           18 :   } else {
      82            8 :     ASSERT_FALSE(result.ok()) << c.label;
      83            4 :   }
      84           22 : }
      85              : 
      86              : INSTANTIATE_TEST_SUITE_P(
      87              :     Accepted,
      88              :     ParameterMatrixTest,
      89              :     testing::ValuesIn(AcceptedMatrixCases()),
      90              :     [](const testing::TestParamInfo<ParameterMatrixCase>& info) {
      91              :       return info.param.label;
      92              :     });
      93              : 
      94              : INSTANTIATE_TEST_SUITE_P(
      95              :     Rejected,
      96              :     ParameterMatrixTest,
      97              :     testing::ValuesIn(RejectedMatrixCases()),
      98              :     [](const testing::TestParamInfo<ParameterMatrixCase>& info) {
      99              :       return info.param.label;
     100              :     });
     101              : 
     102            1 : TEST(ValueParametersTest, TimestampNaiveIsoDefaultsToUtc) {
     103            1 :   auto v = ParseParameterValue("2026-06-22T10:00:00", "TIMESTAMP");
     104            2 :   ASSERT_TRUE(v.ok()) << v.status();
     105            1 :   EXPECT_EQ(absl::ToUnixSeconds(v->ToTime()), 1782122400);
     106            1 : }
     107              : 
     108            1 : TEST(ValueParametersTest, DateRoundTrips) {
     109            1 :   auto v = ParseParameterValue("2020-06-15", "DATE");
     110            2 :   ASSERT_TRUE(v.ok()) << v.status();
     111            1 :   EXPECT_EQ(v->type_kind(), ::googlesql::TYPE_DATE);
     112            1 :   EXPECT_FALSE(v->is_null());
     113            1 : }
     114              : 
     115            1 : TEST(ValueParametersTest, DatetimeSpaceForm) {
     116            1 :   auto v = ParseParameterValue("2020-06-15 12:30:45", "DATETIME");
     117            2 :   ASSERT_TRUE(v.ok()) << v.status();
     118            1 :   EXPECT_EQ(v->type_kind(), ::googlesql::TYPE_DATETIME);
     119            1 : }
     120              : 
     121            1 : TEST(ValueParametersTest, TimeFractionalSeconds) {
     122            1 :   auto v = ParseParameterValue("12:30:45.123456", "TIME");
     123            2 :   ASSERT_TRUE(v.ok()) << v.status();
     124            1 :   EXPECT_EQ(v->type_kind(), ::googlesql::TYPE_TIME);
     125            1 : }
     126              : 
     127            1 : TEST(ValueParametersTest, BytesBase64RoundTrips) {
     128            1 :   auto v = ParseParameterValue("\"SGVsbG8=\"", "BYTES");
     129            2 :   ASSERT_TRUE(v.ok()) << v.status();
     130            1 :   EXPECT_EQ(v->bytes_value(), "Hello");
     131            1 : }
     132              : 
     133            1 : TEST(ValueParametersTest, NumericAndBigNumeric) {
     134            1 :   auto n = ParseParameterValue("1.5", "NUMERIC");
     135            2 :   ASSERT_TRUE(n.ok()) << n.status();
     136            1 :   auto bn = ParseParameterValue("99999999999999999999999999999.999999999",
     137            1 :                                 "BIGNUMERIC");
     138            2 :   ASSERT_TRUE(bn.ok()) << bn.status();
     139            1 : }
     140              : 
     141              : }  // namespace
     142              : }  // namespace semantic
     143              : }  // namespace engine
     144              : }  // namespace backend
     145              : }  // namespace bigquery_emulator
        

Generated by: LCOV version 2.0-1