xref: /llvm-project/mlir/unittests/TableGen/FormatTest.cpp (revision 48a6aa6c513f471c5931c0f817beca5339ed2425)
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