Skip to content

Commit

Permalink
prints type/value parameters when listing tests
Browse files Browse the repository at this point in the history
git-svn-id: http://googletest.googlecode.com/svn/trunk@652 861a406c-534a-0410-8894-cb66d6ee9925
  • Loading branch information
zhanyong.wan committed Apr 10, 2013
1 parent 1189230 commit b3d0b4e
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 39 deletions.
54 changes: 49 additions & 5 deletions src/gtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2638,19 +2638,24 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_end(args);
}

// Text printed in Google Test's text output and --gunit_list_tests
// output to label the type parameter and value parameter for a test.
static const char kTypeParamLabel[] = "TypeParam";
static const char kValueParamLabel[] = "GetParam()";

void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
const char* const type_param = test_info.type_param();
const char* const value_param = test_info.value_param();

if (type_param != NULL || value_param != NULL) {
printf(", where ");
if (type_param != NULL) {
printf("TypeParam = %s", type_param);
printf("%s = %s", kTypeParamLabel, type_param);
if (value_param != NULL)
printf(" and ");
}
if (value_param != NULL) {
printf("GetParam() = %s", value_param);
printf("%s = %s", kValueParamLabel, value_param);
}
}
}
Expand Down Expand Up @@ -2735,7 +2740,7 @@ void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
if (test_case.type_param() == NULL) {
printf("\n");
} else {
printf(", where TypeParam = %s\n", test_case.type_param());
printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param());
}
fflush(stdout);
}
Expand Down Expand Up @@ -4408,8 +4413,33 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
return num_selected_tests;
}

// Prints the given C-string on a single line by replacing all '\n'
// characters with string "\\n". If the output takes more than
// max_length characters, only prints the first max_length characters
// and "...".
static void PrintOnOneLine(const char* str, int max_length) {
if (str != NULL) {
for (int i = 0; *str != '\0'; ++str) {
if (i >= max_length) {
printf("...");
break;
}
if (*str == '\n') {
printf("\\n");
i += 2;
} else {
printf("%c", *str);
++i;
}
}
}
}

// Prints the names of the tests matching the user-specified filter flag.
void UnitTestImpl::ListTestsMatchingFilter() {
// Print at most this many characters for each type/value parameter.
const int kMaxParamLength = 250;

for (size_t i = 0; i < test_cases_.size(); i++) {
const TestCase* const test_case = test_cases_[i];
bool printed_test_case_name = false;
Expand All @@ -4420,9 +4450,23 @@ void UnitTestImpl::ListTestsMatchingFilter() {
if (test_info->matches_filter_) {
if (!printed_test_case_name) {
printed_test_case_name = true;
printf("%s.\n", test_case->name());
printf("%s.", test_case->name());
if (test_case->type_param() != NULL) {
printf(" # %s = ", kTypeParamLabel);
// We print the type parameter on a single line to make
// the output easy to parse by a program.
PrintOnOneLine(test_case->type_param(), kMaxParamLength);
}
printf("\n");
}
printf(" %s", test_info->name());
if (test_info->value_param() != NULL) {
printf(" # %s = ", kValueParamLabel);
// We print the value parameter on a single line to make the
// output easy to parse by a program.
PrintOnOneLine(test_info->value_param(), kMaxParamLength);
}
printf(" %s\n", test_info->name());
printf("\n");
}
}
}
Expand Down
92 changes: 61 additions & 31 deletions test/gtest_list_tests_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
__author__ = 'phanna@google.com (Patrick Hanna)'

import gtest_test_utils
import re


# Constants.
Expand All @@ -52,38 +53,63 @@

# The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests
EXPECTED_OUTPUT_NO_FILTER = """FooDeathTest.
EXPECTED_OUTPUT_NO_FILTER_RE = re.compile(r"""FooDeathTest\.
Test1
Foo.
Foo\.
Bar1
Bar2
DISABLED_Bar3
Abc.
Abc\.
Xyz
Def
FooBar.
FooBar\.
Baz
FooTest.
FooTest\.
Test1
DISABLED_Test2
Test3
"""
TypedTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
TestA
TestB
TypedTest/1\. # TypeParam = int\s*\*
TestA
TestB
TypedTest/2\. # TypeParam = .*MyArray<bool,\s*42>
TestA
TestB
My/TypeParamTest/0\. # TypeParam = (VeryLo{245}|class VeryLo{239})\.\.\.
TestA
TestB
My/TypeParamTest/1\. # TypeParam = int\s*\*
TestA
TestB
My/TypeParamTest/2\. # TypeParam = .*MyArray<bool,\s*42>
TestA
TestB
MyInstantiation/ValueParamTest\.
TestA/0 # GetParam\(\) = one line
TestA/1 # GetParam\(\) = two\\nlines
TestA/2 # GetParam\(\) = a very\\nlo{241}\.\.\.
TestB/0 # GetParam\(\) = one line
TestB/1 # GetParam\(\) = two\\nlines
TestB/2 # GetParam\(\) = a very\\nlo{241}\.\.\.
""")

# The expected output when running gtest_list_tests_unittest_ with
# --gtest_list_tests and --gtest_filter=Foo*.
EXPECTED_OUTPUT_FILTER_FOO = """FooDeathTest.
EXPECTED_OUTPUT_FILTER_FOO_RE = re.compile(r"""FooDeathTest\.
Test1
Foo.
Foo\.
Bar1
Bar2
DISABLED_Bar3
FooBar.
FooBar\.
Baz
FooTest.
FooTest\.
Test1
DISABLED_Test2
Test3
"""
""")

