test_runner.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include <tree_sitter/api.h>
  5. #include <tree_sitter/parser.h>
  6. #include <cstdlib>
  7. #include <filesystem>
  8. #include <fstream>
  9. #include <iostream>
  10. #include <sstream>
  11. #include <string>
  12. #include <vector>
  13. extern "C" {
  14. TSLanguage* tree_sitter_carbon();
  15. }
  16. // Reads a file to string.
  17. static auto ReadFile(std::filesystem::path path) -> std::string {
  18. std::ifstream file(path);
  19. std::stringstream buffer;
  20. buffer << file.rdbuf();
  21. file.close();
  22. return buffer.str();
  23. }
  24. // TODO: use file_test.cpp
  25. auto main(int argc, char** argv) -> int {
  26. if (argc < 2) {
  27. std::cerr << "Usage: treesitter_carbon_tester <file>...\n";
  28. return 2;
  29. }
  30. auto* parser = ts_parser_new();
  31. ts_parser_set_language(parser, tree_sitter_carbon());
  32. bool fail_tests = std::getenv("FAIL_TESTS") != nullptr;
  33. std::vector<std::string> incorrect;
  34. for (int i = 1; i < argc; i++) {
  35. std::string file_path = argv[i];
  36. std::string source = ReadFile(file_path);
  37. auto* tree =
  38. ts_parser_parse_string(parser, nullptr, source.data(), source.size());
  39. auto root = ts_tree_root_node(tree);
  40. auto has_error = ts_node_has_error(root);
  41. char* node_debug = ts_node_string(root);
  42. std::cout << file_path << ":\n" << node_debug << "\n";
  43. if (has_error ^ fail_tests) {
  44. incorrect.push_back(file_path);
  45. }
  46. free(node_debug);
  47. ts_tree_delete(tree);
  48. }
  49. ts_parser_delete(parser);
  50. for (const auto& file : incorrect) {
  51. if (fail_tests) {
  52. std::cout << "INCORRECTLY PASSING " << file << "\n";
  53. } else {
  54. std::cout << "FAILED " << file << "\n";
  55. }
  56. }
  57. if (!incorrect.empty()) {
  58. if (fail_tests) {
  59. std::cout << incorrect.size() << " tests incorrectly passing.\n";
  60. } else {
  61. std::cout << incorrect.size() << " tests failing.\n";
  62. }
  63. return 1;
  64. }
  65. }