kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/cxx/verifier/verifier_unit_test.cc (about)

     1  /*
     2   * Copyright 2014 The Kythe Authors. All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *   http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  #include <optional>
    18  #include <regex>
    19  #include <string_view>
    20  
    21  #include "absl/log/initialize.h"
    22  #include "google/protobuf/text_format.h"
    23  #include "google/protobuf/util/json_util.h"
    24  #include "gtest/gtest.h"
    25  #include "verifier.h"
    26  
    27  namespace kythe {
    28  namespace verifier {
    29  namespace {
    30  using MarkedSource = kythe::proto::common::MarkedSource;
    31  
    32  TEST(VerifierUnitTest, StringPrettyPrinter) {
    33    StringPrettyPrinter c_string;
    34    c_string.Print("c_string");
    35    EXPECT_EQ("c_string", c_string.str());
    36    StringPrettyPrinter std_string;
    37    std_string.Print(std::string("std_string"));
    38    EXPECT_EQ("std_string", std_string.str());
    39    StringPrettyPrinter zero_ptrvoid;
    40    void* zero = nullptr;
    41    zero_ptrvoid.Print(zero);
    42    EXPECT_EQ("0", zero_ptrvoid.str());
    43    void* one = reinterpret_cast<void*>(1);
    44    StringPrettyPrinter one_ptrvoid;
    45    one_ptrvoid.Print(one);
    46    // Some implementations might pad stringified void*s.
    47    std::string one_str = one_ptrvoid.str();
    48    std::regex ptrish_regex("0x0*1");
    49    ASSERT_TRUE(std::regex_match(one_str, ptrish_regex));
    50  }
    51  
    52  TEST(VerifierUnitTest, QuotingPrettyPrinter) {
    53    StringPrettyPrinter c_string;
    54    QuoteEscapingPrettyPrinter c_string_quoting(c_string);
    55    c_string_quoting.Print(R"("hello")");
    56    EXPECT_EQ(R"(\"hello\")", c_string.str());
    57    StringPrettyPrinter std_string;
    58    QuoteEscapingPrettyPrinter std_string_quoting(std_string);
    59    std_string_quoting.Print(std::string(R"(<"'
    60  )"));
    61    EXPECT_EQ(R"(<\"\'\n)", std_string.str());
    62    StringPrettyPrinter zero_ptrvoid;
    63    QuoteEscapingPrettyPrinter zero_ptrvoid_quoting(zero_ptrvoid);
    64    void* zero = nullptr;
    65    zero_ptrvoid_quoting.Print(zero);
    66    EXPECT_EQ("0", zero_ptrvoid.str());
    67  }
    68  
    69  TEST(VerifierUnitTest, HtmlPrettyPrinter) {
    70    StringPrettyPrinter c_string;
    71    HtmlEscapingPrettyPrinter c_string_html(c_string);
    72    c_string_html.Print(R"("hello")");
    73    EXPECT_EQ(R"(&quot;hello&quot;)", c_string.str());
    74    StringPrettyPrinter std_string;
    75    HtmlEscapingPrettyPrinter std_string_html(std_string);
    76    std_string_html.Print(std::string(R"(x<>&"ml)"));
    77    EXPECT_EQ(R"(x&lt;&gt;&amp;&quot;ml)", std_string.str());
    78    StringPrettyPrinter zero_ptrvoid;
    79    HtmlEscapingPrettyPrinter zero_ptrvoid_html(zero_ptrvoid);
    80    void* zero = nullptr;
    81    zero_ptrvoid_html.Print(zero);
    82    EXPECT_EQ("0", zero_ptrvoid.str());
    83  }
    84  
    85  TEST(VerifierUnitTest, UnescapeStringLiterals) {
    86    std::string tmp = "tmp";
    87    EXPECT_TRUE(AssertionParser::Unescape(R"("")", &tmp));
    88    EXPECT_EQ("", tmp);
    89    EXPECT_FALSE(AssertionParser::Unescape("", &tmp));
    90    EXPECT_TRUE(AssertionParser::Unescape(R"("foo")", &tmp));
    91    EXPECT_EQ("foo", tmp);
    92    EXPECT_TRUE(AssertionParser::Unescape(R"("\"foo\"")", &tmp));
    93    EXPECT_EQ("\"foo\"", tmp);
    94    EXPECT_FALSE(AssertionParser::Unescape(R"("\foo")", &tmp));
    95    EXPECT_FALSE(AssertionParser::Unescape(R"("foo\")", &tmp));
    96    EXPECT_TRUE(AssertionParser::Unescape(R"("\\")", &tmp));
    97    EXPECT_EQ("\\", tmp);
    98  }
    99  
   100  bool CheckEVarInit(std::string_view s) { return s != "nil" && !s.empty(); }
   101  
   102  enum class Solver { Old, New };
   103  
   104  class VerifierTest : public testing::TestWithParam<Solver> {
   105   protected:
   106    void SetUp() override {
   107      v.UseFastSolver(GetParam() == Solver::Old ? false : true);
   108    }
   109  
   110    Verifier v;
   111  };
   112  
   113  INSTANTIATE_TEST_SUITE_P(Solvers, VerifierTest,
   114                           testing::Values(Solver::Old, Solver::New),
   115                           [](const auto& p) {
   116                             return p.param == Solver::Old ? "old" : "new";
   117                           });
   118  
   119  TEST_P(VerifierTest, TrivialHappyCase) { ASSERT_TRUE(v.VerifyAllGoals()); }
   120  
   121  TEST(VerifierUnitTest, EmptyProtoIsNotWellFormed) {
   122    Verifier v;
   123    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   124  })"));
   125    ASSERT_FALSE(v.VerifyAllGoals());
   126  }
   127  
   128  TEST(VerifierUnitTest, EmptyVnameIsNotWellFormed) {
   129    Verifier v;
   130    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   131    source { }
   132    fact_name: "testname"
   133    fact_value: "testvalue"
   134  })"));
   135    ASSERT_FALSE(v.PrepareDatabase());
   136    ASSERT_FALSE(v.VerifyAllGoals());
   137  }
   138  
   139  TEST_P(VerifierTest, NoRulesIsOk) {
   140    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   141    source { root: "1" }
   142    fact_name: "testname"
   143    fact_value: "testvalue"
   144  })"));
   145    ASSERT_TRUE(v.PrepareDatabase());
   146    ASSERT_TRUE(v.VerifyAllGoals());
   147  }
   148  
   149  TEST(VerifierUnitTest, DuplicateFactsNotWellFormed) {
   150    Verifier v;
   151    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   152    source { root: "1" }
   153    fact_name: "testname"
   154    fact_value: "testvalue"
   155  }
   156  entries {
   157    source { root: "1" }
   158    fact_name: "testname"
   159    fact_value: "testvalue"
   160  })"));
   161    ASSERT_FALSE(v.PrepareDatabase());
   162    ASSERT_FALSE(v.VerifyAllGoals());
   163  }
   164  
   165  TEST(VerifierUnitTest, DuplicateFactsNotWellFormedEvenIfYouSeparateThem) {
   166    Verifier v;
   167    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   168    source { root: "1" }
   169    fact_name: "testname"
   170    fact_value: "testvalue"
   171  }
   172  entries {
   173    source { root: "2" }
   174    fact_name: "testname"
   175    fact_value: "testvalue"
   176  }
   177  entries {
   178    source { root: "1" }
   179    fact_name: "testname"
   180    fact_value: "testvalue"
   181  })"));
   182    ASSERT_FALSE(v.PrepareDatabase());
   183    ASSERT_FALSE(v.VerifyAllGoals());
   184  }
   185  
   186  TEST(VerifierUnitTest, DuplicateEdgesAreUseless) {
   187    Verifier v;
   188    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   189    source { root: "1" }
   190    edge_kind: "somekind"
   191    target { root: "2" }
   192    fact_name: "/"
   193    fact_value: ""
   194  }
   195  entries {
   196    source { root: "1" }
   197    edge_kind: "somekind"
   198    target { root: "2" }
   199    fact_name: "/"
   200    fact_value: ""
   201  })"));
   202    ASSERT_FALSE(v.PrepareDatabase());
   203    ASSERT_FALSE(v.VerifyAllGoals());
   204  }
   205  
   206  TEST_P(VerifierTest, EdgesCanSupplyMultipleOrdinals) {
   207    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   208    source { root: "1" }
   209    edge_kind: "somekind"
   210    target { root: "2" }
   211    fact_name: "/kythe/ordinal"
   212    fact_value: "42"
   213  }
   214  entries {
   215    source { root: "1" }
   216    edge_kind: "somekind"
   217    target { root: "2" }
   218    fact_name: "/kythe/ordinal"
   219    fact_value: "43"
   220  })"));
   221    ASSERT_TRUE(v.PrepareDatabase());
   222    ASSERT_TRUE(v.VerifyAllGoals());
   223  }
   224  
   225  TEST_P(VerifierTest, EdgesCanSupplyMultipleDotOrdinals) {
   226    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   227    source { root: "1" }
   228    edge_kind: "somekind.42"
   229    target { root: "2" }
   230    fact_name: "/"
   231  }
   232  entries {
   233    source { root: "1" }
   234    edge_kind: "somekind.43"
   235    target { root: "2" }
   236    fact_name: "/"
   237  })"));
   238    ASSERT_TRUE(v.PrepareDatabase());
   239    ASSERT_TRUE(v.VerifyAllGoals());
   240  }
   241  
   242  TEST(VerifierUnitTest, ConflictingFactsNotWellFormed) {
   243    Verifier v;
   244    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   245    source { root: "1" }
   246    fact_name: "testname"
   247    fact_value: "testvalue"
   248  }
   249  entries {
   250    source { root: "1" }
   251    fact_name: "testname"
   252    fact_value: "testvalue2"
   253  })"));
   254    ASSERT_FALSE(v.PrepareDatabase());
   255    ASSERT_FALSE(v.VerifyAllGoals());
   256  }
   257  
   258  TEST(VerifierUnitTest, OnlyTargetIsWrong) {
   259    Verifier v;
   260    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   261    edge_kind: "somekind"
   262    target { root: "2" }
   263    fact_name: "/kythe/ordinal"
   264    fact_value: "42"
   265  })"));
   266    ASSERT_FALSE(v.PrepareDatabase());
   267    ASSERT_FALSE(v.VerifyAllGoals());
   268  }
   269  
   270  TEST(VerifierUnitTest, OnlyTargetIsWrongDotOrdinal) {
   271    Verifier v;
   272    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   273    edge_kind: "somekind.42"
   274    target { root: "2" }
   275    fact_name: "/"
   276  })"));
   277    ASSERT_FALSE(v.PrepareDatabase());
   278    ASSERT_FALSE(v.VerifyAllGoals());
   279  }
   280  
   281  TEST_P(VerifierTest, MissingAnchorTextFails) {
   282    ASSERT_FALSE(v.LoadInlineProtoFile(R"(entries {
   283  #- @text defines SomeNode
   284    source { root: "1" }
   285    fact_name: "testname"
   286    fact_value: "testvalue"
   287  })"));
   288  }
   289  
   290  TEST_P(VerifierTest, AmbiguousAnchorTextFails) {
   291    ASSERT_FALSE(v.LoadInlineProtoFile(R"(entries {
   292  #- @text defines SomeNode
   293  # text text
   294    source { root: "1" }
   295    fact_name: "testname"
   296    fact_value: "testvalue"
   297  })"));
   298  }
   299  
   300  TEST_P(VerifierTest, GenerateAnchorEvarFailsOnEmptyDB) {
   301    ASSERT_TRUE(v.LoadInlineProtoFile(R"(
   302  #- @text defines SomeNode
   303  # text
   304  )"));
   305    ASSERT_TRUE(v.PrepareDatabase());
   306    ASSERT_FALSE(v.VerifyAllGoals());
   307  }
   308  
   309  TEST_P(VerifierTest, OffsetsVersusRuleBlocks) {
   310    ASSERT_TRUE(v.LoadInlineProtoFile(R"(
   311  #- @text defines SomeNode
   312  #- @+2text defines SomeNode
   313  #- @+1text defines SomeNode
   314  # text
   315  )"));
   316    ASSERT_TRUE(v.PrepareDatabase());
   317    ASSERT_FALSE(v.VerifyAllGoals());
   318  }
   319  
   320  TEST_P(VerifierTest, ZeroRelativeLineReferencesDontWork) {
   321    ASSERT_FALSE(v.LoadInlineProtoFile(R"(
   322  #- @+0text defines SomeNode
   323  # text
   324  )"));
   325  }
   326  
   327  TEST_P(VerifierTest, NoMatchingInsideGoalComments) {
   328    ASSERT_FALSE(v.LoadInlineProtoFile(R"(
   329  #- @+1text defines SomeNode
   330  #- @text defines SomeNode
   331  # text
   332  )"));
   333  }
   334  
   335  TEST_P(VerifierTest, OutOfBoundsRelativeLineReferencesDontWork) {
   336    ASSERT_FALSE(v.LoadInlineProtoFile(R"(
   337  #- @+2text defines SomeNode
   338  # text
   339  )"));
   340  }
   341  
   342  TEST_P(VerifierTest, EndOfFileAbsoluteLineReferencesWork) {
   343    ASSERT_TRUE(v.LoadInlineProtoFile(R"(
   344  #- @:3text defines SomeNode
   345  # text
   346  )"));
   347  }
   348  
   349  TEST_P(VerifierTest, OutOfBoundsAbsoluteLineReferencesDontWork) {
   350    Verifier v;
   351    ASSERT_FALSE(v.LoadInlineProtoFile(R"(
   352  #- @:4text defines SomeNode
   353  # text
   354  )"));
   355  }
   356  
   357  TEST_P(VerifierTest, ZeroAbsoluteLineReferencesDontWork) {
   358    ASSERT_FALSE(v.LoadInlineProtoFile(R"(
   359  #- @:0text defines SomeNode
   360  # text
   361  )"));
   362  }
   363  
   364  TEST_P(VerifierTest, SameAbsoluteLineReferencesDontWork) {
   365    ASSERT_FALSE(v.LoadInlineProtoFile(R"(
   366  #- @:1text defines SomeNode
   367  # text
   368  )"));
   369  }
   370  
   371  TEST_P(VerifierTest, HistoricalAbsoluteLineReferencesDontWork) {
   372    ASSERT_FALSE(v.LoadInlineProtoFile(R"(
   373  #
   374  #- @:1text defines SomeNode
   375  # text
   376  )"));
   377  }
   378  
   379  TEST_P(VerifierTest, ParseLiteralString) {
   380    ASSERT_TRUE(v.LoadInlineProtoFile(R"(
   381  #- @"text" defines SomeNode
   382  # text
   383  )"));
   384    ASSERT_TRUE(v.PrepareDatabase());
   385    ASSERT_FALSE(v.VerifyAllGoals());
   386  }
   387  
   388  TEST_P(VerifierTest, ParseLiteralStringWithSpace) {
   389    ASSERT_TRUE(v.LoadInlineProtoFile(R"(
   390  #- @"text txet" defines SomeNode
   391  # text txet
   392  )"));
   393    ASSERT_TRUE(v.PrepareDatabase());
   394    ASSERT_FALSE(v.VerifyAllGoals());
   395  }
   396  
   397  TEST_P(VerifierTest, ParseLiteralStringWithEscape) {
   398    ASSERT_TRUE(v.LoadInlineProtoFile(R"(
   399  #- @"text \"txet\" ettx" defines SomeNode
   400  # text "txet" ettx
   401  )"));
   402    ASSERT_TRUE(v.PrepareDatabase());
   403    ASSERT_FALSE(v.VerifyAllGoals());
   404  }
   405  
   406  TEST_P(VerifierTest, GenerateStartOffsetEVar) {
   407    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   408  #- ANode.loc/start @^text
   409  ##text (line 3 column 2 offset 38-42)
   410  source { root:"1" }
   411  fact_name: "/kythe/node/kind"
   412  fact_value: "anchor"
   413  }
   414  entries {
   415  source { root:"1" }
   416  fact_name: "/kythe/loc/start"
   417  fact_value: "38"
   418  }
   419  entries {
   420  source { root:"1" }
   421  fact_name: "/kythe/loc/end"
   422  fact_value: "42"
   423  }
   424  entries {
   425  source { root:"1" }
   426  edge_kind: "/kythe/edge/defines"
   427  target { root:"2" }
   428  fact_name: "/"
   429  fact_value: ""
   430  })"));
   431    ASSERT_TRUE(v.PrepareDatabase());
   432    ASSERT_TRUE(v.VerifyAllGoals());
   433  }
   434  
   435  TEST_P(VerifierTest, GenerateStartOffsetEVarRelativeLine) {
   436    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   437  #- ANode.loc/start @^+22text
   438  source { root:"1" }
   439  fact_name: "/kythe/node/kind"
   440  fact_value: "anchor"
   441  }
   442  entries {
   443  source { root:"1" }
   444  fact_name: "/kythe/loc/start"
   445  fact_value: "387"
   446  }
   447  entries {
   448  source { root:"1" }
   449  fact_name: "/kythe/loc/end"
   450  fact_value: "391"
   451  }
   452  entries {
   453  source { root:"1" }
   454  edge_kind: "/kythe/edge/defines"
   455  target { root:"2" }
   456  fact_name: "/"
   457  fact_value: ""
   458  }
   459  ##text (line 24 column 2 offset 387-391))"));
   460    ASSERT_TRUE(v.PrepareDatabase());
   461    ASSERT_TRUE(v.VerifyAllGoals());
   462  }
   463  
   464  TEST_P(VerifierTest, GenerateEndOffsetEVarAbsoluteLine) {
   465    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   466  #-   ANode.loc/end @$:24text
   467  source { root:"1" }
   468  fact_name: "/kythe/node/kind"
   469  fact_value: "anchor"
   470  }
   471  entries {
   472  source { root:"1" }
   473  fact_name: "/kythe/loc/start"
   474  fact_value: "387"
   475  }
   476  entries {
   477  source { root:"1" }
   478  fact_name: "/kythe/loc/end"
   479  fact_value: "391"
   480  }
   481  entries {
   482  source { root:"1" }
   483  edge_kind: "/kythe/edge/defines"
   484  target { root:"2" }
   485  fact_name: "/"
   486  fact_value: ""
   487  }
   488  ##text (line 24 column 2 offset 387-391))"));
   489    ASSERT_TRUE(v.PrepareDatabase());
   490    ASSERT_TRUE(v.VerifyAllGoals());
   491  }
   492  
   493  TEST_P(VerifierTest, GenerateEndOffsetEVar) {
   494    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   495  #-   ANode.loc/end @$text
   496  ##text (line 3 column 2 offset 38-42)
   497  source { root:"1" }
   498  fact_name: "/kythe/node/kind"
   499  fact_value: "anchor"
   500  }
   501  entries {
   502  source { root:"1" }
   503  fact_name: "/kythe/loc/start"
   504  fact_value: "38"
   505  }
   506  entries {
   507  source { root:"1" }
   508  fact_name: "/kythe/loc/end"
   509  fact_value: "42"
   510  }
   511  entries {
   512  source { root:"1" }
   513  edge_kind: "/kythe/edge/defines"
   514  target { root:"2" }
   515  fact_name: "/"
   516  fact_value: ""
   517  })"));
   518    ASSERT_TRUE(v.PrepareDatabase());
   519    ASSERT_TRUE(v.VerifyAllGoals());
   520  }
   521  
   522  TEST_P(VerifierTest, AnchorKind) {
   523    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   524  #- @text.node/kind anchor
   525  ##text (line 3 column 2 offset 38-42)
   526  source { root:"1" }
   527  fact_name: "/kythe/node/kind"
   528  fact_value: "anchor"
   529  }
   530  entries {
   531  source { root:"1" }
   532  fact_name: "/kythe/loc/start"
   533  fact_value: "38"
   534  }
   535  entries {
   536  source { root:"1" }
   537  fact_name: "/kythe/loc/end"
   538  fact_value: "42"
   539  }
   540  )",
   541                                      "", "1"));
   542    ASSERT_TRUE(v.PrepareDatabase());
   543    ASSERT_TRUE(v.VerifyAllGoals());
   544  }
   545  
   546  TEST_P(VerifierTest, GenerateAnchorEvar) {
   547    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   548  #- @text defines SomeNode
   549  ##text (line 3 column 2 offset 38-42)
   550  source { root:"1" }
   551  fact_name: "/kythe/node/kind"
   552  fact_value: "anchor"
   553  }
   554  entries {
   555  source { root:"1" }
   556  fact_name: "/kythe/loc/start"
   557  fact_value: "38"
   558  }
   559  entries {
   560  source { root:"1" }
   561  fact_name: "/kythe/loc/end"
   562  fact_value: "42"
   563  }
   564  entries {
   565  source { root:"1" }
   566  edge_kind: "/kythe/edge/defines"
   567  target { root:"2" }
   568  fact_name: "/"
   569  fact_value: ""
   570  })",
   571                                      "", "1"));
   572    ASSERT_TRUE(v.PrepareDatabase());
   573    ASSERT_TRUE(v.VerifyAllGoals());
   574  }
   575  
   576  constexpr char kMatchAnchorSubgraph[] = R"(entries {
   577  source { root:"1" }
   578  fact_name: "/kythe/node/kind"
   579  fact_value: "anchor"
   580  }
   581  entries {
   582  source { root:"1" }
   583  fact_name: "/kythe/loc/start"
   584  fact_value: "40"
   585  }
   586  entries {
   587  source { root:"1" }
   588  fact_name: "/kythe/loc/end"
   589  fact_value: "44"
   590  }
   591  entries {
   592  source { root:"3" }
   593  fact_name: "/kythe/node/kind"
   594  fact_value: "anchor"
   595  }
   596  entries {
   597  source { root:"3" }
   598  fact_name: "/kythe/loc/start"
   599  fact_value: "45"
   600  }
   601  entries {
   602  source { root:"3" }
   603  fact_name: "/kythe/loc/end"
   604  fact_value: "49"
   605  }
   606  entries {
   607  source { root:"4" }
   608  fact_name: "/kythe/node/kind"
   609  fact_value: "anchor"
   610  }
   611  entries {
   612  source { root:"4" }
   613  fact_name: "/kythe/loc/start"
   614  fact_value: "50"
   615  }
   616  entries {
   617  source { root:"4" }
   618  fact_name: "/kythe/loc/end"
   619  fact_value: "54"
   620  })";
   621  
   622  TEST_P(VerifierTest, GenerateAnchorEvarMatchNumber0) {
   623    ASSERT_TRUE(v.LoadInlineProtoFile(std::string(R"(entries {
   624  #- @#0text defines SomeNode
   625  ##text text text(40-44, 45-49, 50-54)
   626  
   627  source { root:"1" }
   628  edge_kind: "/kythe/edge/defines"
   629  target { root:"2" }
   630  fact_name: "/"
   631  fact_value: ""
   632  })") + kMatchAnchorSubgraph,
   633                                      "", "1"));
   634    ASSERT_TRUE(v.PrepareDatabase());
   635    ASSERT_TRUE(v.VerifyAllGoals());
   636  }
   637  
   638  TEST_P(VerifierTest, GenerateAnchorEvarMatchNumber1) {
   639    ASSERT_TRUE(v.LoadInlineProtoFile(std::string(R"(entries {
   640  #- @#1text defines SomeNode
   641  ##text text text(40-44, 45-49, 50-54)
   642  
   643  source { root:"3" }
   644  edge_kind: "/kythe/edge/defines"
   645  target { root:"2" }
   646  fact_name: "/"
   647  fact_value: ""
   648  })") + kMatchAnchorSubgraph,
   649                                      "", "3"));
   650    ASSERT_TRUE(v.PrepareDatabase());
   651    ASSERT_TRUE(v.VerifyAllGoals());
   652  }
   653  
   654  TEST_P(VerifierTest, GenerateAnchorEvarMatchNumber2) {
   655    ASSERT_TRUE(v.LoadInlineProtoFile(std::string(R"(entries {
   656  #- @#2text defines SomeNode
   657  ##text text text(40-44, 45-49, 50-54)
   658  
   659  source { root:"4" }
   660  edge_kind: "/kythe/edge/defines"
   661  target { root:"2" }
   662  fact_name: "/"
   663  fact_value: ""
   664  })") + kMatchAnchorSubgraph,
   665                                      "", "4"));
   666    ASSERT_TRUE(v.PrepareDatabase());
   667    ASSERT_TRUE(v.VerifyAllGoals());
   668  }
   669  
   670  TEST_P(VerifierTest, GenerateAnchorEvarMatchNumber3) {
   671    ASSERT_FALSE(v.LoadInlineProtoFile(R"(entries {
   672  #- @#3text defines SomeNode
   673  ##text text text(40-44, 45-49, 50-54)
   674  })"));
   675  }
   676  
   677  TEST_P(VerifierTest, GenerateAnchorEvarMatchNumberNegative1) {
   678    ASSERT_FALSE(v.LoadInlineProtoFile(R"(entries {
   679  #- @#-1text defines SomeNode
   680  ##text text text(40-44, 45-49, 50-54)
   681  })"));
   682  }
   683  
   684  TEST_P(VerifierTest, GenerateAnchorEvarAbsoluteLine) {
   685    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   686  #- @:24text defines SomeNode
   687  source { root:"1" }
   688  fact_name: "/kythe/node/kind"
   689  fact_value: "anchor"
   690  }
   691  entries {
   692  source { root:"1" }
   693  fact_name: "/kythe/loc/start"
   694  fact_value: "387"
   695  }
   696  entries {
   697  source { root:"1" }
   698  fact_name: "/kythe/loc/end"
   699  fact_value: "391"
   700  }
   701  entries {
   702  source { root:"1" }
   703  edge_kind: "/kythe/edge/defines"
   704  target { root:"2" }
   705  fact_name: "/"
   706  fact_value: ""
   707  }
   708  ##text (line 24 column 2 offset 387-391))",
   709                                      "", "1"));
   710    ASSERT_TRUE(v.PrepareDatabase());
   711    ASSERT_TRUE(v.VerifyAllGoals());
   712  }
   713  
   714  TEST_P(VerifierTest, GenerateAnchorEvarRelativeLine) {
   715    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   716  #- @+22text defines SomeNode
   717  source { root:"1" }
   718  fact_name: "/kythe/node/kind"
   719  fact_value: "anchor"
   720  }
   721  entries {
   722  source { root:"1" }
   723  fact_name: "/kythe/loc/start"
   724  fact_value: "387"
   725  }
   726  entries {
   727  source { root:"1" }
   728  fact_name: "/kythe/loc/end"
   729  fact_value: "391"
   730  }
   731  entries {
   732  source { root:"1" }
   733  edge_kind: "/kythe/edge/defines"
   734  target { root:"2" }
   735  fact_name: "/"
   736  fact_value: ""
   737  }
   738  ##text (line 24 column 2 offset 387-391))",
   739                                      "", "1"));
   740    ASSERT_TRUE(v.PrepareDatabase());
   741    ASSERT_TRUE(v.VerifyAllGoals());
   742  }
   743  
   744  TEST_P(VerifierTest, GenerateAnchorEvarAtEndOfFile) {
   745    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   746  source { root:"1" }
   747  fact_name: "/kythe/node/kind"
   748  fact_value: "anchor"
   749  }
   750  entries {
   751  source { root:"1" }
   752  fact_name: "/kythe/loc/start"
   753  fact_value: "384"
   754  }
   755  entries {
   756  source { root:"1" }
   757  fact_name: "/kythe/loc/end"
   758  fact_value: "388"
   759  }
   760  entries {
   761  source { root:"1" }
   762  edge_kind: "/kythe/edge/defines"
   763  target { root:"2" }
   764  fact_name: "/"
   765  fact_value: ""
   766  }
   767  #- @text defines SomeNode
   768  ##text (line 22 column 2 offset 384-388))",
   769                                      "", "1"));
   770    ASSERT_TRUE(v.PrepareDatabase());
   771    ASSERT_TRUE(v.VerifyAllGoals());
   772  }
   773  
   774  TEST_P(VerifierTest, GenerateAnchorEvarAtEndOfFileWithSpaces) {
   775    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   776  source { root:"1" }
   777  fact_name: "/kythe/node/kind"
   778  fact_value: "anchor"
   779  }
   780  entries {
   781  source { root:"1" }
   782  fact_name: "/kythe/loc/start"
   783  fact_value: "386"
   784  }
   785  entries {
   786  source { root:"1" }
   787  fact_name: "/kythe/loc/end"
   788  fact_value: "390"
   789  }
   790  entries {
   791  source { root:"1" }
   792  edge_kind: "/kythe/edge/defines"
   793  target { root:"2" }
   794  fact_name: "/"
   795  fact_value: ""
   796  }
   797    #- @text defines SomeNode
   798  ##text (line 22 column 2 offset 386-390))",
   799                                      "", "1"));
   800    ASSERT_TRUE(v.PrepareDatabase());
   801    ASSERT_TRUE(v.VerifyAllGoals());
   802  }
   803  
   804  TEST_P(VerifierTest, GenerateAnchorEvarAtEndOfFileWithTrailingRule) {
   805    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   806  source { root:"1" }
   807  fact_name: "/kythe/node/kind"
   808  fact_value: "anchor"
   809  }
   810  entries {
   811  source { root:"1" }
   812  fact_name: "/kythe/loc/start"
   813  fact_value: "384"
   814  }
   815  entries {
   816  source { root:"1" }
   817  fact_name: "/kythe/loc/end"
   818  fact_value: "388"
   819  }
   820  entries {
   821  source { root:"1" }
   822  edge_kind: "/kythe/edge/defines"
   823  target { root:"2" }
   824  fact_name: "/"
   825  fact_value: ""
   826  }
   827  #- @text defines SomeNode
   828  ##text (line 22 column 2 offset 384-388))
   829  #- SomeAnchor defines SomeNode)",
   830                                      "", "1"));
   831    ASSERT_TRUE(v.PrepareDatabase());
   832    ASSERT_TRUE(v.VerifyAllGoals());
   833  }
   834  
   835  TEST_P(VerifierTest, GenerateAnchorEvarAcrossMultipleGoalLines) {
   836    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   837  #- @text defines
   838  #-
   839  #-   SomeNode
   840  ##text (line 5 column 2 offset 46-50)
   841  source { root:"1" }
   842  fact_name: "/kythe/node/kind"
   843  fact_value: "anchor"
   844  }
   845  entries {
   846  source { root:"1" }
   847  fact_name: "/kythe/loc/start"
   848  fact_value: "46"
   849  }
   850  entries {
   851  source { root:"1" }
   852  fact_name: "/kythe/loc/end"
   853  fact_value: "50"
   854  }
   855  entries {
   856  source { root:"1" }
   857  edge_kind: "/kythe/edge/defines"
   858  target { root:"2" }
   859  fact_name: "/"
   860  fact_value: ""
   861  })",
   862                                      "", "1"));
   863    ASSERT_TRUE(v.PrepareDatabase());
   864    ASSERT_TRUE(v.VerifyAllGoals());
   865  }
   866  
   867  TEST_P(VerifierTest, GenerateAnchorEvarAcrossMultipleGoalLinesWithSpaces) {
   868    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   869  #- @text defines
   870    #-
   871   #-   SomeNode
   872    ##text (line 5 column 4 offset 51-55)
   873  source { root:"1" }
   874  fact_name: "/kythe/node/kind"
   875  fact_value: "anchor"
   876  }
   877  entries {
   878  source { root:"1" }
   879  fact_name: "/kythe/loc/start"
   880  fact_value: "51"
   881  }
   882  entries {
   883  source { root:"1" }
   884  fact_name: "/kythe/loc/end"
   885  fact_value: "55"
   886  }
   887  entries {
   888  source { root:"1" }
   889  edge_kind: "/kythe/edge/defines"
   890  target { root:"2" }
   891  fact_name: "/"
   892  fact_value: ""
   893  })",
   894                                      "", "1"));
   895    ASSERT_TRUE(v.PrepareDatabase());
   896    ASSERT_TRUE(v.VerifyAllGoals());
   897  }
   898  
   899  TEST_P(VerifierTest, GenerateAnchorEvarWithBlankLines) {
   900    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   901  source { root:"1" }
   902  fact_name: "/kythe/node/kind"
   903  fact_value: "anchor"
   904  }
   905  entries {
   906  source { root:"1" }
   907  fact_name: "/kythe/loc/start"
   908  fact_value: "384"
   909  }
   910  entries {
   911  source { root:"1" }
   912  fact_name: "/kythe/loc/end"
   913  fact_value: "388"
   914  }
   915  entries {
   916  source { root:"1" }
   917  edge_kind: "/kythe/edge/defines"
   918  target { root:"2" }
   919  fact_name: "/"
   920  fact_value: ""
   921  }
   922  #- @texx defines SomeNode
   923  ##texx (line 22 column 2 offset 384-388))
   924  
   925  #-  SomeAnchor defines SomeNode)",
   926                                      "", "1"));
   927    ASSERT_TRUE(v.PrepareDatabase());
   928    ASSERT_TRUE(v.VerifyAllGoals());
   929  }
   930  
   931  TEST_P(VerifierTest, GenerateAnchorEvarWithWhitespaceLines) {
   932    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   933  source { root:"1" }
   934  fact_name: "/kythe/node/kind"
   935  fact_value: "anchor"
   936  }
   937  entries {
   938  source { root:"1" }
   939  fact_name: "/kythe/loc/start"
   940  fact_value: "384"
   941  }
   942  entries {
   943  source { root:"1" }
   944  fact_name: "/kythe/loc/end"
   945  fact_value: "388"
   946  }
   947  entries {
   948  source { root:"1" }
   949  edge_kind: "/kythe/edge/defines"
   950  target { root:"2" }
   951  fact_name: "/"
   952  fact_value: ""
   953  }
   954  #- @texx defines SomeNode
   955  ##texx (line 22 column 2 offset 384-388))
   956  
   957  #-  SomeAnchor defines SomeNode)",
   958                                      "", "1"));
   959    ASSERT_TRUE(v.PrepareDatabase());
   960    ASSERT_TRUE(v.VerifyAllGoals());
   961  }
   962  
   963  TEST(VerifierUnitTest, GenerateTwoSeparatedAnchorEvars) {
   964    Verifier v;
   965    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
   966  #- @text defines SomeNode
   967  ##text (line 3 column 2 offset 38-42)
   968  #- @more defines OtherNode
   969  #more (line 5 column 1 offset 102-106
   970  source { root:"1" }
   971  fact_name: "/kythe/node/kind"
   972  fact_value: "anchor"
   973  }
   974  entries {
   975  source { root:"1" }
   976  fact_name: "/kythe/loc/start"
   977  fact_value: "38"
   978  }
   979  entries {
   980  source { root:"1" }
   981  fact_name: "/kythe/loc/end"
   982  fact_value: "42"
   983  }
   984  entries {
   985  source { root:"1" }
   986  edge_kind: "/kythe/edge/defines"
   987  target { root:"2" }
   988  fact_name: "/"
   989  fact_value: ""
   990  }
   991  entries {
   992  source { root:"3" }
   993  fact_name: "/kythe/node/kind"
   994  fact_value: "anchor"
   995  }
   996  entries {
   997  source { root:"3" }
   998  fact_name: "/kythe/loc/start"
   999  fact_value: "102"
  1000  }
  1001  entries {
  1002  source { root:"3" }
  1003  fact_name: "/kythe/loc/end"
  1004  fact_value: "106"
  1005  }
  1006  entries {
  1007  source { root:"3" }
  1008  edge_kind: "/kythe/edge/defines"
  1009  target { root:"4" }
  1010  fact_name: "/"
  1011  fact_value: ""
  1012  }
  1013  )"));
  1014    ASSERT_TRUE(v.PrepareDatabase());
  1015    ASSERT_TRUE(v.VerifyAllGoals());
  1016  }
  1017  
  1018  TEST(VerifierUnitTest, GenerateTwoSeparatedAnchorEvarsWithSpaces) {
  1019    Verifier v;
  1020    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1021  #- @" text" defines SomeNode
  1022   ## text (line 3 column 3 offset 42-47)
  1023  #- @" more	" defines OtherNode
  1024  # more	 (line 5 column 1 offset 111-117
  1025  source { root:"1" }
  1026  fact_name: "/kythe/node/kind"
  1027  fact_value: "anchor"
  1028  }
  1029  entries {
  1030  source { root:"1" }
  1031  fact_name: "/kythe/loc/start"
  1032  fact_value: "42"
  1033  }
  1034  entries {
  1035  source { root:"1" }
  1036  fact_name: "/kythe/loc/end"
  1037  fact_value: "47"
  1038  }
  1039  entries {
  1040  source { root:"1" }
  1041  edge_kind: "/kythe/edge/defines"
  1042  target { root:"2" }
  1043  fact_name: "/"
  1044  fact_value: ""
  1045  }
  1046  entries {
  1047  source { root:"3" }
  1048  fact_name: "/kythe/node/kind"
  1049  fact_value: "anchor"
  1050  }
  1051  entries {
  1052  source { root:"3" }
  1053  fact_name: "/kythe/loc/start"
  1054  fact_value: "111"
  1055  }
  1056  entries {
  1057  source { root:"3" }
  1058  fact_name: "/kythe/loc/end"
  1059  fact_value: "117"
  1060  }
  1061  entries {
  1062  source { root:"3" }
  1063  edge_kind: "/kythe/edge/defines"
  1064  target { root:"4" }
  1065  fact_name: "/"
  1066  fact_value: ""
  1067  }
  1068  )"));
  1069    ASSERT_TRUE(v.PrepareDatabase());
  1070    ASSERT_TRUE(v.VerifyAllGoals());
  1071  }
  1072  
  1073  TEST(VerifierUnitTest, GenerateTwoAnchorEvars) {
  1074    Verifier v;
  1075    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1076  #- @more defines SomeNode
  1077  #- @text defines OtherNode
  1078  ##text (line 4 column 2 offset 65-69) more (line 4 column 38 offset 101-105)
  1079  source { root:"1" }
  1080  fact_name: "/kythe/node/kind"
  1081  fact_value: "anchor"
  1082  }
  1083  entries {
  1084  source { root:"1" }
  1085  fact_name: "/kythe/loc/start"
  1086  fact_value: "65"
  1087  }
  1088  entries {
  1089  source { root:"1" }
  1090  fact_name: "/kythe/loc/end"
  1091  fact_value: "69"
  1092  }
  1093  entries {
  1094  source { root:"1" }
  1095  edge_kind: "/kythe/edge/defines"
  1096  target { root:"2" }
  1097  fact_name: "/"
  1098  fact_value: ""
  1099  }
  1100  entries {
  1101  source { root:"3" }
  1102  fact_name: "/kythe/node/kind"
  1103  fact_value: "anchor"
  1104  }
  1105  entries {
  1106  source { root:"3" }
  1107  fact_name: "/kythe/loc/start"
  1108  fact_value: "101"
  1109  }
  1110  entries {
  1111  source { root:"3" }
  1112  fact_name: "/kythe/loc/end"
  1113  fact_value: "105"
  1114  }
  1115  entries {
  1116  source { root:"3" }
  1117  edge_kind: "/kythe/edge/defines"
  1118  target { root:"4" }
  1119  fact_name: "/"
  1120  fact_value: ""
  1121  }
  1122  )"));
  1123    ASSERT_TRUE(v.PrepareDatabase());
  1124    ASSERT_TRUE(v.VerifyAllGoals());
  1125  }
  1126  
  1127  TEST_P(VerifierTest, ContentFactPasses) {
  1128    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1129  #- SomeNode.content 42
  1130  source { root:"1" }
  1131  fact_name: "/kythe/content"
  1132  fact_value: "42"
  1133  })"));
  1134    ASSERT_TRUE(v.PrepareDatabase());
  1135    ASSERT_TRUE(v.VerifyAllGoals());
  1136  }
  1137  
  1138  TEST_P(VerifierTest, BCPLCommentBlocksWrongRule) {
  1139    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1140  #- //SomeNode.content 43
  1141  #- SomeNode.content 42
  1142  source { root:"1" }
  1143  fact_name: "/kythe/content"
  1144  fact_value: "42"
  1145  })"));
  1146    ASSERT_TRUE(v.PrepareDatabase());
  1147    ASSERT_TRUE(v.VerifyAllGoals());
  1148  }
  1149  
  1150  TEST_P(VerifierTest, BCPLCommentInStringLiteral) {
  1151    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1152  #- SomeNode.content "4//2"
  1153  source { root:"1" }
  1154  fact_name: "/kythe/content"
  1155  fact_value: "4//2"
  1156  })"));
  1157    ASSERT_TRUE(v.PrepareDatabase());
  1158    ASSERT_TRUE(v.VerifyAllGoals());
  1159  }
  1160  
  1161  TEST_P(VerifierTest, BCPLCommentTrailingValue) {
  1162    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1163  #- SomeNode.content 42//x
  1164  source { root:"1" }
  1165  fact_name: "/kythe/content"
  1166  fact_value: "42"
  1167  })"));
  1168    ASSERT_TRUE(v.PrepareDatabase());
  1169    ASSERT_TRUE(v.VerifyAllGoals());
  1170  }
  1171  
  1172  TEST_P(VerifierTest, EmptyBCPLCommentTrailingValue) {
  1173    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1174  #- SomeNode.content 42//
  1175  source { root:"1" }
  1176  fact_name: "/kythe/content"
  1177  fact_value: "42"
  1178  })"));
  1179    ASSERT_TRUE(v.PrepareDatabase());
  1180    ASSERT_TRUE(v.VerifyAllGoals());
  1181  }
  1182  
  1183  TEST_P(VerifierTest, EmptyBCPLComment) {
  1184    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1185  #-//
  1186  #- SomeNode.content 43
  1187  source { root:"1" }
  1188  fact_name: "/kythe/content"
  1189  fact_value: "42"
  1190  })"));
  1191    ASSERT_TRUE(v.PrepareDatabase());
  1192    ASSERT_FALSE(v.VerifyAllGoals());
  1193  }
  1194  
  1195  TEST_P(VerifierTest, DontCareInNegativeIsGroundedPass) {
  1196    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1197  #- !{X typed vname(_,"","3","","")}
  1198  source { root:"1" }
  1199  edge_kind: "/kythe/edge/typed"
  1200  target { root:"2" }
  1201  fact_name: "/"
  1202  fact_value: ""
  1203  })"));
  1204    ASSERT_TRUE(v.PrepareDatabase());
  1205    ASSERT_TRUE(v.VerifyAllGoals());
  1206  }
  1207  
  1208  TEST_P(VerifierTest, FastSolverCantInspectNegatedEvar) {
  1209    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1210  #- !{_? nottyped SomeType}
  1211  source { root:"1" }
  1212  edge_kind: "/kythe/edge/typed"
  1213  target { root:"2" }
  1214  fact_name: "/"
  1215  fact_value: ""
  1216  })"));
  1217    ASSERT_TRUE(v.PrepareDatabase());
  1218    if (GetParam() == Solver::New) {
  1219      ASSERT_FALSE(v.VerifyAllGoals());
  1220    } else {
  1221      ASSERT_TRUE(v.VerifyAllGoals());
  1222    }
  1223  }
  1224  
  1225  TEST_P(VerifierTest, FastSolverIgnoresInspectImplicitNegatedDontCareEvar) {
  1226    v.SaveEVarAssignments();
  1227    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1228  #- !{Var=_ nottyped SomeType}
  1229  source { root:"1" }
  1230  edge_kind: "/kythe/edge/typed"
  1231  target { root:"2" }
  1232  fact_name: "/"
  1233  fact_value: ""
  1234  })"));
  1235    ASSERT_TRUE(v.PrepareDatabase());
  1236    // SaveEVarAssignments marks Implicit and SomeType as implicitly inspected
  1237    // EVars. These should not cause verification to fail even though they appear
  1238    // in a negated context.
  1239    ASSERT_TRUE(v.VerifyAllGoals());
  1240  }
  1241  
  1242  TEST_P(VerifierTest, FastSolverIgnoresInspectImplicitNegatedEvar) {
  1243    v.SaveEVarAssignments();
  1244    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1245  #- !{Implicit nottyped SomeType}
  1246  source { root:"1" }
  1247  edge_kind: "/kythe/edge/typed"
  1248  target { root:"2" }
  1249  fact_name: "/"
  1250  fact_value: ""
  1251  })"));
  1252    ASSERT_TRUE(v.PrepareDatabase());
  1253    // SaveEVarAssignments marks Implicit and SomeType as implicitly inspected
  1254    // EVars. These should not cause verification to fail even though they appear
  1255    // in a negated context.
  1256    ASSERT_TRUE(v.VerifyAllGoals());
  1257  }
  1258  
  1259  TEST_P(VerifierTest, DontCareInNegativeIsGroundedFail) {
  1260    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1261  #- !{X typed vname(_,"","2","","")}
  1262  source { root:"1" }
  1263  edge_kind: "/kythe/edge/typed"
  1264  target { root:"2" }
  1265  fact_name: "/"
  1266  fact_value: ""
  1267  })"));
  1268    ASSERT_TRUE(v.PrepareDatabase());
  1269    ASSERT_FALSE(v.VerifyAllGoals());
  1270  }
  1271  
  1272  TEST(VerifierUnitTest, EVarsUnsetAfterNegatedBlock) {
  1273    Verifier v;
  1274    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1275  #- !{vname(_,_,Root?="3",_,_) defines SomeNode}
  1276  source { root:"1" }
  1277  edge_kind: "/kythe/edge/defines"
  1278  target { root:"2" }
  1279  fact_name: "/"
  1280  fact_value: ""
  1281  })"));
  1282    size_t call_count = 0;
  1283    bool evar_unset = false;
  1284    ASSERT_TRUE(v.PrepareDatabase());
  1285    ASSERT_TRUE(v.VerifyAllGoals(
  1286        [&call_count, &evar_unset](Verifier* cxt, const Inspection& inspection,
  1287                                   std::string_view) {
  1288          ++call_count;
  1289          if (inspection.label == "Root" && !inspection.evar->current()) {
  1290            evar_unset = true;
  1291          }
  1292          return true;
  1293        }));
  1294    EXPECT_EQ(1, call_count);
  1295    EXPECT_TRUE(evar_unset);
  1296  }
  1297  
  1298  TEST(VerifierUnitTest, NegatedBlocksDontLeak) {
  1299    Verifier v;
  1300    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1301  #- !{vname(_,_,Root="3",_,_) defines SomeNode}
  1302  #- !{vname(_,_,Root?,_,_) notanedge OtherNode}
  1303  source { root:"1" }
  1304  edge_kind: "/kythe/edge/defines"
  1305  target { root:"2" }
  1306  fact_name: "/"
  1307  fact_value: ""
  1308  })"));
  1309    size_t call_count = 0;
  1310    bool evar_unset = false;
  1311    ASSERT_TRUE(v.PrepareDatabase());
  1312    ASSERT_TRUE(v.VerifyAllGoals(
  1313        [&call_count, &evar_unset](Verifier* cxt, const Inspection& inspection,
  1314                                   std::string_view) {
  1315          ++call_count;
  1316          if (inspection.label == "Root" && !inspection.evar->current()) {
  1317            evar_unset = true;
  1318          }
  1319          return true;
  1320        }));
  1321    EXPECT_EQ(1, call_count);
  1322    EXPECT_TRUE(evar_unset);
  1323  }
  1324  
  1325  TEST(VerifierUnitTest, UngroupedEVarsAvailableInGroupedContexts) {
  1326    Verifier v;
  1327    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1328  #- vname(_,_,Root="3",_,_) defines SomeNode
  1329  #- !{vname(_,_,Root?,_,_) defines SomeNode}
  1330  source { root:"1" }
  1331  edge_kind: "/kythe/edge/defines"
  1332  target { root:"2" }
  1333  fact_name: "/"
  1334  fact_value: ""
  1335  }
  1336  entries {
  1337  source { root:"3" }
  1338  edge_kind: "/kythe/edge/defines"
  1339  target { root:"4" }
  1340  fact_name: "/"
  1341  fact_value: ""
  1342  })"));
  1343    size_t call_count = 0;
  1344    bool evar_set = false;
  1345    ASSERT_TRUE(v.PrepareDatabase());
  1346    ASSERT_FALSE(v.VerifyAllGoals([&call_count, &evar_set](
  1347                                      Verifier* cxt, const Inspection& inspection,
  1348                                      std::string_view) {
  1349      ++call_count;
  1350      if (inspection.label == "Root" && inspection.evar->current()) {
  1351        if (Identifier* identifier = inspection.evar->current()->AsIdentifier()) {
  1352          if (cxt->symbol_table()->text(identifier->symbol()) == "3") {
  1353            evar_set = true;
  1354          }
  1355        }
  1356      }
  1357      return true;
  1358    }));
  1359    EXPECT_EQ(1, call_count);
  1360    EXPECT_TRUE(evar_set);
  1361  }
  1362  
  1363  TEST(VerifierUnitTest, UngroupedEVarsAvailableInGroupedContextsReordered) {
  1364    Verifier v;
  1365    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1366  #- !{vname(_,_,Root?,_,_) defines SomeNode}
  1367  #- vname(_,_,Root="3",_,_) defines SomeNode
  1368  source { root:"1" }
  1369  edge_kind: "/kythe/edge/defines"
  1370  target { root:"2" }
  1371  fact_name: "/"
  1372  fact_value: ""
  1373  }
  1374  entries {
  1375  source { root:"3" }
  1376  edge_kind: "/kythe/edge/defines"
  1377  target { root:"4" }
  1378  fact_name: "/"
  1379  fact_value: ""
  1380  })"));
  1381    size_t call_count = 0;
  1382    bool evar_set = false;
  1383    ASSERT_TRUE(v.PrepareDatabase());
  1384    ASSERT_FALSE(v.VerifyAllGoals([&call_count, &evar_set](
  1385                                      Verifier* cxt, const Inspection& inspection,
  1386                                      std::string_view) {
  1387      ++call_count;
  1388      if (inspection.label == "Root" && inspection.evar->current()) {
  1389        if (Identifier* identifier = inspection.evar->current()->AsIdentifier()) {
  1390          if (cxt->symbol_table()->text(identifier->symbol()) == "3") {
  1391            evar_set = true;
  1392          }
  1393        }
  1394      }
  1395      return true;
  1396    }));
  1397    EXPECT_EQ(1, call_count);
  1398    EXPECT_TRUE(evar_set);
  1399  }
  1400  
  1401  TEST(VerifierUnitTest, EVarsReportedAfterFailedNegatedBlock) {
  1402    Verifier v;
  1403    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1404  #- !{vname(_,_,Root?="1",_,_) defines SomeNode}
  1405  source { root:"1" }
  1406  edge_kind: "/kythe/edge/defines"
  1407  target { root:"2" }
  1408  fact_name: "/"
  1409  fact_value: ""
  1410  })"));
  1411    size_t call_count = 0;
  1412    bool evar_set = false;
  1413    ASSERT_TRUE(v.PrepareDatabase());
  1414    ASSERT_FALSE(v.VerifyAllGoals([&call_count, &evar_set](
  1415                                      Verifier* cxt, const Inspection& inspection,
  1416                                      std::string_view) {
  1417      ++call_count;
  1418      if (inspection.label == "Root" && inspection.evar->current()) {
  1419        if (Identifier* identifier = inspection.evar->current()->AsIdentifier()) {
  1420          if (cxt->symbol_table()->text(identifier->symbol()) == "1") {
  1421            evar_set = true;
  1422          }
  1423        }
  1424      }
  1425      return true;
  1426    }));
  1427    EXPECT_EQ(1, call_count);
  1428    EXPECT_TRUE(evar_set);
  1429  }
  1430  
  1431  TEST_P(VerifierTest, GroupFactFails) {
  1432    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1433  #- { SomeNode.content 43 }
  1434  source { root:"1" }
  1435  fact_name: "/kythe/content"
  1436  fact_value: "42"
  1437  })"));
  1438    ASSERT_TRUE(v.PrepareDatabase());
  1439    ASSERT_FALSE(v.VerifyAllGoals());
  1440  }
  1441  
  1442  // Slightly brittle in that it depends on the order we try facts.
  1443  TEST_P(VerifierTest, FailWithCutInGroups) {
  1444    if (GetParam() == Solver::New) {
  1445      // The new solver will pick the second entry.
  1446      GTEST_SKIP();
  1447    }
  1448    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1449  #- { SomeNode.content SomeValue }
  1450  #- { SomeNode.content 43 }
  1451  source { root:"1" }
  1452  fact_name: "/kythe/content"
  1453  fact_value: "42"
  1454  }
  1455  entries {
  1456  source { root:"2" }
  1457  fact_name: "/kythe/content"
  1458  fact_value: "43"
  1459  })"));
  1460    ASSERT_TRUE(v.PrepareDatabase());
  1461    ASSERT_FALSE(v.VerifyAllGoals());
  1462  }
  1463  
  1464  // Slightly brittle in that it depends on the order we try facts.
  1465  TEST_P(VerifierTest, FailWithCut) {
  1466    if (GetParam() == Solver::New) {
  1467      // The new solver will pick the second entry.
  1468      GTEST_SKIP();
  1469    }
  1470    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1471  #- SomeNode.content SomeValue
  1472  #- { SomeNode.content 43 }
  1473  source { root:"1" }
  1474  fact_name: "/kythe/content"
  1475  fact_value: "42"
  1476  }
  1477  entries {
  1478  source { root:"2" }
  1479  fact_name: "/kythe/content"
  1480  fact_value: "43"
  1481  })"));
  1482    ASSERT_TRUE(v.PrepareDatabase());
  1483    ASSERT_FALSE(v.VerifyAllGoals());
  1484  }
  1485  
  1486  TEST_P(VerifierTest, PassWithoutCut) {
  1487    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1488  #- SomeNode.content SomeValue
  1489  #- SomeNode.content 43
  1490  source { root:"1" }
  1491  fact_name: "/kythe/content"
  1492  fact_value: "42"
  1493  }
  1494  entries {
  1495  source { root:"2" }
  1496  fact_name: "/kythe/content"
  1497  fact_value: "43"
  1498  })"));
  1499    ASSERT_TRUE(v.PrepareDatabase());
  1500    ASSERT_TRUE(v.VerifyAllGoals());
  1501  }
  1502  
  1503  TEST_P(VerifierTest, GroupFactPasses) {
  1504    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1505  #- { SomeNode.content 42 }
  1506  source { root:"1" }
  1507  fact_name: "/kythe/content"
  1508  fact_value: "42"
  1509  })"));
  1510    ASSERT_TRUE(v.PrepareDatabase());
  1511    ASSERT_TRUE(v.VerifyAllGoals());
  1512  }
  1513  
  1514  TEST_P(VerifierTest, CompoundGroups) {
  1515    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1516  #- SomeNode.content 42
  1517  #- !{ OtherNode.content 43
  1518  #-    AnotherNode.content 44 }
  1519  #- !{ LastNode.content 45 }
  1520  source { root:"1" }
  1521  fact_name: "/kythe/content"
  1522  fact_value: "42"
  1523  }
  1524  entries {
  1525  source { root:"2" }
  1526  fact_name: "/kythe/content"
  1527  fact_value: "43"
  1528  }
  1529  )"));
  1530    ASSERT_TRUE(v.PrepareDatabase());
  1531    ASSERT_TRUE(v.VerifyAllGoals());
  1532  }
  1533  
  1534  TEST_P(VerifierTest, ConjunctionInsideNegatedGroupPassFail) {
  1535    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1536  #- !{ SomeNode.content 42
  1537  #-    OtherNode.content 44 }
  1538  source { root:"1" }
  1539  fact_name: "/kythe/content"
  1540  fact_value: "42"
  1541  }
  1542  entries {
  1543  source { root:"2" }
  1544  fact_name: "/kythe/content"
  1545  fact_value: "43"
  1546  }
  1547  )"));
  1548    ASSERT_TRUE(v.PrepareDatabase());
  1549    ASSERT_TRUE(v.VerifyAllGoals());
  1550  }
  1551  
  1552  TEST_P(VerifierTest, ConjunctionInsideNegatedGroupPassPass) {
  1553    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1554  #- !{ SomeNode.content 42
  1555  #-    OtherNode.content 43 }
  1556  source { root:"1" }
  1557  fact_name: "/kythe/content"
  1558  fact_value: "42"
  1559  }
  1560  entries {
  1561  source { root:"2" }
  1562  fact_name: "/kythe/content"
  1563  fact_value: "43"
  1564  }
  1565  )"));
  1566    ASSERT_TRUE(v.PrepareDatabase());
  1567    ASSERT_FALSE(v.VerifyAllGoals());
  1568  }
  1569  
  1570  TEST_P(VerifierTest, AntiContentFactFails) {
  1571    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1572  #- !{ SomeNode.content 42 }
  1573  source { root:"1" }
  1574  fact_name: "/kythe/content"
  1575  fact_value: "42"
  1576  })"));
  1577    ASSERT_TRUE(v.PrepareDatabase());
  1578    ASSERT_FALSE(v.VerifyAllGoals());
  1579  }
  1580  
  1581  TEST_P(VerifierTest, AntiContentFactPasses) {
  1582    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1583  #- !{ SomeNode.content 43 }
  1584  source { root:"1" }
  1585  fact_name: "/kythe/content"
  1586  fact_value: "42"
  1587  })"));
  1588    ASSERT_TRUE(v.PrepareDatabase());
  1589    ASSERT_TRUE(v.VerifyAllGoals());
  1590  }
  1591  
  1592  TEST_P(VerifierTest, SpacesAreOkay) {
  1593    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1594     	 #- SomeNode.content 42
  1595  source { root:"1" }
  1596  fact_name: "/kythe/content"
  1597  fact_value: "42"
  1598  })"));
  1599    ASSERT_TRUE(v.PrepareDatabase());
  1600    ASSERT_TRUE(v.VerifyAllGoals());
  1601  }
  1602  
  1603  TEST_P(VerifierTest, ContentFactFails) {
  1604    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1605  #- SomeNode.content 42
  1606  source { root:"1" }
  1607  fact_name: "/kythe/content"
  1608  fact_value: "43"
  1609  })"));
  1610    ASSERT_TRUE(v.PrepareDatabase());
  1611    ASSERT_FALSE(v.VerifyAllGoals());
  1612  }
  1613  
  1614  TEST_P(VerifierTest, PercentContentFactFails) {
  1615    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1616  #- SomeNode.%content 42
  1617  source { root:"1" }
  1618  fact_name: "%/kythe/content"
  1619  fact_value: "43"
  1620  })"));
  1621    ASSERT_TRUE(v.PrepareDatabase());
  1622    ASSERT_FALSE(v.VerifyAllGoals());
  1623  }
  1624  
  1625  TEST_P(VerifierTest, SpacesDontDisableRules) {
  1626    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1627     	 #- SomeNode.content 42
  1628  source { root:"1" }
  1629  fact_name: "/kythe/content"
  1630  fact_value: "43"
  1631  })"));
  1632    ASSERT_TRUE(v.PrepareDatabase());
  1633    ASSERT_FALSE(v.VerifyAllGoals());
  1634  }
  1635  
  1636  TEST_P(VerifierTest, DefinesEdgePasses) {
  1637    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1638  #- SomeAnchor defines SomeNode
  1639  source { root:"1" }
  1640  edge_kind: "/kythe/edge/defines"
  1641  target { root:"2" }
  1642  fact_name: "/"
  1643  fact_value: ""
  1644  })"));
  1645    ASSERT_TRUE(v.PrepareDatabase());
  1646    ASSERT_TRUE(v.VerifyAllGoals());
  1647  }
  1648  
  1649  TEST_P(VerifierTest, HashDefinesEdgePasses) {
  1650    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1651  #- SomeAnchor #defines SomeNode
  1652  source { root:"1" }
  1653  edge_kind: "#/kythe/edge/defines"
  1654  target { root:"2" }
  1655  fact_name: "/"
  1656  fact_value: ""
  1657  })"));
  1658    ASSERT_TRUE(v.PrepareDatabase());
  1659    ASSERT_TRUE(v.VerifyAllGoals());
  1660  }
  1661  
  1662  TEST_P(VerifierTest, HashFullDefinesEdgePasses) {
  1663    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1664  #- SomeAnchor #/kythe/edge/defines SomeNode
  1665  source { root:"1" }
  1666  edge_kind: "#/kythe/edge/defines"
  1667  target { root:"2" }
  1668  fact_name: "/"
  1669  fact_value: ""
  1670  })"));
  1671    ASSERT_TRUE(v.PrepareDatabase());
  1672    ASSERT_TRUE(v.VerifyAllGoals());
  1673  }
  1674  
  1675  TEST_P(VerifierTest, PercentDefinesEdgePasses) {
  1676    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1677  #- SomeAnchor %defines SomeNode
  1678  source { root:"1" }
  1679  edge_kind: "%/kythe/edge/defines"
  1680  target { root:"2" }
  1681  fact_name: "/"
  1682  fact_value: ""
  1683  })"));
  1684    ASSERT_TRUE(v.PrepareDatabase());
  1685    ASSERT_TRUE(v.VerifyAllGoals());
  1686  }
  1687  
  1688  TEST_P(VerifierTest, PercentFullDefinesEdgePasses) {
  1689    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1690  #- SomeAnchor %/kythe/edge/defines SomeNode
  1691  source { root:"1" }
  1692  edge_kind: "%/kythe/edge/defines"
  1693  target { root:"2" }
  1694  fact_name: "/"
  1695  fact_value: ""
  1696  })"));
  1697    ASSERT_TRUE(v.PrepareDatabase());
  1698    ASSERT_TRUE(v.VerifyAllGoals());
  1699  }
  1700  
  1701  TEST_P(VerifierTest, IsParamEdgePasses) {
  1702    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1703  #- SomeParam is_param.1 SomeNode
  1704  source { root:"1" }
  1705  edge_kind: "/kythe/edge/is_param"
  1706  target { root:"2" }
  1707  fact_name: "/kythe/ordinal"
  1708  fact_value: "1"
  1709  })"));
  1710    ASSERT_TRUE(v.PrepareDatabase());
  1711    ASSERT_TRUE(v.VerifyAllGoals());
  1712  }
  1713  
  1714  TEST_P(VerifierTest, IsParamEdgePassesDotOrdinal) {
  1715    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1716  #- SomeParam is_param.1 SomeNode
  1717  source { root:"1" }
  1718  edge_kind: "/kythe/edge/is_param.1"
  1719  target { root:"2" }
  1720  fact_name: "/"
  1721  })"));
  1722    ASSERT_TRUE(v.PrepareDatabase());
  1723    ASSERT_TRUE(v.VerifyAllGoals());
  1724  }
  1725  
  1726  TEST_P(VerifierTest, IsParamEdgeBadDotOrdinalNoNumber) {
  1727    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1728  #- SomeParam is_param.1 SomeNode
  1729  source { root:"1" }
  1730  edge_kind: "/kythe/edge/is_param."
  1731  target { root:"2" }
  1732  fact_name: "/"
  1733  })"));
  1734    ASSERT_TRUE(v.PrepareDatabase());
  1735    ASSERT_FALSE(v.VerifyAllGoals());
  1736  }
  1737  
  1738  TEST_P(VerifierTest, IsParamEdgeBadDotOrdinalOnlyDot) {
  1739    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1740  #- SomeParam is_param.1 SomeNode
  1741  source { root:"1" }
  1742  edge_kind: "."
  1743  target { root:"2" }
  1744  fact_name: "/"
  1745  })"));
  1746    ASSERT_TRUE(v.PrepareDatabase());
  1747    ASSERT_FALSE(v.VerifyAllGoals());
  1748  }
  1749  
  1750  TEST_P(VerifierTest, IsParamEdgeBadDotOrdinalNoEdge) {
  1751    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1752  #- SomeParam is_param.1 SomeNode
  1753  source { root:"1" }
  1754  edge_kind: ".42"
  1755  target { root:"2" }
  1756  fact_name: "/"
  1757  })"));
  1758    ASSERT_TRUE(v.PrepareDatabase());
  1759    ASSERT_FALSE(v.VerifyAllGoals());
  1760  }
  1761  
  1762  TEST_P(VerifierTest, IsParamEdgeFailsOnWrongOrdinal) {
  1763    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1764  #- SomeParam is_param.1 SomeNode
  1765  source { root:"1" }
  1766  edge_kind: "/kythe/edge/is_param"
  1767  target { root:"2" }
  1768  fact_name: "/kythe/ordinal"
  1769  fact_value: "42"
  1770  })"));
  1771    ASSERT_TRUE(v.PrepareDatabase());
  1772    ASSERT_FALSE(v.VerifyAllGoals());
  1773  }
  1774  
  1775  TEST_P(VerifierTest, IsParamEdgeFailsOnWrongDotOrdinal) {
  1776    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1777  #- SomeParam is_param.1 SomeNode
  1778  source { root:"1" }
  1779  edge_kind: "/kythe/edge/is_param.42"
  1780  target { root:"2" }
  1781  fact_name: "/"
  1782  })"));
  1783    ASSERT_TRUE(v.PrepareDatabase());
  1784    ASSERT_FALSE(v.VerifyAllGoals());
  1785  }
  1786  
  1787  TEST_P(VerifierTest, IsParamEdgeFailsOnMissingOrdinalInGoal) {
  1788    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1789  #- SomeParam is_param SomeNode
  1790  source { root:"1" }
  1791  edge_kind: "/kythe/edge/is_param"
  1792  target { root:"2" }
  1793  fact_name: "/kythe/ordinal"
  1794  fact_value: "42"
  1795  })"));
  1796    ASSERT_TRUE(v.PrepareDatabase());
  1797    ASSERT_FALSE(v.VerifyAllGoals());
  1798  }
  1799  
  1800  TEST_P(VerifierTest, IsParamEdgeFailsOnMissingDotOrdinalInGoal) {
  1801    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1802  #- SomeParam is_param SomeNode
  1803  source { root:"1" }
  1804  edge_kind: "/kythe/edge/is_param.42"
  1805  target { root:"2" }
  1806  fact_name: "/"
  1807  })"));
  1808    ASSERT_TRUE(v.PrepareDatabase());
  1809    ASSERT_FALSE(v.VerifyAllGoals());
  1810  }
  1811  
  1812  TEST_P(VerifierTest, IsParamEdgeFailsOnMissingOrdinalInFact) {
  1813    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1814  #- SomeParam is_param.42 SomeNode
  1815  source { root:"1" }
  1816  edge_kind: "/kythe/edge/is_param"
  1817  target { root:"2" }
  1818  fact_name: "/"
  1819  fact_value: ""
  1820  })"));
  1821    ASSERT_TRUE(v.PrepareDatabase());
  1822    ASSERT_FALSE(v.VerifyAllGoals());
  1823  }
  1824  
  1825  TEST_P(VerifierTest, EvarsShareANamespace) {
  1826    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1827  #- SomeAnchor defines SomeNode
  1828  #- SomeNode defines SomeAnchor
  1829  source { root:"1" }
  1830  edge_kind: "/kythe/edge/defines"
  1831  target { root:"2" }
  1832  fact_name: "/"
  1833  fact_value: ""
  1834  })"));
  1835    ASSERT_TRUE(v.PrepareDatabase());
  1836    ASSERT_FALSE(v.VerifyAllGoals());
  1837  }
  1838  
  1839  TEST_P(VerifierTest, DefinesEdgePassesSymmetry) {
  1840    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1841  #- SomeAnchor defines SomeNode
  1842  source { root:"1" }
  1843  edge_kind: "/kythe/edge/defines"
  1844  target { root:"2" }
  1845  fact_name: "/"
  1846  fact_value: ""
  1847  }
  1848  entries {
  1849  #- SomeNode defined_by SomeAnchor
  1850  source { root:"2" }
  1851  edge_kind: "/kythe/edge/defined_by"
  1852  target { root:"1" }
  1853  fact_name: "/"
  1854  fact_value: ""
  1855  }
  1856  )"));
  1857    ASSERT_TRUE(v.PrepareDatabase());
  1858    ASSERT_TRUE(v.VerifyAllGoals());
  1859  }
  1860  
  1861  TEST_P(VerifierTest, EvarsStillShareANamespace) {
  1862    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1863  #- SomeAnchor defines SomeNode
  1864  source { root:"1" }
  1865  edge_kind: "/kythe/edge/defines"
  1866  target { root:"2" }
  1867  fact_name: "/"
  1868  fact_value: ""
  1869  }
  1870  entries {
  1871  #- SomeAnchor defined_by SomeNode
  1872  source { root:"2" }
  1873  edge_kind: "/kythe/edge/defined_by"
  1874  target { root:"1" }
  1875  fact_name: "/"
  1876  fact_value: ""
  1877  }
  1878  )"));
  1879    ASSERT_TRUE(v.PrepareDatabase());
  1880    ASSERT_FALSE(v.VerifyAllGoals());
  1881  }
  1882  
  1883  TEST(VerifierUnitTest, InspectionCalledFailure) {
  1884    Verifier v;
  1885    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1886  #- SomeAnchor? defines SomeNode
  1887  source { root:"1" }
  1888  edge_kind: "/kythe/edge/defines"
  1889  target { root:"2" }
  1890  fact_name: "/"
  1891  fact_value: ""
  1892  })"));
  1893    ASSERT_TRUE(v.PrepareDatabase());
  1894    ASSERT_FALSE(v.VerifyAllGoals([](Verifier* cxt, const Inspection&,
  1895                                     std::string_view) { return false; }));
  1896  }
  1897  
  1898  TEST(VerifierUnitTest, EvarsAreSharedAcrossInputFiles) {
  1899    Verifier v;
  1900    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1901  #- SomeAnchor? defines SomeNode
  1902  source { root:"1" }
  1903  edge_kind: "/kythe/edge/defines"
  1904  target { root:"2" }
  1905  fact_name: "/"
  1906  fact_value: ""
  1907  })"));
  1908    ASSERT_TRUE(v.LoadInlineProtoFile(R"(
  1909  #- SomeAnchor? defines _
  1910  )"));
  1911    ASSERT_TRUE(v.PrepareDatabase());
  1912    EVar* seen_evar = nullptr;
  1913    int seen_count = 0;
  1914    ASSERT_TRUE(v.VerifyAllGoals(
  1915        [&seen_evar, &seen_count](Verifier* cxt, const Inspection& inspection,
  1916                                  std::string_view) {
  1917          if (inspection.label == "SomeAnchor") {
  1918            ++seen_count;
  1919            if (seen_evar == nullptr) {
  1920              seen_evar = inspection.evar;
  1921            } else if (seen_evar != inspection.evar) {
  1922              return false;
  1923            }
  1924          }
  1925          return true;
  1926        }));
  1927    ASSERT_EQ(2, seen_count);
  1928    ASSERT_NE(nullptr, seen_evar);
  1929  }
  1930  
  1931  TEST(VerifierUnitTest, InspectionCalledSuccess) {
  1932    Verifier v;
  1933    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1934  #- SomeAnchor? defines SomeNode
  1935  source { root:"1" }
  1936  edge_kind: "/kythe/edge/defines"
  1937  target { root:"2" }
  1938  fact_name: "/"
  1939  fact_value: ""
  1940  })"));
  1941    ASSERT_TRUE(v.PrepareDatabase());
  1942    ASSERT_TRUE(v.VerifyAllGoals(
  1943        [](Verifier* cxt, const Inspection&, std::string_view) { return true; }));
  1944  }
  1945  
  1946  TEST_P(VerifierTest, ManyInspectionsDontUpsetSolver) {
  1947    // Souffle ships with a default max arity of 20 and will abort if it hits a
  1948    // larger (output) relation. Check that we handle this.
  1949    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1950  #- I01? defines SomeNode
  1951  #- I02? defines SomeNode
  1952  #- I03? defines SomeNode
  1953  #- I04? defines SomeNode
  1954  #- I05? defines SomeNode
  1955  #- I06? defines SomeNode
  1956  #- I07? defines SomeNode
  1957  #- I08? defines SomeNode
  1958  #- I09? defines SomeNode
  1959  #- I10? defines SomeNode
  1960  #- I11? defines SomeNode
  1961  #- I12? defines SomeNode
  1962  #- I13? defines SomeNode
  1963  #- I14? defines SomeNode
  1964  #- I15? defines SomeNode
  1965  #- I16? defines SomeNode
  1966  #- I17? defines SomeNode
  1967  #- I18? defines SomeNode
  1968  #- I19? defines SomeNode
  1969  #- I20? defines SomeNode
  1970  #- I21? defines SomeNode
  1971  
  1972  source { root:"1" }
  1973  edge_kind: "/kythe/edge/defines"
  1974  target { root:"2" }
  1975  fact_name: "/"
  1976  fact_value: ""
  1977  })"));
  1978    int inspection_count = 0;
  1979    ASSERT_TRUE(v.PrepareDatabase());
  1980    ASSERT_TRUE(
  1981        v.VerifyAllGoals([&](Verifier* cxt, const Inspection&, std::string_view) {
  1982          ++inspection_count;
  1983          return true;
  1984        }));
  1985    EXPECT_EQ(inspection_count, 21);
  1986  }
  1987  
  1988  TEST(VerifierUnitTest, InspectionHappensMoreThanOnceAndThatsOk) {
  1989    Verifier v;
  1990    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  1991  #- SomeAnchor? defines SomeNode
  1992  #- SomeAnchor? defines SomeNode
  1993  source { root:"1" }
  1994  edge_kind: "/kythe/edge/defines"
  1995  target { root:"2" }
  1996  fact_name: "/"
  1997  fact_value: ""
  1998  })"));
  1999    ASSERT_TRUE(v.PrepareDatabase());
  2000    size_t inspect_count = 0;
  2001    ASSERT_TRUE(v.VerifyAllGoals(
  2002        [&inspect_count](Verifier* cxt, const Inspection&, std::string_view) {
  2003          ++inspect_count;
  2004          return true;
  2005        }));
  2006    ASSERT_EQ(2, inspect_count);
  2007  }
  2008  
  2009  TEST_P(VerifierTest, InspectionCalledCorrectly) {
  2010    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2011  #- SomeAnchor? defines SomeNode
  2012  source { root:"1" }
  2013  edge_kind: "/kythe/edge/defines"
  2014  target { root:"2" }
  2015  fact_name: "/"
  2016  fact_value: ""
  2017  })"));
  2018    ASSERT_TRUE(v.PrepareDatabase());
  2019    size_t call_count = 0;
  2020    bool key_was_someanchor = false;
  2021    bool evar_init = false;
  2022    std::string istr;
  2023    ASSERT_TRUE(v.VerifyAllGoals([&](Verifier* cxt, const Inspection& inspection,
  2024                                     std::optional<std::string_view> s) {
  2025      ++call_count;
  2026      // Check for equivalence to `App(#vname, (#"", #"", 1, #"", #""))`
  2027      key_was_someanchor = (inspection.label == "SomeAnchor");
  2028      istr = s ? *s : v.InspectionString(inspection);
  2029      return true;
  2030    }));
  2031    EXPECT_EQ(1, call_count);
  2032    EXPECT_EQ(R"(vname("", "", "1", "", ""))", istr);
  2033    EXPECT_TRUE(key_was_someanchor);
  2034  }
  2035  
  2036  TEST_P(VerifierTest, FactsAreNotLinear) {
  2037    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2038  #- SomeAnchor? defines SomeNode?
  2039  #- AnotherAnchor? defines AnotherNode?
  2040  source { root:"1" }
  2041  edge_kind: "/kythe/edge/defines"
  2042  target { root:"2" }
  2043  fact_name: "/"
  2044  fact_value: ""
  2045  })"));
  2046    ASSERT_TRUE(v.PrepareDatabase());
  2047    std::string some_anchor, some_node, another_anchor, another_node;
  2048    ASSERT_TRUE(v.VerifyAllGoals(
  2049        [&some_anchor, &some_node, &another_anchor, &another_node](
  2050            Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2051          if (inspection.label == "SomeAnchor") {
  2052            some_anchor = s;
  2053          } else if (inspection.label == "SomeNode") {
  2054            some_node = s;
  2055          } else if (inspection.label == "AnotherAnchor") {
  2056            another_anchor = s;
  2057          } else if (inspection.label == "AnotherNode") {
  2058            another_node = s;
  2059          } else {
  2060            return false;
  2061          }
  2062          return true;
  2063        }));
  2064    EXPECT_EQ(some_anchor, another_anchor);
  2065    EXPECT_EQ(some_node, another_node);
  2066    EXPECT_NE(some_anchor, some_node);
  2067    EXPECT_NE(another_anchor, another_node);
  2068  }
  2069  
  2070  TEST_P(VerifierTest, OrdinalsGetUnified) {
  2071    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2072  #- SomeAnchor is_param.Ordinal? SomeNode
  2073  source { root:"1" }
  2074  edge_kind: "/kythe/edge/is_param"
  2075  target { root:"2" }
  2076  fact_name: "/kythe/ordinal"
  2077  fact_value: "42"
  2078  })"));
  2079    ASSERT_TRUE(v.PrepareDatabase());
  2080    size_t call_count = 0;
  2081    bool key_was_ordinal = false;
  2082    bool evar_init = false;
  2083    bool evar_init_to_correct_ordinal = false;
  2084    ASSERT_TRUE(v.VerifyAllGoals(
  2085        [&call_count, &key_was_ordinal, &evar_init,
  2086         &evar_init_to_correct_ordinal](
  2087            Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2088          ++call_count;
  2089          key_was_ordinal = (inspection.label == "Ordinal");
  2090          evar_init = CheckEVarInit(s);
  2091          evar_init_to_correct_ordinal = s == "\"42\"";
  2092          return true;
  2093        }));
  2094    EXPECT_EQ(1, call_count);
  2095    EXPECT_TRUE(key_was_ordinal);
  2096    EXPECT_TRUE(evar_init_to_correct_ordinal);
  2097  }
  2098  
  2099  TEST(VerifierUnitTest, DotOrdinalsGetUnified) {
  2100    Verifier v;
  2101    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2102  #- SomeAnchor is_param.Ordinal? SomeNode
  2103  source { root:"1" }
  2104  edge_kind: "/kythe/edge/is_param.42"
  2105  target { root:"2" }
  2106  fact_name: "/"
  2107  })"));
  2108    ASSERT_TRUE(v.PrepareDatabase());
  2109    size_t call_count = 0;
  2110    bool key_was_ordinal = false;
  2111    bool evar_init = false;
  2112    bool evar_init_to_correct_ordinal = false;
  2113    ASSERT_TRUE(v.VerifyAllGoals(
  2114        [&call_count, &key_was_ordinal, &evar_init,
  2115         &evar_init_to_correct_ordinal](
  2116            Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2117          ++call_count;
  2118          key_was_ordinal = (inspection.label == "Ordinal");
  2119          evar_init = CheckEVarInit(s);
  2120          evar_init_to_correct_ordinal = s == "\"42\"";
  2121          return true;
  2122        }));
  2123    EXPECT_EQ(1, call_count);
  2124    EXPECT_TRUE(key_was_ordinal);
  2125    EXPECT_TRUE(evar_init_to_correct_ordinal);
  2126  }
  2127  
  2128  TEST_P(VerifierTest, EvarsAndIdentifiersCanHaveTheSameText) {
  2129    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2130  #- vname(Signature?, "Signature", Root?, Path?, Language?) defines SomeNode
  2131  source {
  2132    signature:"Signature"
  2133    corpus:"Signature"
  2134    root:"Root"
  2135    path:"Path"
  2136    language:"Language"
  2137  }
  2138  edge_kind: "/kythe/edge/defines"
  2139  target { root:"2" }
  2140  fact_name: "/"
  2141  fact_value: ""
  2142  })"));
  2143    ASSERT_TRUE(v.PrepareDatabase());
  2144    bool signature = false;
  2145    bool root = false;
  2146    bool path = false;
  2147    bool language = false;
  2148    ASSERT_TRUE(v.VerifyAllGoals(
  2149        [&signature, &root, &path, &language](
  2150            Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2151          if (inspection.label == "Signature") signature = s == "Signature";
  2152          if (inspection.label == "Root") root = s == "Root";
  2153          if (inspection.label == "Path") path = s == "Path";
  2154          if (inspection.label == "Language") language = s == "Language";
  2155          return true;
  2156        }));
  2157    EXPECT_TRUE(signature);
  2158    EXPECT_TRUE(root);
  2159    EXPECT_TRUE(path);
  2160    EXPECT_TRUE(language);
  2161  }
  2162  
  2163  TEST_P(VerifierTest, EvarsAndIdentifiersCanHaveTheSameTextAndAreNotRebound) {
  2164    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2165  #- vname(Signature?, "Signature", Signature?, Path?, Language?) defines SomeNode
  2166  source {
  2167    signature:"Signature"
  2168    corpus:"Signature"
  2169    root:"Signature"
  2170    path:"Path"
  2171    language:"Language"
  2172  }
  2173  edge_kind: "/kythe/edge/defines"
  2174  target { root:"2" }
  2175  fact_name: "/"
  2176  fact_value: ""
  2177  })"));
  2178    ASSERT_TRUE(v.PrepareDatabase());
  2179    bool signature = false;
  2180    bool path = false;
  2181    bool language = false;
  2182    ASSERT_TRUE(v.VerifyAllGoals(
  2183        [&signature, &path, &language](
  2184            Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2185          if (s == inspection.label) {
  2186            if (inspection.label == "Signature") signature = true;
  2187            if (inspection.label == "Path") path = true;
  2188            if (inspection.label == "Language") language = true;
  2189          } else {
  2190            return false;
  2191          }
  2192          return true;
  2193        }));
  2194    EXPECT_TRUE(signature);
  2195    EXPECT_TRUE(path);
  2196    EXPECT_TRUE(language);
  2197  }
  2198  
  2199  TEST_P(VerifierTest, EqualityConstraintWorks) {
  2200    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2201  #- One is vname(_,_,Two? = "2",_,_)
  2202  source { root:"1" }
  2203  fact_name: "/"
  2204  fact_value: ""
  2205  edge_kind: "/kythe/edge/is"
  2206  target { root:"2" }
  2207  } entries {
  2208  source { root:"1" }
  2209  fact_name: "/"
  2210  fact_value: ""
  2211  edge_kind: "/kythe/edge/is"
  2212  target { root:"3" }
  2213  })"));
  2214    ASSERT_TRUE(v.PrepareDatabase());
  2215    ASSERT_TRUE(v.VerifyAllGoals(
  2216        [](Verifier* cxt, const Inspection& inspection, absl::string_view s) {
  2217          return (inspection.label == "Two" && s == "\"2\"");
  2218        }));
  2219  }
  2220  
  2221  TEST_P(VerifierTest, EqualityConstraintWorksOnAnchors) {
  2222    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2223  #- Tx?=@text defines SomeNode
  2224  ##text (line 3 column 2 offset 42-46)
  2225  source { root:"1" }
  2226  fact_name: "/kythe/node/kind"
  2227  fact_value: "anchor"
  2228  }
  2229  entries {
  2230  source { root:"1" }
  2231  fact_name: "/kythe/loc/start"
  2232  fact_value: "42"
  2233  }
  2234  entries {
  2235  source { root:"1" }
  2236  fact_name: "/kythe/loc/end"
  2237  fact_value: "46"
  2238  }
  2239  entries {
  2240  source { root:"1" }
  2241  edge_kind: "/kythe/edge/defines"
  2242  target { root:"2" }
  2243  fact_name: "/"
  2244  fact_value: ""
  2245  })",
  2246                                      "", "1"));
  2247    ASSERT_TRUE(v.PrepareDatabase());
  2248    ASSERT_TRUE(v.VerifyAllGoals(
  2249        [](Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2250          return (inspection.label == "Tx" && !s.empty());
  2251        }));
  2252  }
  2253  
  2254  TEST_P(VerifierTest, EqualityConstraintWorksOnAnchorsRev) {
  2255    if (GetParam() == Solver::New) {
  2256      // TODO: Turns out that we do need to propagate (type) equality constraints.
  2257      GTEST_SKIP();
  2258    }
  2259    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2260  #- @text=Tx? defines SomeNode
  2261  ##text (line 3 column 2 offset 42-46)
  2262  source { root:"1" }
  2263  fact_name: "/kythe/node/kind"
  2264  fact_value: "anchor"
  2265  }
  2266  entries {
  2267  source { root:"1" }
  2268  fact_name: "/kythe/loc/start"
  2269  fact_value: "42"
  2270  }
  2271  entries {
  2272  source { root:"1" }
  2273  fact_name: "/kythe/loc/end"
  2274  fact_value: "46"
  2275  }
  2276  entries {
  2277  source { root:"1" }
  2278  edge_kind: "/kythe/edge/defines"
  2279  target { root:"2" }
  2280  fact_name: "/"
  2281  fact_value: ""
  2282  })",
  2283                                      "", "1"));
  2284    ASSERT_TRUE(v.PrepareDatabase());
  2285    ASSERT_TRUE(v.VerifyAllGoals(
  2286        [](Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2287          return (inspection.label == "Tx" && !s.empty());
  2288        }));
  2289  }
  2290  
  2291  // It's possible to match Tx against {root:7}:
  2292  TEST_P(VerifierTest, EqualityConstraintWorksOnAnchorsPossibleConstraint) {
  2293    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2294  #- @text defines SomeNode
  2295  ##text (line 3 column 2 offset 38-42)
  2296  #- Tx.node/kind notananchor
  2297  source { root:"1" }
  2298  fact_name: "/kythe/node/kind"
  2299  fact_value: "anchor"
  2300  }
  2301  entries {
  2302  source { root:"7" }
  2303  fact_name: "/kythe/node/kind"
  2304  fact_value: "notananchor"
  2305  }
  2306  entries {
  2307  source { root:"1" }
  2308  fact_name: "/kythe/loc/start"
  2309  fact_value: "38"
  2310  }
  2311  entries {
  2312  source { root:"1" }
  2313  fact_name: "/kythe/loc/end"
  2314  fact_value: "42"
  2315  }
  2316  entries {
  2317  source { root:"1" }
  2318  edge_kind: "/kythe/edge/defines"
  2319  target { root:"2" }
  2320  fact_name: "/"
  2321  fact_value: ""
  2322  })",
  2323                                      "", "1"));
  2324    ASSERT_TRUE(v.PrepareDatabase());
  2325    ASSERT_TRUE(v.VerifyAllGoals());
  2326  }
  2327  
  2328  // It's impossible to match Tx against {root:7} if we constrain Tx to equal
  2329  // an anchor specifier.
  2330  TEST_P(VerifierTest, EqualityConstraintWorksOnAnchorsImpossibleConstraint) {
  2331    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2332  #- Tx?=@text defines SomeNode
  2333  ##text (line 3 column 2 offset 42-46)
  2334  #- Tx.node/kind notananchor
  2335  source { root:"1" }
  2336  fact_name: "/kythe/node/kind"
  2337  fact_value: "anchor"
  2338  }
  2339  entries {
  2340  source { root:"7" }
  2341  fact_name: "/kythe/node/kind"
  2342  fact_value: "notananchor"
  2343  }
  2344  entries {
  2345  source { root:"1" }
  2346  fact_name: "/kythe/loc/start"
  2347  fact_value: "42"
  2348  }
  2349  entries {
  2350  source { root:"1" }
  2351  fact_name: "/kythe/loc/end"
  2352  fact_value: "46"
  2353  }
  2354  entries {
  2355  source { root:"1" }
  2356  edge_kind: "/kythe/edge/defines"
  2357  target { root:"2" }
  2358  fact_name: "/"
  2359  fact_value: ""
  2360  })"));
  2361    ASSERT_TRUE(v.PrepareDatabase());
  2362    ASSERT_FALSE(v.VerifyAllGoals());
  2363  }
  2364  
  2365  TEST_P(VerifierTest, EqualityConstraintWorksWithOtherSortedRules) {
  2366    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2367  #- One is vname(_,_,Three? = "3",_,_)
  2368  source { root:"1" }
  2369  fact_name: "/"
  2370  fact_value: ""
  2371  edge_kind: "/kythe/edge/is"
  2372  target { root:"2" }
  2373  } entries {
  2374  source { root:"1" }
  2375  fact_name: "/"
  2376  fact_value: ""
  2377  edge_kind: "/kythe/edge/is"
  2378  target { root:"3" }
  2379  })"));
  2380    ASSERT_TRUE(v.PrepareDatabase());
  2381    ASSERT_TRUE(
  2382        v.VerifyAllGoals([](Verifier* cxt, const Inspection& inspection,
  2383                            std::string_view s) { return s == "\"3\""; }));
  2384  }
  2385  
  2386  TEST_P(VerifierTest, EqualityConstraintFails) {
  2387    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2388  #- One is vname(_,_,Two = "2",_,_)
  2389  #- One is vname(_,_,Three = "3",_,_)
  2390  #- One is vname(_,_,Two = Three,_,_)
  2391  source { root:"1" }
  2392  fact_name: "/"
  2393  fact_value: ""
  2394  edge_kind: "/kythe/edge/is"
  2395  target { root:"2" }
  2396  } entries {
  2397  source { root:"1" }
  2398  fact_name: "/"
  2399  fact_value: ""
  2400  edge_kind: "/kythe/edge/is"
  2401  target { root:"3" }
  2402  })"));
  2403    ASSERT_TRUE(v.PrepareDatabase());
  2404    ASSERT_FALSE(v.VerifyAllGoals());
  2405  }
  2406  
  2407  TEST_P(VerifierTest, IdentityEqualityConstraintSucceeds) {
  2408    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2409  #- One is vname(_,_,Two = Two,_,_)
  2410  source { root:"1" }
  2411  fact_name: "/"
  2412  fact_value: ""
  2413  edge_kind: "/kythe/edge/is"
  2414  target { root:"2" }
  2415  } entries {
  2416  source { root:"1" }
  2417  fact_name: "/"
  2418  fact_value: ""
  2419  edge_kind: "/kythe/edge/is"
  2420  target { root:"3" }
  2421  })"));
  2422    ASSERT_TRUE(v.PrepareDatabase());
  2423    ASSERT_TRUE(v.VerifyAllGoals());
  2424  }
  2425  
  2426  TEST_P(VerifierTest, TransitiveIdentityEqualityConstraintFails) {
  2427    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2428  #- One is vname(_,_,Two = Dos = Two,_,_)
  2429  source { root:"1" }
  2430  fact_name: "/"
  2431  fact_value: ""
  2432  edge_kind: "/kythe/edge/is"
  2433  target { root:"2" }
  2434  } entries {
  2435  source { root:"1" }
  2436  fact_name: "/"
  2437  fact_value: ""
  2438  edge_kind: "/kythe/edge/is"
  2439  target { root:"3" }
  2440  })"));
  2441    ASSERT_TRUE(v.PrepareDatabase());
  2442    if (GetParam() == Solver::New) {
  2443      // The new solver can handle cycles in equality constraints.
  2444      ASSERT_TRUE(v.VerifyAllGoals());
  2445    } else {
  2446      ASSERT_FALSE(v.VerifyAllGoals());
  2447    }
  2448  }
  2449  
  2450  TEST_P(VerifierTest, GraphEqualityConstraintFails) {
  2451    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2452  #- One is Two = vname(_,_,Two,_,_)
  2453  source { root:"1" }
  2454  fact_name: "/"
  2455  fact_value: ""
  2456  edge_kind: "/kythe/edge/is"
  2457  target { root:"2" }
  2458  } entries {
  2459  source { root:"1" }
  2460  fact_name: "/"
  2461  fact_value: ""
  2462  edge_kind: "/kythe/edge/is"
  2463  target { root:"3" }
  2464  })"));
  2465    ASSERT_TRUE(v.PrepareDatabase());
  2466    ASSERT_FALSE(v.VerifyAllGoals());
  2467  }
  2468  
  2469  TEST_P(VerifierTest, UnifyVersusVname) {
  2470    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2471  #- vname(Signature?, Corpus?, Root?, Path?, Language?) defines SomeNode
  2472  source {
  2473    signature:"Signature"
  2474    corpus:"Corpus"
  2475    root:"Root"
  2476    path:"Path"
  2477    language:"Language"
  2478  }
  2479  edge_kind: "/kythe/edge/defines"
  2480  target { root:"2" }
  2481  fact_name: "/"
  2482  fact_value: ""
  2483  })"));
  2484    ASSERT_TRUE(v.PrepareDatabase());
  2485    bool signature = false;
  2486    bool corpus = false;
  2487    bool root = false;
  2488    bool path = false;
  2489    bool language = false;
  2490    ASSERT_TRUE(v.VerifyAllGoals(
  2491        [&signature, &corpus, &root, &path, &language](
  2492            Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2493          if (inspection.label == "Signature") signature = true;
  2494          if (inspection.label == "Corpus") corpus = true;
  2495          if (inspection.label == "Root") root = true;
  2496          if (inspection.label == "Path") path = true;
  2497          if (inspection.label == "Language") language = true;
  2498          return (s == inspection.label);
  2499        }));
  2500    EXPECT_TRUE(signature);
  2501    EXPECT_TRUE(corpus);
  2502    EXPECT_TRUE(root);
  2503    EXPECT_TRUE(path);
  2504    EXPECT_TRUE(language);
  2505  }
  2506  
  2507  TEST_P(VerifierTest, UnifyVersusVnameWithDontCare) {
  2508    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2509  #- vname(Signature?, Corpus?, Root?, _?, Language?) defines SomeNode
  2510  source {
  2511    signature:"Signature"
  2512    corpus:"Corpus"
  2513    root:"Root"
  2514    path:"Path"
  2515    language:"Language"
  2516  }
  2517  edge_kind: "/kythe/edge/defines"
  2518  target { root:"2" }
  2519  fact_name: "/"
  2520  fact_value: ""
  2521  })"));
  2522    ASSERT_TRUE(v.PrepareDatabase());
  2523    bool signature = false;
  2524    bool corpus = false;
  2525    bool root = false;
  2526    bool path = false;
  2527    bool language = false;
  2528    ASSERT_TRUE(v.VerifyAllGoals(
  2529        [&signature, &corpus, &root, &path, &language](
  2530            Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2531          if ((inspection.label != "Path" && s == inspection.label) ||
  2532              (inspection.label == "_" && s == "Path")) {
  2533            if (inspection.label == "Signature") signature = true;
  2534            if (inspection.label == "Corpus") corpus = true;
  2535            if (inspection.label == "Root") root = true;
  2536            if (inspection.label == "_") path = true;
  2537            if (inspection.label == "Language") language = true;
  2538            return true;
  2539          }
  2540          return false;
  2541        }));
  2542    EXPECT_TRUE(signature);
  2543    EXPECT_TRUE(corpus);
  2544    EXPECT_TRUE(root);
  2545    EXPECT_TRUE(path);
  2546    EXPECT_TRUE(language);
  2547  }
  2548  
  2549  TEST_P(VerifierTest, UnifyVersusVnameWithEmptyStringSpelledOut) {
  2550    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2551  #- vname(Signature?, Corpus?, Root?, "", Language?) defines SomeNode
  2552  source {
  2553    signature:"Signature"
  2554    corpus:"Corpus"
  2555    root:"Root"
  2556    language:"Language"
  2557  }
  2558  edge_kind: "/kythe/edge/defines"
  2559  target { root:"2" }
  2560  fact_name: "/"
  2561  fact_value: ""
  2562  })"));
  2563    ASSERT_TRUE(v.PrepareDatabase());
  2564    bool signature = false;
  2565    bool corpus = false;
  2566    bool root = false;
  2567    bool path = false;
  2568    bool language = false;
  2569    ASSERT_TRUE(v.VerifyAllGoals(
  2570        [&signature, &corpus, &root, &language](
  2571            Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2572          if (inspection.label == "Signature") signature = true;
  2573          if (inspection.label == "Corpus") corpus = true;
  2574          if (inspection.label == "Root") root = true;
  2575          if (inspection.label == "Language") language = true;
  2576          return (s == inspection.label);
  2577        }));
  2578    EXPECT_TRUE(signature);
  2579    EXPECT_TRUE(corpus);
  2580    EXPECT_TRUE(root);
  2581    EXPECT_TRUE(language);
  2582  }
  2583  
  2584  TEST_P(VerifierTest, UnifyVersusVnameWithEmptyStringBound) {
  2585    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2586  #- vname(Signature?, Corpus?, Root?, Path?, Language?) defines SomeNode
  2587  source {
  2588    signature:"Signature"
  2589    corpus:"Corpus"
  2590    root:"Root"
  2591    language:"Language"
  2592  }
  2593  edge_kind: "/kythe/edge/defines"
  2594  target { root:"2" }
  2595  fact_name: "/"
  2596  fact_value: ""
  2597  })"));
  2598    ASSERT_TRUE(v.PrepareDatabase());
  2599    bool signature = false;
  2600    bool corpus = false;
  2601    bool root = false;
  2602    bool path = false;
  2603    bool language = false;
  2604    ASSERT_TRUE(v.VerifyAllGoals(
  2605        [&signature, &corpus, &root, &path, &language](
  2606            Verifier* cxt, const Inspection& inspection, std::string_view s) {
  2607          if ((inspection.label != "Path" && s == inspection.label) ||
  2608              (inspection.label == "Path" && s == "\"\"")) {
  2609            if (inspection.label == "Signature") signature = true;
  2610            if (inspection.label == "Corpus") corpus = true;
  2611            if (inspection.label == "Root") root = true;
  2612            if (inspection.label == "Path") path = true;
  2613            if (inspection.label == "Language") language = true;
  2614            return true;
  2615          }
  2616  
  2617          return false;
  2618        }));
  2619    EXPECT_TRUE(signature);
  2620    EXPECT_TRUE(corpus);
  2621    EXPECT_TRUE(root);
  2622    EXPECT_TRUE(path);
  2623    EXPECT_TRUE(language);
  2624  }
  2625  
  2626  TEST_P(VerifierTest, LastGoalToFailIsSelected) {
  2627    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2628  #- SomeNode.content 43
  2629  #- SomeNode.content 43
  2630  #- SomeNode.content 42
  2631  #- SomeNode.content 46
  2632  source { root:"1" }
  2633  fact_name: "/kythe/content"
  2634  fact_value: "43"
  2635  })"));
  2636    ASSERT_TRUE(v.PrepareDatabase());
  2637    ASSERT_FALSE(v.VerifyAllGoals());
  2638    ASSERT_EQ(2, v.highest_goal_reached());
  2639  }
  2640  
  2641  TEST_P(VerifierTest, ReadGoalsFromFileNodeFailure) {
  2642    v.UseFileNodes();
  2643    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2644  source { path:"test" }
  2645  fact_name: "/kythe/node/kind"
  2646  fact_value: "file"
  2647  }
  2648  entries {
  2649  source { path:"test" }
  2650  fact_name: "/kythe/text"
  2651  fact_value: "//- A.node/kind file\n//- A.notafact yes\n"
  2652  })"));
  2653    ASSERT_TRUE(v.PrepareDatabase());
  2654    ASSERT_FALSE(v.VerifyAllGoals());
  2655    ASSERT_EQ(1, v.highest_goal_reached());
  2656  }
  2657  
  2658  TEST_P(VerifierTest, ReadGoalsFromFileNodeSuccess) {
  2659    v.UseFileNodes();
  2660    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2661  source { path:"test" }
  2662  fact_name: "/kythe/node/kind"
  2663  fact_value: "file"
  2664  }
  2665  entries {
  2666  source { path:"test" }
  2667  fact_name: "/kythe/text"
  2668  fact_value: "//- A.node/kind file\n"
  2669  })"));
  2670    ASSERT_TRUE(v.PrepareDatabase());
  2671    ASSERT_TRUE(v.VerifyAllGoals());
  2672  }
  2673  
  2674  TEST_P(VerifierTest, ReadGoalsFromFileNodeEmptyCorpusSuccess) {
  2675    v.UseFileNodes();
  2676    v.UseDefaultFileCorpus("testcorpus");
  2677    ASSERT_TRUE(v.LoadInlineProtoFile(R"(entries {
  2678  source { path:"test" }
  2679  fact_name: "/kythe/node/kind"
  2680  fact_value: "file"
  2681  }
  2682  entries {
  2683  source { path:"test" }
  2684  fact_name: "/kythe/text"
  2685  fact_value: "//- @a.node/kind anchor\na"
  2686  }
  2687  entries {
  2688  source { signature: "a" corpus:"testcorpus" path:"test" }
  2689  fact_name: "/kythe/node/kind"
  2690  fact_value: "anchor"
  2691  }
  2692  entries {
  2693  source { signature: "a" corpus:"testcorpus" path:"test" }
  2694  fact_name: "/kythe/loc/start"
  2695  fact_value: "24"
  2696  }
  2697  entries {
  2698  source { signature: "a" corpus:"testcorpus" path:"test" }
  2699  fact_name: "/kythe/loc/end"
  2700  fact_value: "25"
  2701  }
  2702  )"));
  2703    ASSERT_TRUE(v.PrepareDatabase());
  2704    ASSERT_TRUE(v.VerifyAllGoals());
  2705  }
  2706  
  2707  TEST_P(VerifierTest, ReadGoalsFromFileNodeFailParse) {
  2708    v.UseFileNodes();
  2709    bool parsed = v.LoadInlineProtoFile(R"(entries {
  2710  source { path:"test" }
  2711  fact_name: "/kythe/node/kind"
  2712  fact_value: "file"
  2713  }
  2714  entries {
  2715  source { path:"test" }
  2716  fact_name: "/kythe/text"
  2717  fact_value: "//- A->node/kind file\n"
  2718  })");
  2719    if (GetParam() == Solver::Old) {
  2720      ASSERT_TRUE(parsed);
  2721      ASSERT_FALSE(v.PrepareDatabase());
  2722    } else {
  2723      ASSERT_FALSE(parsed);
  2724    }
  2725  }
  2726  
  2727  TEST_P(VerifierTest, DontConvertMarkedSource) {
  2728    MarkedSource source;
  2729    std::string source_string;
  2730    ASSERT_TRUE(source.SerializeToString(&source_string));
  2731    google::protobuf::TextFormat::FieldValuePrinter printer;
  2732    std::string enc_source = printer.PrintBytes(source_string);
  2733    ASSERT_TRUE(v.LoadInlineProtoFile(R"(
  2734    entries {
  2735      source { signature:"test" }
  2736      fact_name: "/kythe/code"
  2737      fact_value: )" + enc_source + R"(
  2738    }
  2739    #- vname("test","","","","").code _
  2740    #- !{vname("test","","","","") code _}
  2741    )"));
  2742    ASSERT_TRUE(v.PrepareDatabase());
  2743    ASSERT_TRUE(v.VerifyAllGoals());
  2744  }
  2745  
  2746  enum class MsFormat { kTextProto, kJson };
  2747  
  2748  class VerifierMarkedSourceUnitTest
  2749      : public ::testing::TestWithParam<std::tuple<MsFormat, Solver>> {
  2750   protected:
  2751    std::string Entries(const MarkedSource& source) const {
  2752      kythe::proto::Entries entries;
  2753      auto entry = entries.add_entries();
  2754      entry->mutable_source()->set_signature("test");
  2755      entry->set_fact_name(FactName());
  2756      entry->set_fact_value(Encode(source));
  2757      std::string result;
  2758      GTEST_CHECK_(google::protobuf::TextFormat::PrintToString(entries, &result));
  2759      return result;
  2760    }
  2761  
  2762    void ConfigureVerifier(Verifier& v) {
  2763      v.UseFastSolver(std::get<1>(GetParam()) == Solver::Old ? false : true);
  2764    }
  2765  
  2766   private:
  2767    std::string FactName() const {
  2768      return std::get<0>(GetParam()) == MsFormat::kTextProto ? "/kythe/code"
  2769                                                             : "/kythe/code/json";
  2770    }
  2771  
  2772    std::string Encode(const MarkedSource& source) const {
  2773      if (std::get<0>(GetParam()) == MsFormat::kTextProto) {
  2774        std::string source_string;
  2775        GTEST_CHECK_(source.SerializeToString(&source_string))
  2776            << "Failure serializing MarkedSource";
  2777        return source_string;
  2778      } else {
  2779        std::string source_string;
  2780        GTEST_CHECK_(
  2781            google::protobuf::util::MessageToJsonString(source, &source_string)
  2782                .ok())
  2783            << "Failure serializing MarkedSource to JSON";
  2784        return source_string;
  2785      }
  2786    }
  2787  };
  2788  
  2789  TEST_P(VerifierMarkedSourceUnitTest, ConvertMarkedSource) {
  2790    Verifier v;
  2791    ConfigureVerifier(v);
  2792    v.ConvertMarkedSource();
  2793    MarkedSource source;
  2794    ASSERT_TRUE(v.LoadInlineProtoFile(Entries(source) + R"(
  2795    #- !{vname("test","","","","").code _}
  2796    #- vname("test","","","","") code Tree
  2797    #- Tree.kind "BOX"
  2798    #- Tree.pre_text ""
  2799    #- Tree.post_child_text ""
  2800    #- Tree.post_text ""
  2801    #- Tree.lookup_index 0
  2802    #- Tree.default_children_count 0
  2803    #- Tree.add_final_list_token false
  2804    )"));
  2805    ASSERT_TRUE(v.PrepareDatabase());
  2806    ASSERT_TRUE(v.VerifyAllGoals());
  2807  }
  2808  
  2809  TEST_P(VerifierMarkedSourceUnitTest, ConvertMarkedSourceKindEnums) {
  2810    for (int kind = MarkedSource::Kind_MIN; kind <= MarkedSource::Kind_MAX;
  2811         ++kind) {
  2812      if (!MarkedSource::Kind_IsValid(kind)) {
  2813        continue;
  2814      }
  2815      auto kind_enum = static_cast<MarkedSource::Kind>(kind);
  2816      Verifier v;
  2817      ConfigureVerifier(v);
  2818      v.ConvertMarkedSource();
  2819      MarkedSource source;
  2820      source.set_kind(kind_enum);
  2821      ASSERT_TRUE(v.LoadInlineProtoFile(Entries(source) + R"(
  2822      #- vname("test","","","","") code Tree
  2823      #- Tree.kind ")" + MarkedSource::Kind_Name(kind_enum) +
  2824                                        R"("
  2825      )"));
  2826      ASSERT_TRUE(v.PrepareDatabase());
  2827      ASSERT_TRUE(v.VerifyAllGoals());
  2828    }
  2829  }
  2830  
  2831  TEST_P(VerifierMarkedSourceUnitTest, ConvertMarkedSourceLinks) {
  2832    Verifier v;
  2833    ConfigureVerifier(v);
  2834    v.ConvertMarkedSource();
  2835    MarkedSource source;
  2836    source.add_link()->add_definition("kythe://corpus#sig");
  2837    ASSERT_TRUE(v.LoadInlineProtoFile(Entries(source) + R"(
  2838    #- vname("test","","","","") code Tree
  2839    #- Tree link vname("sig", "corpus", "", "", "")
  2840    )"));
  2841    ASSERT_TRUE(v.PrepareDatabase());
  2842    ASSERT_TRUE(v.VerifyAllGoals());
  2843  }
  2844  
  2845  TEST_P(VerifierMarkedSourceUnitTest, ConvertMarkedSourceLinksBadUri) {
  2846    Verifier v;
  2847    ConfigureVerifier(v);
  2848    v.ConvertMarkedSource();
  2849    MarkedSource source;
  2850    source.add_link()->add_definition("kythe:/&bad");
  2851    ASSERT_FALSE(v.LoadInlineProtoFile(Entries(source)));
  2852  }
  2853  
  2854  TEST_P(VerifierMarkedSourceUnitTest, ConvertMarkedSourceLinksMissingUri) {
  2855    Verifier v;
  2856    ConfigureVerifier(v);
  2857    v.ConvertMarkedSource();
  2858    MarkedSource source;
  2859    source.add_link();
  2860    ASSERT_FALSE(v.LoadInlineProtoFile(Entries(source)));
  2861  }
  2862  
  2863  TEST_P(VerifierMarkedSourceUnitTest, ConvertMarkedSourceLinksMultipleUri) {
  2864    Verifier v;
  2865    ConfigureVerifier(v);
  2866    v.ConvertMarkedSource();
  2867    MarkedSource source;
  2868    auto* link = source.add_link();
  2869    link->add_definition("kythe://corpus#sig");
  2870    link->add_definition("kythe://corpus#sig2");
  2871    ASSERT_FALSE(v.LoadInlineProtoFile(Entries(source)));
  2872  }
  2873  
  2874  TEST_P(VerifierMarkedSourceUnitTest, ConvertMarkedSourceChildren) {
  2875    Verifier v;
  2876    ConfigureVerifier(v);
  2877    v.ConvertMarkedSource();
  2878    MarkedSource source;
  2879    auto* child = source.add_child();
  2880    child->set_kind(MarkedSource::IDENTIFIER);
  2881    child = source.add_child();
  2882    child->set_kind(MarkedSource::CONTEXT);
  2883    ASSERT_TRUE(v.LoadInlineProtoFile(Entries(source) + R"(
  2884    #- vname("test","","","","") code Tree
  2885    #- Tree child.0 IdChild
  2886    #- IdChild.kind "IDENTIFIER"
  2887    #- Tree child.1 ContextChild
  2888    #- ContextChild.kind "CONTEXT"
  2889    )"));
  2890    ASSERT_TRUE(v.PrepareDatabase());
  2891    ASSERT_TRUE(v.VerifyAllGoals());
  2892  }
  2893  
  2894  TEST_P(VerifierMarkedSourceUnitTest, ConvertMarkedSourceBadChildren) {
  2895    Verifier v;
  2896    ConfigureVerifier(v);
  2897    v.ConvertMarkedSource();
  2898    MarkedSource parent;
  2899    MarkedSource* child = parent.add_child();
  2900    auto* link = child->add_link();
  2901    link->add_definition("kythe://corpus#sig");
  2902    link->add_definition("kythe://corpus#sig2");
  2903    ASSERT_FALSE(v.LoadInlineProtoFile(Entries(parent)));
  2904  }
  2905  
  2906  TEST_P(VerifierMarkedSourceUnitTest, ConvertMarkedSourceFields) {
  2907    Verifier v;
  2908    ConfigureVerifier(v);
  2909    v.ConvertMarkedSource();
  2910    MarkedSource source;
  2911    source.set_pre_text("pre_text");
  2912    source.set_post_child_text("post_child_text");
  2913    source.set_post_text("post_text");
  2914    source.set_lookup_index(42);
  2915    source.set_default_children_count(43);
  2916    source.set_add_final_list_token(true);
  2917    ASSERT_TRUE(v.LoadInlineProtoFile(Entries(source) + R"(
  2918    #- vname("test","","","","") code Tree
  2919    #- Tree.pre_text "pre_text"
  2920    #- Tree.post_child_text "post_child_text"
  2921    #- Tree.post_text "post_text"
  2922    #- Tree.lookup_index 42
  2923    #- Tree.default_children_count 43
  2924    #- Tree.add_final_list_token true
  2925    )"));
  2926    ASSERT_TRUE(v.PrepareDatabase());
  2927    ASSERT_TRUE(v.VerifyAllGoals());
  2928  }
  2929  
  2930  TEST_P(VerifierMarkedSourceUnitTest,
  2931         DontConvertMarkedSourceDuplicateFactsWellFormed) {
  2932    Verifier v;
  2933    ConfigureVerifier(v);
  2934    MarkedSource source;
  2935    v.IgnoreDuplicateFacts();
  2936    ASSERT_TRUE(v.LoadInlineProtoFile(Entries(source) + "\n" + Entries(source)));
  2937    ASSERT_TRUE(v.PrepareDatabase());
  2938    ASSERT_TRUE(v.VerifyAllGoals());
  2939  }
  2940  
  2941  TEST_P(VerifierMarkedSourceUnitTest,
  2942         ConvertMarkedSourceDuplicateFactsWellFormed) {
  2943    Verifier v;
  2944    ConfigureVerifier(v);
  2945    v.ConvertMarkedSource();
  2946    MarkedSource source;
  2947    ASSERT_TRUE(v.LoadInlineProtoFile(Entries(source) + "\n" + Entries(source)));
  2948    ASSERT_TRUE(v.PrepareDatabase());
  2949    ASSERT_TRUE(v.VerifyAllGoals());
  2950  }
  2951  
  2952  TEST_P(VerifierMarkedSourceUnitTest, ConflictingCodeFactsNotWellFormed) {
  2953    if (std::get<1>(GetParam()) == Solver::New) {
  2954      // The new solver doesn't currently perform conflict checks.
  2955      GTEST_SKIP();
  2956    }
  2957    Verifier v;
  2958    ConfigureVerifier(v);
  2959    MarkedSource source;
  2960  
  2961    MarkedSource source_conflict;
  2962    source_conflict.set_pre_text("pre_text");
  2963    ASSERT_TRUE(
  2964        v.LoadInlineProtoFile(Entries(source) + "\n" + Entries(source_conflict)));
  2965    ASSERT_FALSE(v.PrepareDatabase());
  2966    ASSERT_FALSE(v.VerifyAllGoals());
  2967  }
  2968  
  2969  TEST_P(VerifierMarkedSourceUnitTest, ConflictingCodeFactsIgnoreWellFormed) {
  2970    Verifier v;
  2971    ConfigureVerifier(v);
  2972    v.IgnoreCodeConflicts();
  2973    MarkedSource source;
  2974    MarkedSource source_conflict;
  2975    source_conflict.set_pre_text("pre_text");
  2976    ASSERT_TRUE(
  2977        v.LoadInlineProtoFile(Entries(source) + "\n" + Entries(source_conflict)));
  2978    ASSERT_TRUE(v.PrepareDatabase());
  2979    ASSERT_TRUE(v.VerifyAllGoals());
  2980  }
  2981  
  2982  INSTANTIATE_TEST_SUITE_P(
  2983      JsonAndProto, VerifierMarkedSourceUnitTest,
  2984      ::testing::Combine(::testing::Values(MsFormat::kTextProto, MsFormat::kJson),
  2985                         ::testing::Values(Solver::Old, Solver::New)),
  2986      [](const auto& p) {
  2987        if (std::get<0>(p.param) == MsFormat::kTextProto)
  2988          return std::get<1>(p.param) == Solver::Old ? "textold" : "textnew";
  2989        else
  2990          return std::get<1>(p.param) == Solver::Old ? "jsonold" : "jsonnew";
  2991      });
  2992  
  2993  }  // anonymous namespace
  2994  }  // namespace verifier
  2995  }  // namespace kythe
  2996  
  2997  int main(int argc, char** argv) {
  2998    GOOGLE_PROTOBUF_VERIFY_VERSION;
  2999    ::absl::InitializeLog();
  3000    ::testing::InitGoogleTest(&argc, argv);
  3001    return RUN_ALL_TESTS();
  3002  }