# Utilities.

Expand All @@ -100,19 +126,18 @@ def Run(args):
class GTestListTestsUnitTest(gtest_test_utils.TestCase):
"""Tests using the --gtest_list_tests flag to list all tests."""

def RunAndVerify(self, flag_value, expected_output, other_flag):
def RunAndVerify(self, flag_value, expected_output_re, other_flag):
"""Runs gtest_list_tests_unittest_ and verifies that it prints
the correct tests.
Args:
flag_value: value of the --gtest_list_tests flag;
None if the flag should not be present.
expected_output: the expected output after running command;
other_flag: a different flag to be passed to command
along with gtest_list_tests;
None if the flag should not be present.
flag_value: value of the --gtest_list_tests flag;
None if the flag should not be present.
expected_output_re: regular expression that matches the expected
output after running command;
other_flag: a different flag to be passed to command
along with gtest_list_tests;
None if the flag should not be present.
"""

if flag_value is None:
Expand All @@ -132,44 +157,49 @@ def RunAndVerify(self, flag_value, expected_output, other_flag):

output = Run(args)

msg = ('when %s is %s, the output of "%s" is "%s".' %
(LIST_TESTS_FLAG, flag_expression, ' '.join(args), output))

if expected_output is not None:
self.assert_(output == expected_output, msg)
if expected_output_re:
self.assert_(
expected_output_re.match(output),
('when %s is %s, the output of "%s" is "%s",\n'
'which does not match regex "%s"' %
(LIST_TESTS_FLAG, flag_expression, ' '.join(args), output,
expected_output_re.pattern)))
else:
self.assert_(output != EXPECTED_OUTPUT_NO_FILTER, msg)
self.assert_(
not EXPECTED_OUTPUT_NO_FILTER_RE.match(output),
('when %s is %s, the output of "%s" is "%s"'%
(LIST_TESTS_FLAG, flag_expression, ' '.join(args), output)))

def testDefaultBehavior(self):
"""Tests the behavior of the default mode."""

self.RunAndVerify(flag_value=None,
expected_output=None,
expected_output_re=None,
other_flag=None)

def testFlag(self):
"""Tests using the --gtest_list_tests flag."""

self.RunAndVerify(flag_value='0',
expected_output=None,
expected_output_re=None,
other_flag=None)
self.RunAndVerify(flag_value='1',
expected_output=EXPECTED_OUTPUT_NO_FILTER,
expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE,
other_flag=None)

def testOverrideNonFilterFlags(self):
"""Tests that --gtest_list_tests overrides the non-filter flags."""

self.RunAndVerify(flag_value='1',
expected_output=EXPECTED_OUTPUT_NO_FILTER,
expected_output_re=EXPECTED_OUTPUT_NO_FILTER_RE,
other_flag='--gtest_break_on_failure')

def testWithFilterFlags(self):
"""Tests that --gtest_list_tests takes into account the
--gtest_filter flag."""

self.RunAndVerify(flag_value='1',
expected_output=EXPECTED_OUTPUT_FILTER_FOO,
expected_output_re=EXPECTED_OUTPUT_FILTER_FOO_RE,
other_flag='--gtest_filter=Foo*')


Expand Down
78 changes: 75 additions & 3 deletions test/gtest_list_tests_unittest_.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@

#include "gtest/gtest.h"

namespace {

// Several different test cases and tests that will be listed.
TEST(Foo, Bar1) {
}
Expand Down Expand Up @@ -76,7 +74,81 @@ TEST_F(FooTest, Test3) {
TEST(FooDeathTest, Test1) {
}

} // namespace
// A group of value-parameterized tests.

class MyType {
public:
explicit MyType(const std::string& a_value) : value_(a_value) {}

const std::string& value() const { return value_; }

private:
std::string value_;
};

// Teaches Google Test how to print a MyType.
void PrintTo(const MyType& x, std::ostream* os) {
*os << x.value();
}

class ValueParamTest : public testing::TestWithParam<MyType> {
};

TEST_P(ValueParamTest, TestA) {
}

TEST_P(ValueParamTest, TestB) {
}

INSTANTIATE_TEST_CASE_P(
MyInstantiation, ValueParamTest,
testing::Values(MyType("one line"),
MyType("two\nlines"),
MyType("a very\nloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong line"))); // NOLINT

// A group of typed tests.

// A deliberately long type name for testing the line-truncating
// behavior when printing a type parameter.
class VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName { // NOLINT
};

template <typename T>
class TypedTest : public testing::Test {
};

template <typename T, int kSize>
class MyArray {
};

typedef testing::Types<VeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooogName, // NOLINT
int*, MyArray<bool, 42> > MyTypes;

TYPED_TEST_CASE(TypedTest, MyTypes);

TYPED_TEST(TypedTest, TestA) {
}

TYPED_TEST(TypedTest, TestB) {
}

// A group of type-parameterized tests.

template <typename T>
class TypeParamTest : public testing::Test {
};

TYPED_TEST_CASE_P(TypeParamTest);

TYPED_TEST_P(TypeParamTest, TestA) {
}

TYPED_TEST_P(TypeParamTest, TestB) {
}

REGISTER_TYPED_TEST_CASE_P(TypeParamTest, TestA, TestB);

INSTANTIATE_TYPED_TEST_CASE_P(My, TypeParamTest, MyTypes);

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
Expand Down

0 comments on commit b3d0b4e

Please sign in to comment.