Skip to content

Commit

Permalink
Print content of columns for gtest (#5243)
Browse files Browse the repository at this point in the history
close #5203
  • Loading branch information
xzhangxian1008 authored Jul 11, 2022
1 parent 2af78c5 commit cf7aa5e
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
56 changes: 56 additions & 0 deletions dbms/src/TestUtils/FunctionTestUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

#include <Columns/ColumnNullable.h>
#include <Common/FmtUtils.h>
#include <Core/ColumnNumbers.h>
#include <Core/Row.h>
#include <DataTypes/DataTypeNothing.h>
Expand Down Expand Up @@ -120,6 +121,7 @@ ::testing::AssertionResult blockEqual(
{
const auto & expected_col = expected.getByPosition(i);
const auto & actual_col = actual.getByPosition(i);

auto cmp_res = columnEqual(expected_col, actual_col);
if (!cmp_res)
return cmp_res;
Expand Down Expand Up @@ -375,9 +377,63 @@ ColumnWithTypeAndName toNullableDatetimeVec(String name, const std::vector<Strin
return {makeColumn<Nullable<MyDateTime>>(data_type, vec), data_type, name, 0};
}

String getColumnsContent(const ColumnsWithTypeAndName & cols)
{
if (cols.size() <= 0)
return "";
return getColumnsContent(cols, 0, cols[0].column->size() - 1);
}

String getColumnsContent(const ColumnsWithTypeAndName & cols, size_t begin, size_t end)
{
const size_t col_num = cols.size();
if (col_num <= 0)
return "";

const size_t col_size = cols[0].column->size();
assert(begin <= end);
assert(col_size > end);
assert(col_size > begin);

bool is_same = true;

for (size_t i = 1; i < col_num; ++i)
{
if (cols[i].column->size() != col_size)
is_same = false;
}

assert(is_same); /// Ensure the sizes of columns in cols are the same

std::vector<std::pair<size_t, String>> col_content;
FmtBuffer fmt_buf;
for (size_t i = 0; i < col_num; ++i)
{
/// Push the column name
fmt_buf.append(fmt::format("{}: (", cols[i].name));
for (size_t j = begin; j <= end; ++j)
col_content.push_back(std::make_pair(j, (*cols[i].column)[j].toString()));

/// Add content
fmt_buf.joinStr(
col_content.begin(),
col_content.end(),
[](const auto & content, FmtBuffer & fmt_buf) {
fmt_buf.append(fmt::format("{}: {}", content.first, content.second));
},
", ");

fmt_buf.append(")\n");
col_content.clear();
}

return fmt_buf.toString();
}

ColumnsWithTypeAndName createColumns(const ColumnsWithTypeAndName & cols)
{
return cols;
}

} // namespace tests
} // namespace DB
6 changes: 5 additions & 1 deletion dbms/src/TestUtils/FunctionTestUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -514,13 +514,17 @@ ColumnWithTypeAndName createConstColumn(
return createConstColumn<T>(data_type_args, size, InferredFieldType<T>(std::nullopt), name);
}

String getColumnsContent(const ColumnsWithTypeAndName & cols);

/// We can designate the range of columns printed with begin and end. range: [begin, end]
String getColumnsContent(const ColumnsWithTypeAndName & cols, size_t begin, size_t end);

// This wrapper function only serves to construct columns input for function-like macros,
// since preprocessor recognizes `{col1, col2, col3}` as three arguments instead of one.
// E.g. preprocessor does not allow us to write `ASSERT_COLUMNS_EQ_R({col1, col2, col3}, actual_cols)`,
// but with this func we can write `ASSERT_COLUMNS_EQ_R(createColumns{col1, col2, col3}, actual_cols)` instead.
ColumnsWithTypeAndName createColumns(const ColumnsWithTypeAndName & cols);


::testing::AssertionResult dataTypeEqual(
const DataTypePtr & expected,
const DataTypePtr & actual);
Expand Down
57 changes: 57 additions & 0 deletions dbms/src/TestUtils/tests/gtest_print_columns.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2022 PingCAP, Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <TestUtils/ExecutorTestUtils.h>
#include <TestUtils/mockExecutor.h>

namespace DB
{
namespace tests
{

class PrintColumnsTest : public DB::tests::ExecutorTest
{
public:
using ColStringType = std::optional<typename TypeTraits<String>::FieldType>;
using ColInt32Type = std::optional<typename TypeTraits<Int32>::FieldType>;
using ColumnWithString = std::vector<ColStringType>;
using ColumnWithInt32 = std::vector<ColInt32Type>;

void initializeContext() override
{
test_cols.push_back(toNullableVec<Int32>("col1", ColumnWithInt32{36, 34, 32, 27, {}, {}}));
test_cols.push_back(toNullableVec<String>("col2", ColumnWithString{"female", "male", "male", "female", "male", "female"}));
col_len = test_cols[0].column->size();
}

ColumnsWithTypeAndName test_cols;
size_t col_len;
const String result1{"col1: (0: Int64_36, 1: Int64_34, 2: Int64_32, 3: Int64_27, 4: NULL, 5: NULL)\ncol2: (0: 'female', 1: 'male', 2: 'male', 3: 'female', 4: 'male', 5: 'female')\n"};
const String result2{"col1: (0: Int64_36, 1: Int64_34, 2: Int64_32, 3: Int64_27, 4: NULL, 5: NULL)\ncol2: (0: 'female', 1: 'male', 2: 'male', 3: 'female', 4: 'male', 5: 'female')\n"};
const String result3{"col1: (0: Int64_36)\ncol2: (0: 'female')\n"};
const String result4{"col1: (1: Int64_34, 2: Int64_32, 3: Int64_27, 4: NULL)\ncol2: (1: 'male', 2: 'male', 3: 'female', 4: 'male')\n"};
};

TEST_F(PrintColumnsTest, SimpleTest)
try
{
EXPECT_EQ(getColumnsContent(test_cols), result1);
EXPECT_EQ(getColumnsContent(test_cols, 0, col_len - 1), result2);
EXPECT_EQ(getColumnsContent(test_cols, 0, 0), result3);
EXPECT_EQ(getColumnsContent(test_cols, 1, col_len - 2), result4);
}
CATCH

} // namespace tests
} // namespace DB

0 comments on commit cf7aa5e

Please sign in to comment.