Avi Drissman | dfd88085 | 2022-09-15 20:11:09 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Gayane Petrosyan | 945148b | 2021-11-04 18:52:03 | [diff] [blame] | 5 | #include "testing/data_driven_testing/data_driven_test.h" |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 6 | |
[email protected] | 25a4c1c | 2013-06-08 04:53:36 | [diff] [blame] | 7 | #include "base/files/file_enumerator.h" |
thestig | 819adcc8 | 2014-09-10 22:24:53 | [diff] [blame] | 8 | #include "base/files/file_util.h" |
[email protected] | 4cc42fe | 2013-06-11 04:17:10 | [diff] [blame] | 9 | #include "base/strings/string_util.h" |
jam | 3f2d393 | 2017-04-26 20:28:51 | [diff] [blame] | 10 | #include "base/threading/thread_restrictions.h" |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 11 | #include "testing/gtest/include/gtest/gtest.h" |
Dominic Battre | 5010349 | 2019-09-19 08:38:11 | [diff] [blame] | 12 | #include "third_party/re2/src/re2/re2.h" |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 13 | |
Gayane Petrosyan | 945148b | 2021-11-04 18:52:03 | [diff] [blame] | 14 | namespace testing { |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 15 | namespace { |
| 16 | |
| 17 | // Reads |file| into |content|, and converts Windows line-endings to Unix ones. |
| 18 | // Returns true on success. |
[email protected] | 650b2d5 | 2013-02-10 03:41:45 | [diff] [blame] | 19 | bool ReadFile(const base::FilePath& file, std::string* content) { |
[email protected] | 82f84b9 | 2013-08-30 18:23:50 | [diff] [blame] | 20 | if (!base::ReadFileToString(file, content)) |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 21 | return false; |
| 22 | |
brettw | e6dae46 | 2015-06-24 20:54:45 | [diff] [blame] | 23 | base::ReplaceSubstringsAfterOffset(content, 0, "\r\n", "\n"); |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 24 | return true; |
| 25 | } |
| 26 | |
| 27 | // Write |content| to |file|. Returns true on success. |
[email protected] | 650b2d5 | 2013-02-10 03:41:45 | [diff] [blame] | 28 | bool WriteFile(const base::FilePath& file, const std::string& content) { |
Claudio DeSouza | 94ad878 | 2023-02-27 09:05:41 | [diff] [blame] | 29 | return base::WriteFile(file, content); |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 30 | } |
| 31 | |
Dominic Battre | 5010349 | 2019-09-19 08:38:11 | [diff] [blame] | 32 | // Removes lines starting with (optional) whitespace and a #. |
| 33 | void StripComments(std::string* content) { |
| 34 | RE2::GlobalReplace( |
| 35 | content, |
| 36 | // Enable multi-line mode, ^ and $ match begin/end line in addition to |
| 37 | // begin/end text. |
| 38 | "(?m)" |
| 39 | // Search for start of lines (^), ignore spaces (\\s*), and then look for |
| 40 | // '#'. |
| 41 | "^\\s*#" |
| 42 | // Consume all characters (.*) until end of line ($). |
| 43 | ".*$" |
| 44 | // Consume the line wrapping so that the entire line is gone. |
| 45 | "[\\r\\n]*", |
| 46 | // Replace entire line with empty string. |
| 47 | ""); |
| 48 | } |
| 49 | |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 50 | } // namespace |
| 51 | |
| 52 | void DataDrivenTest::RunDataDrivenTest( |
[email protected] | 650b2d5 | 2013-02-10 03:41:45 | [diff] [blame] | 53 | const base::FilePath& input_directory, |
| 54 | const base::FilePath& output_directory, |
| 55 | const base::FilePath::StringType& file_name_pattern) { |
Francois Doray | e6fb2d0 | 2017-10-18 21:29:13 | [diff] [blame] | 56 | base::ScopedAllowBlockingForTesting allow_blocking; |
[email protected] | 0faac1d | 2013-07-19 23:51:04 | [diff] [blame] | 57 | ASSERT_TRUE(base::DirectoryExists(input_directory)); |
| 58 | ASSERT_TRUE(base::DirectoryExists(output_directory)); |
Gayane Petrosyan | 945148b | 2021-11-04 18:52:03 | [diff] [blame] | 59 | base::FileEnumerator input_files( |
| 60 | input_directory, false, base::FileEnumerator::FILES, file_name_pattern); |
Roger McFarlane | bf55e6a | 2017-11-28 18:55:23 | [diff] [blame] | 61 | const bool kIsExpectedToPass = true; |
Gayane Petrosyan | 945148b | 2021-11-04 18:52:03 | [diff] [blame] | 62 | for (base::FilePath input_file = input_files.Next(); !input_file.empty(); |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 63 | input_file = input_files.Next()) { |
Roger McFarlane | bf55e6a | 2017-11-28 18:55:23 | [diff] [blame] | 64 | RunOneDataDrivenTest(input_file, output_directory, kIsExpectedToPass); |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 65 | } |
| 66 | } |
| 67 | |
Evan Stade | f11e8ceb2 | 2015-01-08 23:11:26 | [diff] [blame] | 68 | void DataDrivenTest::RunOneDataDrivenTest( |
| 69 | const base::FilePath& test_file_name, |
Roger McFarlane | bf55e6a | 2017-11-28 18:55:23 | [diff] [blame] | 70 | const base::FilePath& output_directory, |
| 71 | bool is_expected_to_pass) { |
Francois Doray | e6fb2d0 | 2017-10-18 21:29:13 | [diff] [blame] | 72 | base::ScopedAllowBlockingForTesting allow_blocking; |
estade | 431dfb72 | 2015-06-05 22:30:01 | [diff] [blame] | 73 | // iOS doesn't get rid of removed test files. TODO(estade): remove this after |
| 74 | // all iOS bots are clobbered. |
| 75 | if (test_file_name.BaseName().value() == FILE_PATH_LITERAL("multimerge.in")) |
| 76 | return; |
| 77 | |
Evan Stade | f11e8ceb2 | 2015-01-08 23:11:26 | [diff] [blame] | 78 | ASSERT_TRUE(base::DirectoryExists(output_directory)); |
| 79 | SCOPED_TRACE(test_file_name.BaseName().value()); |
| 80 | |
| 81 | std::string input; |
| 82 | ReadFile(test_file_name, &input); |
| 83 | |
| 84 | std::string output; |
Gabriel Charette | ad33042 | 2021-07-21 00:49:28 | [diff] [blame] | 85 | { |
| 86 | base::ScopedDisallowBlocking disallow_blocking; |
| 87 | GenerateResults(input, &output); |
| 88 | } |
Evan Stade | f11e8ceb2 | 2015-01-08 23:11:26 | [diff] [blame] | 89 | |
| 90 | base::FilePath output_file = output_directory.Append( |
| 91 | test_file_name.BaseName().StripTrailingSeparators().ReplaceExtension( |
| 92 | FILE_PATH_LITERAL(".out"))); |
| 93 | |
| 94 | std::string output_file_contents; |
Roger McFarlane | bf55e6a | 2017-11-28 18:55:23 | [diff] [blame] | 95 | if (!ReadFile(output_file, &output_file_contents)) { |
Evan Stade | f11e8ceb2 | 2015-01-08 23:11:26 | [diff] [blame] | 96 | ASSERT_TRUE(WriteFile(output_file, output)); |
Roger McFarlane | bf55e6a | 2017-11-28 18:55:23 | [diff] [blame] | 97 | return; |
| 98 | } |
Dominic Battre | 5010349 | 2019-09-19 08:38:11 | [diff] [blame] | 99 | // Remove comment lines (lead by '#' character). |
| 100 | StripComments(&output_file_contents); |
Roger McFarlane | bf55e6a | 2017-11-28 18:55:23 | [diff] [blame] | 101 | |
| 102 | if (is_expected_to_pass) { |
| 103 | EXPECT_EQ(output_file_contents, output); |
| 104 | } else { |
| 105 | EXPECT_NE(output_file_contents, output); |
| 106 | } |
Evan Stade | f11e8ceb2 | 2015-01-08 23:11:26 | [diff] [blame] | 107 | } |
| 108 | |
Gayane Petrosyan | 945148b | 2021-11-04 18:52:03 | [diff] [blame] | 109 | base::FilePath DataDrivenTest::GetInputDirectory() { |
| 110 | return test_data_directory_.Append(feature_directory_) |
| 111 | .Append(test_name_) |
Roger McFarlane | bf55e6a | 2017-11-28 18:55:23 | [diff] [blame] | 112 | .AppendASCII("input"); |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 113 | } |
| 114 | |
Gayane Petrosyan | 945148b | 2021-11-04 18:52:03 | [diff] [blame] | 115 | base::FilePath DataDrivenTest::GetOutputDirectory() { |
| 116 | return test_data_directory_.Append(feature_directory_) |
| 117 | .Append(test_name_) |
Roger McFarlane | bf55e6a | 2017-11-28 18:55:23 | [diff] [blame] | 118 | .AppendASCII("output"); |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 119 | } |
| 120 | |
Gayane Petrosyan | 945148b | 2021-11-04 18:52:03 | [diff] [blame] | 121 | DataDrivenTest::DataDrivenTest( |
| 122 | const base::FilePath& test_data_directory, |
| 123 | const base::FilePath::StringType& feature_directory, |
| 124 | const base::FilePath::StringType& test_name) |
| 125 | : test_data_directory_(test_data_directory), |
| 126 | feature_directory_(feature_directory), |
| 127 | test_name_(test_name) {} |
[email protected] | 7173edd0 | 2011-02-09 00:31:57 | [diff] [blame] | 128 | |
Gayane Petrosyan | 945148b | 2021-11-04 18:52:03 | [diff] [blame] | 129 | DataDrivenTest::~DataDrivenTest() {} |
[email protected] | e217c563 | 2013-04-12 19:11:48 | [diff] [blame] | 130 | |
Gayane Petrosyan | 945148b | 2021-11-04 18:52:03 | [diff] [blame] | 131 | } // namespace testing |