1 /*
2  * Copyright (c) 2023 iSoftStone Information Technology (Group) Co.,Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <cstdint>
17 #include <functional>
18 #include <string>
19 #include <tuple>
20 #include <vector>
21 
22 #include "gtest/gtest.h"
23 
24 #include "base/geometry/dimension.h"
25 
26 #define protected public
27 #define private public
28 
29 #include "test/mock/base/mock_task_executor.h"
30 #include "test/mock/core/common/mock_container.h"
31 #include "test/mock/core/pipeline/mock_pipeline_context.h"
32 
33 #include "core/components_ng/property/templates_parser.h"
34 
35 using namespace testing;
36 using namespace testing::ext;
37 
38 namespace OHOS::Ace::NG {
39 namespace {}
40 
41 class TemplatesParserTestNg : public testing::Test {
42 public:
SetUpTestSuite()43     static void SetUpTestSuite() {};
TearDownTestSuite()44     static void TearDownTestSuite() {};
45 };
46 
47 /**
48  * @tc.name: TemplatesParserTestNg001
49  * @tc.desc: Test ParseTemplateArgs.
50  * @tc.type: FUNC
51  */
52 HWTEST_F(TemplatesParserTestNg, TemplatesParserTestNg001, TestSize.Level1)
53 {
54     /**
55      * @tc.steps: step1 init args of ParseTemplateArgs and
56                 call ParseTemplateArgs.
57      * @tc.expected: the return value is same as the forth val of tuple.
58      */
59     double size = 0;
60     double gap = 0;
61     int32_t childrenCount = 0;
62     std::vector<std::tuple<std::function<std::string(void)>, double, double, int32_t, std::vector<double>>> parms = {
__anoncbe85c680202() 63         { [&]() {
64             size = 200;
65             gap = 10;
66             childrenCount = 5;
67             return "";
68         },
69             size, gap, childrenCount, {} },
__anoncbe85c680402() 70         { [&]() {
71             size = 200;
72             gap = 10;
73             childrenCount = 5;
74             return "abc";
75         },
76             size, gap, childrenCount, {} },
__anoncbe85c680602() 77         { [&]() {
78             size = 200;
79             gap = 10;
80             childrenCount = 5;
81             return "1fr 2px 3%";
82         },
83             size, gap, childrenCount, { -2, 0, 0 } },
__anoncbe85c680802() 84         { [&]() {
85             size = 200;
86             gap = 10;
87             childrenCount = 5;
88             return "1fr 2px 900%";
89         },
90             size, gap, childrenCount, { -2, 0, 0 } },
__anoncbe85c680a02() 91         { [&]() {
92             size = 200;
93             gap = 10;
94             childrenCount = 5;
95             return "auto-fill 1fr 3fr";
96         },
97             size, gap, childrenCount, {} },
__anoncbe85c680c02() 98         { [&]() {
99             size = 200;
100             gap = 100;
101             childrenCount = 5;
102             return "0.1fr 20px 100px";
103         },
104             size, gap, childrenCount, { -12, 0, 0 } },
__anoncbe85c680e02() 105         { [&]() {
106             size = 200;
107             gap = 10;
108             childrenCount = 5;
109             return "repeat";
110         },
111             size, gap, childrenCount, {} },
__anoncbe85c681002() 112         { [&]() {
113             size = 200;
114             gap = 10;
115             childrenCount = 5;
116             return "auto-fill";
117         },
118             size, gap, childrenCount, {} },
__anoncbe85c681202() 119         { [&]() {
120             size = 200;
121             gap = 10;
122             childrenCount = 5;
123             return "repeat(1, 100px 2px 3px 4px 5px 6px 7px 8px)";
124         },
125             size, gap, childrenCount, { 0, 0, 0, 0, 0, 0, 0, 0 } },
__anoncbe85c681402() 126         { [&]() {
127             size = 200;
128             gap = 10;
129             childrenCount = 5;
130             return "repeatabcdefghi";
131         },
132             size, gap, childrenCount, {} },
__anoncbe85c681602() 133         { [&]() {
134             size = 200;
135             gap = 10;
136             childrenCount = 5;
137             return "repeat(3, 100px a b c d e f g)";
138         },
139             size, gap, childrenCount, {} },
__anoncbe85c681802() 140         { [&]() {
141             size = 200;
142             gap = 10;
143             childrenCount = 5;
144             return "repeat auto-fill 1fr 2px 900%";
145         },
146             size, gap, childrenCount, { 0 } },
__anoncbe85c681a02() 147         { [&]() {
148             size = 200;
149             gap = 10;
150             childrenCount = 5;
151             return "auto-fill arepeatpx10vp10 10)2";
152         },
153             size, gap, childrenCount, { 0 } },
__anoncbe85c681c02() 154         { [&]() {
155             size = 200;
156             gap = 10;
157             childrenCount = 5;
158             return "repeat(auto-fill, 2px )repeat(auto-fill, 2px )repeat(auto-fill, 2vp)";
159         },
160             size, gap, childrenCount, { 0 } },
__anoncbe85c681e02() 161         { [&]() {
162             size = 200;
163             gap = 10;
164             childrenCount = 5;
165             return "repeat(auto-fill, 2px 2% 2vp 2 )";
166         },
167             size, gap, childrenCount, { 2, 0, 2, 2 } },
__anoncbe85c682002() 168         { [&]() {
169             size = 200;
170             gap = 10;
171             childrenCount = 5;
172             return "2px 2px repeat(auto-fill, 2px 2% 2 ) 2px";
173         },
174             size, gap, childrenCount, { 2, 2, 2, 0, 2, 2 } },
__anoncbe85c682202() 175         { [&]() {
176             size = 200;
177             gap = 10;
178             childrenCount = 5;
179             return "(auto-fit, 2px 2)";
180         },
181             size, gap, childrenCount, {} },
__anoncbe85c682402() 182         { [&]() {
183             size = 200;
184             gap = 10;
185             childrenCount = 5;
186             return "repeat(auto-fit, ) 2px";
187         },
188             size, gap, childrenCount, { 0 } }
189     };
190     for (auto [args, size, gap, childrenCount, rt] : parms) {
191         auto result = ParseTemplateArgs(args(), size, gap, childrenCount);
192         EXPECT_EQ(result.first.size(), rt.size());
193         for (int i = 0; i < rt.size() && i < result.first.size(); i++) {
194             EXPECT_EQ(rt[i], result.first[i]);
195         }
196     }
197 }
198 
199 /**
200  * @tc.name: TemplatesParserTestNg002
201  * @tc.desc: Test ParseTemplateArgs.
202  * @tc.type: FUNC
203  */
204 HWTEST_F(TemplatesParserTestNg, TemplatesParserTestNg002, TestSize.Level1)
205 {
206     /**
207      * @tc.steps: step1. Test ParseArgsWithAutoFit.
208      * @tc.expected: retVal.first is empty.
209      */
210     std::string args = "repeat(auto-fit,4px) 2px 2px 2px";
211     double size = 100;
212     double gap = -10;
213     int32_t childrenCount = 6;
214 
215     auto retVal = ParseTemplateArgs(args, size, gap, childrenCount);
216     EXPECT_EQ(retVal.first.size(), 4);
217 
218     /**
219      * @tc.steps: step2. Test ParseArgsWithAutoFill.
220      * @tc.expected: retVal.first.size() is 100.
221      */
222     args = "repeat(auto-fill,4px) 2px 2px 2px";
223     size = 6;
224     gap = 100;
225     childrenCount = 6;
226     vector<int> gt { 4, 2, 2, 2 };
227 
228     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
229     EXPECT_EQ(retVal.first.size(), 4);
230     for (int i = 0; i < retVal.first.size(); i++) {
231         EXPECT_EQ(retVal.first[i], gt[i]);
232     }
233 
234     /**
235      * @tc.steps: step2. Test ParseAutoFill.
236      * @tc.expected: retVal.first.size() is empty.
237      */
238     args = "auto-fill,4px 2px 2px 2px";
239     size = 6;
240     gap = -10;
241     childrenCount = 6;
242 
243     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
244     EXPECT_TRUE(retVal.first.empty());
245 }
246 
247 /**
248  * @tc.name: TemplatesParserTestNg003
249  * @tc.desc: Test ParseArgsWithAutoStretch.
250  * @tc.type: FUNC
251  */
252 HWTEST_F(TemplatesParserTestNg, TemplatesParserTestNg003, TestSize.Level1)
253 {
254     /**
255      * @tc.steps: step1. Test ParseArgsWithAutoStretch with normal args.
256      * @tc.expected: retVal.first is { 4, 4} and retVal.second is 1
257      */
258     std::string args = "repeat(auto-stretch, 4)";
259     double size = 9;
260     double gap = 1;
261     int32_t childrenCount = 2;
262     vector<int> gt { 4, 4 };
263 
264     auto retVal = ParseTemplateArgs(args, size, gap, childrenCount);
265     for (int i = 0; i < retVal.first.size(); i++) {
266         EXPECT_EQ(retVal.first[i], gt[i]);
267     }
268     EXPECT_EQ(retVal.second, 1);
269 
270     /**
271      * @tc.steps: step2. Test ParseArgsWithAutoStretch with invalid args.
272      * @tc.expected: retVal.first is empty.
273      */
274     args = "repeat(auto-stretch, 4, 6)";
275 
276     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
277     EXPECT_TRUE(retVal.first.empty());
278 
279     /**
280      * @tc.steps: step3. Test ParseArgsWithAutoStretch with need calculate gap args.
281      * @tc.expected: retVal.first is { 4, 4} and retVal.second is 2
282      */
283     args = "repeat(auto-stretch, 4)";
284     size = 10;
285     gap = 1;
286     gt = { 4, 4 };
287 
288     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
289     EXPECT_EQ(retVal.first.size(), gt.size());
290     for (int i = 0; i < retVal.first.size(); i++) {
291         EXPECT_EQ(retVal.first[i], gt[i]);
292     }
293     EXPECT_EQ(retVal.second, 2);
294 
295     /**
296      * @tc.steps: step4. Test ParseArgsWithAutoStretch with px args.
297      * @tc.expected: retVal.first is { 4, 4, 4, 4 } and retVal.second is 2.
298      */
299     args = "repeat(auto-stretch, 4px)";
300     size = 22;
301     gap = 1;
302     gt = { 4, 4, 4, 4 };
303 
304     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
305     EXPECT_EQ(retVal.first.size(), gt.size());
306     for (int i = 0; i < retVal.first.size(); i++) {
307         EXPECT_EQ(retVal.first[i], gt[i]);
308     }
309     EXPECT_EQ(retVal.second, 2);
310 
311     /**
312      * @tc.steps: step5. Test ParseArgsWithAutoStretch with % args.
313      * @tc.expected: retVal.first is empty .
314      */
315     args = "repeat(auto-stretch, 5%)";
316     size = 35;
317     gap = 2;
318     gt = { 5, 5, 5, 5, 5 };
319     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
320     EXPECT_TRUE(retVal.first.empty());
321 }
322 
323 /**
324  * @tc.name: TemplatesParserTestNg004
325  * @tc.desc: Test ParseArgsWithoutAutoFill.
326  * @tc.type: FUNC
327  */
328 HWTEST_F(TemplatesParserTestNg, TemplatesParserTestNg004, TestSize.Level1)
329 {
330     std::string args = "auto-fill 4px) 4";
331     double size = 0;
332     double gap = -1;
333     int32_t childrenCount = 2;
334     vector<int> gt { 4, 4 };
335     auto retVal = ParseTemplateArgs(args, size, gap, childrenCount);
336 
337     /**
338      * @tc.steps:. Test ParseArgsWithAutoStretch with vp args.
339      * @tc.expected: retVal.first is { 5, 5, 5, 5, 5 } and retVal.second is 2.5 .
340      */
341     args = "repeat(auto-stretch, 5vp)";
342     size = 35;
343     gap = 2;
344     gt = { 5, 5, 5, 5, 5 };
345     MockPipelineContext::SetUp();
346     MockContainer::SetUp();
347     MockContainer::Current()->pipelineContext_ = MockPipelineContext::GetCurrentContext();
348     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
349     EXPECT_EQ(retVal.first.size(), gt.size());
350     for (int i = 0; i < retVal.first.size(); i++) {
351         EXPECT_EQ(retVal.first[i], gt[i]);
352     }
353     EXPECT_EQ(retVal.second, 2.5);
354     MockPipelineContext::TearDown();
355     MockContainer::TearDown();
356 
357     args = "repeat(auto-stretch, 10vp)";
358     size = 1;
359     gap = 2;
360     gt = { 5, 5, 5, 5, 5 };
361     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
362 
363     args = "repeat(auto-fill,0vp)";
364     size = 6;
365     gap = 100;
366     childrenCount = 6;
367     gt = { 4, 2, 2, 2 };
368     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
369     EXPECT_EQ(gap, 100);
370 }
371 
372 /**
373  * @tc.name: TemplatesParserTestNg005
374  * @tc.desc: Test ParseArgsWithoutAutoFill.
375  * @tc.type: FUNC
376  */
377 HWTEST_F(TemplatesParserTestNg, TemplatesParserTestNg005, TestSize.Level1)
378 {
379     std::string args = "repeat(auto-fill,0vp)";
380     double size = 6;
381     double gap = 100;
382     int32_t childrenCount = -1;
383     vector<int> gt = { 4, 2, 2, 2 };
384     auto retVal = ParseTemplateArgs(args, size, gap, childrenCount);
385 
386     args = "repeat(auto-fit,0vp)";
387     size = 6;
388     gap = 100;
389     childrenCount = 6;
390     gt = { 4, 2, 2, 2 };
391     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
392 
393     args = "repeat(auto-fit,0vp)";
394     size = 6;
395     gap = 100;
396     childrenCount = -1;
397     gt = { 4, 2, 2, 2 };
398     retVal = ParseTemplateArgs(args, size, gap, childrenCount);
399     EXPECT_EQ(gap, 100);
400 }
401 } // namespace OHOS::Ace::NG
402