1*48a6aa6cSLei Zhang //===- FormatTest.cpp - TableGen Format Utility Tests ---------------------===// 2*48a6aa6cSLei Zhang // 3*48a6aa6cSLei Zhang // Copyright 2019 The MLIR Authors. 4*48a6aa6cSLei Zhang // 5*48a6aa6cSLei Zhang // Licensed under the Apache License, Version 2.0 (the "License"); 6*48a6aa6cSLei Zhang // you may not use this file except in compliance with the License. 7*48a6aa6cSLei Zhang // You may obtain a copy of the License at 8*48a6aa6cSLei Zhang // 9*48a6aa6cSLei Zhang // http://www.apache.org/licenses/LICENSE-2.0 10*48a6aa6cSLei Zhang // 11*48a6aa6cSLei Zhang // Unless required by applicable law or agreed to in writing, software 12*48a6aa6cSLei Zhang // distributed under the License is distributed on an "AS IS" BASIS, 13*48a6aa6cSLei Zhang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*48a6aa6cSLei Zhang // See the License for the specific language governing permissions and 15*48a6aa6cSLei Zhang // limitations under the License. 16*48a6aa6cSLei Zhang // ============================================================================= 17*48a6aa6cSLei Zhang 18*48a6aa6cSLei Zhang #include "mlir/TableGen/Format.h" 19*48a6aa6cSLei Zhang #include "gmock/gmock.h" 20*48a6aa6cSLei Zhang 21*48a6aa6cSLei Zhang using mlir::tblgen::FmtContext; 22*48a6aa6cSLei Zhang using mlir::tblgen::tgfmt; 23*48a6aa6cSLei Zhang using ::testing::StrEq; 24*48a6aa6cSLei Zhang 25*48a6aa6cSLei Zhang TEST(FormatTest, EmptyFmtStr) { 26*48a6aa6cSLei Zhang FmtContext ctx; 27*48a6aa6cSLei Zhang std::string result = tgfmt("", &ctx); 28*48a6aa6cSLei Zhang EXPECT_TRUE(result.empty()); 29*48a6aa6cSLei Zhang } 30*48a6aa6cSLei Zhang 31*48a6aa6cSLei Zhang // Allow extra unused positional parameters 32*48a6aa6cSLei Zhang TEST(FormatTest, EmptyFmtStrExtraParams) { 33*48a6aa6cSLei Zhang FmtContext ctx; 34*48a6aa6cSLei Zhang std::string result = tgfmt("", &ctx, "a", "b", "c"); 35*48a6aa6cSLei Zhang EXPECT_TRUE(result.empty()); 36*48a6aa6cSLei Zhang } 37*48a6aa6cSLei Zhang 38*48a6aa6cSLei Zhang // Allow unused placeholder substitution in context 39*48a6aa6cSLei Zhang TEST(FormatTest, EmptyFmtStrPopulatedCtx) { 40*48a6aa6cSLei Zhang FmtContext ctx; 41*48a6aa6cSLei Zhang ctx.withBuilder("builder"); 42*48a6aa6cSLei Zhang std::string result = tgfmt("", &ctx); 43*48a6aa6cSLei Zhang EXPECT_TRUE(result.empty()); 44*48a6aa6cSLei Zhang } 45*48a6aa6cSLei Zhang 46*48a6aa6cSLei Zhang TEST(FormatTest, LiteralFmtStr) { 47*48a6aa6cSLei Zhang FmtContext ctx; 48*48a6aa6cSLei Zhang std::string result = tgfmt("void foo {}", &ctx); 49*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("void foo {}")); 50*48a6aa6cSLei Zhang } 51*48a6aa6cSLei Zhang 52*48a6aa6cSLei Zhang // Print single dollar literally 53*48a6aa6cSLei Zhang TEST(FormatTest, AdjacentDollar) { 54*48a6aa6cSLei Zhang FmtContext ctx; 55*48a6aa6cSLei Zhang std::string result = tgfmt("$", &ctx); 56*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("$")); 57*48a6aa6cSLei Zhang } 58*48a6aa6cSLei Zhang 59*48a6aa6cSLei Zhang // Print dangling dollar literally 60*48a6aa6cSLei Zhang TEST(FormatTest, DanglingDollar) { 61*48a6aa6cSLei Zhang FmtContext ctx; 62*48a6aa6cSLei Zhang std::string result = tgfmt("foo bar baz$", &ctx); 63*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("foo bar baz$")); 64*48a6aa6cSLei Zhang } 65*48a6aa6cSLei Zhang 66*48a6aa6cSLei Zhang // Allow escape dollars with '$$' 67*48a6aa6cSLei Zhang TEST(FormatTest, EscapeDollars) { 68*48a6aa6cSLei Zhang FmtContext ctx; 69*48a6aa6cSLei Zhang std::string result = 70*48a6aa6cSLei Zhang tgfmt("$$ $$$$ $$$0 $$$_self", &ctx.withSelf("self"), "-0"); 71*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("$ $$ $-0 $self")); 72*48a6aa6cSLei Zhang } 73*48a6aa6cSLei Zhang 74*48a6aa6cSLei Zhang TEST(FormatTest, PositionalFmtStr) { 75*48a6aa6cSLei Zhang FmtContext ctx; 76*48a6aa6cSLei Zhang std::string b = "b"; 77*48a6aa6cSLei Zhang int c = 42; 78*48a6aa6cSLei Zhang char d = 'd'; 79*48a6aa6cSLei Zhang std::string result = tgfmt("$0 $1 $2 $3", &ctx, "a", b, c + 1, d); 80*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("a b 43 d")); 81*48a6aa6cSLei Zhang } 82*48a6aa6cSLei Zhang 83*48a6aa6cSLei Zhang // Output the placeholder if missing substitution 84*48a6aa6cSLei Zhang TEST(FormatTest, PositionalFmtStrMissingParams) { 85*48a6aa6cSLei Zhang FmtContext ctx; 86*48a6aa6cSLei Zhang std::string result = tgfmt("$0 %1 $2", &ctx); 87*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("$0<no-subst-found> %1 $2<no-subst-found>")); 88*48a6aa6cSLei Zhang } 89*48a6aa6cSLei Zhang 90*48a6aa6cSLei Zhang // Allow flexible reference of positional parameters 91*48a6aa6cSLei Zhang TEST(FormatTest, PositionalFmtStrFlexibleRef) { 92*48a6aa6cSLei Zhang FmtContext ctx; 93*48a6aa6cSLei Zhang std::string result = tgfmt("$2 $0 $2", &ctx, "a", "b", "c"); 94*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("c a c")); 95*48a6aa6cSLei Zhang } 96*48a6aa6cSLei Zhang 97*48a6aa6cSLei Zhang TEST(FormatTest, PositionalFmtStrNoWhitespace) { 98*48a6aa6cSLei Zhang FmtContext ctx; 99*48a6aa6cSLei Zhang std::string result = tgfmt("foo$0bar", &ctx, "-"); 100*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("foo-bar")); 101*48a6aa6cSLei Zhang } 102*48a6aa6cSLei Zhang 103*48a6aa6cSLei Zhang TEST(FormatTest, PlaceHolderFmtStrWithSelf) { 104*48a6aa6cSLei Zhang FmtContext ctx; 105*48a6aa6cSLei Zhang std::string result = tgfmt("$_self", &ctx.withSelf("sss")); 106*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("sss")); 107*48a6aa6cSLei Zhang } 108*48a6aa6cSLei Zhang 109*48a6aa6cSLei Zhang TEST(FormatTest, PlaceHolderFmtStrWithBuilder) { 110*48a6aa6cSLei Zhang FmtContext ctx; 111*48a6aa6cSLei Zhang 112*48a6aa6cSLei Zhang std::string result = tgfmt("$_builder", &ctx.withBuilder("bbb")); 113*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("bbb")); 114*48a6aa6cSLei Zhang } 115*48a6aa6cSLei Zhang 116*48a6aa6cSLei Zhang TEST(FormatTest, PlaceHolderFmtStrWithOp) { 117*48a6aa6cSLei Zhang FmtContext ctx; 118*48a6aa6cSLei Zhang std::string result = tgfmt("$_op", &ctx.withOp("ooo")); 119*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("ooo")); 120*48a6aa6cSLei Zhang } 121*48a6aa6cSLei Zhang 122*48a6aa6cSLei Zhang TEST(FormatTest, PlaceHolderMissingCtx) { 123*48a6aa6cSLei Zhang std::string result = tgfmt("$_op", nullptr); 124*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("$_op<no-subst-found>")); 125*48a6aa6cSLei Zhang } 126*48a6aa6cSLei Zhang 127*48a6aa6cSLei Zhang TEST(FormatTest, PlaceHolderMissingSubst) { 128*48a6aa6cSLei Zhang FmtContext ctx; 129*48a6aa6cSLei Zhang std::string result = tgfmt("$_op", &ctx.withBuilder("builder")); 130*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("$_op<no-subst-found>")); 131*48a6aa6cSLei Zhang } 132*48a6aa6cSLei Zhang 133*48a6aa6cSLei Zhang // Test commonly used delimiters in C++ 134*48a6aa6cSLei Zhang TEST(FormatTest, PlaceHolderFmtStrDelimiter) { 135*48a6aa6cSLei Zhang FmtContext ctx; 136*48a6aa6cSLei Zhang ctx.addSubst("m", ""); 137*48a6aa6cSLei Zhang std::string result = tgfmt("$m{$m($m[$m]$m)$m}$m|", &ctx); 138*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("{([])}|")); 139*48a6aa6cSLei Zhang } 140*48a6aa6cSLei Zhang 141*48a6aa6cSLei Zhang // Test allowed characters in placeholder symbol 142*48a6aa6cSLei Zhang TEST(FormatTest, CustomPlaceHolderFmtStrPlaceHolderChars) { 143*48a6aa6cSLei Zhang FmtContext ctx; 144*48a6aa6cSLei Zhang ctx.addSubst("m", "0 "); 145*48a6aa6cSLei Zhang ctx.addSubst("m1", "1 "); 146*48a6aa6cSLei Zhang ctx.addSubst("m2C", "2 "); 147*48a6aa6cSLei Zhang ctx.addSubst("M_3", "3 "); 148*48a6aa6cSLei Zhang std::string result = tgfmt("$m$m1$m2C$M_3", &ctx); 149*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("0 1 2 3 ")); 150*48a6aa6cSLei Zhang } 151*48a6aa6cSLei Zhang 152*48a6aa6cSLei Zhang TEST(FormatTest, CustomPlaceHolderFmtStrUnregisteredPlaceHolders) { 153*48a6aa6cSLei Zhang FmtContext ctx; 154*48a6aa6cSLei Zhang std::string result = tgfmt("foo($awesome, $param)", &ctx); 155*48a6aa6cSLei Zhang EXPECT_THAT(result, 156*48a6aa6cSLei Zhang StrEq("foo($awesome<no-subst-found>, $param<no-subst-found>)")); 157*48a6aa6cSLei Zhang } 158*48a6aa6cSLei Zhang 159*48a6aa6cSLei Zhang TEST(FormatTest, MixedFmtStr) { 160*48a6aa6cSLei Zhang FmtContext ctx; 161*48a6aa6cSLei Zhang ctx.withBuilder("bbb"); 162*48a6aa6cSLei Zhang 163*48a6aa6cSLei Zhang std::string result = tgfmt("$_builder.build($_self, {$0, $1})", 164*48a6aa6cSLei Zhang &ctx.withSelf("sss"), "a", "b"); 165*48a6aa6cSLei Zhang EXPECT_THAT(result, StrEq("bbb.build(sss, {a, b})")); 166*48a6aa6cSLei Zhang } 167