clone_test.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  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 <gmock/gmock.h>
  5. #include <google/protobuf/util/message_differencer.h>
  6. #include <gtest/gtest.h>
  7. #include "explorer/ast/clone_context.h"
  8. #include "explorer/fuzzing/ast_to_proto.h"
  9. #include "explorer/syntax/parse.h"
  10. namespace Carbon::Testing {
  11. namespace {
  12. static std::vector<llvm::StringRef>* carbon_files = nullptr;
  13. auto CloneAST(Arena& arena, const AST& ast) -> AST {
  14. CloneContext context(&arena);
  15. return {
  16. .package = ast.package,
  17. .is_api = ast.is_api,
  18. .imports = ast.imports,
  19. .declarations = context.Clone(ast.declarations),
  20. .main_call = context.Clone(ast.main_call),
  21. .num_prelude_declarations = ast.num_prelude_declarations,
  22. };
  23. }
  24. // Returns a string representation of `ast`.
  25. auto AstToString(const AST& ast) -> std::string {
  26. std::string s;
  27. llvm::raw_string_ostream out(s);
  28. out << "package " << ast.package.package << (ast.is_api ? "api" : "impl")
  29. << ";\n";
  30. for (auto* declaration : ast.declarations) {
  31. out << *declaration << "\n";
  32. }
  33. return s;
  34. }
  35. TEST(CloneTest, SameProtoAfterClone) {
  36. int parsed_ok_count = 0;
  37. for (const llvm::StringRef f : *carbon_files) {
  38. Carbon::Arena arena;
  39. const ErrorOr<AST> ast = Carbon::Parse(&arena, f, /*parser_debug=*/false);
  40. if (ast.ok()) {
  41. ++parsed_ok_count;
  42. const AST clone = CloneAST(arena, *ast);
  43. const Fuzzing::CompilationUnit orig_proto = AstToProto(*ast);
  44. const Fuzzing::CompilationUnit clone_proto = AstToProto(clone);
  45. // TODO: Use EqualsProto once it's available.
  46. EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(
  47. orig_proto, clone_proto))
  48. << "clone produced a different AST. original:\n"
  49. << AstToString(*ast) << "clone:\n"
  50. << AstToString(clone);
  51. }
  52. }
  53. // Makes sure files were actually processed.
  54. EXPECT_GT(parsed_ok_count, 0);
  55. }
  56. } // namespace
  57. } // namespace Carbon::Testing
  58. auto main(int argc, char** argv) -> int {
  59. ::testing::InitGoogleTest(&argc, argv);
  60. // gtest should remove flags, leaving just input files.
  61. std::vector<llvm::StringRef> carbon_files(&argv[1], &argv[argc]);
  62. Carbon::Testing::carbon_files = &carbon_files;
  63. return RUN_ALL_TESTS();
  64. }