mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-10-31 20:53:01 +00:00 
			
		
		
		
	Enhance index test selection filtering
This commit is contained in:
		
							parent
							
								
									4781e9a53d
								
							
						
					
					
						commit
						719c6c9ae9
					
				| @ -454,7 +454,8 @@ Command line options: | |||||||
|   --test-unit   Run unit tests. |   --test-unit   Run unit tests. | ||||||
|   --test-index <opt_filter_path> |   --test-index <opt_filter_path> | ||||||
|                 Run index tests. opt_filter_path can be used to specify which |                 Run index tests. opt_filter_path can be used to specify which | ||||||
|                 test to run. If not provided all tests are run. |                 test to run (ie, "foo" will run all tests which contain "foo" | ||||||
|  |                 in the path). If not provided all tests are run. | ||||||
|   --log-stdin-stdout-to-stderr |   --log-stdin-stdout-to-stderr | ||||||
|                 Print stdin and stdout messages to stderr. This is a aid for |                 Print stdin and stdout messages to stderr. This is a aid for | ||||||
|                 developing new language clients, as it makes it easier to figure |                 developing new language clients, as it makes it easier to figure | ||||||
|  | |||||||
							
								
								
									
										203
									
								
								src/test.cc
									
									
									
									
									
								
							
							
						
						
									
										203
									
								
								src/test.cc
									
									
									
									
									
								
							| @ -132,116 +132,117 @@ void RunIndexTests(const std::string& filter_path) { | |||||||
|       continue; |       continue; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     { |     if (path.find(filter_path) == std::string::npos) | ||||||
|       if (!EndsWith(path, filter_path)) |       continue; | ||||||
|         continue; |  | ||||||
| 
 | 
 | ||||||
|       // Parse expected output from the test, parse it into JSON document.
 |     if (!filter_path.empty()) | ||||||
|       std::vector<std::string> lines_with_endings = ReadLinesWithEnding(path); |       std::cout << "Running " << path << std::endl; | ||||||
|       TextReplacer text_replacer; |  | ||||||
|       std::vector<std::string> flags; |  | ||||||
|       std::unordered_map<std::string, std::string> all_expected_output; |  | ||||||
|       ParseTestExpectation(path, lines_with_endings, &text_replacer, &flags, |  | ||||||
|                            &all_expected_output); |  | ||||||
| 
 | 
 | ||||||
|       // Build flags.
 |     // Parse expected output from the test, parse it into JSON document.
 | ||||||
|       bool had_extra_flags = !flags.empty(); |     std::vector<std::string> lines_with_endings = ReadLinesWithEnding(path); | ||||||
|       if (!AnyStartsWith(flags, "-x")) |     TextReplacer text_replacer; | ||||||
|         flags.push_back("-xc++"); |     std::vector<std::string> flags; | ||||||
|       if (!AnyStartsWith(flags, "-std")) |     std::unordered_map<std::string, std::string> all_expected_output; | ||||||
|         flags.push_back("-std=c++11"); |     ParseTestExpectation(path, lines_with_endings, &text_replacer, &flags, | ||||||
|       flags.push_back("-resource_dir=" + GetDefaultResourceDirectory()); |                          &all_expected_output); | ||||||
|       if (had_extra_flags) { | 
 | ||||||
|  |     // Build flags.
 | ||||||
|  |     bool had_extra_flags = !flags.empty(); | ||||||
|  |     if (!AnyStartsWith(flags, "-x")) | ||||||
|  |       flags.push_back("-xc++"); | ||||||
|  |     if (!AnyStartsWith(flags, "-std")) | ||||||
|  |       flags.push_back("-std=c++11"); | ||||||
|  |     flags.push_back("-resource_dir=" + GetDefaultResourceDirectory()); | ||||||
|  |     if (had_extra_flags) { | ||||||
|  |       std::cout << "For " << path << std::endl; | ||||||
|  |       std::cout << "  flags: " << StringJoin(flags) << std::endl; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Run test.
 | ||||||
|  |     Config config; | ||||||
|  |     FileConsumer::SharedState file_consumer_shared; | ||||||
|  |     PerformanceImportFile perf; | ||||||
|  |     std::vector<std::unique_ptr<IndexFile>> dbs = | ||||||
|  |         Parse(&config, &file_consumer_shared, path, flags, {}, &perf, &index, | ||||||
|  |               false /*dump_ast*/); | ||||||
|  | 
 | ||||||
|  |     for (const auto& entry : all_expected_output) { | ||||||
|  |       const std::string& expected_path = entry.first; | ||||||
|  |       std::string expected_output = text_replacer.Apply(entry.second); | ||||||
|  | 
 | ||||||
|  |       // FIXME: promote to utils, find and remove duplicates (ie,
 | ||||||
|  |       // cquery_call_tree.cc, maybe something in project.cc).
 | ||||||
|  |       auto basename = [](const std::string& path) -> std::string { | ||||||
|  |         size_t last_index = path.find_last_of('/'); | ||||||
|  |         if (last_index == std::string::npos) | ||||||
|  |           return path; | ||||||
|  |         return path.substr(last_index + 1); | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       auto severity_to_string = [](const lsDiagnosticSeverity& severity) { | ||||||
|  |         switch (severity) { | ||||||
|  |           case lsDiagnosticSeverity::Error: | ||||||
|  |             return "error "; | ||||||
|  |           case lsDiagnosticSeverity::Warning: | ||||||
|  |             return "warning "; | ||||||
|  |           case lsDiagnosticSeverity::Information: | ||||||
|  |             return "information "; | ||||||
|  |           case lsDiagnosticSeverity::Hint: | ||||||
|  |             return "hint "; | ||||||
|  |         } | ||||||
|  |         assert(false && "not reached"); | ||||||
|  |         return ""; | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       // Get output from index operation.
 | ||||||
|  |       IndexFile* db = FindDbForPathEnding(expected_path, dbs); | ||||||
|  |       if (!db->diagnostics_.empty()) { | ||||||
|         std::cout << "For " << path << std::endl; |         std::cout << "For " << path << std::endl; | ||||||
|         std::cout << "  flags: " << StringJoin(flags) << std::endl; |         for (const lsDiagnostic& diagnostic : db->diagnostics_) { | ||||||
|  |           std::cout << "  "; | ||||||
|  |           if (diagnostic.severity) | ||||||
|  |             std::cout << severity_to_string(*diagnostic.severity); | ||||||
|  |           std::cout << basename(db->path) << ":" | ||||||
|  |                     << diagnostic.range.start.ToString() << "-" | ||||||
|  |                     << diagnostic.range.end.ToString() << ": " | ||||||
|  |                     << diagnostic.message << std::endl; | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|  |       std::string actual_output = "{}"; | ||||||
|  |       if (db) { | ||||||
|  |         VerifySerializeToFrom(db); | ||||||
|  |         actual_output = db->ToString(); | ||||||
|  |       } | ||||||
|  |       actual_output = text_replacer.Apply(actual_output); | ||||||
| 
 | 
 | ||||||
|       // Run test.
 |       // Compare output via rapidjson::Document to ignore any formatting
 | ||||||
|       Config config; |       // differences.
 | ||||||
|       FileConsumer::SharedState file_consumer_shared; |       rapidjson::Document actual; | ||||||
|       PerformanceImportFile perf; |       actual.Parse(actual_output.c_str()); | ||||||
|       std::vector<std::unique_ptr<IndexFile>> dbs = |       rapidjson::Document expected; | ||||||
|           Parse(&config, &file_consumer_shared, path, flags, {}, &perf, &index, |       expected.Parse(expected_output.c_str()); | ||||||
|                 false /*dump_ast*/); |  | ||||||
| 
 | 
 | ||||||
|       for (const auto& entry : all_expected_output) { |       if (actual == expected) { | ||||||
|         const std::string& expected_path = entry.first; |         // std::cout << "[PASSED] " << path << std::endl;
 | ||||||
|         std::string expected_output = text_replacer.Apply(entry.second); |       } else { | ||||||
| 
 |         DiffDocuments(path, expected_path, expected, actual); | ||||||
|         // FIXME: promote to utils, find and remove duplicates (ie,
 |         std::cout << std::endl; | ||||||
|         // cquery_call_tree.cc, maybe something in project.cc).
 |         std::cout << std::endl; | ||||||
|         auto basename = [](const std::string& path) -> std::string { |         std::cout | ||||||
|           size_t last_index = path.find_last_of('/'); |             << "[Enter to continue - type u to update test, a to update all]"; | ||||||
|           if (last_index == std::string::npos) |         char c = 'u'; | ||||||
|             return path; |         if (!update_all) { | ||||||
|           return path.substr(last_index + 1); |           c = (char)std::cin.get(); | ||||||
|         }; |           std::cin.get(); | ||||||
| 
 |  | ||||||
|         auto severity_to_string = [](const lsDiagnosticSeverity& severity) { |  | ||||||
|           switch (severity) { |  | ||||||
|             case lsDiagnosticSeverity::Error: |  | ||||||
|               return "error "; |  | ||||||
|             case lsDiagnosticSeverity::Warning: |  | ||||||
|               return "warning "; |  | ||||||
|             case lsDiagnosticSeverity::Information: |  | ||||||
|               return "information "; |  | ||||||
|             case lsDiagnosticSeverity::Hint: |  | ||||||
|               return "hint "; |  | ||||||
|           } |  | ||||||
|           assert(false && "not reached"); |  | ||||||
|           return ""; |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         // Get output from index operation.
 |  | ||||||
|         IndexFile* db = FindDbForPathEnding(expected_path, dbs); |  | ||||||
|         if (!db->diagnostics_.empty()) { |  | ||||||
|           std::cout << "For " << path << std::endl; |  | ||||||
|           for (const lsDiagnostic& diagnostic : db->diagnostics_) { |  | ||||||
|             std::cout << "  "; |  | ||||||
|             if (diagnostic.severity) |  | ||||||
|               std::cout << severity_to_string(*diagnostic.severity); |  | ||||||
|             std::cout << basename(db->path) << ":" |  | ||||||
|                       << diagnostic.range.start.ToString() << "-" |  | ||||||
|                       << diagnostic.range.end.ToString() << ": " |  | ||||||
|                       << diagnostic.message << std::endl; |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|         std::string actual_output = "{}"; |  | ||||||
|         if (db) { |  | ||||||
|           VerifySerializeToFrom(db); |  | ||||||
|           actual_output = db->ToString(); |  | ||||||
|         } |  | ||||||
|         actual_output = text_replacer.Apply(actual_output); |  | ||||||
| 
 | 
 | ||||||
|         // Compare output via rapidjson::Document to ignore any formatting
 |         if (c == 'a') | ||||||
|         // differences.
 |           update_all = true; | ||||||
|         rapidjson::Document actual; |  | ||||||
|         actual.Parse(actual_output.c_str()); |  | ||||||
|         rapidjson::Document expected; |  | ||||||
|         expected.Parse(expected_output.c_str()); |  | ||||||
| 
 | 
 | ||||||
|         if (actual == expected) { |         if (update_all || c == 'u') { | ||||||
|           // std::cout << "[PASSED] " << path << std::endl;
 |           // Note: we use |entry.second| instead of |expected_output| because
 | ||||||
|         } else { |           // |expected_output| has had text replacements applied.
 | ||||||
|           DiffDocuments(path, expected_path, expected, actual); |           UpdateTestExpectation(path, entry.second, ToString(actual) + "\n"); | ||||||
|           std::cout << std::endl; |  | ||||||
|           std::cout << std::endl; |  | ||||||
|           std::cout |  | ||||||
|               << "[Enter to continue - type u to update test, a to update all]"; |  | ||||||
|           char c = 'u'; |  | ||||||
|           if (!update_all) { |  | ||||||
|             c = (char)std::cin.get(); |  | ||||||
|             std::cin.get(); |  | ||||||
|           } |  | ||||||
| 
 |  | ||||||
|           if (c == 'a') |  | ||||||
|             update_all = true; |  | ||||||
| 
 |  | ||||||
|           if (update_all || c == 'u') { |  | ||||||
|             // Note: we use |entry.second| instead of |expected_output| because
 |  | ||||||
|             // |expected_output| has had text replacements applied.
 |  | ||||||
|             UpdateTestExpectation(path, entry.second, ToString(actual) + "\n"); |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user