@@ -39,6 +39,61 @@ class CommandLineTest : public ::testing::Test {
3939  }
4040};
4141
42+ template  <typename  M>
43+ std::string describeContainsN (M InnerMatcher, unsigned  N, bool  Negation) {
44+   StringRef Contains = Negation ? " doesn't contain"   : " contains"  ;
45+   StringRef Instance = N == 1  ? "  instance "   : "  instances "  ;
46+   StringRef Element = " of element that "  ;
47+ 
48+   std::ostringstream Inner;
49+   InnerMatcher.impl ().DescribeTo (&Inner);
50+ 
51+   return  (Contains + "  exactly "   + Twine (N) + Instance + Element + Inner.str ())
52+       .str ();
53+ }
54+ 
55+ MATCHER_P2 (ContainsN, InnerMatcher, N,
56+            describeContainsN (InnerMatcher, N, negation)) {
57+   auto  InnerMatches = [this ](const  auto  &Element) {
58+     ::testing::internal::DummyMatchResultListener InnerListener;
59+     return  InnerMatcher.impl ().MatchAndExplain (Element, &InnerListener);
60+   };
61+ 
62+   return  count_if (arg, InnerMatches) == N;
63+ }
64+ 
65+ TEST (ContainsN, Empty) {
66+   const  char  *Array[] = {" "  };
67+ 
68+   ASSERT_THAT (Array, ContainsN (StrEq (" x"  ), 0 ));
69+   ASSERT_THAT (Array, Not (ContainsN (StrEq (" x"  ), 1 )));
70+   ASSERT_THAT (Array, Not (ContainsN (StrEq (" x"  ), 2 )));
71+ }
72+ 
73+ TEST (ContainsN, Zero) {
74+   const  char  *Array[] = {" y"  };
75+ 
76+   ASSERT_THAT (Array, ContainsN (StrEq (" x"  ), 0 ));
77+   ASSERT_THAT (Array, Not (ContainsN (StrEq (" x"  ), 1 )));
78+   ASSERT_THAT (Array, Not (ContainsN (StrEq (" x"  ), 2 )));
79+ }
80+ 
81+ TEST (ContainsN, One) {
82+   const  char  *Array[] = {" a"  , " b"  , " x"  , " z"  };
83+ 
84+   ASSERT_THAT (Array, Not (ContainsN (StrEq (" x"  ), 0 )));
85+   ASSERT_THAT (Array, ContainsN (StrEq (" x"  ), 1 ));
86+   ASSERT_THAT (Array, Not (ContainsN (StrEq (" x"  ), 2 )));
87+ }
88+ 
89+ TEST (ContainsN, Two) {
90+   const  char  *Array[] = {" x"  , " a"  , " b"  , " x"  };
91+ 
92+   ASSERT_THAT (Array, Not (ContainsN (StrEq (" x"  ), 0 )));
93+   ASSERT_THAT (Array, Not (ContainsN (StrEq (" x"  ), 1 )));
94+   ASSERT_THAT (Array, ContainsN (StrEq (" x"  ), 2 ));
95+ }
96+ 
4297//  Boolean option with a keypath that defaults to true.
4398//  The only flag with a negative spelling can set the keypath to false.
4499
@@ -270,7 +325,7 @@ TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentPos) {
270325
271326  Invocation.generateCC1CommandLine (GeneratedArgs, *this );
272327
273-   ASSERT_EQ ( count ( GeneratedArgs, StringRef ( " -fdebug-pass-manager"  )) , 1 );
328+   ASSERT_THAT ( GeneratedArgs, ContainsN ( StrEq ( " -fdebug-pass-manager"  ), 1 ) );
274329  ASSERT_THAT (GeneratedArgs, Not (Contains (StrEq (" -fno-debug-pass-manager"  ))));
275330}
276331
@@ -418,7 +473,8 @@ TEST_F(CommandLineTest, StringVectorEmpty) {
418473  ASSERT_TRUE (Invocation.getFrontendOpts ().ModuleMapFiles .empty ());
419474
420475  Invocation.generateCC1CommandLine (GeneratedArgs, *this );
421-   ASSERT_THAT (GeneratedArgs, Not (Contains (HasSubstr (" -fmodule-map-file="  ))));
476+ 
477+   ASSERT_THAT (GeneratedArgs, Not (Contains (HasSubstr (" -fmodule-map-file"  ))));
422478}
423479
424480TEST_F (CommandLineTest, StringVectorSingle) {
@@ -431,7 +487,9 @@ TEST_F(CommandLineTest, StringVectorSingle) {
431487            std::vector<std::string>({" a"  }));
432488
433489  Invocation.generateCC1CommandLine (GeneratedArgs, *this );
434-   ASSERT_EQ (count (GeneratedArgs, StringRef (" -fmodule-map-file=a"  )), 1 );
490+ 
491+   ASSERT_THAT (GeneratedArgs, ContainsN (StrEq (" -fmodule-map-file=a"  ), 1 ));
492+   ASSERT_THAT (GeneratedArgs, ContainsN (HasSubstr (" -fmodule-map-file"  ), 1 ));
435493}
436494
437495TEST_F (CommandLineTest, StringVectorMultiple) {
@@ -443,71 +501,11 @@ TEST_F(CommandLineTest, StringVectorMultiple) {
443501  ASSERT_TRUE (Invocation.getFrontendOpts ().ModuleMapFiles  ==
444502              std::vector<std::string>({" a"  , " b"  }));
445503
446-   Invocation.generateCC1CommandLine (GeneratedArgs, *this );
447-   ASSERT_EQ (count (GeneratedArgs, StringRef (" -fmodule-map-file=a"  )), 1 );
448-   ASSERT_EQ (count (GeneratedArgs, StringRef (" -fmodule-map-file=b"  )), 1 );
449- }
450- 
451- //  A flag that should be parsed only if a condition is met.
452- 
453- TEST_F (CommandLineTest, ConditionalParsingIfFalseFlagNotPresent) {
454-   const  char  *Args[] = {" "  };
455- 
456-   CompilerInvocation::CreateFromArgs (Invocation, Args, *Diags);
457- 
458-   ASSERT_FALSE (Diags->hasErrorOccurred ());
459-   ASSERT_FALSE (Invocation.getLangOpts ()->SYCL );
460-   ASSERT_EQ (Invocation.getLangOpts ()->getSYCLVersion (), LangOptions::SYCL_None);
461- 
462-   Invocation.generateCC1CommandLine (GeneratedArgs, *this );
463- 
464-   ASSERT_THAT (GeneratedArgs, Not (Contains (StrEq (" -fsycl"  ))));
465-   ASSERT_THAT (GeneratedArgs, Not (Contains (HasSubstr (" -sycl-std="  ))));
466- }
467- 
468- TEST_F (CommandLineTest, ConditionalParsingIfFalseFlagPresent) {
469-   const  char  *Args[] = {" -sycl-std=2017"  };
470- 
471-   CompilerInvocation::CreateFromArgs (Invocation, Args, *Diags);
472- 
473-   ASSERT_FALSE (Diags->hasErrorOccurred ());
474-   ASSERT_FALSE (Invocation.getLangOpts ()->SYCL );
475-   ASSERT_EQ (Invocation.getLangOpts ()->getSYCLVersion (), LangOptions::SYCL_None);
476- 
477-   Invocation.generateCC1CommandLine (GeneratedArgs, *this );
478- 
479-   ASSERT_THAT (GeneratedArgs, Not (Contains (StrEq (" -fsycl"  ))));
480-   ASSERT_THAT (GeneratedArgs, Not (Contains (HasSubstr (" -sycl-std="  ))));
481- }
482- 
483- TEST_F (CommandLineTest, ConditionalParsingIfTrueFlagNotPresent) {
484-   const  char  *Args[] = {" -fsycl"  };
485- 
486-   CompilerInvocation::CreateFromArgs (Invocation, Args, *Diags);
487- 
488-   ASSERT_FALSE (Diags->hasErrorOccurred ());
489-   ASSERT_TRUE (Invocation.getLangOpts ()->SYCL );
490-   ASSERT_EQ (Invocation.getLangOpts ()->getSYCLVersion (), LangOptions::SYCL_None);
491- 
492-   Invocation.generateCC1CommandLine (GeneratedArgs, *this );
493- 
494-   ASSERT_THAT (GeneratedArgs, Contains (StrEq (" -fsycl"  )));
495-   ASSERT_THAT (GeneratedArgs, Not (Contains (HasSubstr (" -sycl-std="  ))));
496- }
497- 
498- TEST_F (CommandLineTest, ConditionalParsingIfTrueFlagPresent) {
499-   const  char  *Args[] = {" -fsycl"  , " -sycl-std=2017"  };
500- 
501-   CompilerInvocation::CreateFromArgs (Invocation, Args, *Diags);
502- 
503-   ASSERT_FALSE (Diags->hasErrorOccurred ());
504-   ASSERT_TRUE (Invocation.getLangOpts ()->SYCL );
505-   ASSERT_EQ (Invocation.getLangOpts ()->getSYCLVersion (), LangOptions::SYCL_2017);
506- 
507504  Invocation.generateCC1CommandLine (GeneratedArgs, *this );
508505
509-   ASSERT_THAT (GeneratedArgs, Contains (StrEq (" -fsycl"  )));
510-   ASSERT_THAT (GeneratedArgs, Contains (StrEq (" -sycl-std=2017"  )));
506+   ASSERT_THAT (GeneratedArgs, ContainsN (StrEq (" -fmodule-map-file=a"  ), 1 ));
507+   ASSERT_THAT (GeneratedArgs, ContainsN (StrEq (" -fmodule-map-file=b"  ), 1 ));
508+   ASSERT_THAT (GeneratedArgs, ContainsN (HasSubstr (" -fmodule-map-file"  ), 2 ));
511509}
512510
513511//  Wide integer option.
0 commit comments